English | [繁體中文](README.zh-TW.md) # @casys/mcp-erpnext [![JSR](https://jsr.io/badges/@casys/mcp-erpnext)](https://jsr.io/@casys/mcp-erpnext) [![npm](https://img.shields.io/npm/v/@casys/mcp-erpnext?logo=npm&color=cb3837)](https://www.npmjs.com/package/@casys/mcp-erpnext) [![CI](https://github.com/Casys-AI/mcp-erpnext/actions/workflows/test.yml/badge.svg)](https://github.com/Casys-AI/mcp-erpnext/actions/workflows/test.yml) [![MCP](https://img.shields.io/badge/MCP-server-1f6feb?logo=modelcontextprotocol&logoColor=white)](https://modelcontextprotocol.io) [![M8ven Score](https://m8ven.ai/badge/mcp/casys-ai-mcp-erpnext-1kev4k)](https://m8ven.ai/mcp/casys-ai-mcp-erpnext-1kev4k) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) > [!IMPORTANT] > **Installing 3.3:** for npm/Node use `npx -y @casys/mcp-erpnext@latest`; for > Deno use `deno run -A jsr:@casys/mcp-erpnext@3.3.0/server`. 3.3.0 is the > stable release and carries npm's `latest` tag; prereleases, when published, > use the `next` tag. 3.3 adds graduated selection to the active context: list > checkboxes, select-all over the filtered rows, Shift-click ranges and > Ctrl/Cmd-click toggles, compact records for one to three selections, > references up to eight and a single `erpnext_doc_list` query item beyond. > Chart clicks snap to the nearest point in their column. Test it with the MCP > host your users actually run before replacing an existing deployment. See the > [CHANGELOG](CHANGELOG.md) for release history. Let any MCP-compatible AI agent operate your [ERPNext](https://erpnext.com) / Frappe instance — documents, workflows, and interactive viewers inside the host (Claude Desktop, Claude Code, VS Code Copilot, or custom). Works with **self-hosted** and **ERPNext Cloud** (frappe.cloud) instances. > Built on **[@mcpview/server](https://github.com/mcpview/mcpview)** — the MCP > server framework (concurrency, auth, MCP Apps, observability) that powers this > project. See [mcpview.dev](https://mcpview.dev). ## Screenshots Interactive viewers rendered inside an MCP host, driven entirely by tool results.
Document list viewer with chip filters and inline detail
doclist-viewer — any DocType as a sortable table with chip filters and an inline detail panel
Invoice viewer with line items and actions
invoice-viewer — invoice with parties, line items, item drill-down and Submit/Cancel/Payments
Sales funnel viewer
funnel-viewer — Lead → Opportunity → Quotation → Order with conversion rates
KPI viewer with sparkline
kpi-viewer — big-number KPI with delta vs last period and a sparkline
Chart viewer
chart-viewer — universal Recharts renderer (here: stock levels)
Stock balance viewer
stock-viewer — stock balance with color-coded quantity badges
Read-write kanban board
kanban-viewer — read-write board (Task / Opportunity / Issue) with inline edit
Profit and loss composed chart
chart-viewer — composed dual-axis chart (here: profit & loss)
## What's New **3.2.0 is the stable release.** All nine viewers navigate inside the view with back and breadcrumb navigation, and a confirmed document change marks the derived levels stale until they are read again. Active-context selection covers the interactive viewers, and chart, KPI and nested-chart details open from a visible button on touch screens. The generic document viewer, child tables and attachment workflows follow ERPNext's own DocType metadata. Tool-selection filters (`ERPNEXT_CATEGORIES`, `ERPNEXT_EXCLUDE_CATEGORIES`, `ERPNEXT_EXCLUDE_TOOLS`) limit what a deployment exposes, attachment downloads are refused to clients that do not announce MCP Apps, and errors are structured. Viewer enrichment (refresh requests, navigation jumps, tool manifests) travels in `_meta`, out of the model's context, instead of the result text. 3.2.0 also carries the creation-error guidance, ERPNext 16 Opportunity compatibility, calendar-date, KPI percentage and funnel currency fixes of the stable 3.0.5 and 3.1.0 releases. Features remain capability-gated by the MCP host; Buy evidence does not purchase or qualify a live ERP. For stable npm installations use `@casys/mcp-erpnext@latest`; for Deno use `jsr:@casys/mcp-erpnext@3.3.0/server`. See the [CHANGELOG](CHANGELOG.md) for the full release history, or the [latest release](https://github.com/Casys-AI/mcp-erpnext/releases/latest) for the current version's highlights. See the [3.0 to 3.1 migration guide](docs/migration-3.0-to-3.1.md) for the source contracts, host requirements, and deployment limits carried into 3.2; it applies when upgrading from 3.0 or from stable 3.1.0. ## Documentation Organised by what you are doing, following [Diátaxis](https://diataxis.fr): | | | | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Learning** — never used this before | [Your first tool call](docs/tutorial-first-tool-call.md) — from nothing to a working response in four steps | | **Doing** — you have a specific goal | [Seed a blank ERPNext instance](docs/fresh-instance-setup.md) · [Run the HTTP server](docs/http-deployment.md) · [Set up OAuth](docs/oauth-setup.md) · [Migrate from 3.0 to 3.1](docs/migration-3.0-to-3.1.md) · [Migrate to 2026-07-28](docs/migration-mcp-spec-2026-07-28.md) | | **Looking something up** | [Tools](docs/tools.md) · [Environment variables](docs/environment-variables.md) · [DocType coverage](docs/coverage.md) | | **Understanding why** | [Concepts](docs/concepts.md) — link resolution, transports, MRTR, and which cache does what · [ERPNext quirks](docs/erpnext-quirks.md) | ## Quick Start ### Prerequisites Generate API credentials in ERPNext: 1. Login to ERPNext → top-right menu → **My Settings** 2. Section **API Access** → **Generate Keys** 3. Copy `API Key` and `API Secret` ### Claude Desktop / Claude Code (npm) ```json { "mcpServers": { "erpnext": { "command": "npx", "args": ["-y", "@casys/mcp-erpnext"], "env": { "ERPNEXT_URL": "http://localhost:8000", "ERPNEXT_API_KEY": "your-api-key", "ERPNEXT_API_SECRET": "your-api-secret" } } } } ``` > **Works with ERPNext Cloud** — set `ERPNEXT_URL` to your Frappe Cloud URL > (e.g. `https://mycompany.erpnext.com` or `https://mysite.frappe.cloud`). API > key authentication works the same way on self-hosted and cloud instances. ### VS Code Copilot Add to `.vscode/mcp.json`: ```json { "servers": { "erpnext": { "type": "stdio", "command": "npx", "args": ["-y", "@casys/mcp-erpnext"], "env": { "ERPNEXT_URL": "http://localhost:8000", "ERPNEXT_API_KEY": "your-api-key", "ERPNEXT_API_SECRET": "your-api-secret" } } } } ``` ### Deno (stdio) ```json { "mcpServers": { "erpnext": { "command": "deno", "args": ["run", "--allow-all", "server.ts"], "env": { "ERPNEXT_URL": "http://localhost:8000", "ERPNEXT_API_KEY": "your-api-key", "ERPNEXT_API_SECRET": "your-api-secret" } } } } ``` ### HTTP mode For a shared, always-on server rather than one process per client: [how to run the HTTP server](docs/http-deployment.md). Note it is breaking for pre-2026 HTTP clients in 3.0.0. ### Category filtering Load only the categories you need: ```bash npx -y @casys/mcp-erpnext --categories=sales,inventory ``` Category and individual-tool exclusions are also supported, with environment-variable equivalents: ```bash deno run -A server.ts --categories=sales,inventory,operations --exclude-tools=erpnext_file_upload,erpnext_doc_delete ``` CLI values override `ERPNEXT_CATEGORIES`, `ERPNEXT_EXCLUDE_CATEGORIES`, and `ERPNEXT_EXCLUDE_TOOLS` individually. Excluded tools disappear from calls, viewer actions, and cache warm-up. Use `--flag=value`; invalid exclusions or an empty server selection fail startup. Full rules: [tool selection](docs/environment-variables.md#tool-selection). ## Fresh Instance Setup A blank ERPNext instance has no master data, so business tools fail validation until it exists. See [Seed a blank ERPNext instance](docs/fresh-instance-setup.md). ## UI Viewers Nine interactive [MCP Apps](https://github.com/modelcontextprotocol/ext-apps) viewers, registered as `ui://mcp-erpnext/{name}`: | Viewer | Description | Interactive Features | | --------------------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | | `doc-viewer` | Generic ERPNext document with fields and child tables | Capability-gated attachments, typed navigation, guarded Submit/Cancel, and raw JSON fallback. | | `doclist-viewer` | Generic document table with sort, filter, pagination, CSV export | Inline details, typed nested navigation, Submit/Cancel, and compact status filters. | | `invoice-viewer` | Sales Orders, Sales Invoices, and Quotations with line totals | Item, stock, party, and payment navigation plus guarded Submit/Cancel actions. | | `stock-viewer` | Stock balance table with color-coded qty badges | Item details, recent movements, stock charts, and stock-entry navigation. | | `chart-viewer` | Universal chart renderer (12 types via Recharts) | Exact point/series navigation and active-context selection across simple and composed charts. | | `kanban-viewer` | Read-write kanban for Task, Opportunity, Issue | Drag-and-drop, inline editing, serialized saves, and typed related-document navigation. | | `kpi-viewer` | Big number card with delta, sparkline, trend | Number and trend navigation with bounded active-context selection. | | `funnel-viewer` | Trapezoid sales funnel with conversion rates | Period-aware stage navigation and bounded active-context selection. | | `buy-evidence-viewer` | Immutable sealed Buy evidence (recorded session only) | Complete, partial, unresolved, and unavailable projections; no live ERP refresh or mutation. | Viewers and Buy result fields use the host locale: English, French, Simplified Chinese, Traditional Chinese, Hindi, Bengali, Tamil and Urdu. Chinese script tags take precedence over region tags; `zh-TW`, `zh-HK` and `zh-MO` select Traditional Chinese when no script is specified. Urdu uses right-to-left document direction, and a later host locale change updates the language and direction without reloading the viewer. App-level waiting and rejection screens retain English labels in 3.2; host-context support for those shared surface screens remains an upstream MCP View follow-up. ### Navigation and active context Viewers progressively select the best interaction supported by the host: - `serverTools` opens typed list, record, and chart targets inside the current viewer through `app.callServerTool()`. Back and breadcrumb navigation restore the state of each level. - `downloadFile` lets the host confirm and save an attachment returned as a bounded embedded resource. The server also requires the MCP client to announce the MCP Apps extension and HTML MIME type before serving file bytes. The viewer never opens an ERPNext file URL directly. - `updateModelContext` lets chart, KPI, and funnel selections join a bounded active-context snapshot. The compact context chip keeps up to eight items and lets users remove one item or clear them all. The snapshot contains selected values, never hidden instructions for the model. - `message.text` keeps `app.sendMessage()` as a conversational fallback when direct navigation or context replacement is unavailable. - Without these capabilities, local inspection remains available and unsupported remote actions are omitted. - The Buy evidence viewer is recorded-session only. It does not call server tools, refresh live documents, or mutate ERP state. The server supplies typed navigation metadata and the exact `_availableTools` allowed for each viewer, so category-filtered deployments do not expose tools that are not loaded. ### Refresh model Read-only viewers revalidate on focus and through their refresh control. Mutations use an explicit read-only request to fetch committed state; a mutating tool is never replayed automatically. Overlapping or stale responses are ignored when a newer host payload or mutation has already won. A confirmed document change marks every potentially derived snapshot in the current navigation stack as stale; each marker is removed only when that surface has actually been read again. Separate MCP Apps are not synchronized automatically in 3.2. ### Building UI viewers ```bash cd src/ui npm ci node build-all.mjs ``` For local iteration, run `deno task ui:dev-host` from the repository root. The [local test host](src/ui/dev-host/README.md) uses the actual local MCP server and its built viewers, rebuilding and reloading them without restarting the desktop client. Open `http://127.0.0.1:5177/?viewer=doclist` for the real Company list. The host records viewer context updates but has no connected model or conversation; model consumption and conversational actions require a desktop host check. ## Buy evidence capture **One** read-only tool and **one** recorded App. They do not purchase, create a BOM/RFQ/PO, refresh live documents, replace generic ERP viewers, or qualify a live ERPNext instance. - Tool: `erpnext_buy_capture`. Closed DocTypes only (Item, BOM, Item Price, Supplier Quotation, Supplier, Price List, UOM, Currency Exchange). Two `skipCache` reads must agree on `modified` and the closed projection fingerprint. Return is ephemeral canonical JSON + SHA-256 + byte count. The caller cannot pass `sourceInstance`, URL, credentials, `capturedAt`, or a digest. Digital Thread stores those bytes in its own CAS; this server does not keep a second CAS. - App: `io.casys.mcp-erpnext.buy-evidence`, App version `3.1.0` (independent of the package version), resource `ui://mcp-erpnext/buy-evidence-viewer` (`text/html;profile=mcp-app`), manifest `ui://mcp-erpnext/buy-evidence-manifest` (`application/json`), `acceptedActions` = `viewer.session.apply` only. Complete, partial, unresolved, and unavailable projections stay labelled. No live DocViewer refresh, mutation, or `app.callServerTool`. Session `anchor` is the sealed Digital Thread artefact (`provenance.bundleRef`), not a hash of the displayed projection. - Schemas: `io.casys.mcp-erpnext.buy-source-capture/1.0`, `io.casys.mcp-erpnext.buy-recorded-result/1.0` and `/2.0`, `io.casys.mcp-erpnext.buy-recorded-session/1.0`. - Result `/2.0` carries bounded `excludedLines` metadata for selected lines absent from priced `lines`: exact line ID, quantity, unit, and stated reason. It carries no amount, currency, or price source; covered subtotals remain sealed values and unresolved lines remain visible. - The viewer is built with the other MCP Apps (`cd src/ui && npm ci && node build-all.mjs`). Published JSR/npm artifacts include `src/ui/dist/` and the Buy TypeScript module; the HTML resource and generated manifest are what a published installation serves. Digital Thread owns configuration/seal (`buy-configuration/1.0`, `buy-cost-bundle/1.0`, `buy.capture-configuration-cost@1`, `buy.seal-configuration-cost@1`). A qualified `commerce.read-erpnext-buy-source@1` binding is required before dispatch. ## Tools Record `_list` tools return interactive results via the doclist-viewer with row click, inline detail, and cross-viewer navigation. The attachment-specific `erpnext_file_list` tool does not render doclist-viewer. Generic and dedicated document reads use `doc-viewer`, except Sales Order, Sales Invoice, and Quotation, which retain the specialized invoice surface. - **Sales** — Customers, Sales Orders, Invoices, and Quotations with full CRUD, Submit, and Cancel. - **Purchasing** — Suppliers, Purchase Orders, Purchase Invoices, Receipts, and Supplier Quotations. - **Inventory** — Items, Stock Balance, Warehouses, and Stock Entries. - **Accounting** — Chart of Accounts, Journal Entries, and Payment Entries. - **HR** — Employees, Attendance, Leave Applications, Salary Slips, Payroll Entries, and Expense Claims. - **Project** — Projects, Tasks (with native assignment), and Timesheets. - **Delivery** — Delivery Notes and Shipments. - **Manufacturing** — BOMs, Work Orders, and Job Cards. - **CRM** — Leads, Opportunities, Contacts, and Campaigns. - **Assets** — Assets, Movements, Maintenance records, and Categories. - **Operations** — Generic CRUD, native assignment, attachment listing, upload, host-mediated download, and deny-by-default Frappe method calls (`erpnext_doc_*`, `erpnext_file_*`, `erpnext_method_call`). - **Kanban** — Read-write boards for Task, Opportunity, and Issue with drag-and-drop. - **Analytics** — Charts (bar, area, treemap, radar, scatter, P&L…), KPIs with sparklines, and a sales funnel. - **Buy** — Read-only sealed capture of closed commercial documents (`erpnext_buy_capture`) and an immutable recorded-session evidence viewer. Not a purchase, BOM/RFQ/PO, or live ERP qualification. - **Setup** — Company creation and assignable user listing. Full per-tool reference with parameters: [`docs/tools.md`](docs/tools.md). ## Environment Variables | Variable | Required | Description | | ---------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------- | | `ERPNEXT_URL` | Yes | ERPNext base URL — self-hosted (e.g. `http://localhost:8000`) or cloud (e.g. `https://mycompany.erpnext.com`) | | `ERPNEXT_API_KEY` | Yes | API Key from User Settings | | `ERPNEXT_API_SECRET` | Yes | API Secret from User Settings | | `ERPNEXT_MAX_UPLOAD_BYTES` | No | Maximum decoded file-upload size in bytes (positive integer; default: 10 MiB) | | `ERPNEXT_MAX_DOWNLOAD_BYTES` | No | Maximum attachment-download size in bytes (positive integer; default: 10 MiB) | | `ERPNEXT_METHOD_ALLOWLIST` | No | Comma-separated exact method paths or `prefix.*`; unset means `erpnext_method_call` denies every method, while `*` allows all | | `MCP_MRTR_SIGNING_KEY` | No | Exactly 64 lowercase hex characters; enables signed ambiguous-link elicitation. **Single-instance deployments only** — see below | MRTR is opt-in. Without this key, or when the client does not advertise elicitation, ambiguous links keep returning the existing actionable ambiguity error instead of prompting for a selection. > **Do not run MRTR behind a load balancer with this configuration.** The > signing key proves a retry token is authentic; it does not make it single-use. > That is the job of a replay store, and the default one is process-local. Share > the key across two instances and the same signed retry validates on both — > creating the purchase order, leave application or expense claim **twice**, > irreversibly once submitted. > > A multi-instance deployment must pass a shared atomic `mrtr.replayStore` to > `McpApp` (Redis satisfies the contract with `SET key 1 NX EXAT`). The > framework logs a warning at startup whenever MRTR is enabled without one — > that warning is not noise, it is this paragraph. ## Architecture Tools are grouped by business domain under `src/tools/`, the Frappe REST client is dependency-free, and each UI viewer is a separate build under `src/ui/`. Full layout: [repository layout](docs/architecture.md). ## npm Package The npm package (`@casys/mcp-erpnext`) is a single self-contained bundle with zero runtime dependencies. UI viewers are embedded. Requires Node >= 20. ## Contributing Contributions are welcome — see **[CONTRIBUTING.md](CONTRIBUTING.md)** to get started, and [AGENTS.md](AGENTS.md) for the full architecture and conventions. ## License MIT