Skip to main content
Glama
Kydaix

Font Design MCP

by Kydaix

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.

CI Python: 3.11–3.13 License: MIT

English · Français

Get started · Connect a client · Documentation · Report an issue


Get started

  1. Clone the repository and install the dependencies with the commands below.

  2. Run the diagnostic and demo to generate your first font specimen.

  3. 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. Install from source; this version is not published to PyPI.

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 ./workspace

doctor checks the installed dependencies and rasterizes a PNG. 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

specimen.html

Read-only previews and links to the generated fonts; no web server needed

demo-calls.json

The MCP calls and their structured results

demo-report.json

Project, revision, source, build, and validation references

revisions/ and artifacts/

UFO snapshots, PNGs, TTF/WOFF2, parameters, and hashes

Generated workspaces stay local and are ignored by Git.

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.

Miette, an original rounded typeface created with Font Design MCP

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 = 180

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

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.

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

project_create

Create a project with metadata, metrics, and an optional brief

project_open

Reopen a server-created project and verify its integrity

project_inspect

Read metadata, metrics, kerning, and a paginated glyph inventory

project_update

Update the brief, supported metadata, vertical metrics, or decision journal

glyph_get

Inspect contours, IDs, components, anchors, advance, bounds, and bearings

glyph_edit

Apply a typed, atomic vector-editing batch to a glyph

spacing_edit

Set advances, side bearings, kerning pairs, and kerning groups

render_glyph

Render a glyph with optional guides, handles, and revision comparison

render_text

Compile, shape, and render text at multiple sizes

font_validate

Check geometry, Unicode coverage, compilation, and OpenType tables

font_build

Export TTF and/or WOFF2 from a frozen revision

history_list

Browse committed revisions and change summaries

history_restore

Restore an earlier state by creating a new revision

Exact JSON schemas · Detailed tool reference, in French

Save and restore your work

UFO 3 is the authoritative typography source. Fonts and images are derived artifacts tied to a revision:

workspace/<project_id>/
├── HEAD.json
├── revisions/<revision>/
│   ├── source.ufo/
│   └── manifest.json
└── artifacts/<artifact_id>/
    ├── font.ttf / font.woff2 / image.png
    └── artifact.json

Edits 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. See the architecture and recovery notes, in French for details.

Supported formats and limits

Current scope: static fonts with one master, 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.

Not supported in this version: OTF, variable fonts, multiple masters, 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. General combining-mark positioning (mark/mkmk) and complex-script coverage are not advertised. 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 build

Output: dist/. Dependency versions are pinned in pyproject.toml and uv.lock; requirements.lock provides a hashed export for pip installations.

Checks

uv run --frozen pytest -q
uv run --frozen ruff check src tests scripts examples
uv run --frozen python tests/test_acceptance.py

The 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

21 local tests passed, including real STDIO calls, builds, rendering, recovery, and embedding defaults

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

The CI result covers its runner environments, not every OS version or CPU architecture. The original delivery report, in French records the local tests before CI was first run.

Documentation

English is the default README language; a French README is also maintained. The detailed guides currently remain in French, except the dependency inventory and machine-readable schemas.

Reference

Contents

Tool reference

Input conventions, vector operations, spacing, results, and error codes

JSON schemas

Schemas exported from a live tools/list call

Architecture

Domain, persistence, rendering, compilation, limits, and recovery

Test report

Original acceptance evidence, captures, and remaining visual review

Dependency licenses

Locked dependencies and native-library notices

Initial audit

Development environment, technical choices, and official sources

Credits and license

Built with the official MCP Python SDK, UFO sources, HarfBuzz, and FreeType/Pillow. See dependency licenses for third-party notices.

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.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Kydaix/Font-Design-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server