Skip to main content
Glama

deliverable-mcp

A zero-dependency MCP server that exposes a document delivery pipeline — render, page-count, verify, ship — as tools any MCP client can call.

Built because shipping a document reliably is the part people get wrong: the file renders, but it's empty, or it's the wrong page count, or it overwrote the wrong path. This server makes those failures impossible to ignore.

Speaks Model Context Protocol (JSON-RPC 2.0 over stdio) directly. No SDK, no framework, nothing to install but Python.


Why this exists

I run a content pipeline that produces resumes, reports, and decks. Every failure mode I hit was a delivery failure, not a generation failure:

Failure

What it looked like

Empty artifact shipped

pdftoppm produced 0 pages, link still went out

Wrong page count

2-page resume rendered as 4 pages, unnoticed

Silent overwrite

New build clobbered the previous approved version

Wrong destination

File written to a path no one serves

Each of those is now a gate in the pipeline. The MCP server is how any agent — Claude Desktop, Cursor, a fleet of my own agents — calls those gates without reimplementing them.


Related MCP server: mcp-server-markdown

Tools

Tool

Purpose

Returns

render_markdown

Markdown → HTML

HTML document

count_pages

Estimate rendered page count

{pages_estimate, bytes, basis}

verify_delivery

Assert exists, non-empty, within size bounds

{verified: true, bytes}

ship

Atomically copy into a public directory

{shipped, bytes}


Run it

python -m deliverable_mcp

It reads newline-delimited JSON-RPC on stdin and writes responses on stdout — the standard MCP stdio transport.

Manual smoke test

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
  '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"render_markdown","arguments":{"markdown":"# Hello"}}}' \
| python -m deliverable_mcp

Client configuration (e.g. Claude Desktop)

{
  "mcpServers": {
    "deliverable": {
      "command": "python",
      "args": ["-m", "deliverable_mcp"],
      "cwd": "/path/to/deliverable-mcp"
    }
  }
}

Protocol coverage

Method

Implemented

initialize

✅ handshake + capabilities

tools/list

✅

tools/call

✅

ping

✅

notifications/*

✅ accepted, no response (per spec)

unknown method

✅ -32601

malformed JSON

✅ -32700

bad tool input

✅ -32602

Errors are returned as proper JSON-RPC error objects — the server never crashes on bad input.


Design decisions

No SDK on purpose. The official mcp package is convenient, but the wire protocol is small and worth owning. Implementing it directly means the server runs anywhere Python runs, with zero install friction, and the whole thing is auditable in one sitting. That auditability is the point for a tool that gates what gets shipped.

Escape-then-format rendering. render_markdown escapes HTML before applying inline formatting, so <script> in input becomes text, never markup. Injection-safe by construction rather than by blocklist.

Atomic ship. ship writes to a .tmp file and os.replaces it into place, and refuses to overwrite unless explicitly told to. A partially-written artifact never becomes the live one.

Gates as tools. Verification isn't a side effect tucked inside a render function — it's a separately callable tool. That means a client can verify anything, including artifacts it didn't produce.


Tests

pip install pytest
pytest

16 tests covering the full protocol surface (initialize, list, call, notifications, unknown methods, parse errors) and every tool including the failure paths: HTML escaping, page estimation, empty/oversized rejection, overwrite protection, and stdio transport with real JSON-RPC lines.

No network. No API keys. No SDK. Pure stdlib + pytest.


Layout

deliverable_mcp/
├── __init__.py     public exports
├── __main__.py     python -m deliverable_mcp
├── server.py       JSON-RPC transport + method dispatch
└── tools.py        the four tool implementations + MCP schemas
tests/
└── test_server.py  protocol and tool tests

License

MIT

Available Tools

4 tools
count_pagesA

Estimate page count for a rendered artifact.

Inputs: path (required), chars_per_page.

render_markdownA

Render a Markdown string to an HTML document.

Inputs: markdown (required), title.

shipC

Copy a verified artifact into a public directory.

Inputs: src (required), dest_dir (required), overwrite.

verify_deliveryC

Verify an artifact exists, is non-empty, and is within size bounds.

Inputs: path (required), max_bytes, min_bytes.

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    B3.4/5.0

    Scored across 4 tools

    Disambiguation5/5

    Each tool performs a distinct, non-overlapping operation: rendering, counting, verifying, and shipping. There is no ambiguity about which tool to choose for a given step in the workflow.

    Naming Consistency4/5

    Three tools follow the verb_noun pattern (render_markdown, count_pages, verify_delivery), but 'ship' breaks the pattern with a bare verb. Still, the names are clear and predictable overall.

    Tool Count5/5

    Four tools cover a focused deliverable pipeline without redundancy or excess. The count is well-suited to the server's narrow purpose.

    Completeness4/5

    The suite covers the core lifecycle from rendering to shipping, but lacks features like listing or retrieving existing deliverables. This is a minor gap that agents can work around.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers