Skip to main content
Glama
Snovel993

ERPNext MCP Server

by Snovel993

ERPNext MCP Server

mcp_erpnext exposes bounded, profile-specific ERPNext capabilities through MCP. It is not a generic ERPNext, Frappe, SQL, or arbitrary-DocType CRUD interface. Native Frappe and ERPNext remain authoritative for document validation, permissions, defaults, ledgers, and transactional side effects.

Ownership and architecture

mcp_erpnext owns FastMCP construction, transport and backend selection, profile-specific tool registration, request-scoped Frappe lifecycle, typed tool contracts, approvals, and business-service orchestration. Its required apps are erpnext and mcp_identity.

mcp_identity owns HTTP authentication-mode configuration, trusted-header authentication, configured stdio-user validation, and Frappe OAuth resource-binding/token-verification support. It does not own MCP business tools or ERPNext permissions. See the current architecture reference and mcp_identity's README.

MCP client -> stdio or Streamable HTTP -> authenticated execution identity (when HTTP)
           -> selected profile's MCP tools -> mcp_erpnext services and scoped Frappe context
           -> native Frappe / ERPNext permissions and business rules

Related MCP server: Accounting Ledger MCP Server

Profiles and public tools

MCP_PROFILE selects one public inventory per process. It is server configuration, never a tool argument. Omitted means sales; accepted values are sales, purchase, accounts, and all.

Profile

Current scope

sales (default)

Customer, Item, and Contact masters; Quotation, Sales Order, Sales Invoice, and Delivery Note workflows/conversions; exact reads, queries/aggregates, lifecycle, PDF, and document email where registered.

purchase

Supplier and purchase Item resolution; Purchase Order workflow, lifecycle/read, PDF, and document email.

accounts

Sales Invoice payments, multi-invoice receipts, standalone Payment Entries, Sales Order advances, payment reconciliation, Payment Entry reads/queries/aggregates, and applicable lifecycle actions.

Profiles isolate exposed MCP capabilities; they do not grant ERPNext access. Every call remains subject to the resolved user's normal Frappe and ERPNext permissions. The generated tool catalog is the human-readable inventory; MCP tools/list is the machine-readable authority.

Write safety

Consequential operations use a prepare -> preview -> approval -> confirm boundary. Prepare returns a server-held pending operation and does not make the final write. Confirm reclaims that operation atomically and rechecks its site, user, action, payload digest, expiry, single-use state, and normal Frappe permissions before native persistence.

MCP_APPROVAL_MODE is server-only and defaults to agent_delegated: the authenticated MCP client/Agent must obtain explicit user approval before it calls a confirm tool. trusted_human instead requires an independently verified, internally recorded approval; without it confirmation fails closed with TRUSTED_APPROVAL_UNAVAILABLE. A tool argument such as confirm=true never provides that approval. Pending operations live in Frappe's configured shared Redis cache, so compatible workers can claim a still-valid operation; expiry, eviction, flush, or Redis loss requires a fresh prepare. See approval safety.

Document Update, Cancel, and Delete have separate, server-only availability gates. MCP_UPDATE_MODE, MCP_CANCEL_MODE, and MCP_DELETE_MODE each default to disabled; opt in to an action with approval_required. This opt-in does not replace MCP_APPROVAL_MODE, the action-specific profile/DocType allowlist, the prepared-operation approval, or native Frappe permissions and hooks. Deleting a Submitted document uses the governed cancel_delete plan and therefore requires both modes to be approval_required.

The six Update/Cancel/Delete tools remain discoverable while disabled; the shared service returns UPDATE_DISABLED, CANCEL_DISABLED, or DELETE_DISABLED before target loading or approval creation. These modes are process environment configuration, not site/business data or tool arguments. Apply the same values to every executor worker/replica and restart or drain them together. With the REST backend, the remote Frappe web process is authoritative; a local caller cannot forward a trusted mode.

Runtime, transport, and identity

The default local path is MCP_BACKEND=direct with MCP_TRANSPORT=stdio. It requires MCP_FRAPPE_SITE and MCP_FRAPPE_USER; after the app opens the site context, mcp_identity validates the configured enabled non-Guest Frappe User and mcp_erpnext applies it with frappe.set_user().

For MCP_TRANSPORT=streamable-http, MCP_BACKEND must be direct. HTTP has two exact, case-sensitive MCP_HTTP_AUTH_MODE values, owned by mcp_identity:

  • trusted_header is the backward-compatible default. It requires a server-only MCP_HTTP_SHARED_SECRET of at least 32 characters in Authorization: Bearer ... plus X-MCP-User-Email on every request. The email is resolved only after bearer authentication to an enabled non-Guest Frappe User.

  • oauth is implemented for Streamable HTTP. FastMCP uses mcp_identity's Frappe-native opaque-token verifier and protected-resource settings. The token's Frappe User is the only execution identity; X-MCP-User-Email, MCP_FRAPPE_USER, and the shared secret have no authority in this mode.

HTTP never falls back to the process-level stdio user and clears Frappe context before and after each tool call. OAuth startup requires mcp_identity to be installed and migrated on the target site, a resource-bound native Frappe OAuth Client, and MCP_OAUTH_ISSUER_URL, MCP_OAUTH_RESOURCE_SERVER_URL, MCP_OAUTH_REQUIRED_SCOPES, and MCP_OAUTH_FRAPPE_CLIENT_ID. The OAuth client must support authorization code + code, have the canonical public /mcp resource configured, and issue a token with every required scope. The detailed resource-binding setup is in mcp_identity's README.

MCP_BACKEND=rest is also implemented, but supports only stdio. It calls the fixed mcp_erpnext.remote_api.execute_mcp_operation bridge on a compatible remote site as the remote API key/secret owner, never as a caller-selected identity and never through generic CRUD. REST requires ERPNEXT_BASE_URL, ERPNEXT_API_KEY, and ERPNEXT_API_SECRET; HTTPS is required except for an explicit loopback development origin with MCP_REST_ALLOW_INSECURE_HTTP=1.

Setup and operation

Copy .env.example only as a private starting point; the server does not load .env itself. The selected site must have both apps installed and migrations applied before their code or OAuth Custom Fields are available. Installation/migration, service start/restart, and deployment are operator actions.

Never put real credentials, bearer secrets, or OAuth tokens in this repository or MCP tool arguments.

Contributing

New or changed public MCP tools must follow the MCP Tool Contract Standard: typed input/output contracts, side-effect classification, contract tests, and a checked generated catalog. Resolver changes must preserve ambiguous until an explicit candidate is selected and revalidated.

License

mit

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    A
    maintenance
    Enables interaction with the QuickBooks Online Accounting API to manage customers, invoices, expenses, and payments through MCP-compatible clients. It supports comprehensive financial workflows and the generation of reports like Profit and Loss or Balance Sheets.
    133
    2
    Apache 2.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    A comprehensive MCP server for ERPNext providing generic, doctype-agnostic access to any ERPNext document type with robust permission controls, audit logging, and enterprise-grade security.
    MIT