Font Design MCP
Font Design MCP is a local MCP server for AI-assisted type design that manages UFO-based font projects, enables atomic, validated edits, and builds real font files.
Create, open, inspect, and restore UFO font projects with metadata, metrics, revision history, and integrity checks.
Read and edit glyph outlines, components, anchors, advances, bounds, and bearings in font units using typed vector operations and drawing primitives.
Adjust spacing and kerning groups/values; outlines move with bearings.
Edit font-level metadata such as naming, copyright, license text, and other technical properties.
Configure variable-font axes, clone masters within the same project, and select locations for rendering or building.
Render glyphs or text to PNG images via HarfBuzz shaping and FreeType/Pillow rasterization, with no system-font fallback.
Validate fonts: run technical checks, compile a TTF, inspect tables, and report corpus coverage and warnings.
Build real TTF and/or WOFF2 files from a frozen revision; variable fonts are exported automatically when axes are configured.
Work locally with the official MCP Python SDK, supporting Python 3.11/3.13, and demonstrate end-to-end workflows with the included example client.
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., "@Font Design MCPCreate a new font project, draw a bold rounded 'A' glyph, preview it, then export as TTF."
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.
Font Design MCP
Draw, inspect, refine, and build fonts through MCP.
A local MCP server for AI-assisted type design, from vector outlines to TTF and WOFF2.
English · Français
Get started · Connect a client · Report an issue
Get started
Version 0.6.0 adds regional stroke checks, interpolation diagnostics, persistent stroke constructions, and revision-bound visual release evidence. See the release notes and quality and release guide. Installation runs directly from GitHub, with automatic client detection. With Node.js 20+ and Git, run:
npx --yes github:Kydaix/Font-Design-MCPThe installer prepares uv and Python 3.13 if needed, installs the MCP in a persistent environment, detects Codex, Claude Code and Cursor, and asks which clients to configure. Restart those clients after installation. MCP tools belong to the client application and are available to its compatible models.
npx --yes github:Kydaix/Font-Design-MCP --clients codex cursor
npx --yes github:Kydaix/Font-Design-MCP --yes
npx --yes github:Kydaix/Font-Design-MCP --clients codex --dry-run--yes selects all detected clients; --clients explicitly selects one or more, including claude-code.
--workspace /absolute/path chooses where fonts are saved. --dry-run prepares the runtime but only
previews client changes. Existing configuration files receive a .font-design-<id>.bak backup before
atomic replacement. Other servers and existing per-server settings are preserved. Invalid configuration
files are refused. Re-running the command updates the installation without duplicating server entries.
An existing workspace is retained unless --workspace or FONT_DESIGN_MCP_WORKSPACE explicitly changes it.
Each install creates a separate runtime, so active servers do not block Windows updates.
Previous runtimes are retained for running clients and configuration backups.
The installed runtime survives removal of the npm cache. Remove its MCP entry in a client to disconnect it;
font projects remain in the workspace.
The MCP is distributed through GitHub, without publishing to PyPI or npm. Python dependencies still
download from their package index on first installation. Pin a checkout with github:Kydaix/Font-Design-MCP#v0.6.0.
For manual setup, font-design-mcp config prints JSON using the versioned GitHub release wheel;
config --from /absolute/path/package.whl uses a downloaded wheel. Neither command edits client files.
--workspace overrides FONT_DESIGN_MCP_WORKSPACE, which overrides the dedicated user-data default:
%LOCALAPPDATA%/font-design-mcp/workspace on Windows, ~/Library/Application Support/font-design-mcp/workspace
on macOS, $XDG_DATA_HOME/font-design-mcp/workspace (or ~/.local/share/...) on Linux.
The workspace stays outside UV's cache and survives upgrades or extension removal.
The MCPB extension targets hosts supporting the UV runtime in manifest 0.4.
Development from source
Clone the repository and install the dependencies with the commands below.
Run the diagnostic and demo to generate your first font specimen.
Connect your MCP client to start designing with an agent.
Requirements: Python 3.11–3.13, uv, and a GitHub account with access to this repository. Commands work in PowerShell and POSIX shells.
git clone https://github.com/Kydaix/font-design-mcp.git
cd font-design-mcp
uv sync --frozen --python 3.11
uv run --frozen font-design-mcp doctor
uv run --frozen python examples/demo.py --workspace ./workspacedoctor checks dependencies and rasterizes a PNG; doctor --build also compiles TTF and WOFF2. Font operations run locally after installation;
the server needs no model API key or proprietary editor. The client agent may use a remote model.
The demo launches a real STDIO server through the official MCP Python SDK. It draws A, V, O, Q, acute, and Á,
sets AV kerning to −80 units, moves A's apex, compares revisions, validates, and builds both export formats.
Each run creates a new project and prints the path to specimen.html. Open it directly in a browser.
Demo output | Contents |
| Read-only previews and links to the generated fonts; no web server needed |
| The MCP calls and their structured results |
| Project, revision, source, build, and validation references |
| UFO snapshots, PNGs, TTF/WOFF2, parameters, and hashes |
Generated workspaces stay local and are ignored by Git.
Related MCP server: FontLab MCP Server
Miette: a rounded typeface example
Miette Regular is an original, soft rounded font with 84 letters: uppercase and lowercase Latin, French accents, and æ/œ/Æ/Œ. Basic punctuation and spaces bring the total to 107 encoded characters. Its drawings, accent components, optical kerning, and complete MCP build recipe are included.

Download TTF · Download WOFF2 · Specimen and reproduction
Open examples/miette/specimen.html locally to type your own text, adjust its size, and compare kerning.
This first Regular style focuses on French letters; digits and additional styles are not included.
Connect a client
The MCP client launches the server process. Set an absolute interpreter path and an absolute workspace path in the client's configuration:
{
"mcpServers": {
"font-design": {
"command": "/absolute/path/font-design-mcp/.venv/bin/python",
"args": ["-m", "font_design_mcp", "serve", "--workspace", "/absolute/path/font-workspace"]
}
}
}On Windows, use C:/path/font-design-mcp/.venv/Scripts/python.exe for command and a Windows absolute path
for the workspace. The user sets this directory at launch; a tool call cannot expand it.
Add a block like this to your Codex configuration, adapting both paths:
[mcp_servers.font_design]
command = "/absolute/path/font-design-mcp/.venv/bin/python"
args = ["-m", "font_design_mcp", "serve", "--workspace", "/absolute/path/font-workspace"]
startup_timeout_sec = 20
tool_timeout_sec = 180The format follows the official Codex MCP documentation. The Windows example needs its installation-specific paths adjusted. The SDK client is tested end to end. Miette also exercised a live Codex MCP connection on Windows, including project creation, inspection, image previews, and font exports.
Windows / PowerShell:
.\.venv\Scripts\font-design-mcp.exe serve --workspace "$PWD\workspace"macOS / Linux:
.venv/bin/font-design-mcp serve --workspace "$PWD/workspace"The process waits for MCP messages on stdin. Stdout is reserved for JSON-RPC, so there is no startup banner. Logs go to stderr or captured compiler logs. Using the installed executable avoids dependency resolution at server startup. Normally, let the client start the process itself.
Image visibility depends on the client. Render tools return actual MCP image blocks, plus persistent paths, dimensions, hashes, and revisions. The client must forward those images to a model that can use them.
Design a font
The client agent makes the creative decisions; the server applies validated operations and keeps a revision history.
Step | What you can do |
Draw | Start with a brief and a few structural glyphs. Create lines, cubic and quadratic curves, counters, components, and anchors. |
Preview and refine | Inspect PNG previews with guides and handles. Move points by stable ID and compare revisions at the same sizes. |
Space and kern | Stabilize proportions, set side bearings, then adjust kerning. Test words with kerning on and off before extending the alphabet. |
Validate and export | Check geometry, coverage, and compilation. Build TTF and WOFF2 from a frozen revision. |
Record hypotheses and observed corrections in the project's decision journal.
The development version adds default outline diagnostics, perpendicular stroke/counter profiles and
revision-bound visual reviews. font_build defaults to a proof export; purpose="release" requires an
explicit review contract. See the quality and release workflow.
Every call names its project. Source edits require expected_revision; stale requests fail instead of
overwriting another edit. Points and handles have stable IDs, so a correction can be as small as:
{
"op": "move_point",
"point_id": "Aouter_1",
"x": 340,
"y": 720
}Pass this operation in glyph_edit.operations with the project ID, glyph ID, and current expected revision.
A successful edit returns the new revision and changed IDs. compare_revision on either render tool shows
two revisions under the same viewing conditions.
Technical validation and the agent's judgement are distinct from human approval. The server does not assign an artistic score or accept an agent-supplied claim of authenticated human approval.
Work from your own drawings
Import explicitly calibrated PNG references with reference_import, preserve their distinctive features,
and compare reconstructed outlines with render_glyph(reference_id=...). Use design_spec to retain
coverage and measurable style targets, font_analyze to find localized issues, and render_proof to compare
letters and digits at a common scale. Handle-preserving edits and optionally linked accents prevent
some local corrections from breaking related geometry.
This is controlled reconstruction and review, not automatic tracing or a guarantee of professional quality. See the reference-driven design workflow for calibration, examples, limits, optional export checks and schema-3 compatibility.
Available tools
The official MCP SDK publishes input and output schemas through tools/list. Responses include structured
data, readable summaries, revisions, warnings, and identifiable errors.
Tool | Purpose |
| Create a project with metadata, metrics, and an optional brief |
| Reopen a server-created project and verify its integrity |
| Read metadata, metrics, kerning, and a paginated glyph inventory |
| Update the brief, supported metadata, vertical metrics, or decision journal |
| Inspect contours, IDs, components, anchors, advance, bounds, and bearings |
| Apply a typed, atomic vector-editing batch to a glyph |
| Edit up to 128 glyphs and their spacing atomically in one revision |
| Set advances, side bearings, kerning pairs, and kerning groups |
| Render a glyph with optional guides, handles, and revision comparison |
| Compile, shape, and render text at multiple sizes |
| Import a calibrated PNG from workspace/inbox as an immutable drawing reference |
| Check visible ink, matching outlines, crossings, design coverage and declared metrics/profiles |
| Record an agent assessment of immutable proofs and intentional localized findings |
| Report missing measurements, glyph/text reviews and unresolved findings across masters |
| Compare multiple glyphs at a shared scale, optionally across revisions |
| Check geometry, Unicode coverage, compilation, and OpenType tables |
| Export static or variable TTF and/or WOFF2 from a frozen revision |
| Define continuous axes and clone/edit the project's master configuration |
| Browse committed revisions and change summaries |
| Restore an earlier state by creating a new revision |
Exact input and output schemas are available through MCP tools/list.
Inspection, glyph reads/edits, batch edits, validation, and renders default to
detail="summary". Use detail="full" for complete data, including point IDs before editing them;
render_text also accepts detail="positions". Rendered images remain inline by default;
image_mode="resource" returns references for retrieval through MCP resources.
Save and restore your work
UFO 3 is authoritative for outlines. Design contracts and links are revisioned in the manifest.
Compiled fonts and preview images are derived artifacts; imported drawing references are project inputs
and their referenced artifacts/ entries must be retained and backed up with the project:
workspace/<project_id>/
├── HEAD.json
├── revisions/<revision>/
│ ├── source.ufo/
│ └── manifest.json
└── artifacts/<artifact_id>/
├── font.ttf / font.woff2 / image.png
└── artifact.jsonEdits validate the whole project, write a complete new UFO snapshot, then atomically update the revision pointer under an OS lock. Invalid batches leave the committed state intact. Hashes detect external changes; restoration preserves existing history. Back up the entire project directory, preferably with the server stopped.
Use a private local workspace and edit snapshots through the tools. The server checks paths and UFO references, rejects symlinks/junctions and unsafe XML, and exposes no arbitrary code, shell, download, or package-installation tool. Inputs, images, geometry, compiler time, and logs are bounded. These checks are not an OS sandbox against a hostile process with the same user privileges, and snapshots are not a substitute for an external backup. Disk usage has no automatic global quota or history purge.
Coordinates use font units, baseline y=0, with Y pointing up. Advance, visible width, and side bearings are
different measurements. UPM is fixed at creation. Closed contours use non-zero filling; counters need the
opposite winding.
Supported formats and limits
Current scope: static and variable TTF/WOFF2 fonts, freeform closed contours, components, anchors, and kerning. Text is shaped with HarfBuzz from a compiled TTF and rasterized with FreeType/Pillow, without system-font fallback.
For variable fonts, variable_configure defines axes and clones masters within the same project.
Editing tools accept master_id, render_text accepts location: {"wght": 500}, and font_build
automatically exports a variable font. Up to 4 continuous axes and 8 masters, subject to source size limits.
Not supported in this version: OTF, arbitrary UFO/SVG import, image tracing, editor adapters, collaborative networking, and a full graphical editor. No hinting or arbitrary OpenType feature code is exposed. Text previews are single-line specimens, not paragraph layout.
Precomposed Á built from components is tested. Latin combining marks with matching base/mark anchors
are checked for reachable mark positioning in TTF and WOFF2, including variable exports and cached builds.
Stacked marks (mkmk) and complex-script coverage are not certified. Source previews can differ slightly from compiled contours
after curve conversion, and unhinted FreeType output need not match native OS rendering.
Build from source
After completing Get started, build the source archive and wheel:
uv buildOutput: dist/. Dependency versions are pinned in pyproject.toml and uv.lock;
requirements.lock provides hashed dependencies for pip installations. Install them with
pip install --require-hashes -r requirements.lock, then install the built wheel with pip install --no-deps /path/to/package.whl.
Checks
uv run --frozen pytest -q
uv run --frozen ruff check src tests scripts examples
uv run --frozen python tests/test_acceptance.pyThe standalone acceptance client retains its captures and JSON-RPC transcript under test-output/acceptance-*.
It checks actual compiled kerning, edit isolation, revision conflicts, failed atomic batches, unsafe paths,
compiler failure, restart, and interrupted writes.
Verification | Evidence |
Windows 11 x64, Python 3.11 | 53 local tests passed, including client installation, variable interpolation, real STDIO calls, atomic edits, rendering, and recovery |
Windows, macOS, Linux runners | CI results, covering Python 3.11 and 3.13 |
Installed wheel | Entry point and full MCP demo tested in a separate environment |
MCPB extension | Installed outside the repository; diagnostic, STDIO calls, and TTF/WOFF2 exports tested |
The CI result covers its runner environments, not every OS version or CPU architecture.
Credits and license
Built with the official MCP Python SDK, UFO sources, HarfBuzz, and FreeType/Pillow. Third-party notices are included in the installed dependency packages.
The server code and original examples are MIT licensed. This does not automatically license fonts you create with the server. Font license metadata is empty by default and remains under the creator's control. No third-party font outlines or font files are included.
Available Tools
20 toolsfont_analyzeC
Check visible ink, matching outlines and self crossings by default; measure declared design rules, normal stroke/counter profiles, smooth joins, digit spacing and required coverage. Rules accept master_id or a variable location; variation_profiles measure normal-width progression. interpolation=true adds timed source correspondence and compiled axis-grid checks. Returns regional coverage and localized candidates, not artistic approval. Full reports include measurements and evidence_plan.
| Name | Required | Description | Default |
|---|---|---|---|
| detail | No | summary | |
| revision | No | ||
| master_id | No | default | |
| project_id | Yes | ||
| interpolation | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations (readOnlyHint=false, destructiveHint=false, idempotentHint=false, openWorldHint=false) already convey the safety/idempotency profile. The description adds useful behavioral context the annotations lack: what is checked by default, what interpolation adds, and that the output is 'regional coverage and localized candidates, not artistic approval' with 'measurements and evidence_plan'. It does not explain why the operation is non-read-only/non-idempotent (likely report generation), leaving a gap.
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 compact and avoids padding, and the default checks are front-loaded. But the semicolon-packed, jargon-heavy prose is hard to parse and buries the top-level purpose, so the structure does not maximize clarity per token.
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?
An output schema exists, so return values need not be re-explained, and the description covers several behavioral/parameter facets. Still, with 5 parameters at 0% schema coverage, no usage routing among siblings, and no explanation of the non-read-only nature, it is only adequately complete.
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 load: it adds meaning for master_id ('Rules accept master_id or a variable location') and for interpolation ('adds timed source correspondence and compiled axis-grid checks'), and indirectly for detail ('Full reports include...'). It says nothing about revision or project_id, so compensation is only partial.
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 concrete check categories ('visible ink', 'matching outlines', 'self crossings', 'digit spacing') and implies an analysis/QA role over a font project, so the general purpose is inferable. However it never states plainly what resource is being analyzed or how it differs from siblings like font_validate or font_release_check, and the dense jargon obscures the core purpose.
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 when-to-use or when-not-to-use guidance, and no alternative tool is named. The only conditional language ('by default', 'interpolation=true adds...') describes parameter behavior rather than the choice between this tool and its siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
font_buildB
Build real TTF and/or WOFF2 from a frozen revision, automatically variable when axes/masters are configured. Returns persistent relative paths and hashes. Does not alter sources.
| Name | Required | Description | Default |
|---|---|---|---|
| formats | No | ||
| purpose | No | proof | |
| revision | No | ||
| project_id | Yes | ||
| review_uris | No | ||
| require_design_checks | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and destructiveHint=false, so the mutation profile is known. The description adds useful context ('Does not alter sources', 'Returns persistent relative paths and hashes', automatic variable output), but omits whether builds are cached, whether they overwrite existing artifacts, or any auth/permission requirements. Given annotations cover the safety profile, this additional context earns a middle score.
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 tightly packed sentences with no filler, front-loading the core action and then the behavioral guarantees. Every clause supplies 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?
An output schema exists, so return-value explanation is unnecessary. However, for a 6-parameter, mutation-performing build tool with 0% schema description coverage, the absence of parameter-level guidance (especially purpose and the check/review options) leaves the agent under-informed.
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 burden for 6 parameters. It mentions formats implicitly ('TTF and/or WOFF2') and the revision source ('from a frozen revision'), but does not explain purpose (proof vs release), require_design_checks, review_uris, or project_id. It leaves most parameters 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+resource: building real TTF/WOFF2 from a frozen revision, and notes automatic variable output when axes/masters are configured. Does not explicitly distinguish itself from font_release_check or font_validate siblings, but the build output (font binaries) is clearly 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?
No when-to-use or when-not-to-use guidance. There is no mention of alternatives such as font_release_check or font_validate, nor any indication of when a 'proof' vs 'release' build should be performed despite that distinction existing in the schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
font_editB
Edit up to 128 glyphs atomically in master_id (default: 'default'), then apply spacing. Forward component references resolve at final validation; any failure rolls back the batch.
| Name | Required | Description | Default |
|---|---|---|---|
| detail | No | summary | |
| glyphs | Yes | ||
| spacing | No | ||
| summary | No | ||
| master_id | No | default | |
| project_id | Yes | ||
| expected_revision | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly=false, idempotent=false, destructive=false), and the description adds real behavior beyond them: atomicity, rollback on any failure, and deferred resolution of forward component references at final validation. That last point materially affects how a caller sequences dependent operations.
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 tightly packed sentences, front-loaded with the action and scope, then the correctness guarantees. No filler and no repetition of structured data beyond the master_id default.
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 with a very large nested schema and no output-value burden (an output schema exists), the description is too thin: it omits expected_revision semantics, the create flag on GlyphChange, and any sense of what the glyphs/spacing operation payloads do. Adequate for safety, inadequate for invocation.
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 7 parameters, and the description explains only master_id (including its default). The heavyweight inputs the agent must construct – glyphs with its 19-way operation union, spacing, project_id, expected_revision, summary, detail – are left entirely to the schema, and expected_revision's optimistic-concurrency role is never stated.
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 (edit), resource (glyphs), and scope (up to 128, atomically in master_id, plus spacing). This distinguishes it from glyph_edit and spacing_edit implicitly via the batch/atomic/covers-both framing, but it never names a sibling to route the agent.
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 explicit when-to-use or when-not-to-use statement. The atomic 128-glyph batch with a trailing spacing pass implies the use case is bulk edits, but an agent must infer this and has no guidance on choosing between font_edit, glyph_edit, and spacing_edit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
font_release_checkB
Evaluate all masters, structural measurements, glyph review coverage, localized findings, reference comparisons and shaped text reviews before release. Supply proof_review report_uris. Returns actionable missing requirements; never certifies aesthetic perfection.
| Name | Required | Description | Default |
|---|---|---|---|
| revision | No | ||
| project_id | Yes | ||
| review_uris | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false, destructiveHint=false, idempotentHint=false and a closed world, so the agent already knows this is a non-destructive but non-idempotent state-affecting call. The description adds that it returns actionable missing requirements and 'never certifies aesthetic perfection', which usefully sets expectations, but it does not disclose what side effects the check has or what it persists.
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 compact sentences, with the scope of the evaluation front-loaded before the input instruction and the return-value caveat. The long enumeration of check categories is dense but each item is informative and nothing is repeated.
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?
An output schema exists, so return format need not be documented, and the description does note the actionable-findings nature of the result. However, for a state-affecting tool with 0% parameter documentation, the description leaves the meaning of project_id/revision and the overall side-effect profile underspecified.
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 3 parameters, so the description carries the full burden, yet it only hints at one of them ('supply proof_review report_uris' loosely maps to review_uris). project_id and revision receive no explanation, and the accepted URI format/limit is left entirely to the 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 gives a specific verb (Evaluate) and enumerates the concrete resource scope: masters, structural measurements, glyph review coverage, localized findings, reference comparisons, shaped text reviews, before release. That is far more specific than a tautology and separable from siblings like font_validate or font_analyze, though it never explicitly contrasts itself with them.
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 phrase 'before release' implies timing and the instruction to 'Supply proof_review report_uris' hints at a prerequisite, but no sibling is named as an alternative and no exclusion is stated (e.g., when to use font_validate instead). Usage is implied rather than spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
font_validateB
Run technical checks, compile a TTF, inspect tables and corpus coverage. Reports errors, warnings and observations; does not assess artistic merit.
| Name | Required | Description | Default |
|---|---|---|---|
| corpus | No | ||
| detail | No | summary | |
| revision | No | ||
| project_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are minimal (all hints false), so the description carries the behavioral burden. It discloses that it compiles a TTF, inspects tables, and reports errors/warnings/observations. However, it does not clarify whether the compiled TTF is persisted, whether any project state is modified, or what side effects occur. The 'compile' action implies potential file creation, but the description is vague about persistence. It also doesn't mention permissions or reversibility. This is partial transparency.
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 two sentences with no wasted words. It front-loads the primary actions (run checks, compile, inspect) and adds the reporting scope and the artistic merit exclusion. Every clause earns its place. It is compact and readable.
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 tool has 4 parameters, an output schema, and complex behavior (compilation, inspection). The description is far too sparse to be complete. It does not explain parameter usage, when to use it versus font_build, or what the output report includes beyond errors/warnings/observations. Even though an output schema exists, the description should still clarify the tool's role and parameter semantics. The missing guidance leaves significant gaps for an agent.
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 provides essentially no parameter-level semantics. It mentions 'corpus coverage' which alludes to the corpus parameter but does not explain it, nor does it explain detail (summary vs full), revision, or the purpose of project_id beyond the obvious. With zero coverage, the description must compensate by explaining each parameter, and it fails to do so. The agent is left to guess what these parameters control.
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 clearly states the verb 'Run technical checks', the resource (a font/project via project_id), and specific actions: compile a TTF, inspect tables and corpus coverage. It also explicitly differentiates by stating it does not assess artistic merit, which distinguishes it from render or edit tools. The purpose is unambiguous and well-scoped.
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 provides no explicit guidance on when to use this tool versus alternatives. It mentions 'technical checks' but does not name sibling tools like font_build or render_glyph, nor does it state conditions for choosing this over them. The 'does not assess artistic merit' hint is too implicit to serve as a routing rule. An agent would have to infer when to invoke this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
glyph_editC
Apply typed vector operations or drawing primitives atomically to one glyph in master_id (default: 'default'). Use detail=full for added/removed/touched IDs. Replacements are explicit.
| Name | Required | Description | Default |
|---|---|---|---|
| create | No | ||
| detail | No | summary | |
| summary | No | ||
| glyph_id | Yes | ||
| master_id | No | default | |
| operations | Yes | ||
| project_id | Yes | ||
| expected_revision | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the mutation profile (readOnlyHint=false, idempotentHint=false, destructiveHint=false), so the safety bar is lower. The description usefully adds that operations are applied 'atomically' and that 'replacements are explicit', which is real behavioral context beyond the annotations, but it omits the concurrency semantics (expected_revision) that govern a mutation of this kind.
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 tightly written sentences with the primary action front-loaded and no filler. It is efficient, though 'Replacements are explicit' is somewhat cryptic in isolation.
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 highly complex mutation tool (19 operation variants, 8 params, optimistic concurrency via expected_revision, and a create flag), the description is far too terse. An output schema exists so return values need not be explained, but the missing param coverage and lack of concurrency/creation guidance leave real gaps.
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 full explanatory burden, yet it only mentions master_id's default and the detail=full option. Key parameters such as expected_revision, create, and the 19-variant operations payload receive no explanation, leaving the parameter semantics largely 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 (apply) and resource (typed vector operations/drawing primitives to one glyph in a master), which is clear. It does not, however, differentiate itself from siblings like glyph_get or font_edit, so an agent must infer the boundary from the word 'operations' alone.
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 guidance on when to use this versus font_edit, glyph_get, or spacing_edit. The only conditional offered is the detail=full hint, which concerns output verbosity, not tool selection. No prerequisites or exclusions are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
glyph_getARead-onlyIdempotent
Read a master's glyph metrics in font units, Y upwards. master_id defaults to 'default'. Use detail=full for contour/point/component/anchor IDs and geometry.
| Name | Required | Description | Default |
|---|---|---|---|
| detail | No | summary | |
| glyph_id | Yes | ||
| revision | No | ||
| master_id | No | default | |
| project_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description adds valuable behavioral context beyond annotations by specifying the coordinate system (Y upwards) and what detail=full reveals (contour/point/component/anchor IDs and geometry). It does not cover pagination or errors, but these are less critical for a simple read operation.
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 concise sentences with no fluff. The primary action is front-loaded, and the detail=full guidance is placed second. Every word serves a purpose.
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?
Given that an output schema exists (has output schema: true), the description need not detail return values. It covers the essential purpose, coordinate system, and the main optional parameter behavior. It doesn't mention revision handling or edge cases, but these are secondary for a read-only tool with strong annotations and schema.
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 adds meaning for 'detail' by explaining what detail=full returns and notes that master_id defaults to 'default' (already in schema). However, it does not explain 'revision', 'project_id', or 'glyph_id', which are not self-evident. The partial compensation warrants a 3.
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 clearly states a specific action ('Read a master's glyph metrics'), the resource (master's glyph), and adds relevant details (font units, Y upwards). It distinguishes itself from siblings like glyph_edit (write) and render_glyph (rendering) by focusing on reading metrics.
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 gives guidance on parameter usage ('Use detail=full for contour/point/component/anchor IDs and geometry') but does not explicitly address when to use this tool versus alternatives. It lacks 'when not to use' or references to sibling tools like glyph_edit or render_glyph, so an agent must infer the appropriate context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
history_listBRead-onlyIdempotent
List committed revisions and summaries with pagination; interrupted uncommitted stages are excluded.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| detail | No | summary | |
| offset | No | ||
| revision | No | ||
| project_id | Yes | ||
| include_total | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds a meaningful behavioral detail: it excludes interrupted uncommitted stages, which is not inferable from annotations and helps the agent understand the tool's scope.
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, front-loaded sentence that conveys purpose and a key exclusion without waste. It is appropriately concise for the tool's straightforward nature.
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 6 parameters and 0% schema description coverage, the description is incomplete. It fails to explain parameter semantics, and while an output schema exists, the tool's behavior regarding filtering by revision or detail level is undocumented. The description is too sparse to fully guide correct invocation.
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 for parameter meanings. It mentions pagination but does not explain limit, offset, detail, revision, include_total, or how they interact. The schema itself provides defaults and constraints but no descriptions, leaving the agent without guidance on parameter usage beyond names.
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 clearly states the tool lists committed revisions and summaries, with a specific exclusion of interrupted uncommitted stages. It uses a specific verb ('List') and resource, but does not explicitly differentiate from sibling tools like history_restore, though the purpose 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?
The description implies usage for listing committed revisions only, and notes that uncommitted stages are excluded, which hints at when not to use it. However, it does not mention alternative tools or explicit when-to-use conditions, leaving some inference required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
history_restoreA
Restore a committed revision by creating a NEW revision; requires the current expected_revision and preserves history.
| Name | Required | Description | Default |
|---|---|---|---|
| summary | No | ||
| project_id | Yes | ||
| target_revision | Yes | ||
| expected_revision | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate this is a non-read-only, non-idempotent, and non-destructive operation. The description adds valuable context by clarifying it creates a NEW revision (so no overwrite) and preserves history, reinforcing the non-destructive nature. It does not contradict annotations.
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 front-loads the core action and key precondition. Every clause adds meaningful information without redundancy.
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 covers the purpose, the non-destructive behavior, and the main precondition. With an output schema present, return details are not required. However, it omits explicit guidance on error conditions or concurrency failure handling, which could be helpful for a mutation 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 coverage is 0%, so the description must compensate. It explicitly explains expected_revision ('current expected_revision') and implies target_revision (the revision to restore), but it does not clarify project_id or summary. This partially bridges the schema gap but leaves two parameters under-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?
The description clearly states the action ('Restore a committed revision') and the mechanism ('by creating a NEW revision'), distinguishing it from history_list (which lists revisions) and project_update (which modifies settings). It also highlights a critical requirement (expected_revision) that sets it apart from simple reads.
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 implies usage context by requiring the current expected_revision, suggesting a concurrency-aware restore. However, it does not explicitly contrast with sibling tools or state when NOT to use it, leaving some inference to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
project_createC
Create a project in the launch workspace with Unicode UFO sources and technical glyphs.
| Name | Required | Description | Default |
|---|---|---|---|
| brief | No | ||
| metrics | No | ||
| metadata | Yes | ||
| design_spec | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, idempotentHint=false, and openWorldHint=false, so the safety profile is covered. The description adds essentially no behavioral context beyond those annotations — no side effects, permissions, or post-creation state are described.
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 single sentence is front-loaded with the verb and contains no filler. It is concise, though arguably too terse for the complexity of the tool.
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?
Given a required nested metadata object and a sprawling design_spec with many sub-definitions, the description is far too thin. The output schema exists so returns need not be explained, but the description does not help an agent populate the rich input 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?
Top-level schema description coverage is 0%, so the description must carry parameter meaning, but it only loosely gestures at 'UFO sources and technical glyphs.' It does not explain 'brief,' 'metrics,' 'metadata,' or the very complex 'design_spec,' leaving the agent to reverse-engineer the nested schema alone.
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 ('Create') and resource ('project') and adds scope ('in the launch workspace') plus content hints ('Unicode UFO sources and technical glyphs'). It is distinguishable from project_open and project_update by the verb, but it does not explicitly differentiate itself from siblings.
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 guidance on when to use this tool versus alternatives, no prerequisites, and no mention of when not to use it. The sentence describes the outcome but gives an agent no decision context beyond the bare verb.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
project_inspectBRead-onlyIdempotent
Inspect a master with optional sections and glyph_ids focus. Full collections are paginated; pagination lists each continuation. Use sections=['design'] for the complete design contract without spacing/compositions.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| detail | No | summary | |
| offset | No | ||
| revision | No | ||
| sections | No | ||
| glyph_ids | No | ||
| master_id | No | default | |
| project_id | Yes | ||
| include_total | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | 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 bar is low. The description adds genuinely new behavioral context beyond the annotations: full collections are paginated and each continuation is listed, and the design section's scope is qualified. Return format is not described, hence 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?
Three tight sentences, front-loaded with the core action, and no filler. It could be marginally tighter but every sentence carries content.
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?
An output schema exists, so return values need no explanation, and pagination is disclosed. However, for a 9-parameter tool with zero schema coverage and an enum-driven detail mode, the description leaves too many parameters and the summary-vs-full behavior unaddressed to be considered complete.
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 9 parameters, so the description must carry the load. It only addresses two of them (sections, glyph_ids) and leaves limit, offset, detail, revision, master_id, and include_total entirely unexplained, including which value of detail the pagination note applies to.
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 concrete verb (Inspect) and resource (a master), plus the scoping axes (sections, glyph_ids). An agent can distinguish it from project_open/project_create, but the description never says it is a font-master inspection or names a sibling to differentiate against, so it stops 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?
One explicit usage hint is given: sections=['design'] yields the complete design contract without spacing/compositions. That is real guidance for one path, but there is no when-to-use-this-vs-project_open, no exclusion conditions, and no guidance on detail/offset/limit selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
project_openARead-onlyIdempotent
Reopen a server-created project by ID; verifies committed sources and returns its revision.
| Name | Required | Description | Default |
|---|---|---|---|
| project_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, covering safety traits. The description adds extra behavior: that it verifies committed sources and returns a revision, which is not in the annotations and gives useful operational context. This enriches transparency without contradicting the annotations.
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, compact sentence that states the action, target, and key outcomes. It is front-loaded with the verb and resource, and every phrase adds value. No filler or redundant 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?
For a simple read-only operation with one parameter and an output schema present, the description covers the essential behavior: what it does, what it verifies, and what it returns. It does not mention prerequisites or edge cases, but given the tool's simplicity and the annotations, this is adequately complete. The presence of an output schema reduces the need to describe return 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?
The schema has only one parameter (project_id) with a regex pattern, but the schema description coverage is 0%, meaning no descriptive text in the schema. The description only says 'by ID,' which barely adds meaning beyond the parameter name itself. It does not explain the format, purpose, or constraints beyond what the pattern already implies, so the description carries minimal additional semantic weight.
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 uses a specific verb ('Reopen') and identifies the resource ('server-created project') along with the identifier type. It also mentions two concrete outcomes (verifying committed sources and returning revision), making the tool's purpose unambiguous and distinct from siblings like project_inspect or project_create.
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 context by specifying 'server-created project,' which suggests it is not for locally created ones, but it does not explicitly contrast with alternatives. There is no guidance on when to choose project_open over project_inspect or project_update, leaving the agent to infer the distinction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
project_updateB
Atomically update metadata, brief or decision journal. Requires expected_revision. UPM changes on nonempty fonts fail.
| Name | Required | Description | Default |
|---|---|---|---|
| brief | No | ||
| metrics | No | ||
| summary | No | ||
| decision | No | ||
| metadata | No | ||
| project_id | Yes | ||
| design_spec | No | ||
| expected_revision | Yes | ||
| remove_reference_ids | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the safety profile (not read-only, not idempotent, not destructive), so the bar is lower. The description adds real context beyond them: atomicity of the operation, the optimistic-concurrency requirement of expected_revision, and a concrete failure condition ('UPM changes on nonempty fonts fail'). It stops short of saying what happens on revision mismatch or whether omitted fields are cleared.
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 short sentences, front-loaded with the core action, then the precondition, then the failure caveat. Zero padding. Slight deduction because 'UPM' is used as undefined jargon that an agent cannot map to units_per_em without schema inspection.
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?
This is a complex 9-parameter mutation tool with 0% schema coverage, and the description covers only a fraction of the input surface. The presence of an output schema removes the need to explain return values, but the missing guidance on the remaining update domains, revision-mismatch behavior, and field-clearing semantics leaves the definition under-specified for its 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% across 9 parameters, several of them deeply nested objects, so the description must carry the burden. It names only three of the update domains (metadata, brief, decision) and leaves design_spec, metrics, summary, remove_reference_ids, project_id, and expected_revision format/semantics unexplained. Partial compensation at best.
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 with scope: 'Atomically update metadata, brief or decision journal.' An agent can tell this is the mutation counterpart to project_create/project_open/project_inspect without opening a schema. It does not, however, enumerate the full set of updatable surfaces (metrics, design_spec, summary, remove_reference_ids) or name a sibling explicitly.
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 only usage guidance is the precondition 'Requires expected_revision.' There is no statement of when to prefer this over project_inspect, project_open, or history_restore, and no guidance on partial vs full updates. The agent is left to infer the workflow context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
proof_reviewA
Record an agent's visual review of immutable render report_uris from an exact revision. Use verdict=revise for defects; accepted intentional findings require their finding_id and a reason. Does not alter font sources or assert human approval. Inspect actual images before calling.
| Name | Required | Description | Default |
|---|---|---|---|
| verdict | Yes | ||
| revision | Yes | ||
| project_id | Yes | ||
| proof_uris | Yes | ||
| observation | Yes | ||
| resolutions | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only give the generic flags (readOnlyHint=false, destructiveHint=false, idempotentHint=false); the description adds real behavioral context by stating the review is recorded against 'immutable' revision-bound report URIs and that it 'Does not alter font sources or assert human approval,' which sets expectations about side effects and scope of authority. It omits that repeat calls are non-idempotent (new records), which the annotations imply.
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, front-loaded with the core action, then verdict rules, then the boundary statement. No filler; every sentence carries information, though the final two clauses are slightly compressed and could read ambiguously.
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 non-read-only recording tool with an output schema present, the description covers the precondition (inspect images first), the verdict-dependent requirements, and what it does not do (no font-source mutation, no human approval claim). It is nearly complete, with only the non-idempotent recording behavior and observation input constraints unaddressed.
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 does explain the verdict semantics and the finding_id/reason requirement for resolutions, and ties proof_uris and revision together ('immutable render report_uris from an exact revision'). However, project_id, observation, and the array/length constraints (maxItems 8, minLength 12/20, hex patterns) are left entirely to the 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: 'Record an agent's visual review of immutable render report_uris from an exact revision.' This clearly separates it from siblings like render_proof or font_validate, though it never names an adjacent tool explicitly, so an agent must infer the pairing with render_proof.
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 actionable conditions: 'Use verdict=revise for defects', 'accepted intentional findings require their finding_id and a reason', and the precondition 'Inspect actual images before calling.' That is clear when-to-use guidance, but there is no exclusion (e.g., when not to use this versus re-rendering the proof) and no mention of alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reference_importA
Import a bounded single-frame PNG from workspace/inbox as an immutable drawing reference. image_to_font maps image pixels (top-left, Y down) to font units (baseline, Y up). Requires expected_revision. No tracing or automatic rescaling; use reference_id with render_glyph.
| Name | Required | Description | Default |
|---|---|---|---|
| crop | No | ||
| label | No | ||
| replace | No | ||
| summary | No | ||
| glyph_id | Yes | ||
| image_mode | No | inline | |
| project_id | Yes | ||
| source_path | Yes | ||
| reference_id | Yes | ||
| image_to_font | Yes | ||
| expected_revision | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only tell the agent it is a non-read-only, non-destructive, non-idempotent operation. The description adds real behavioral context not in structured fields: the image_to_font pixel-to-font-unit convention (top-left, Y down → baseline, Y up), the immutability of the resulting reference, and the concurrency requirement (expected_revision). It omits the effect of `replace` and image_mode, but adds substantial value.
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 tightly packed sentences with the core action front-loaded and constraints following. No filler, though the mapping sentence and the trailing guidance could be split more clearly for scanning.
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?
An output schema exists so return values need not be described, and annotations cover the safety profile. Still, for a mutation tool with 11 mostly-undocumented parameters, the description leaves gaps (crop semantics, replace behavior, image_mode) that an agent must guess at.
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 11 parameters, so the description must compensate. It usefully explains image_to_font and flags expected_revision, but leaves crop, label, replace, summary, image_mode, source_path, glyph_id and reference_id entirely undocumented, which is most of the surface.
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 (Import), resource (bounded single-frame PNG), source location (workspace/inbox) and its nature (immutable drawing reference). An agent can distinguish this from siblings like glyph_edit or render_glyph 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?
It points forward ("use reference_id with render_glyph") and excludes behaviors ("No tracing or automatic rescaling"), which is useful. However, it never says when to choose this import over other workflows or what prerequisites/preconditions apply beyond requiring expected_revision.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
render_glyphC
Persist and return PNG image content from the selected UFO revision, with optional guides/handles. Comparison uses the same frame.
| Name | Required | Description | Default |
|---|---|---|---|
| width | No | ||
| detail | No | summary | |
| guides | No | ||
| height | No | ||
| points | No | ||
| glyph_id | Yes | ||
| revision | No | ||
| master_id | No | default | |
| image_mode | No | inline | |
| project_id | Yes | ||
| measurements | No | ||
| reference_id | No | ||
| comparison_mode | No | overlay | |
| compare_revision | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and non-idempotent, and 'Persist' is consistent with a write, so no contradiction. However, with 14 parameters the description does not explain what persisting entails (caching, overwrite, storage cost), whether it requires an open project, or what the comparison frame constraint actually means operationally.
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 verb and resource, no filler. The second sentence is terse but carries a real constraint about comparison framing.
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 14-parameter tool with zero schema descriptions, no output-schema explanation needed (output schema exists), the description is far too thin to let an agent call it confidently without reading every property.
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% across 14 parameters, so the description must compensate but only touches guides/handles and comparison. Width, height, detail, master_id, image_mode, measurements, revision, and comparison_mode/reference_id/compare_revision are all left 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 pair (persist and return) and resource (PNG image content from the selected UFO revision), so an agent can tell it renders glyphs to images. It does not differentiate itself from siblings like render_text or render_proof, which also produce rendered output.
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 when-to-use guidance, no mention of alternatives (render_text, render_proof, glyph_get), and no indication of prerequisites such as an open project or valid revision. The only hint is that comparison reuses the same frame, which is a constraint rather than a selection rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
render_proofA
Render up to 32 glyphs at one common scale, optionally comparing revisions. Missing glyphs are explicit placeholders; use render_text separately for shaped words.
| Name | Required | Description | Default |
|---|---|---|---|
| detail | No | summary | |
| guides | No | ||
| points | No | ||
| columns | No | ||
| revision | No | ||
| glyph_ids | Yes | ||
| master_id | No | default | |
| cell_width | No | ||
| image_mode | No | inline | |
| project_id | Yes | ||
| cell_height | No | ||
| compare_revision | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide no meaningful safety hints, so the description carries the burden. It discloses useful behavior beyond the name: missing glyphs become explicit placeholders, revisions can be compared, and all glyphs share one scale. This adds practical expectations without contradicting annotations.
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 short sentences deliver the core capability, key limits, a behavioral guarantee, and a routing alternative. There is no filler or repetition.
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 12-parameter tool with 0% schema description coverage, the description only partially covers the invocation surface. The top-level purpose and the most important differentiation are clear, and an output schema exists, but several parameters still lack guidance. This is adequate but not complete.
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 captures the central parameter meanings: glyph count ('up to 32 glyphs'), unified scaling ('one common scale'), and revision comparison. However, it leaves several parameters unspecified (detail, guides, points, columns, master_id, image_mode, cell dimensions), relying on schema names and enums.
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 ('Render'), a bounded resource ('up to 32 glyphs'), and a distinguishing mode ('one common scale, optionally comparing revisions'). It also explicitly separates itself from render_text for shaped words, which helps distinguish it from a close sibling.
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 clearly says to use render_text for shaped words instead, an explicit when-not with an alternative. However, it does not explicitly mention render_glyph for single-glyph rendering or other alternatives, so some usage context is left implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
render_textB
Compile the revision, shape with HarfBuzz and return FreeType PNGs. For variable fonts, location maps axis tags to values; omitted axes use defaults. Missing Unicode is reported. Optional same-conditions revision comparison.
| Name | Required | Description | Default |
|---|---|---|---|
| dark | No | ||
| kern | No | ||
| text | Yes | ||
| sizes | No | ||
| width | No | ||
| detail | No | summary | |
| location | No | ||
| revision | No | ||
| image_mode | No | inline | |
| project_id | Yes | ||
| compare_revision | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are all false (readOnlyHint, destructiveHint, idempotentHint), providing no safety profile. The description adds some behavioral context: it compiles the revision, shapes with HarfBuzz, returns PNGs, reports missing Unicode, and supports optional comparison. However, it doesn't clarify side effects (e.g., whether compiling modifies state) or error behavior. Given the annotations are uninformative, the description partially compensates but leaves gaps.
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 two sentences, front-loaded with the primary action. It efficiently covers key behaviors without excess verbosity. The structure is clean, though it omits crucial parameter details.
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 11 parameters, no schema descriptions, and an output schema present, the description is far from complete. It fails to explain the meaning of most parameters, their defaults, or relationships. The description covers only a fraction of what an agent needs to correctly invoke the tool, especially given the absence of schema descriptions.
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 explain parameters. It only touches on location (axis tags and defaults) and implicitly on compare_revision (same-conditions comparison). The remaining nine parameters (dark, kern, sizes, width, detail, image_mode, revision, project_id, text) are not explained at all. This is a significant gap for an 11-parameter tool.
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 (compile, shape, return) and resource (text rendering), and mentions key behaviors like variable font support and missing Unicode reporting. While it doesn't explicitly distinguish from render_glyph, the text-focused purpose is clear and 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?
The description implies this tool is for rendering text (as opposed to render_glyph for single glyphs) but provides no explicit when-to-use or when-not-to-use guidance. It mentions an optional comparison feature but doesn't specify conditions for using it. No exclusions or alternatives are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
spacing_editA
Atomically set advances, side bearings, kerning groups or pairs in master_id (default: 'default'). Bearings move outlines; advances do not.
| Name | Required | Description | Default |
|---|---|---|---|
| summary | No | ||
| master_id | No | default | |
| operations | Yes | ||
| project_id | Yes | ||
| expected_revision | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate a non-read-only, non-idempotent mutation. The description adds two valuable behavioral details: atomicity (all-or-nothing) and the distinction that bearings move outlines while advances do not. This goes beyond the annotations without contradicting them.
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 concise (two sentences) and front-loads the atomicity and scope. The key behavioral distinction is delivered efficiently without redundancy.
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 tool with four operation types and atomic semantics, the description covers the core purpose and one behavioral nuance but omits details like batching behavior, the role of expected_revision (optimistic locking), and failure handling. The output schema may clarify return values, but the description itself leaves gaps for a complex mutation 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 compensate. It only names the four operation types (advances, bearings, kern pairs/groups) but does not explain fields like 'left', 'right', 'value', or 'glyph_id'. The schema itself provides no descriptions, leaving the agent to infer field meanings from names alone.
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 clearly states the tool's action ('Atomically set') and resources (advances, side bearings, kerning groups or pairs). It also specifies the default master_id, making the purpose unambiguous and distinct from sibling editing 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?
The description implies usage for spacing adjustments but does not explicitly compare with alternatives like glyph_edit or font_edit, nor does it state when not to use this tool. There is no exclusion or routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
variable_configureC
Configure continuous axes and masters in this project. Master 'default' is the existing source at the default location. New IDs clone it; existing IDs keep their drawings; omitted IDs are removed in a new revision. Edit masters with master_id. Compatibility is checked at build/validation time.
| Name | Required | Description | Default |
|---|---|---|---|
| summary | No | ||
| variation | Yes | ||
| project_id | Yes | ||
| expected_revision | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| data | No | |
| error | No | |
| changed | No | |
| summary | Yes | |
| revision | No | |
| warnings | No | |
| project_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses behaviors like new IDs cloning the default master, existing IDs keeping drawings, and omitted IDs being removed, but the removal behavior contradicts the annotation destructiveHint=false. This is a significant inconsistency, so the description fails to provide accurate behavioral transparency.
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 concise, consisting of three sentences with no fluff. It front-loads the purpose and adds behavioral details efficiently.
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?
Given the complex schema with nested objects and many constraints, the description lacks guidance on how to specify axes and masters, the meaning of continuous axes, and the relationship between parameters. It mentions project context but not enough for an agent to construct a valid variation object. The output schema exists so return values are not needed, but input guidance is insufficient.
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 description provides no parameter information. With schema description coverage at 0%, the description must compensate, but it does not explain any of the parameters, including required fields like project_id, expected_revision, or the variation structure.
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 clearly states the tool configures continuous axes and masters in a project, which is a specific resource. It distinguishes from generic update tools by focusing on variable font configuration, though it doesn't explicitly compare to siblings.
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 project_update or font_edit. The description implies usage for configuring axes and masters but doesn't state conditions or exclusions.
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.
11 tool updates
v0.6.0- Changed
font_analyze1 field changed- added
Input schema / properties / interpolationAdded value: +{ + "default": false, + "type": "boolean" +}
- Changed
font_build2 fields changed- added
Input schema / properties / purposeAdded value: +{ + "default": "proof", + "enum": [ + "proof", + "release" + ], + "type": "string" +} - added
Input schema / properties / review_urisAdded value: +{ + "items": { + "maxLength": 250, + "type": "string" + }, + "maxItems": 128, + "type": "array" +}
- Changed
font_edit9 fields changed- added
Input schema / $defs / DetachStrokeNetworkAdded value: +{ + "additionalProperties": false, + "properties": { + "op": { + "const": "detach_stroke_network", + "type": "string" + } + }, + "required": [ + "op" + ], + "type": "object" +} - added
Input schema / $defs / GlyphChange / properties / operations / items / discriminator / mapping / detach_stroke_networkAdded value: +"#/$defs/DetachStrokeNetwork" - added
Input schema / $defs / GlyphChange / properties / operations / items / discriminator / mapping / stroke_networkAdded value: +"#/$defs/SetStrokeNetwork" - added
Input schema / $defs / GlyphChange / properties / operations / items / discriminator / mapping / update_stroke_networkAdded value: +"#/$defs/UpdateStrokeNetwork" - changed
Input schema / $defs / GlyphChange / properties / operations / items / oneOfPrevious value: -[ - { - "$ref": "#/$defs/PutContour" - }, - { - "$ref": "#/$defs/MovePoint" - }, - { - "$ref": "#/$defs/MoveHandle" - }, - { - "$ref": "#/$defs/SetSmooth" - }, - { - "$ref": "#/$defs/DetachComposition" - }, - { - "$ref": "#/$defs/Transform" - }, - { - "$ref": "#/$defs/PutComponent" - }, - { - "$ref": "#/$defs/PutAnchor" - }, - { - "$ref": "#/$defs/Remove" - }, - { - "$ref": "#/$defs/SetUnicodes" - }, - { - "$ref": "#/$defs/ReplaceGlyph" - }, - { - "$ref": "#/$defs/FilledPath" - }, - { - "$ref": "#/$defs/StrokePath" - }, - { - "$ref": "#/$defs/Primitive" - }, - { - "$ref": "#/$defs/Duplicate" - }, - { - "$ref": "#/$defs/ComposeAccent" - } -]New value: +[ + { + "$ref": "#/$defs/PutContour" + }, + { + "$ref": "#/$defs/MovePoint" + }, + { + "$ref": "#/$defs/MoveHandle" + }, + { + "$ref": "#/$defs/SetSmooth" + }, + { + "$ref": "#/$defs/DetachComposition" + }, + { + "$ref": "#/$defs/Transform" + }, + { + "$ref": "#/$defs/PutComponent" + }, + { + "$ref": "#/$defs/PutAnchor" + }, + { + "$ref": "#/$defs/Remove" + }, + { + "$ref": "#/$defs/SetUnicodes" + }, + { + "$ref": "#/$defs/ReplaceGlyph" + }, + { + "$ref": "#/$defs/FilledPath" + }, + { + "$ref": "#/$defs/StrokePath" + }, + { + "$ref": "#/$defs/SetStrokeNetwork" + }, + { + "$ref": "#/$defs/UpdateStrokeNetwork" + }, + { + "$ref": "#/$defs/DetachStrokeNetwork" + }, + { + "$ref": "#/$defs/Primitive" + }, + { + "$ref": "#/$defs/Duplicate" + }, + { + "$ref": "#/$defs/ComposeAccent" + } +] - added
Input schema / $defs / NetworkStrokeAdded value: +{ + "additionalProperties": false, + "properties": { + "cap": { + "default": "butt", + "enum": [ + "round", + "butt", + "square" + ], + "type": "string" + }, + "id": { + "pattern": "^[a-zA-Z_][a-zA-Z0-9_]{0,15}$", + "type": "string" + }, + "join": { + "default": "miter", + "enum": [ + "round", + "bevel", + "miter" + ], + "type": "string" + }, + "path": { + "maxLength": 16000, + "minLength": 1, + "type": "string" + }, + "width_parameter": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + } + }, + "required": [ + "id", + "path", + "width_parameter" + ], + "type": "object" +} - added
Input schema / $defs / SetStrokeNetworkAdded value: +{ + "additionalProperties": false, + "properties": { + "network": { + "$ref": "#/$defs/StrokeNetwork" + }, + "op": { + "const": "stroke_network", + "type": "string" + }, + "replace": { + "default": false, + "type": "boolean" + } + }, + "required": [ + "op", + "network" + ], + "type": "object" +} - added
Input schema / $defs / StrokeNetworkAdded value: +{ + "additionalProperties": false, + "properties": { + "advance": { + "default": 600, + "maximum": 16000, + "minimum": 0, + "type": "number" + }, + "horizontal_scale": { + "default": 1, + "exclusiveMinimum": 0, + "maximum": 4, + "type": "number" + }, + "origin_x": { + "default": 0, + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + "parameters": { + "maxProperties": 16, + "minProperties": 1, + "patternProperties": { + "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$": { + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "number" + } + }, + "type": "object" + }, + "strokes": { + "items": { + "$ref": "#/$defs/NetworkStroke" + }, + "maxItems": 16, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "parameters", + "strokes" + ], + "type": "object" +} - added
Input schema / $defs / UpdateStrokeNetworkAdded value: +{ + "additionalProperties": false, + "properties": { + "advance": { + "anyOf": [ + { + "maximum": 16000, + "minimum": 0, + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "horizontal_scale": { + "anyOf": [ + { + "exclusiveMinimum": 0, + "maximum": 4, + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "op": { + "const": "update_stroke_network", + "type": "string" + }, + "parameters": { + "maxProperties": 16, + "patternProperties": { + "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$": { + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "op" + ], + "type": "object" +}
- Added
font_release_check - Changed
glyph_edit9 fields changed- added
Input schema / $defs / DetachStrokeNetworkAdded value: +{ + "additionalProperties": false, + "properties": { + "op": { + "const": "detach_stroke_network", + "type": "string" + } + }, + "required": [ + "op" + ], + "type": "object" +} - added
Input schema / $defs / NetworkStrokeAdded value: +{ + "additionalProperties": false, + "properties": { + "cap": { + "default": "butt", + "enum": [ + "round", + "butt", + "square" + ], + "type": "string" + }, + "id": { + "pattern": "^[a-zA-Z_][a-zA-Z0-9_]{0,15}$", + "type": "string" + }, + "join": { + "default": "miter", + "enum": [ + "round", + "bevel", + "miter" + ], + "type": "string" + }, + "path": { + "maxLength": 16000, + "minLength": 1, + "type": "string" + }, + "width_parameter": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + } + }, + "required": [ + "id", + "path", + "width_parameter" + ], + "type": "object" +} - added
Input schema / $defs / SetStrokeNetworkAdded value: +{ + "additionalProperties": false, + "properties": { + "network": { + "$ref": "#/$defs/StrokeNetwork" + }, + "op": { + "const": "stroke_network", + "type": "string" + }, + "replace": { + "default": false, + "type": "boolean" + } + }, + "required": [ + "op", + "network" + ], + "type": "object" +} - added
Input schema / $defs / StrokeNetworkAdded value: +{ + "additionalProperties": false, + "properties": { + "advance": { + "default": 600, + "maximum": 16000, + "minimum": 0, + "type": "number" + }, + "horizontal_scale": { + "default": 1, + "exclusiveMinimum": 0, + "maximum": 4, + "type": "number" + }, + "origin_x": { + "default": 0, + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + "parameters": { + "maxProperties": 16, + "minProperties": 1, + "patternProperties": { + "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$": { + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "number" + } + }, + "type": "object" + }, + "strokes": { + "items": { + "$ref": "#/$defs/NetworkStroke" + }, + "maxItems": 16, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "parameters", + "strokes" + ], + "type": "object" +} - added
Input schema / $defs / UpdateStrokeNetworkAdded value: +{ + "additionalProperties": false, + "properties": { + "advance": { + "anyOf": [ + { + "maximum": 16000, + "minimum": 0, + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "horizontal_scale": { + "anyOf": [ + { + "exclusiveMinimum": 0, + "maximum": 4, + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "op": { + "const": "update_stroke_network", + "type": "string" + }, + "parameters": { + "maxProperties": 16, + "patternProperties": { + "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$": { + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "op" + ], + "type": "object" +} - added
Input schema / properties / operations / items / discriminator / mapping / detach_stroke_networkAdded value: +"#/$defs/DetachStrokeNetwork" - added
Input schema / properties / operations / items / discriminator / mapping / stroke_networkAdded value: +"#/$defs/SetStrokeNetwork" - added
Input schema / properties / operations / items / discriminator / mapping / update_stroke_networkAdded value: +"#/$defs/UpdateStrokeNetwork" - changed
Input schema / properties / operations / items / oneOfPrevious value: -[ - { - "$ref": "#/$defs/PutContour" - }, - { - "$ref": "#/$defs/MovePoint" - }, - { - "$ref": "#/$defs/MoveHandle" - }, - { - "$ref": "#/$defs/SetSmooth" - }, - { - "$ref": "#/$defs/DetachComposition" - }, - { - "$ref": "#/$defs/Transform" - }, - { - "$ref": "#/$defs/PutComponent" - }, - { - "$ref": "#/$defs/PutAnchor" - }, - { - "$ref": "#/$defs/Remove" - }, - { - "$ref": "#/$defs/SetUnicodes" - }, - { - "$ref": "#/$defs/ReplaceGlyph" - }, - { - "$ref": "#/$defs/FilledPath" - }, - { - "$ref": "#/$defs/StrokePath" - }, - { - "$ref": "#/$defs/Primitive" - }, - { - "$ref": "#/$defs/Duplicate" - }, - { - "$ref": "#/$defs/ComposeAccent" - } -]New value: +[ + { + "$ref": "#/$defs/PutContour" + }, + { + "$ref": "#/$defs/MovePoint" + }, + { + "$ref": "#/$defs/MoveHandle" + }, + { + "$ref": "#/$defs/SetSmooth" + }, + { + "$ref": "#/$defs/DetachComposition" + }, + { + "$ref": "#/$defs/Transform" + }, + { + "$ref": "#/$defs/PutComponent" + }, + { + "$ref": "#/$defs/PutAnchor" + }, + { + "$ref": "#/$defs/Remove" + }, + { + "$ref": "#/$defs/SetUnicodes" + }, + { + "$ref": "#/$defs/ReplaceGlyph" + }, + { + "$ref": "#/$defs/FilledPath" + }, + { + "$ref": "#/$defs/StrokePath" + }, + { + "$ref": "#/$defs/SetStrokeNetwork" + }, + { + "$ref": "#/$defs/UpdateStrokeNetwork" + }, + { + "$ref": "#/$defs/DetachStrokeNetwork" + }, + { + "$ref": "#/$defs/Primitive" + }, + { + "$ref": "#/$defs/Duplicate" + }, + { + "$ref": "#/$defs/ComposeAccent" + } +]
- Changed
project_create15 fields changed- added
Input schema / $defs / DesignRegionAdded value: +{ + "additionalProperties": false, + "description": "A declared area in normalized visible bounds; useful for non-Latin and alternate anatomy.", + "properties": { + "bounds": { + "maxItems": 4, + "minItems": 4, + "prefixItems": [ + { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + { + "maximum": 1, + "minimum": 0, + "type": "number" + } + ], + "type": "array" + }, + "glyph_id": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "id": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "location": { + "anyOf": [ + { + "maxProperties": 4, + "patternProperties": { + "^[A-Za-z][A-Za-z0-9]{3}$": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + } + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null + }, + "master_id": { + "anyOf": [ + { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "minimum_samples": { + "default": 2, + "maximum": 17, + "minimum": 1, + "type": "integer" + }, + "role": { + "enum": [ + "stem", + "branch", + "junction", + "counter", + "curve", + "terminal" + ], + "type": "string" + } + }, + "required": [ + "id", + "glyph_id", + "bounds", + "role" + ], + "type": "object" +} - added
Input schema / $defs / DesignSpec / properties / glyph_originsAdded value: +{ + "items": { + "$ref": "#/$defs/GlyphOrigin" + }, + "maxItems": 512, + "type": "array" +} - added
Input schema / $defs / DesignSpec / properties / regionsAdded value: +{ + "items": { + "$ref": "#/$defs/DesignRegion" + }, + "maxItems": 512, + "type": "array" +} - added
Input schema / $defs / DesignSpec / properties / stroke_profilesAdded value: +{ + "items": { + "$ref": "#/$defs/StrokeProfile" + }, + "maxItems": 512, + "type": "array" +} - added
Input schema / $defs / DesignSpec / properties / usage_textsAdded value: +{ + "items": { + "maxLength": 80, + "minLength": 2, + "type": "string" + }, + "maxItems": 64, + "type": "array" +} - added
Input schema / $defs / DesignSpec / properties / variation_probesAdded value: +{ + "items": { + "$ref": "#/$defs/VariationProbe" + }, + "maxItems": 32, + "type": "array" +} - added
Input schema / $defs / DesignSpec / properties / variation_profilesAdded value: +{ + "items": { + "$ref": "#/$defs/VariationProfile" + }, + "maxItems": 128, + "type": "array" +} - added
Input schema / $defs / GlyphOriginAdded value: +{ + "additionalProperties": false, + "properties": { + "glyph_id": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "observation": { + "maxLength": 1000, + "minLength": 20, + "type": "string" + }, + "reference_ids": { + "items": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "maxItems": 16, + "type": "array" + }, + "status": { + "enum": [ + "observed", + "extrapolated", + "original" + ], + "type": "string" + } + }, + "required": [ + "glyph_id", + "status", + "observation" + ], + "type": "object" +} - added
Input schema / $defs / MetricRule / properties / locationAdded value: +{ + "anyOf": [ + { + "maxProperties": 4, + "patternProperties": { + "^[A-Za-z][A-Za-z0-9]{3}$": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + } + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / $defs / MetricRule / properties / master_idAdded value: +{ + "anyOf": [ + { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / $defs / StrokeProbe / properties / locationAdded value: +{ + "anyOf": [ + { + "maxProperties": 4, + "patternProperties": { + "^[A-Za-z][A-Za-z0-9]{3}$": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + } + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / $defs / StrokeProbe / properties / master_idAdded value: +{ + "anyOf": [ + { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / $defs / StrokeProfileAdded value: +{ + "additionalProperties": false, + "description": "Sample perpendicular to a centerline; measure ink or a bounded counter, in font units.", + "properties": { + "end": { + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + } + ], + "type": "array" + }, + "glyph_id": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "id": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "location": { + "anyOf": [ + { + "maxProperties": 4, + "patternProperties": { + "^[A-Za-z][A-Za-z0-9]{3}$": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + } + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null + }, + "master_id": { + "anyOf": [ + { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "max_ratio": { + "anyOf": [ + { + "maximum": 100, + "minimum": 1, + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "maximum": { + "exclusiveMinimum": 0, + "maximum": 4000, + "type": "number" + }, + "minimum": { + "exclusiveMinimum": 0, + "maximum": 4000, + "type": "number" + }, + "region": { + "default": "ink", + "enum": [ + "ink", + "counter" + ], + "type": "string" + }, + "samples": { + "default": 5, + "maximum": 17, + "minimum": 2, + "type": "integer" + }, + "start": { + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + } + ], + "type": "array" + } + }, + "required": [ + "id", + "glyph_id", + "start", + "end", + "minimum", + "maximum" + ], + "type": "object" +} - added
Input schema / $defs / VariationProbeAdded value: +{ + "additionalProperties": false, + "description": "Sample a declared stroke across an axis; this is not an optical weight estimate.", + "properties": { + "axis": { + "default": "horizontal", + "enum": [ + "horizontal", + "vertical" + ], + "type": "string" + }, + "axis_tag": { + "pattern": "^[A-Za-z][A-Za-z0-9]{3}$", + "type": "string" + }, + "direction": { + "default": "nondecreasing", + "enum": [ + "nondecreasing", + "nonincreasing" + ], + "type": "string" + }, + "glyph_id": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "id": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "location": { + "maxProperties": 4, + "patternProperties": { + "^[A-Za-z][A-Za-z0-9]{3}$": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + } + }, + "type": "object" + }, + "minimum_change": { + "default": 0, + "maximum": 4000, + "minimum": 0, + "type": "number" + }, + "position": { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + "span_index": { + "default": 0, + "maximum": 63, + "minimum": 0, + "type": "integer" + }, + "tolerance": { + "default": 2, + "maximum": 1000, + "minimum": 0.5, + "type": "number" + }, + "values": { + "items": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + }, + "maxItems": 9, + "minItems": 2, + "type": "array" + } + }, + "required": [ + "id", + "glyph_id", + "position", + "axis_tag", + "values" + ], + "type": "object" +} - added
Input schema / $defs / VariationProfileAdded value: +{ + "additionalProperties": false, + "properties": { + "axis_tag": { + "pattern": "^[A-Za-z][A-Za-z0-9]{3}$", + "type": "string" + }, + "direction": { + "default": "nondecreasing", + "enum": [ + "nondecreasing", + "nonincreasing" + ], + "type": "string" + }, + "end": { + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + } + ], + "type": "array" + }, + "glyph_id": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "id": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "location": { + "maxProperties": 4, + "patternProperties": { + "^[A-Za-z][A-Za-z0-9]{3}$": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + } + }, + "type": "object" + }, + "master_id": { + "anyOf": [ + { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "max_ratio": { + "anyOf": [ + { + "maximum": 100, + "minimum": 1, + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "maximum": { + "exclusiveMinimum": 0, + "maximum": 4000, + "type": "number" + }, + "minimum": { + "exclusiveMinimum": 0, + "maximum": 4000, + "type": "number" + }, + "minimum_change": { + "default": 0, + "maximum": 4000, + "minimum": 0, + "type": "number" + }, + "region": { + "default": "ink", + "enum": [ + "ink", + "counter" + ], + "type": "string" + }, + "samples": { + "default": 5, + "maximum": 17, + "minimum": 2, + "type": "integer" + }, + "start": { + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + } + ], + "type": "array" + }, + "tolerance": { + "default": 2, + "maximum": 1000, + "minimum": 0.5, + "type": "number" + }, + "values": { + "items": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + }, + "maxItems": 9, + "minItems": 2, + "type": "array" + } + }, + "required": [ + "id", + "glyph_id", + "start", + "end", + "minimum", + "maximum", + "axis_tag", + "values" + ], + "type": "object" +}
- Changed
project_inspect3 fields changed- added
Input schema / properties / glyph_idsAdded value: +{ + "items": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "maxItems": 32, + "type": "array" +} - added
Input schema / properties / master_idAdded value: +{ + "default": "default", + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" +} - added
Input schema / properties / sectionsAdded value: +{ + "anyOf": [ + { + "items": { + "enum": [ + "metadata", + "design", + "glyphs", + "spacing", + "compositions", + "history" + ], + "type": "string" + }, + "maxItems": 6, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
project_update15 fields changed- added
Input schema / $defs / DesignRegionAdded value: +{ + "additionalProperties": false, + "description": "A declared area in normalized visible bounds; useful for non-Latin and alternate anatomy.", + "properties": { + "bounds": { + "maxItems": 4, + "minItems": 4, + "prefixItems": [ + { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + { + "maximum": 1, + "minimum": 0, + "type": "number" + } + ], + "type": "array" + }, + "glyph_id": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "id": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "location": { + "anyOf": [ + { + "maxProperties": 4, + "patternProperties": { + "^[A-Za-z][A-Za-z0-9]{3}$": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + } + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null + }, + "master_id": { + "anyOf": [ + { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "minimum_samples": { + "default": 2, + "maximum": 17, + "minimum": 1, + "type": "integer" + }, + "role": { + "enum": [ + "stem", + "branch", + "junction", + "counter", + "curve", + "terminal" + ], + "type": "string" + } + }, + "required": [ + "id", + "glyph_id", + "bounds", + "role" + ], + "type": "object" +} - added
Input schema / $defs / DesignSpec / properties / glyph_originsAdded value: +{ + "items": { + "$ref": "#/$defs/GlyphOrigin" + }, + "maxItems": 512, + "type": "array" +} - added
Input schema / $defs / DesignSpec / properties / regionsAdded value: +{ + "items": { + "$ref": "#/$defs/DesignRegion" + }, + "maxItems": 512, + "type": "array" +} - added
Input schema / $defs / DesignSpec / properties / stroke_profilesAdded value: +{ + "items": { + "$ref": "#/$defs/StrokeProfile" + }, + "maxItems": 512, + "type": "array" +} - added
Input schema / $defs / DesignSpec / properties / usage_textsAdded value: +{ + "items": { + "maxLength": 80, + "minLength": 2, + "type": "string" + }, + "maxItems": 64, + "type": "array" +} - added
Input schema / $defs / DesignSpec / properties / variation_probesAdded value: +{ + "items": { + "$ref": "#/$defs/VariationProbe" + }, + "maxItems": 32, + "type": "array" +} - added
Input schema / $defs / DesignSpec / properties / variation_profilesAdded value: +{ + "items": { + "$ref": "#/$defs/VariationProfile" + }, + "maxItems": 128, + "type": "array" +} - added
Input schema / $defs / GlyphOriginAdded value: +{ + "additionalProperties": false, + "properties": { + "glyph_id": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "observation": { + "maxLength": 1000, + "minLength": 20, + "type": "string" + }, + "reference_ids": { + "items": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "maxItems": 16, + "type": "array" + }, + "status": { + "enum": [ + "observed", + "extrapolated", + "original" + ], + "type": "string" + } + }, + "required": [ + "glyph_id", + "status", + "observation" + ], + "type": "object" +} - added
Input schema / $defs / MetricRule / properties / locationAdded value: +{ + "anyOf": [ + { + "maxProperties": 4, + "patternProperties": { + "^[A-Za-z][A-Za-z0-9]{3}$": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + } + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / $defs / MetricRule / properties / master_idAdded value: +{ + "anyOf": [ + { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / $defs / StrokeProbe / properties / locationAdded value: +{ + "anyOf": [ + { + "maxProperties": 4, + "patternProperties": { + "^[A-Za-z][A-Za-z0-9]{3}$": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + } + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / $defs / StrokeProbe / properties / master_idAdded value: +{ + "anyOf": [ + { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / $defs / StrokeProfileAdded value: +{ + "additionalProperties": false, + "description": "Sample perpendicular to a centerline; measure ink or a bounded counter, in font units.", + "properties": { + "end": { + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + } + ], + "type": "array" + }, + "glyph_id": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "id": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "location": { + "anyOf": [ + { + "maxProperties": 4, + "patternProperties": { + "^[A-Za-z][A-Za-z0-9]{3}$": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + } + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null + }, + "master_id": { + "anyOf": [ + { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "max_ratio": { + "anyOf": [ + { + "maximum": 100, + "minimum": 1, + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "maximum": { + "exclusiveMinimum": 0, + "maximum": 4000, + "type": "number" + }, + "minimum": { + "exclusiveMinimum": 0, + "maximum": 4000, + "type": "number" + }, + "region": { + "default": "ink", + "enum": [ + "ink", + "counter" + ], + "type": "string" + }, + "samples": { + "default": 5, + "maximum": 17, + "minimum": 2, + "type": "integer" + }, + "start": { + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + } + ], + "type": "array" + } + }, + "required": [ + "id", + "glyph_id", + "start", + "end", + "minimum", + "maximum" + ], + "type": "object" +} - added
Input schema / $defs / VariationProbeAdded value: +{ + "additionalProperties": false, + "description": "Sample a declared stroke across an axis; this is not an optical weight estimate.", + "properties": { + "axis": { + "default": "horizontal", + "enum": [ + "horizontal", + "vertical" + ], + "type": "string" + }, + "axis_tag": { + "pattern": "^[A-Za-z][A-Za-z0-9]{3}$", + "type": "string" + }, + "direction": { + "default": "nondecreasing", + "enum": [ + "nondecreasing", + "nonincreasing" + ], + "type": "string" + }, + "glyph_id": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "id": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "location": { + "maxProperties": 4, + "patternProperties": { + "^[A-Za-z][A-Za-z0-9]{3}$": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + } + }, + "type": "object" + }, + "minimum_change": { + "default": 0, + "maximum": 4000, + "minimum": 0, + "type": "number" + }, + "position": { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + "span_index": { + "default": 0, + "maximum": 63, + "minimum": 0, + "type": "integer" + }, + "tolerance": { + "default": 2, + "maximum": 1000, + "minimum": 0.5, + "type": "number" + }, + "values": { + "items": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + }, + "maxItems": 9, + "minItems": 2, + "type": "array" + } + }, + "required": [ + "id", + "glyph_id", + "position", + "axis_tag", + "values" + ], + "type": "object" +} - added
Input schema / $defs / VariationProfileAdded value: +{ + "additionalProperties": false, + "properties": { + "axis_tag": { + "pattern": "^[A-Za-z][A-Za-z0-9]{3}$", + "type": "string" + }, + "direction": { + "default": "nondecreasing", + "enum": [ + "nondecreasing", + "nonincreasing" + ], + "type": "string" + }, + "end": { + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + } + ], + "type": "array" + }, + "glyph_id": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "id": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "location": { + "maxProperties": 4, + "patternProperties": { + "^[A-Za-z][A-Za-z0-9]{3}$": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + } + }, + "type": "object" + }, + "master_id": { + "anyOf": [ + { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "max_ratio": { + "anyOf": [ + { + "maximum": 100, + "minimum": 1, + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "maximum": { + "exclusiveMinimum": 0, + "maximum": 4000, + "type": "number" + }, + "minimum": { + "exclusiveMinimum": 0, + "maximum": 4000, + "type": "number" + }, + "minimum_change": { + "default": 0, + "maximum": 4000, + "minimum": 0, + "type": "number" + }, + "region": { + "default": "ink", + "enum": [ + "ink", + "counter" + ], + "type": "string" + }, + "samples": { + "default": 5, + "maximum": 17, + "minimum": 2, + "type": "integer" + }, + "start": { + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + } + ], + "type": "array" + }, + "tolerance": { + "default": 2, + "maximum": 1000, + "minimum": 0.5, + "type": "number" + }, + "values": { + "items": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + }, + "maxItems": 9, + "minItems": 2, + "type": "array" + } + }, + "required": [ + "id", + "glyph_id", + "start", + "end", + "minimum", + "maximum", + "axis_tag", + "values" + ], + "type": "object" +}
- Added
proof_review - Changed
reference_import1 field changed- added
Input schema / properties / cropAdded value: +{ + "anyOf": [ + { + "maxItems": 4, + "minItems": 4, + "prefixItems": [ + { + "maximum": 2048, + "minimum": 0, + "type": "integer" + }, + { + "maximum": 2048, + "minimum": 0, + "type": "integer" + }, + { + "maximum": 2048, + "minimum": 1, + "type": "integer" + }, + { + "maximum": 2048, + "minimum": 1, + "type": "integer" + } + ], + "type": "array" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
render_glyph2 fields changed- added
Input schema / properties / comparison_modeAdded value: +{ + "default": "overlay", + "enum": [ + "overlay", + "difference" + ], + "type": "string" +} - added
Input schema / properties / measurementsAdded value: +{ + "default": false, + "type": "boolean" +}
9 tool updates
v0.5.0- Added
font_analyze - Changed
font_build1 field changed- added
Input schema / properties / require_design_checksAdded value: +{ + "default": false, + "type": "boolean" +}
- Changed
font_edit9 fields changed- added
Input schema / $defs / ComposeAccent / properties / auto_alignAdded value: +{ + "default": false, + "type": "boolean" +} - added
Input schema / $defs / DetachCompositionAdded value: +{ + "additionalProperties": false, + "properties": { + "op": { + "const": "detach_composition", + "type": "string" + } + }, + "required": [ + "op" + ], + "type": "object" +} - added
Input schema / $defs / GlyphChange / properties / operations / items / discriminator / mapping / detach_compositionAdded value: +"#/$defs/DetachComposition" - added
Input schema / $defs / GlyphChange / properties / operations / items / discriminator / mapping / move_handleAdded value: +"#/$defs/MoveHandle" - added
Input schema / $defs / GlyphChange / properties / operations / items / discriminator / mapping / set_smoothAdded value: +"#/$defs/SetSmooth" - changed
Input schema / $defs / GlyphChange / properties / operations / items / oneOfPrevious value: -[ - { - "$ref": "#/$defs/PutContour" - }, - { - "$ref": "#/$defs/MovePoint" - }, - { - "$ref": "#/$defs/Transform" - }, - { - "$ref": "#/$defs/PutComponent" - }, - { - "$ref": "#/$defs/PutAnchor" - }, - { - "$ref": "#/$defs/Remove" - }, - { - "$ref": "#/$defs/SetUnicodes" - }, - { - "$ref": "#/$defs/ReplaceGlyph" - }, - { - "$ref": "#/$defs/FilledPath" - }, - { - "$ref": "#/$defs/StrokePath" - }, - { - "$ref": "#/$defs/Primitive" - }, - { - "$ref": "#/$defs/Duplicate" - }, - { - "$ref": "#/$defs/ComposeAccent" - } -]New value: +[ + { + "$ref": "#/$defs/PutContour" + }, + { + "$ref": "#/$defs/MovePoint" + }, + { + "$ref": "#/$defs/MoveHandle" + }, + { + "$ref": "#/$defs/SetSmooth" + }, + { + "$ref": "#/$defs/DetachComposition" + }, + { + "$ref": "#/$defs/Transform" + }, + { + "$ref": "#/$defs/PutComponent" + }, + { + "$ref": "#/$defs/PutAnchor" + }, + { + "$ref": "#/$defs/Remove" + }, + { + "$ref": "#/$defs/SetUnicodes" + }, + { + "$ref": "#/$defs/ReplaceGlyph" + }, + { + "$ref": "#/$defs/FilledPath" + }, + { + "$ref": "#/$defs/StrokePath" + }, + { + "$ref": "#/$defs/Primitive" + }, + { + "$ref": "#/$defs/Duplicate" + }, + { + "$ref": "#/$defs/ComposeAccent" + } +] - added
Input schema / $defs / MoveHandleAdded value: +{ + "additionalProperties": false, + "properties": { + "mode": { + "default": "aligned", + "enum": [ + "aligned", + "symmetric" + ], + "type": "string" + }, + "op": { + "const": "move_handle", + "type": "string" + }, + "point_id": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "x": { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + "y": { + "maximum": 16000, + "minimum": -16000, + "type": "number" + } + }, + "required": [ + "op", + "point_id", + "x", + "y" + ], + "type": "object" +} - added
Input schema / $defs / MovePoint / properties / preserve_handlesAdded value: +{ + "default": false, + "type": "boolean" +} - added
Input schema / $defs / SetSmoothAdded value: +{ + "additionalProperties": false, + "properties": { + "op": { + "const": "set_smooth", + "type": "string" + }, + "point_id": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "smooth": { + "type": "boolean" + } + }, + "required": [ + "op", + "point_id", + "smooth" + ], + "type": "object" +}
- Changed
glyph_edit9 fields changed- added
Input schema / $defs / ComposeAccent / properties / auto_alignAdded value: +{ + "default": false, + "type": "boolean" +} - added
Input schema / $defs / DetachCompositionAdded value: +{ + "additionalProperties": false, + "properties": { + "op": { + "const": "detach_composition", + "type": "string" + } + }, + "required": [ + "op" + ], + "type": "object" +} - added
Input schema / $defs / MoveHandleAdded value: +{ + "additionalProperties": false, + "properties": { + "mode": { + "default": "aligned", + "enum": [ + "aligned", + "symmetric" + ], + "type": "string" + }, + "op": { + "const": "move_handle", + "type": "string" + }, + "point_id": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "x": { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + "y": { + "maximum": 16000, + "minimum": -16000, + "type": "number" + } + }, + "required": [ + "op", + "point_id", + "x", + "y" + ], + "type": "object" +} - added
Input schema / $defs / MovePoint / properties / preserve_handlesAdded value: +{ + "default": false, + "type": "boolean" +} - added
Input schema / $defs / SetSmoothAdded value: +{ + "additionalProperties": false, + "properties": { + "op": { + "const": "set_smooth", + "type": "string" + }, + "point_id": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "smooth": { + "type": "boolean" + } + }, + "required": [ + "op", + "point_id", + "smooth" + ], + "type": "object" +} - added
Input schema / properties / operations / items / discriminator / mapping / detach_compositionAdded value: +"#/$defs/DetachComposition" - added
Input schema / properties / operations / items / discriminator / mapping / move_handleAdded value: +"#/$defs/MoveHandle" - added
Input schema / properties / operations / items / discriminator / mapping / set_smoothAdded value: +"#/$defs/SetSmooth" - changed
Input schema / properties / operations / items / oneOfPrevious value: -[ - { - "$ref": "#/$defs/PutContour" - }, - { - "$ref": "#/$defs/MovePoint" - }, - { - "$ref": "#/$defs/Transform" - }, - { - "$ref": "#/$defs/PutComponent" - }, - { - "$ref": "#/$defs/PutAnchor" - }, - { - "$ref": "#/$defs/Remove" - }, - { - "$ref": "#/$defs/SetUnicodes" - }, - { - "$ref": "#/$defs/ReplaceGlyph" - }, - { - "$ref": "#/$defs/FilledPath" - }, - { - "$ref": "#/$defs/StrokePath" - }, - { - "$ref": "#/$defs/Primitive" - }, - { - "$ref": "#/$defs/Duplicate" - }, - { - "$ref": "#/$defs/ComposeAccent" - } -]New value: +[ + { + "$ref": "#/$defs/PutContour" + }, + { + "$ref": "#/$defs/MovePoint" + }, + { + "$ref": "#/$defs/MoveHandle" + }, + { + "$ref": "#/$defs/SetSmooth" + }, + { + "$ref": "#/$defs/DetachComposition" + }, + { + "$ref": "#/$defs/Transform" + }, + { + "$ref": "#/$defs/PutComponent" + }, + { + "$ref": "#/$defs/PutAnchor" + }, + { + "$ref": "#/$defs/Remove" + }, + { + "$ref": "#/$defs/SetUnicodes" + }, + { + "$ref": "#/$defs/ReplaceGlyph" + }, + { + "$ref": "#/$defs/FilledPath" + }, + { + "$ref": "#/$defs/StrokePath" + }, + { + "$ref": "#/$defs/Primitive" + }, + { + "$ref": "#/$defs/Duplicate" + }, + { + "$ref": "#/$defs/ComposeAccent" + } +]
- Changed
project_create4 fields changed- added
Input schema / $defs / DesignSpecAdded value: +{ + "additionalProperties": false, + "properties": { + "digit_spacing": { + "default": "unspecified", + "enum": [ + "unspecified", + "proportional", + "tabular" + ], + "type": "string" + }, + "digit_tolerance": { + "default": 0.5, + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "metric_rules": { + "items": { + "$ref": "#/$defs/MetricRule" + }, + "maxItems": 64, + "type": "array" + }, + "notes": { + "default": "", + "maxLength": 4000, + "type": "string" + }, + "protected_features": { + "default": "", + "maxLength": 4000, + "type": "string" + }, + "reference_glyphs": { + "items": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "maxItems": 64, + "type": "array" + }, + "required_characters": { + "default": "", + "maxLength": 4000, + "type": "string" + }, + "stroke_probes": { + "items": { + "$ref": "#/$defs/StrokeProbe" + }, + "maxItems": 128, + "type": "array" + }, + "tangent_tolerance_degrees": { + "default": 3, + "exclusiveMinimum": 0, + "maximum": 30, + "type": "number" + } + }, + "type": "object" +} - added
Input schema / $defs / MetricRuleAdded value: +{ + "additionalProperties": false, + "description": "Explicit equality targets, not inferred rules of beauty. All values are font units.", + "properties": { + "glyphs": { + "items": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "maxItems": 64, + "minItems": 1, + "type": "array" + }, + "id": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "metric": { + "enum": [ + "advance", + "visible_width", + "height", + "left_bearing", + "right_bearing" + ], + "type": "string" + }, + "target": { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + "tolerance": { + "default": 1, + "maximum": 1000, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "id", + "glyphs", + "metric", + "target" + ], + "type": "object" +} - added
Input schema / $defs / StrokeProbeAdded value: +{ + "additionalProperties": false, + "description": "Measure a filled interval on a declared scanline; choose away from junctions.", + "properties": { + "axis": { + "default": "horizontal", + "enum": [ + "horizontal", + "vertical" + ], + "type": "string" + }, + "glyph_id": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "id": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "position": { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + "span_index": { + "default": 0, + "maximum": 63, + "minimum": 0, + "type": "integer" + }, + "target": { + "exclusiveMinimum": 0, + "maximum": 4000, + "type": "number" + }, + "tolerance": { + "default": 2, + "maximum": 1000, + "minimum": 0.5, + "type": "number" + } + }, + "required": [ + "id", + "glyph_id", + "position", + "target" + ], + "type": "object" +} - added
Input schema / properties / design_specAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/DesignSpec" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
project_update5 fields changed- added
Input schema / $defs / DesignSpecAdded value: +{ + "additionalProperties": false, + "properties": { + "digit_spacing": { + "default": "unspecified", + "enum": [ + "unspecified", + "proportional", + "tabular" + ], + "type": "string" + }, + "digit_tolerance": { + "default": 0.5, + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "metric_rules": { + "items": { + "$ref": "#/$defs/MetricRule" + }, + "maxItems": 64, + "type": "array" + }, + "notes": { + "default": "", + "maxLength": 4000, + "type": "string" + }, + "protected_features": { + "default": "", + "maxLength": 4000, + "type": "string" + }, + "reference_glyphs": { + "items": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "maxItems": 64, + "type": "array" + }, + "required_characters": { + "default": "", + "maxLength": 4000, + "type": "string" + }, + "stroke_probes": { + "items": { + "$ref": "#/$defs/StrokeProbe" + }, + "maxItems": 128, + "type": "array" + }, + "tangent_tolerance_degrees": { + "default": 3, + "exclusiveMinimum": 0, + "maximum": 30, + "type": "number" + } + }, + "type": "object" +} - added
Input schema / $defs / MetricRuleAdded value: +{ + "additionalProperties": false, + "description": "Explicit equality targets, not inferred rules of beauty. All values are font units.", + "properties": { + "glyphs": { + "items": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "maxItems": 64, + "minItems": 1, + "type": "array" + }, + "id": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "metric": { + "enum": [ + "advance", + "visible_width", + "height", + "left_bearing", + "right_bearing" + ], + "type": "string" + }, + "target": { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + "tolerance": { + "default": 1, + "maximum": 1000, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "id", + "glyphs", + "metric", + "target" + ], + "type": "object" +} - added
Input schema / $defs / StrokeProbeAdded value: +{ + "additionalProperties": false, + "description": "Measure a filled interval on a declared scanline; choose away from junctions.", + "properties": { + "axis": { + "default": "horizontal", + "enum": [ + "horizontal", + "vertical" + ], + "type": "string" + }, + "glyph_id": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "id": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "position": { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + "span_index": { + "default": 0, + "maximum": 63, + "minimum": 0, + "type": "integer" + }, + "target": { + "exclusiveMinimum": 0, + "maximum": 4000, + "type": "number" + }, + "tolerance": { + "default": 2, + "maximum": 1000, + "minimum": 0.5, + "type": "number" + } + }, + "required": [ + "id", + "glyph_id", + "position", + "target" + ], + "type": "object" +} - added
Input schema / properties / design_specAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/DesignSpec" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / remove_reference_idsAdded value: +{ + "items": { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "maxItems": 64, + "type": "array" +}
- Added
reference_import - Changed
render_glyph1 field changed- added
Input schema / properties / reference_idAdded value: +{ + "anyOf": [ + { + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +}
- Added
render_proof
15 tool updates
v0.4.3- Changed
font_build13 fields changed- removed
Input schema / properties / formats / titleRemoved value: -"Formats" - removed
Input schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Input schema / properties / revision / titleRemoved value: -"Revision" - removed
Input schema / titleRemoved value: -"Build" - removed
Output schema / properties / changed / titleRemoved value: -"Changed" - removed
Output schema / properties / data / titleRemoved value: -"Data" - removed
Output schema / properties / error / titleRemoved value: -"Error" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / summary / titleRemoved value: -"Summary" - removed
Output schema / properties / warnings / titleRemoved value: -"Warnings" - removed
Output schema / titleRemoved value: -"Result"
- Added
font_edit - Changed
font_validate14 fields changed- removed
Input schema / properties / corpus / titleRemoved value: -"Corpus" - added
Input schema / properties / detailAdded value: +{ + "default": "summary", + "enum": [ + "summary", + "full" + ], + "type": "string" +} - removed
Input schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Input schema / properties / revision / titleRemoved value: -"Revision" - removed
Input schema / titleRemoved value: -"Validate" - removed
Output schema / properties / changed / titleRemoved value: -"Changed" - removed
Output schema / properties / data / titleRemoved value: -"Data" - removed
Output schema / properties / error / titleRemoved value: -"Error" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / summary / titleRemoved value: -"Summary" - removed
Output schema / properties / warnings / titleRemoved value: -"Warnings" - removed
Output schema / titleRemoved value: -"Result"
- Changed
glyph_edit81 fields changed- removed
Input schema / $defs / Anchor / properties / id / titleRemoved value: -"Id" - removed
Input schema / $defs / Anchor / properties / name / titleRemoved value: -"Name" - removed
Input schema / $defs / Anchor / properties / x / titleRemoved value: -"X" - removed
Input schema / $defs / Anchor / properties / y / titleRemoved value: -"Y" - removed
Input schema / $defs / Anchor / titleRemoved value: -"Anchor" - removed
Input schema / $defs / Component / properties / base / titleRemoved value: -"Base" - removed
Input schema / $defs / Component / properties / id / titleRemoved value: -"Id" - removed
Input schema / $defs / Component / properties / transform / titleRemoved value: -"Transform" - removed
Input schema / $defs / Component / titleRemoved value: -"Component" - added
Input schema / $defs / ComposeAccentAdded value: +{ + "additionalProperties": false, + "properties": { + "base": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "base_anchor": { + "default": "top", + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "mark": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + }, + "mark_anchor": { + "default": "_top", + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" + }, + "op": { + "const": "compose_accent", + "type": "string" + } + }, + "required": [ + "op", + "base", + "mark" + ], + "type": "object" +} - removed
Input schema / $defs / Contour / properties / id / titleRemoved value: -"Id" - removed
Input schema / $defs / Contour / properties / points / titleRemoved value: -"Points" - removed
Input schema / $defs / Contour / titleRemoved value: -"Contour" - added
Input schema / $defs / DuplicateAdded value: +{ + "additionalProperties": false, + "properties": { + "matrix": { + "default": [ + 1, + 0, + 0, + 1, + 0, + 0 + ], + "maxItems": 6, + "minItems": 6, + "prefixItems": [ + { + "maximum": 16, + "minimum": -16, + "type": "number" + }, + { + "maximum": 16, + "minimum": -16, + "type": "number" + }, + { + "maximum": 16, + "minimum": -16, + "type": "number" + }, + { + "maximum": 16, + "minimum": -16, + "type": "number" + }, + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + { + "maximum": 16000, + "minimum": -16000, + "type": "number" + } + ], + "type": "array" + }, + "op": { + "const": "duplicate", + "type": "string" + }, + "source": { + "pattern": "^(?:\\.notdef|[a-zA-Z_][a-zA-Z0-9_.]{0,62})$", + "type": "string" + } + }, + "required": [ + "op", + "source" + ], + "type": "object" +} - added
Input schema / $defs / FilledPathAdded value: +{ + "additionalProperties": false, + "properties": { + "advance": { + "anyOf": [ + { + "maximum": 16000, + "minimum": 0, + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "id": { + "default": "outline", + "pattern": "^[a-zA-Z_][a-zA-Z0-9_]{0,23}$", + "type": "string" + }, + "op": { + "const": "filled_path", + "type": "string" + }, + "paths": { + "items": { + "maxLength": 16000, + "minLength": 1, + "type": "string" + }, + "maxItems": 32, + "minItems": 1, + "type": "array" + }, + "replace": { + "default": false, + "type": "boolean" + } + }, + "required": [ + "op", + "paths" + ], + "type": "object" +} - removed
Input schema / $defs / Glyph / properties / advance / titleRemoved value: -"Advance" - removed
Input schema / $defs / Glyph / properties / anchors / titleRemoved value: -"Anchors" - removed
Input schema / $defs / Glyph / properties / components / titleRemoved value: -"Components" - removed
Input schema / $defs / Glyph / properties / contours / titleRemoved value: -"Contours" - removed
Input schema / $defs / Glyph / properties / unicodes / titleRemoved value: -"Unicodes" - removed
Input schema / $defs / Glyph / titleRemoved value: -"Glyph" - removed
Input schema / $defs / MovePoint / properties / op / titleRemoved value: -"Op" - removed
Input schema / $defs / MovePoint / properties / point_id / titleRemoved value: -"Point Id" - removed
Input schema / $defs / MovePoint / properties / x / titleRemoved value: -"X" - removed
Input schema / $defs / MovePoint / properties / y / titleRemoved value: -"Y" - removed
Input schema / $defs / MovePoint / titleRemoved value: -"MovePoint" - removed
Input schema / $defs / Point / properties / id / titleRemoved value: -"Id" - removed
Input schema / $defs / Point / properties / smooth / titleRemoved value: -"Smooth" - removed
Input schema / $defs / Point / properties / type / titleRemoved value: -"Type" - removed
Input schema / $defs / Point / properties / x / titleRemoved value: -"X" - removed
Input schema / $defs / Point / properties / y / titleRemoved value: -"Y" - removed
Input schema / $defs / Point / titleRemoved value: -"Point" - added
Input schema / $defs / PrimitiveAdded value: +{ + "additionalProperties": false, + "properties": { + "advance": { + "anyOf": [ + { + "maximum": 16000, + "minimum": 0, + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "height": { + "exclusiveMinimum": 0, + "maximum": 16000, + "type": "number" + }, + "id": { + "default": "outline", + "pattern": "^[a-zA-Z_][a-zA-Z0-9_]{0,23}$", + "type": "string" + }, + "op": { + "const": "primitive", + "type": "string" + }, + "replace": { + "default": false, + "type": "boolean" + }, + "shape": { + "enum": [ + "rectangle", + "ellipse" + ], + "type": "string" + }, + "width": { + "exclusiveMinimum": 0, + "maximum": 16000, + "type": "number" + }, + "x": { + "maximum": 16000, + "minimum": -16000, + "type": "number" + }, + "y": { + "maximum": 16000, + "minimum": -16000, + "type": "number" + } + }, + "required": [ + "op", + "shape", + "x", + "y", + "width", + "height" + ], + "type": "object" +} - removed
Input schema / $defs / PutAnchor / properties / op / titleRemoved value: -"Op" - removed
Input schema / $defs / PutAnchor / properties / replace / titleRemoved value: -"Replace" - removed
Input schema / $defs / PutAnchor / titleRemoved value: -"PutAnchor" - removed
Input schema / $defs / PutComponent / properties / op / titleRemoved value: -"Op" - removed
Input schema / $defs / PutComponent / properties / replace / titleRemoved value: -"Replace" - removed
Input schema / $defs / PutComponent / titleRemoved value: -"PutComponent" - removed
Input schema / $defs / PutContour / properties / op / titleRemoved value: -"Op" - removed
Input schema / $defs / PutContour / properties / replace / titleRemoved value: -"Replace" - removed
Input schema / $defs / PutContour / titleRemoved value: -"PutContour" - removed
Input schema / $defs / Remove / properties / id / titleRemoved value: -"Id" - removed
Input schema / $defs / Remove / properties / kind / titleRemoved value: -"Kind" - removed
Input schema / $defs / Remove / properties / op / titleRemoved value: -"Op" - removed
Input schema / $defs / Remove / titleRemoved value: -"Remove" - removed
Input schema / $defs / ReplaceGlyph / properties / op / titleRemoved value: -"Op" - removed
Input schema / $defs / ReplaceGlyph / titleRemoved value: -"ReplaceGlyph" - removed
Input schema / $defs / SetUnicodes / properties / op / titleRemoved value: -"Op" - removed
Input schema / $defs / SetUnicodes / properties / unicodes / titleRemoved value: -"Unicodes" - removed
Input schema / $defs / SetUnicodes / titleRemoved value: -"SetUnicodes" - added
Input schema / $defs / StrokePathAdded value: +{ + "additionalProperties": false, + "properties": { + "advance": { + "anyOf": [ + { + "maximum": 16000, + "minimum": 0, + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "cap": { + "default": "round", + "enum": [ + "round", + "butt", + "square" + ], + "type": "string" + }, + "id": { + "default": "outline", + "pattern": "^[a-zA-Z_][a-zA-Z0-9_]{0,23}$", + "type": "string" + }, + "join": { + "default": "round", + "enum": [ + "round", + "bevel", + "miter" + ], + "type": "string" + }, + "op": { + "const": "stroke_path", + "type": "string" + }, + "paths": { + "items": { + "maxLength": 16000, + "minLength": 1, + "type": "string" + }, + "maxItems": 32, + "minItems": 1, + "type": "array" + }, + "replace": { + "default": false, + "type": "boolean" + }, + "width": { + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "number" + } + }, + "required": [ + "op", + "paths", + "width" + ], + "type": "object" +} - removed
Input schema / $defs / Transform / properties / contour_ids / titleRemoved value: -"Contour Ids" - removed
Input schema / $defs / Transform / properties / matrix / titleRemoved value: -"Matrix" - removed
Input schema / $defs / Transform / properties / op / titleRemoved value: -"Op" - removed
Input schema / $defs / Transform / titleRemoved value: -"Transform" - removed
Input schema / properties / create / titleRemoved value: -"Create" - added
Input schema / properties / detailAdded value: +{ + "default": "summary", + "enum": [ + "summary", + "full" + ], + "type": "string" +} - removed
Input schema / properties / expected_revision / titleRemoved value: -"Expected Revision" - removed
Input schema / properties / glyph_id / titleRemoved value: -"Glyph Id" - added
Input schema / properties / master_idAdded value: +{ + "default": "default", + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" +} - added
Input schema / properties / operations / items / discriminator / mapping / compose_accentAdded value: +"#/$defs/ComposeAccent" - added
Input schema / properties / operations / items / discriminator / mapping / duplicateAdded value: +"#/$defs/Duplicate" - added
Input schema / properties / operations / items / discriminator / mapping / filled_pathAdded value: +"#/$defs/FilledPath" - added
Input schema / properties / operations / items / discriminator / mapping / primitiveAdded value: +"#/$defs/Primitive" - added
Input schema / properties / operations / items / discriminator / mapping / stroke_pathAdded value: +"#/$defs/StrokePath" - changed
Input schema / properties / operations / items / oneOfPrevious value: -[ - { - "$ref": "#/$defs/PutContour" - }, - { - "$ref": "#/$defs/MovePoint" - }, - { - "$ref": "#/$defs/Transform" - }, - { - "$ref": "#/$defs/PutComponent" - }, - { - "$ref": "#/$defs/PutAnchor" - }, - { - "$ref": "#/$defs/Remove" - }, - { - "$ref": "#/$defs/SetUnicodes" - }, - { - "$ref": "#/$defs/ReplaceGlyph" - } -]New value: +[ + { + "$ref": "#/$defs/PutContour" + }, + { + "$ref": "#/$defs/MovePoint" + }, + { + "$ref": "#/$defs/Transform" + }, + { + "$ref": "#/$defs/PutComponent" + }, + { + "$ref": "#/$defs/PutAnchor" + }, + { + "$ref": "#/$defs/Remove" + }, + { + "$ref": "#/$defs/SetUnicodes" + }, + { + "$ref": "#/$defs/ReplaceGlyph" + }, + { + "$ref": "#/$defs/FilledPath" + }, + { + "$ref": "#/$defs/StrokePath" + }, + { + "$ref": "#/$defs/Primitive" + }, + { + "$ref": "#/$defs/Duplicate" + }, + { + "$ref": "#/$defs/ComposeAccent" + } +] - removed
Input schema / properties / operations / titleRemoved value: -"Operations" - removed
Input schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Input schema / properties / summary / titleRemoved value: -"Summary" - changed
Input schema / requiredPrevious value: -[ - "project_id", - "expected_revision", - "glyph_id", - "operations" -]New value: +[ + "glyph_id", + "operations", + "project_id", + "expected_revision" +] - removed
Input schema / titleRemoved value: -"GlyphEdit" - removed
Output schema / properties / changed / titleRemoved value: -"Changed" - removed
Output schema / properties / data / titleRemoved value: -"Data" - removed
Output schema / properties / error / titleRemoved value: -"Error" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / summary / titleRemoved value: -"Summary" - removed
Output schema / properties / warnings / titleRemoved value: -"Warnings" - removed
Output schema / titleRemoved value: -"Result"
- Changed
glyph_get15 fields changed- added
Input schema / properties / detailAdded value: +{ + "default": "summary", + "enum": [ + "summary", + "full" + ], + "type": "string" +} - removed
Input schema / properties / glyph_id / titleRemoved value: -"Glyph Id" - added
Input schema / properties / master_idAdded value: +{ + "default": "default", + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" +} - removed
Input schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Input schema / properties / revision / titleRemoved value: -"Revision" - removed
Input schema / titleRemoved value: -"GlyphGet" - removed
Output schema / properties / changed / titleRemoved value: -"Changed" - removed
Output schema / properties / data / titleRemoved value: -"Data" - removed
Output schema / properties / error / titleRemoved value: -"Error" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / summary / titleRemoved value: -"Summary" - removed
Output schema / properties / warnings / titleRemoved value: -"Warnings" - removed
Output schema / titleRemoved value: -"Result"
- Changed
history_list16 fields changed- added
Input schema / properties / detailAdded value: +{ + "default": "summary", + "enum": [ + "summary", + "full" + ], + "type": "string" +} - added
Input schema / properties / include_totalAdded value: +{ + "default": false, + "type": "boolean" +} - removed
Input schema / properties / limit / titleRemoved value: -"Limit" - removed
Input schema / properties / offset / titleRemoved value: -"Offset" - removed
Input schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Input schema / properties / revision / titleRemoved value: -"Revision" - removed
Input schema / titleRemoved value: -"Page" - removed
Output schema / properties / changed / titleRemoved value: -"Changed" - removed
Output schema / properties / data / titleRemoved value: -"Data" - removed
Output schema / properties / error / titleRemoved value: -"Error" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / summary / titleRemoved value: -"Summary" - removed
Output schema / properties / warnings / titleRemoved value: -"Warnings" - removed
Output schema / titleRemoved value: -"Result"
- Changed
history_restore14 fields changed- removed
Input schema / properties / expected_revision / titleRemoved value: -"Expected Revision" - removed
Input schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Input schema / properties / summary / titleRemoved value: -"Summary" - removed
Input schema / properties / target_revision / titleRemoved value: -"Target Revision" - removed
Input schema / titleRemoved value: -"Restore" - removed
Output schema / properties / changed / titleRemoved value: -"Changed" - removed
Output schema / properties / data / titleRemoved value: -"Data" - removed
Output schema / properties / error / titleRemoved value: -"Error" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / summary / titleRemoved value: -"Summary" - removed
Output schema / properties / warnings / titleRemoved value: -"Warnings" - removed
Output schema / titleRemoved value: -"Result"
- Changed
project_create22 fields changed- removed
Input schema / $defs / Metadata / properties / copyright / titleRemoved value: -"Copyright" - removed
Input schema / $defs / Metadata / properties / family / titleRemoved value: -"Family" - removed
Input schema / $defs / Metadata / properties / license_text / titleRemoved value: -"License Text" - removed
Input schema / $defs / Metadata / properties / style / titleRemoved value: -"Style" - removed
Input schema / $defs / Metadata / titleRemoved value: -"Metadata" - removed
Input schema / $defs / Metrics / properties / ascender / titleRemoved value: -"Ascender" - removed
Input schema / $defs / Metrics / properties / cap_height / titleRemoved value: -"Cap Height" - removed
Input schema / $defs / Metrics / properties / descender / titleRemoved value: -"Descender" - removed
Input schema / $defs / Metrics / properties / units_per_em / titleRemoved value: -"Units Per Em" - removed
Input schema / $defs / Metrics / properties / x_height / titleRemoved value: -"X Height" - removed
Input schema / $defs / Metrics / titleRemoved value: -"Metrics" - removed
Input schema / properties / brief / titleRemoved value: -"Brief" - removed
Input schema / titleRemoved value: -"ProjectCreate" - removed
Output schema / properties / changed / titleRemoved value: -"Changed" - removed
Output schema / properties / data / titleRemoved value: -"Data" - removed
Output schema / properties / error / titleRemoved value: -"Error" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / summary / titleRemoved value: -"Summary" - removed
Output schema / properties / warnings / titleRemoved value: -"Warnings" - removed
Output schema / titleRemoved value: -"Result"
- Changed
project_inspect16 fields changed- added
Input schema / properties / detailAdded value: +{ + "default": "summary", + "enum": [ + "summary", + "full" + ], + "type": "string" +} - added
Input schema / properties / include_totalAdded value: +{ + "default": false, + "type": "boolean" +} - removed
Input schema / properties / limit / titleRemoved value: -"Limit" - removed
Input schema / properties / offset / titleRemoved value: -"Offset" - removed
Input schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Input schema / properties / revision / titleRemoved value: -"Revision" - removed
Input schema / titleRemoved value: -"Page" - removed
Output schema / properties / changed / titleRemoved value: -"Changed" - removed
Output schema / properties / data / titleRemoved value: -"Data" - removed
Output schema / properties / error / titleRemoved value: -"Error" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / summary / titleRemoved value: -"Summary" - removed
Output schema / properties / warnings / titleRemoved value: -"Warnings" - removed
Output schema / titleRemoved value: -"Result"
- Changed
project_open11 fields changed- removed
Input schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Input schema / titleRemoved value: -"ProjectRef" - removed
Output schema / properties / changed / titleRemoved value: -"Changed" - removed
Output schema / properties / data / titleRemoved value: -"Data" - removed
Output schema / properties / error / titleRemoved value: -"Error" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / summary / titleRemoved value: -"Summary" - removed
Output schema / properties / warnings / titleRemoved value: -"Warnings" - removed
Output schema / titleRemoved value: -"Result"
- Changed
project_update30 fields changed- removed
Input schema / $defs / Decision / properties / hypothesis / titleRemoved value: -"Hypothesis" - removed
Input schema / $defs / Decision / properties / observation / titleRemoved value: -"Observation" - removed
Input schema / $defs / Decision / properties / review / titleRemoved value: -"Review" - removed
Input schema / $defs / Decision / properties / variant / titleRemoved value: -"Variant" - removed
Input schema / $defs / Decision / titleRemoved value: -"Decision" - removed
Input schema / $defs / Metadata / properties / copyright / titleRemoved value: -"Copyright" - removed
Input schema / $defs / Metadata / properties / family / titleRemoved value: -"Family" - removed
Input schema / $defs / Metadata / properties / license_text / titleRemoved value: -"License Text" - removed
Input schema / $defs / Metadata / properties / style / titleRemoved value: -"Style" - removed
Input schema / $defs / Metadata / titleRemoved value: -"Metadata" - removed
Input schema / $defs / Metrics / properties / ascender / titleRemoved value: -"Ascender" - removed
Input schema / $defs / Metrics / properties / cap_height / titleRemoved value: -"Cap Height" - removed
Input schema / $defs / Metrics / properties / descender / titleRemoved value: -"Descender" - removed
Input schema / $defs / Metrics / properties / units_per_em / titleRemoved value: -"Units Per Em" - removed
Input schema / $defs / Metrics / properties / x_height / titleRemoved value: -"X Height" - removed
Input schema / $defs / Metrics / titleRemoved value: -"Metrics" - removed
Input schema / properties / brief / titleRemoved value: -"Brief" - removed
Input schema / properties / expected_revision / titleRemoved value: -"Expected Revision" - removed
Input schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Input schema / properties / summary / titleRemoved value: -"Summary" - removed
Input schema / titleRemoved value: -"ProjectUpdate" - removed
Output schema / properties / changed / titleRemoved value: -"Changed" - removed
Output schema / properties / data / titleRemoved value: -"Data" - removed
Output schema / properties / error / titleRemoved value: -"Error" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / summary / titleRemoved value: -"Summary" - removed
Output schema / properties / warnings / titleRemoved value: -"Warnings" - removed
Output schema / titleRemoved value: -"Result"
- Changed
render_glyph21 fields changed- removed
Input schema / properties / compare_revision / titleRemoved value: -"Compare Revision" - added
Input schema / properties / detailAdded value: +{ + "default": "summary", + "enum": [ + "summary", + "full" + ], + "type": "string" +} - removed
Input schema / properties / glyph_id / titleRemoved value: -"Glyph Id" - removed
Input schema / properties / guides / titleRemoved value: -"Guides" - removed
Input schema / properties / height / titleRemoved value: -"Height" - added
Input schema / properties / image_modeAdded value: +{ + "default": "inline", + "enum": [ + "inline", + "resource" + ], + "type": "string" +} - added
Input schema / properties / master_idAdded value: +{ + "default": "default", + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" +} - removed
Input schema / properties / points / titleRemoved value: -"Points" - removed
Input schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Input schema / properties / revision / titleRemoved value: -"Revision" - removed
Input schema / properties / width / titleRemoved value: -"Width" - removed
Input schema / titleRemoved value: -"RenderGlyph" - removed
Output schema / properties / changed / titleRemoved value: -"Changed" - removed
Output schema / properties / data / titleRemoved value: -"Data" - removed
Output schema / properties / error / titleRemoved value: -"Error" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / summary / titleRemoved value: -"Summary" - removed
Output schema / properties / warnings / titleRemoved value: -"Warnings" - removed
Output schema / titleRemoved value: -"Result"
- Changed
render_text21 fields changed- removed
Input schema / properties / compare_revision / titleRemoved value: -"Compare Revision" - removed
Input schema / properties / dark / titleRemoved value: -"Dark" - added
Input schema / properties / detailAdded value: +{ + "default": "summary", + "enum": [ + "summary", + "positions", + "full" + ], + "type": "string" +} - added
Input schema / properties / image_modeAdded value: +{ + "default": "inline", + "enum": [ + "inline", + "resource" + ], + "type": "string" +} - removed
Input schema / properties / kern / titleRemoved value: -"Kern" - added
Input schema / properties / locationAdded value: +{ + "maxProperties": 4, + "patternProperties": { + "^[A-Za-z][A-Za-z0-9]{3}$": { + "maximum": 32767, + "minimum": -32768, + "type": "number" + } + }, + "type": "object" +} - removed
Input schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Input schema / properties / revision / titleRemoved value: -"Revision" - removed
Input schema / properties / sizes / titleRemoved value: -"Sizes" - removed
Input schema / properties / text / titleRemoved value: -"Text" - removed
Input schema / properties / width / titleRemoved value: -"Width" - removed
Input schema / titleRemoved value: -"RenderText" - removed
Output schema / properties / changed / titleRemoved value: -"Changed" - removed
Output schema / properties / data / titleRemoved value: -"Data" - removed
Output schema / properties / error / titleRemoved value: -"Error" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / summary / titleRemoved value: -"Summary" - removed
Output schema / properties / warnings / titleRemoved value: -"Warnings" - removed
Output schema / titleRemoved value: -"Result"
- Changed
spacing_edit33 fields changed- removed
Input schema / $defs / Bearings / properties / glyph_id / titleRemoved value: -"Glyph Id" - removed
Input schema / $defs / Bearings / properties / left / titleRemoved value: -"Left" - removed
Input schema / $defs / Bearings / properties / op / titleRemoved value: -"Op" - removed
Input schema / $defs / Bearings / properties / right / titleRemoved value: -"Right" - removed
Input schema / $defs / Bearings / titleRemoved value: -"Bearings" - removed
Input schema / $defs / KernGroup / properties / glyphs / titleRemoved value: -"Glyphs" - removed
Input schema / $defs / KernGroup / properties / name / titleRemoved value: -"Name" - removed
Input schema / $defs / KernGroup / properties / op / titleRemoved value: -"Op" - removed
Input schema / $defs / KernGroup / titleRemoved value: -"KernGroup" - removed
Input schema / $defs / KernPair / properties / left / titleRemoved value: -"Left" - removed
Input schema / $defs / KernPair / properties / op / titleRemoved value: -"Op" - removed
Input schema / $defs / KernPair / properties / right / titleRemoved value: -"Right" - removed
Input schema / $defs / KernPair / properties / value / titleRemoved value: -"Value" - removed
Input schema / $defs / KernPair / titleRemoved value: -"KernPair" - removed
Input schema / $defs / SetAdvance / properties / glyph_id / titleRemoved value: -"Glyph Id" - removed
Input schema / $defs / SetAdvance / properties / op / titleRemoved value: -"Op" - removed
Input schema / $defs / SetAdvance / properties / value / titleRemoved value: -"Value" - removed
Input schema / $defs / SetAdvance / titleRemoved value: -"SetAdvance" - removed
Input schema / properties / expected_revision / titleRemoved value: -"Expected Revision" - added
Input schema / properties / master_idAdded value: +{ + "default": "default", + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", + "type": "string" +} - removed
Input schema / properties / operations / titleRemoved value: -"Operations" - removed
Input schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Input schema / properties / summary / titleRemoved value: -"Summary" - removed
Input schema / titleRemoved value: -"SpacingEdit" - removed
Output schema / properties / changed / titleRemoved value: -"Changed" - removed
Output schema / properties / data / titleRemoved value: -"Data" - removed
Output schema / properties / error / titleRemoved value: -"Error" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / project_id / titleRemoved value: -"Project Id" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / summary / titleRemoved value: -"Summary" - removed
Output schema / properties / warnings / titleRemoved value: -"Warnings" - removed
Output schema / titleRemoved value: -"Result"
- Added
variable_configure
13 tool updates
v0.1.0- First observed
font_build - First observed
font_validate - First observed
glyph_edit - First observed
glyph_get - First observed
history_list - First observed
history_restore - First observed
project_create - First observed
project_inspect - First observed
project_open - First observed
project_update - First observed
render_glyph - First observed
render_text - First observed
spacing_edit
TDQS
Scored across 20 tools
Most tools target distinct font-design resources and phases, such as project setup, glyph editing, rendering, validation, and history. Some boundaries blur between glyph_edit and font_edit, and among render_text, render_glyph, and render_proof, but descriptions and parameters clarify their scopes. Validation-related tools are also distinct enough across validate, analyze, and release_check phases.
The set mostly follows a consistent snake_case resource_action pattern, e.g. project_create, glyph_edit, font_validate, and history_restore. Minor deviations appear in render_text, render_glyph, and render_proof, which use verb-first ordering, and in the longer font_release_check. The convention is still predictable overall.
At 20 tools, the set is slightly above the ideal 3-15 range, but the domain is genuinely complex and spans project setup, variable configuration, editing, rendering, validation, proofing, release checks, import, build, and history. The tools do not appear redundantly padded, so the count is reasonable though heavy.
The surface covers the core font-design lifecycle: project create/open/update/inspect, variable configuration, glyph and font editing, spacing, rendering, validation/analysis, proof review, release checking, reference import, build, and history restore. Minor gaps exist, such as no explicit project listing/deletion or dedicated glyph deletion/export operation, but agents have workarounds and the critical paths are present.
Maintenance
Related MCP Connectors
AI-agent design tools: fonts, font recognition, palettes, color naming, contrast, code, SVG, CSS.
Cross-agent artifact workspace with provenance across Claude Code, Codex, Cursor, LangGraph.
Git-backed platform for skills, tools, and context for AI agents
Agent-Native design tool - create and edit visual designs with agent assistance
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to diagnose, modify, and validate OTF/TTF fonts interactively through a set of read-only, write, and validation tools.-
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with FontLab for font design and manipulation, including querying font metadata, creating/modifying glyphs, applying transformations, and exporting fonts.8MIT
- AlicenseNot gradedqualityCmaintenanceMCP bridge for AI-assisted type design in GlyphsApp. Lets Claude, Cursor, or any MCP client read and write font data directly in GlyphsApp — bidirectional, real-time, live in the editor.7MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI tools to create and edit Font Proof documents for type designers, supporting PDF font proofs and live-reload from Glyphs.app.15 npmMIT