Create a key via POST /space/:id/keys (see Keys docs) and hand its raw value to the MCP client. modeller and creator exist specifically to scope down what an assistant can do; read/write also work but are broader than most MCP use cases need.
| keyType | Can do via MCP |
|---|---|
read | List/read models and content. No write tools succeed. |
write | Full read/write on both models and content. No delete tool exists for any key type — see below. |
modeller | List/read/create/update models. Cannot touch content at all. |
creator | List/read models (to know what to author against), create/update content. Cannot create/update models. |
Deleting a model or content item is a deliberately irreversible, high-blast-radius action, so it's excluded from the MCP tool surface entirely — delete_model/delete_content are simply never registered in tools/list, for any key type, including write. Deletion is still available over plain REST (DELETE /models/:id, DELETE /content/:id) for callers who need it.
Speaks the MCP Streamable HTTP transport in stateless mode — every request is handled independently (no session id, no server-side connection state), so a client sends a normal JSON-RPC 2.0 body per request. GET/DELETE /mcp return 405 since there is no session/SSE stream to resume.
Headers
| Header | Notes |
|---|---|
X-Contently-Key | Required. An Authorization Bearer token is not accepted on this route. |
Content-Type | application/json |
Accept | Required by the MCP Streamable HTTP spec: must include both application/json and text/event-stream, or the request is rejected with 406 before any auth/tool logic runs. |
Example: tools/list request
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}
Example: tools/call request (a creator key creating content)
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "create_content",
"arguments": {
"modelId": 1,
"title": "Hello world",
"status": "draft",
"data": {
"body": "First post"
}
}
}
}
Example: denied call (same key calling create_model)
{
"content": [
{
"type": "text",
"text": "This API key does not permit write access to model"
}
],
"isError": true
}
A permission denial is a normal MCP tool result with isError: true, not an HTTP error — the JSON-RPC call itself still succeeds.
| Tool | Resource / action |
|---|---|
list_models | model / read |
get_model | model / read |
create_model | model / write |
update_model | model / write |
validate_model_data | model / read |
validate_model_change | model / read |
list_model_content | model / read |
list_content | content / read |
get_content | content / read |
get_resolved_content | content / read |
get_content_references | content / read |
create_content | content / write |
update_content | content / write |
Either a one-line CLI command (personal scope), or a project-shared .mcp.json committed to the repo — both need the raw key in an env var, never hardcoded.
CLI (personal scope)
claude mcp add --transport http contently https://your-host/mcp --header "X-Contently-Key: ${CONTENTLY_MCP_KEY}"
.mcp.json (project-shared, committed to the repo)
{
"mcpServers": {
"contently": {
"type": "http",
"url": "https://your-host/mcp",
"headers": {
"X-Contently-Key": "${CONTENTLY_MCP_KEY}"
}
}
}
}
Claude Code expands ${VAR} from the shell environment at connect time — export CONTENTLY_MCP_KEY before launching Claude Code.
Add a workspace .vscode/mcp.json (or use the Command Palette → "MCP: Open User Configuration" for a user-level config). Use an inputs entry so VS Code prompts for the key once and stores it in its secret storage, instead of writing it into the file.
.vscode/mcp.json
{
"servers": {
"contently": {
"type": "http",
"url": "https://your-host/mcp",
"headers": {
"X-Contently-Key": "${input:contently_mcp_key}"
}
}
},
"inputs": [
{
"id": "contently_mcp_key",
"type": "promptString",
"description": "Contently MCP API key (modeller or creator)",
"password": true
}
]
}
Point your-host at wherever the app is actually deployed (see the README's BASE_PATH note) — and prefer a modeller or creator key over a write key here, since the whole point of these key types is to scope down what the assistant can do.