Overview
Kuroco Admin MCP is a feature that exposes Kuroco admin panel operations (administrative operations equivalent to admin_api) MCP (Model Context Protocol) serveras tools. It is based on JSON-RPC 2.0 and can be connected to from MCP clients such as Claude Code / Claude Desktop / ChatGPT.
Recommended feature for performing Kuroco administrative operations from AI agents. It conforms to the standard MCP protocol and OAuth 2.0, so it can be used as-is from major MCP clients without installing additional tools.
Key characteristic: Tools are not registered in the DB; instead,admin panel controllers and service models are dynamically turned into MCP tools at runtime. Operations that can be performed in the admin panel can, in principle, be used as-is as MCP tools.
Official reference: MCP client configuration reference Because the specification is actively updated, refer to the official documentation for the final confirmation of connection procedures. It can also be referenced from the bundled kuroco-docs skill:
../kuroco-docs/docs/reference-mcp-ai.mdwithinmcp-server(MCP server) /mcp-client-configuration(client configuration) pages
Distinction from similar features (beware of confusion):
| Feature | Target | Tool implementation |
|---|---|---|
| Admin MCP(this skill) | General administrative operations | Admin controllers/services dynamically turned into tools |
| Front API MCP | Specific APIs (/rcms-api/{id}/...) |
MCP tools registered in the admin panel |
| KurocoEdge MCP actions | Call MCP from Edge rulesClient side | External/own-site MCP tools |
Endpoint
POST https://<site_key>.g.kuroco.app/direct/rcms_api/admin_mcp/x/<module>[,<module>][/readonly]
| URL | Meaning |
|---|---|
.../admin_mcp/x/all |
All tools of all modules |
.../admin_mcp/x/all/readonly |
All modules, read-only |
.../admin_mcp/x/topics_group_5 |
Only record operations for specific content definitions |
.../admin_mcp/x/topics_group |
CRUD for group definitions (TopicsGroup) |
.../admin_mcp/x/member,topics_group_5 |
Multiple modules (comma-separated) |
.../admin_mcp/?MODE=tools |
List of available modules (REST, GET) |
Important rules:
- The endpoint domain is the API domain (
<site_key>.g.kuroco.app)。 The admin domain (.g.kuroco-mng.app) is for the admin panel and Issuer URL, and is not used for the MCP endpoint. Do not assemble the URL by hand; use the values displayed on theAdmin MCP information pageas-is. /x/<スコープ>is required. bare の/direct/rcms_api/admin_mcp/は 400 is returned (the old specification of "omitting scopes = all tools" has been abolished. All tools must always be/x/all)。- The base path must end with a trailing slash. dispatcher URL (default audience) is
/direct/rcms_api/admin_mcp/(including the slash), and/direct/rcms_api/admin_mcp(without the slash) is not resolved.Scoped URLs (/x/all, etc.) should be written without a trailing slash, as shown in the examples. Since the OAuth audience must exactly match the URL notation at token issuance, do not change the URL notation after registration. - Module identifiers may contain only lowercase alphanumeric characters and underscores (
^[a-z][a-z0-9_]*$). The comma-separated order has no functional meaning, but the URL notation is treated as the audience, so once registered, the notation must be fixed. - Regarding topics,Use the three identifiers properly:
topics_group_<N>— scoped to group NActual operations on content (records)topics_group— CRUD on the group definition (TopicsGroup) itself(topics_group-create/-list/-update/-delete)topicsspecified alone — discovery only(an equivalent expression without group constraints). Tool calls are rejected, so it cannot be used for actual operations. Specifytopics_group_<N>for record operations andtopics_groupfor group definition operations
Authentication
There are 3 methods.If a Bearer token is presented, do not fall back to the session (RFC 6750 compliant. Invalid tokens return 401).
Method 1: OAuth 2.0 Authorization Code Flow (recommended)
In the admin console, the OAuth Authorization Server for Admin MCP is
created automatically (on first Admin MCP (default) is seeded).
- Issuer URL:
https://<管理ドメイン>/direct/login/oauth_idp/<idp_id>- Admin console [Admin MCP information page] or displayed on the OAuth Authorization Server edit screen
- CIMD (Client ID Metadata Document / URL client ID) is disabled by default.
When enabled, manual configuration of client_id / secret on the client side becomes unnecessary.
Clients using CIMD will have authorization requests rejected with
invalid_clientwhile it remains disabled (details:Unknown client_id. Client ID metadata documents are not enabled for this authorization server.). Enable it on the OAuth Authorization Server edit screen - Dynamic Client Registration (RFC 7591) is not supported. If CIMD is not used, clients must be registered manually in the admin console
- Protected Resource Metadata (RFC 9728) is published without authentication:
GET /.well-known/oauth-protected-resource/direct/rcms_api/admin_mcp/ - CI/unattended agents use
client_credentialsgrant. It cannot be used with CIMD clients, so manual registration is required (includeclient_credentialsin the "supported grant types" of both the authorization server and the client, and set the client's token endpoint authentication method toclient_secret_basic/client_secret_post). When requesting a token, specify the scoped URL in theresourceparameter (RFC 8707). Refresh tokens are not issued, so it is not suitable for regular use by interactive clients (for interactive use, useauthorization_code)
Method 2: Privileged static token
A method for management tools from before OAuth was introduced.Authorization: Bearer <特権静的トークン> Connect with.
There are no scope restrictions and all privileges (equivalent tomcp:admin ) are granted, so handle with care.
Method 3: Admin session
Dedicated to calls from the UI within the admin panel (AI agent assistance, tool checker, etc.). Do not use from external clients.
IP address access restriction
The Admin MCP endpoint isnot subject to the admin panel's IP address restriction(to support cloud-type MCP clients whose source IP is not fixed). To restrict connection sources, enable a dedicated allowed IP list in **[Environment Settings]→[Admin Panel]'s "Admin MCP access restriction (IP address)"**.
- The determination isbefore authentication. From a non-allowed IP, regardless of whether the token is valid or not,
403(Access from this IP address is not allowed.is returned - Target: Admin MCP endpoint (including
?MODE=tools) and file upload (/direct/rcms_api/mcp_upload/). Applies to both Bearer and admin session routes, and also applies to the AI agent functions within the admin panel - Not targeted:
?MODE=protected_resource_metadata(RFC 9728 metadata distribution) client_credentialsToken acquisition via and calls with issued tokens are not subject to the "Admin Panel access restriction (IP address)" (only the Admin MCP dedicated list applies)
OAuth scopes (permission levels)
The permissions of the authorization server for Admin MCP are not individually selected scopes butsingle-level selection(4 levels).
Levels must be identified by scope string(because the Japanese labels in the admin panel contain similar words and are confusing).
whoami の permissions.connection.scope What returns is also this scope string:
| Scopes (from weakest) | Write upper limit |
|---|---|
mcp:tools.read |
No write allowed (all modules' select only) |
mcp:tools.write |
topics / csvtable / tag / comment only such as insert・update only.delete is not allowed in any module。rcms_api member group batch is not included |
mcp:tools.all |
All modules, all operations. However, there are exceptions below |
mcp:admin |
No upper limit |
mcp:tools.writecannot be selected alone,mcp:tools.readとare granted as a set(read affects all modules)auth.scopesalso contains values other than those in the table above. used to retrieve the tool listmcp:tools.listis also granted, sowhoamireturns, for example,["mcp:admin", "mcp:tools.list"]. This is not a permission level.To determine the effective permission level,auth.scopesrather thanpermissions.connection.scopelook atmcp:tools.allexception — Creation, modification, and deletion of groups (permissions) and general-purpose Smarty batches / granting superuser groups to members / issuing privileged static tokenscannot be done (because the upper limit cannot be safely carried over to delayed execution or privileged static tokens)mcp:adminはonly a superuser can approve. Other members are presented with the maximum level that can be approved on the consent screen, and it is issued at that level. If directly requested as a scope, with the message "mcp:tools.allrequestit is rejected
What can be confirmed by the label on the admin screen is mcp:tools.all = "All operations (within the scope of the delegated member's permissions)"。
A scope is a "ceiling" and not a grant of permissions. Effective permissions are the member's own permissions ∩ the scope's ceiling. For modules not included in the ceiling, all operations are denied. Conversely, even if the ceiling is broad, nothing can be done if the member does not have permissions.
Scopes required for construction work
The scopes required for site construction are determined bywhich module to write to:
| Task | Permission module | Required scope |
|---|---|---|
| Creation and updating of content definitions (TopicsGroup) | topics |
mcp:tools.write |
| Insertion and updating of content | topics |
mcp:tools.write |
| Creation of API definitions and endpoints | rcms_api |
mcp:tools.all |
| Issuance of static access tokens | rcms_api |
mcp:tools.all |
| Deletion of records in general | — | mcp:tools.all |
| Creation, modification, and deletion of member groups and general-purpose Smarty batches | group / batch |
mcp:admin |
| Granting superuser groups to members | member |
mcp:admin |
Issuance of privileged static tokens,kuroco_front-generate_deploy_token |
— | mcp:admin |
At the point of creating an API endpoint, mcp:tools.write is not enough(rcms_api が
mcp:tools.write because it is not included in the ceiling of , all operations are denied). Up to the creation of content definitions, you proceed with
mcp:tools.write , soit fails for the first time just before endpoint creation. Confirm this before starting.
If you perform a series of construction tasks end to end, mcp:tools.all, and if you include the tasks corresponding to the mcp:admin row in the table above, mcp:admin is required.
Resource-unit scopes also exist:
mcp:module.<mt>— a specific module (e.g.,mcp:module.member)、mcp:module.*for all modulesmcp:topics_group.<N>— a specific content definition,mcp:topics_group.*for all definitions
enforce-if-present method: The scope is enforced only when a scope is granted to the OAuth token . Tokens without a scope (legacy admin agent tokens, privileged static tokens) are not restricted. Be sure to tell the user that "not setting a scope = no restrictions".
Privileged meta-tool:
kuroco_front-generate_deploy_tokenはmcp:adminscope requiredrcms_api_token-createはrcms_api/updatepermission required (=mcp:tools.allor higher). Furthermore,token_type: "privileged_static"はstrictmcp:adminis requiredで、mcp:tools.allcannot be issued even with (because the issued token becomes a permanent credential with no upper limit on the connecting side).token_type: "static"does not have this additional restrictionrcms_api_token-deleteもrcms_api/updatepermission required. For OAuth connections,privileged_staticto revoke a tokenstrictmcp:adminis requiredbut a normalstatictoken can be revoked withmcp:tools.allcan be revoked with
Configuration location: permission level and resource scope are configured in the OAuth Authorization Server edit screen
(/management/external/memberregist_sso_oauth_idp_edit/). The configured values and Issuer URL can also be checked on the
Admin MCP information page.
Client connection
The authoritative source for connection procedures is kuroco-docs
The per-client support status (CIMD / manual client registration / header authentication) and configuration procedures are
../kuroco-docs/docs/reference-mcp-ai.md の mcp-client-configuration page is the authoritative source.
It includes the support table and procedures for Claude Code / Claude (Web, Desktop, Mobile) / ChatGPT (Developer mode) / Codex CLI /
Cursor / Slackbot / GitHub Copilot / custom implementations.
This skill does not duplicate the connection procedures. docs は /sync-docs Because it is regenerated from the official site at ,
duplicating it means that each resync updates only one side and they diverge. What is placed here is only
"how to assemble Admin MCP-specific URLs" and "behavior as an agent," which are not in the docs.
Admin MCP-specific: the URL is the scope and the resource identifier
Replace the URL portion of the docs procedure with the Admin MCP scoped URL.
https://<site_key>.g.kuroco.app/direct/rcms_api/admin_mcp/x/all
https://<site_key>.g.kuroco.app/direct/rcms_api/admin_mcp/x/topics_group_5
https://<site_key>.g.kuroco.app/direct/rcms_api/admin_mcp/x/topics_group_1,member/readonly
Common prerequisites:
- Because the OAuth authorization flow goes through Kuroco admin panel login and consent,the connecting user needs a management member account for the target site
- If the URL (scope) is changed, reauthorization is required(because the audience must exactly match the URL notation). If the URL cannot be edited in the client UI, delete the connector and add a new one
- If team use or permission separation is required, without changing the default
Admin MCP (default)we recommend creating a dedicated authorization server for each purpose - CLI の
mcp loginis run on the user's own local machine. The OAuth authorization code flow requires a real TTY and browser (callback listener), so it cannot be run from the agent's sandboxed shell (the same applies via!). On the same machine,~/.claude.jsonis shared, so after authentication completes, the agent side will also be connected. The tool list is loaded at session start, so for tools from a server authenticated mid-session, start a new session to use them
CLI example (the OAuth registration method itself follows the docs):
# Claude Code
claude mcp add --transport http kuroco https://<site_key>.g.kuroco.app/direct/rcms_api/admin_mcp/x/all
claude mcp login kuroco
# Codex CLI
codex mcp add kuroco --url https://<site_key>.g.kuroco.app/direct/rcms_api/admin_mcp/x/all
codex mcp login kuroco
Give each connection a distinguishable server name (kuroco-blog , etc.). For clients configured from the UI
(Claude Web, Desktop, Mobile, ChatGPT), enter the above URL in the MCP URL field.
When using a privileged static token (not via OAuth. It grants all permissions, so handle with care → Method 2: Privileged static token):
claude mcp add --transport http kuroco \
https://<site_key>.g.kuroco.app/direct/rcms_api/admin_mcp/x/all \
--header "Authorization: Bearer <特権静的トークン>"
Admin MCP header authentication is Authorization: Bearer. Content API MCP's
X-RCMS-API-ACCESS-TOKEN is different, so do not reuse the docs' header authentication procedure as-is.
Behavior when connecting
- Identify the client in use, then choose the procedure. Do not assume there is automatic detection that works for all clients. Judge from information provided by the system or the user's explanation, and confirm once only if it is absent and affects the choice of procedure
- Do not mix procedures for different clients. Do not ask CLI users to perform UI operations, or ask desktop users to run CLI commands without reason
- Manual client registration is a persistent configuration change in the admin UI. Obtain user approval before executing. Check whether CIMD is available in the docs' compatibility table, and do not fall back to manual registration for any reason other than "an error occurred"
- Kuroco does not implement RFC 7591 DCR. For clients that only support DCR (such as Cursor), manual client registration is the only path
- The agent must not finalize configuration changes that affect the entire site. If changes to the authorization server configuration or enabling CIMD are required, explain the need and have the user perform the operation themselves
- After connecting, start a new task and run
whoamirun and, and confirm the connection host, effective scope, read/write permissions, and site-specific limits before starting work (pre-check with whoami)。 For clients where recreating the session loses context, end the connection before requirements gathering or design (because agreements made in conversation are lost with each session). If a connection becomes necessary midway, write out the agreed content to a file before recreating the session - the minimum scope URLrequired for the work (scopes required for build work)
-
Decide based on the person's responsibility:
Person's responsibility Scope Build lead mcp:adminModification lead Also allow mcp:adminas neededMaintenance/operations lead Least privilege Other least privilege
-
Tool naming conventions and usage
tools/list The tool name returned by is dynamically generated. The controller name suffix and MODE
folded into the verb {resource}-{verb} format (1 controller action = 1 tool):
There is exactly one hyphen separating resource and verb. {resource} is derived from the controller name by
_api and the last word (_list / _edit / _upload) removed, andnot the module directory name
(topics_group_edit_api → topics_group). Underscores contained in the resource name are not
replaced with hyphens.
| Pattern | Example | Meaning |
|---|---|---|
{resource}-{verb} |
topics-list, topics-create, topics-update, topics-delete |
Controller operations (INSERT→create, etc.; separate tool per MODE) |
{resource}-{verb}(composite resource) |
topics_group-list, topics_group-create |
Sub-entity (group definitions, etc.).There is one hyphen, and underscores on the resource name side remain as-is |
| Bulk specification (not a separate tool) | topics-update / topics-delete の ids / filter / set / rows |
For multiple records, specify them in the arguments of the same update / delete tool.dry_run check the count with and expected_cnt guard with, and for over 200 records async: true |
{mt}-get |
topics-get |
Retrieve a single record by specifying its ID |
{service}-{method} |
email-send |
Service model |
| Meta tool | whoami, topics-describe |
Check effective permissions / check field definitions of topics |
| Staging | files-create_temp_upload_url |
File upload (presigned PUT to temporary storage. Also exposed in the topics bundle) |
Always check the exact tool name and input schema with tools/list (do not call by guessing the name).
topics_group_<N>Even when connected with the scope, the tool name remains the generictopics-{verb}. The allowed groups are constrained as the enum of each tool'stopics_group_idargument, and specifying a group outside the allowed set is rejected- Rejections originating from the scope are determined at runtime.
topics_group_idIf you specify an ID not listed in the enum of and it is rejected, use a read tool to determine whether it is due to insufficient scope or the ID not existing
Typical arguments(the exact specification is governed by each tool's inputSchema):
- list-type(
{mt}-list):filter(Kuroco DSL)・order_query(sort)・cnt/pageID(paging)・columns(column filtering). For topics,topics_keyword/vector_query(search) is additionally available. When retrieving a single record by ID, prioritize{mt}-getprioritize - update / delete (single-record type): ID(
topics_id, etc.) are required. topics-type tools, regardless of the verb,topics_group_idpass
Usage flow:
whoamiCheck effective permissions with(below). Especially before starting construction work and before destructive operationstools/listcheck available tools with (or REST's?MODE=toolsfor module list)- Check current state with read tools (parent-child relationships: for Topics,
topics_group_id, for Member,group_idis required. Resolve the parent ID first withtopics_group-listetc.)- list-type tools return all columns by default.
columnsnarrow to only the necessary columns with the argument
- list-type tools return all columns by default.
- Check the inputSchema of write tools before executing
-
Topics' extended fields (ext_col) are not listed in the inputSchema.
topics-describecheck the target group's field definitions with:// tool: topics-describe(topics_group_id は必須) { "topics_group_id": 5 } -
update-type tools perform partial updates: fields not sent are not changed and retain their existing values. If you want to change only some fields, send only the ID and the fields to change (no need to resend existing values). Large text columns can also be partially updated on a per-row basis (see "Partial update」)
-
- Confirm INSERT / UPDATE / DELETE with the user before executing
- Execute writes of multiple records one at a time, not in parallel. Each write involves server-side
search index rebuilding, cache invalidation, and trigger processing, and parallel writes are
subject to rate limiting (HTTP 429). For multiple records, combine them into a single call using the same update / delete tool's
ids/filter(+set) (dry_run→expected_cntin this order for safety) - Success responses may also include the
errorsarray. Always check
Notes on lightweight_mode: topics の create/update で
lightweight_mode: truePassing makes writes significantly lighter, but only the search index and vector embeddings are reflected in the follow-up batch.Triggers, external notifications (FCM/email), and tag aggregation are skipped and never executed. Since this changes the default behavior, use it only after confirming with the user.
Checklist when tools are not visible:
- Whether the target table is Modules with 0 records have read tools excluded(empty modules show only INSERT)
- Whether the module is included in the URL scope (
/x/<module>) readonlyWrite tools do not appear for URLs with- Whether it is restricted by OAuth scope (
mcp:module.*/mcp:topics_group.*) - For content operations, are you specifying
topicsinstead oftopics_group_<N>?
Partial update
Admin MCP's update-type tools support two-stage partial updates. Both are mechanisms for "not having to send the parts you don't change," reducing transmission volume and context consumption.
Field-level (all update-type tools)
Fields that are not sent retain their existing values. Send only the ID and the fields to change. There is no need to re-read the existing values and resend them.
Line-based (patch.<カラム>)
For columns that become long, such as CSS, JS, and Smarty templates,you can specify a line range and rewrite only part of it. Instead of sending the entire column, pass patch.<カラム名> to the same update tool.
patch. is the partial-updatereserved prefix. Even if supported columns increase, no dedicated tool is added;
the resource's -update simply gains one more argument, so the tool list does not grow.
Supported columns(tools/list 's inputSchema is the source of truth):
| Resource | Column |
|---|---|
custom_function(custom processing) |
contents |
topics_group(content definition) |
custom_css / custom_js / wysiwyg_custom_css / search_template_keyword / search_template_vector |
Procedure:
- Use the read tool (
custom_function-get/topics_group-get) to get the target column's<カラム名>_hash(SHA-256 of the stored content) - Pass that value to
base_hashand call update
// tool: topics_group-update
{
"topics_group_id": 5,
"patch.custom_css": {
"base_hash": "<topics_group-get が返した custom_css_hash>",
"start_line": 2, // 1始まり
"delete_line_count": 1, // 0 なら挿入(replacement は空にできない)
"replacement": "/* 差し替え */" // 空文字なら該当行を削除
}
}
base_hashis optimistic locking. If someone else has changed that column since it was read, it is rejected with "changed since it was read". Re-read and retry- The update response also includes the post-save
<カラム名>_hash. If you continue patching, use that value without re-reading - The column name itself and
patch.<カラム名>cannot be used together(specifying both is an error). If you send the column name, it becomes a full replacement as before - Line endings are normalized to match the original content (if the content has no line breaks,
replacement) - Multiple columns can be patched at the same time in one call (each requires
base_hash)
The hash is calculated from the stored content. There are columns whose values are normalized server-side when saved (e.g.,
search_template_*is replaced with the full default template when empty,custom_css/custom_jsis saved as empty when it matches the editor's placeholder),the value sent and the value saved may not match. Therefore,base_hashmust always use the read tool's<カラム名>_hash, and do not calculate the hash yourself.
Pre-check with whoami
whoami はAlways present on all scoped endpointsMeta tool (readonly also appears in the bundle).
It can be called with no arguments and returns the connection's effective context.
| Returned fields | Content |
|---|---|
member |
Connected member and affiliated groups |
auth.method / auth.scopes / auth.expires_at |
Authentication method, granted scopes, token expiration time |
permissions.granted / denied |
The account's own module permissions |
permissions.approval_required |
Writes areGoes to approval workflowModule (not directly reflected) |
permissions.connection.scope |
Effective for this connectionEffective scope(mcp:tools.write / mcp:tools.all / mcp:admin etc.) |
permissions.connection.available_scopes |
Scopes obtainable by reauthorizinglist (strongest first) |
permissions.connection.readonly / modules |
readonly bundle or endpoint module restriction |
request.client_ip |
Source IP (used to isolate IP restrictions) |
site |
Destination site identification information (Site mix-up detection)。topics_ext_key_format でKey naming for this site's extended fields、limits でContent structure limitscan be determined (see below) |
security.ip_restrictions |
IP restriction status (settings only for connections that can update site settings) |
What can actually be called is permissions.granted ∩ permissions.connection。 Do not judge by looking at only one side.
Key naming for extended fields (site.topics_ext_key_format)
The key names for topics extended fields areVaries in two ways depending on site settings。whoami returns a naming string that can be used as-is:
site.topics_ext_key_format |
Meaning |
|---|---|
ext_<n> |
Sequential number format (e.g., ext_1). Sites that store extended fields as JSONB |
ext_col_<nn> |
Zero-padded 2-digit format (e.g., ext_col_01). Legacy format sites |
- Do not guess key names. Naming is determined per site, so before reading/writing topics, check with
whoamicheck with - The return value is the naming itself, not a constant name, so
<n>/<nn>can be replaced with the item number and used as-is - The source of truth per group is
topics-describe。 The actual field definitions (which number is which item,ext_slugwhether is set) are checked here.topics_ext_key_formatis for knowing the site-wide naming convention first ext_slugItems for which is set are not affected by this branch because the slug becomes the key in the frontend API- On old sites,
topics_ext_key_formatmay not be returned. In that case, treattopics-describe's result as authoritative
Content structure limits (site.limits)
site.limits returns the four limits related to content structure in the form {current, max} return in the form of.current is the current setting value for this site,max is the upper limit that can be raised in the system. Do not guess either—always check here before design/creation.
| Key | Content | max |
|---|---|---|
topics_max_extension |
Number of extended fields per TopicsGroup | If the site stores extended fields in JSONB format,999, and if in legacy format,99 |
topics_ext_group_loop |
Number of repetitions of field groups (repeating items) | 99 |
topics_contents_type_cnt |
Number of categories per TopicsGroup (contents_type) |
99 |
member_max_extension |
Number of member extended fields | 999 |
currentがmaxIf less than,admin_setting-updatecan be brought up with the tool(tools/listexists before use. If it is not yet visible, it is an unsupported server, so guide the user through the procedure to bring it up in the admin screen). If you receive a consultation like "only up to 99 extended fields can be created," first look at thislimitsand determine whether it is legacy format (max=99) or JSONB format (max=999), or whether the current value has simply reached the upper limit.
Timing to call:
- At session start — confirm whether the connection destination site is the intended one and which member you are operating as
- Before starting construction work —
connection.scopeがmcp:tools.allormcp:admincheck. If you start with "read/write,"it succeeds up to content definition and fails for the first time at endpoint creation, so a partially created state remains. If insufficient, presentavailable_scopesand request reauthorization - Before designing the content structure —
site.limits(above), check the upper limits for extended fields, field groups, categories, and member extended fields./kuroco-content-structuredecides splitting/compression based on this value - Before destructive operations — reconfirm the target site and permissions
If scopes are insufficient,Do not call tools by guesswork to see if they fail.
available_scopesattach and ask the user to reauthorize at the necessary level.
File upload
Do not send binaries directly to MCP; use thestaging → pass-by-referencetwo-stage method:
-
files-create_temp_upload_urlWhen you call the tool,file_idand an S3 presigned PUTpresigned_url(andpresigned_short_url) are issued.file_size(number of bytes) andext(extension) declarations are required:// tool: files-create_temp_upload_url { "file_size": 1048576, "ext": "pdf" } -
PUT the file body (raw bytes) to the issued URL (if
presigned_short_urlreturns 307, resolveLocationwith GET and then PUT to that URL) -
topics-create/topics-updateas the value of the file/image type field offile_idand consume it. The value form is the string"files/temp/...", or with caption{"file_id": "files/temp/...", "desc": "キャプション"}
Upload to the file manager (file_manager-upload)
If placing in the file manager tree (files/user/・files/ltd//cloud storage) rather than topics items, use file_manager-upload .
// 16MB まで: data URI をそのまま渡す
{ "storage": "kurocofiles_public", "directory": "docs/2026", "file": "data:application/pdf;base64,...", "file_name": "report.pdf" }
// それ以上: files-create_temp_upload_url で PUT した file_id を渡す
{ "storage": "cloud_public", "directory": "videos", "file": "files/temp/kuroco/<site>/<uuid>.mp4", "file_name": "intro.mp4" }
file_namedetermines the saved name and extension. The extension must be one on the site's upload allowlist (executable types such as php are not allowed) and must match the content (disguises such as placing HTML/SVG/JS content with an image extension are rejected). Per-folder extension restrictions also applydirectoryはfile_manager-listreturned bypathWith the same relative path as , intermediate folders are created automatically (there is no folder creation tool)- Files with the same name are overwritten (the tool is treated as destructive).
allow_overwrite: falsecan be rejected with - Cloud storage (
cloud_public/cloud_private) addressed tofile_idis copied on the storage side and does not go through Kuroco's servers.files-create_temp_upload_urlにstorage: "S3"issued withfile_idhas no size limit - Local storage (
kurocofiles_*) addressed tofile_idは up to 80MB. If it exceeds that, place it in cloud storage - the value passed to in the response,
pathはfile_manager-list/file_manager-deletethe value passed to ,content_field_valueis the value written to an item of type "File (from File Manager)"
Order with the approval gate: obtain user approval before writing, then issue the URL, and perform "issue → PUT → consume" as a single continuous sequence (issuing while waiting for approval risks expiration).
Constraints:
- The expiration time of the presigned URL is 10 minutes. Complete "issue → upload → consume" within 10 minutes
- The size limit is
file_sizeis checked against the declared value and rechecked at consumption time (default 100MB) storage: "S3"Adding places it directly in the site's S3 bucket'sfiles/temp/(not possible for GCS sites)- Small files (up to 16MB) are also accepted as inline data URIs
Bulk download from File Manager (file_manager-list の download: true)
When extracting everything under a directory together,file_manager-list に download: true Add . Instead of a list,directory the temporary URL of a single zip of everything under (including subdirectories) is returned.
{ "storage": "kurocofiles_public", "directory": "docs/2026", "download": true }
// → { "directory": "files/user/docs/2026/", "download": { "download_url": "...", "filename": "2026.zip", "size": 12345, "entries": 8, "expiration_unix": ... } }
- The entry paths in the zip are relative paths from
directory. Items that do not appear in the list (hidden files/folders, folders not visible due to access restrictions) are not included in the zip either - The limit is the same as the zip extraction for uploads: 1000 files / 500MB after extraction. Trees that exceed this are rejected, so extract them split by subdirectory
download_urlThe expiration time of is 10 minutes. Retrieve it immediately after issuing- Access-restricted files (
kurocofiles_private/cloud_privateThe only route by which the contents can be read from MCP.file_manager-listreturnsurlrequires admin panel login, so use this one from the agent - For sites that have neither cloud storage nor a temporary bucket, a temporary URL cannot be issued, and
downloadis rejected
Admin panel: Admin MCP information page
/management/rcms_api/admin_mcp_info/ The Admin MCP configuration information is consolidated in:
- List of endpoint URLs (
x/all、x/all/readonly, examples of module specification) - List of OAuth authorization servers and Issuer URL
- List of connected clients (only client_id is displayed; secret is not shown)
- List of AI agents using Admin MCP (public modules / read-only settings)
- Tool checker (UI for checking available tools)
When guiding users to the Issuer URL or endpoints, have them refer to this page first.
Troubleshooting
| Symptom | Cause and remedy |
|---|---|
| 400 Bad Request | URL に /x/<スコープ> There is no ./x/all Add etc. |
401 + WWW-Authenticate |
Token invalid/expired.resource_metadata Re-authenticate from the URL. Note that when a Bearer is presented, it does not fall back to the session |
403 Access from this IP address is not allowed. |
IP address restriction for Admin MCP. Add the source IP to "Admin MCP access restriction (IP address)" in [Environment Settings] → [Admin Panel] |
| Can connect but tools are empty/few | Check the "Checklist when tools are not visible" above |
| Permission error only for endpoint creation | rcms_api は mcp:tools.write is outside the upper limit.whoami で connection.scope Check , andmcp:tools.all Re-authorize with or higher.whoami If has already returned mcp:tools.all / mcp:admin this row is not the cause — proceed to "Troubleshooting permission errors" below |
privileged_static Token cannot be issued |
Strict is required ( mcp:admin is needed (mcp:tools.all not possible with ). Re-authorization as a superuser is required |
| Write succeeds but is not reflected | whoami の permissions.approval_required Check whether the corresponding module exists in . It may be waiting for an approval workflow |
| Token rejected due to audience mismatch | Check whether the trailing slash and path notation of the endpoint URL exactly match those at token issuance |
rcms_api_token-create is a permission error |
rcms_api/update is required, so mcp:tools.all or higher.privileged_static further requires mcp:admin is required |
files/temp/... の file_id cannot be resolved |
Presigned URL expired (10 minutes), consumed before PUT, or issued on a different site file_id. Reissue the URL and start over from PUT |
| Authorization server does not appear on the information page | An authorization server deleted by an administrator is not automatically recreated. Recreate it manually |
| OAuth client registration does not go through | Check whether CIMD (Client ID Metadata Document) is enabled on the authorization server. Clients that do not support CIMD require manual client registration (Kuroco does not implement DCR). For per-client support, see ../kuroco-docs/docs/reference-mcp-ai.md の mcp-client-configuration See |
invalid_client / Client ID metadata documents are not enabled for this authorization server. |
CIMD is disabled on the authorization server (disabled by default). Enable it in the OAuth Authorization Server edit screen, then re-authorize on the client side |
| The client shows "Connected" but there are 0 tools | It may not have passed through Kuroco's consent screen.The client's connection status display does not necessarily mean authorization is complete(Some clients show "Connected" even before consent). Complete the consent screen through "Allow", and after a token is issued, re-fetch the tool list |
| Cannot connect from Codex | ① Whether CIMD is enabled on the authorization server ② Whether a scoped URL (/x/...) is specified ③ Whether ~/.codex/config.toml の [mcp_servers.<name>.oauth] に client_id remains (a configured client_id takes precedence and CIMD is not used). If not using CIMD, manual client registration is required (Kuroco does not implement DCR) |
Isolating permission errors
Do not determine the cause based solely on matching symptoms in the table above. Reports of "a write resulted in a permission error" can look the same even when the cause is something other than insufficient scope. Even if the user self-diagnoses with "I think it's insufficient scope,"First confirm the facts。
- Check the HTTP status.
401is authentication (invalid or expired token),403is authorization (scope, permissions, IP restrictions). If you mix these up, all subsequent isolation will be off whoamicall(do not call tools based on guesswork to reproduce a failure)- Branch based on the facts returned:
whoami result of |
Determination |
|---|---|
connection.scope が mcp:tools.write or less, and the target is rcms_api modules outside the limit, etc. |
Insufficient scope。available_scopes and request re-authorization |
permissions.denied The target module is present in |
The member's own insufficient permissions. Increasing the scope will not resolve it. Grant permissions in the admin screen |
permissions.approval_required The target module is present in |
Not a permission error butAwaiting approval workflow(the write succeeds but is not reflected) |
connection.readonly が true, or connection.modules there is no target module in |
Restriction on the endpoint URL side. Change the connection URL, not the scope (re-authorization required) |
security.ip_restrictions.admin_mcp.current_ip_allowed が false |
IP restriction(403, determined before authentication) |
auth.expires_at is before the failure time |
Token expired(401). Re-authenticate |
| None of the above apply, and both scope and permissions are sufficient | It is not a scope problem. Move on to candidates such as input value validation errors (URI duplication, naming convention violations, etc.), operations on a different connection/different site, etc. Check the full error message, the connection name used, and the failure time |
whoami Even if sufficient permissions have been demonstrated, you must not guide the user with "please reauthorize".
Presenting a remedy that contradicts the confirmed facts causes the user to spend time on work that will not resolve the issue.
Security notes
- Operation on a public endpoint (security = none) is not recommended. In particular, do not expose writes without authentication
- Privileged static tokens do not have effective scope restrictions (full permissions). Use OAuth + an appropriate permission level whenever possible
- For read purposes, use
x/all/readonlyor the "read-only" permission level to enforce least privilege - Do not output client_secret or token values to logs or conversations
- Admin MCP requests are recorded in the admin log, just like the Admin APIBilled per request
Coordination with other skills
| Skill | How to choose between them |
|---|---|
/kuroco-security-audit |
Inspect and diagnose security settings with the Admin MCP read-type tools (read-only) |
/kuroco-content-structure |
Design decisions for content definitions (TopicsGroup) and field definition reference when creating them with MCP tools |
/kuroco-api-content |
Design and authentication for the front-end API for end users |
/kuroco-docs |
Cross-search of official documentation |
Guidelines for choosing between them: For administrative operations from AI agents, Admin MCP (this skill) is recommended. It can be used via a standard MCP connection from any of Claude Desktop / claude.ai / ChatGPT / Claude Code.