NocoBase CRM MCP
Read-only MCP server for remote agents that need customer, contact, follow-up, and CRM overview data from NocoBase.
The server calls the official nb api resource list|get|query commands. It does not expose create, update, destroy, or arbitrary command execution tools.
Configure
This repository already includes a local config.json generated for the current CRM. To regenerate it from the example:
cp config.example.json config.json
The known CRM collection names in this environment are:
- customers:
t_nt3pjadelqi(客户) - contacts:
t_j77ftx1rf84(客户联系人) - followups:
t_07667a5evtr(跟进记录)
The checked-in example config uses the confirmed mapping:
- customer owner:
kehu_followup_person(跟进人) - customer status/progress:
kh_progress(进度) - customer source:
f_225h6n6v654(客户来源) - contact-to-customer relation:
kehulianxiren_client - follow-up-to-customer relation:
gjjl_client - follow-up-to-contact relation:
gjjl_client_contacts - follow-up owner fields:
gjjl_followup_personandcreatedBy - follow-up date/content:
f_srysmjkwfq1andf_19iplxz0nds
The default NocoBase CLI env is nb-mcp. Override it with:
export NOCOBASE_MCP_ENV=nb-mcp
export NOCOBASE_MCP_CONFIG=/home/nac/repo/nocobase-mcp/config.json
Local stdio MCP
uv run nocobase-crm-mcp --config config.json
Exposed tools:
crm_healthcrm_schemacrm_overviewcrm_filter_optionsresolve_ownerlist_customersget_customerlist_contactslist_followups
crm_config_template is hidden by default because it needs NocoBase data-modeling metadata permissions. Enable it only during configuration work:
NOCOBASE_MCP_ENABLE_CONFIG_TOOLS=1 uv run nocobase-crm-mcp --config config.json
The owner parameter on crm_overview, list_customers, and list_followups accepts a user's username, nickname, email, or English name. The server resolves that value through the users resource, then filters CRM relation fields by user id. If the value is missing or ambiguous, the tool returns a structured error object with candidate users instead of throwing an MCP error. Remote agents should call resolve_owner first when they are unsure which user the requester means.
Use crm_filter_options to discover status/source values and owner candidates before constructing filtered queries. Status/source options are sorted by count descending, with blank source values last.
List tools clamp limit to 1..100 and normalize negative offsets to 0. list_customers, list_contacts, and list_followups return compact rows by default so remote agents do not receive large nested NocoBase relation payloads. Pass include_raw=true only when the original NocoBase row is needed; the raw row is then attached under raw.
list_followups returns content_preview in compact mode. Use include_raw=true when the full follow-up text is needed. get_customer keeps the customer detail record intact, and its related follow-ups stay compact unless include_raw_followups=true.
Tool runtime failures are returned as structured errors:
{
"error": {
"code": "nb_command_failed",
"message": "...",
"hint": "...",
"retryable": false
}
}
Permissions
Runtime tools are read-only, but the role behind nb-mcp needs these read permissions:
- CRM collections:
t_nt3pjadelqi,t_j77ftx1rf84,t_07667a5evtr - user lookup collection:
users, at leastid,username,nickname,email,f_yh_english_name
crm_schema(include_fields=true) and the opt-in crm_config_template are configuration helpers. They use this read-only NocoBase data-modeling command:
nb api data-modeling collections fields list --collection-name <collection> --env nb-mcp --yes
Use a super-admin or configuration-capable role for this one-time discovery step. The remote Agent does not need data-modeling access after config.json is generated.
Do not grant write permissions such as collection apply/destroy, fields apply, or business data create/update/destroy for this MCP.
Remote HTTP MCP
HTTP mode uses streamable HTTP with a separate bearer token for MCP access:
export NOCOBASE_MCP_TOKEN='<long-random-token>'
uv run nocobase-crm-mcp --transport streamable-http --config config.json
Default bind is 0.0.0.0:10087 with path /mcp.
Remote clients must send:
Authorization: Bearer <long-random-token>
For a managed user-level systemd service:
bash scripts/mcp_service.sh start
The first start creates .runtime/nocobase-crm-mcp.env with a random bearer token automatically. It also discovers the current nb executable and saves it as NOCOBASE_MCP_NB_BIN, because the systemd user service does not inherit an interactive shell or nvm PATH. Use new-token only when rotating the token later.
If nb is installed somewhere unusual, set its absolute path before starting:
NOCOBASE_MCP_NB_BIN=/absolute/path/to/nb bash scripts/mcp_service.sh start
Show the saved URL/header/client config:
bash scripts/mcp_service.sh show-config
Check service state, saved paths, saved nb executable, URL, and local HTTP probe:
bash scripts/mcp_service.sh status
Stop or uninstall:
bash scripts/mcp_service.sh stop
bash scripts/mcp_service.sh uninstall
The systemd unit references .runtime/nocobase-crm-mcp.env; it does not embed the bearer token. The env file is written with 0600 permissions and .runtime/ is ignored.