Skip to main content
Glama

PostScript MCP

An MCP server that gives AI agents the tools to write high-quality PostScript — grounded in the Adobe manuals and Kees van der Laan's PSlib rather than guessed from memory.

It exposes four capabilities:

Capability

Tools

What it does

Render & validate

validate_postscript, render_postscript

Run a program through Ghostscript, get a PDF/PNG/SVG and structured diagnostics — the write→check→fix loop that lets an agent self-correct.

Operator lookup

lookup_operator, search_operators

Exact PLRM operator definitions (stack signature, LanguageLevel, errors). 270 operators shipped, offline.

PSlib fragments

get_pslib_fragment, search_pslib

Retrieve van der Laan's vetted procedures by name, with their stack signatures and source, so agents reuse code instead of reinventing it.

Reference search

search_reference

Cited passages from the PLRM, Blue/Green books, DSC/EPS specs and tutorials.

Plus postscript_capabilities for setup/debugging.


Why

LLMs write plausible-looking PostScript that fails on a real interpreter: wrong operand order, undefined names, unbalanced gsave/grestore, EPS files with no %%BoundingBox. This server closes that gap. The agent can confirm an operator's signature before using it, paste in a procedure that is known to work, quote the spec when behaviour is subtle, and — crucially — actually run the program and read the errors back before handing code to a human.

Pair it with the skill suite for the authoring conventions.


Related MCP server: Font Tools MCP

Requirements

  • Python 3.10+

  • Ghostscript — the gs binary (rendering & validation)

    • macOS: brew install ghostscript · Debian/Ubuntu: apt install ghostscript

    • Windows: the official installer, then ensure gswin64c.exe is on PATH

  • pdftotext (poppler-utils) — only needed to build the reference corpus

    • macOS: brew install poppler · Debian/Ubuntu: apt install poppler-utils

Install

cd postscript-mcp
python -m venv .venv && source .venv/bin/activate      # optional
pip install -e .                                        # installs the `mcp` dep

That is enough for operator lookup and render/validate to work immediately (the operator dataset ships in data/operators.json).

Build the indexes (PSlib + reference corpus)

Point the ingester at your PostScript reference library — the folder with the Adobe PDFs and the PSlib sources (this project was built around exactly such a library; see the accompanying REFERENCE_INDEX.md):

python scripts/ingest.py --library "/path/to/postscript reference"

This writes:

  • data/pslib_index.json — every PSlib procedure, parsed from PSlib.ps / PSlib.eps (auto-discovered; or pass --pslib PSlib.ps).

  • corpus/corpus_index.json — one searchable chunk per PDF page and per block of each .ps/.txt source.

Re-run it whenever your library changes. Useful flags: --skip-corpus, --skip-pslib, --pslib <files…>, --library, --corpus, --data.

You can also set defaults via environment variables (below) instead of flags.

Connect it to a client

Claude Desktop

Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\):

{
  "mcpServers": {
    "postscript": {
      "command": "python",
      "args": ["-m", "postscript_mcp"],
      "env": {
        "PSMCP_LIBRARY_DIR": "/path/to/postscript reference",
        "PSMCP_DATA_DIR": "/path/to/postscript-mcp/data",
        "PSMCP_CORPUS_DIR": "/path/to/postscript-mcp/corpus"
      }
    }
  }
}

If you installed with pip install -e ., you can use the console script instead: "command": "postscript-mcp", "args": []. Point command at the Python inside your virtualenv if you used one.

Claude Code

claude mcp add postscript -- python -m postscript_mcp

(run from the project directory, or give the absolute interpreter path).

Any MCP client

The server speaks MCP over stdio: launch python -m postscript_mcp.

Remote / cloud deployment (public HTTPS endpoint)

To expose this server on the network so any client can reach it over HTTP, see the deployment guides. It serves MCP over Streamable HTTP at /mcp, containerised with Docker (Ghostscript included):

  • DEPLOY_RENDER.md — recommended, free, no credit card: deploy to the Render free tier (GitHub sign-in) and point your own domain at it.

  • DEPLOY.md — alternative: a free Oracle Cloud Always Free VM running Docker + Caddy (TLS).

{
  "mcpServers": {
    "postscript": {
      "type": "http",
      "url": "https://mcp.example.com/mcp"
    }
  }
}

Tool reference

validate_postscript(source="", path="") → {ok, diagnostics[], bbox, hires_bbox, hint, …} Interpret without rasterising (fast). Diagnostics carry error, offending_command and whether it is a genuine interpreter error. hint gives a plain-language nudge for common failures. Great for filling an EPS %%BoundingBox from hires_bbox.

render_postscript(source="", path="", output_format="png", resolution=150, page=None, eps_crop=True, return_base64=False) → {ok, output_path, page_count, bbox, diagnostics[], …} output_format ∈ png, png-alpha, pdf, svg. Returns the output file path; set return_base64=True to also get PNG bytes inline.

lookup_operator(name) → the operator's signature, operands, results, summary, category, level, errors. On a miss, returns did_you_mean.

search_operators(query, category="", limit=20) → ranked operators, or a whole category listing.

get_pslib_fragment(name) → {signature, source, category, attribution, line} for one PSlib procedure.

search_pslib(query="", category="", limit=20) → matching procedures (names + one-line signatures); follow up with get_pslib_fragment.

search_reference(query, limit=8, doc="") → cited passages {doc, page, snippet, score}. Restrict to a document with doc (e.g. "PLRM", "Green", "DSC").

postscript_capabilities() → what is available right now (Ghostscript present? indexes built?) and how to build what is missing.

  1. Draft using lookup_operator / search_pslib + get_pslib_fragment.

  2. Consult search_reference when behaviour is subtle (imaging model, save/restore, DSC rules).

  3. Check with validate_postscript — fix every diagnostic.

  4. Render with render_postscript and, for figures, verify the bounding box and that the image looks right.

  5. For embeddable output, emit a correct %%BoundingBox and DSC comments (see examples/square.eps).


Configuration (environment variables)

Variable

Default

Purpose

PSMCP_LIBRARY_DIR

./library

Where your reference PDFs / PSlib sources live (for ingest).

PSMCP_DATA_DIR

./data

Location of operators.json and pslib_index.json.

PSMCP_CORPUS_DIR

./corpus

Location of the search corpus.

PSMCP_GHOSTSCRIPT

auto-detected

Path to the gs binary.

PSMCP_OUTPUT_DIR

temp dir

Where rendered files are written.

PSMCP_RENDER_TIMEOUT

30

Ghostscript wall-clock limit (seconds).

PSMCP_MAX_SOURCE_BYTES

4194304

Max program size accepted.

Safety

Every Ghostscript invocation uses -dSAFER (no arbitrary file writes / device control from the program) and a wall-clock timeout, and source size is capped. The server never executes PostScript except through Ghostscript.

Development

pip install -e ".[dev]"
python scripts/gen_operators.py     # regenerate data/operators.json
python -m pytest -q                 # run the test suite

Layout

postscript_mcp/      server + the four capability modules
  server.py          FastMCP wiring (the tools)
  render.py          Ghostscript validate/render
  operators.py       operator reference access
  pslib.py           PSlib tokeniser / parser / index
  reference.py       BM25 corpus search
  config.py          paths & limits from env
data/operators.json  curated PLRM operator reference (shipped)
scripts/ingest.py    build pslib_index.json + corpus from your library
scripts/gen_operators.py   rebuild the operator dataset
skills/              agent skill suite (see below)
examples/            conformant EPS + PSlib usage
tests/               pytest suite (+ a real PSlib fixture)

Skills

The skills/ folder holds a composable suite an agent loads alongside this server:

  • postscript-authoring — stack discipline, structure, the render/verify loop.

  • postscript-pslib — reusing van der Laan's library correctly.

  • postscript-eps-dsc — conformant EPS / DSC output for embedding & print.

Credits & licences

  • PSlib © Kees van der Laan (kisa1@xs4all.nl) — parsed and indexed here for reference; its own terms apply to the code itself.

  • Operator reference curated from the PostScript Language Reference Manual, 3rd ed. (Adobe, 1999).

  • This server's code: MIT (see LICENSE).

Available Tools

8 tools
get_pslib_fragmentA

Return a PSlib procedure by name, with its stack signature and source.

PSlib is Kees van der Laan's library (colours, geometry such as circle inversion and Apollonius, Lauwerier fractals, Blue-Book text/graphics helpers). Reuse these vetted procedures instead of reinventing them. The source is ready to paste; include the whole library at run time with e.g. (PSlib.eps) run.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses the output (stack signature and source), notes that the source is 'ready to paste,' and explains how to include the library. This is good behavioral transparency for a read-only retrieval. It does not mention failure behavior (e.g., if name is not found), but for a simple getter, this is a minor gap. The description adds value beyond what structured fields provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded with the core purpose. The background on PSlib (Kees van der Laan's library) and the reuse advice are useful context that earns their place. It is two short paragraphs without wasted words, though the second sentence could be trimmed without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with one parameter and no output schema, the description is quite complete. It states what the tool returns (procedure, stack signature, source) and how to use the source. It does not describe the exact structure of the stack signature or error handling, but these are minor for a retrieval tool. Overall, an agent has enough context to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has a single 'name' parameter with 0% description coverage. The description clarifies that 'name' refers to a PSlib procedure, which adds some meaning beyond the bare schema. However, it does not specify the format, case sensitivity, or provide examples, leaving the agent to infer the exact expected value. Since schema coverage is zero, the description partially compensates but not fully.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action: 'Return a PSlib procedure by name, with its stack signature and source.' It names the specific resource (PSlib procedures) and the output. This distinguishes it from siblings like search_pslib, which would be for finding procedures without knowing the name, and lookup_operator, which targets operators. The purpose is unambiguous and specific.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear usage rationale: 'Reuse these vetted procedures instead of reinventing them,' implying the tool should be used when a known PSlib procedure is needed. It also explains how to include the whole library at runtime. However, it does not explicitly state when not to use this tool or compare it with siblings like search_pslib, 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.

lookup_operatorA

Return the exact PLRM definition of a PostScript operator.

Gives the stack signature (operands operator results), a summary, the LanguageLevel it requires, and the errors it can raise. Use this to get operand order and types right instead of guessing.

Example: lookup_operator("arc") → signature "x y r ang1 ang2 arc -", category "path", level 1.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must disclose behavior. It states the return content (signature, summary, level, errors) and gives an example output, implying a read-only operation. It does not cover error handling (e.g., unknown operator), a minor omission, but the description is largely transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured: purpose first, then details, then usage guidance, and finally an example. Every sentence adds value with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter lookup with no output schema, the description covers purpose, return details, and usage. It lacks information about error behavior or edge cases, but these are minor for the tool's simplicity. The example adds practical completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. The example 'lookup_operator("arc")' implies the 'name' parameter is the operator name, but it does not explicitly define it or mention constraints like case sensitivity or exact spelling. The description adds some value but is not fully explicit.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Return the exact PLRM definition') and the resource (a PostScript operator). It also enumerates the specific details returned (stack signature, summary, LanguageLevel, errors) and includes an example, making it distinct from sibling search tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says 'Use this to get operand order and types right instead of guessing,' providing a clear use case. However, it does not mention when to avoid this tool or suggest alternatives like search_operators, so exclusions are not explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

postscript_capabilitiesA

Report what this server can currently do (for setup/debugging).

Tells you whether Ghostscript is available for rendering, how many operators are loaded, whether the PSlib index and reference corpus have been built, and how to build them if not.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, and the description implies a read-only reporting operation without explicitly stating side effects or safety. It describes what information is reported but not behavioral guarantees like no modification or cost implications, leaving some burden on the agent to infer safety.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences that directly state the tool's function and the key reported items. No fluff or unnecessary detail, making it efficient and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description adequately lists the key information returned (Ghostscript availability, operator count, PSlib index/reference corpus status) and even mentions guidance on building if missing. It does not specify the exact format or data types, but for a simple status report this is reasonably complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so there is no parameter semantics to describe. The description correctly focuses on the report content, and no additional parameter guidance is needed or missing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool reports server capabilities, specifically Ghostscript availability, operator count, PSlib index and reference corpus status. This is a distinct purpose from sibling tools like lookup, search, or render.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly mentions 'for setup/debugging', giving a clear when-to-use context. It does not explicitly contrast with siblings, but the setup/debugging framing is sufficient guidance for when this status tool is appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

render_postscriptA

Render a PostScript/EPS program to a PDF, PNG or SVG file.

output_format is one of: "png", "png-alpha", "pdf", "svg". resolution is DPI for raster output. page (1-based) renders a single page. eps_crop trims to the bounding box (good for EPS figures). Set return_base64 to also receive PNG bytes inline for quick preview.

Provide EITHER source or path. The output file path is returned so a human can open it. Diagnostics are reported the same way as validate_postscript — always check ok and fix any diagnostics.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo
pathNo
sourceNo
eps_cropNo
resolutionNo
output_formatNopng
return_base64No

TDQS

A4.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations, so description carries full burden. Discloses output file path, optional base64 return, and diagnostics pattern. Doesn't mention file overwrite behavior, permissions, or cleanup. Adequate but not exhaustive for a file-writing tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Efficient and front-loaded: purpose stated first, then parameter details in a compact semicolon-separated list. No redundant or filler sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers purpose, all parameters, output behavior (path, base64), error handling via ok/diagnostics, and usage constraints (source/path). For a tool with no output schema and 0% param coverage, this is thorough and actionable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, but the description explains all 7 parameters: output_format allowed values, resolution purpose (DPI for raster), page 1-based, eps_crop trimming, return_base64 behavior, and source/path exclusivity. Comprehensive compensation for missing schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear verb+resource: 'Render a PostScript/EPS program' to specified output formats. Distinguishes itself from siblings like validate_postscript (validation) and postscript_capabilities (capabilities) by focusing on output generation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit usage instructions: 'Provide EITHER source or path', recommends eps_crop for EPS figures, and suggests return_base64 for quick preview. References validate_postscript for diagnostics, implying when to use this vs. validation. Lacks explicit exclusions but context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_operatorsA

Search PostScript operators by keyword or browse a category.

Pass a query (e.g. "rotate", "fill path", "cmyk") to rank operators by relevance, or a category to list it. Categories include: stack, math, array, dict, string, boolean, control, type, file, vm, gstate, color, matrix, path, paint, text, font, device, resource, misc.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
categoryNo

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description bears full responsibility for behavioral disclosure. It mentions 'rank operators by relevance' and 'browse a category,' implying sorting and listing behavior, but it leaves key behaviors unspecified: what happens if both query and category are supplied, how the limit parameter affects results, whether partial matches are supported, and what the response structure looks like. These ambiguities are not severe for a read-only search tool, but they are notable gaps, warranting a 3.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two compact paragraphs. The first sentence delivers the core purpose. The second paragraph gives actionable instructions, examples, and a complete category list. There is no redundant phrasing, and every sentence contributes to the agent's ability to use the tool correctly. It is well-structured and appropriately sized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is a simple search with three parameters and no output schema. The description covers the input side well, but it does not describe the return value (e.g., what fields each operator entry includes) or clarify edge cases like empty results or behavior when both query and category are provided. Given that there is no output schema, the description should at least hint at what the agent can expect in response, which it does not. This leaves the agent with gaps in understanding the tool's full behavior, so a 3 is appropriate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does so for two of three parameters: it explains 'query' with examples and its role in relevance ranking, and it explains 'category' by listing all accepted values. However, it says nothing about the 'limit' parameter, leaving its purpose (likely pagination) implicit. Since most parameters are clarified with concrete details, this is strong compensation, though not complete, hence a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear statement: 'Search PostScript operators by keyword or browse a category.' It identifies a specific resource (PostScript operators) and two distinct modes of use. The examples ('rotate', 'fill path', 'cmyk') further clarify intent and distinguish it from sibling tools like search_pslib (which likely searches library fragments) and search_reference (which might search reference docs). This is a well-defined purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says how to use the tool: pass a query for keyword search or pass a category to list operators. It even enumerates the valid categories. However, it does not contrast with sibling tools like lookup_operator (which likely retrieves a single operator by exact name) or explain when search_operators would be preferred over them. It provides clear context but lacks explicit exclusions or alternative routing, so it earns a 4 rather than a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_pslibA

Search or browse PSlib procedures.

Pass a query (e.g. "dragon", "circle inversion", "cmyk colour") or a category (color, fractal, geometry, text, complex, linalg, arrow, units, util, misc). Returns names with one-line signatures; call get_pslib_fragment to retrieve full source.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryNo
categoryNo

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses what the tool returns ('names with one-line signatures') and that full source is not included, providing some transparency. However, it does not explicitly mention side effects, errors, or that it is read-only. Since there are no annotations to supplement, the description carries the full burden and falls short of fully disclosing behavioral traits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is exceptionally concise, using only three sentences to state purpose, usage, and output format. It front-loads the primary action and avoids any redundant information, making it highly efficient and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the presence of sibling tools like get_pslib_fragment and search_operators, the description adequately positions itself as a search tool and points to the next step for full source. It does not cover edge cases (e.g., what happens if both query and category are provided), but for a straightforward search tool, the provided context is sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage, so the description must compensate. It explains 'query' with examples and 'category' with a list of values, but it does not explain the 'limit' parameter at all, leaving a gap. Thus, it partially compensates for the lack of schema descriptions but not completely.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the tool's function ('Search or browse PSlib procedures') and provides concrete examples of queries and categories, making its purpose unmistakable. It also distinguishes itself by mentioning that it returns names with signatures, implying it is not for full source retrieval.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives direct usage instructions ('Pass a query or a category') with illustrative examples for both parameters. It also guides the user to 'call get_pslib_fragment to retrieve full source,' indicating a follow-up step. However, it does not explicitly state when to choose this tool over siblings like search_operators, though the context implies it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_referenceA

Search the PostScript reference corpus and return cited passages.

Covers whatever was ingested: the PLRM, the Blue and Green books, the DSC and EPS specifications, and the tutorials. Optionally restrict to one document with doc (substring of its name, e.g. "PLRM", "Green", "DSC"). Each hit includes the document, page/block number and a snippet so you can cite the spec precisely.

ParametersJSON Schema
NameRequiredDescriptionDefault
docNo
limitNo
queryYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden, and it does well: it discloses the return format ('document, page/block number and a snippet'), the substring-match filtering behavior of doc, and the scope limitation to ingested material. It stops short of noting edge cases like empty-result behavior or the effect of the limit parameter, but the core behaviors are transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact paragraphs with the core purpose front-loaded in the first sentence. The second paragraph adds scope, filtering semantics, and return format — all useful, none redundant. No filler or repetition of schema details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a search tool with 3 params, no output schema, and no annotations, the description is reasonably complete: it specifies what is searched, how filtering works, and what each hit contains. The only gaps are limit behavior and empty-result handling, which are minor for a search tool whose return format is already disclosed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It adds real value for 'doc' by explaining substring matching with concrete examples ('PLRM', 'Green', 'DSC'). However, 'query' and 'limit' are left to inference from their names/types, which are fairly self-evident. The description covers the one non-obvious parameter but not the other two.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: 'Search the PostScript reference corpus and return cited passages.' It enumerates the exact corpus contents (PLRM, Blue/Green books, DSC/EPS specs, tutorials), which clearly distinguishes it from siblings like search_operators (operator-specific) and search_pslib. An agent can tell what it targets without inspecting other tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The corpus description ('Covers whatever was ingested...') implies when to use it — when you need to cite a PostScript specification — but it never explicitly names alternatives or exclusions. It does not say 'use search_operators for operator syntax' or otherwise route between sibling search tools. The guidance is implied, not stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_postscriptA

Interpret a PostScript/EPS program WITHOUT rasterising and report errors.

This is the fast self-check to run before presenting any PostScript. It uses Ghostscript's bbox device, so it catches real interpreter errors (undefined names, stack underflow, type errors, unbalanced save/restore) and returns the computed bounding box — useful for setting an EPS %%BoundingBox.

Provide EITHER source (the program text) or path (a file on disk).

Returns: {ok, diagnostics[{error, offending_command, message, is_postscript_error}], bbox, hires_bbox, hint, ghostscript_stderr}.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNo
sourceNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden and largely delivers: it discloses the mechanism (Ghostscript's bbox device), enumerates the specific errors caught (undefined names, stack underflow, type errors, unbalanced save/restore), and details the return structure including ok, diagnostics, bbox, hires_bbox, hint, and ghostscript_stderr. This is transparent for a validation tool whose read-only nature is implied by 'WITHOUT rasterising.'

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured into focused paragraphs: core purpose first, then usage context, then parameter guidance, then return format. Every sentence earns its place, and the return-format line is justified given the absence of an output schema. Slightly long but appropriately front-loaded with the most critical scoping information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 2-parameter tool with no annotations and no output schema, the description is remarkably complete: it explains the return format (essential since no output schema exists), the parameter semantics, the underlying mechanism, and the error categories detected. Minor omissions include handling when both or neither parameter is provided, but nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it does meaningfully: 'Provide EITHER source (the program text) or path (a file on disk)' explains what each parameter holds and, critically, the exclusive either/or relationship between them. This adds substantial value beyond the bare schema titles, though it stops short of detailing formats or error behavior when neither is supplied.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening line, 'Interpret a PostScript/EPS program WITHOUT rasterising and report errors,' uses a specific verb (interpret/validate), a clear resource (PostScript/EPS), and a differentiating qualifier (WITHOUT rasterising) that separates it from the sibling render_postscript. The purpose is unmistakable and immediately distinguishes this validation tool from its rendering counterpart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly states when to use it: 'This is the fast self-check to run before presenting any PostScript.' It also frames the alternative implicitly through 'WITHOUT rasterising,' implying render_postscript is the choice when rasterized output is needed. However, it never names alternatives explicitly or states when NOT to use it, leaving a small gap in exclusion guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 8 tool updatesv0.1.0
    • First observedget_pslib_fragment
    • First observedlookup_operator
    • First observedpostscript_capabilities
    • First observedrender_postscript
    • First observedsearch_operators
    • First observedsearch_pslib
    • First observedsearch_reference
    • First observedvalidate_postscript

TDQS

A4.3/5.0

Scored across 8 tools

Disambiguation5/5

Each tool targets a distinct job: exact operator definitions vs operator search, validation vs rendering, PSlib retrieval vs searching, and reference/capability lookups. Even the paired search/get tools are clearly separated by role.

Naming Consistency4/5

Most tools follow a consistent verb_noun pattern (lookup_operator, validate_postscript, search_operators). The only deviation is postscript_capabilities, which lacks a verb; otherwise the naming is uniform and predictable.

Tool Count5/5

Eight tools is an appropriate size for a PostScript assistant: each one covers a necessary stage of authoring, checking, rendering, and reference lookup without redundancy. The count feels intentional rather than padded.

Completeness5/5

The surface covers a full workflow: discover operators, validate code, render output, reuse library procedures, and consult authoritative references. There are no dead ends or obvious missing operations for the stated domain.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    Not graded
    maintenance
    Enables AI assistants to render 3D models by providing tools to execute OpenSCAD code and generate single or multi-perspective views. It returns high-quality PNG renderings directly to LLM applications for visual feedback and 3D model visualization.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to diagnose, modify, and validate OTF/TTF fonts interactively through a set of read-only, write, and validation tools.
    -