Skip to main content
Glama
prodline-ai

erp-mcp

Official
by prodline-ai

erp-mcp

An open-source Model Context Protocol server that exposes ERP data — production orders, inventory, BOM, customers — to any MCP client (Claude Desktop, Cursor, the MCP Inspector, or the Prodline analytics platform).

Backend-neutral by design: a clean adapter seam (ERPBackend) maps each ERP into one product-neutral contract. It ships with a mock backend so you can run and test it today with zero ERP access; planned real backends include ERPNext, 用友 U8, and 畅捷通.

Part of Prodline. The connector is intentionally standalone and MIT-licensed — the proprietary value lives in Prodline's expertise engine, not here. We benefit from distribution.


What it exposes

Kind

Name

Description

Resource

erp://orders

All production orders

Resource

erp://inventory

Current stock levels

Resource

erp://customers

Customer master data

Resource

erp://bom

Bill of materials

Tool

query_orders(status, customer, due_before, due_after)

Filter orders

Tool

get_bom(product_code)

BOM for one product

Tool

get_inventory(part_no)

Stock for one part

Prompt

overdue_orders

Orders past due date

Prompt

low_stock_alert

Materials below reorder point

Prompt

due_this_week

Orders due in the next 7 days

Order records carry order_no (the natural key), so an export drops straight into Prodline's production_orders via the standard ingestion pipeline.


Related MCP server: demo-mcps

Quick start (mock backend — no ERP needed)

pip install -e .
ERP_PRODUCT=mock erp-mcp          # runs over stdio

Configuration via .env: both erp-mcp and erp-agent auto-load a .env file (found by walking up from the working directory) on startup. Copy the template and fill it in:

cp .env.example .env             # then edit .env with your ERP_PRODUCT + credentials

Real environment variables always win over .env (so an MCP client's env block or a shell export overrides it). .env is gitignored; .env.example is the committed reference.

Inspect it interactively:

npx @modelcontextprotocol/inspector erp-mcp

Use it in Claude Desktop — add to claude_desktop_config.json:

{
  "mcpServers": {
    "erp": {
      "command": "erp-mcp",
      "env": { "ERP_PRODUCT": "mock" }
    }
  }
}

Then ask Claude: "Which orders are overdue?" or "List materials below reorder point."


Testing layers

This connector is built so the first two layers need no ERP account at all:

Layer

What it proves

ERP account?

L1

Prodline's ingestion turns this server's output into production_orders

No — point Prodline at ERP_PRODUCT=mock

L2

The MCP surface is correct (resources/tools/prompts)

No — run under MCP Inspector / Claude Desktop

L3

The real ERP data path (auth + endpoints + data shapes)

Yes — see below

Run the unit tests (L1/L2 logic, no client, no ERP):

pip install -e ".[dev]"
pytest

Feeding Prodline — the on-prem sync agent

For automated sync into the Prodline platform, run the bundled agent (erp-agent) on the same LAN. It reads the ERP locally via the connector and pushes outbound to Prodline — Prodline never connects into the customer network (firewall-friendly).

PRODLINE_URL=https://app.prodline.ai \
PRODLINE_TOKEN=<per-tenant connector token> \
ERP_PRODUCT=mock \
erp-agent

Each run:

  1. fetches the collection plan from Prodline (GET /api/connector/collection-plan) — what entities to pull, delta vs snapshot, schedule

  2. for each due entity, pulls rows from the ERP (delta passes filter updated_after=<local watermark>)

  3. pushes the batch outbound (POST /api/connector/ingest), which reconciles into Prodline (idempotent upsert by order_no, user-edited fields sticky)

  4. advances the local watermark (AGENT_STATE_FILE)

Run it continuously with the built-in loop, or one-shot under an external scheduler:

erp-agent                       # one pass, then exit (for cron / Task Scheduler)
erp-agent --interval 1800       # loop: sync every 30 min until stopped (or AGENT_INTERVAL_SECONDS=1800)

A delta cadence keeps data fresh cheaply (orders / work orders / quality inspections pull only rows changed since the last watermark); the weekly snapshot pass reconciles edits. Inventory / BOM / routings are snapshot pulls (current-state / low-churn). The agent is a thin generic pump — what's available comes from the connector, what to collect comes from the server-pushed plan — so it rarely needs updating.

Protocol & compatibility

This repo and the Prodline platform are separate — the only coupling is the /api/connector/* HTTP contract, so it's versioned (src/erp_mcp/protocol.py, PROTOCOL_VERSION) and checked on every sync via the X-Connector-Protocol header:

  • The agent sends its version and refuses to sync against a server on an incompatible MAJOR (pushing mismatched row shapes would silently corrupt data). The server likewise answers 426 Upgrade Required to an incompatible agent.

  • Same MAJOR ⇒ compatible; a MINOR bump is a backward-compatible addition (new optional field, new entity). Bump MAJOR only for a breaking shape change.

If you change a request/response shape, bump PROTOCOL_VERSION here and CONNECTOR_PROTOCOL_VERSION on the platform in lockstep. tests/test_protocol.py (here) and the platform's test_connector_contract.py pin both ends.


Going live (L3) — implementing a real backend

The server only ever calls the ERPBackend interface (src/erp_mcp/backends/base.py). Adding a real product = implementing that interface.

ERPNext / Frappe (ERP_PRODUCT=erpnext) — implemented ✅

  • Read-only via the Frappe REST API. In ERPNext: user → API Access → Generate Keys, then set ERPNEXT_URL / ERPNEXT_API_KEY / ERPNEXT_API_SECRET.

  • Mappings: Sales Order (+ Sales Order Item) → orders; BOM (+ BOM Item) → BOM; Bin (+ Item) → inventory; Customer → customers. Manufacturing depth (Phase B): Work Order → work orders; BOM Operation → routing steps; Quality Inspection → quality inspections (→ Prodline's B19 tables). See src/erp_mcp/backends/erpnext.py.

  • Stand up a dev instance with frappe_docker and load the manufacturing demo data to test end-to-end. Mapping is unit-tested (mocked) in tests/test_erpnext_backend.py — no live instance needed for CI.

用友 U8 (ERP_PRODUCT=u8) — stub

  • Free developer test accounts during development — you can build and integration-test without a paying customer or a purchased OpenAPI module (the customer buys that only for production: ~¥3,000/yr operating mode).

  • Docs: https://open.yonyouup.com/ · Support: https://u8open.yonyou.com/

  • Implement src/erp_mcp/backends/u8.py.

畅捷通 好会计 / T+ (ERP_PRODUCT=chanjet)

Heads-up: Chinese open platforms commonly require enterprise real-name verification (企业实名认证) to register a developer app, even for sandbox keys. Have your company identity ready.

Each backend method maps one ERP API call → a normalized model in src/erp_mcp/models.py. The MCP surface and all downstream consumers stay unchanged.

src/erp_mcp/
├── server.py            # MCP resources / tools / prompts (never changes per-product)
├── models.py            # normalized Order / BomLine / InventoryItem / Customer
└── backends/
    ├── base.py          # ERPBackend protocol — the adapter seam
    ├── __init__.py      # get_backend() — selects by ERP_PRODUCT
    ├── mock.py          # in-memory fixtures (L1/L2)
    ├── u8.py            # 用友 U8 (L3 — implement me)
    └── chanjet.py       # 畅捷通 (L3 — implement me)

License

MIT

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Provides manufacturing demo data across procurement, production, quality, warehouse, and finance categories via MCP Streamable HTTP, enabling LLMs to retrieve mock datasets.
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    MCP server that enables AI platforms to search products, customers, and warehouses, and prepare and submit sales orders to a fixed ERP endpoint with per-session bearer authentication.
    -
  • F
    license
    A
    quality
    B
    maintenance
    MCP server that exposes read-only NetSuite tools for querying warehouse stock levels and order status, using mock data locally and a pluggable client interface.
    2
    -