lineus-mcp
Summary: An MCP server that lets an AI agent design, preview, and draw with a Line-us pen plotter on the local network.
Preview any drawing as PNG before committing:
preview_paths,preview_svg,preview_text,preview_scene(each returns a diagnostic view plus a hardware-accurate simulation).Draw strokes, SVGs, text, or declarative scenes:
draw_paths,draw_svg,draw_text,draw_scene— all asynchronous, returning ajob_id.Plan a scene without drawing or rendering:
plan_scenereports stroke/point counts, bounding box, pen-up travel, and warnings.Scenes (main interface): compact declarative descriptions compiled server-side from parametric expressions, text, paths, SVG, doodles, or traced images — with fills/hatching, transforms, smoothing, repeats, occlusion, and stroke-join planning.
Handwriting: nine single-line print/cursive fonts (plus legacy Hershey);
list_fontsreports passes, aperture, and joins to pick legible faces.Doodles: browse and pick real Quick, Draw! drawings — 184 curated in 31 categories, or any of 345 categories fetched and cached on demand via
doodles.Examples:
get_example(andlineus://examplesresources) returns finished starter scenes to modify.Job and robot control:
get_job,abort,home,get_status, anddraw_orientation_testto verify canvas orientation.Run without hardware via
LINEUS_MOCK=1; extensive env configuration (host, speed, pen height, envelope, preview path, etc.).
Fetches drawings from Google's Quick, Draw! dataset on demand. Any of the 345 doodle categories can be requested, and the server retrieves that category's stroke data for rendering and plotting as robot drawings.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@lineus-mcpdraw 'hello world' on the plotter and show me the preview"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
lineus-mcp
An MCP server that lets an AI agent draw with a Line-us robot drawing arm.
Line-us is a small pen plotter that started on Kickstarter: a three-servo arm that speaks G-code over TCP. It needs nothing beyond the local network: this server talks to it directly and puts it behind MCP, where any MCP client and the AI agent behind it can preview and draw.
you ──▶ agent ──▶ lineus-mcp ──▶ TCP 1337 ──▶ Line-us
│
preview PNG ◀── see it before it drawsWhat it does
Tool | Purpose |
| The main interface. A declarative scene, compiled to strokes server-side |
| Stroke/point counts, bounding box, travel and warnings — without drawing or rendering |
| The handwriting faces, with the measurements that say which will survive |
| Finished drawings to start from instead of a blank page (also as |
| Real doodles from Google's Quick, Draw!: browse a numbered contact sheet, then pick one |
| Render a PNG of what would be drawn — no movement |
| Polylines in millimetres: |
| SVG line art fitted into a box (strokes only; fills are not hatched) |
| A single line or block of single-stroke text |
| Firmware banner, diagnostics, page size, reachable envelope, last job |
| Async job control |
| Frame + an "F" to verify the canvas orientation |
Drawing is asynchronous: draw_* returns a job_id, and you poll get_job.
Only one drawing runs at a time.
Every preview_* returns two pictures: a diagnostic view (envelope, page, pen-up travel)
and a simulated one showing what the arm will actually put on paper. The simulation
applies the faults measured on this hardware: corners blended through by the firmware's
one-command lookahead, and a short tick at both ends of every stroke, lying along the line
to the shoulder because the pen-lift axis isn't vertical, and longer the further the arm
reaches. The simulated image is also written to ~/.cache/lineus-mcp/preview.png,
so you can watch iterations in any viewer that reloads on change. Pass simulate=false
for the clean ink render instead.
Judge drawings by the simulation, not the clean render. Every drawing in this project that disappointed on paper had looked fine as a clean render.
Drawing checks
preview_scene, draw_scene and plan_scene also run checks that report where to fix
something, in page millimetres. Each check exists because the mistake was actually made:
check | catches |
same line twice | a mesh drawn without |
lines merging | two lines running within 1.1 mm without meeting — parallels that blot, sliver triangles that fill in, an eye too narrow to stay open |
glued one-line |
|
They're measured as runs along the line, so a crossing doesn't count. Two lines that cross come together only briefly; that's the difference from either fault. Fills are exempt, since blotting is the point there.
What no check can catch is bad drawing: proportion, silhouette, character. That knowledge is in the server's instructions, which every agent reads on connecting, and in the examples.
Related MCP server: Plotter Studio
Scenes
Sending coordinates is expensive and fragile — a page of generated curves is tens of thousands of characters, and preview and draw are two separate pastes that can silently disagree. A scene is a description that the server compiles:
{"shapes": [
{"text": "Slow is smooth", "font": "neutral", "align": "center", "box": [4, 2, 72, 10]},
{"param": {"t": [0, 47, 900],
"x": "40+33*exp(-0.028*t)*sin(2.01*t)",
"y": "30+10*exp(-0.028*t)*sin(3.02*t+1.2)"}},
{"param": {"t": [0, 6.2832, 160], "x": "55+8*cos(t)", "y": "11+8*sin(t)", "closed": true},
"fill": {"hatch": 45, "spacing": 1.15}}
]}That harmonograph is 125 characters where its 2,000 points would be 27,542 — about 220×.
There is deliberately no library of shapes. A fixed vocabulary of circle/rect/arc would
handle the dull cases and send everything interesting straight back to pasting
coordinates, which is the problem scenes exist to solve. Curves are expressions, so a
circle, a spiral, a rose and a harmonograph are the same producer with different formulae.
Expressions are evaluated by a whitelisted AST walk — no imports, no attribute access, no
exec — so the open-endedness costs no safety.
producer | |
|
|
| a string, or a list of |
| raw points, the escape hatch |
| imported line art |
|
|
| a line-art image traced along the centre of each line, see below |
modifier | |
|
|
| close the path before smoothing |
|
|
|
|
| scale this shape into |
| N, exposing |
|
|
smooth is what makes hand-drawn figures affordable: a cat is ~30 control points instead
of ~400 sampled ones. It is centripetal Catmull-Rom specifically — the uniform
parameterisation puts cusps and little self-intersecting loops wherever control points
bunch up, which is exactly where a drawn figure has them.
Draw with curves, not shapes
The quickest way to make a drawing look childish is to assemble it from shapes: a circle for the head, ovals for hands, rectangles for limbs. It does not matter how carefully they are placed. The same figure drawn the way an illustrator draws reads as a drawing:
Proportions and pose first. A person is about 6–6.5 heads tall, not 3, with the weight on one leg and the shoulders tilted against the hips.
Long contours. Each is a smooth path through a few well-placed points, and one line runs through several parts: collar, shoulder and sleeve in a single stroke, or the whole back.
Detail as open strokes. A fold, a crease, an elbow or a knee is one short line, not a closed outline.
Lines stop. They end just short of the line they meet, and where something passes in front of them.
Features belong to contours. A nose is a bump in the profile line, not a shape stuck on the face.
flowing_walker is the worked example. It is the same character as an earlier
shape-built attempt, redrawn with these rules and no reference image. Tall subjects
should be drawn sideways along the page's 80 mm side, which gives 78 mm of height
instead of 43.
Hidden lines
A pen cannot paint over a line, so "in front of" has to be done by not drawing the part
of an earlier stroke that a nearer shape covers. With "occlude": true on the scene, shapes
are drawn back to front and every closed stroke, or filled shape, hides whatever is already
underneath it, hatching included:
{"occlude": true, "shapes": [
{"param": {"t": [0, 6.2832, 160], "x": "57+6*cos(t)", "y": "15+6*sin(t)", "closed": true}},
{"path": [[2,43],[2,27],[27,10],[45,17],[78,29],[78,43],[2,43]], "fill": {"hatch": 60, "spacing": 1.6}}
]}The sun is listed first, so the mountain hides its lower half. Without occlusion every outline shows through and the drawing reads as a wireframe. That one setting is the difference between overlapping shapes and line art: a paw in front of a body, hills in front of mountains. The details:
Open strokes never hide anything. Only an enclosed area can be in front.
Even-odd. A shape drawn as an outer and an inner closed stroke is a ring, and its hole stays see-through.
Shared edges survive. A line lying exactly on the boundary of a nearer shape is kept, so two shapes that share an edge both still have it. The exception is hatching under a shape that draws its own outline: there, a hatch connector running along the outline would be a second pass over the same line, broken into pieces that each land with a smear, so it is dropped.
Cut hatching can be re-joined, on request. Hiding part of a fill cuts away the serpentine's turns and leaves every span its own pen lift.
"occlude": {"rejoin": true}joins the pieces again where their ends are within 1.6 spacings, but only by a connector that no front shape covers. A chord between two cut points on a circle would run inside the circle, so it is refused. On the landscape example this takes 49 strokes down to 29. It is off by default: fewer lifts is not automatically a better drawing, and the separate spans may well look better on paper. That has not been tested on the robot yet.
The same idea as vpype's occult plugin, done natively: occult needs vpype (Python ≥ 3.11)
and shapely, and the geometry here is small enough for a segment-against-edge clip with a
grid index in pure Python. plan_scene reports how much line was hidden (hidden_mm).
Tracing an image
{"trace": "drawing.png"} turns a line-art image into strokes that follow the centre
of each line. Ordinary tracing (potrace, Inkscape's default Trace Bitmap) follows the
edges of the ink, so every line comes back as a thin closed outline and the pen draws it
twice. Here the ink is thinned to a one-pixel skeleton (Zhang–Suen), read as a graph of
endpoints and junctions, and each run between them becomes one stroke. Then:
Whiskers that thinning grows at corners are pruned. Short separate strokes are not, because an eye, an eyebrow or a strand of hair is exactly that. An early version pruned them as if they were whiskers and traced a face as a bare profile.
Crossings. Thinning splits an X into two Ts joined by a stub; those are collapsed back into one junction.
Junctions. Thinning bends a line as it nears a junction; each run is cut back by a line-width and reconnected straight to the junction centre.
The pixel staircase is smoothed away.
Options: threshold (0–255, default Otsu), invert for light lines on dark,
resolution (the long side, default 600 px), spur, smooth, despeckle. A trace is
fitted to the page unless it has a box; add "join": {"chain": true} to merge the runs
into trails. On a scanned comic that took 154 strokes to 64.
It is for line art: dark lines, a few pixels thick, on a light background. A solid black area thins to its medial axis, which is rarely what you want. Hatch it instead. And the page is small: a busy picture fitted to 45 mm puts lines closer than the ~1.15 mm the nib can keep apart, which the drawing checks will point out.
Planning the strokes
A scene-level "join" block rewrites the whole pile of strokes before drawing:
{"join": {"explode": true, "dedupe": true, "chain": true, "one_line": false, "weld": 0.3}}
| break polylines into segments first, so shared edges become visible |
| drop segments already drawn — on by default |
| join strokes that meet into the fewest continuous trails |
| bridge every trail into a single unbroken stroke |
| how close two ends must be to count as touching, in mm |
This matters more than it sounds. A triangle mesh supplied as triangles redraws every interior edge twice: on the bundled fox, 1,075 mm of ink against 609 mm planned — 43% of the drawing — and the repeat lands slightly off the original so the edge reads as doubled. Planned, it also drops from 48 strokes to 8 — and every pen lift costs a landing smear, so fewer lifts is a quality setting here, not just a faster one.
chain is Hierholzer with odd-vertex pairing, not greedy extension. Greedy looks fine and
is not: it strands edges and leaves extra trails. A component with k odd-degree vertices
needs exactly max(1, k/2) trails, so the odd vertices are paired with dummy edges, the
Eulerian circuit is found, and the circuit is cut back open at the dummies. Pairing nearest
first also minimises the travel between the trails that result.
one_line bridges with tangent-continuous cubic Hermite hops — the line leaves and
rejoins along the direction it was already travelling, because a straight connector reads
as a mistake. The firmware's 1–2 mm corner blending then smooths any residual kink, which
is the one place that fault helps us.
Variables are t, plus i and n inside a repeat. Functions: sin cos tan asin acos atan atan2 sinh cosh tanh exp log sqrt hypot floor ceil fmod degrees radians abs min max round pow sign clamp lerp, and pi tau e.
No scene id is ever issued. Pass the same scene to draw_scene that you passed to
preview_scene: compilation is deterministic and content-hashed, so the two agree by
construction, and there is no id to go stale.
Handwriting
Bundled in data/fonts/ are nine single-line faces under the SIL Open Font
License — real handwriting typefaces, not engraving fonts — with attribution in
NOTICE.md.
faces | |
| |
cursive |
|
The cursive faces weld: a letter's exit sits close enough to the next letter's entry that they join into one continuous stroke per word. "minimum" is 4 strokes, not 7 lifts.
The classic Hershey names still work, but most of them are a bad idea on a plotter — see below.
Doodles
Real drawings by real people, from Google's
Quick, Draw! dataset
(CC BY 4.0, attribution in NOTICE.md): 50 million doodles
in 345 categories. They're stored as recorded pen strokes, in the order the person drew
them, not outlines or fills. So every line is one stroke and its width comes from the
pen alone, and with order="asis" the robot replays a doodle stroke by stroke as it was
drawn.
{"shapes": [{"doodle": "owl", "pick": 2, "box": [25, 3, 30, 39]}]}Curated set. 184 doodles in 31 categories ship in data/doodles/: animals, sun
and moon, house, vehicles, objects. Every one was chosen by eye. Ranking alone isn't
enough: the top-ranked candidates still included scribbles, drawings with the word written
in them ("duck", "quack"), and a cat that reads as a bull.
Everything else is fetched on demand. Any of the 345 categories can be used. The
server reads the first ~600 KB of that category's file (several hundred drawings) with a
byte-range request, ranks them, and caches the result under ~/.cache/lineus-mcp. The
cache is what keeps preview and draw identical. Category names are checked against the
dataset's own list before anything is fetched, so the server can't be pointed at an
arbitrary URL.
Look before picking. doodles("camel") returns a numbered contact sheet. Web
candidates get no human review, and quality depends on the subject: things with a
distinctive silhouette (camel humps, ears, wheels) come out well, while scenes with detail
(a lighthouse and its beam) are mostly unreadable. The ranking rejects scribbles and
favours clean, moderate ink. A clean five-pointed star has about ten points, so an earlier
ranking that rewarded detail threw away the good stars and kept the scribbled ones. But no
score replaces looking.
Coordinates
Millimetres, origin top-left of the page, u right, v down.
The page is 80 × 45 mm and is the default framing for text and SVG. It is not a
boundary — draw_paths may use negative coordinates and go anywhere the arm reaches.
The real limit is the measured envelope: a circular segment of outer radius
1850 units (~92 mm) cut off by a straight inner chord, roughly three times the page area.
Points outside the envelope are reported as warnings, never silently moved. This matters: the firmware clamps out-of-reach targets radially toward the origin and lifts the pen, so an out-of-range point does not merely distort a stroke, it breaks it.
Note that the "app drawing area" the official documentation gives — x 650…1775, y −1000…1000 — is not all reachable. Its far corners sit at radius 2037 against the 1950 this arm actually manages, so a drawing that fills that rectangle quietly loses its corners. Other projects hardcode it. The envelope here was measured over 45 probes instead.
Install
The server is a Python package with a lineus-mcp command, speaking MCP over stdio, so it
works with any MCP client. The simplest way to run it is uvx, which installs it into an
isolated environment on first use. Whatever the client, it needs:
command:
uvxargs:
--from git+https://github.com/BenTeoNeb/lineus-mcp lineus-mcpenv:
LINEUS_HOST=line-us.local
GUI clients don't inherit your shell PATH, so give them the absolute path to uvx
(command -v uvx; with pyenv, pyenv which uvx). Two examples:
Claude Code
claude mcp add lineus -e LINEUS_HOST=line-us.local -- \
uvx --from git+https://github.com/BenTeoNeb/lineus-mcp lineus-mcpClaude Desktop: edit claude_desktop_config.json, then restart. Many other clients
use the same mcpServers shape in their own config file:
{
"mcpServers": {
"lineus": {
"command": "/absolute/path/to/uvx",
"args": ["--from", "git+https://github.com/BenTeoNeb/lineus-mcp", "lineus-mcp"],
"env": { "LINEUS_HOST": "line-us.local" }
}
}
}From a clone, which is handy while changing the code: uv run --directory /path/to/lineus-mcp lineus-mcp, or python -m lineus_mcp inside its environment.
Try it without a robot: set LINEUS_MOCK=1. Everything works except the moving.
Configuration
Variable | Default | Meaning |
|
| Hostname or IP. Use the IP if mDNS is unreliable. |
| unset |
|
|
| Default |
|
| Floor. Speed 1 can wedge the firmware — see below |
|
| Socket timeout in seconds |
|
|
|
|
| How far down the pen goes. Not 0 — see the landing smear below |
|
| Where the simulated preview is written |
|
| Nib width for that preview. Set it when you change pens |
|
| How close a cursive letter's exit must be to the next letter's entry to weld |
|
| Corner-blending window used by the simulated preview |
|
| Simulated stroke-end tick at radius 1500 units; scales with reach |
|
| Where fetched doodles are cached |
|
| How much of a Quick, Draw! category file to read when fetching |
|
| Orientation fixes |
|
| Envelope limits |
Run draw_orientation_test first. The "F" must read normally at the top-left; if it is
mirrored or rotated, adjust the SWAP/FLIP variables.
Things we learned the hard way
All of this was measured on real hardware, and several of it corrects something we had believed earlier. Where a conclusion was overturned, the overturned version is named too — the wrong guesses are the useful part.
Two separate faults, not one. They look like a single "the arm does not settle" problem, and we spent a long time treating them as one. They are not:
Corner rounding is planner blending. The firmware accepts the next move while still executing the current one — exactly one command of lookahead — so it blends through vertices instead of stopping. The radius is roughly constant at 1–2 mm, which makes it invisible on a 20 mm shape and fatal on a 6 mm one.
The pen-landing smear is geometric. The lift axis is not vertical: the nib travels
radially with respect to the shoulder as it descends, laying ink from first contact
until Z bottoms out. So every stroke start and end gets a short radial drag, every one
pointing at the same place and growing with distance from it. Timing has nothing to do with
it — at constant radius, speed changes nothing, and the fix is a shallower pen-down Z
(the server uses 300, not 0), not a pause. Any amount of waiting is wasted effort here.
Most engraving fonts retrace every stem, and it shows. Hershey's bold and serif faces
fake weight by drawing each stem two or three times side by side — a capital H in
rowmant is 27 strokes, against the 3 a person uses. On a plotter that reads as a
sketchy scribble rather than writing. futural is the only Hershey face that does not do
it. The bundled single-line faces all draw a letter about once.
Pick a face by its aperture, not by how it looks on screen. The measurement that
predicts legibility here is the width of the opening in a letter — the gap in s, a,
e, o — against the 1–2 mm that corner blending eats. brush has a 0.89 mm aperture
at a 5 mm cap height, and turns "oo" into something like "rr" on paper. architect has
2.74 mm and stays crisp. list_fonts reports this per face. Two faces chosen from clean
renders both lost to the ones aperture favoured, so trust the number over the preview.
Line art beats dot art, by a lot. The same ladybug: 358 dots took 154 s and every mark smeared. 17 polylines took 33 s and came out clean. For solid blacks, hatch at ~1.15 mm — do not pack dots.
Stroke order is a quality setting, not just cosmetics. order="human" (the default)
draws row by row, letter by letter, in the letterform's own stroke order, never reversing a
stroke. It costs ~2.8× the pen-up travel but only ~4% wall-clock, because travel is not the
bottleneck — and the joins actually meet, because servo backlash stays correlated within a
glyph. order="fast" (nearest-neighbour) is available when throughput matters.
Pen height is mechanical and fragile. Z0 (down) and Z1000 (up) are hard limits with
no software headroom — a negative Z is rejected and snaps the pen fully up. Total lift
travel is only ~3 mm, so the paper surface has to sit inside that window. Re-check after
every pen change; examples/penhold.py parks the arm so you can set it against the real
contact point.
Do not use speed 1. A G01 blocks until the move completes, and at S1 a long travel
can exceed the socket timeout; the firmware's command parser then stops responding entirely
and only a power cycle recovers it. The server floors speed at 2 for this reason. Symptom:
get_status times out while ping and nc -z line-us.local 1337 both succeed.
Examples
Scenes in data/examples/, ready to pass straight to preview_scene — or
fetched by the agent with get_example, and best used as starting points ("the cat, lying
down"). Each carries a _comment explaining what made it work:
scene_demo.json— text, a hatched blob, a harmonograph and a repeat family. 473 characters of geometry compiling to 1,836 points (the file is longer; it is commented)one_line_cat.json— a sitting cat in a single continuous line. One designed path, not an outline with details bridged on: bridging separate pieces reads as gluegeometric_fox.json— a low-poly fox head, 48 triangles with solid-filled eyes and nose, no angle under 19°. Its mesh is 48 strokes and 1,075 mm of ink naively, 8 strokes and 609 mm planned — exactly its unique edge length, so nothing is drawn twicelayered_landscape.json— sun, hatched mountains, hills and trees, listed back to front with"occlude": true. Nothing is clipped by hand; turn occlusion off and every layer shows throughflowing_walker.json— a figure walking, drawn sideways with curves alone. Long contours, open creases, a nose in the profile line, and a back line that stops behind the arm. No stock shapes, no reference imagetext_oneliners.json— one-liners, with a note on why the page width sets your cap height rather than the box you ask for
Standalone generator scripts in examples/, each printing a stroke list you
can hand to draw_paths:
layered_landscape.py— generateslayered_landscape.jsonflowing_walker.py— generatesflowing_walker.jsonharmonograph.py— damped Lissajous figure, one unbroken stroke. The machine's best case.stipple.py— tonal stippling by variable-radius Poisson samplingladybug_lines.py— line art with hatched fillsenvelope_art.py— draws the robot's own reachable envelope, plus a spiral into its centrepenhold.py— parks the arm for pen-height adjustmentcorner_speed.py— corner-sharpness test across the speed range
examples/raw_driver.py is a dependency-free 45-line driver, useful for poking the robot
directly: python3 examples/raw_driver.py star.
Development
src/lineus_mcp/
server.py MCP tools, resources and the instructions every agent reads
scene.py the scene language and its deterministic compiler
expr.py sandboxed expressions behind parametric curves
geometry.py ordering, fitting, splines, hatching
planner.py weld, explode at junctions, dedupe, chain, one line
occlude.py hidden-line removal
trace.py centerline tracing of line-art images
checks.py drawing checks that report where a drawing will fail
machine.py the envelope, the pen model, and the simulation of what it really draws
text.py single-line handwriting faces and Hershey fonts
doodles.py Quick, Draw!: the curated set, web fetch and cache
render.py the diagnostic and ink renders
robot.py the TCP link and background drawing jobs
config.py every setting
data/ fonts, doodles and example scenes, shipped inside the package
tests/ pytest: no robot, no network
examples/ standalone generator scripts and a raw driveruv sync # environment, with pytest and ruff
uv run pytest # 100 tests, a few seconds
uv run ruff check src tests examplesThe tests need neither the robot nor the network. The server runs in mock mode, the doodle web fetch is tested against a fake network, and one test starts the real server over stdio and talks to it with the MCP client, which catches anything that would corrupt the protocol stream. CI runs lint and the tests on Python 3.10 to 3.13.
Safety
Always preview before drawing.
Never expose port 1337 to the internet. There is no authentication.
Licence
MIT — see LICENSE.
Available Tools
17 toolsabortBDestructiveIdempotent
Stop the current drawing, lift the pen and go home.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, so the safety profile is covered by structured data. The description adds modest context (pen is lifted, session returns to a home state) but never says what is destroyed or whether the drawing is saved, which matters for a destructive tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence, front-loaded with the action. The vivid phrasing is memorable, though the metaphor slightly blurs rather than sharpens the meaning given the sibling 'home'.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters, no output schema, and annotations covering safety traits, the description needs only to convey consequences and timing. It conveys the immediate action but omits what happens to in-progress work and whether this returns the agent to a home state, leaving a real gap for a destructive tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is no parameter semantics for the description to explain. Baseline for a parameterless tool applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The verb 'Stop' plus the resource 'the current drawing' makes the core action identifiable, and 'lift the pen' reinforces the physical metaphor. However, 'go home' overlaps with the sibling tool named 'home', so the scope isn't perfectly disambiguated from its neighbors.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit guidance on when to call abort versus alternatives such as 'home' or simply not drawing. The phrase implies stopping an in-progress drawing but never states prerequisites, when-not-to-use, or the relationship to the sibling 'home' tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
doodlesARead-onlyIdempotent
Real doodles from Google's Quick, Draw! dataset (CC BY 4.0): single strokes, in the order a person drew them, so line width comes from the pen alone.
With no category: the curated categories bundled with the server, and every category that can be fetched from the web (345 in all). With a category: a NUMBERED CONTACT SHEET of candidates. Look at it and choose a pick, then use {"doodle": category, "pick": N, "box": [x,y,w,h]} in a scene.
source: "auto" (default) uses the curated set if the category has one, else fetches from the web; "web" always fetches -- more variety, NO human review; "bundled" never goes online. Fetched categories are cached on disk, which keeps preview and draw identical. Web candidates are ranked automatically but many are still scribbles or have the word written in them: that is what the contact sheet is for. Draw with order="asis" to replay a doodle exactly as its author drew it.
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | ||
| start | No | ||
| source | No | auto | |
| category | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint and destructiveHint=false. The description adds real behavior beyond that: fetched categories are cached on disk so preview and draw match, web candidates are auto-ranked but many are scribbles or contain written words, and the contact sheet exists precisely because of that unreliability. It omits any statement about rate limits or failure modes when the web fetch fails.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The content is front-loaded and organized into readable blocks, but it strays into instructions for other tools' parameters — the inline {"doodle": category, "pick": N, "box": [...]} object and order="asis" do not exist in this schema, so that text does not earn its place in this definition and risks confusing the agent about what to pass here.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description reasonably explains what comes back (a category list, or a numbered contact sheet of candidates) and why. Combined with the annotations covering safety and the open-world nature, an agent has enough to call it correctly, with only count/start left unexplained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden. It explains 'source' (auto/web/bundled semantics) and 'category' (present vs absent behavior) thoroughly, but 'count' and 'start' are never mentioned, leaving their pagination meaning entirely undocumented. Partial compensation only.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource (real doodles from Google's Quick, Draw! dataset) and explains two distinct modes: no-category returns the bundled/web category list, and with-category returns a numbered contact sheet. It does not explicitly contrast itself against siblings like preview_paths or draw_paths, but the resource is unique enough that an agent can distinguish it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear conditions: use no category to see what's available, supply a category to get a contact sheet and choose a pick, and it spells out the source tradeoffs ('auto' curated-first, 'web' always fetches with more variety but no human review, 'bundled' never goes online). It stops short of naming sibling tools as alternatives for the actual drawing step, so it is clear context without explicit routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_orientation_testA
Draws a frame around the canvas plus an 'F' in the top-left corner so a human can confirm the canvas orientation (F must read normally, top-left).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=false and destructiveHint=false, so the agent knows this mutates canvas state. The description usefully adds what is drawn and how to interpret the result, but says nothing about whether existing canvas content is preserved or cleared, or whether a canvas must exist first — meaningful gaps for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that front-loads the action and the artifact, then gives the interpretation rule. No filler, nothing repeated from annotations or schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so by explaining that the result is a visual frame plus 'F' a human reads. For a zero-parameter diagnostic tool whose annotations cover the safety profile this is nearly complete, missing only the effect on pre-existing canvas content.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate and the baseline is 4. The description correctly describes a no-argument action.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (draws) plus the exact artifact produced (a frame around the canvas and an 'F' in the top-left corner), which is a purpose no sibling tool shares — draw_paths, draw_svg, draw_text and draw_scene all render user content, not a diagnostic overlay. An agent can identify this tool without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The clause 'so a human can confirm the canvas orientation' gives clear context for when this tool is appropriate, and the parenthetical 'F must read normally, top-left' states the success condition. It stops short of naming alternatives or exclusions (e.g. use preview_* to check content without mutating the canvas), so it is clear context rather than full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_pathsA
Draw polylines given in canvas millimetres: [[ [u,v], [u,v], ... ], ...]. Each inner list is one pen-down stroke. Returns a job_id. speed: G94 S, the max step size for PEN-DOWN moves (1 finest/slowest .. 30 coarsest/fastest, default 5). Not a speed dial: it is interpolation granularity. Pen-UP travel is G94 P, set by LINEUS_TRAVEL_SPEED. order: how strokes are sequenced. "human" (default) top row first, left to right within a row, never reversed. Looks like a person drawing. Costs more pen-up travel (~2.8x on text) but this machine is slow enough that it rarely matters. "fast" nearest-neighbour, may draw a stroke backwards. Least travel, but it hops between rows and looks chaotic to watch. "asis" exactly the order supplied, untouched — you control the sequence.
| Name | Required | Description | Default |
|---|---|---|---|
| order | No | human | |
| paths | Yes | ||
| speed | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (which only mark it non-read-only, non-idempotent, open-world), the description discloses that it returns a job_id (async job model), clarifies that speed is interpolation granularity rather than a speed dial, and reveals that pen-up travel is governed by the external LINEUS_TRAVEL_SPEED setting. These are meaningful behavioral facts an agent cannot infer from annotations or schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Content is front-loaded with the core call contract (paths format, return value) before the parameter detail, and the nested order explanations are indented and scannable. It runs long on the order tradeoffs, but nearly every clause carries decision-relevant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet the description states the return value (job_id) and explains the async job model. Combined with full parameter documentation and the external travel-speed caveat, an agent has everything needed to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage and 3 parameters, the description carries the full load: it documents the paths structure precisely, gives speed's valid range (1–30) and default (5), and enumerates the three order values with their sequencing semantics. This is exactly the compensation needed for an undocumented schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource — 'Draw polylines given in canvas millimetres' — and pins the exact input shape ([[u,v],...] with each inner list a pen-down stroke). This clearly separates it from siblings like draw_svg, draw_text, and draw_scene that take different input formats.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete guidance for the 'order' parameter, explaining when each mode is appropriate ('human' for natural-looking output, 'fast' for least travel, 'asis' when the caller controls sequencing). It never names or excludes the sibling preview_paths, so there is no explicit when-not or alternative-tool routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_sceneA
Draw a declarative scene (same object as preview_scene -- see it for the shape language). Compilation is deterministic and content-hashed, so passing the scene you previewed draws exactly what you saw. Returns a job_id and the scene_id.
| Name | Required | Description | Default |
|---|---|---|---|
| order | No | human | |
| scene | Yes | ||
| speed | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare a non-read-only, open-world, non-idempotent, non-destructive write. The description adds genuinely new behavior: compilation is deterministic and content-hashed (so previewed output is reproduced exactly) and the call returns a job_id and scene_id, signaling async job semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: purpose, the determinism guarantee, and the return contract. Nothing is redundant and the differentiating information (see preview_scene) is front-loaded in the first sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool the annotations carry the safety profile and the description names the return values, which is good. But with a nested scene object at 0% schema coverage and unexplained 'order'/'speed' parameters, an agent lacks the argument-level detail needed to invoke it confidently.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across three parameters (order, scene, speed). The description points to preview_scene for the shape language of 'scene', which is useful, but 'order' and 'speed' receive no explanation anywhere, so the description does not compensate for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('draw a declarative scene') and explicitly ties it to its sibling by noting the scene object is the same as preview_scene, so the agent can separate 'draw' from 'preview' and from draw_paths/draw_svg/draw_text without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies a clear workflow: pass the scene you previewed and it draws exactly what you saw, which routes the agent through preview_scene first. It does not explicitly state when to choose this over draw_paths, draw_svg, or draw_text, so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_svgA
Draw an SVG fitted into box (x,y,w,h) in canvas mm, aspect ratio kept. Line art works best; fills are not hatched. Returns a job_id.
| Name | Required | Description | Default |
|---|---|---|---|
| h | No | ||
| w | No | ||
| x | No | ||
| y | No | ||
| svg | Yes | ||
| order | No | human | |
| speed | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, non-idempotent, open-world, non-destructive, so the mutation profile is covered. The description adds real value beyond them: the coordinate box in canvas mm, aspect-ratio preservation, the fill/hatching limitation, and the asynchronous 'Returns a job_id' contract.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences with the core action, sizing semantics, and return value front-loaded; no filler and every clause is actionable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the essential action, units, aspect ratio, content suitability, and async return. With 7 undocumented params and no output schema, gaps remain around 'order', 'speed', and how to retrieve the resulting job, which sibling tools like get_job would address.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the burden. It meaningfully explains the x/y/w/h box and aspect-ratio behavior, but leaves 'order' (default 'human'), 'speed', and the 'svg' payload itself completely unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Draw an SVG') and adds the sizing semantics (fitted into box in canvas mm, aspect ratio kept). It clearly implies a physical/plotted output versus the sibling preview_svg, but it never names an alternative to fully disambiguate the pair.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Offers content-level guidance ('Line art works best; fills are not hatched'), which helps an agent choose suitable input. However, it gives no explicit when-to-use condition and never distinguishes itself from the sibling preview_svg or explains when to prepare a scene instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_textA
Write text with a single-stroke Hershey font fitted into box (x,y,w,h) mm.
Prefer the handwriting faces: print neutral/architect, cursive italienne/
cursive2 (these weld into one stroke per word). See list_fonts(). For multi-line or
MULTI-FONT text prefer a scene: draw_scene puts several fonts and alignment in one call.
speed: G94 S, max step size for pen-down moves, 1 (finest) .. 30 (coarsest).
| Name | Required | Description | Default |
|---|---|---|---|
| h | No | ||
| w | No | ||
| x | No | ||
| y | No | ||
| font | No | futural | |
| text | Yes | ||
| order | No | human | |
| speed | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the safety profile (readOnly=false, destructive=false, openWorld=true, idempotent=false), so the bar is lower. The description adds real behavioral detail (fonts weld into one stroke per word; speed controls pen-down step size), but says nothing about physical-plotter side effects, connection/auth requirements, or what happens to prior output.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core action, then layers font advice, the scene alternative, and speed semantics. Dense but ordered; a couple of clauses (e.g. the G94 aside) are jargon-heavy for the value they add.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter tool with 0% schema coverage and no output schema, the description covers purpose, fonts, an alternative, and speed, but leaves order semantics and the auto-fit behavior of null w/h unexplained. Adequate but with clear gaps given the complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It clarifies the box coordinates (x,y,w,h in mm) and the speed parameter ('G94 S, max step size for pen-down moves, 1..30'), and names good font values, but leaves `order` (default 'human') and the null w/h behavior entirely undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Write text with a single-stroke Hershey font') plus the operating constraint ('fitted into box (x,y,w,h) mm'). It also names the sibling alternatives (list_fonts, draw_scene), so an agent can distinguish this from preview_text/draw_scene without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete guidance: prefer handwriting faces for specific looks, and 'For multi-line or MULTI-FONT text prefer a scene: draw_scene' names the alternative and the condition that selects it. It stops short of explicit when-not-to-use exclusions, but the routing advice is actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_exampleARead-onlyIdempotent
Worked example scenes: finished drawings that went through several rounds of critique on this machine. With no name, lists them. With a name, returns the scene -- pass it to preview_scene as-is, or modify it ("the cat, lying down") rather than starting from nothing. Each carries a _comment explaining what made it work.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive), and the description adds useful behavior beyond that: the dual list/return mode and the fact that each scene carries a _comment explaining what made it work. No auth, rate-limit, or pagination details are given.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the resource and its dual behavior, then the workflow hint. The sentences are a little run-on with parenthetical asides, but each carries weight and nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-optional-parameter tool with no output schema, the description covers purpose, both invocation modes, the return content (_comment), and the follow-up workflow. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the parameter meaning, and it does: empty name lists, a name returns the scene. It even illustrates how to modify a returned scene. That compensates well for the undocumented `name` parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (worked example scenes) and a clear dual-mode behavior: no name lists them, a name returns the scene. It also names a sibling (preview_scene) as the downstream consumer, so an agent can place it in the workflow without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context for use: pull an example to preview as-is or to modify rather than starting from nothing, which is a genuine routing hint. It does not, however, state when to avoid this tool or contrast it with siblings like doodles or plan_scene.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_jobCRead-onlyIdempotent
Progress of a drawing job.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and safe non-destructive behavior. The description adds nothing beyond the annotation title 'Drawing progress'—no return format, polling advice, or auth needs are disclosed. Minimal added value beyond structured metadata.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single short phrase with no waste, but it is arguably too terse to be useful; it is front-loaded but lacks a clear action verb and structure. Not wasteful, but not well-structured for an agent to parse action and intent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read tool with no output schema, the description should explain what 'progress' entails (e.g., status, percentage) and how to obtain job_id. It omits both, leaving key context missing and relying entirely on annotations and the parameter name.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description does not mention the required job_id parameter at all. It fails to clarify format, source, or constraints, leaving the single parameter undocumented beyond its self-explanatory name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Progress of a drawing job' implies the tool retrieves job progress, but uses a noun phrase with no explicit verb and does not differentiate from sibling 'get_status' which could also report status of an entity. It identifies the resource but lacks specificity about the action and scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives like get_status or preview tools. It provides no context about prerequisites, polling behavior, or conditions for calling, leaving the agent to infer usage entirely.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_statusARead-onlyIdempotent
Robot firmware banner, canvas size in mm, and current/last job.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so safety and repeat-call behavior are covered. The description adds real value by disclosing what the response contains (firmware banner, canvas size in mm, job info), which the annotations do not.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence listing the three returned artifacts, with zero filler or repetition of the tool name. Nothing could be cut without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no parameters, the description carries the burden of telling the agent what comes back, and it does so for three of the likely fields. It stops short of full completeness because it doesn't indicate whether the payload is a fixed shape or what 'last job' means relative to get_job.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so per the rubric the baseline is 4; there is nothing for the description to disambiguate. No parameter-level claims are made or needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the concrete payload (firmware banner, canvas size in mm, current/last job), which makes the tool's scope identifiable at a glance. It does not explicitly differentiate itself from the sibling get_job, even though 'current/last job' overlaps with that tool's territory, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to call this versus the alternatives; a reader must infer that this is the general status snapshot and get_job is the per-job detail call. No prerequisites or exclusions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
homeAIdempotent
Lift the pen and move the arm to its home position.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the mutation/idempotent/non-destructive profile, so the safety burden is covered. The description adds one useful behavioral detail (the pen is lifted, so homing won't drag the pen across the work), but says nothing about whether the call blocks, how long it takes, or any connection prerequisites.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single compact sentence with the key action front-loaded. Every word earns its place and nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter action tool with no output schema, the description covers what the tool physically does. The main gap is the absence of any indication of when the agent should invoke it or what happens on completion, but the operation is simple enough that little more is strictly required.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters and 100% schema coverage, so the baseline is 4. There is no parameter meaning the description could or should add.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (lift) and physical resource (the arm to its home position), which is distinctive against drawing siblings like draw_paths and preview_svg. It does not explicitly name an alternative, but the homing action is self-evidently distinct.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description never says when to call this tool, under what conditions the arm should be homed, or how it relates to siblings like abort or draw_paths. Usage must be inferred entirely from the action itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_fontsARead-onlyIdempotent
Every typeface available to text, draw_text and a scene's "text" producer.
Two families, and the difference matters on paper:
HANDWRITING (fonts/, SIL OFL) -- real single-line handwriting faces, print and
cursive. Each letter is drawn ONCE. Prefer these.
HERSHEY -- the classic 1967 engraving set, kept for compatibility. Its bold and serif
faces fake weight by RETRACING every stem (a capital H in rowmant is 27 strokes),
which on a pen plotter reads as a scribble. Pass include_hershey=true to list them.
Three measurements decide whether a face works here, and they catch different
failures -- all three were learned the hard way on paper:
passes strokes per letter vs a human's. Catches retracing.
aperture the width of a letter's opening (the gap in s/a/e/o/g) against the 1-2 mm
the firmware's corner blending eats. Catches letters that close into blobs:
brush at 0.89 mm turned "oo" into "rr" on the test sheet.
joins for cursive, whether letters weld into one continuous stroke per word.
| Name | Required | Description | Default |
|---|---|---|---|
| include_hershey | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, idempotent, non-destructive, closed-world), so the bar is lower, and the description adds real context: the two families, the license note for fonts/ (SIL OFL), and the three measurements (passes, aperture, joins) that appear in the results. It stops short of describing the literal return format or field order, but the semantic behavior is well disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded with the purpose sentence and organized into labeled blocks, which helps. But for a simple listing tool it is verbose, spending many lines on illustrative lore (a capital H in rowmant is 27 strokes; brush at 0.89 mm) that informs font choice rather than tool invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of describing results, and it does so semantically by naming the families and the three decision measurements an agent will see. Pagination, counts, or exact returned fields are not covered, but the agent has enough to call and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry the parameter, and it does: it explains what include_hershey=true does (list the legacy Hershey faces) and pairs that with a concrete reason to avoid it. The default is left to the schema, which is fine.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states the resource (typefaces/fonts) and ties it to the consuming tools (text, draw_text, a scene's "text" producer), so the agent knows this is the discovery step before drawing text. It is clear but does not explicitly differentiate itself from siblings like preview_text or get_example beyond the font-listing scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Guidance is implied rather than explicit: it says handwriting faces are preferred and that include_hershey=true reveals the legacy set, which is useful selection advice. However, it never states plainly when to call this tool (e.g., before draw_text to discover valid font names) or why not to use include_hershey by default beyond the scribble warning.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plan_sceneARead-onlyIdempotent
Compile a scene and report what it would cost, WITHOUT drawing or rendering: stroke/point counts, bounding box, pen-up travel and any warnings.
| Name | Required | Description | Default |
|---|---|---|---|
| scene | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false, so safety is covered. The description adds valuable behavioral context beyond the annotations: it clarifies that the tool compiles and reports cost without drawing or rendering, and it lists the exact output contents (counts, bounding box, travel, warnings).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no wasted words. The key constraint (no drawing/rendering) and the reported outputs are packed efficiently using a colon list.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description adequately covers the tool's purpose and output content even without an output schema, and annotations cover safety. However, the input scene parameter is a nested object with no schema description and the description provides no structural guidance, leaving a notable gap for an agent trying to construct a valid call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is one required parameter named 'scene' with 0% schema description coverage and a nested object type, yet the description only repeats the word 'scene' from the tool name. No details about the scene structure, format, or required fields are provided, so it does not compensate for the schema's lack of parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the specific verb 'Compile' and resource 'scene', and explicitly distinguishes the operation from drawing/rendering siblings with 'WITHOUT drawing or rendering'. It also names the reported outputs (stroke/point counts, bounding box, pen-up travel, warnings), so an agent can tell it apart from draw_scene and preview_scene without opening the schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by saying it compiles and reports cost without drawing or rendering, which helps avoid using it when actual drawing is needed. However, it does not explicitly state when to choose this tool over siblings like preview_scene or draw_scene, nor does it name alternatives or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
preview_pathsARead-onlyIdempotent
Render polylines (canvas mm, [[ [u,v], ... ], ...]) without drawing. Returns the diagnostic view (pink = pen-up travel, grey box = page) and, with simulate=true (default), what the arm will actually put on paper.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | Yes | ||
| simulate | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive, and closed-world behavior. The description adds genuine value beyond them: it discloses what is returned (diagnostic view with pink pen-up travel, grey page box) and that simulate=true is the default that shows what the arm will actually draw.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core action and format before the return-value detail. Every clause earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description correctly explains the return (diagnostic view and simulation). It is sufficient for a read-only preview tool, though it omits details like units per segment beyond 'canvas mm' and whether the view is returned as an image or structure.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry parameter meaning, and it does: it documents the nested paths format ('canvas mm, [[[u,v], ...], ...]') and explains that simulate (default true) controls whether the simulated on-paper result is shown. This compensates well for the empty schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (render/preview polylines) and clarifies scope with 'without drawing', which distinguishes it from the draw_* siblings. The input format is also given inline. It stops short of naming the draw_paths alternative explicitly, but the intent is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Without drawing' implies this is the preview counterpart to draw_paths, so usage is inferable. However, there is no explicit when-to-use/when-not guidance or named alternative, leaving the agent to infer the preview-vs-draw choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
preview_sceneARead-onlyIdempotent
Render a declarative SCENE as a PNG without drawing. Prefer this over preview_paths: a scene is ~50x smaller than the coordinates it compiles to, and draw_scene given the SAME scene provably draws what you previewed.
scene = {"shapes": [ ...shape... ], "fit": [x,y,w,h] (optional, scales the lot)}
There is deliberately NO library of shapes -- a fixed catalogue would handle the
dull cases and send everything interesting back to pasting raw points. Curves are
EXPRESSIONS, so the vocabulary is open:
{"param": {"t": [0, 6.2832, 200],
"x": "33+5.5*cos(t)", "y": "30+5.5*sin(t)", "closed": true}}
is a circle; change the expressions and it is a spiral, rose, lissajous or
harmonograph. Variables: t, plus i and n inside "repeat". Functions: sin cos tan
asin acos atan atan2 sinh cosh tanh exp log sqrt hypot floor ceil fmod degrees
radians abs min max round pow sign clamp lerp; constants pi, tau, e.
Producers (exactly one per shape):
"param" {"t":[start,stop,steps], "x":expr, "y":expr, "closed":bool}
"path" [[u,v], ...] one stroke, the escape hatch
"paths" [[[u,v], ...], ...] several strokes
"text" "a
b", or [{"s":"a","font":"timesr"}, {"s":"b","font":"scriptc"}] with "font", "align" (left|center|right), "leading" (default 1.4) "svg" "..." "doodle" "cat", with "pick" (index), "source" (auto|bundled|web) -- real drawings from Google's Quick, Draw!, single strokes in the order a person drew them. Call doodles() first to SEE the candidates and choose a pick. Modifiers (any producer): "fill" {"hatch":deg, "spacing":mm (default 1.15), "cross":bool, "outline":bool} -- hatching is how you get solid black here "transform" {"translate":[dx,dy], "rotate":deg, "scale":s|[sx,sy], "about":[x,y]} "box"/"fit" [x,y,w,h] scale this shape into a box "repeat" N, with i (0..N-1) and n available in the expressions
| Name | Required | Description | Default |
|---|---|---|---|
| scene | Yes | ||
| simulate | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, but the description adds a genuine behavioral guarantee not in the annotations: the preview is a faithful stand-in for draw_scene output, and no drawing occurs. It also discloses the 'exactly one producer per shape' constraint. It does not explain the simulate flag or return delivery, so not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and routing, then organized into producers/modifiers blocks that are easy to scan. It is long, and a couple of sentences (e.g. the rationale for having no shape catalogue) are more justification than instruction, but for a DSL this length is largely earned.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description carries return-value burden; 'Render ... as a PNG' states the artifact type but not how the image is delivered. The DSL surface is otherwise thoroughly specified. The undocumented 'simulate' flag is the main remaining hole.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the scene object is undocumented in the schema, so the description must compensate — and it does so exhaustively, enumerating producers, modifiers, variables, functions, and constants with examples. However, the second parameter 'simulate' (default true) is never mentioned anywhere, leaving a real gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Render a declarative SCENE as a PNG without drawing') and immediately distinguishes itself from siblings preview_paths and draw_scene. An agent knows exactly what this does and how it differs from the drawing tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Prefer this over preview_paths', gives the reason (scene ~50x smaller than compiled coordinates), and ties it to draw_scene ('draw_scene given the SAME scene provably draws what you previewed'). It also routes to doodles() first for doodle picks. Clear when-to-use and named alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
preview_svgARead-onlyIdempotent
Render an SVG (paths/shapes, strokes only — fills are ignored) fitted into the box (x,y,w,h) in canvas mm (default: whole canvas). Returns a PNG.
| Name | Required | Description | Default |
|---|---|---|---|
| h | No | ||
| w | No | ||
| x | No | ||
| y | No | ||
| svg | Yes | ||
| simulate | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, so the safety profile is covered. The description adds real behavioral context beyond that: fills are ignored (strokes only), coordinates are in canvas mm, and the box defaults to the whole canvas. It omits any mention of what the simulate flag does.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single compact sentence with no waste, front-loading the render action and the strokes-only constraint. It could be shorter only by dropping genuinely useful detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With readOnly/idempotent annotations and no output schema, the description correctly states the PNG return, so return handling is fine. However, the simulate parameter (default true) is never explained, and the svg input format is unspecified, leaving gaps an agent must guess at for a 6-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry parameter meaning. It documents x,y,w,h as a fit box in canvas mm with a whole-canvas default, but says nothing about the required svg string's expected format or the simulate parameter at all, leaving two of six parameters uninterpretable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ("Render") and resource (SVG, paths/shapes) and declares the output (PNG), so the agent knows exactly what it produces. It does not explicitly distinguish itself from the sibling draw_svg, but the "preview" framing is implied by the render-only nature.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: rendering rather than committing, and returning a PNG, suggests a non-side-effecting preview as opposed to draw_svg. There is no explicit when-to-use/when-not statement or named alternative, leaving the agent to infer the preview-vs-draw split from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
preview_textARead-onlyIdempotent
Render single-stroke (Hershey) text fitted into box (x,y,w,h) mm. Use \n for new lines. Prefer the HANDWRITING faces -- print: neutral architect pancakes delight casual; cursive (welded, one stroke per word): italienne cursive2 brush allure. call list_fonts() for the measurements. Hershey names still work but most of them retrace every stem.
| Name | Required | Description | Default |
|---|---|---|---|
| h | No | ||
| w | No | ||
| x | No | ||
| y | No | ||
| font | No | futural | |
| text | Yes | ||
| simulate | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly/idempotent/non-destructive, so the bar is lower. The description adds real context beyond that: box-fitting in mm, '\n' newline semantics, and the caveat that most Hershey names retrace every stem. It stops short of saying what the preview output actually looks like.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core operation, then the operational details. The font enumeration is somewhat long but is high-value content rather than filler, so waste is minimal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Adequate for a preview tool with no output schema, but incomplete: 7 parameters at 0% schema coverage means the description should clarify at least simulate and the optional box coordinates, and it does neither. An agent still has open questions about what the call returns.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description carries the burden, and it does explain the box semantics (x,y,w,h in mm) and newline handling for text. However, font is only hinted at via face names, and the defaulted simulate flag plus the null-default nature of x/y/w/h are never explained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ("Render single-stroke (Hershey) text fitted into box") and clarifies units (mm) and newline handling. It does not, however, distinguish itself from the sibling draw_text, leaving the preview-vs-draw distinction to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete guidance on font selection (prefer handwriting faces, with named examples) and points to list_fonts() for measurements, which is useful. But it never says when to choose preview_text over the sibling draw_text or preview_svg, and the simulate parameter's role is left unaddressed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
17 tool updates
v0.1.0- First observed
abort - First observed
doodles - First observed
draw_orientation_test - First observed
draw_paths - First observed
draw_scene - First observed
draw_svg - First observed
draw_text - First observed
get_example - First observed
get_job - First observed
get_status - First observed
home - First observed
list_fonts - First observed
plan_scene - First observed
preview_paths - First observed
preview_scene - First observed
preview_svg - First observed
preview_text
TDQS
Scored across 17 tools
The preview_*/draw_* pairing gives each tool a clear render-vs-execute role, and distinct modalities (paths, svg, text, scene) separate the rest. Some overlap remains: preview_scene explicitly supersedes preview_paths and its text producer overlaps preview_text/draw_text, but the descriptions steer the agent well.
The dominant pattern is verb_noun (get_status, get_job, preview_paths, draw_scene, plan_scene, list_fonts, get_example). A few deviate (bare 'abort', 'home', and the noun 'doodles'), but overall it is predictable and readable.
17 tools is on the heavier side but each preview/draw pair and helper (plan_scene, list_fonts, get_example, doodles) earns its place. Nothing feels redundant or padded.
Strong lifecycle coverage: status/job monitoring, abort/home, orientation calibration, four input modalities with preview and execute, plus cost planning, font enumeration, examples, and doodle sourcing. Minor gaps like explicit queue management or pen/feed control are easy to work around.
Maintenance
Related MCP Connectors
Persistent memory, hybrid search and a goal graph for AI agents, over stdio or remote HTTP.
Deterministic reasoning stack for AI agents: simulate, decide & compute, plus cross-domain tools.
AI agent draws editable hand-drawn diagrams (flowchart, ER, architecture) via MCP, not static images
- OwlCADOAuthcom.owlcad
Parametric 3D CAD for AI agents: build print-ready parts, check them, export STL, 3MF or STEP.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceMCP server that lets AI agents drive Inkscape — interactively alongside the GUI or headlessly from the CLI259 PyPI76MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that gives AI agents eyes and a robotic arm to compose and iterate generative art on an AxiDraw pen plotter via webcam feedback.1AGPL 3.0
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to control pen plotters via MCP tools for text layout, SVG/DXF import, G-code generation, device control, and vision calibration.9-

Rayzia MCPofficial
AlicenseNot gradedqualityCmaintenanceEnables AI agents to drive a live SVG/vector editor, allowing a full observe-and-act loop on a canvas with real tools, state reading, and PNG rendering.1MIT