Skip to main content

Aventora CRM — MCP Server

Aventora CRM exposes a Model Context Protocol (MCP) server at the workspace URL so Cursor, Claude Desktop, and other MCP clients can find and update People and Notes.

The HTTP path is still POST /mcp. The implementation is Aventora-owned named tools that wrap existing REST record APIs (/rest/people, /rest/notes, /rest/noteTargets). It does not use Twenty’s get_tool_catalog / learn_tools / execute_tool catalog.

Related: CRM complete guide · Engagement Hub MCP · API Security Model


Endpoint

POST https://{crm-host}/mcp
Authorization: Bearer <credential>
Content-Type: application/json

{crm-host} is the CRM public origin from SERVER_URL (for example https://crm.aventora.ai). The canonical MCP URL is always {SERVER_URL origin}/mcp.

Protocol: JSON-RPC 2.0, MCP 2024-11-05 / 2025-03-26 / 2025-06-18 (streamable HTTP). POST /mcp returns HTTP 200 with Content-Type: application/json. JSON-RPC notifications (notifications/*) return 202.

Two credentials are accepted:

ClientCredential
Cursor and existing MCP clientsWorkspace API key JWT from Settings → APIs
Claude Custom ConnectorsMCP OAuth access token (mcp:tools, audience = {origin}/mcp)

Object permissions on the consenting workspace user still apply for Claude OAuth. Workspace API keys keep using the API-key role. Contact create limits still apply.

Settings → AI shows a copy-paste Cursor snippet that uses the workspace API key against this same URL.


Cursor config

{
"mcpServers": {
"aventora-crm": {
"type": "streamable-http",
"url": "https://{crm-host}/mcp",
"headers": {
"Authorization": "Bearer [CRM_API_KEY]"
}
}
}
}

Claude Custom Connector (OAuth)

Claude Custom Connectors use OAuth 2.1 authorization-code + PKCE against the existing CRM Application OAuth server. They do not use a stored workspace API key.

The advertised authorization endpoint is GET /oauth/authorize. That route validates and normalizes the request, then 302s the browser to the existing CRM consent page at /authorize. It does not return JSON.

Authorization-server metadata advertises scopes_supported = ["api", "profile", "mcp:tools"]. Claude may request all of those. The dedicated Claude MCP client (claude-aventora-crm) accepts that request, then grants only mcp:tools. The access token and JWT do not receive generic CRM api or profile access unless those scopes are later configured as allowed for that MCP client. A request with no allowed MCP scope (api profile only) is rejected.

Generic Twenty Application OAuth clients still require the requested scopes to be a subset of the client's registered scopes.

Operator: create the Claude OAuth client

Run once per CRM deployment (or --rotate to issue a new secret). The plaintext secret is printed once and stored only as a bcrypt hash.

docker compose exec server yarn command:prod application:register-claude-mcp-client -w <workspace-uuid>

Optional: --client-id <id> (default claude-aventora-crm), --rotate.

Copy CLIENT_ID and CLIENT_SECRET from the command output. Do not commit the secret.

Registered redirect URIs (exact match):

  • https://claude.ai/api/mcp/auth_callback
  • https://claude.com/api/mcp/auth_callback

Values to enter in Claude

FieldValue
Connector nameAventora CRM
MCP URLhttps://{crm-host}/mcp (must match GET /.well-known/oauth-protected-resource/mcpresource)
OAuth Client IDclaude-aventora-crm (or the --client-id you passed)
OAuth Client Secretthe generated secret from the command

Unauthenticated POST /mcp returns 401 with:

WWW-Authenticate: Bearer realm="mcp", resource_metadata="https://{crm-host}/.well-known/oauth-protected-resource/mcp"

Manual certification

  1. Add the connector in Claude with the values above.
  2. Click Connect.
  3. Confirm the CRM login/consent page appears (unauthenticated users are sent to sign-in; the app is not silently authorized).
  4. Authorize. Confirm the callback to Claude completes.
  5. Confirm Claude discovers MCP tools.
  6. Run tools/list.
  7. Execute a read-only call such as crm_find_people.
  8. Confirm the request is associated with the CRM user who consented (same workspace).
  9. Confirm Cursor / API-key POST /mcp still works independently.

Dynamic Client Registration is not enabled in this phase.


Tools (v1)

ToolWraps
crm_find_peopleGET /rest/people (email, phone, and/or name)
crm_get_personGET /rest/people/{id}
crm_create_personPOST /rest/people
crm_update_personPATCH /rest/people/{id}
crm_create_notePOST /rest/notes and optional POST /rest/noteTargets

This server does not start Hub calls. Use the Engagement Hub MCP for engagements.

Calls to retired Twenty tool names (get_tool_catalog, learn_tools, execute_tool, load_skills) return a JSON-RPC error that lists the Aventora tool names.


Example

{
"jsonrpc": "2.0",
"id": "1",
"method": "tools/call",
"params": {
"name": "crm_find_people",
"arguments": { "email": "jordan@example.com" }
}
}

Changelog

DateChange
2026-08-18Claude MCP Streamable HTTP: POST /mcp returns HTTP 200 and Content-Type: application/json (no charset). Notifications return 202. Nest’s default POST 201 caused Claude to wrap successful crm_find_people as “Error occurred during tool execution”. Rebuild the CRM server image after this change — a container restart is not enough.
2026-08-18Claude MCP REST wrap: named tools no longer clone the live Express IncomingMessage (that threw Cannot set property path). Existing Claude OAuth sessions stay valid.
2026-08-18Claude MCP tools: crm_find_people and other named tools run as the user who approved the connector (not a role-less LOCAL OAuth app). Name search quotes REST ilike filters. Tool failures return MCP isError with the CRM message instead of a generic Claude wrapper.
2026-08-18Claude MCP authorize: advertised authorization_endpoint is GET /oauth/authorize, which 302s to the CRM SPA consent page. It no longer returns { authorization_endpoint: ... } JSON to the browser.
2026-08-18Claude MCP scopes: if Claude requests advertised api profile mcp:tools, CRM grants only mcp:tools on the authorization code and access token. Generic Application OAuth clients are unchanged.
2026-08-18Claude Custom Connectors: OAuth authorization-code + PKCE on the existing CRM Application OAuth server. Unauthenticated /mcp returns 401 with protected-resource metadata. Workspace API keys still work. Operator command: application:register-claude-mcp-client.
2026-08-18Aventora-owned CRM MCP at POST /mcp with named People/Notes tools. Twenty catalog tools are no longer served on this endpoint.