关于 suitecrm-mcp
suitecrm-mcp 是开源网关,让 AI 助手能够访问 SuiteCRM 记录和活动。它面向运行一个或多个 CRM 实例的组织,结合 CRUD 工具、OAuth2/OIDC 身份验证和运维监控。
主要功能
- 01提供 24 个 CRM 操作工具
- 02支持记录搜索、CRUD 和批量更新
- 03处理活动、关联和附件
- 04使用 OAuth2/OIDC 与可撤销 API 密钥
- 05支持多 CRM 实体和 Redis 扩展
- 06集成 Prometheus、Grafana 和 Loki 监控
适用场景
- 01通过 Agent 搜索和更新 SuiteCRM 记录
- 02记录通话并创建关联的 CRM 任务
- 03将助手连接到多个 CRM 实例
- 04检查工具活动和网关运行状态
MCP 相关
该网关通过 SSE 向 MCP 客户端提供 SuiteCRM 搜索、记录、活动和管理工具。客户端使用 API 密钥,CRM 凭据则保留在网关上。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y suitecrm-mcp-gatewaySUITECRM_ENDPOINTSuiteCRM v4_1 REST endpoint URL, e.g. https://crm.example.com/service/v4_1/rest.phpSUITECRM_PREFIXTool name prefix, e.g. suitecrmPORTPort the gateway listens onAUTH0_DOMAIN密钥OIDC provider domain, e.g. your-tenant.auth0.comAUTH0_AUDIENCE密钥OAuth2 API audience identifier本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
suitecrm-mcp
⚡ 在不到 5 分钟内安全地将 AI Agent 连接到企业 CRM。可用于生产环境。
一个用于 SuiteCRM 的开源 MCP(Model Context Protocol)网关。借助安全、持久的 SSE 连接,让 Claude Desktop、Claude Code 和 OpenClaw 等 AI 助手读取和写入你的 CRM 数据。
基于真实的生产环境部署构建。商业替代方案价格昂贵;这个方案免费且开源。
内置由 Redis 驱动的无状态架构,支持水平扩展,并提供完整的可观测性技术栈:Prometheus 指标、Grafana 仪表板(33 个面板)和 Loki 日志聚合。
🚀 为什么选择 SuiteCRM-MCP?
| 特性 | SuiteCRM-MCP(开源) | 商业替代方案 |
|---|---|---|
| 价格 | 永久免费 | 每年数千美元 |
| 功能 | 完整 CRUD(24+ 个工具) | 通常仅支持读取 / 功能有限 |
| 数据隐私 | 100% 可自托管 | 第三方云端 / SaaS |
| 复杂度 | 5 分钟即可设置 | 销售洽谈和漫长的试用期 |
| 可观测性 | 完整的 Grafana/Prometheus | 功能有限 / 封闭 |
🛡️ 企业级信任与安全
专为数据完整性和隐私不可妥协的生产环境打造。
- 凭据零信任: CRM 密码绝不会离开网关服务。MCP 客户端(例如 Claude)仅持有不透明、可撤销的 API 密钥。
- 身份优先: 可无缝集成 Auth0、Azure AD 或任何 OIDC 提供商。
- 满足审计要求: 每次工具调用都会以结构化 JSON(Loki)记录,让你实时准确地了解 AI Agent 正在执行的操作。
- 断路器保护: 如果后端无响应,会自动保护 CRM,避免故障级联。
目录
| 章节 | |
|---|---|
| ✨ | 功能 |
| 🛠️ | 工具 |
| 🏗️ | 架构 |
| 📊 | 可观测性 |
| 📋 | 前置条件 |
| 🔑 | SuiteCRM API 用户设置 |
| ⚡ | 快速开始 - 单个 CRM |
| 🌐 | 多实体安装 |
| 🐳 | Docker |
| ⚙️ | 配置 |
| 🔒 | TLS |
| 🔌 | 连接客户端 |
| 📊 | 运行状况检查与监控 |
| 🔧 | 故障排除 |
| ✅ | 支持的 SuiteCRM 版本 |
| ⚠️ | 已知限制 |
| 🛡️ | 安全说明 |
| 📄 | 许可证 |
✨ 功能
- 24 个工具,涵盖完整的 CRUD、活动日志(通话、任务、备注)、批量操作、文件附件、下拉选项查询等
- SSE 传输 - 兼容 Claude Desktop、Claude Code、OpenClaw,以及任何支持 HTTP+SSE 的 MCP 客户端
- OAuth2/OIDC 身份验证 - 用户通过 Auth0、Azure AD 或任何 OIDC 提供方登录;网关会签发可撤销的个人 API 密钥
- 客户端计算机上无需凭据 - MCP 客户端仅持有不透明的 API 密钥;CRM 密码保存在网关上
- 基于用户组的实体访问控制 - JWT 用户组声明决定每位用户可以访问哪些 CRM 实例
- 会话自动续期 - CRM 会话过期时会自动重新进行身份验证
- 无状态且可扩展 - 身份验证会话和用户配置缓存在 Redis 中,支持零停机重启,并可在负载均衡器后水平扩展,同时通过粘性会话进行路由(SSE 连接按进程建立;
/messages端点必须到达拥有该 SSE 传输的同一进程) - 统一安装程序 - 一个脚本即可处理单个 CRM(无需 nginx)或 nginx 后的 N 个 CRM,并支持交互式 OAuth 设置
- 实体前缀工具 - 可并行运行多个 CRM 实例,避免名称冲突
- 管理员报告 -
mcp-admin report可根据 Loki 和 SQLite 生成可浏览的 HTML 活动报告,并支持按用户深入查看通话历史、试运行,以及包含模块和字段详情的错误
🛠️ 工具
| 工具 | 描述 |
|---|---|
{prefix}_search | 使用 SQL WHERE 子句搜索记录 |
{prefix}_search_text | 跨模块全文搜索 |
{prefix}_get | 根据 UUID 获取单条记录 |
{prefix}_get_many | 单次调用按 ID 列表获取最多 100 条记录 |
{prefix}_create | 创建新记录 |
{prefix}_update | 更新现有记录 |
{prefix}_delete | 软删除记录 |
{prefix}_count | 统计符合查询条件的记录数 |
{prefix}_bulk_upsert | 一次创建或更新最多 100 条记录 |
{prefix}_get_relationships | 通过链接字段获取相关记录 |
{prefix}_link_records | 在记录之间建立关联 |
{prefix}_unlink_records | 移除关联 |
{prefix}_get_module_fields | 获取模块的字段定义 |
{prefix}_get_dropdown_values | 列出所有下拉选项,或获取其中一项的 key→label 值 |
{prefix}_list_modules | 列出所有可用的 CRM 模块 |
{prefix}_get_recent | 获取当前用户最近查看的记录 |
{prefix}_get_upcoming_activities | 获取即将进行的通话、会议和任务 |
{prefix}_get_record_activities | 获取任意记录的活动历史 |
{prefix}_log_call | 创建通话记录,并将其关联到联系人/客户 |
{prefix}_create_task | 创建任务,可选择关联父记录 |
{prefix}_create_note | 创建备注并关联到父记录 |
{prefix}_get_note_attachment | 从 Notes 记录下载文件附件 |
{prefix}_set_note_attachment | 将文件附件上传到 Notes 记录 |
{prefix}_server_info | 网关状态和连接信息 |
将 {prefix} 替换为已配置的 SUITECRM_PREFIX(默认值:suitecrm)。
支持的模块包括:Accounts、Contacts、Leads、Opportunities、Cases、Calls、Meetings、Tasks、Notes、Emails、Documents、Campaigns、AOS_Quotes、AOS_Invoices、AOS_Products、AOS_Contracts、AOR_Reports、AOW_WorkFlow、SecurityGroups,以及实例中的任何自定义模块。
🏗️ 架构
%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart TB
IdP["🔐 Auth0 / Azure AD\nIdentity Provider"]
subgraph Clients["MCP Clients"]
CD["Claude Desktop"] ~~~ CC["Claude Code"] ~~~ OC["OpenClaw"]
end
GW["⚡ suitecrm-mcp gateway\nOAuth2 · API keys · SSE"]
subgraph CRMs["SuiteCRM Instances"]
C1[("CRM A")] ~~~ C2[("CRM B")] ~~~ CX[("CRM X")]
end
IdP -.->|"confirms identity (OAuth2 callback)"| GW
GW -.->|"issues API key"| Clients
Clients -->|"Bearer token"| GW
GW -->|"Hybrid v8 GraphQL\n(v4_1 Fallback)"| CRMs
style GW fill:#2b6cb0,stroke:#63b3ed,stroke-width:2px,color:#fff
style IdP fill:#2d3748,stroke:#718096,color:#e2e8f0
style CD fill:#2a4a7f,stroke:#63b3ed,stroke-width:1px,color:#ebf8ff
style CC fill:#2a4a7f,stroke:#63b3ed,stroke-width:1px,color:#ebf8ff
style OC fill:#2a4a7f,stroke:#63b3ed,stroke-width:1px,color:#ebf8ff
style C1 fill:#553c9a,stroke:#b794f4,stroke-width:1px,color:#faf5ff
style C2 fill:#553c9a,stroke:#b794f4,stroke-width:1px,color:#faf5ff
style CX fill:#553c9a,stroke:#b794f4,stroke-width:1px,color:#faf5ff
style Clients fill:#0d1b2e,stroke:#4299e1,stroke-width:1px,color:#90cdf4
style CRMs fill:#1a0533,stroke:#9f7aea,stroke-width:1px,color:#d6bcfa
用户通过 Auth0 或 Azure AD 登录一次;网关会签发个人 API 密钥。MCP 客户端在每个请求中都将其附加为 Authorization: Bearer <key>。CRM 凭据绝不会离开网关。支持多个 CRM 实例——每个实例使用自己的端口和工具命名空间(suitecrm_crm1_*、suitecrm_crm2_*)。
智能混合路由: 网关会自动通过速度极快的 SuiteCRM 8 GraphQL API 路由基本 CRUD 操作和记录获取。如果 AI 请求的复杂搜索需要使用 GraphQL 不支持的原始 SQL 筛选条件,网关会拦截请求,并透明地回退到旧版 v4.1 REST API,从而确保功能 100% 完整,无需人工干预。
无状态持久化: 网关将身份验证会话和用户资料从本地内存/文件迁移到 Redis,因此完全无状态。这支持水平扩展(在负载均衡器后运行多个网关实例)、全局速率限制,以及无缝重启而不会断开活动中的 AI 连接。在负载均衡器后运行多个实例时,必须启用粘性会话路由:SSE 传输及其 /messages 端点必须由同一进程处理。
📊 可观测性
项目附带完整的可观测性技术栈,配置位于 docker-compose.yml 中——只需一条命令,即可与网关一同启动所有组件。
| 组件 | 提供内容 |
|---|---|
| Prometheus | 17 项指标:请求速率、按实体划分的延迟直方图、活动会话、CRM 错误代码、熔断器状态、速率限制触发次数、身份验证计数器 |
| Grafana | 包含 33 个面板的实体仪表板(系统健康状况、用户/会话表、CRM 后端、安全性、工具细分)+ 多实体舰队概览仪表板。可在 Grafana Explore 中并排查询结构化日志和指标。 |
| Loki | 通过 Promtail 摄取结构化 JSON 日志——在 Grafana Explore 中使用 LogQL,直接按用户、实体或请求 ID 搜索和筛选日志,并与指标一同查询。非个人身份信息字段(状态、阶段、类型、日期)会记录实际值;敏感字段(姓名、电子邮件、搜索查询)始终会被脱敏。 |
内置告警规则包括:熔断器开启、身份验证失败率过高、延迟违反 SLO、会话过期风暴。
mcp-admin report 会使用两个数据源生成 HTML 活动报告——Loki 提供历史调用记录,SQLite 覆盖当前时段,两者会自动合并。默认报告周期为每日;也支持 --period weekly 和 --period monthly。--serve 会通过 nginx 在 /report 发布报告。--user <email> 可查看单个用户的调用、试运行和错误详情,包括模块和字段信息。
📋 前置条件
- Ubuntu 20.04+ 或 Debian 11+(安装程序使用
apt、systemd和nginx) - Python 3.8+
- Root/sudo 访问权限
- 如果未安装 Node.js,安装程序会自动安装
- Redis 6.0+(会话和资料持久化所必需)
🔑 SuiteCRM API 用户设置
连接前,请确保已为 CRM 用户启用 API 访问权限:
- 以管理员身份登录 SuiteCRM
- 前往 Admin → User Management → 打开用于身份验证的用户
- 勾选 "Is Admin",或将 "API User" 设为 Yes(字段名称因 SuiteCRM 版本而异)
- 保存
如果未启用 API 访问权限,网关会在连接时立即返回 HTTP 401 和 CRM authentication failed: Invalid Login;这是首次运行时最常见的问题。
对于生产环境:请创建专用的 API 用户,仅授予 AI 助手所需的模块权限。不要使用管理员账号。
⚡ 快速开始 - 单个 CRM
适用于一个 CRM,并自动配置 HTTPS 和 OAuth 登录。
要求: Ubuntu/Debian、Python 3.8+、root 权限、指向此服务器的域名、OAuth 应用凭据(参见 docs/auth0-setup.md)
git clone https://github.com/anirudhx7/suitecrm-mcp.git
cd suitecrm-mcp
sudo python3 install.py \
--url https://your-crm.example.com \
--domain mcp.yourserver.com \
--email [email protected]
安装程序会提示你配置 OAuth(issuer、client ID/secret、audience、gateway URL),然后自动设置 nginx、certbot 和 systemd。
安装完成后,用户可通过 https://mcp.yourserver.com/auth/login 进行身份验证并获取 API 密钥。
测试网关运行状况:
curl https://mcp.yourserver.com/health
在 Claude Desktop 中验证是否正常运行:
添加 MCP 服务配置(参见 docs/connect-claude-desktop.md)并重启 Claude Desktop 后,点击锤子图标。你应该会看到 24 个工具:suitecrm_search、suitecrm_get 等。
试试这个测试提示词:"列出 CRM 中最前面的 5 个账户"——Claude 应该会自动调用 suitecrm_search。
🌐 多实体安装
适用于 nginx 后面的 N 个 CRM 实例——每个实例都有自己的端口和路径。
1. 复制并填写配置:
cp entities.example.json entities.json
# Edit entities.json with your CRM endpoints and ports
2. 运行安装程序:
sudo python3 install.py --config entities.json
3. 启用 HTTPS(生产环境推荐):
传入 --domain 和 --email。安装程序会使用你的域名更新 nginx 配置,并自动运行 certbot。
sudo python3 install.py --config entities.json \
--domain mcp.yourserver.com \
--email [email protected]
域名必须已指向此服务器的公网 IP,并且必须开放端口 80 和 443。完成此步骤后,可通过 https://mcp.yourserver.com/<code>/sse 访问网关。
配置完成后,域名会自动保存。之后运行 --add 和 --remove 时会保留 HTTPS,无需再次指定 --domain。
4. 开放 nginx 端口(如果使用 ufw,仅限 HTTP 安装):
sudo ufw allow 8080/tcp
5. 测试特定实体:
在 /auth/login 完成身份验证并获取 API 密钥后:
curl -s -H "Authorization: Bearer your_api_key_here" \
http://YOUR_SERVER:8080/crm1/test
# Expected: {"success":true,"crm_user":"...","email":"...","entity":"crm1"}
6. 连接地址: http://YOUR_SERVER:8080/<code>/sse(若启用了 HTTPS,则使用 https://your-domain/<code>/sse)
在 Claude Desktop 中验证是否正常运行: 重启 Claude Desktop 后,点击锤子图标。你应该会看到每个实体有 24 个工具:suitecrm_crm1_search、suitecrm_crm2_search 等。
稍后添加实体(不会影响现有实体):
sudo python3 install.py --add --config entities.json
移除实体:
sudo python3 install.py --remove crm2
🐳 Docker
无需接触 Node.js 或系统软件包即可运行网关的最快方式。每次向 main 推送时,都会将预构建镜像发布到 GitHub Container Registry。
生产环境中,请固定到 v5.4.0 这样的发布标签,而不要使用浮动的 latest。
curl -o docker-compose.yml https://raw.githubusercontent.com/anirudhx7/suitecrm-mcp/v5.4.0/docker-compose.yml
创建实体配置(身份验证服务会读取此配置以构建 MCP 客户端命令):
cp entities.example.json entities.json
# edit entities.json - set endpoint, port, group for your CRM
编辑 docker-compose.yml 并填写 SUITECRM_ENDPOINT、AUTH0_* 变量和 GATEWAY_PUBLIC_URL,然后:
docker compose up -d
网关运行在 http://localhost:3101。访问 /auth/login 进行身份验证并获取 API 密钥。
要更新到较新的固定版本,请更改 docker-compose.yml 中的镜像标签并重新部署:
docker compose pull && docker compose up -d
从 v5.0.0 之前的版本升级: v5.0.0 引入了无状态 Redis 架构。如果你有旧镜像创建的现有
suitecrm-state命名卷,该卷将不再用于 SQLite。系统会自动配置新的 Redis 容器和卷。docker compose down docker volume rm suitecrm-mcp_suitecrm-state docker compose up -d所有持久化状态(会话、配置文件)都存储在此卷中。重新创建该卷会清除其中的文件,用户需要重新登录。
对于使用自签名证书的 CRM,请在环境变量块中添加 NODE_TLS_REJECT_UNAUTHORIZED: "0"。若要终止 HTTPS(生产环境中的 OAuth 必需),请在前面部署反向代理(nginx、Caddy)。
测试网关运行状况:
curl http://localhost:3101/health
使用 Docker 部署多实体
每个容器只处理一个 CRM 实体。对于 N 个实体,请在 docker-compose.yml 中添加 N 个服务块,每个服务使用独立端口。
完整的多实体 Compose 示例(两个实体)
services:
suitecrm-mcp-auth:
image: ghcr.io/anirudhx7/suitecrm-mcp:v5.4.0
command: node auth.mjs
working_dir: /app
ports:
- "127.0.0.1:3100:3100"
- "127.0.0.1:9091:9091" # auth metrics (Prometheus)
environment:
AUTH0_DOMAIN: your-tenant.auth0.com
AUTH0_CLIENT_ID: your-client-id
AUTH0_CLIENT_SECRET: your-client-secret
AUTH0_AUDIENCE: https://your-api-identifier
GATEWAY_PUBLIC_URL: https://mcp.yourdomain.com
SESSION_TTL_DAYS: "30"
PORT: "3100"
METRICS_PORT: "9091"
METRICS_BIND: "0.0.0.0" # 0.0.0.0 required so the Prometheus container can reach it by service name
restart: unless-stopped
suitecrm-mcp-crm1:
image: ghcr.io/anirudhx7/suitecrm-mcp:v5.4.0
ports:
- "127.0.0.1:3101:3101" # expose via reverse proxy only
- "127.0.0.1:9101:9090" # entity metrics (Prometheus)
environment:
SUITECRM_ENDPOINT: https://crm1.example.com/legacy/service/v4_1/rest.php
SUITECRM_PREFIX: suitecrm_crm1
SUITECRM_CODE: crm1
AUTH0_DOMAIN: your-tenant.auth0.com
AUTH0_AUDIENCE: https://your-api-identifier
REQUIRED_GROUP: crm1_users
PORT: "3101"
METRICS_PORT: "9090"
METRICS_BIND: "0.0.0.0"
depends_on:
suitecrm-mcp-auth:
condition: service_healthy
restart: unless-stopped
suitecrm-mcp-crm2:
image: ghcr.io/anirudhx7/suitecrm-mcp:v5.4.0
ports:
- "127.0.0.1:3102:3102" # expose via reverse proxy only
- "127.0.0.1:9102:9090" # entity metrics (Prometheus)
environment:
SUITECRM_ENDPOINT: https://crm2.example.com/legacy/service/v4_1/rest.php
SUITECRM_PREFIX: suitecrm_crm2
SUITECRM_CODE: crm2
AUTH0_DOMAIN: your-tenant.auth0.com
AUTH0_AUDIENCE: https://your-api-identifier
REQUIRED_GROUP: crm2_users
PORT: "3102"
METRICS_PORT: "9090"
METRICS_BIND: "0.0.0.0"
depends_on:
suitecrm-mcp-auth:
condition: service_healthy
restart: unless-stopped
每个实体需要修改的内容:
- 服务名称(
suitecrm-mcp-crm1、suitecrm-mcp-crm2……) SUITECRM_ENDPOINT:该 CRM 的 REST API URL(域名后的路径因 SuiteCRM 安装方式而异)SUITECRM_CODE:用于工具名称和 URL 路由的简短标识符(例如,crm1会生成名为suitecrm_crm1_search、suitecrm_crm1_get等的工具)PORT和主机端口映射:每个实体都需要使用独立端口(3101、3102……)
所有实体共用的内容:
AUTH0_DOMAIN和AUTH0_AUDIENCE:一个 Auth0 应用负责处理所有实体- 认证服务(
suitecrm-mcp-auth)为共享服务;实体容器依赖于它
在前面配置反向代理(nginx、Caddy),将 /crm1/ 路由到端口 3101,将 /crm2/ 路由到端口 3102,并将 /auth/ 路由到任意一个实例。在生产环境中使用多个 CRM 时,install.py --config entities.json 会在 Linux 主机上自动完成所有这些配置。
⚙️ 配置
单实体 - 环境变量
| 变量 | 必需 | 默认值 | 说明 |
|---|---|---|---|
SUITECRM_ENDPOINT | 是 | - | 指向 /service/v4_1/rest.php 的完整 URL |
SUITECRM_PREFIX | 否 | suitecrm | 工具名称前缀 |
PORT | 否 | 3101 | 监听端口 |
BIND_HOST | 否 | 127.0.0.1 | 网关服务绑定的接口 |
SUITECRM_CODE | 否 | - | 用于多实体 nginx 路由的实体代码 |
REDIS_URL | 是 | redis://127.0.0.1:6379 | Redis 会话存储的连接字符串 |
AUTH0_DOMAIN | 是(认证) | - | Auth0 租户域名(实体网关) |
AUTH0_AUDIENCE | 是(认证) | - | Auth0 API 标识符(实体网关) |
AUTH0_CLIENT_ID | 是(认证服务) | - | Auth0 客户端 ID(仅限认证服务) |
AUTH0_CLIENT_SECRET | 是(认证服务) | - | Auth0 客户端密钥(仅限认证服务) |
GATEWAY_PUBLIC_URL | 是(认证服务) | - | 网关的公开基础 URL(仅限认证服务) |
SESSION_TTL_DAYS | 否(认证服务) | 30 | 会话令牌有效期,单位为天(仅限认证服务) |
REQUIRED_GROUP | 否 | - | 访问此实体所需的 Auth0 角色 |
NODE_TLS_REJECT_UNAUTHORIZED | 否 | - | 仅对自签名证书设置为 0 |
NODE_NO_WARNINGS | 否 | - | 设置为 1 以禁止显示 Node 警告 |
TRUST_PROXY | 否 | - | 在 nginx 或其他反向代理后运行时设置为 1 |
METRICS_PORT | 否 | 9090 | Prometheus 指标服务器端口 |
METRICS_BIND | 否 | 127.0.0.1 | 指标服务器绑定地址 |
CRM_TIMEOUT_MS | 否 | 30000 | CRM REST API 请求超时时间,单位为毫秒 |
CIRCUIT_BREAKER_THRESHOLD | 否 | 5 | 熔断器打开前允许的连续 CRM 故障次数 |
CIRCUIT_BREAKER_RESET_MS | 否 | 60000 | 熔断器转为半开状态前的等待时间,单位为毫秒 |
多实体 - entities.json
{
"crm1": {
"label": "My Company CRM",
"endpoint": "https://crm.mycompany.com/service/v4_1/rest.php",
"port": 3101
},
"crm2": {
"label": "Client B CRM",
"endpoint": "https://crm.clientb.com/service/v4_1/rest.php",
"port": 3102,
"tls_skip": true
}
}
键会成为实体代码(nginx 路径前缀、工具前缀后缀、服务名称)。端口必须唯一。
🔒 TLS
网关 HTTPS(Let's Encrypt)
向安装程序传入 --domain 和 --email,即可为网关本身启用 HTTPS。安装程序会将 nginx 配置为 TLS 终止反向代理,并运行 certbot 来获取和自动续期证书。
要求:
- 域名必须已指向此服务器的公网 IP
- 必须开放 80 端口(ACME 挑战)和 443 端口(HTTPS)
如果 certbot 在安装期间运行失败,网关仍会通过 HTTP 运行。修复 DNS/防火墙后重新运行:
certbot --nginx -d your.domain.com -m [email protected] --agree-tos --redirect
自签名 CRM 证书
如果你的 SuiteCRM 使用自签名证书,请在实体配置(多实体模式)中添加 "tls_skip": true,或在单实体模式下传入 --tls-skip。这会设置 NODE_TLS_REJECT_UNAUTHORIZED=0。
仅在可信的内部网络中使用此设置。切勿将跳过 TLS 验证的网关暴露到公共互联网。
🔌 连接客户端
任何支持带自定义请求标头的 SSE 传输的 MCP 客户端均可使用。 每个客户端的设置过程各不相同,请参阅对应的客户端指南:
| 客户端 | 连接方式 | 设置指南 |
|---|---|---|
| Claude Desktop | 直接使用 SSE,无需桥接 | docs/connect-claude-desktop.md |
| Claude Code (CLI) | 直接使用 SSE,无需桥接 | docs/connect-claude-code.md |
| OpenClaw | 需要安装桥接程序 | docs/connect-openclaw.md |
Claude Desktop 和 Claude Code 通过 SSE 直接连接到网关 URL。 安装网关后,将 SSE 端点和 CRM 凭据添加到 客户端配置中。上述指南提供了完整步骤,包括单实体/多实体配置、HTTPS 变体和验证。
OpenClaw 使用由两个组件构成的设置:网关运行在远程服务上
(通过 install.py 安装),桥接插件则在 OpenClaw
设备上本地运行(通过 install-bridge.py 安装)。桥接程序会将全部 24 个 SuiteCRM
工具代理到网关。OpenClaw 指南涵盖这两个组件的完整配置流程。
📊 健康检查与监控
健康检查端点
| 端点 | 身份验证 | 描述 |
|---|---|---|
GET /health | 无 | 浅层检查——只要进程在运行就会响应 |
GET /health/deep | 无 | 深度检查——对 CRM REST API 执行 ping 并返回延迟 |
# Shallow health
curl http://YOUR_SERVER:3101/health
# {"status":"ok","entity":"crm1","port":3101,"active":2,"circuit_breaker":"closed"}
# Deep health (pings CRM, returns latency)
curl http://YOUR_SERVER:3101/health/deep
# {"status":"healthy","entity":"crm1","uptime":3600,"connections":2,"circuit_breaker":"closed",
# "checks":{"endpoint":{"status":"ok","url":"https://crm.example.com"},
# "api":{"status":"ok","latency_ms":45},
# "sessions":{"status":"ok","active":2}},"duration_ms":47}
/health/deep 在服务正常时返回 HTTP 200,CRM 无法访问时返回 503。每分钟最多允许 10 次请求。
Prometheus 指标
两个组件会在不同端口上暴露 Prometheus 指标(仅限 localhost)。
网关实体指标(默认端口 9090)
| 指标 | 类型 | 描述 |
|---|---|---|
suitecrm_mcp_active_connections | Gauge | 当前打开的 SSE 连接数 |
suitecrm_mcp_connections_total | Counter | 已建立的 SSE 连接总数 |
suitecrm_mcp_tool_calls_total | Counter | 按名称和状态(成功/错误)统计的工具调用次数 |
suitecrm_mcp_tool_duration_seconds | Histogram | 工具调用延迟(通过 buckets 统计 p50/p95/p99) |
suitecrm_mcp_crm_api_duration_seconds | Histogram | CRM REST API 调用延迟 |
suitecrm_mcp_session_renewals_total | Counter | CRM 会话重新认证次数 |
suitecrm_mcp_auth_failures_total | Counter | 认证失败次数 |
suitecrm_mcp_circuit_breaker_state | Gauge | 0=关闭,1=半开,2=开启 |
suitecrm_mcp_circuit_breaker_openings_total | Counter | 熔断器触发次数 |
认证服务指标(默认端口 9091)
| 指标 | 类型 | 描述 |
|---|---|---|
suitecrm_auth_logins_total | Counter | 按结果(新建/复用/错误)统计的 OAuth2 登录完成次数 |
suitecrm_auth_bridge_sessions_total | Counter | 桥接会话事件(已启动/已完成/已过期) |
suitecrm_auth_sessions_active | Gauge | 当前存储的未过期网关会话数 |
# Scrape gateway metrics (single-entity systemd)
curl http://127.0.0.1:9090/metrics
# Scrape auth service metrics
curl http://127.0.0.1:9091/metrics
随附的 docker-compose.yml 会启动 Prometheus + Grafana + Loki 堆栈,并自动抓取这两个服务的指标。在环境中设置 GRAFANA_PASSWORD,然后访问 http://localhost:3000。
系统会自动配置两个仪表板:
- suitecrm-mcp - 单实体视图:33 个面板,涵盖系统健康状况、用户/会话、CRM 后端、安全性和工具明细行
- suitecrm-mcp-fleet - 多实体概览:一览所有实体(熔断器状态、连接数、错误率、延迟)
对于 systemd 安装,请将抓取目标添加到 monitoring/prometheus.yml:
scrape_configs:
- job_name: suitecrm-mcp-auth
static_configs:
- targets: ['127.0.0.1:9091']
- job_name: suitecrm-mcp-crm1
static_configs:
- targets: ['127.0.0.1:9101'] # port 3101 + 6000
- job_name: suitecrm-mcp-crm2
static_configs:
- targets: ['127.0.0.1:9102'] # port 3102 + 6000
熔断器
网关会按实体跟踪连续发生的 CRM REST API 故障次数。当故障次数达到 CIRCUIT_BREAKER_THRESHOLD(默认值为 5)时,熔断器会打开,所有工具调用都会立即返回错误,而不会访问 CRM。经过 CIRCUIT_BREAKER_RESET_MS(默认值为 60 秒)后,熔断器会转为半开状态,并允许一次探测调用通过。探测成功会关闭熔断器;探测失败则会使其保持打开状态。
这样可以防止响应缓慢或无响应的 CRM 占用连接,并导致 MCP 客户端发生级联超时。
当前状态会显示在 /health 和 {prefix}_server_info 工具响应中。
🔧 故障排除
检查服务状态:
sudo python3 install.py --status
查看日志:
journalctl -u suitecrm-mcp -f # single
journalctl -u suitecrm-mcp-crm1 -f # multi
测试网关运行状况:
curl https://mcp.yourserver.com/health
常见问题:
- SSE 返回
HTTP 401- API 密钥无效或已过期;请在/auth/login重新认证 - SSE 返回
HTTP 403- 用户不属于此实体所需的组;请检查身份提供商中的组成员资格 - OAuth 回调错误 - 确认
OAUTH_REDIRECT_URI与身份提供商中注册的值完全一致 - OAuth 后出现
CRM login failed- 找不到 CRM 用户,或未启用 API 访问;运行mcp-admin list,确认该用户在 Redis 中有配置文件 Non-JSON response- CRM 端点 URL 错误;检查其是否以/service/v4_1/rest.php结尾ECONNREFUSED- 服务未运行;请运行journalctl -u suitecrm-mcp- SSE 连接断开 - 长时间空闲时属于正常情况;客户端会自动重新连接
✅ 支持的 SuiteCRM 版本
已在 SuiteCRM 8.8.x 上测试。应该适用于任何提供 v4_1 REST API 的 SuiteCRM 版本——该 API 从早期 SuiteCRM 版本起就已存在。
不支持 SugarCRM——SuiteCRM 分支之后,两个产品的 API 出现了显著差异。
查找你的端点 URL
REST API 的路径因 SuiteCRM 的安装方式而异。常见模式:
https://crm.example.com/service/v4_1/rest.php
https://crm.example.com/legacy/service/v4_1/rest.php
https://crm.example.com/crm/service/v4_1/rest.php
https://crm.example.com/crm/public/legacy/service/v4_1/rest.php
查找端点:登录 SuiteCRM,前往 管理 → 诊断工具 并查看站点 URL,或咨询服务器管理员。端点始终以 /service/v4_1/rest.php 结尾——只有此前的前缀会变化。使用以下命令进行测试:
curl -s -X POST "https://YOUR-PATH/service/v4_1/rest.php" \
--data 'method=get_server_info&input_type=JSON&response_type=JSON&rest_data={}'
# Should return: {"flavor":"CE","version":"...","gmt_time":"..."}
⚠️ 已知限制
LDAP / SSO 用户无法通过 REST API 进行身份验证
SuiteCRM 的 v4_1 REST API 仅使用本地数据库密码进行身份验证。如果你的组织使用 LDAP、Active Directory 或 SSO,通过这些服务登录 CRM 网页界面的用户将没有本地密码——即使凭据正确,网关仍会向他们返回 Invalid Login。
解决方法: 在 CRM 虚拟机上使用 crm-provision-user(由 --setup-crm-host 部署),为任何现有 LDAP/SSO 用户设置本地 API 密码,且不会影响其网页登录。支持为单个用户设置,也支持通过 CSV 批量设置。
# SSH into the CRM VM, then:
# Single user
sudo crm-provision-user john.doe secretpassword
# Bulk - CSV format: username,password
sudo crm-provision-user --csv /path/to/users.csv
这是 SuiteCRM REST API 的限制,并非此网关特有。
🛡️ 安全说明
- 生产环境必须使用 HTTPS。 OAuth 流程和 API 密钥不得通过普通 HTTP 传输。使用
--domain启用 Let's Encrypt,或将网关置于终止 TLS 的代理之后。 - API 密钥属于个人,且可撤销。 每位用户都有一个与其身份关联的专属密钥。管理员可以使用
mcp-admin revoke <sub>立即撤销密钥。密钥泄露不会暴露其他用户的信息。 - CRM 密码不会离开网关。 客户端计算机(Claude Desktop、Claude Code、OpenClaw)仅持有不透明的 API 密钥。CRM 凭据存储在网关 Redis 的
crm:profiles哈希中(通过 Redis 身份验证和网络绑定进行访问控制)。 - 妥善保管
AUTH0_CLIENT_SECRET。 它存储在/etc/suitecrm-mcp/auth.env中(模式为 600),且只有身份验证服务会读取它。 - 环境文件以模式
600写入,环境目录的模式为700 entities.json已列入.gitignore——切勿提交该文件(其中包含 CRM 端点和组名)
有关控制措施和已知限制的完整详情,请参阅 SECURITY.md。
📄 许可证
由 Anirudhx7 构建
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。