Skip to main content
Glama
erpuae

Synapse

by erpuae

Synapse

一个面向 Frappe 和 ERPNext 的权限感知型 MCP 服务器。它让 LLM 客户端能够以真实用户的身份、在该用户自己的权限之下,通过 OAuth 读取和写入站点数据,并且每次调用都会写入审计日志。

POST https://<your-site>/api/method/synapse.mcp.handle_mcp

为什么又造一个轮子

大多数 Frappe MCP 服务器以特权模式运行,并把原始 SQL 或 ignore_permissions 文档访问权交给模型。这在个人沙盒环境中没问题,但在业务系统上不可接受。Synapse 采取了相反的立场:

  • 任何地方都不使用 ignore_permissions。 每个工具都以调用用户的身份运行。DocType 权限、用户权限、共享规则以及提交/取消权限全部生效,写入操作通过 Document.insert/save/submit/cancel 进行,因此验证、钩子和工作流与在桌面端完全一致地触发。

  • 在权限之上还有第二道边界,因为“该用户可以在桌面端编辑销售发票”和“持有该用户令牌的代理可以编辑销售发票”是两种不同的决策。

  • 所有操作都会被记录,包括在到达工具之前就被拒绝的调用。

  • 无依赖。 MCP 服务器是内置的,因此 bench install-app 就是完整的安装过程,bench update 也保持安全。

Related MCP server: Frappe Assistant Core

安装

bench get-app https://github.com/erpuae/synapse
bench --site <your-site> install-app synapse

然后随时检查站点状态:

bench --site <your-site> execute synapse.mcp_tools.check.report

它会按需要修复的顺序打印出已配置和缺失的内容。全新安装是完全封闭的:除非你明确允许,否则任何内容都不可访问。

工具

工具

所需操作

list_available_doctypes, describe_doctype

读取

get_doc, get_value, get_list, get_count

读取

create_doc, update_doc, set_value

写入

submit_doc

提交

cancel_doc

取消

delete_doc

删除

run_sql_query

MCP SQL Reader 角色 — 见下文

日期以 MCP 设置中设定的格式返回,默认是 ISO。写入操作接受 ISO 或 DD-MM-YYYY 格式,因此读取-修改-写入的往返过程不会交换日和月。

刻意不暴露:frappe.db.set_value(跳过验证和钩子 — set_value 工具改为加载并保存文档)、任意白名单方法执行、重命名和修订。

四道门

每次调用都要通过全部四道门。它们相互独立,最窄的一道生效。

  1. 身份验证。 端点对访客关闭,因此未认证的 POST 会在任何工具代码运行之前被框架拒绝。

  2. 工具上的角色。 文档工具需要 MCP Agent,SQL 工具需要 MCP SQL Reader。没有该角色,工具甚至不会被列出。

  3. MCP 访问列表(MCP 设置),可以是允许列表或拒绝列表。对于读取以外的任何操作,调用者还必须持有站点已授予该操作的角色。

  4. Frappe 自身的权限,如上所述。

管理员也不例外。它拥有所有角色,因此第 2 和第 3 道的角色检查会通过,但 DocType 列表仍然具有约束力。

访问模式

允许列表 — 除了列出的 DocType(每个都勾选了操作)之外,其他任何内容都不可访问。失败即关闭;新的 DocType 在有人明确允许之前保持不可访问。这是默认模式,全新安装的列表为空,因此任何内容都不可访问。

拒绝列表 — 除了列出的 DocType 之外,所有 DocType 都可访问。用户自身的 Frappe 权限成为工作边界,列表划出任何代理都不应触碰的内容,无论其用户可能做什么。每一行默认阻止所有操作;取消勾选 Block Read 可让 DocType 可读但不可更改。

拒绝列表在完整的 ERP 上更容易使用。其代价是新的 DocType 默认可访问,因此在该模式下会强制执行两组设置,无论是否有人列出它们:

  • 永远不可访问:OAuth Bearer Token、OAuth Authorization Code、OAuth Client、Token Cache、Social Login Key、Connected App、Webhook、Email Account、Integration Request、User Social Login、Access Log。读取这些内容正是读者变成写者的途径。

  • 始终只读:DocType、DocField、DocPerm、Custom DocPerm、Custom Field、Property Setter、Server Script、Client Script、Print Format、Report、Role、Has Role、User、User Permission、System Settings、Workflow、Scheduled Job Type。能够编辑 Custom DocPerm 的代理可以给自己授予任何权限。

在允许列表模式下,这两组设置都不适用 — 那里只有表格是唯一权威。

子表永远不能直接访问;它们通过父表进行读写。匹配不区分大小写,并且在查询列表之前,DocType 名称会针对站点进行规范化,因此 salary slip 无法绕过 Salary Slip 行。

要填充大型允许列表而无需勾选数百个网格行:

bench --site <your-site> execute synapse.mcp_tools.allowlist.grant_all --kwargs "{'dry_run': 1}"
bench --site <your-site> execute synapse.mcp_tools.allowlist.grant_all
bench --site <your-site> execute synapse.mcp_tools.allowlist.show

grant_all 默认只读,并应用相同的两组受保护设置。如果你希望所有内容都可访问,拒绝列表模式加上空列表比 700 行允许列表更诚实地表达了这一点。

设置

1. OAuth。 Frappe 16 发布 OAuth 服务器元数据并支持动态客户端注册,这使 MCP 客户端无需手动创建 OAuth Client 记录即可连接。默认关闭。在 OAuth Settings 中打开 Show Auth Server Metadata、Show Protected Resource Metadata 和 Enable Dynamic Client Registration。Synapse 从不更改这些设置 — 它们影响整个站点的 OAuth 行为,而不仅仅是 MCP。

要清楚令牌授予了什么:Frappe OAuth 令牌不限于 MCP。它授权该用户对整个 /api 表面的访问。

2. 将 MCP Agent 分配给代理将代表的用户。任何进行身份验证的人都是每个工具运行的身份,因此将该用户的范围限定为代理应看到的内容,而不是使用 Administrator。

3. 填写 MCP 设置。 勾选 Enable MCP Endpoint,选择 Access Mode,并填写显示的列表。此时读取操作即可工作。对于写入操作,还要勾选 Enable Write Tools 并在 Role Permissions 中将操作授予特定角色;如果该表为空,则无论其他设置如何,端点都保持只读。

连接客户端

claude mcp add --transport http mysite https://<your-site>/api/method/synapse.mcp.handle_mcp

然后进行身份验证 — 浏览器会打开站点的登录页面。任何支持 Streamable HTTP 和 OAuth 的 MCP 客户端都以相同方式工作;在 Claude Desktop 中,它是 Settings → Connectors → Add custom connector,使用相同的 URL。

原始 SQL — 启用前请阅读

run_sql_query 完全绕过 Frappe 的权限系统。持有 MCP SQL Reader 的用户可以读取站点上的所有表,无论其 DocType 权限如何。只授予那些已经拥有完整数据库访问权限的用户。

在勾选 Enable Read-Only SQL Tool 之前,它处于关闭状态,并且不使用 DocType 访问列表 — 它无法使用,因为它从不指定 DocType。优先使用 get_list 和 get_doc;只有在需要它们无法表达的连接或聚合时才使用 SQL。如果代理经常使用 SQL,说明文档工具缺少它需要的东西。

它背后有两层保护:

  1. 只读数据库用户,由 MariaDB 强制执行,因此即使查询通过了文本过滤器,也无法写入。

  2. mcp_tools/guard.py — 语句类型、无注释、无堆叠语句、关键字阻止列表、表阻止列表和长度上限。文本匹配,因此将其视为腰带而非护甲。

按站点设置第 1 层。以 MariaDB root 身份:

CREATE USER 'mcp_ro'@'localhost' IDENTIFIED BY '<STRONG_PASSWORD>';
GRANT SELECT ON `<DB_NAME>`.* TO 'mcp_ro'@'localhost';
REVOKE FILE ON *.* FROM 'mcp_ro'@'localhost';
FLUSH PRIVILEGES;

然后在 site_config.json 中(绝不在仓库中):

{
  "mcp_ro_db_user": "mcp_ro",
  "mcp_ro_db_password": "<STRONG_PASSWORD>"
}

如果没有这些键,工具会回退到站点自身的读写连接,并在每次查询后回滚。 它可以工作,但守卫成为唯一的边界。在无法创建第二个数据库用户的托管平台上,该回退是唯一选项 — 在启用 SQL 之前要有意识地决定。

使用 site_config.json 中的 mcp_sql_blocked_tables 按站点扩展表阻止列表。仅支持 MariaDB;connection.py 在其他后端上会抛出 NotImplementedError。

审计

每次调用都会写入一条 MCP Access Log 记录 — 成功、拒绝或错误 — 包含工具、用户、身份验证方式、IP、触及的文档、行数和耗时。写入操作还会记录提交的值以及每个更改字段的前后状态。在工具主体运行之前被拒绝的调用(未知工具、缺少角色、参数不匹配)也会被记录:代理探测其无权访问的工具正是审计跟踪的用途。

日志中完全缺失的调用从未到达服务器。 如果工具显示被阻止但日志中没有记录,则阻止发生在客户端,通常是客户端自身的工具权限提示。这是首先要检查的内容。

行在回滚后使用自己的提交写入,因此失败或拒绝的写入仍会留下记录。System Manager 可读取和报告,但无法从桌面端创建或编辑。reference_doctype 和 reference_name 故意使用 Data 而不是 Link 字段 — 审计行绝不能阻止删除其记录的内容。每日任务会删除超过保留窗口的行。如果数据本身不应复制到日志中,请取消勾选 Log Field Values;密码类字段无论如何都会被掩码。

测试

bench --site <your-site> run-tests --app synapse

访问列表、SQL 守卫、工具模式和值转换不导入 frappe,因此它们也可以在无站点的情况下运行:

python -m unittest discover -s apps/synapse -p 'test_mcp_*.py'

许可证

GNU Affero General Public License v3.0 或更高版本。参见 LICENSE。

AGPL 是深思熟虑的选择:如果你将修改后的 Synapse 作为网络服务运行,使用它的人有权获得你的更改。

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables LLMs to interact with any ERPNext instance through comprehensive CRUD operations, advanced permissions, and a web chat interface.
    1
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP server that enables LLMs to interact with ERPNext/Frappe sites for document CRUD, search, reports, workflows, and analytics, respecting user permissions and logging all actions.
    320
    AGPL 3.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI models to securely interact with Frappe Framework/ERPNext instances, supporting document CRUD, RPC methods, file management, workflows, reporting, and more via the Model Context Protocol.
    379 npm
    ISC
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to interact with ERPNext data and functionality through the Model Context Protocol, including document CRUD, report running, and API method calls.
    MIT