Skip to main content
Glama
justdukkan

invoice-intake-mcp

by justdukkan

invoice-intake-mcp

Reference implementation of the tool-design rules in Designing MCP servers and tools that agents can use safely, on a real back-office process: supplier invoice intake.

It is small on purpose. The fake ERP is a JSON file; everything else is the shape we use in production systems.

What it shows

Rule

Where

Model the business operation, not the API

erp_match_po, erp_stage_invoice, not PATCH /invoices

Separate reads, drafts and commits

--role read server (reads + reversible staging) vs --role commit server (irreversible post)

Strict schemas

Literal enums for currency, ids not names, found=false as a valid empty result

Permissions on the server and credential

specialist agents get read; only the orchestrator connects to commit

Tool results are untrusted input

invoices_extract says so in its description; the eval set includes a prompt-injection case

Typed errors

{"error": "approval_required" | "validation_failed" | "business_rule" | "not_found", "retryable": bool, ...}

Log for the auditor

audit.jsonl: actor, tool, ids, approval reference

Human checkpoint enforced server-side

erp_post_invoice refuses without a recorded approval, whatever the client believes

Related MCP server: Ledger

Run it

python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"

python -m invoice_intake_mcp.orchestrator            # process the inbox
python -m invoice_intake_mcp.approve list            # see what is waiting
python -m invoice_intake_mcp.approve APR-xxxx approved --by cfo
python -m invoice_intake_mcp.orchestrator --resume   # post the approved item
cat audit.jsonl

Expected first run:

plan: 4 new invoices -> extract, resolve vendor, match, stage, post-or-approve
  invoice_2291.pdf: staged STG-… -> WAITING for APR-…        (7,420 EUR > 5,000 limit)
  invoice_2292.pdf: match=goods_not_received -> REVIEW
  invoice_2293.pdf: match=variance {"variance_pct": 2.34} -> REVIEW
  invoice_2294.pdf: no PO reference -> REVIEW (ask requester)

The orchestrator is deterministic so the flow replays without an API key. An LLM belongs in the places marked in orchestrator.py (ambiguous vendor candidates, free-text remarks, the note back to the requester), not in the match rule, the tolerance or the approval limit.

Use the servers from an MCP client

{
  "mcpServers": {
    "invoice-intake-read":   { "command": "uvx", "args": ["invoice-intake-mcp", "--role", "read"] },
    "invoice-intake-commit": { "command": "uvx", "args": ["invoice-intake-mcp", "--role", "commit"] }
  }
}

Give an agent only the read server unless it is the orchestrator.

Tests and evals

pytest                 # unit tests on the core operations and the gate
python evals/run.py    # replayable decision cases, run on every change

Layout

invoice_intake_mcp/
  core.py          business operations + policy (tolerance, approval limit), pure functions
  server.py        the two MCP servers and their tool descriptions
  orchestrator.py  minimal hub over MCP stdio: read server for work, commit server for posting
  approve.py       the human decision, as a CLI
  audit.py         append-only JSONL audit log
  erp.py           fake ERP / inbox state (JSON file)
tests/             pytest
evals/             cases.jsonl + run.py

MIT. Built by JustDukkan, AI solutions architecture.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    An accounting-ops agent that reconciles payments against open orders, auto-books provably safe payments through a deterministic policy gate, and escalates exceptions to a human queue with audit trails.
    MIT
  • F
    license
    A
    quality
    B
    maintenance
    Exposes a ledger system (invoice queue, duplicate control, VAT register, contractor history, decision journal) as MCP tools for AI agents, enabling accurate invoice processing with deterministic validation.
    7
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to safely mutate business state by demonstrating phase-gating, validation-before-mutation, and structured audit logging in a toy inventory and purchase order system.
    -