MCP Server Reference
Kuroco provides two kinds of Model Context Protocol (MCP) servers. This page summarizes the endpoints, authentication methods, and tool structure of each.
| Server | Endpoint | Purpose |
|---|---|---|
| Client API MCP server | /rcms-api/{id}/mcp | Exposes Client API endpoints as MCP tools. |
| Admin MCP server | /direct/rcms_api/admin_mcp/ | Exposes the same admin operations as the Admin API as MCP tools. |
For MCP client setup (Claude Code, Claude Desktop, Cursor, etc.), see the MCP Client Configuration Reference.
Client API MCP server
An MCP server provided per API (e.g. https://{your-site}.g.kuroco.app/rcms-api/{id}/mcp). When you enable the MCP settings (tool name / input schema / status) on an endpoint, that endpoint is published as an MCP tool.
For detailed setup steps, see Model Context Protocol (MCP) Integration with Kuroco.
Authentication
The connection method follows the API's security setting.
| API security | Connection method |
|---|---|
| None | Connect with the MCP server URL only (no authentication). |
| Static token / privileged static token | Set the token in the X-RCMS-API-ACCESS-TOKEN header. A client that supports header authentication is required. |
| Dynamic access token / Cookie | Connect with OAuth authentication (OAuth Authorization Server, usage = API). Supported by the Claude.ai connector feature and others. |
For dynamic access token / Cookie, this MCP server's resource identifier (the RFC 8707 resource) is the MCP server URL. Access tokens are bound to that identifier:
{API domain}/rcms-api/{id}/mcp
401 responses include an RFC 6750 WWW-Authenticate challenge whose resource_metadata points to the following metadata document (RFC 9728 Protected Resource Metadata). Clients that derive the metadata document URL from the MCP server URL arrive at the same URL:
{API domain}/.well-known/oauth-protected-resource/rcms-api/{id}/mcp
It is a public endpoint (no authentication required), so MCP clients can discover the Authorization Server without authenticating first. It is also reachable via /rcms-api/{id}/mcp?MODE=protected_resource_metadata.
The REST endpoint of the same API (/rcms-api/{id}) is a separate OAuth resource. A token obtained for the MCP server cannot be used for REST calls, and vice versa.
Public endpoints without authentication are not recommended for production use. See the MCP Client Configuration Reference for details.
For the steps to register a Claude.ai connector using OAuth authentication, see How to Register an MCP Connector in Claude.ai.
Admin MCP server
Kuroco exposes the same admin operations as the Admin API as a JSON-RPC 2.0 MCP server, available at /direct/rcms_api/admin_mcp/. MCP-aware clients can register a module-scoped URL described below (e.g. /direct/rcms_api/admin_mcp/x/all) — no CLI build is required.
Authentication
Authentication mode is selected by the credential presented with the request:
| Credential | Mode | Notes |
|---|---|---|
Bearer token (Authorization header) | OAuth access token | Accepts only access tokens issued by an OAuth Authorization Server (usage = AdminMCP). Tokens are audience-bound per RFC 8707 to the scoped URL (/x/...) being accessed. For CI and unattended agents that cannot run the interactive OAuth authorization flow, use the client_credentials grant. |
| No Bearer token (access from the admin UI domain) | Admin session cookie | Uses the same login session as the admin UI. |
401 responses include an RFC 6750 WWW-Authenticate challenge whose resource_metadata points to the metadata document (RFC 9728 Protected Resource Metadata) for the scoped URL being accessed:
/.well-known/oauth-protected-resource/direct/rcms_api/admin_mcp/x/all
A metadata document is served per scoped URL (the above is the /x/all example). It is a public endpoint (no authentication required) that lets MCP clients discover the Authorization Server, and is also reachable via ?MODE=protected_resource_metadata.
OAuth scopes
An access token carries scopes describing which kinds of operation it may perform. Which modules it may operate on is not decided by scopes but by the token audience (the /x/... bundle URL).
| Scope | Permitted operations |
|---|---|
mcp:tools.read | Run read tools, and tools/list |
mcp:tools.write | Run write tools, and tools/list (read tools are permitted too) |
mcp:tools.all | Run every tool, except creating, updating, or deleting groups (permissions) or generic Smarty batches, reconfiguring an OAuth Authorization Server or revoking the authorizations it issued, granting the super-user group to a member, minting a privileged static token, changing the access restrictions (IP addresses), and changing the trigger settings of custom functions (see OAuth Authorization Server for details). |
mcp:admin | Run every tool. Tools that mint tokens are available only with this scope. |
mcp:tools.list | tools/list only (no tool execution) |
- The
401WWW-Authenticatechallenge names the scopes the bundle being accessed requires. A/readonlybundle does not request write scopes. - When the scope is insufficient, the response is
403witherror="insufficient_scope"inWWW-Authenticate, plus a JSON-RPC error. - A token without
mcp:adminneeds at least one of the scopes above. A token carrying onlyopenidreaches no tool. - Connections using the admin session cookie are not restricted by scopes (the administrator's own permissions apply).
IP address access restriction
The Admin MCP endpoint is excluded from the admin panel and KurocoFiles IP address restrictions (so that cloud-hosted MCP clients, whose source IP addresses are not fixed, keep working). To limit connections at the network level, enable the dedicated Admin MCP IP allowlist.
The setting is [Admin MCP access restriction (IP address)] under [Environment] -> [Admin panel]. Select "Enable" and enter one allowed IP address per line. CIDR notation, #comments, and [[IPSETS_*]] constants are supported. For the setup steps, see Admin panel.
Scope and behavior:
| Item | Description |
|---|---|
| Target | The Admin MCP endpoint (/direct/rcms_api/admin_mcp/, including module-scoped URLs and ?MODE=tools). |
| Target authentication paths | Both Bearer tokens (OAuth access tokens) and the admin session cookie. |
| Not covered | ?MODE=protected_resource_metadata (RFC 9728 metadata). It remains a public endpoint that requires no authentication. |
| Evaluation timing | Evaluated before authentication. A request from a disallowed IP address returns 403 regardless of whether the token is valid. |
| Response when denied | 403 with a JSON-RPC error body (Access from this IP address is not allowed.). |
| Behavior when disabled | No restriction is applied when "Enable" is off or when the list is empty (including a list that contains only comment lines). The default is no restriction. |
| When constants expand to nothing | No allowed IP address is obtained, so all requests are denied (for example, when an undefined [[IPSETS_*]] is specified). |
[Admin panel access restriction (IP address)] does not apply to the Admin MCP endpoint. However, the OAuth authorization code flow (authorization_code) and the admin session cookie both go through the admin panel login and consent screens, and those screens are subject to [Admin panel access restriction (IP address)].
Obtaining a token with client_credentials, refreshing a token, and calling Admin MCP with an already-issued token are not subject to [Admin panel access restriction (IP address)]. Use [Admin MCP access restriction (IP address)] to limit the source of those requests as well.
This restriction also applies to Admin MCP access from AI agent features inside the admin panel, such as AI agent assist. An administrator using the admin panel from an IP address that is not on the list cannot use these features until that IP address is added.
The [Environment] -> [Admin panel] screen itself is not subject to this restriction, so the setting can always be changed or turned off.
Module-scoped MCP servers
Path segments after /admin_mcp/ bundle one or more admin modules into a single MCP server (one credential per agent), modeled on the GitHub MCP /x/<csv>/readonly pattern:
POST /direct/rcms_api/admin_mcp/x/all # All tools
POST /direct/rcms_api/admin_mcp/x/topics_group_1,topics_group_5,member,services
POST /direct/rcms_api/admin_mcp/x/topics_group_1,topics_group_5/readonly
POST /direct/rcms_api/admin_mcp/x/topics_group # Group definition CRUD
POST /direct/rcms_api/admin_mcp/x/sitebuild # Preset for site building
A scoping segment (/x/...) is required. Requests to the bare base URL (/direct/rcms_api/admin_mcp/) are rejected with 400. To use all tools, specify /x/all explicitly.
Recognized CSV entries (same identifiers as the "Published modules" setting of an AI agent):
| Entry | Meaning |
|---|---|
topics_group_<N> | Topics record controllers scoped to topics_group_id = N. The constructor surfaces N in each tool's topics_group_id enum and rejects calls outside the allowed list. |
topics | Same as above with no group restriction. Useful only for admin discovery — tool calls are rejected. |
topics_group | Group definition management (CRUD on t_topics_group). |
services | Service models (Email, Slack, etc.). |
<mt> | Any other admin module (member, ec, batch, etc.). |
| Sub-modules | Identifiers that expose only part of a module's operations (site_management_plugin). Only the access scope differs; tool names are the same as with <mt>. |
sitebuild | A preset of tools selected for site building. It exposes tools for content definitions and content, API definitions, site settings, custom functions, and front-end deployment, and does not expose tools for running an existing site (billing and usage, adding sites, form submissions, mail magazine, comments, EC, crawler, member search conditions and issued qualification information, and access-related logs). |
When modules are specified:
- Each write operation becomes its own tool (create / update / delete, and so on)
- A module with no records exposes no read tools (only the create tool is listed)
- Tools that cannot run on the site given its configuration are not listed (Kuroco Edge cache purge on a site that does not go through Kuroco Edge, the Slack and LINE service methods when the integration is not enabled, site environment management on a site with no child sites, and so on)
Appending /readonly to the path removes write tools from the listing.
Module discovery (REST)
Available on the base URL without a scoping segment (/x/...); authentication is still required.
GET /direct/rcms_api/admin_mcp/?MODE=tools
Returns:
{
"modules": [
{"module": "topics", "type": "topics", "tool_count": 8, "label": "...", "description": "..."},
{"module": "member", "type": "controller", "tool_count": 5, "label": "...", "description": "..."},
{"module": "services", "type": "service", "tool_count": 4, "label": "...", "description": "..."}
]
}
type is one of topics (topics record operations), topics_group_admin (group definition management), controller (a general admin module), or service (a service model). Each entry includes the module's display name (label) and description (description); the topics entry also includes the list of selectable groups (groups).
MCP protocol surface
JSON-RPC 2.0 over HTTP POST. The protocol versions negotiated by initialize are 2025-11-25, 2025-06-18, and 2025-03-26.
Supported methods:
| Method | Description |
|---|---|
initialize | Handshake and protocol version negotiation |
notifications/initialized | Client ready notification |
ping | Connection check |
tools/list | List available admin tools (scoped by module) |
tools/call | Execute an admin tool by name |
prompts/list | Returns an empty list (no prompts are provided) |
resources/list | Returns an empty list (no resources are provided) |
The initialize response advertises tools.listChanged. When an operation changes the tool listing or the input schemas (adding a content definition, for example), notifications/tools/list_changed is sent and the tool result also states that the listing is now stale. On receiving the notification, fetch tools/list again.
Tool names take the form {resource}-{verb}. The resource names the kind of record the tool operates on, and does not always match the module name (the site module, for example, holds the kuroco_front, usage, and const resources). Exactly one hyphen is used, separating the resource from the verb; separators inside a resource name stay as underscores (topics_group-create).
| Verb | Operation | Example |
|---|---|---|
-list | List and search records | topics-list |
-get | Get a single record by ID | topics-get |
-create | Add a record | topics-create |
-update | Update records (one, or many via ids / filter; reordering is expressed via the rows argument) | topics-update |
-delete | Delete records (same) | topics-delete |
-validate | Validate input without saving | topics-validate |
-import | Import CSV or row data | topics-import |
| Other admin operations | The admin operation becomes the verb | topics-accept |
| Service methods | {service}-{method} (the service model name is lowercased) | email-send |
Three tools have fixed names and no resource name: whoami (see The whoami tool), topics-describe (content definition structure), and files-create_temp_upload_url (see File uploads).
Exports (CSV / JSON downloads) have no tools of their own: they are requested through the download argument of the corresponding read tool (for example topics-list, member-list), and attachment ZIPs through the download_attachments argument. Neither returns rows; a temporary download URL comes back in download.download_url. When both are sent, download takes precedence. Form display settings have no list/get tool; exporting them uses the dedicated inquiry_disp-export tool.
Cardinality (one record vs many) and execution mode (synchronous vs job) are specified via arguments, not in the tool name. Bulk operations therefore have no dedicated tool names (such as bulk_delete): with {resource}-delete / {resource}-update, select the targets via arguments (ids or filter) and use dry_run / expected_cnt as guards. Tools that support job execution switch between synchronous and job execution via the async argument (e.g. {resource}-import).
The complete tool list depends on which controllers your modules expose. Issue a JSON-RPC tools/list against the scoped URL to enumerate.
Example call:
POST /direct/rcms_api/admin_mcp/x/topics_group_1
Authorization: Bearer <token>
Content-Type: application/json
{"jsonrpc":"2.0","method":"tools/call",
"params":{"name":"topics-create",
"arguments":{"subject":"Hello","topics_group_id":1}},
"id":3}
The whoami tool
whoami returns the effective context of the account and the connection. It is available on every scoped URL and, being a read tool, runs with the mcp:tools.read scope and on /readonly bundles as well. Use it at the start of a session, and before operations with a large impact, to confirm which account, which permissions, and which site the connection is using.
The only argument is kuroco_skills_version (optional). Passing the version of the installed Kuroco Skills bundle returns a comparison against the version this Kuroco revision expects.
The response includes member info, the authentication method, permissions, the client IP, site information (including site.version), security settings, and the Kuroco Skills version comparison. Each field is explained in the response's own notes, so call the tool and check the response directly.
The Kuroco version of the connected site (site.version)
site.version reports the Kuroco version the connected site runs (the release version shown in the admin panel).
| Field | Contents |
|---|---|
site.version.release_level | The release level (100 = stable / 90 = RC / 20 = beta / 0 = alpha) |
site.version.name | The version identifier (stable / rc / beta / alpha). An empty string is returned for a level outside the versions Kuroco itself offers (a level added by an OEM). |
site.version.available | The versions Kuroco offers, with a description of each, most stable first |
site.version.availablelists the versions Kuroco offers, not the values a given site may be switched to. The switchable values are therelease_levelofsite-update/site-create, and the operation runs on the parent site.- A site with no release level set is treated as stable.
For what each version means and how to switch, see Kuroco version management.
Admin MCP is currently updated at high frequency from its feedback loop, and a fix takes several release cycles to reach the stable release. RC carries fixes earlier than stable does, so RC (site.version.name = rc) is recommended when using Admin MCP. The same guidance is included in the description of the whoami tool and in site.version of the response's notes.
The same version block is included in the response of the Admin API GET /direct/rcms_api/admin_api/?action=whoami. Which version to prefer is guidance specific to Admin MCP, so the response itself does not rank the versions (there is no recommended field).
File uploads
A content image/file field accepts a file inline as a data: URI (RFC 2397). The form {"data": "data:...", "desc": "caption"} also sets a caption. Files passed this way are accepted up to 16MB.
For files larger than 16MB, or files you do not want to convert to a data: URI, mint an upload target into temporary storage with the files-create_temp_upload_url tool and upload the bytes out of band.
- Call
files-create_temp_upload_url.file_size(bytes) andext(extension) must be declared. The response carriesfile_id, the presigned upload URL (presigned_url) and its shortened form (presigned_short_url), and the expiry (expiration,expiration_unix). PUTthe raw file bytes topresigned_url.presigned_short_urlis a307redirect topresigned_url, so aPUTsent there may be rejected at the edge with405. In that case resolve the redirect with aGET, read theLocationheader, andPUTto that URL.- Pass the returned
file_idas the value of the image/file field ontopics-create/topics-update(the form{"file_id": "files/temp/...", "desc": "caption"}is also accepted).
The declared file_size and ext are checked both when the upload target is minted and when the file is consumed by the content record. The destination is selected with the storage argument: the shared temporary storage by default, or the site's own S3 bucket with S3 (S3 must be specified on sites where the shared temporary storage is not configured; the tool is not available on GCS sites).
files-create_temp_upload_url is listed only in bundles that expose content record tools. Being a write tool, it is never listed in a /readonly bundle, nor on sites where no presigned upload destination is configured.
Retrieving the OpenAPI definition
The api-export_openapi tool returns an API's endpoint definition in OpenAPI format (OpenAPI 3.1.0). It returns the same content as Export OpenAPI in the admin panel, without going through Swagger UI or a browser.
It is a read tool, so it can be executed with the mcp:tools.read scope and in /readonly bundles. It is exposed in bundles that include the rcms_api module.
| Parameter | Type | Required | Description |
|---|---|---|---|
api_id | integer | Yes | ID of the target API |
format | string | No | Output format: json (default) or yaml. |
The return value contains format and openapi_data. When format is json, openapi_data is a structured object; when it is yaml, openapi_data is a string. Specifying an api_id that does not exist returns an error.
Example call:
POST /direct/rcms_api/admin_mcp/x/rcms_api/readonly
Authorization: Bearer <token>
Content-Type: application/json
{"jsonrpc":"2.0","method":"tools/call",
"params":{"name":"api-export_openapi",
"arguments":{"api_id":1,"format":"json"}},
"id":4}
Limitations
An MCP client may expand a single instruction into several tool calls and send them in parallel. A single admin write does more than save a record — it also rebuilds the search index, purges caches, and runs triggers — so accepting that parallel fan-out as-is would slow down the public site served from the same instance. The following caps prevent that.
All of these caps apply regardless of the credential used (OAuth access token or admin session cookie), so features that use Admin MCP from inside the admin panel, such as AI agent assist, are also covered.
Write request rate limit
| Item | Description |
|---|---|
| Limit | 8 requests per 2 seconds (per site) |
| Target | tools/call for write tools. Counted in the same budget as write requests to the Admin API (/direct/rcms_api/admin_api/). |
| Not covered | tools/call for read tools, and methods such as initialize / tools/list / ping. Fetching the tool list right after connecting, and read calls, are not counted against this write rate limit (the Kuroco-wide concurrent connection limit still applies). |
| Response when exceeded | HTTP 429 with a Retry-After header, plus a JSON-RPC error. The error message also states how many seconds until a retry is admitted. |
| What to do | Issue write calls one at a time instead of in parallel. To combine updates of the same kind, pass ids or filter to {mt}-delete / {mt}-update and handle them in a single call. |
Admission is decided by the number of write requests accepted within that 2-second window. Sending a handful of writes in parallel gets through, but the 9th and later requests receive 429 (the sustained ceiling averages 4 requests per second). A client that receives 429 should retry according to Retry-After (the wait is at most 2 seconds).
Per-request caps on bulk operations
| Item | Description |
|---|---|
| Synchronous | Up to 200 records per call |
Asynchronous (queued as a job with async=true) | Up to 100,000 records per job |
| When exceeded | An error is returned. To handle more than 200 records, either specify async=true or split the call. |
CSV file imports are judged by the same record counts, and a file over the cap fails without importing a single row.
Processing time notice
When a single tool call takes more than 1,000ms, the elapsed time and guidance are appended to the tool result. This is not an error, but consider measures such as stopping parallel writes or narrowing the fields and number of records you request.
Caps on log query tools
| Item | Description |
|---|---|
| Queryable period | The last 12 hours (timestamp_start is required, and a value earlier than 12 hours ago is an error) |
| Call interval | Once every 5 seconds per admin user |
API analytics (api_analytics-list) is exempt from these caps, because it returns results aggregated per
endpoint, so a longer period does not increase the number of rows returned. Instead, a single query may span at
most 35 days: if the difference between timestamp_end and timestamp_start exceeds 35 days, the call fails.
To analyze trends over a long period, use API analytics rather than the raw log tools (api_log-list and
similar). The raw log tools are suited to inspecting individual requests when aggregates cannot explain a
behavior.
Settings that cannot be changed over MCP
Endpoint cache settings (such as the cache period) cannot be changed with the Admin MCP tools: the
api_uri-upsert schema does not declare those parameters, so passing them returns an error. Change the cache
period from the endpoint settings in the admin panel
instead.
Requests to the Admin MCP (/direct/rcms_api/admin_mcp/) are billed per request, the same as regular API requests. Use module-scoped MCP URLs and /readonly whenever possible to limit unintended write traffic.
For CLI-based access to Kuroco Client API, a separate Client CLI (kuroco-client) is also available.
See Kuroco AI Architecture for details.
MCP tooling feedback
The initialize response (instructions) of both the Client API MCP server and the Admin MCP server includes submission steps that let AI clients report problems with the MCP tooling itself to the Kuroco development team. When an AI client notices an unclear tool description, an input schema that does not match actual behavior, or an unexpected error while working, it reports the problem to a dedicated feedback API provided by Kuroco. Reports go to the Kuroco development team and are used to improve MCP.
A report contains the following fields:
| Field | Content |
|---|---|
| Subject (required) | One-line summary of the problem or request |
| Details (required) | Current behavior, expected behavior, reproduction steps |
| Target MCP tool name | e.g. topics-list |
| Client | e.g. Claude Code |
| Model | e.g. claude-fable-5 |
| Email address | Only when a reply is wanted |
The instructions place the following constraints on AI clients:
- Before submitting, the client must always show the user the exact report content and get their approval — feedback must never be submitted silently
- The email address may be sent only when the user asks for a reply and agrees to share it
- No other user data or secrets may be included in the report
Enabling / disabling
The feature is enabled by default. It can be switched on either of the following screens:
- The "MCP tooling feedback" checkbox on [Environment] -> [Site settings] (
/management/site/site_edit/) - The toggle button on the "MCP tooling feedback" card of the Admin MCP settings page (
/management/rcms_api/admin_mcp_info/)
When disabled, the feedback submission steps are removed from the instructions of both MCP servers.
Related documentation
- Model Context Protocol (MCP) Integration with Kuroco - Setup steps for the Client API MCP server
- MCP Client Configuration Reference - Per-client connection setup
- How to Register an MCP Connector in Claude.ai - Connecting with OAuth authentication
- Kuroco Skills Reference - Details on each Kuroco Skills skill
Support
If you have any other questions, please contact us or check out Our Slack Community.