SuperAPI AI Directory

kuroco-admin-api-browser

Office & productivity

View repository

Updated 10-15 18:32

About this skill

Kuroco admin_api Browser Skill

Overview

A skill for operating Kuroco's admin API (admin_api) via the claude-in-chrome MCP tool.

admin_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() with, the cookie is sent automatically, so token extraction is unnecessary.

Prerequisites:

  • claude-in-chrome MCP is available (if not configured, see Step 0 in "Operation Flow" below)
  • The user is logged in to the Kuroco admin screen (https://*.*.kuroco-mng.app)
  • If the target site is unknown, confirm the site key or admin screen URL with the user to identify it
  • All operations are executed with the permissions of the logged-in user

Minimal operation flow (read: 4-5 tool calls, write: 5-6 tool calls):

  1. javascript_tool: Authentication check (MODE=whoami)
  2. navigate + get_page_text: /llms.txt to identify the module/controller
  3. navigate + get_page_text: /direct/rcms_api/llms/?mt={module} to retrieve field names and parameter specifications
  4. (when writing) javascript_tool: Retrieve field types, required fields, and block editor structure with MODE=schema
  5. javascript_tool: Execute the API (mt/ct format)

Step 3 is mandatory. /llms.txt(Overview) only contains the module list, and does not include ext_col field names. To grasp field names, module details are required. Step 4 is mandatory for write operations. The schema is data.request.properties returns field definitions in JSON Schema format.topics_group_id By 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.

Decision before starting an operation: When receiving a request from the user 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 admin screen UI is right in front of you, do not reflexively start clicking. Data that can be retrieved via API should be retrieved via API. Use UI browser operations 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__* Depends on the tool set. Before starting operations, check whether 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 a direct Anthropic 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 → base URL from that tab's 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 → AskUserQuestion tools to 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 → construct https://{site_key}.{env}.kuroco-mng.app (confirm the env with the user, default is g)

Note: All operations are executed with the permissions of the user logged in to the browser. Models or methods that 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/admin_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_tool In top-level await cannot be used. Because it evaluates in the page context, when usingawait always write (async () => { ... })() Wrap with . At top level await , SyntaxError: await is only valid in async functions .

MODE=whoami is a lightweight endpoint that returns session information (member_id, name1, name2, group_ids, expiresAt). It allows you to obtain the logged-in user's permission information at the same time as verifying authentication.

Step 3: Understand site structure via llms.txt (required)

navigate + get_page_text to read llms.txt. A single request yields the following:

  • List of all modules and controllers
  • Site map of content definitions, APIs, forms, etc.
  • How to use admin_api and parameter specifications
  • Workflow examples
navigate → /llms.txt
get_page_text → サイト全体の構造を取得

Note:

  • Always check llms.txt before going through admin panel pages. Most structural information can be obtained here (discover mode is usually unnecessary)
  • llms.txt is provided by KurocoGenerates 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 via module details (required)

Once the module to operate on 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、パラメータ仕様を取得

Do not skip this step. The field names for ext_col_01–20 (e.g., ext_col_03 = to, ext_col_04 = cc) are only described 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 check the field structure. In particular, for content definitions that have a block editor or extended fields (ext_col), required field names and types can only be determined from the schema.

Important: The schema response is in JSON Schema format. data.request There is no field information directly under it.data.request.properties contains the field definitions, anddata.request.required contains 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/admin_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_id If you omit it, only generic fields are returned (ext_col is not included)
  • topics_group_id If you specify it, you can retrieve the field names for the block editor and extended items (ext_1, ext_14 etc.), types, and required flags
  • list-type controllers (topics_listetc.) return an empty schema, so specify a write controller (topics_edit)
  • Response x-kuroco-type lets you determine the field type (wysiwyg, json, checkbox, file etc.)

Step 5: API Execution

Once authentication confirmation and structure understanding are complete, execute the API according to theAPI execution patterns.

Step 6: Handling Authentication Failure / Session Expiration

If 401 or 403 is returned:

  1. Tell the user that login is required
  2. Login URL: {base_url}/management/login/login/(base_url is obtained from the tab URL)
  3. Wait until the user logs in
  4. Check authentication again after login

If 401/403 occurs during a multi-step operation:

  1. Stop the operation immediately
  2. Report to the user how far the operation succeeded
  3. Guide them through re-authentication
  4. After re-authentication, resume from the incomplete operation

Criteria for Choosing a Method (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 with javascript_tool の fetch() , sothe authentication cost is the same for UI navigation and API calls。

Purpose Method Reason
Retrieving, searching, and filtering data lists API(admin_api) Structured JSON, programmatically processable
Detailed confirmation of specific content API(admin_api) Can retrieve only necessary items by specifying columns
Understanding site structure and API specifications llms.txt Can grasp the whole picture in one go
File upload, preview, GUI-specific setting changes UI browser operations Only operations not possible via API

Anti-pattern

Common mistake Problem Recommended
Clicking UI elements on the admin screen to search and browse data Merely imitating human operations. Slow, and results are not structured in HTML. Does not lead to improvement or automation Retrieve JSON with admin_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 doesn't work,.map()to extract)
fetch() to get HTML → parse with DOMParser The Vue.js rendering part becomes empty Retrieve JSON with admin_api
document.querySelector('main').textContent to get the full text Risk of Cookie blocks Extract only the necessary data
Top-level await use SyntaxError becomes Always (async () => { ... })() wrapped with
Returning field values containing email addresses as-is [BLOCKED] becomes .includes() Return only the determination result with
Object.keys(data.request) to find the fields of the schema Since it is in JSON Schema format, type,properties,required is all that is returned data.request.properties to get the field list
When retrieving the schema, topics_group_id omit Only generic fields, and ext_col is not included &topics_group_id={id} specify to get fields specific to the content definition

API Execution Patterns

Parameter Format

In admin_api, mt(module) and ct(controller) format.

parameter Description Example
mt Module name (lowercase) topics, member, inquiry
ct Controller name topics_list, topics_edit, member_list

Note: model=Topics&method=list Do not use the format. HTML may be returned. Always mt/ct use the format.

GET Requests (List Retrieval/Search)

// javascript_tool — columns + cnt で必要最小限のレスポンスを取得
(async () => {
  const r = await fetch('/direct/rcms_api/admin_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 columns specify. On supported endpoints, server-side filtering is performed; even if unsupported, it is simply ignored, so there is no problem in always specifying it. If it does not work, on the client side .map() to extract.columnsis exclusive to execute mode (not applied to discover mode).

POST Requests (Create/Update/Delete)

// javascript_tool — MODE=INSERTで新規作成
(async () => {
  const r = await fetch('/direct/rcms_api/admin_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

rule Description
credentials For all requests, credentials: 'include' required
Parameter Format Always mt/ct use format (model/method format 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]})
Result count limit If the response is large, cnt limit with parameter
columns specification columns=col1,col2 minimize response columns with .Always specify on supported endpoints(countermeasure for javascript_tool output limits / response efficiency). Some endpoints do not support it, in which case extract on the client side
Confirmation of change 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 try multiple times; grasp the structure in one go:

(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 exploration

advise mode (AI-assisted, recommended)

If you explain what you want to do in natural language, the AI answers which APIs to call in which order. The response's endpoint, api_spec is auto-generated by the system (no hallucination).summary, description, body_example, note is generated by AI.

// javascript_tool — やりたいことからAPI手順を取得
(async () => {
  const r = await fetch('/direct/rcms_api/admin_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/admin_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 separately

Method Purpose
llms.txt overview(recommended) Grasp 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 operations

Used when API calls alone are insufficient (file uploads, previews, GUI setting changes, etc.).

Procedure

  1. mcp__claude-in-chrome__navigate Navigate to the admin panel page with
  2. mcp__claude-in-chrome__read_page Get the accessibility tree with
  3. mcp__claude-in-chrome__find / mcp__claude-in-chrome__form_input / mcp__claude-in-chrome__computer Operate forms with
  4. mcp__claude-in-chrome__get_page_text Get page content with

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}

The URL pattern is /management/{module}/{action}/. For the full URL list, refer to 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 parameter 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, refer to references/error-handling.md Refer to


Security notes

  • Do not display or log Cookie values — Prevent session information leakage
  • document.cookieExtracting tokens with — Not obtainable due to HttpOnly and 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 credentials 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_id Sensitive 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
Caution on pages with many URL parameters If sensitive parameter names are included in the URL itself, it is subject to blocking
// ✅ 安全 — admin_apiからcolumns指定+必要フィールドのみ抽出
(async () => {
  const r = await fetch('/direct/rcms_api/admin_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/admin_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 Blocking risk Use
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 + admin_api JSON Low (safe if only necessary fields are extracted) Data manipulation / API execution
javascript_tool + fetch() → raw text High Avoid
javascript_tool + full DOM retrieval Medium–High (depends on page content) Limit to extracting only specific elements

Cooperation with other skills

Skill Use 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 automated deployment Frontend implementation
/kuroco-docs Refer to Kuroco documentation Search official documentation

This skill specializes in executing admin_api via the browser and operating the admin screen. For operations on the frontend API (*.g.kuroco.app), use the related skills above.