MCP任务-通用ERPNext MCP连接器
全面 模型上下文协议(MCP)连接器 ERPNext,使LLM能够通过标准化工具和高级权限控制与任何ERPNext实例无缝交互。
 ](https://www.python.org/downloads/) ](https://github.com/frappe/frappe)
🎯 概述
MCP任务是 通用MCP连接器 它将任何ERPNext实例转换为AI可访问的业务系统。它提供:
- 🔌 通用DocType支持:无需配置即可与任何ERPNext DocType一起使用
- 🛡️ 高级权限模型:字段级、操作级和条件访问控制
- 🚀 完成CRUD操作:创建、读取、更新、删除,并进行完全验证
- 🎨 网络聊天界面:内置聊天小部件,用于直接LLM交互
- 📊 全面审计:完成活动记录和权限跟踪
- ⚡ 生产就绪:企业级安全性、错误处理和性能
🌟 主要特点
🔧 完成ERPNext集成
- 完整的CRUD操作:创建、读取、更新、删除任何文档类型
- 智能搜索:在所有文档字段中进行基于文本的搜索
- 灵活过滤:查询具有复杂过滤条件的文档
- DocType不可知:自动使用标准和自定义DocType
🛡️ 高级安全和权限
- 多级访问控制:用户角色、DocType权限、字段限制
- 条件接收:基于Python的动态权限评估规则
- 审计跟踪:完整记录所有LLM交互和数据访问
- 现场级安全:隐藏敏感字段,防止LLM访问
🎨 用户体验
- 网络聊天界面:浮动聊天小部件集成到ERPNext UI中
- 实时响应:加载指示器的即时反馈
- 对话历史:每个用户的持续聊天会话
- 移动响应:可在台式机和移动设备上无缝工作
🏗️ 建筑
系统概述
graph TB
LLM[LLM Client
Claude, GPT, etc.] --> MCP[MCP Protocol Handler]
MCP --> TR[Tool Registry]
TR --> TOOLS[Document Tools
CRUD 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核心组件
1. MCP协议处理程序 (api/__init__.py)
- JSON-RPC 2.0合规性:完整的MCP协议实施
- 请求路由:处理初始化、工具/列表、工具/调用方法
- 错误管理:具有适当状态代码的全面错误处理
- 认证:与ERPNext会话管理集成
2. 工具注册系统 (core/)
- 动态发现:自动工具加载和注册
- 权限集成:每个工具的内置权限验证
- 可扩展架构:轻松添加自定义工具
- 元数据管理:工具描述和输入模式
3. 文档工具 (tools/)
create_document:创建任何带有验证的ERPNext文档get_document:使用字段筛选检索文档数据list_documents:使用灵活的筛选器查询文档search_documents:跨文档类型的全文搜索update_document:通过验证修改文档字段delete_document:删除带有依赖性检查的文档
4. 高级权限引擎
MCP Permission Configuration:可配置的访问控制DocType- 多级安全:角色、DocType、字段和操作控件
- 条件脚本:基于Python的动态权限评估
- 字段过滤:自动从响应中删除受限字段
5. web界面 (public/js/mcp_task.js)
- 浮动聊天小部件:非侵入式接口集成到ERPNext中
- 实时通信:基于WebSocket的聊天,带有加载指示器
- 对话持久性:用户特定聊天记录管理
- 响应式设计:移动和桌面兼容性
6. 审计和记录系统
MCP Chat Log:完整的交互日志记录以确保合规性- 权限跟踪:访问控制决策的详细日志
- 性能监控:请求定时和错误率跟踪
- 安全审计:访问尝试失败和违反策略
🚀 安装和设置
先决条件
- ERPNext v15+ 或 Frappe框架v15+
- Python 3.10+
- Node.js 18+ (建筑资产)
- 雷迪斯 (用于后台作业和缓存)
步骤1:安装应用程序
# 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步骤2:配置权限
基本设置(所有用户)
# 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)"高级设置(基于角色)
- 创建MCP角色 (通过设置>用户和权限>角色):
- MCP Admin:完全访问配置和工具 - MCP User:获得标准操作的机会有限
- 指派角色 通过用户管理向用户提供
步骤3:环境变量
创建一个 .env bench目录中的文件:
# 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步骤4:基本配置测试
# 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
}'步骤5:聊天界面设置
安装后聊天界面会自动可用。用户登录后将在导航栏中看到聊天图标。
故障排除:如果聊天图标未出现:
# Clear cache and rebuild
bench --site your-site.com clear-cache
bench build --app mcp_task
bench restart🔒 权限模型与访问控制
概述
MCP任务实现了 多层安全模型 它允许对ERPNext数据的LLM访问进行精细控制:
- 用户认证:需要标准ERPNext登录
- 基于角色的访问:ERPNext角色系统集成
- DocType权限:本地ERPNext权限系统
- MCP特定控制:先进的现场和操作限制
权限配置
创建权限规则
引导到 设置>MCP任务>MCP权限配置 要创建自定义访问规则,请执行以下操作:
# 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"]
}
}字段级别限制
控制LLM可以访问哪些字段:
{
"field_restrictions": {
"allowed_fields": ["customer_name", "customer_group", "territory"],
"blocked_fields": ["credit_limit", "outstanding_amount", "payment_terms"]
}
}基于条件的访问
使用Python脚本进行动态权限评估:
# 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权限示例
示例1:基本用户限制
{
"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"]
}
}示例2:部门特定访问
{
"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')"
}示例3:金融数据保护
{
"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
"""
}安全最佳实践
1. 最小特权原则
- 从最低权限开始,根据需要添加
- 使用基于角色的限制,而不是用户特定的规则
- 定期审核权限配置
2. 现场敏感性分类
# 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. 审核配置
- 为所有权限决策启用详细日志记录
- 监控失败的访问尝试
- 定期审查许可有效性
🎯 API使用示例
LLM提示示例
文档创建
"Create a new Customer with the name 'Tech Solutions Inc', customer group 'Corporate', and territory 'India'. Set the customer type to 'Company'."MCP请求:
{
"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
}使用字段过滤进行文档检索
"Show me the customer details for CUST-001, but hide any financial information."MCP响应(应用了现场限制):
{
"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
}复杂搜索
"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请求:
{
"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
}⚠️ 安全考虑
数据保护
- 传输中的加密:所有MCP通信都使用HTTPS/WSS
- 会话管理:具有可配置超时的ERPNext会话令牌
- API速率限制:每个用户/IP的可配置请求限制
- 审计日志:所有LLM互动的完整记录
故障模式和缓解措施
1. 权限绕过尝试
- 风险:LLM尝试访问受限数据
- 缓解:多层验证,默认拒绝策略
- 监控:权限失败时发出警报
2. 通过字段过滤泄露数据
- 风险:通过相关领域暴露的敏感数据
- 缓解:深场分析,级联限制
- 示例:阻止
customer.credit_limit过滤客户数据时
3. 条件脚本漏洞
- 风险:条件脚本中的恶意Python代码
- 缓解:沙盒执行,限制进口
- 验证:语法检查、安全审查
4. 大数据提取
- 风险:LLM查询返回过多的数据量
- 缓解:结果大小限制、分页控制
- 配置:
MAX_RESULTS_PER_QUERY = 1000
安全监控
# 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"
}
}🛠️ 开发与定制
添加自定义工具
- 创建工具类 (
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- 注册工具 (in
core/tool_registry.py):
from mcp_task.tools.my_custom_tool import MyCustomTool
# Add to load_tools method
self.register_tool(MyCustomTool())扩展权限系统
- 自定义权限验证器:
# 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- 基于插件的体系结构:
# mcp_task/plugins/custom_business_rules.py
class CustomBusinessRules:
def apply_restrictions(self, tool_name, user, doc_data):
# Custom business logic
pass聊天界面定制
CSS样式 (public/css/custom_chat.css):
.mcp-chat-widget {
/* Custom positioning */
bottom: 20px;
right: 20px;
/* Brand colors */
--primary-color: #1976d2;
--secondary-color: #424242;
}
.mcp-message-bubble.user {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}JavaScript扩展 (public/js/custom_chat.js):
// Extend chat functionality
frappe.ready(() => {
// Custom message preprocessing
window.mcpChat.preprocessMessage = function(message) {
// Add custom logic
return message;
};
// Custom response formatting
window.mcpChat.formatResponse = function(response) {
// Add charts, tables, etc.
return response;
};
});📋 完整的API参考资料
MCP协议端点
mcp_task.api.handle_mcp_request
支持JSON-RPC 2.0规范的主MCP协议处理程序。
支持的方法:
initialize:建立MCP连接tools/list:获取当前用户可用的工具tools/call:执行特定工具ping:连接健康检查
可用工具
create_document
通过验证创建新的ERPNext文档。
输入架构:
{
"doctype": "string (required)",
"data": "object (required)",
"submit": "boolean (optional)"
}例子:
{
"doctype": "Customer",
"data": {
"customer_name": "ABC Corp",
"customer_type": "Company"
}
}get_document
按DocType和名称检索文档。
输入架构:
{
"doctype": "string (required)",
"name": "string (required)"
}list_documents
灵活过滤查询文档。
输入架构:
{
"doctype": "string (required)",
"filters": "object (optional)",
"fields": "array (optional)",
"limit": "integer (optional, default: 20)",
"order_by": "string (optional)"
}例子:
{
"doctype": "Sales Order",
"filters": {
"customer": "CUST-001",
"docstatus": 1
},
"fields": ["name", "customer", "grand_total"],
"order_by": "creation desc"
}search_documents
跨文档字段的全文搜索。
输入架构:
{
"doctype": "string (required)",
"search_text": "string (required)",
"fields": "array (optional)"
}update_document
修改现有文档字段。
输入架构:
{
"doctype": "string (required)",
"name": "string (required)",
"data": "object (required)"
}delete_document
删除具有依赖关系验证的文档。
输入架构:
{
"doctype": "string (required)",
"name": "string (required)",
"force": "boolean (optional, default: false)"
}聊天界面API
mcp_task.api.send_chat_message
通过web界面发送消息。
参数:
message:聊天消息文本conversation_id:可选对话ID
mcp_task.api.get_conversation_history
检索当前用户的聊天记录。
参数:
conversation_id:可选的特定对话limit:要检索的邮件数
权限配置API
check_mcp_permissions
验证特定上下文的访问权限。
from mcp_task.mcp_task.doctype.mcp_permission_configuration.mcp_permission_configuration import check_mcp_permissions
result = check_mcp_permissions(
user="user@example.com",
tool_name="get_document",
doctype_name="Customer",
operation="read",
doc_data={"customer_name": "ABC Corp"}
)🔧 故障排除
常见问题
1. 聊天图标未出现
# Check if app is installed
bench --site your-site.com list-apps
# Rebuild assets
bench build --app mcp_task
bench restart
# Check browser console for JavaScript errors2. 权限被拒绝错误
# Check user roles
frappe.get_roles("user@example.com")
# Verify DocType permissions
frappe.has_permission("Customer", "read", user="user@example.com")
# Check MCP permission configurations
frappe.get_all("MCP Permission Configuration", {"enabled": 1})3. 未找到工具
# Check tool registry
from mcp_task.core.tool_registry import get_tool_registry
registry = get_tool_registry()
print([tool["name"] for tool in registry.list_tools()])4. 未应用字段限制
# Check permission configuration syntax
bench --site your-site.com console
>>> doc = frappe.get_doc("MCP Permission Configuration", "CONFIG-NAME")
>>> doc.validate_json_fields()5. 性能问题
# Enable query debugging
frappe.db.set_debug(True)
# Check slow queries in logs
tail -f logs/frappe.log | grep "SLOW QUERY"
# Monitor memory usage
psutil.virtual_memory()调试模式
启用详细日志以进行故障排除:
# Enable debug mode
export MCP_DEBUG=1
bench restart
# Check debug logs
tail -f logs/mcp_task.log日志分析
# Analyze permission failures
frappe.db.sql("""
SELECT user, tool_name, COUNT(*) as failures
FROM `tabMCP Chat Log`
WHERE success = 0
AND creation >= NOW() - INTERVAL 1 DAY
GROUP BY user, tool_name
ORDER BY failures DESC
""")🚀 性能优化
缓存策略
# Tool result caching
from frappe.utils import cint
cache_timeout = cint(frappe.conf.get("mcp_cache_timeout", 300))
@frappe.cache(ttl=cache_timeout)
def get_cached_document_list(doctype, filters):
return frappe.get_all(doctype, filters)数据库优化
-- Add indexes for common queries
CREATE INDEX idx_mcp_chat_log_user_creation
ON `tabMCP Chat Log`(user, creation);
CREATE INDEX idx_mcp_permission_config_enabled
ON `tabMCP Permission Configuration`(enabled, doctype_name);内存管理
# Limit result set sizes
MAX_RESULTS_PER_QUERY = 1000
MAX_FIELD_LENGTH = 10000
def apply_result_limits(results):
if len(results) > MAX_RESULTS_PER_QUERY:
results = results[:MAX_RESULTS_PER_QUERY]
return results� 监控和分析
性能指标
# Built-in metrics collection
METRICS = {
"requests_per_minute": "tools_called / time_window",
"average_response_time": "sum(response_times) / request_count",
"error_rate": "failed_requests / total_requests",
"permission_denials": "count(access_denied_events)"
}健康检查
# System health endpoint
curl -X POST http://your-site.com/api/method/mcp_task.api.handle_mcp_request \
-d '{"jsonrpc": "2.0", "method": "ping", "id": 1}'
# Expected response
{"jsonrpc": "2.0", "result": {"status": "ok", "timestamp": "2024-01-14T12:00:00"}, "id": 1}使用情况分析
# Popular tools report
frappe.db.sql("""
SELECT
tool_name,
COUNT(*) as usage_count,
AVG(CASE WHEN success=1 THEN 1 ELSE 0 END) as success_rate
FROM `tabMCP Chat Log`
WHERE creation >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY tool_name
ORDER BY usage_count DESC
""")🤝 贡献
我们欢迎捐款!请遵循以下指南:
开发设置
# Fork and clone the repository
git clone https://github.com/yourusername/mcp_task
cd mcp_task
# Install development dependencies
pip install -e ".[dev]"
pre-commit install
# Run tests
python -m pytest tests/代码规范
- python:遵循PEP 8,使用类型提示
- 脚本:使用ESLint配置
- 文档:更新README和文档字符串
- 测试:添加新功能的测试
拉取请求流程
- 创建特征分支:
git checkout -b feature/your-feature - 编写测试:确保代码覆盖率>80%
- 更新文档:包括示例和API文档
- 提交PR:附有详细说明和测试结果
📄 许可证
MIT许可证
版权所有(c)2025 MCP任务贡献者
特此免费授予任何获得本软件和相关文档文件(“软件”)副本的人在不受限制的情况下处理软件的权限,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本的权利,以及允许获得软件的人这样做,但须符合以下条件:
上述版权声明和本许可声明应包含在软件的所有副本或实质部分中。
软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、特定用途适用性和非侵权性的保证。在任何情况下,作者或版权持有人均不对因软件或软件的使用或其他交易而产生或与之相关的任何索赔、损害赔偿或其他责任承担责任,无论是在合同、侵权或其他诉讼中。
🆘 支持与社区
获取帮助
- 📖 文档: 全部文件
- 🐛 问题:
- 💬 讨论:
- 📧 电子邮件: ahmedmansy265@gmail.com
社区
- Discord 的中文翻译是“不和谐”或“纷争”。: 加入我们的社区服务器
- 电报: @mcp_tosk_社区
- 领英: 关注更新
商业支持
提供专业实施和支持服务:
- 实施咨询:自定义部署和配置
- 培训和研讨会:MCP集成团队培训
- 定制开发:量身定制的工具和扩展
- 企业支持:SLA支持的支持计划
联系: enterprise@yourcompany.com
______________________________________________________________________
由以下材料制成❤️ ERPNext社区
*使用MCP Task(智能自动化的通用连接器)将ERPNext转换为人工智能驱动的业务系统。*
🎨 UI组件
聊天小部件功能
- 浮动界面:非侵入式聊天覆盖
- 消息气泡:用户和助手消息样式
- 打字指示器:显示AI正在处理的时间
- 响应式设计:适应移动屏幕
- 对话历史:持续聊天会话
集成点
- 导航栏图标:从任何页面轻松访问
- 自动加载:页面加载时初始化
- 事件处理:键盘快捷键和单击处理程序
🔧 配置
为用户启用聊天
默认情况下,所有登录用户都可以使用聊天。您可以通过修改DocType设置中的权限来自定义访问权限。
自定义AI响应
在……里面 api/__init__.py,修改 _process_with_llm 功能与您首选的LLM提供商(OpenAI、Claude等)集成。
📊 监控
聊天记录
所有工具执行都记录在 MCP Chat Log DocType用于:
- 审计合规性
- 性能监控
- 误差跟踪
- 使用情况分析
会话分析
通过以下方式监控聊天使用情况:
- 每个用户的对话计数
- 常用工具用法
- 错误率
- 响应时间
🚀 路线图
- \[\]与外部LLM API(OpenAI,Claude)集成
- \[\]高级工具链和工作流程
- \[\]语音聊天功能
- \[\]多语言支持
- \[\]自定义工具的插件架构
- \[\]高级分析仪表板
🤝 贡献
- 分叉存储库
- 创建要素分支
- 进行更改
- 添加测试
- 提交拉取请求
📄 许可证
MIT许可证-有关详细信息,请参阅许可证文件。
🆘 支持
对于问题和疑问:
- 在GitHub上创建问题
- 检查文档
- 联系人:ahmedmansy265@gmail.com
安装
您可以使用安装此应用程序 长凳 CLI:
cd $PATH_TO_YOUR_BENCH
bench get-app $URL_OF_THIS_REPO --branch develop
bench install-app mcp_task贡献
此应用程序使用 pre-commit 用于代码格式化和linting。请 安装预提交 并为此存储库启用它:
cd apps/mcp_task
pre-commit install预提交配置为使用以下工具检查和格式化代码:
- 颈毛
- 滑动
- 更漂亮
- pyupgrade
许可证
麻省理工学院
