eazydraw — Python client and MCP server for EazyDraw
EazyDraw is a vector drawing application for the Mac: technical drawings, diagrams, illustrations, schematics, and layouts, with layers, libraries, and a full set of line, fill, and text styling. EazyDraw 12 includes an Automation API, an HTTP interface served by the running app.
This package is the Python side of that API. It gives you two ways to drive EazyDraw:
eazydraw— a Python client. One class,EazyDraw, with a method for every API endpoint. Open, create, and save drawings; add and style graphics; edit text; manage layers; export to PDF, SVG, PNG, or JPEG.eazydraw-mcp— a Model Context Protocol server. Exposes the same capabilities to an AI agent such as Claude as intent-level tools that work by name ("fill theclient_namefield", "put the legend beside the chart", "render it"). The agent never sees UUIDs or your API token.
Requires macOS, Python 3.10+, and EazyDraw 12 with the Automation API turned on in EazyDraw ▸ Settings ▸ API Settings.
What you can do
Drawings — list open drawings, open a file, create a blank drawing, Save and Save As, close, undo and redo (every API call is one undo step), read and set the selection, page setup, grids, drawing scale, and the window viewport.
Layers — list, create, rename, reorder, and delete layers, show/hide/lock them, select by layer, and apply saved layer configurations.
Graphics — add shapes (rectangles, ovals, lines, polygons, and more), paths from node lists, and curves fitted through points. Name, move, resize, scale, rotate, flip, duplicate, group and ungroup, combine (union, difference, intersection), reorder front-to-back, move between layers, lock, and delete.
Styling — stroke and fill color, line width, dash patterns, shadows, gradients, fill patterns, hatching, arrowheads, calligraphic brush profiles, conduits (double-line paths) with crossover styles, and path offsets.
Text — read and set text, with fit information so you know whether it overflowed; work at the run level for mixed fonts and colors; insert, align, highlight, shadow, and disconnect linked text boxes; edit annotations.
Images — insert an image or PDF, or fit one into a named slot.
Libraries — browse the installed libraries and place their elements into a drawing.
Arrange (semantic layer and MCP) — place a graphic beside a reference, nudge, anchor to page positions (center, corners, edges), align, and distribute.
Render and export — render to PNG at a chosen dpi, or export a drawing,
layer, or graphic as PDF, SVG, PNG, JPEG, or the native .ezdjson format.
The MCP server exposes about 90 tools covering the list above, plus
eazydraw://drawings and eazydraw://drawing/{uuid}/fields resources. The
authoritative reference for both the API and the tools is the
API Reference Help page.
Install
pip install eazydraw # the Python client
pip install "eazydraw[mcp]" # client + MCP server (adds the eazydraw-mcp command)
Generate a bearer token in EazyDraw's API Settings (Reveal / Copy). Keep EazyDraw running with the API enabled; the package talks to the live app.
Transport: TCP or UNIX socket
The direct-download EazyDraw serves the API on localhost:52737. The App Store
EazyDraw is sandboxed and serves the same API on a UNIX-domain socket in its
container instead. API Settings shows which one your copy uses. Everything else
is identical:
from eazydraw import EazyDraw, DEFAULT_SOCKET
ed = EazyDraw(token="...") # direct build, TCP
ed = EazyDraw(token="...", socket_path=DEFAULT_SOCKET) # App Store build
Python quickstart
from eazydraw import EazyDraw
ed = EazyDraw(token="7b3f...") # from API Settings -> Reveal
ed.status()
# {'status': 'OK', 'version': '12.10.0', 'build': '52075'}
# Open a drawing and walk to the graphics on its first layer
d = ed.open_drawing("~/Documents/sketch.ezdjson")
layers = ed.layers(d["uuid"])
graphics = ed.layer_graphics(d["uuid"], layers[0]["uuid"])
# Export it as a PNG
ed.export_drawing(d["uuid"], "png", save_to="~/Desktop/sketch.png")
ed.close_drawing(d["uuid"])
# Start from nothing
n = ed.new_drawing("Plan")
lyr = ed.layers(n["uuid"])[0]["uuid"]
box = ed.add_shape(n["uuid"], lyr, shape="rectangle",
bounds={"x": 72, "y": 72, "width": 200, "height": 100}, name="frame")
ed.set_style(n["uuid"], lyr, box["graphicUUID"],
fill={"color": "#DDEEFF"}, stroke={"width": 2})
ed.set_selection(n["uuid"], [box["graphicUUID"]])
ed.save_drawing(n["uuid"], path="~/Documents/plan.ezdjson")
Methods take UUIDs as positional strings in path order and return the raw JSON
as dicts and lists. Collection endpoints return the list directly. Non-2xx
responses raise EazyDrawError(status_code, message, body), and the last
requests response is kept on ed.last_response when the status code matters
(201 newly opened vs 200 already open, for example).
Typed models (optional)
eazydraw.models has pydantic v2 models mirroring the API's JSON shapes:
from eazydraw import Graphic
g = Graphic.model_validate(ed.graphic(D, L, G))
g.hidden_bounds.width, g.is_group # snake_case fields
g.model_dump(by_alias=True) # back to wire form
Working by name
eazydraw.semantic.Semantic resolves names to graphics and does layout
geometry client-side, so scripts can say what they mean:
from eazydraw.semantic import Semantic
sem = Semantic(ed)
sem.move_beside(d["uuid"], target="legend", reference="chart", direction="right", gap=24)
sem.align(d["uuid"], ["a", "b", "c"], edge="left")
MCP server (Claude Desktop, Claude Code, any MCP client)
The server speaks the Model Context Protocol, so one entry serves every MCP
client. For Claude Desktop add it to ~/Library/Application Support/Claude/ claude_desktop_config.json and restart; for Claude Code, claude mcp add eazydraw -e EAZYDRAW_TOKEN=... -- uvx --refresh-package eazydraw --from "eazydraw[mcp]" eazydraw-mcp; another agent host takes the same command, args
and env in its own MCP configuration. It uses uv's
uvx, so there is nothing to install by hand, and --refresh-package picks up
new releases automatically:
{
"mcpServers": {
"eazydraw": {
"command": "uvx",
"args": ["--refresh-package", "eazydraw", "--from", "eazydraw[mcp]", "eazydraw-mcp"],
"env": { "EAZYDRAW_TOKEN": "PASTE_TOKEN_HERE" }
}
}
}
For the App Store EazyDraw add "EAZYDRAW_SOCKET": "default" to env. The
Copy Claude Desktop config button in API Settings produces this block with
the right token and transport filled in.
Then ask Claude something like: "Open ~/Documents/engagement.ezdjson, list its
fields, set client_name to 'Ryan Mattson', then render it so I can see."
Notes:
- The server sends an instructions block when a client connects (the page
coordinate system, points,
get_pagefirst, whatrenderis), andguide(topic)has the deeper notes: coordinates, text, forms, styling, export, libraries, setup. renderreturns a PNG inline so the agent can see the result (96 dpi, white background, whatever the Export panel says).export_drawingwrites a file instead (PDF, SVG, or 144 dpi PNG/JPEG by default) to~/EazyDraw-Renders(orEAZYDRAW_RENDER_DIR, read at launch) and returns only the path;backgroundandalphaoverride the export settings per call.export_layerandexport_graphicwrite one layer or one graphic.save_renderis the same tool asexport_drawingunder its earlier name.- An "active drawing" is tracked, so with one drawing open the tools do not
need a
drawingargument. - Environment:
EAZYDRAW_TOKEN(required),EAZYDRAW_SOCKET,EAZYDRAW_HOST,EAZYDRAW_PORT,EAZYDRAW_RENDER_DIR. - Run the server by hand with
eazydraw-mcporpython -m eazydraw.mcp.
Links
- EazyDraw: https://www.eazydraw.com
- API Reference (endpoints and MCP tools): https://www.eazydraw.com/ezdHelpPages/apiReference.htm
- Changelog: see CHANGELOG.md in the source distribution
- License: MIT
Metadata
Release files for eazydraw 1.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| eazydraw-1.3.0.tar.gz | 84.2 kB | Without provenance | Details for eazydraw-1.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| eazydraw-1.3.0-py3-none-any.whl | Python 3 | none | any | Details for eazydraw-1.3.0-py3-none-any.whl |
Total release size: 162.6 kB
Release files / eazydraw-1.3.0.tar.gz
| Download URL | eazydraw-1.3.0.tar.gz |
|---|---|
| Size | 84.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
19418dabcf5d16a1cc79f4d7ccec92df9172f8da8064919ca0db7e080ba47935
|
|
BLAKE2b-256 checksum How to use checksums |
c33552df40ce1f684bfcfed6a2f8c4de7cc91f99f019a5144a4b37d88d072386
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / eazydraw-1.3.0-py3-none-any.whl
| Download URL | eazydraw-1.3.0-py3-none-any.whl |
|---|---|
| Size | 78.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cc9262ee5a2b5d556e09ab69bce2293ca0d7b4dd1619bf265f8688ea027a4f30
|
|
BLAKE2b-256 checksum How to use checksums |
5d5c92228a29d2cde26b0092136bfa4cbb9b02a9772c19f305daac855909cdc3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Security for eazydraw 1.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.