Skip to main content
Glama

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 draws

What it does

Tool

Purpose

preview_scene / draw_scene

The main interface. A declarative scene, compiled to strokes server-side

plan_scene

Stroke/point counts, bounding box, travel and warnings — without drawing or rendering

list_fonts

The handwriting faces, with the measurements that say which will survive

get_example

Finished drawings to start from instead of a blank page (also as lineus://examples resources)

doodles

Real doodles from Google's Quick, Draw!: browse a numbered contact sheet, then pick one

preview_paths / preview_svg / preview_text

Render a PNG of what would be drawn — no movement

draw_paths

Polylines in millimetres: [[[u,v], [u,v], ...], ...] — the escape hatch

draw_svg

SVG line art fitted into a box (strokes only; fills are not hatched)

draw_text

A single line or block of single-stroke text

get_status

Firmware banner, diagnostics, page size, reachable envelope, last job

get_job / abort / home

Async job control

draw_orientation_test

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 join, so every shared edge doubles

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

one_line bridging several separate pieces, which reads as glue

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

param

{"t": [start, stop, steps], "x": expr, "y": expr, "closed": bool}

text

a string, or a list of {"s", "font"} for multi-font blocks

path / paths

raw points, the escape hatch

svg

imported line art

doodle

"cat" with pick and source — a real drawing from Quick, Draw!, see below

trace

a line-art image traced along the centre of each line, see below

modifier

smooth

true, or samples per span — centripetal Catmull-Rom through the control points

closed

close the path before smoothing

fill

{"hatch": deg, "spacing": mm, "cross": bool} — how you get solid black here

transform

translate, rotate, scale, about

box / fit

scale this shape into [x, y, w, h]

repeat

N, exposing i and n to the expressions

opaque

false to stop this shape hiding anything when the scene occludes

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:

  1. 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.

  2. 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.

  3. Detail as open strokes. A fold, a crease, an elbow or a knee is one short line, not a closed outline.

  4. Lines stop. They end just short of the line they meet, and where something passes in front of them.

  5. 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}}

explode

break polylines into segments first, so shared edges become visible

dedupe

drop segments already drawn — on by default

chain

join strokes that meet into the fewest continuous trails

one_line

bridge every trail into a single unbroken stroke

weld

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

print

neutral architect pancakes delight casual

cursive

italienne cursive2 brush allure

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: uvx

  • args: --from git+https://github.com/BenTeoNeb/lineus-mcp lineus-mcp

  • env: 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-mcp

Claude 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

LINEUS_HOST

line-us.local

Hostname or IP. Use the IP if mDNS is unreliable.

LINEUS_MOCK

unset

1 to run without hardware

LINEUS_SPEED

5

Default G94 speed, 2 (slow, sharp) … 30 (fast, rounded)

LINEUS_MIN_SPEED

2

Floor. Speed 1 can wedge the firmware — see below

LINEUS_TIMEOUT

180

Socket timeout in seconds

LINEUS_TRAVEL_SPEED

30

G94 P, pen-up step size. Proven not to affect mark quality, so it is pure throughput

LINEUS_PEN_DOWN_Z

300

How far down the pen goes. Not 0 — see the landing smear below

LINEUS_PREVIEW

~/.cache/lineus-mcp/preview.png

Where the simulated preview is written

LINEUS_NIB_MM

0.5

Nib width for that preview. Set it when you change pens

LINEUS_JOIN_EM

0.13

How close a cursive letter's exit must be to the next letter's entry to weld

LINEUS_BLEND_MM

1.5

Corner-blending window used by the simulated preview

LINEUS_TICK_MM

0.5

Simulated stroke-end tick at radius 1500 units; scales with reach

LINEUS_CACHE

~/.cache/lineus-mcp

Where fetched doodles are cached

LINEUS_QD_BYTES

600000

How much of a Quick, Draw! category file to read when fetching

LINEUS_SWAP / LINEUS_FLIP_U / LINEUS_FLIP_V

1/0/0

Orientation fixes

LINEUS_R_MAX / LINEUS_R_MIN / LINEUS_X_MIN

1850/650/650

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 glue

  • geometric_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 twice

  • layered_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 through

  • flowing_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 image

  • text_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 — generates layered_landscape.json

  • flowing_walker.py — generates flowing_walker.json

  • harmonograph.py — damped Lissajous figure, one unbroken stroke. The machine's best case.

  • stipple.py — tonal stippling by variable-radius Poisson sampling

  • ladybug_lines.py — line art with hatched fills

  • envelope_art.py — draws the robot's own reachable envelope, plus a spiral into its centre

  • penhold.py — parks the arm for pen-height adjustment

  • corner_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 driver
uv sync                                  # environment, with pytest and ruff
uv run pytest                            # 100 tests, a few seconds
uv run ruff check src tests examples

The 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 tools
abortB
DestructiveIdempotent

Stop the current drawing, lift the pen and go home.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.3/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

doodlesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
countNo
startNo
sourceNoauto
categoryNo

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness3/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
orderNohuman
pathsYes
speedNo

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
orderNohuman
sceneYes
speedNo

TDQS

A4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
hNo
wNo
xNo
yNo
svgYes
orderNohuman
speedNo

TDQS

A3.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
hNo
wNo
xNo
yNo
fontNofutural
textYes
orderNohuman
speedNo

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_exampleA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNo

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_jobC
Read-onlyIdempotent

Progress of a drawing job.

ParametersJSON Schema
NameRequiredDescriptionDefault
job_idYes

TDQS

C2.4/5.0
Behavior2/5

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.

Conciseness3/5

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.

Completeness2/5

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.

Parameters2/5

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.

Purpose3/5

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.

Usage Guidelines2/5

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_statusA
Read-onlyIdempotent

Robot firmware banner, canvas size in mm, and current/last job.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

homeA
Idempotent

Lift the pen and move the arm to its home position.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.5/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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_fontsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
include_hersheyNo

TDQS

A3.7/5.0
Behavior4/5

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.

Conciseness3/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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_sceneA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
sceneYes

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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_pathsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathsYes
simulateNo

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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_sceneA
Read-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

ParametersJSON Schema
NameRequiredDescriptionDefault
sceneYes
simulateNo

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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_svgA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
hNo
wNo
xNo
yNo
svgYes
simulateNo

TDQS

A3.6/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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_textA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
hNo
wNo
xNo
yNo
fontNofutural
textYes
simulateNo

TDQS

A3.6/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

  1. 17 tool updatesv0.1.0
    • First observedabort
    • First observeddoodles
    • First observeddraw_orientation_test
    • First observeddraw_paths
    • First observeddraw_scene
    • First observeddraw_svg
    • First observeddraw_text
    • First observedget_example
    • First observedget_job
    • First observedget_status
    • First observedhome
    • First observedlist_fonts
    • First observedplan_scene
    • First observedpreview_paths
    • First observedpreview_scene
    • First observedpreview_svg
    • First observedpreview_text

TDQS

B3.4/5.0

Scored across 17 tools

Disambiguation4/5

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.

Naming Consistency4/5

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.

Tool Count4/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to control pen plotters via MCP tools for text layout, SVG/DXF import, G-code generation, device control, and vision calibration.
    9
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables 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.
    1
    MIT