mcpField
E
Erpnext_mcp_server

Erpnext_mcp_server

Local
github.com/ManotLuijiuBusiness & Marketing4Updated 15w ago

About Erpnext_mcp_server

Erpnext_mcp_server is an MCP server that runs at the Frappe/ERPNext bench level, for teams managing ERPNext through MCP clients. A single instance serves multiple sites on a bench and can switch site context between tool calls.

Key features

  1. 01Runs at the bench level
  2. 02Switches site context dynamically
  3. 03Reads and modifies ERPNext documents
  4. 04Read-only SQL and restricted file access
  5. 05Searches DocTypes and documents

Use cases

  1. 01Query ERPNext records across sites
  2. 02Create or update business documents
  3. 03Inspect database structure and system information
  4. 04Read files in permitted bench paths

MCP support

Over stdio, the server exposes site management, document operations, search, database queries, and file tools to MCP clients. SQL is limited to SELECT, while file access and bench commands are restricted.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

No install method listed yet

We haven’t collected a package or remote endpoint for this server. Follow the instructions in the project README.

Repository

Tools

No tool list yet

Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.

Details

From the project README

ERPNext MCP Server

Framework-level MCP Server for Frappe/ERPNext — works like Doppio CLI, not site-specific.

Built by AWS Solution Ltd. | Contact: [email protected]

Overview

Unlike typical Frappe apps that install per-site, this MCP server runs at the bench framework level:

  • One server instance serves all sites on the bench
  • Site context switches dynamically via tool calls
  • No installation to each site needed
┌─────────────────────────────────────────────────────┐
│  MCP Client (Claude, Hermes, etc.)                 │
│  (running on another machine)                        │
└────────────────────┬────────────────────────────────┘
                     │ stdio
┌────────────────────▼────────────────────────────────┐
│  ERPNext MCP Server                                 │
│  (this bench)                                       │
│                                                     │
│  • list_sites     → all bench sites               │
│  • switch_site    → change context                 │
│  • get_document   → query current site             │
│  • execute_sql    → safe SELECT queries            │
│  • bench_command  → read-only bench operations     │
│  • ... + 15 more tools                            │
└─────────────────────────────────────────────────────┘

Prerequisites

  • Frappe/ERPNext v15+ installed on a bench
  • Python 3.10+ (uses bench's virtual environment)
  • MCP client (Claude Code, Hermes Agent, etc.)

Quick Start

1. Verify Python Environment
cd ~/frappe-bench
./env/bin/python --version  # Should be Python 3.10+
2. Test Locally
# Set your default site
export FRAPPE_SITE=your-site.domain.com
export BENCH_PATH=/path/to/your/frappe-bench

# Run the server
./env/bin/python -m erpnext_mcp_server.mcp.server
3. Configure MCP Client
For Claude Code

Add to .mcp.json in your project:

{
  "mcpServers": {
    "erpnext": {
      "command": "python",
      "args": ["-m", "erpnext_mcp_server.mcp.server"],
      "env": {
        "FRAPPE_SITE": "your-site.domain.com",
        "BENCH_PATH": "/home/youruser/frappe-bench"
      }
    }
  }
}
For Hermes Agent

In your Hermes configuration:

mcp_servers:
  erpnext:
    command: ssh
    args:
      - user@your-server
      - 'cd /path/to/bench && FRAPPE_SITE=your-site.com ./env/bin/python -m erpnext_mcp_server.mcp.server'
For Other MCP Clients

The server uses STDIO transport (stdin/stdout). Any MCP client that supports stdio will work:

{
  "mcpServers": {
    "erpnext": {
      "command": "/path/to/frappe-bench/env/bin/python",
      "args": ["-m", "erpnext_mcp_server.mcp.server"],
      "env": {
        "FRAPPE_SITE": "your-site.domain.com",
        "BENCH_PATH": "/path/to/frappe-bench"
      }
    }
  }
}

Available Tools

Site Management
ToolArgumentsDescription
list_sites—List all sites on this bench
switch_sitesiteSwitch to a different site
current_site—Get current site name
Document CRUD
ToolArgumentsDescription
get_documentdoctype, nameGet document by ID
list_documentsdoctype, filters?, limit?List documents with filters
create_documentdoctype, dataCreate new document
update_documentdoctype, name, dataUpdate existing document
delete_documentdoctype, nameDelete/cancel document
count_documentsdoctype, filters?Count matching documents
Metadata
ToolArgumentsDescription
list_doctypesmodule?List all DocTypes
get_doctype_metadoctypeGet field definitions
Database
ToolArgumentsDescription
execute_sqlquery, limit?Execute SELECT query (safe)
get_table_infotableGet table structure
System Info
ToolArgumentsDescription
get_system_info—System and DB info
get_versions—Installed app versions
bench_commandcommandRun read-only bench commands
Workflow
ToolArgumentsDescription
submit_documentdoctype, nameSubmit (docstatus 0→1)
cancel_documentdoctype, nameCancel submitted doc
Search
ToolArgumentsDescription
searchquery, doctype?, limit?Search across DocTypes
Files
ToolArgumentsDescription
read_filepath, lines?Read file (safe paths only)
list_filespath, recursive?List directory

Usage Examples

Python Client Test
import subprocess
import json

proc = subprocess.Popen(
    ["./env/bin/python", "-m", "erpnext_mcp_server.mcp.server"],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    cwd="/path/to/frappe-bench",
    env={"FRAPPE_SITE": "your-site.domain.com"}
)

# Initialize
init_msg = {
    "jsonrpc": "2.0", "id": 1,
    "method": "initialize",
    "params": {
        "protocolVersion": "2024-11-05",
        "capabilities": {},
        "clientInfo": {"name": "test", "version": "1.0"}
    }
}
proc.stdin.write((json.dumps(init_msg) + "\n").encode())
proc.stdin.flush()

# List sites
list_msg = {
    "jsonrpc": "2.0", "id": 2,
    "method": "tools/call",
    "params": {"name": "list_sites", "arguments": {}}
}
proc.stdin.write((json.dumps(list_msg) + "\n").encode())
proc.stdin.flush()

proc.stdin.close()
print(proc.stdout.read().decode())
Claude Code Usage

Once configured, simply ask Claude:

> List all customers in ERPNext
> Create a new Sales Order for customer ABC
> What is the total outstanding for Invoice INV-001?

Claude will use the MCP tools to query ERPNext directly.

Architecture

erpnext_mcp_server/
├── __init__.py
├── hooks.py
├── mcp/
│   ├── __init__.py
│   ├── __main__.py          # Entry point
│   ├── server.py            # Main MCP server
│   └── config.py            # Configuration
└── doctype/                 # Settings DocTypes (optional)
Design Principles
  1. Framework Level — Runs at bench level, not per-site
  2. Lazy Loading — Frappe imported only when needed
  3. Site Context — Switches context dynamically per tool call
  4. Security First — SQL limited to SELECT, files restricted to safe paths

Security

RestrictionDetails
SQLOnly SELECT queries allowed
FilesOnly sites/, apps/, logs/, config/ paths
Bench commandsRead-only operations only
Site accessEnforced via Frappe permissions

Environment Variables

VariableRequiredDefaultDescription
FRAPPE_SITEYes—Default site name
BENCH_PATHNo/home/frappe/frappe-benchBench directory
FRAPPE_STREAM_LOGGINGNo1Disable file logging

Troubleshooting

"site does not exist" error
# Verify site exists
ls ~/frappe-bench/sites/  | grep your-site

# Check site config
cat ~/frappe-bench/sites/your-site.domain.com/site_config.json
Connection refused

The server uses stdio transport, not HTTP. Ensure your MCP client is connecting via stdin/stdout pipes.

Permission denied

Ensure the user running the server has:

  • Read access to bench directory
  • Database access for the site
  • Permission to execute bench commands

License

Proprietary - AWS Solution Ltd.

Support


Built with Frappe Framework | MCP Protocol | STDIO Transport

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.