ERPNext MCP Server
A comprehensive Model Context Protocol (MCP) server for ERPNext that provides generic, doctype-agnostic access to any ERPNext document type with robust permission controls, audit logging, and enterprise-grade security.
Architecture Overview
graph TB
A[Claude/LLM Client] --> B[MCP Protocol]
B --> C[ERPNext MCP Server]
C --> D[Permission Manager]
C --> E[ERPNext Client]
E --> H[ERPNext API]
D --> I[Audit Logger]
subgraph "Permission System"
D --> J[Doctype Permissions]
D --> K[Field-Level Control]
D --> L[Operation Validation]
D --> M[Condition Checking]
end
subgraph "ERPNext Integration"
E --> N[Generic CRUD]
E --> O[Search & Filter]
E --> P[Schema Discovery]
end
Core Components
- Generic Client — Works with any ERPNext doctype (Customer, Item, Sales Invoice, GL Entry, Client Script, etc.)
- Permission System — Multi-layer access control with field-level restrictions
- Audit System — Comprehensive logging of all operations
- Performance — Built-in caching and rate limiting
- Discovery — Dynamic tool generation based on configured doctypes
---
Quick Start
1. Clone & Install
git clone https://github.com/Sheikh-Muhammad-Mujtaba/ErpNext-MCP.git
cd ErpNext-MCP/
# Create virtual environment
uv sync
source .venv/bin/activate # Windows: .venv\Scripts\activate
# Install dependencies
uv pip install -r requirements.txt
2. Configure Environment
Create a .env file in the project root:
ERPNEXT_URL=https://your-erpnext-instance.com
# api key or username/password
ERPNEXT_API_KEY=your_api_key
ERPNEXT_API_SECRET=your_api_secret
ERPNEXT_USERNAME=username
ERPNEXT_PASSWORD=pass
3. Configure Permissions
Edit config/config.json:
{
"erpnext": {
"timeout": 30
},
"permissions": {
"doctypes": {
"Customer": {
"read": true,
"create": true,
"update": true,
"delete": false,
"allowed_fields": ["customer_name", "email_id", "mobile_no"],
"conditions": {
"create": {"customer_type": ["Company", "Individual"]}
}
}
},
"default": {
"read": true,
"create": true,
"update": false,
"delete": false
}
},
"audit": {
"enabled": true,
"log_file": "logs/audit.log",
"log_level": "INFO"
},
"rate_limiting": {
"enabled": true,
"requests_per_minute": 60,
"requests_per_hour": 1000
},
"cache": {
"enabled": true,
"ttl": 300,
"max_size": 1000
}
}
4. Run the Server
python -m src.server
---
Connect to Claude Code
User-scoped (available across all projects)
claude mcp add erpnext -s user -- bash -c "cd '/path/to/ERP_Next-MCP' && .venv/bin/python -m src.server"
Project-scoped (current directory only)
claude mcp add erpnext -- bash -c "cd '/path/to/ERP_Next-MCP' && .venv/bin/python -m src.server"
Verify connection
claude mcp list
Claude Desktop Integration
Add to claude_desktop_config.json:
{
"mcpServers": {
"erpnext": {
"command": "bash",
"args": ["-c", "cd '/path/to/ERP_Next-MCP' && .venv/bin/python -m src.server"],
"env": {
"MCP_LOG_LEVEL": "INFO"
}
}
}
}
---
Available MCP Tools
System Tools
| Tool | Description | |------|-------------| | test_connection | Test ERPNext server connectivity | | get_system_info | Get ERPNext system information | | list_doctypes | List all configured doctypes and permissions | | get_doctype_permissions | Get detailed permissions for a specific doctype | | get_doctype_schema | Get schema/metadata for any doctype |
Generic Document Tools
| Tool | Description | |------|-------------| | get_generic_document | Get any document by doctype and name | | list_generic_documents | List documents for any doctype with filters | | create_generic_document | Create a document for any doctype | | update_generic_document | Update a document for any doctype |
Customer-Specific Tools
| Tool | Description | |------|-------------| | list_customer_documents | List customers with optional filters | | get_customer_document | Get a specific customer by name | | search_customer_documents | Search customers by text | | create_customer_document | Create a new customer | | update_customer_document | Update an existing customer |
For each doctype configured in
config.json, the server auto-generates:list_,get_,search_,create_,update_, anddelete_tools.
---
Known Limitations
list_generic_documentsonly returnsnamefields — field filtering in thefieldsparameter is not applied by the list endpoint; useget_generic_documentto retrieve full document details.- The list endpoint is capped at 100 results per call.
- Aggregated queries (SUM, COUNT, GROUP BY) are not supported — use ERPNext's built-in reports for financial summaries.
---
Permission Model
Multi-Layer Security
1. Operation-Level
{
"Customer": {
"read": true,
"create": true,
"update": true,
"delete": false
}
}
2. Field-Level Access Control
{
"Customer": {
"allowed_fields": ["customer_name", "email_id", "mobile_no"],
"restricted_fields": ["creation", "modified", "owner", "credit_limit"]
}
}
3. Conditional Validation
{
"Customer": {
"conditions": {
"create": {
"customer_type": ["Company", "Individual"]
},
"update": {
"status": {"not_in": ["Disabled", "Blocked"]}
}
}
}
}
4. Audit Logging
{
"audit": {
"enabled": true,
"log_file": "logs/audit.log",
"log_level": "INFO"
}
}
Example Configurations
Read-only analyst
{
"permissions": {
"doctypes": {
"Customer": {
"read": true, "create": false, "update": false, "delete": false,
"allowed_fields": ["name", "customer_name", "territory", "customer_group"]
},
"Sales Invoice": {
"read": true, "create": false, "update": false, "delete": false,
"allowed_fields": ["name", "customer", "grand_total", "status", "posting_date"]
}
}
}
}
Sales user
{
"permissions": {
"doctypes": {
"Customer": {
"read": true, "create": true, "update": true, "delete": false,
"allowed_fields": ["customer_name", "customer_type", "email_id", "mobile_no", "territory"],
"conditions": {
"create": {"customer_type": ["Company", "Individual"]},
"update": {"status": {"not_in": ["Disabled"]}}
}
}
}
}
}
---
Example Prompts
Fetch a document
Get the Client Script document named "Sales Invoice"
List documents
List all Client Script documents
Financial queries
Get GL Entry ACC-GLE-2025-113787
Search
Search customer documents for "National"
Cross-doctype analysis
Get the Sales Invoice ACC-SINV-2025-06622 and show me the items and COGS
---
Security
Authentication
- Uses ERPNext API Key/Secret — no passwords stored
- Credentials loaded from
.envfile (never commit this file) - Supports ERPNext user-level role permissions
Generate API Keys in ERPNext
- Go to Settings > Integrations > API Access
- Click Generate Keys
- Assign the API user appropriate roles (e.g., "Accounts User", "Sales Manager")
- Copy the key and secret into your
.envfile
Network
- HTTPS-only connections to ERPNext
- Configurable request timeouts
- Rate limiting: 60 req/min, 1000 req/hour (configurable)
Audit Trail
All operations are logged with timestamp, operation type, doctype, and result:
2025-08-29 11:18:35 - INFO - Operation: READ | DocType: Sales Invoice | Result: ALLOWED | Document: ACC-SINV-2025-06622
2025-08-29 11:18:35 - WARNING - Operation: DELETE | DocType: Customer | Result: DENIED | Reason: Delete not permitted
---
Testing
python test.py
---
Project Structure
ERP_Next-MCP/
├── src/
│ ├── server.py # MCP server entry point
│ ├── erpnext_client.py # ERPNext API client
│ └── permissions.py # Permission manager
├── config/
│ ├── config.json # Main configuration
│ ├── multi_doctype_config.json
│ └── restricted_config.json
├── logs/
│ └── audit.log
├── .env # API credentials (not committed)
├── .env.example # Example env file
├── requirements.txt
└── test.py










