MCP / AI agents
The service exposes a Model Context Protocol (MCP) server at /mcp. AI
agents — Claude Code, Cursor, in-house agent SDKs — and AI web chats such as
claude.ai and ChatGPT can connect to it and render documents directly from a
conversation, without any custom integration code.
Every tool call is scoped to the caller's organization and authenticated by either an API key or an OAuth 2.0 access token. The agent never needs to know which org it belongs to; that is resolved from the credential.
The three tools
The MCP server exposes three tools in sequence:
| Tool | What it does |
|---|---|
list_templates | Returns the templates available in the caller's organization (name, hash, description). |
get_template_schema | Takes a template hash and returns the expected data fields, so the agent knows what JSON to build. |
render_document | Renders a template with supplied data in the requested format and returns a short-lived download URL (not the file inline). |
A typical agent flow:
- Call
list_templatesto find the right template. - Call
get_template_schemawith the chosen hash to understand the data shape. - Collect or build the data, then call
render_document. - Return the download URL to the user — it expires after 15 minutes by default
(
MCP_RENDER_URL_TTL).
Output formats
render_document accepts the same format values as the HTTP API:
format | What you get |
|---|---|
pdf (default) | Print-ready PDF |
html | Self-contained HTML (inline SVG pages) |
docx | Filled-in Word document |
xlsx | Filled-in spreadsheet |
jpg | Rasterised JPEG pages |
webp | Rasterised WebP pages (lossless) |
original | Source file with data substituted |
csv is not supported and will be rejected.
For jpg and webp, a multi-page document returns a ZIP archive containing
pages/page-001.jpg, pages/page-002.jpg, … Single-page renders return the
bare image URL.
Connecting a developer tool (API key)
Agents running locally — Claude Code, Cursor, MCP-compatible SDKs — authenticate
with an API key. Generate one under Account → API Keys (dc_live_…).
Claude Code (CLI):
claude mcp add --transport http https://<your-host>/mcp \
--header "Authorization: Bearer dc_live_<your-key>"Generic JSON config (works with Cursor, most agent SDKs, and mcp.json):
{
"mcpServers": {
"calco": {
"type": "http",
"url": "https://<your-host>/mcp",
"headers": {
"Authorization": "Bearer dc_live_<your-key>"
}
}
}
}Replace <your-host> with your deployment URL and <your-key> with the key you
generated. The server uses the Streamable HTTP transport (POST /mcp).
Connecting a web chat (OAuth)
claude.ai, ChatGPT, and other MCP-capable web chats can connect via OAuth instead of an API key. The chat walks you through a sign-in using your organization's identity provider — no manual token handling needed.
To add the connector:
- In claude.ai, open Settings → Integrations and choose Add a custom connector.
- Paste the URL:
https://<your-host>/mcp. - Complete the OAuth sign-in flow that appears. The connector will be linked to your account and organization.
ChatGPT's equivalent is found under Settings → Connected apps (Developer Mode).
An administrator must pre-register the chat's OAuth client on the organization's
identity provider (Ory or another OIDC issuer) before users can connect.
Each client needs its redirect URI allowlisted and its access tokens configured
to carry the /mcp URL as the token audience (MCP_RESOURCE_URL). For
claude.ai the redirect URI is https://claude.ai/api/mcp/auth_callback; for
ChatGPT, use the redirect URI from OpenAI's connector documentation. This is a
one-time setup per workspace.
Authentication summary
All requests to /mcp are authenticated. There are two supported methods:
- API key (
Authorization: Bearer dc_live_…) — for developer tools, CI pipelines, and in-house agents. Manage keys in the account area. - OAuth 2.0 access token — for web-chat connectors. Tokens are validated
against the OIDC issuer configured via
OIDC_ISSUER_URL; opaque tokens are validated via RFC 7662 introspection whenOIDC_INTROSPECTION_URLis set.
Either way, every tool call operates within the caller's single organization. No tool argument ever carries an org identifier — it is always resolved from the credential.