erp-mcp
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., "@erp-mcp Preview posting invoice FTR2026000123 for vendor tax ID 4821963570"
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.
erp-mcp
A Model Context Protocol server that gives an agent guarded access to an ERP REST API: look up vendors and purchase orders, and post vendor invoices. It ships with a small mock ERP, so it runs and is tested without a real system.
The interesting part of putting an agent in front of an accounting system is not the read tools. It is making sure a write happens once, after a person has seen it, and that a failure tells the model what to do next. This repository is a worked example of that. The code is written from scratch; it contains no client code or data.
Tools
Tool | Kind | What it does |
| read | Find vendors by name or tax number, at most 10 matches |
| read | A vendor's orders with the amount still open, paged |
| read | One order by number |
| write | Run the posting checks; post only when |
Related MCP server: namakan-mcp-erp
Design decisions
Writes are two-step.
post_vendor_invoicewithoutconfirmruns every check and returns a preview; nothing is sent to the ERP. The server instructions tell the model to show the preview and post only after the user agrees. A failed check blocks the posting even whenconfirmis true.Posting is idempotent. The idempotency key is derived from vendor and invoice reference, so a retry after a timeout returns the document that was already created instead of creating a second one. A later attempt to post the same reference is caught by the duplicate check before anything is written.
Checks are data, not prose. The result lists each check (
vendor,amounts,currency,duplicate,purchase_order) with pass or fail and the values compared, so the model can explain what is wrong and a host application can render it.Errors say what to do next. ERP errors are mapped to tool errors with a stable code and one line of advice per code: retry, ask the user, or stop. A timeout on a posting says the call is safe to repeat.
Arguments are validated by the schema. Amount ranges, the currency pattern, the status enum and page limits are part of the tool's input schema, so invalid calls are rejected before the ERP is called.
The ERP is behind one module.
client.pyis the only place that knows paths, headers and the error format. The API key lives there and never appears in tool input or output.Typed, bounded results. Tools return Pydantic models, so results carry an output schema. Lists are capped and paged with
next_offset.
Quick start
pip install -e ".[dev]"
pytestRun it against the mock ERP:
ERP_API_KEY=dev-key erp-mock # terminal 1: mock ERP on 127.0.0.1:8080
ERP_API_KEY=dev-key erp-mcp # terminal 2: MCP server on stdioTo use it from an MCP host, register the stdio command:
{
"mcpServers": {
"erp": {
"command": "erp-mcp",
"env": { "ERP_BASE_URL": "http://127.0.0.1:8080", "ERP_API_KEY": "dev-key" }
}
}
}A preview call and its result:
{"vendor_tax_id": "4821963570", "reference": "FTR2026000123", "document_date": "2026-03-12",
"gross_amount": "12000.00", "tax_amount": "2000.00", "currency": "TRY", "purchase_order": "4500001201"}{
"posted": false,
"document_number": null,
"checks": [
{"name": "vendor", "passed": true, "detail": "V1001 Kuzey Ambalaj Sanayi A.Ş."},
{"name": "amounts", "passed": true, "detail": "gross 12000.00, tax 2000.00"},
{"name": "currency", "passed": true, "detail": "invoice TRY, vendor TRY"},
{"name": "duplicate", "passed": true, "detail": "0 posted with reference FTR2026000123"},
{"name": "purchase_order", "passed": true, "detail": "open, remaining 75000.00, net 10000.00"}
],
"next_step": "All checks passed. Call again with confirm=true to post."
}Tests
The suite connects an MCP client to the server in memory and the server to the mock ERP through an ASGI transport, so every test goes through the protocol and the HTTP layer without opening a socket. It covers:
tool listing and read/write annotations
paging
a preview writes nothing
a confirmed posting writes exactly once, also when the call is repeated
the same idempotency key returns the same document
each failed check blocks posting even with
confirminvalid arguments never reach the ERP
the API key does not appear in tool output
a wrong API key is reported as a configuration problem
Layout
src/erp_mcp/
server.py tools, checks, error advice
client.py HTTP client and error mapping
mock_erp.py in-memory ERP with a REST API
tests/
test_server.pyPointing it at a real system
Replace client.py. The tools depend on five client methods (search_vendors, list_purchase_orders, get_purchase_order, find_invoices, post_invoice) and on ErpError codes; the mapping in ADVICE lists the codes the server knows how to explain. The mock ERP is not a model of any particular product.
Requires the MCP Python SDK 2.x.
License
MIT
Available Tools
4 toolsget_purchase_orderCRead-only
Get one purchase order by its number.
Inputs: number (required). Returns: amount, number, status, currency, +3 more
list_purchase_ordersBRead-only
List a vendor's purchase orders with the amount still open on each.
Inputs: vendor_id (required), limit, offset, status. Returns: items, total, next_offset
post_vendor_invoiceBIdempotent
Post a vendor invoice. Without confirm it only runs the checks and returns a preview.
Posting is idempotent: repeating a confirmed call with the same vendor and reference returns the document that was already created.
Inputs: currency (required), reference (required), tax_amount (required), gross_amount (required), +4 more. Returns: checks, posted, next_step, document_number
search_vendorsARead-only
Find vendors by name or tax number. Returns at most 10 matches.
Inputs: query (required). Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 4 tools
Each tool targets a distinct resource and action: vendor search, PO listing, single PO retrieval, and invoice posting. There is no overlap between listing purchase orders and getting one order, since one is scoped per-vendor and the other per-document.
All four names follow a strict verb_noun snake_case pattern (search_vendors, list_purchase_orders, get_purchase_order, post_vendor_invoice). Verbs are well chosen and consistently distinguish read vs. write operations.
Four tools is on the lean side but each supports a step in the vendor-invoice workflow, so nothing is redundant. A slightly broader surface (e.g. retrieving posted invoices) would make the set feel less minimal.
The core workflow — find vendor, inspect open PO amounts, read a PO, then post/preview an invoice — is fully covered, including idempotency. Minor gaps remain: no way to list or fetch invoices by vendor/reference outside of a repeat post, and no vendor-detail retrieval.
Maintenance
Related MCP Connectors
Give AI agents 30,000+ safe, token-optimized actions across Workday, SAP, Oracle + hundreds more.
Acumatica MCP server for ChatGPT, Claude and any AI agent: create AP bill, create AR invoice, release invoice, list open invoices and approve payment in your own Acumatica account. Cotlet works in the account through your Cloud Browser, a real Chrome where you sign in to Acumatica yourself; Cotlet does not store your password and you need no Acumatica API key. About the official Acumatica API: Yes. Acumatica has a full contract-based REST API with OAuth 2.0 (checked 14 Oct 2026). Setup and FAQ: https://cotlet.dev/integrations/acumatica-api-mcp-server
Map how a company works, and run B2B order to cash with AI agents that ask before they act.
Shared business knowledge, tools and skills for AI agents, with citations and approval controls.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to query and manage ERP procurement data, including suppliers, parts, inventory, and purchase orders, with human approval for write operations.-
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to query and operate on ERP data through a unified tool interface, working across CSV exports, SFTP drop folders, SQLite/ODBC, and optional enterprise APIs. It supports purchase orders, vendors, and inventory lookups while keeping agent-facing tools consistent regardless of backend.MIT
- FlicenseAqualityCmaintenanceEnables an AI agent to handle accounts payable tasks against a mock ERP, including reading and writing bills and vendors, checking duplicates, matching invoices, recommending approvals, and queuing payment releases, with configurable profiles that limit available tools.11-
- AlicenseAqualityBmaintenanceIt enables an LLM agent to list and inspect invoices, run three-way matches against purchase orders and goods receipts, and route exceptions under server-enforced policy.5MIT