Reference
AI connectors (MCP), coming soon
Coming soon. AI connectors are not available yet; this page describes how they will work. Citron’s remote Model Context Protocol server lets an AI tool work in one workspace as one member, with that member’s permissions.
Endpoint#
The server is at https://api.console.citronos.com/mcp. Like /graphql, the path has no /v1. It speaks protocol version 2025-11-25 over streamable HTTP and is stateless: every POST gets a JSON answer, there are no sessions, and GET and DELETE answer 405.
AI connectors is a module an admin switches on for the workspace. While it is off, /mcp answers 403 for that workspace’s tokens. Members need the mcp.use permission to connect; mcp.manage lets an admin see and revoke everyone’s connections.
Once it launches, Claude (claude.ai, Claude Desktop and Claude Code), ChatGPT, Cursor, VS Code and any other MCP client can connect. Clients that support OAuth sign in on their own; the rest use a personal token.
Connect a client#
Claude Code#
Add the server, then run /mcp in Claude Code and choose Authenticate. A browser opens on the Citron consent screen. To skip OAuth, pass a personal token as a header instead.
claude mcp add --transport http citron https://api.console.citronos.com/mcp
# then, inside Claude Code: /mcp → citron → Authenticateclaude mcp add --transport http citron https://api.console.citronos.com/mcp \
--header "Authorization: Bearer cmcp_pat_…"Claude Desktop and claude.ai#
Open Settings → Connectors → Add custom connector, enter https://api.console.citronos.com/mcp as the URL and choose Connect, then approve in Citron. To run it locally with a personal token instead, add this to claude_desktop_config.json:
{
"mcpServers": {
"citron": {
"command": "citron-mcp",
"args": ["--base-url", "https://api.console.citronos.com"],
"env": { "CITRON_MCP_TOKEN": "cmcp_pat_…" }
}
}
}Cursor#
Add the server to ~/.cursor/mcp.json. Leave out headers to sign in with OAuth instead of a token.
{
"mcpServers": {
"citron": {
"url": "https://api.console.citronos.com/mcp",
"headers": { "Authorization": "Bearer cmcp_pat_…" }
}
}
}ChatGPT#
Open Settings → Apps & Connectors → Advanced settings, turn on Developer mode, then Create connector. Enter https://api.console.citronos.com/mcp as the MCP server URL and choose OAuth for authentication.
Clients that only run local servers#
A small local stdio server, citron-mcp, forwards every call to the remote endpoint. It is not on npm yet, so ask us for the package file and never install a package of that name from anywhere else. It takes a personal token as --token or in CITRON_MCP_TOKEN, and the base URL as --base-url or in CITRON_BASE_URL. It needs Node 20 or later.
# Node 20+. Not on npm yet: install the package file we send you
npm install -g ./citron-mcp-0.1.0.tgz
citron-mcp --base-url https://api.console.citronos.com --token cmcp_pat_…
# or with environment variables
CITRON_BASE_URL=https://api.console.citronos.com CITRON_MCP_TOKEN=cmcp_pat_… citron-mcpAuthentication#
There are two kinds of credential. OAuth is recommended for clients that support it. Personal tokens work everywhere else.
OAuth 2.1#
The client discovers everything itself. A request without a token gets 401 with a WWW-Authenticate header that points at the protected resource metadata.
POST /mcp HTTP/1.1
Host: api.console.citronos.com
Content-Type: application/json
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://api.console.citronos.com/.well-known/oauth-protected-resource/mcp"| Path | What |
|---|---|
GET /.well-known/oauth-protected-resource/mcp | Protected resource metadata (RFC 9728). |
GET /.well-known/oauth-authorization-server | Authorization server metadata (RFC 8414). The issuer is https://api.console.citronos.com. |
POST /mcp/oauth/register | Dynamic client registration (RFC 7591). |
GET /mcp/oauth/authorize | Starts the authorization code flow. |
POST /mcp/oauth/token | Grants authorization_code and refresh_token. |
POST /mcp/oauth/revoke | Token revocation (RFC 7009). |
- Authorization code with PKCE. Only the
S256method is accepted. - Registered clients are public by default.
client_secret_postandclient_secret_basicare also supported. - A client ID metadata document (an https URL as
client_id) works instead of registration. - Send the resource indicator (RFC 8707)
resource=https://api.console.citronos.com/mcp. - Redirect URIs must be https. Plain http is allowed only on
localhost,127.0.0.1or[::1], on any port. App schemes such ascursor://…are allowed too. - Scopes are
mcp:readandmcp:write. Write includes read. - Access tokens (
cmcp_oat_…) live 1 hour. Refresh tokens (cmcp_ort_…) last 30 days and rotate on every use. - An authorization code used twice revokes everything it issued.
The user approves the connection on a consent screen in the Citron console (/admin/connect/mcp), signed in with their normal session. There they choose the workspace and Read only or Read & write.
Personal tokens#
- Create the tokenIn the console, open Settings → Developers → AI connectors and choose New token.
- Choose name, access and expiryAccess is Read only or Read & write. The token expires after 7, 30 or 90 days, after 1 year, or never.
- Copy it onceThe token (
cmcp_pat_…) is shown once. Citron stores only its SHA-256 hash. Send it asAuthorization: Bearer cmcp_pat_….
The list of tokens shows when each one was last used. You can revoke any of them at any time.
Who the connection acts as#
Both kinds of credential act as the member who created or approved them, in that one workspace. They use the member’s current permissions: changing the member’s role or removing them takes effect immediately. The token’s access level caps what the member could otherwise do.
Record policies (field and record rules), collection access restrictions and module switches apply exactly as in the console.
Tools#
The tools are the same as those of the console’s AI assistant. They cover the inbox and enquiries, forms, bookings, content collections and entries, media, CRM, automations, dashboards and more. What a client sees depends on the member’s permissions, the workspace’s modules and the token’s access.
- Read tools (search, read, summarise, run a dashboard query) work with any token.
- Write tools are listed and run only with a Read & write token. Over MCP a write is applied at once, with no confirmation step in the console. It goes through the same service methods as the console, is audited and returns an
actionId. When the change can be undone, theundo_changetool reverts it. - Destructive tools (delete, archive, revoke) also need the argument
confirm: true. Without it the call returnsCONFIRMATION_REQUIREDand nothing happens. The AI should pass it only after the user has agreed. - Security changes (roles, members, API keys, SSO, domains) need a fresh sign-in, so they are never available over MCP and return
UNAVAILABLE_OVER_MCP. Tools that only navigate the console are not listed. - Tool results mark record data as untrusted. The assistant’s data minimisation applies: no e-mail addresses or phone numbers, and names and message text only when the workspace lets AI read inbox and CRM content (Settings → AI).
- Tools carry the
readOnlyHintanddestructiveHintannotations.
Tool errors#
A tool that fails returns a result with isError: true. Its text starts with one of these codes.
{
"content": [{ "type": "text", "text": "CONFIRMATION_REQUIRED: …" }],
"isError": true
}| Code | When |
|---|---|
READ_ONLY_TOKEN | A write tool was called with a read-only token. |
CONFIRMATION_REQUIRED | A destructive tool was called without confirm: true. Nothing was changed. |
UNAVAILABLE_OVER_MCP | The tool changes security settings and works only in the console. |
PERMISSION_DENIED | The member’s role does not allow this. |
MODULE_OFF | The module the tool belongs to is switched off. |
NOT_FOUND | The record does not exist. |
INVALID_INPUT | The arguments do not fit the tool’s schema. |
LIMIT_REACHED | A limit was reached. |
UNKNOWN_TOOL | No tool by that name is available to this connection. |
Resources#
| URI | Contents |
|---|---|
citron://workspace/summary | The workspace, you, this connection, this week’s numbers, the collections and the tool areas. |
citron://collections/schema | The collections you can read, with their fields. |
citron://collections/{slug}/entries | The first 50 published entries, exactly as the REST delivery API serves them. |
citron://inbox/recent | The latest 25 enquiries, minimised. |
Prompts#
| Prompt | Arguments | What it does |
|---|---|---|
triage_inbox | days | Triages recent enquiries. |
draft_reply | enquiryId, tone, language (bg or en) | Drafts a reply to an enquiry. It never sends it. |
build_collection | description | Plans a content collection from a description. |
HTTP errors and rate limits#
| Status | When |
|---|---|
401 | No usable token: MCP_TOKEN_REQUIRED, MCP_TOKEN_INVALID, MCP_TOKEN_EXPIRED, MCP_TOKEN_REVOKED or MCP_TOKEN_INACTIVE. The answer carries WWW-Authenticate. |
403 | The AI connectors module is off for the workspace. |
405 | GET or DELETE on /mcp. |
429 | Over 120 requests a minute for one token. The answer carries Retry-After: 60. |
503 | MCP is switched off for the whole platform. |
The OAuth endpoints answer errors in the RFC style, { "error", "error_description" }. The public API’s errors are described in errors and rate limits.
Audit and revoking access#
Every tool call writes one mcp.tool.call row to the audit log: the tool, whether it succeeded or its error code, the token id, the OAuth client, the access level and the names of the arguments. Argument values are never logged.
Creating and revoking tokens and OAuth approvals are audited too, as mcp.token.create, mcp.token.revoke, mcp.oauth.approve, mcp.oauth.deny and mcp.oauth.grant.
Revoke a token or a connected app at any time under Settings → Developers → AI connectors. Revoking an OAuth app also ends its refresh token.
This reference covers the public API only and follows the API’s compatibility contract: public responses only ever gain fields. The OpenAPI description of these routes is at /developers/openapi.json.