Overview
A skill for operating Kuroco's management API (mng_api) via the claude-in-chrome MCP tool.
mng_api's 5 modes:
- whoami: Retrieve session information (GET) — returns member_id, name, group_ids, expiresAt
- discover: Explore available modules and controllers (GET)
- schema: Retrieve request/response schemas for controllers/services (GET)
- advise: When you describe what you want to do in natural language, the AI answers with the API to call and the procedure (POST)
- execute: Execute the API (GET/POST) —
columnsResponse columns can be selected via parameters
Authentication method: Browser session cookie (__Host-rcms_api_access_token, HttpOnly).javascript_toolIf you execute fetch() at , the Cookie is sent automatically, so token extraction is unnecessary.
Prerequisites:
- claude-in-chrome MCP is available (if not configured, guidance is provided in Step 0 of the "Operation Flow" below)
- The user is logged in to the Kuroco management screen (
https://*.*.kuroco-mng.app) - If the target site is unknown, identify it by asking the user for the site key or management screen URL
- All operations are executed with the permissions of the logged-in user
Minimum operation flow (read: 4-5 tool calls, write: 5-6 tool calls):
javascript_tool: Authentication check (MODE=whoami)navigate+get_page_text:/llms.txtto identify the module/controllernavigate+get_page_text:/direct/rcms_api/llms/?mt={module}to retrieve field names and parameter specifications- (when writing)
javascript_tool: Retrieve field types, required items, and block editor structure with MODE=schemajavascript_tool: API execution (mt/ct format)Step 3 is mandatory.
/llms.txt(overview) contains only the module list and does not include ext_col field names. Module details are required to grasp field names. Step 4 is mandatory for write operations. The schema isdata.request.propertiesreturns field definitions in JSON Schema format.topics_group_idBy specifying , the required fields of ext_col/block editor become clear. discover mode is normally unnecessary. The two stages of llms.txt (overview → details) provide sufficient information.
Operation Flow
All API operations must follow this flow.
Judgment before starting an operation: When the user makes a request such as "check ~", "search for ~", or "look at the data for ~", first determine whether it can be resolved by **data retrieval (API)**. Even if the management screen UI is right in front of you, do not reflexively start click operations. Data that can be retrieved via API should be retrieved via API. UI browser operations are used only for operations that are impossible via API (file uploads, previews, GUI-specific setting changes, etc.).
Step 0: Check claude-in-chrome MCP
This skill mcp__claude-in-chrome__* It depends on the toolset. Before starting operations, verify that these tools are available.
How to check: mcp__claude-in-chrome__tabs_context_mcp .
- If successful → Proceed to Step 1
- If the tool is not found / connection error → Guide the user through setup:
ブラウザ操作に必要な claude-in-chrome MCP が利用できません。
以下の手順でセットアップしてください。
【必要なもの】
1. Google Chrome または Microsoft Edge
2. Claude in Chrome 拡張機能(v1.0.36以上)
→ Chrome Web Store からインストール:
https://chromewebstore.google.com/detail/claude/fcoeoabgfenejglbffodgkkbkcdhcgfn
3. Claude Code v2.0.73 以上
【有効化の手順】
- Claude Code セッション内で `/chrome` を実行
- または `claude --chrome` で起動
セットアップ完了後、もう一度お試しください。
Note: Chrome integration requires an Anthropic direct plan (Pro, Max, Teams, Enterprise). It is not available via third-party providers (Amazon Bedrock, Google Cloud Vertex AI, etc.).
Step 1: Identify the target site
mcp__claude-in-chrome__tabs_context_mcpand look for a tab matching the URL pattern *.*.kuroco-mng.app .
- If one tab is found → from that tab's URL, the base URL (
https://{site_key}.{env}.kuroco-mng.app) and use it in subsequent operations - If multiple Kuroco tabs are found → Ask the user which site to operate on
- If no tab is found →
AskUserQuestionto check the site key or admin panel URL:
{
"questions": [{
"question": "操作対象のKuroco管理画面を特定できませんでした。サイトキーまたは管理画面URLを教えてください(例: demo / https://demo.g.kuroco-mng.app/management/ / https://demo.stg.kuroco-mng.app/management/)",
"header": "対象サイト",
"options": [
{ "label": "URLを入力する", "description": "管理画面のURL(https://***.*.kuroco-mng.app/management/)を入力" },
{ "label": "サイトキーを入力する", "description": "サイトキー(例: demo)を入力。環境はタブのURLまたはユーザーに確認" }
],
"multiSelect": false
}]
}
Identify the base URL from the user's answer, and open the admin panel withmcp__claude-in-chrome__tabs_create_mcp :
- If a URL is provided → Extract the host part from the URL (e.g.,
https://demo.g.kuroco-mng.app) - If a site key is provided →
https://{site_key}.{env}.kuroco-mng.app(confirm env with the user, default isg)
Note: All operations are performed with the permissions of the user logged in to the browser. Models or methods that the user does not have access to cannot be operated.
Step 2: Authentication check (lightweight request)
mcp__claude-in-chrome__javascript_toolto execute the following:
(async () => {
const r = await fetch('/direct/rcms_api/mng_api/?MODE=whoami', {credentials:'include'});
const d = await r.json();
return JSON.stringify({status: r.status, ok: r.ok, member_id: d.member_id, name: (d.name2 || '') + ' ' + (d.name1 || ''), group_ids: d.group_ids});
})()
Important:
javascript_toolIn top-levelawaitcannot be used. Since it is evaluated in the page context, when usingawait, always write(async () => { ... })()must be wrapped with . At top-levelawaitresults inSyntaxError: await is only valid in async functionsbecomes .
MODE=whoamiis a lightweight endpoint that returns session information (member_id, name1, name2, group_ids, expiresAt). Authentication check and the logged-in user's permission information can be obtained at the same time.
Step 3: Understand site structure via llms.txt (required)
navigate + get_page_text to read llms.txt. A single request provides the following:
- List of all modules and controllers
- Site map of content definitions, APIs, forms, etc.
- How to use mng_api and parameter specifications
- Workflow examples
navigate → /llms.txt
get_page_text → サイト全体の構造を取得
Note:
- Always check llms.txt before traversing admin panel pages. Most structural information can be obtained here (discover mode usually unnecessary)
- llms.txt is provided by KurocoIt is generated dynamically based on the logged-in user's permissions. APIs outside the user's permissions are not displayed
/llms.txt(overview) contains only the module list. ext_col field names are obtained in the next Step 3.5
Step 3.5: Understand field names in module details (required)
Once the target module for operations is identified,AlwaysRead the module details and understand the field names.
navigate → /direct/rcms_api/llms/?mt={module}
get_page_text → ext_colのフィールド名、Available Columns、パラメータ仕様を取得
This step must not be skipped. The field names ext_col_01〜20 (e.g., ext_col_03 = to, ext_col_04 = cc) are described only in the module details. Traversing the admin screen DOM or guessing the contents of API responses is inefficient and causes errors.
Step 4: Schema retrieval (required for write operations)
When performing write operations (INSERT/UPDATE), always retrieve the schema and confirm the field structure. Especially for content definitions with a block editor or extended fields (ext_col), required field names and types can only be understood from the schema.
Important: The schema response is in JSON Schema format.
data.requestThere is no field information directly under it.data.request.propertiescontains the field definitions, anddata.request.requiredcontains the required fields.
To retrieve fields specific to a content definition, specify topics_group_id :
// javascript_tool — topics_group_id指定でext_col含むフィールド一覧を取得
(async () => {
const r = await fetch('/direct/rcms_api/mng_api/?MODE=schema&mt=topics&ct=topics_edit&topics_group_id=99', {credentials:'include'});
const data = await r.json();
const props = data.request?.properties || {};
const required = Array.isArray(data.request?.required) ? data.request.required : Object.keys(data.request?.required || {});
const fields = {};
Object.entries(props).forEach(([k, v]) => {
fields[k] = {type: v.type, description: v.description, kurocoType: v['x-kuroco-type'], required: required.includes(k)};
});
return JSON.stringify(fields, null, 2);
})();
Note:
topics_group_idIf you omit it, only generic fields are returned (ext_col is not included)topics_group_idIf you specify it, you can retrieve the field names of the block editor and extended fields (ext_1,ext_14etc.), types, and required flags- list-type controllers (
topics_listetc.) return an empty schema, so specify a controller for writing (topics_edit)- Response
x-kuroco-typelets you know the field type (wysiwyg,json,checkbox,fileetc.)
Step 5: API execution
Once authentication verification and structure understanding are complete,API execution patternexecute the API according to
Step 6: Handling authentication failure / session expiration
If 401 or 403 is returned:
- Tell the user that login is required
- Login URL:
{base_url}/management/login/login/(base_url is obtained from the tab URL) - Wait until the user logs in
- Check authentication again after login
If 401/403 occurs during a multi-step operation:
- Stop the operation immediately
- Report to the user how far it succeeded
- Guide them to re-authenticate
- After re-authentication, resume from the incomplete operation
Criteria for choosing a means (most important)
Principle: If the purpose is data retrieval, search, or filtering, use the API rather than the UI.
Even if the admin screen is open in the browser, clicking UI elements to find information is a human operation method, not an AI agent's operation method. The browser session cookie is also automatically sent by javascript_tool の fetch() , soThe authentication cost is the same for UI navigation and API calls。
| Purpose | Means | Reason |
|---|---|---|
| Retrieval, search, and filtering of data lists | API(mng_api) | Structured JSON, programmatically processable |
| Checking details of specific content | API(mng_api) | Only necessary items can be retrieved by specifying columns |
| Understanding site structure and API specifications | llms.txt | The whole picture can be grasped in one go |
| File upload, preview, GUI-specific setting changes | UI browser operation | Only operations impossible via API |
Anti-patterns
| Common mistakes | Problem | Recommended |
|---|---|---|
| Clicking UI elements on the admin screen to search and view data | It merely mimics human operations. It is slow, and the results are not structured as HTML. It does not lead to improvement or automation | Retrieve JSON with mng_api's fetch(). Since the same session cookie can be used, there is no reason to go through the UI |
columnsGET request without specifying |
The response is huge and gets blocked | Alwayscolumns=必要カラムspecify (if it does not work,.map()extract with |
fetch() to fetch HTML → parse with DOMParser |
The Vue.js-rendered parts become empty | Retrieve JSON with mng_api |
document.querySelector('main').textContent to fetch the full text |
Cookie block risks | Extract only the necessary data |
Top-level await use |
SyntaxError becomes |
Always (async () => { ... })() wrapped with |
| Return field values containing email addresses as-is | [BLOCKED] becomes |
.includes() return only the determination result with |
Object.keys(data.request) to search for a schema field |
Since it is in JSON Schema format, type,properties,required is all that is returned |
data.request.properties to retrieve the field list with |
When retrieving the schema, topics_group_id omit |
Only generic fields are included and ext_col is not included | &topics_group_id={id} specify to retrieve fields specific to the content definition |
API execution patterns
Parameter format
In mng_api, mt(module) and ctUse the (controller) format.
| Parameters | Description | Example |
|---|---|---|
mt |
Module name (lowercase) | topics, member, inquiry |
ct |
Controller name | topics_list, topics_edit, member_list |
Note:
model=Topics&method=listDo not use the format. HTML may be returned. Alwaysmt/ctuse the format.
GET request (list retrieval/search)
// javascript_tool — columns + cnt で必要最小限のレスポンスを取得
(async () => {
const r = await fetch('/direct/rcms_api/mng_api/?mt=topics&ct=topics_list&topics_group_id[]=1&cnt=10&columns=topics_id,subject,ymd', {credentials:'include'});
const data = await r.json();
return JSON.stringify(data, null, 2);
// → columns対応エンドポイントではサーバー側フィルタ(各アイテム {topics_id, subject, ymd} のみ)
// → 非対応の場合は .map() でクライアント側抽出:
// data.topics_list?.map(t => ({id: t.topics_id, subject: t.subject}))
})()
columns principle: For GET requests, always
columnsspecify. On supported endpoints, server-side filtering is performed; even if unsupported, it is simply ignored, so there is no problem with always specifying it. If it does not work, on the client side.map()extract with.columnsis dedicated to execute mode (it does not apply to discover mode).
POST request (create/update/delete)
// javascript_tool — MODE=INSERTで新規作成
(async () => {
const r = await fetch('/direct/rcms_api/mng_api/?mt=topics&ct=topics_edit_api&MODE=INSERT', {
method: 'POST',
credentials: 'include',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
subject: 'タイトル',
contents: '本文',
topics_group_id: 1
})
});
const data = await r.json();
return JSON.stringify(data, null, 2);
})()
Important rules
| Rules | Description |
|---|---|
| credentials | Required for all requests: credentials: 'include' required |
| Parameter format | Always mt/ct Use the format (model/method the format is not allowed) |
| GET array parameters | [] suffix required (e.g., topics_group_id[]=1) |
| POST array parameters | Native JSON array (e.g., {"topics_group_id": [1]}) |
| Record count limit | If the response is large, cnt limit with the parameter |
| columns specification | columns=col1,col2 Minimize response columns with .Always specify on supported endpoints(countermeasure for javascript_tool output limits and response efficiency). Some endpoints do not support it; in that case, extract on the client side |
| Confirmation of modification operations | insert/update/deleteはConfirm with the user before executionDo it |
| Response truncation | javascript_toolBecause of output limits, extract only the necessary parts from large responses |
When the response structure is unknown
.map() Before doing Object.keys() check the structure with . Do not guess property names and retry multiple times; understand the structure in one try:
(async () => {
const r = await fetch(url, {credentials:'include'});
const data = await r.json();
const keys = Object.keys(data);
const firstArrayKey = keys.find(k => Array.isArray(data[k]));
const firstItem = firstArrayKey ? data[firstArrayKey][0] : null;
return JSON.stringify({
topLevelKeys: keys, firstArrayKey,
firstItemKeys: firstItem ? Object.keys(firstItem) : null
}, null, 2);
})();
For details, see references/error-handling.md For details, see
API discovery
advise mode (AI-assisted, recommended)
When you describe what you want to do in natural language, the AI answers which APIs to call in what order. Response endpoint, api_spec is automatically generated by the system (no hallucinations).summary, description, body_example, note is generated by AI.
// javascript_tool — やりたいことからAPI手順を取得
(async () => {
const r = await fetch('/direct/rcms_api/mng_api/?MODE=advise', {
method: 'POST',
credentials: 'include',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({request: '記事を新しく作成したい'})
});
const data = await r.json();
return JSON.stringify(data.advice?.steps?.map(s => ({
step: s.step, description: s.description, mt: s.mt, ct: s.ct,
http_method: s.http_method, mode: s.mode, endpoint: s.endpoint
})), null, 2);
})()
discover mode (structured JSON, usually unnecessary)
// javascript_tool — モジュール一覧取得(特定モジュールは &mt=topics を追加)
(async () => {
const r = await fetch('/direct/rcms_api/mng_api/?MODE=discover', {credentials:'include'});
const data = await r.json();
return JSON.stringify(data.modules.map(m => ({mt: m.mt, controllers: m.controllers.map(c => c.ct)})), null, 2);
})()
How to use them differently
| Method | Purpose |
|---|---|
| llms.txt overview(recommended) | Understand the API structure of the entire site (use first) |
| llms.txt details | Check the parameter specifications of a specific module |
| advise | AI suggests API procedures from what you want to do (useful when mt/ct are unknown) |
| discover | Programmatically enumerate modules/controllers (usually unnecessary) |
For details, see references/api-discovery.md For details, see
Admin panel browser operation
Use when API calls alone are insufficient (file uploads, previews, GUI setting changes, etc.).
Procedure
mcp__claude-in-chrome__navigateto navigate to the admin pagemcp__claude-in-chrome__read_pageto get the accessibility treemcp__claude-in-chrome__find/mcp__claude-in-chrome__form_input/mcp__claude-in-chrome__computerto operate formsmcp__claude-in-chrome__get_page_textto get page content
Main URLs
| Page | URL |
|---|---|
| Create new content | /management/topics/topics_edit/?topics_group_id={id} |
| Edit content | /management/topics/topics_edit/?topics_id={id} |
| Content list | /management/topics/topics_list/?topics_group_id={id} |
URL pattern is
/management/{module}/{action}/. For the full URL list, see references/admin-ui-patterns.md refer to
Error handling
| Code | Cause | Action |
|---|---|---|
| 401/403 | Session expired/insufficient permissions | Guide to login URL, retry after re-authentication |
| 400 | Invalid parameters | Check specifications in llms.txt details, fix parameters |
| 404 | Module/controller not found | Check existence with discover |
| 500 | Server error | Check request content, retry |
| Network Error | Tab is on a different domain | Check whether you are executing in a Kuroco domain tab |
For details, see references/error-handling.md refer to
Security notes
- Do not display or log Cookie values — Prevent leakage of session information
document.cookieExtracting tokens with is prohibited — Cannot be obtained with HttpOnly and is unnecessary- Always perform change operations after user confirmation — insert/update/delete are difficult to undo
- Saving API response files requires user consent — May contain personal information
- Do not include authentication information in javascript_tool output — Do not return header or Cookie contents
Safe usage of javascript_tool
Blocking mechanism
javascript_tool The return value of passes through the chrome extension's security filter. If the following are detected, it is replaced with [BLOCKED] :
- Session Cookie values,
email/login_idSensitive query parameters such as - Field values containing email addresses (also applies when stored in ext_col)
- Large amounts of text containing personal information
Bypass rules and recommended patterns
| Rule | Reason |
|---|---|
| Limit return values to the minimum necessary | Extract only necessary fields, such as IDs, counts, and names only |
| Do not return the raw fetch() response as is | Cookie-related data may be mixed in |
| Do not return the textContent of the entire DOM | Sensitive information may be contained in hidden inputs or URL strings |
| Be careful on pages with many URL parameters | Blocked if the URL itself contains sensitive parameter names |
// ✅ 安全 — mng_apiからcolumns指定+必要フィールドのみ抽出
(async () => {
const r = await fetch('/direct/rcms_api/mng_api/?mt=topics&ct=topics_group_list&columns=topics_group_id,group_nm', {credentials:'include'});
const data = await r.json();
return JSON.stringify(data.topics_group_list?.map(g => ({id: g.topics_group_id, name: g.group_nm})));
})();
// ✅ 安全 — メールアドレスは値を返さず判定結果だけ返す
(async () => {
const target = 'user@example.com';
const r = await fetch('/direct/rcms_api/mng_api/?mt=topics&ct=topics_list&topics_group_id[]=1&cnt=30&columns=topics_id,subject,ext_col_03&keyword=' + encodeURIComponent(target), {credentials:'include'});
const data = await r.json();
return JSON.stringify(data.topics_list?.filter(t => {
return (t.ext_col_03 || []).some(v => v && v.includes(target));
}).map(t => ({id: t.topics_id, subject: t.subject})));
})();
Safety level by tool
| Tool | Block risk | Use case |
|---|---|---|
get_page_text |
Low (the extension returns filtered text) | Reading the full page text |
read_page |
Low (accessibility tree, does not include cookies) | Understanding the DOM structure |
javascript_tool + mng_api JSON |
Low (safe if only the necessary fields are extracted) | Data manipulation/API execution |
javascript_tool + fetch() → raw text |
High | Avoid |
javascript_tool + retrieving the full DOM |
Medium–High (depends on the page content) | Limit to extracting only specific elements |
Coordination with other skills
| Skill | Use case | How to use them differently |
|---|---|---|
/kuroco-api-content |
Frontend API design/authentication patterns, content CRUD patterns | End-user-facing API |
/kuroco-frontend-integration |
Nuxt.js/Next.js integration, AI automatic deployment | Frontend implementation |
/kuroco-docs |
Referencing Kuroco documentation | Official documentation search |
This skill specializes in executing mng_api via the browser and operating the admin panel. For operations on the frontend API (*.g.kuroco.app), use the related skills above.