AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

MCP LLM Server FOR ERPNext

mcp-ahmed-mansy-mansico-mcp-llm-server-for-erpnext · by Ahmed-Mansy-Mansico

MCP server from Ahmed-Mansy-Mansico/MCP_LLM_Server_FOR_ERPNext.

No reviews yet
0 installs
18 views
0.0% view→install

Install

$ agentstack add mcp-ahmed-mansy-mansico-mcp-llm-server-for-erpnext

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-ahmed-mansy-mansico-mcp-llm-server-for-erpnext)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
10mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of MCP LLM Server FOR ERPNext? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

MCP Task - Universal ERPNext MCP Connector

A comprehensive Model Context Protocol (MCP) connector for ERPNext that enables LLMs to interact seamlessly with any ERPNext instance through standardized tools and advanced permission controls.

[](https://opensource.org/licenses/MIT) [](https://www.python.org/downloads/) [](https://github.com/frappe/frappe)

🎯 Overview

MCP Task is a general-purpose MCP connector that transforms any ERPNext instance into an AI-accessible business system. It provides:

  • 🔌 Universal DocType Support: Works with any ERPNext DocType without configuration
  • 🛡️ Advanced Permission Model: Field-level, operation-level, and conditional access controls
  • 🚀 Complete CRUD Operations: Create, Read, Update, Delete with full validation
  • 🎨 Web Chat Interface: Built-in chat widget for direct LLM interaction
  • 📊 Comprehensive Auditing: Complete activity logging and permission tracking
  • ⚡ Production Ready: Enterprise-grade security, error handling, and performance

🌟 Key Features

🔧 Complete ERPNext Integration

  • Full CRUD Operations: Create, Read, Update, Delete any document type
  • Intelligent Search: Text-based search across all document fields
  • Flexible Filtering: Query documents with complex filter conditions
  • DocType Agnostic: Works with standard and custom DocTypes automatically

🛡️ Advanced Security & Permissions

  • Multi-Level Access Control: User roles, DocType permissions, field restrictions
  • Conditional Access: Python-based rules for dynamic permission evaluation
  • Audit Trail: Complete logging of all LLM interactions and data access
  • Field-Level Security: Hide sensitive fields from LLM access

🎨 User Experience

  • Web Chat Interface: Floating chat widget integrated into ERPNext UI
  • Real-time Responses: Instant feedback with loading indicators
  • Conversation History: Persistent chat sessions per user
  • Mobile Responsive: Works seamlessly on desktop and mobile devices

🏗️ Architecture

System Overview

graph TB
    LLM[LLM ClientClaude, GPT, etc.] --> MCP[MCP Protocol Handler]
    MCP --> TR[Tool Registry]
    TR --> TOOLS[Document ToolsCRUD Operations]
    TOOLS --> PERM[Permission Engine]
    PERM --> ERP[ERPNext Database]
    
    PERM --> CONFIG[Permission Configuration]
    CONFIG --> FIELD[Field Restrictions]
    CONFIG --> OP[Operation Controls]  
    CONFIG --> COND[Condition Scripts]
    
    MCP --> AUDIT[Audit Logger]
    MCP --> CHAT[Chat Interface]
    
    subgraph "Security Layers"
        PERM
        CONFIG
        AUDIT
    end

Core Components

1. MCP Protocol Handler (api/__init__.py)
  • JSON-RPC 2.0 Compliance: Full MCP protocol implementation
  • Request Routing: Handles initialize, tools/list, tools/call methods
  • Error Management: Comprehensive error handling with proper status codes
  • Authentication: Integration with ERPNext session management
2. Tool Registry System (core/)
  • Dynamic Discovery: Automatic tool loading and registration
  • Permission Integration: Built-in permission validation for each tool
  • Extensible Architecture: Easy addition of custom tools
  • Metadata Management: Tool descriptions and input schemas
3. Document Tools (tools/)
  • create_document: Create any ERPNext document with validation
  • get_document: Retrieve document data with field filtering
  • list_documents: Query documents with flexible filters
  • search_documents: Full-text search across document types
  • update_document: Modify document fields with validation
  • delete_document: Remove documents with dependency checks
4. Advanced Permission Engine
  • MCP Permission Configuration: Configurable access control DocType
  • Multi-Level Security: Role, DocType, field, and operation controls
  • Condition Scripts: Python-based dynamic permission evaluation
  • Field Filtering: Automatic removal of restricted fields from responses
5. Web Interface (public/js/mcp_task.js)
  • Floating Chat Widget: Non-intrusive interface integrated into ERPNext
  • Real-time Communication: WebSocket-based chat with loading indicators
  • Conversation Persistence: User-specific chat history management
  • Responsive Design: Mobile and desktop compatibility
6. Audit & Logging System
  • MCP Chat Log: Complete interaction logging for compliance
  • Permission Tracking: Detailed logs of access control decisions
  • Performance Monitoring: Request timing and error rate tracking
  • Security Auditing: Failed access attempts and policy violations

🚀 Installation & Setup

Prerequisites

  • ERPNext v15+ or Frappe Framework v15+
  • Python 3.10+
  • Node.js 18+ (for building assets)
  • Redis (for background jobs and caching)

Step 1: Install the App

# Clone the repository
cd frappe-bench
bench get-app https://github.com/yourusername/mcp_task

# Install on your site
bench --site your-site.com install-app mcp_task

# Migrate database
bench --site your-site.com migrate

# Build and restart
bench build --app mcp_task
bench restart

Step 2: Configure Permissions

Basic Setup (All Users)
# Enable MCP access for all users (basic setup)
bench --site your-site.com execute "frappe.db.set_single_value('System Settings', 'enable_mcp_chat', 1)"
Advanced Setup (Role-Based)
  1. Create MCP Roles (via Setup > Users and Permissions > Role):
  • MCP Admin: Full access to configuration and tools
  • MCP User: Limited access to standard operations
  1. Assign Roles to users through User management

Step 3: Environment Variables

Create a .env file in your bench directory:

# MCP Configuration
MCP_ENABLED=1
MCP_DEBUG=0
MCP_LOG_LEVEL=INFO

# Security Settings
MCP_RATE_LIMIT=100  # Requests per minute per user
MCP_SESSION_TIMEOUT=3600  # Session timeout in seconds

# Optional: External LLM Integration
OPENAI_API_KEY=your_openai_key_here
CLAUDE_API_KEY=your_claude_key_here

Step 4: Basic Configuration Test

# Test MCP endpoint
curl -X POST http://your-site.com/api/method/mcp_task.api.handle_mcp_request \
  -H "Content-Type: application/json" \
  -H "Authorization: token your_api_key:your_api_secret" \
  -d '{
    "jsonrpc": "2.0",
    "method": "initialize", 
    "params": {"protocolVersion": "2024-11-05"},
    "id": 1
  }'

Step 5: Chat Interface Setup

The chat interface is automatically available after installation. Users will see a chat icon in the navbar when logged in.

Troubleshooting: If chat icon doesn't appear:

# Clear cache and rebuild
bench --site your-site.com clear-cache
bench build --app mcp_task
bench restart

🔒 Permission Model & Access Control

Overview

MCP Task implements a multi-layered security model that allows granular control over LLM access to your ERPNext data:

  1. User Authentication: Standard ERPNext login required
  2. Role-Based Access: ERPNext role system integration
  3. DocType Permissions: Native ERPNext permission system
  4. MCP-Specific Controls: Advanced field and operation restrictions

Permission Configuration

Creating Permission Rules

Navigate to Setup > MCP Task > MCP Permission Configuration to create custom access rules:

# Example: Restrict Sales User to read-only Customer data
{
  "title": "Sales User Customer Access",
  "doctype_name": "Customer", 
  "user_roles": "Sales User",
  "operation_restrictions": {
    "allowed_operations": ["read", "list", "search"],
    "blocked_operations": ["create", "update", "delete"]
  },
  "field_restrictions": {
    "blocked_fields": ["credit_limit", "payment_terms"]
  }
}
Field-Level Restrictions

Control which fields are accessible to the LLM:

{
  "field_restrictions": {
    "allowed_fields": ["customer_name", "customer_group", "territory"],
    "blocked_fields": ["credit_limit", "outstanding_amount", "payment_terms"]
  }
}
Condition-Based Access

Use Python scripts for dynamic permission evaluation:

# Condition Script Example: Only allow access to own records
if doc and doc.get("owner") == user:
    result = True
else:
    result = False

# Complex example: Time-based restrictions
import datetime
current_hour = datetime.datetime.now().hour
if current_hour  17:  # Business hours only
    result = False
else:
    result = True

Permission Examples

Example 1: Basic User Restrictions
{
  "title": "Standard User Access",
  "user_roles": "Employee, Desk User",
  "operation_restrictions": {
    "allowed_operations": ["read", "search", "list"]
  },
  "field_restrictions": {
    "blocked_fields": ["base_amount", "outstanding_amount", "credit_limit"]
  }
}
Example 2: Department-Specific Access
{
  "title": "HR Department Access", 
  "doctype_name": "Employee",
  "user_roles": "HR User, HR Manager",
  "field_restrictions": {
    "allowed_fields": ["employee_name", "department", "designation", "reports_to"]
  },
  "condition_script": "result = frappe.get_roles(user).contains('HR Manager') or doc.get('department') == frappe.db.get_value('Employee', {'user_id': user}, 'department')"
}
Example 3: Financial Data Protection
{
  "title": "Accounts Restricted Access",
  "tool_names": "get_document, list_documents", 
  "operation_restrictions": {
    "conditions": {
      "financial_doctypes": ["Sales Invoice", "Purchase Invoice", "Payment Entry"],
      "require_role": "Accounts User"
    }
  },
  "condition_script": """
# Only accounts users can access financial documents
if doctype in ['Sales Invoice', 'Purchase Invoice', 'Payment Entry']:
    result = 'Accounts User' in frappe.get_roles(user)
else:
    result = True
  """
}

Security Best Practices

1. Principle of Least Privilege
  • Start with minimal permissions and add as needed
  • Use role-based restrictions rather than user-specific rules
  • Regularly audit permission configurations
2. Field Sensitivity Classification
# High Sensitivity (Always Block)
HIGH_SENSITIVITY = [
    "bank_account", "iban", "swift_number",
    "salary", "ctc", "password", "api_key"
]

# Medium Sensitivity (Role-Based Access)
MEDIUM_SENSITIVITY = [
    "credit_limit", "outstanding_amount", 
    "employee_id", "phone", "email"
]
3. Audit Configuration
  • Enable detailed logging for all permission decisions
  • Monitor failed access attempts
  • Regular review of permission effectiveness

🎯 API Usage Examples

LLM Prompt Examples

Document Creation
"Create a new Customer with the name 'Tech Solutions Inc', customer group 'Corporate', and territory 'India'. Set the customer type to 'Company'."

MCP Request:

{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "create_document",
    "arguments": {
      "doctype": "Customer",
      "data": {
        "customer_name": "Tech Solutions Inc",
        "customer_group": "Corporate", 
        "territory": "India",
        "customer_type": "Company"
      }
    }
  },
  "id": 1
}
Document Retrieval with Field Filtering
"Show me the customer details for CUST-001, but hide any financial information."

MCP Response (with field restrictions applied):

{
  "jsonrpc": "2.0", 
  "result": {
    "content": [{
      "type": "text",
      "text": {
        "customer_name": "Tech Solutions Inc",
        "customer_group": "Corporate",
        "territory": "India",
        "customer_type": "Company"
        // Sensitive fields like credit_limit filtered out
      }
    }]
  },
  "id": 1
}
Complex Searches
"Find all Sales Orders from the last 30 days where the customer is from Mumbai territory and the order value is above 50,000."

MCP Request:

{
  "jsonrpc": "2.0",
  "method": "tools/call", 
  "params": {
    "name": "list_documents",
    "arguments": {
      "doctype": "Sales Order",
      "filters": {
        "creation": [">=", "2024-12-15"],
        "territory": "Mumbai",
        "grand_total": [">", 50000]
      },
      "fields": ["name", "customer", "grand_total", "delivery_date"]
    }
  },
  "id": 1
}

⚠️ Security Considerations

Data Protection

  • Encryption in Transit: All MCP communications use HTTPS/WSS
  • Session Management: ERPNext session tokens with configurable timeouts
  • API Rate Limiting: Configurable request limits per user/IP
  • Audit Logging: Complete trail of all LLM interactions

Failure Modes & Mitigation

1. Permission Bypass Attempts
  • Risk: LLM attempts to access restricted data
  • Mitigation: Multi-layer validation, default-deny policies
  • Monitoring: Alert on permission failures
2. Data Leakage via Field Filtering
  • Risk: Sensitive data exposed through related fields
  • Mitigation: Deep field analysis, cascading restrictions
  • Example: Block customer.credit_limit when customer data is filtered
3. Condition Script Vulnerabilities
  • Risk: Malicious Python code in condition scripts
  • Mitigation: Sandboxed execution, restricted imports
  • Validation: Syntax checking, security reviews
4. Large Data Extraction
  • Risk: LLM queries return excessive data volumes
  • Mitigation: Result size limits, pagination controls
  • Configuration: MAX_RESULTS_PER_QUERY = 1000

Security Monitoring

# Example monitoring alerts
SECURITY_ALERTS = {
    "permission_failures": {
        "threshold": 10,  # failures per hour
        "action": "notify_admin"
    },
    "large_queries": {
        "threshold": 5000,  # records per query
        "action": "log_and_limit"
    },
    "sensitive_field_access": {
        "fields": ["salary", "credit_limit", "bank_account"],
        "action": "audit_log"
    }
}

🛠️ Development & Customization

Adding Custom Tools

  1. Create Tool Class (tools/my_custom_tool.py):
from typing import Any
from mcp_task.core.base_tool import BaseTool
import frappe

class MyCustomTool(BaseTool):
    def __init__(self):
        super().__init__()
        self.name = "my_custom_tool"
        self.description = "Custom business logic tool"
        self.requires_permission = "My Custom DocType"
        self.inputSchema = {
            "type": "object",
            "properties": {
                "param1": {"type": "string", "description": "First parameter"},
                "param2": {"type": "integer", "description": "Second parameter"}
            },
            "required": ["param1"]
        }
    
    def execute(self, arguments: dict[str, Any]) -> dict[str, Any]:
        try:
            # Your custom logic here
            result = self.perform_custom_operation(arguments)
            return {"success": True, "data": result}
        except Exception as e:
            return {"success": False, "error": str(e)}
    
    def perform_custom_operation(self, args):
        # Implement your business logic
        pass
  1. Register Tool (in core/tool_registry.py):
from mcp_task.tools.my_custom_tool import MyCustomTool

# Add to load_tools method
self.register_tool(MyCustomTool())

Extending Permission System

  1. Custom Permission Validators:
# mcp_task/permissions/custom_validators.py
def validate_customer_territory(user, doc_data):
    """Only allow access to customers in user's territory"""
    user_territory = frappe.db.get_value("Employee", 
        {"user_id": user}, "territory")
    return doc_data.get("territory") == user_territory
  1. Plugin-Based Architecture:
# mcp_task/plugins/custom_business_rules.py
class CustomBusinessRules:
    def apply_restrictions(self, tool_name, user, doc_data):
        # Custom business logic
        pass

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Ahmed-Mansy-Mansico](https://github.com/Ahmed-Mansy-Mansico)
- **Source:** [Ahmed-Mansy-Mansico/MCP_LLM_Server_FOR_ERPNext](https://github.com/Ahmed-Mansy-Mansico/MCP_LLM_Server_FOR_ERPNext)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.