Skip to content

MCP API

The Model Context Protocol (MCP) endpoint lets AI coding assistants (GitHub Copilot, Claude Code, Cursor, etc.) interact with CometCMS directly from the editor. It exposes content types, entries, and media as tools that the AI can discover and call on demand.

MCP is a server-to-server protocol designed for AI tool calling. For traditional REST consumption from frontends or scripts, use the Public API or Admin API instead.


Base URL

https://yourdomain.com/mcp/v1/workspaces/{workspace}

The workspace slug is always part of the URL — there is no unscoped MCP endpoint.


Protocol

CometCMS implements the MCP specification (protocol version 2025-06-18) over JSON-RPC 2.0 with JSON over HTTP POST.

AspectDetail
TransportHTTP POST, Content-Type: application/json
ProtocolJSON-RPC 2.0 + MCP tool primitives
AuthenticationBearer token (see API Tokens)
Required headerAuthorization: Bearer YOUR_TOKEN_HERE
Non-POST requestsReturn 405 Method Not Allowed

Lifecycle

  1. Initialize — the client calls initialize to negotiate the protocol version and discover server capabilities.
  2. Tool discovery — the client calls tools/list to fetch available tool schemas.
  3. Tool calls — the client invokes individual tools via tools/call.
  4. Notificationsnotifications/initialized and ping are accepted but produce no response.

Notifications and requests without an id field are treated as fire-and-forget and return 202 Accepted.


Authentication

All tools require a valid Bearer token with appropriate permission grants. Tokens are created in API-Tokens in the admin:

http
Authorization: Bearer cms_ct_abc123...
HTTP statusMeaning
401Missing or malformed token.
403Token is valid but lacks permission for the requested tool.
404Workspace or resource not found.
422Validation error — check parameter values and types.
500Internal server error.

Error responses follow the JSON-RPC 2.0 error shape with additional context in data:

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32000,
    "message": "Forbidden.",
    "data": {
      "status": 403,
      "details": { "code": "forbidden" },
      "required_permissions": ["content.read:my-workspace:content:pages:*"],
      "recovery": [
        "The token is valid but lacks permission. Update the token in API-Tokens or use a token that already has the required grant."
      ]
    }
  }
}

Server Info

The initialize response advertises the server identity:

json
{
  "protocolVersion": "2025-06-18",
  "capabilities": {
    "tools": { "listChanged": false }
  },
  "serverInfo": {
    "name": "cometcms",
    "title": "CometCMS",
    "version": "0.9.6",
    "description": "Headless CMS content, schema, and media tools."
  }
}

Available Tools

comet_health

Check that the CometCMS instance is reachable and report runtime capabilities.

ParameterTypeRequired
(none)

Required permission: none (authenticated only).

Response fields: ok, name, version, time, extensions.gd (thumbnail support), extensions.zip (backup archive support).


list_content_types

List all content type schemas in the workspace.

ParameterTypeRequired
(none)

Required permission: schema.read on schema:*


get_content_type

Fetch a single content type schema by its collection name.

ParameterTypeRequired
collectionstring

Required permission: schema.read on schema:{collection}


create_content_type

Create a new content type.

ParameterTypeRequired
namestring
labelstring
iconstring
fieldsobject
localesarray of strings
default_localestring
singletonboolean

Required permission: schema.create on schema:{name}

Field names may only contain letters, numbers, underscores, and dashes.


update_content_type

Surgically update an existing content type. Omitted properties are preserved — this is not a full replacement.

ParameterTypeRequired
collectionstring
labelstring
iconstring
fieldsobject
remove_fieldsarray of strings
replace_fieldsboolean
localesarray of strings
default_localestring
singletonboolean

Required permission: schema.update on schema:{collection}

Important: By default, fields are merged into the existing schema (new keys added, existing keys overwritten). To delete fields, use remove_fields. To replace the entire field map, set "replace_fields": true.


delete_content_type

Permanently delete a content type and all its entries.

ParameterTypeRequired
collectionstring

Required permission: schema.delete on schema:{collection}


list_entries

Fetch one paginated page of entries.

ParameterTypeRequired
collectionstring
qstring
sortstring
includestring
localestring
filtersobject
limitinteger (1–100)
offsetinteger
DefaultValue
sort-created_at
limit20
offset0

Required permission: content.read on content:{collection}

Use comma-separated relation names in include to expand relation fields inline (e.g. "include": "author,category").


get_entry

Fetch one entry by its stable ID or slug.

ParameterTypeRequired
collectionstring
identifierstring
includestring
localestring

Required permission: content.read on content:{collection}:{identifier}

When locale matches one of the content type's configured locales, the entry's localized field values are returned for that locale.


create_entry

Create a content entry.

ParameterTypeRequired
collectionstring
entryobject

Required permission: content.create on content:{collection}

The entry object should contain the field values defined in the content type schema. To publish immediately, include "status": "published" (requires the content.publish permission grant).


update_entry

Update a content entry by its stable ID or slug.

ParameterTypeRequired
collectionstring
identifierstring
entryobject

Required permission: content.update on content:{collection}:{identifier}

Only the fields included in entry are modified; omitted fields keep their existing values.


delete_entry

Soft-delete a content entry by stable ID or slug (moves it to the trash).

ParameterTypeRequired
collectionstring
identifierstring

Required permission: content.delete on content:{collection}:{identifier}


list_media

Fetch a compact overview of media files with category counts and one paginated page of results. Use get_media_item for full metadata and URLs.

ParameterTypeRequired
qstring
categorystring
limitinteger (1–100)
offsetinteger

Required permission: media.read


get_media_item

Fetch one media file with URLs, dimensions, visibility status, and editable metadata.

ParameterTypeRequired
filenamestring

Required permission: media.read on media:{filename}


create_media_category

Create a media category or subcategory.

ParameterTypeRequired
namestring
parentstring

Required permission: media.update

If parent is provided, the category is created as a child subcategory. Category names are returned in the meta.categories array of the response.


set_media_category

Assign or clear the category of a media file.

ParameterTypeRequired
filenamestring
categorystring

Required permission: media.update on media:{filename}

Omit category or pass an empty string to remove the file from its current category.


delete_media

Delete a media file.

ParameterTypeRequired
filenamestring

Required permission: media.delete on media:{filename}


Example Session

Initialize

json
--> {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}

<-- {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-06-18","capabilities":{"tools":{"listChanged":false}},"serverInfo":{"name":"cometcms","title":"CometCMS","version":"0.9.6","description":"Headless CMS content, schema, and media tools."}}}

List tools

json
--> {"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}

<-- {"jsonrpc":"2.0","id":2,"result":{"tools":[{"name":"comet_health","title":"CometCMS health","description":"Check the configured CometCMS public API health endpoint.","inputSchema":{"type":"object","properties":{},"additionalProperties":false}},{"name":"list_content_types","title":"List content types","description":"List CometCMS content type schemas.","inputSchema":{"type":"object","properties":{},"additionalProperties":false}}, ...]}}

Call a tool

json
--> {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"list_content_types","arguments":{}}}

<-- {"jsonrpc":"2.0","id":3,"result":{"content":[{"type":"text","text":"{\n    \"data\": [\n        {\n            \"name\": \"pages\",\n            \"label\": \"Pages\",\n            \"icon\": \"file-text\",\n            \"fields\": {\n                \"title\": {\"type\": \"text\", \"required\": true},\n                \"body\": {\"type\": \"richtext\"}\n            }\n        }\n    ]\n}"}]}}

Tool Discovery

AI assistants discover available tools automatically by calling tools/list during initialization. The server returns the full schema for each tool, including parameter names, types, descriptions, and required fields — no out-of-band configuration needed on the client side.


Permission Reference

Every MCP tool maps to one or more permission grants. Below is a quick reference:

ToolPermission(s)
comet_health(authenticated only)
list_content_typesschema.read
get_content_typeschema.read
create_content_typeschema.create
update_content_typeschema.update
delete_content_typeschema.delete
list_entriescontent.read
get_entrycontent.read
create_entrycontent.create (+ content.publish to publish)
update_entrycontent.update (+ content.publish to publish)
delete_entrycontent.delete
list_mediamedia.read
get_media_itemmedia.read
create_media_categorymedia.update
set_media_categorymedia.update
delete_mediamedia.delete

See API Tokens for details on creating tokens and assigning permission grants.

CometCMS Documentation