Design the content definition (TopicsGroup) in Part 1, and create it in Part 2 using Admin MCP. Adding fields or changing types after creation is costly because it involves modifying already-inserted data, soagree with the user on the Part 1 deliverable (design deliverable template) before proceeding to Part 2. Do not skip the design and start building based only on syntax (/kuroco-app-builder this design is also done after the Phase 1 screens are finalized for the same reason).
If the request is only "I want to create a definition that is already decided," you may start from Part 2, but if TopicsGroup splitting, the master representation method, orext_slug are undecided, finalize them first in Part 1. Conversely,if the request is only for design consultation, present the deliverables in §6 and finish(do not proceed to Part 2).
Table of Contents
- Part 1: Design Decisions
- TopicsGroup Splitting
- Compressing the Number of Fields with JSON Items
- Master Data Representation Method
- How to Hold Classifications (Categories/Tags/Relations)
- ext_slug Naming Policy
- Design Deliverable Template
- Design Anti-Patterns
- Part 2: Creation with Admin MCP
- Finding the MCP Tool
- Basic Structure
- Content Definition Parameters — body field, publish scope, viewing/editing limits
- Verifying the result — mandatory read-back after every write
- Common Field Properties
- Field Type Reference — per-type properties and full examples: references/field-types.md
- Field Groups (Repeatable)
- Important Notes
Part 1: Design Decisions
1. TopicsGroup Splitting
Check the upper limit on the number of extended items withwhoamiのsite.limits.topics_max_extension({current, max}).maxis 999 when the site holds extended items in JSONB format, and 99 for the legacy format——do not guess。currentがmaxIf it is less thanadmin_setting-updateit can be raised with the tool (details: /kuroco-admin-mcp). If you are approaching the upper limit, or trying to cram data of different natures into a single definition, check whether there is room to raise it while also considering splitting.
| State | Decision |
|---|---|
| The number of fields is near the upper limit, or is expected to keep increasing | Split |
| Content of different natures (different listing methods, publication settings, viewing/editing restrictions) | Split (e.g., articles and announcements) |
| Attribute differences within data of the same nature (e.g., the "feature" classification within articles) | Do not split. Express it with categories and extended item options |
If the main cause of approaching the upper limit is "an accumulation of simple ancillary items not used for search, listing, or external integration," consider compressing with JSON items as described in the next section before splitting.
2. Compressing the Number of Fields with JSON Items
Simple ancillary information that is not used for search, listing, or external integration (filtering, sorting, integration keys)should not be divided into individual extended items butjsonConsider consolidating them into a single field of type (ext_type 28). A mass of configuration values and metadata that tends to keep growing can be handled this way without consuming the upper limit on the number of extended items (see 1.).
Criteria: For each item, if there is a YES to any of "should it appear in the list," "should it be used for search/filtering," or "will it be a key for integration with other systems," make it a separate extended item. If all are No, it may be stored together with other simple incidental items in a JSON item.
Example: Configuration values such as "display settings (background color, layout mode, internal notes)" that are neither search targets nor list display targets should be consolidated into a single JSON item. Items used for filtering, sorting, or list display, such as "category," "price," and "publication date," should remain as separate extended items.
Constraints (stated explicitly as points not confirmed in primary sources): Standardfilter/orderNo documentation has been found stating that the internal keys of a JSON item can be directly filtered or sorted in a query. The filtering operations provided for individual extended items (contains/=/</>, etc.) assume values of a fixed type, and there is no documentation covering free-form internal structures such as the JSON type.If a requirement arises to filter by the internal keys of a JSON item contrary to these criteria, do not proceed by guesswork; actually test and confirm it with Admin MCP.
3. How to represent master data: CSV table vs. relation (separate TopicsGroup)
There are two ways to have "masters (common data referenced repeatedly)" in Kuroco.The type of the field on the calling side directly determines the shape of the API response.
CSV table + csvtable/csvtable_checkbox |
Separate TopicsGroup + relation |
|
|---|---|---|
| Entity of the master | CSV table (a separate resource outside the TopicsGroup) | A normal TopicsGroup (content) |
| API response on the calling side | The master's values are not included (only the key). The contents must be combined by yourself by callingMaster::listseparately |
id + label (e.g., subject) are returned inline("ext_col_11": { "topics_id": 123, "subject": "タイトル" }) |
| Whether the master side can have extended items, categories, and publication control | Cannot (only CSV rows and columns) | Can (because it is ordinary content) |
| Want to filter by the master's own attributes (e.g., "only brands in a specific category") | Not possible | Possible (:R()search. There are constraints described below) |
| Cases it suits | Static and extremely simplestatic and very simplekey/value mappings, such as lists of prefectures or industries | When the master itself is edited in the admin panel, has attributes, or is used for filtering |
Principle: The field on the side that calls the master should be ofrelationtype. A CSV table is used as a lightweight alternative when it is a "truly simple fixed list." Whichever you choose, creation follows thecreation tool compatibility tablein Part 2 (the CSV table itself is created separately with csvtable-create ).
However,relationis not a "full join." By default, what is returned isonly id + label(module_idand one label). If you want to include all fields of the related content in the response,add custom processing to the endpoint's post-processingis necessary (api_methodretrieve the model withappendand replace withmodule_typeがtopics/member/inquiry. The implementation changes depending on which of these). For implementation, see/kuroco-server-processing; for details, see/kuroco-api-content. If you do not write this extra step into the deliverables at the design stage, it will lead to rework such as "relationeven though it was set to relation, the contents of the master cannot be retrieved."
Notes for multilingual sites: :R()Filtering related items bycan only be executed for the primary language. Even if multilingual settings are enabled, the linked content is based on the primary language. If you design filtered search using a multilingual master, clearly state this constraint in the deliverables.
4. How to hold classifications: categories / tags / relations
There is no official Kuroco guideline on "which one should be used." The following are design decisions derived from the actual behavior of each mechanism (
/kuroco-api-content) and are not primary Kuroco information.
| Mechanism | Entity | Multiple selection | Suitable cases |
|---|---|---|---|
| Category | A single hierarchical ID (the API field name iscontents_type). Options are managed by the administrator with topics_category-* managed with |
By default, one content has one category. In the definition's contents_type_cnt , 0 = categories disabled / N>1 = multiple slots |
Exclusive classification (e.g., article type) |
| Tag | String array. Options are registered with tag-* . If set to tag_allow_private_flg=1 in the definition, non-administrator contributors can also register their own tags |
Yes | Cross-cutting labeling (e.g., keywords) |
| Relation | Reference to other content | Depends on the type | When the classification target itself has attributes, or when you want to edit the classification target in the admin screen (effectively the same decision as "master" in 3.) |
Categories are topics_category-create, tags are tag-create and are registered after creating TopicsGroup (creation tool compatibility table in Part 2).Upper limit on the number of categoriesはwhoamiのsite.limits.topics_contents_type_cnt({current, max}、maxis 99). If there are multiple classification axes you want to classify finely, or if the options are expected to keep increasing, lean toward tags or relations rather than categories.
5. ext_slug naming policy
For all extension fieldsext_slugset. If not set, the key name isext_1format andext_col_01format is split per site (whoamiのsite.topics_ext_key_format, determined by), and the frontend mapper changes per site (details: /kuroco-app-builder の references/mock-contract.md). At design time, decide the slug name (make it match the field name for the app) and state it explicitly in the deliverable. Put the title in the standard item subject instead of making it an extension field (subject is also a reserved word and is returned as the relation label). For reserved words, check references/field-types.md › Reserved slug names (description / title / price is allowed,subject / tags / keyword is not).
6. Design deliverable template
Before proceeding to Part 2, summarize in this format for each TopicsGroup and get the user's agreement:
## コンテンツ定義: 記事
- 本文の持ち方: content_input_type 2(本文は WYSIWYG 拡張項目 `body` として持つ)
- 閲覧制限(secure_level): なし(公開) / 編集制限(writer_groups): 編集部
- 承認(need_application_groups): なし / 自分の投稿のみ(my_topics_only_limit_groups): なし
(グループは名前で書き、ID は Part 2 で `group-list` から解決する)
- 多言語: 有効/無効(有効なら relation の `:R()` 絞り込みは主言語基準、CSVテーブルの表示名は言語別の列で持つ)
- タイトル: 標準項目 `subject`(拡張項目にしない)
| フィールド名(ext_slug) | 型 | 必須 | 備考 |
|---|---|---|---|
| body | wysiwyg | ✓ | 本文 |
| lead_text | text | - | |
| main_image | image | ✓ | |
| author | relation (module: member) | ✓ | 全データ取得が必要ならエンドポイント後処理を追加 |
| brand | relation (module: topics, group_id: X) | - | マスタ=別TopicsGroup |
| prefecture | csvtable (csv_master_id: Y) | - | 静的固定リストのため |
| display_settings | json | - | 背景色・レイアウトモード等、検索/一覧/連携に使わない付随設定をまとめて格納 |
| gallery(グループ, group_repetitions 5) | image + text(caption) | - | 繰り返しフィールドグループ。子フィールドは repetitions 1 |
## コンテンツ定義: ブランド(マスタ)
(別 TopicsGroup にしたマスタは、それ自体にも上と同じ定義ブロックを1つ書く。既定: 編集制限は呼び出し側と揃える/閲覧制限は呼び出し側と同じ/承認・自分の投稿のみは「なし」)
## Part 2 前にユーザーへ確認する未決事項
- 例: 給与の単位(月給/年収)、必須にする項目、画像の上限サイズ、承認者(approvalflow)の有無 — 要件文に無い属性は既定で埋めず、ここに列挙して合意を取る
## マスタ一覧
| マスタ名 | 表現方法 | 作成手段 | 理由 |
|---|---|---|---|
| ブランド | 別TopicsGroup + relation | `topics_group-create`(呼び出し側より先に作り、返る id を relation の group_id に渡す) | 属性(ロゴ画像・説明文)を持つため |
| 都道府県 | CSVテーブル | `csvtable-create`(既存なら `csvtable-list` で id) → `csv_master_id` | 固定・属性不要のため |
Design anti-patterns
| What you must not do | Reason |
|---|---|
| You just want to have a master, but you make it a huge fixed list of choices (select) | Every time you add or change a choice, you have to edit the content structure itself. Make it a CSV table or a relation |
relationAssume that if you set |
the default is only id + label. If you need all the data, endpoint post-processing is required |
| Forcibly fit data of different natures into one TopicsGroup | You quickly reach the upper limit on the number of extension fields, and you can no longer finely separate publish settings and viewing/editing limits |
ext_slugDesign the API with numeric keys without setting |
The key format differs by site (ext_1/ext_col_01), and the frontend implementation becomes site-dependent |
| Lump even items used for search, listing, and filtering into a JSON item | Filtering and sorting by JSON internal keys is not confirmed to be supported by standard features. Expose them as individual extension fields |
| Dutifully make even simple accompanying information into individual extension fields and approach the upper limit | If it will not be used for listing, search, or integration, combine it into one JSON item so it does not strain the upper limit |
Part 2: Creating with Admin MCP
The procedure and syntax for creating the design finalized in Part 1 with Admin MCP's topics_group-create Terminology mapping: extension field = extension field (hereafter field), content structure = content structure / TopicsGroup, viewing/editing limits = viewing / editing limit (secure_level / writer_groups. Definition-level settings are collectively called container parameters ).
Creation tools for the elements selected in Part 1
| What was selected in the design | Creation tool |
|---|---|
| TopicsGroup itself and extension fields | topics_group-create. Adding to an existing definition is topics_group-update(→ Adding fields to an existing definition) |
| CSV table (master) | csvtable-create(if it already exists, get the ID with csvtable-list ). Pass that ID to the CSV table type field |
| Category | topics_group-create automatically creates the first category with the same name as the group, and returns its ID in topics_category_id . Renaming and adding are done with topics_category-update / topics_category-create |
| tags | tag-create(tag classification is resolved with tag_category-create) |
| view/edit/approve group IDs | group-list .Do not guess |
Source of Truth: Build each field with the property vocabulary documented in this skill (options, required, and the per-type properties in references/field-types.md) — these are what the write handler consumes. Use the tool's live inputSchema for the top-level parameters (see Content Definition Parameters); that object sets additionalProperties: false, so an undeclared top-level key is rejected.
Verify by read-back after every write (see Verifying the result). A successful response means the call was accepted, not that every field landed as intended — check before reporting success to the user.
Finding the MCP Tool
Content Structures are managed through the Kuroco Admin MCP server (/direct/rcms_api/admin_mcp/). Group-definition CRUD requires the topics_group scope in the connection URL (e.g., /x/topics_group or /x/all). See /kuroco-admin-mcp for connection setup, OAuth authentication, and scopes.
How to find the correct tool:
- Verify the connection with the
whoamitool (present on every scoped endpoint, includingreadonlyones), then runtools/list.- Group definitions live under the
topicspermission module, somcp:tools.writeis enough to create them. - But that level cannot create API endpoints (
rcms_apiis outside its ceiling). If the user's goal includes exposing this content through an API, tell them up front that the endpoint step needsmcp:tools.allor higher — otherwise they get a content definition they cannot serve. See/kuroco-admin-mcp. - Check
permissions.approval_requiredtoo: iftopicsis listed, writes enter the approval workflow instead of taking effect directly.
- Group definitions live under the
- Look for the group-definition tools — with the standard naming convention this is
topics_group-create(list/update/delete follow the sametopics_group-{verb}pattern). Tool names are generated dynamically, so always confirm the exact name andinputSchemaviatools/list— never guess. - If no matching tool appears, check the connection scope (
topics_groupmissing, or areadonlyURL hides write tools — see the/kuroco-admin-mcpchecklist), or ask the user which MCP server they have configured. - Build your JSON against the tool's
inputSchemaand call the tool. Creating a content structure is a write operation — confirm with the user before executing.
Recommended workflow
- Check the tool's live
inputSchema(tools/list) for the top-level parameters — that object rejects undeclared keys, so this is where the schema is authoritative. - Take the Part 1 §6 artifact as input and carry its definition-level settings into the container parameters; elicit only what the artifact lacks: body field (
content_input_type) and access rules (non_public_flg/secure_level/writer_groups). See Content Definition Parameters. Resolve any group IDs withgroup-list— never guess them. - Build the
fieldsarray using the property vocabulary of this skill (options,required, and the per-type properties inreferences/field-types.md) — not the rawext_option/ext_limit_itemcolumns, which are silently ignored on write. - Show the final JSON and confirm once — the design was agreed in Part 1, so this confirmation covers only the payload — then send it to the tool.
- Read the record back with
topics_group-getand verify the stored values. See Verifying the result.
Basic Structure
Top-level JSON structure:
{
"name": "Content structure name (required)",
"description": "Description of the content structure (optional)",
"fields": [
// Array of field definitions or field groups (at least one required)
]
}
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Name of the content structure |
description |
string | No | Description of the content structure |
fields |
array | Yes | Array of field definitions or field groups (minimum 1) |
Content Definition Parameters
name / description / fields are not the whole contract. The parameters below live at the top level of the same JSON and control the body field and the access rules for every record in this definition. They cannot be expressed as fields, and omitting them silently accepts defaults that are often wrong for the request.
| Parameter | Type | Description |
|---|---|---|
content_input_type |
number | 0=WYSIWYG body, 1=Textarea body, 2=Custom. 2 is the recommended value and is the default on API/MCP INSERT — leave it as is. 2 means the built-in contents field is not used and every item is built as an extension field in fields. When the content needs a main body, declare a WYSIWYG field (ext_type: 6) for it instead of switching to 0/1 |
open_flg |
number | 0=unpublished/disabled, 1=published/enabled (default 1). The UI label depends on non_public_flg |
non_public_flg |
number | 0=publish-oriented (default), 1=internal use only. secure_level is required when this is 1 |
secure_level |
integer[] | Viewing limit: group IDs allowed to view records. An empty array means publicly viewable |
writer_groups |
integer[] | Editing limit: group IDs allowed to insert/update/delete records. How administrator groups and multiple limits combine is defined in /kuroco-api-content (priority order of view/edit restrictions) — check it before promising "only group X can edit" |
need_application_groups |
integer[] | Group IDs whose updates require approval (data_waiting) before going live |
my_topics_only_limit_groups |
integer[] | Group IDs restricted to records they authored themselves |
can_save_draft_groups |
integer[] | Group IDs allowed to save drafts instead of publishing immediately |
Reading back the unset state: when you omit
secure_level/writer_groups/need_application_groups/my_topics_only_limit_groups/can_save_draft_groups, they are stored as the string"0", not as an empty string or empty array."0"means "no restriction configured" — do not read it as "group 0 is allowed".
Mapping natural-language requests to these parameters — a request phrased in terms of visibility is a request for these parameters, not for a field:
| The user says | Set |
|---|---|
| "do not expose externally", "internal use only", "internal only" | non_public_flg: 1 + secure_level: [<group ids>] |
| "only the person in charge can see it", "members only" | secure_level: [<group ids>] |
| "only the editorial department can edit" | writer_groups: [<group ids>] |
| "approval required before publishing" | need_application_groups: [<group ids>] — usually the same groups as writer_groups (the people who can edit are the ones whose updates need approval). This only marks whose updates wait; who approves is configured separately with the approvalflow-* tools (outside this skill) — say so, or approvals go nowhere |
| "show/edit only records I created" | my_topics_only_limit_groups: [<group ids>](definition level). For relation fields, self_only is different, andselectable candidates for the related targetis the property that narrows to one's own creations |
| "article body is needed", "blog / news article" | Keep content_input_type: 2 and declare a WYSIWYG field (ext_type: 6) in fields |
Do not switch to content_input_type: 0/1 just because the content has a body. 2 (Custom) is the recommended shape: every piece of content is an explicit, named field. The Practical Examples in references/field-types.md follow this pattern — Example 1 declares its own Article Body WYSIWYG field while leaving content_input_type at its default.
Never guess group IDs. Resolve them with group-list first — group names and IDs differ per site (e.g. a site may have Administrator=1, Editor=2, User=104 with no contiguous numbering).
Verifying the result
A successful topics_group-create response does not prove your fields were stored as intended: the ignored properties above fail silently. After every create/update, read the record back and check the stored values.
// tool: topics_group-get
{ "topics_group_id": <returned id> }
Check formData in the response — it exposes the per-field stored state with a numeric suffix per field:
| What you intended | Field to check | Expected when it worked |
|---|---|---|
select / checkbox choices |
options_<n> |
{"news":"お知らせ",...} — the key→label map. (ext_option_<n> holds the same data serialized as "key::val" lines, "key::default::val" when an option carries "default": true) |
required: true |
ext_limit_item_<n> / limits_<n> |
"required=1" / {"required":"1"} |
| Field type | ext_type_<n> |
The ext_type you sent |
| Repeatable group | ext_group_loop_<n>, ext_group_parent_ext_col_<n> |
Repetition count on every member field; children point at the group's first field (e.g. "ext_3") |
| Access rules | non_public_flg, secure_level, writer_groups, need_application_groups, my_topics_only_limit_groups, can_save_draft_groups |
1 for the flag; group lists as comma-separated strings ("1,2"), unset ones as "0" |
Per-type properties (file_type, true_label, csv_master_id, …) |
not individually documented here | Diff the whole formData against the before-snapshot (or the intended payload) instead of guessing key names; topics-describe confirms the API-facing result |
topics-describe is the complementary check: it reports the resulting API-facing shape of each field (e.g. a 5-repetition group appears as "type": "array", "maxItems": 5).
Report any discrepancy to the user rather than assuming the write took effect.
Common Field Properties
Properties shared by all field types:
| Property | Type | Required | Description |
|---|---|---|---|
ext_title |
string | Yes | Display name of the field |
ext_type |
number | Yes | Field type identifier (see reference table below) |
type |
string | No | Field type name (see reference table below). Not required — creation succeeds without it, since ext_type carries the type. Kept in the examples below because it is harmless and self-documenting |
ext_slug |
string | No | Slug for API access. Set this on every field. With a slug, the front API returns the field under that name (main_image). Without one, the key is positional, and its form differs per site: either ext_1 (plain counter) or ext_col_01 (zero-padded). whoami reports which one this site uses in site.topics_ext_key_format, and topics-describe is authoritative for a specific group. Positional keys also break when fields are reordered, so a slug removes both problems |
ext_help_msg |
string | No | Help text displayed to editors (admin UI only) |
description |
string | No | Field description used in the generated API schema (OpenAPI / MCP tool schema) |
repetitions |
number | No | Number of repetitions allowed |
required |
boolean | No | Whether the field is required |
searchable |
boolean | No | Expose the field in the management-screen search form (ext_limit_item.searchable=1). Unrelated to front API filtering |
template |
string | No | Custom template HTML |
Field Type Reference
Reconciled against
topics_group-describeon 2026-08-27.topics_group-describeis the live primary source for which types exist and which per-type parameters they accept — call it when in doubt.
| ext_type | type | Description |
|---|---|---|
| 0 | text |
Single-line text input |
| 1 | textarea |
Multi-line text area |
| 2 | select |
Select box (single choice) |
| 4 | image |
Image upload |
| 5 | checkbox |
Checkbox (multiple choice) |
| 6 | wysiwyg |
WYSIWYG rich text editor — when you want editors to write without being conscious of HTML. The editor reconstructs the HTML |
| 7 | link |
URL link input |
| 8 | date |
Date/datetime picker |
| 9 | file |
File upload |
| 10 | table |
Table input |
| 11 | location |
Geolocation (map) |
| 13 | textauto |
Autocomplete text |
| 20 | relation |
Relation (reference to other records) |
| 21 | html |
HTML code input — when you want to write HTML as-is and do not want it formatted. No reconstruction occurs (sanitization works the same as in 6) |
| 27 | s3file |
Amazon S3 file upload — not listed by topics_group-describe; MCP creation unverified |
| 28 | json |
JSON data input |
| 29 | csvtable |
CSV table |
| 30 | filemanager |
File manager |
| 31 | vimeo |
Vimeo video upload — not listed by topics_group-describe; MCP creation unverified |
| 32 | api |
External API integration |
| 33 | gcsfile |
Google Cloud Storage file upload — not listed by topics_group-describe; MCP creation unverified |
| 34 | counter |
Auto-increment counter — since increments do not go through the update history, it suits values that are counted frequently |
| 35 | number |
Numeric input |
| 36 | bool |
Boolean (ON/OFF toggle) |
| 37 | csvtable_checkbox |
CSV table checkbox |
| 38 | block_editor |
Block-based content editor — only as the first field of a field group. It cannot be made searchable, but it suits bodies whose structure varies from record to record |
Per-type properties (placeholder, options, module, csv_master_id, …), the repeatable-group example, and three complete payloads (news / product catalog / events) are in references/field-types.md — read the section for each type you are about to use before building the fields array.
Field Groups (Repeatable)
Field groups allow you to bundle multiple fields into a repeatable section.
Group Structure
{
"group_nm": "Group Name (required)",
"group_slug": "group-slug",
"group_repetitions": 5,
"fields": [
// Fields inside the group (each field must have repetitions: 1)
]
}
| Parameter | Type | Required | Description |
|---|---|---|---|
group_nm |
string | Yes | Group display name |
group_slug |
string | No | Group slug for API |
group_repetitions |
number | No | Number of allowed repetitions (default: 1, minimum: 1) |
fields |
array | Yes | Array of fields in the group (minimum 1) |
Important: Fields inside a group must have repetitions: 1.
Site-wide ceiling: the maximum group_repetitions a site allows is reported by whoami's site.limits.topics_ext_group_loop ({current, max}, max is 99). Don't assume a number — check whoami before setting a large group_repetitions. current is raisable up to max via admin_setting-update (see /kuroco-admin-mcp).
The granularity of updates is per field, and partial updates cannot be made within a repeat: topics-update Fields not sent inare retained, but repeat fields are replaced entirely with the sent content as soon as they are sent. You cannot replace only the second of three entries, and even when you want to change just one slot, you must read the current value with topics-get and then assemble and send all slots.For fields that are frequently rewritten only in part, consider at design time separating them into a different field or a different record instead of making them a repeat.
Adding fields to an existing definition
Use topics_group-update with topics_group_id. Its semantics (from the tool schema):
- Resolve the target first: get
topics_group_idfromtopics_group-list({}— fetch all and matchgroup_nmlocally; check itsinputSchemafor a name filter) — never guess it; if several definitions match, list them and let the user choose. Thentopics_group-getthe definition and keep theformDataas a before-snapshot. - Re-check the ceiling: existing field count + new fields must stay within
whoami→site.limits.topics_max_extension.current(raise viaadmin_setting-updateifcurrent < max). - Partial update: any top-level column you omit is back-filled from the current row, so send only what changes (e.g. just
secure_level, or justfields). To clear a value, send it explicitly empty (""/0/[]). fieldsadds, never removes: entries infieldsare appended as new fields; existing fields you do not mention are preserved as-is. This endpoint cannot delete or reorder existing fields — tell the user when a request needs that.- Before adding, call
topics_group-getand check the existingext_slugs so the new slug does not collide, then read back after the write as in Verifying the result. New fields get new suffixes<n>— find them by matchingext_slug_<n>to the slugs you sent, and confirm every other<n>is identical to the before-snapshot. file_sizemust be within the site'sMAX_FILE_SIZE; that value is not exposed bywhoami, so a too-large value surfaces as a tool error or a clamped read-back — check the read-back.required: trueon a new field affects existing records: their next edit fails validation until the field is filled. Ask before making an added field required.- A definition has no approval/draft workflow of its own: the update applies immediately.
need_application_groups/can_save_draft_groupsgovern the content records, not the definition.
Important Notes
ext_typeis what determines the field type. If you also sendtype, it must be the matching pair (see the Field Type Reference table); omittingtypeis fineselectandcheckboxtypes requireoptions(at least one option)- A request about who can see or edit the content is a container parameter, not a field → Content Definition Parameters
- Read the record back after every write and confirm the fields were stored → Verifying the result
relationtype requiresmoduleapitype requiresapi_settings- Fields inside field groups must have
repetitions: 1 name(content structure name) and each field'sext_titlecannot be empty stringsext_slug/group_slugmay contain only[a-zA-Z0-9_-]and must not be a reserved name — the tool rejects them. The complete list is in references/field-types.md › Reserved slug names; check it before proposing slugs (e.g.description,title,priceare fine;subject,tags,keyword,contentsare not)
Related skills
| Skills | Role |
|---|---|
/kuroco-admin-mcp |
Admin MCP connection, OAuth, scopes,whoami の site.limits と admin_setting-update raising the limit with , checking tool names |
/kuroco-api-content |
API response format by field type,:R() search syntax, priority order of view/edit restrictions, content CRUD |
/kuroco-server-processing |
Fetching all data of relation targets (custom functions for endpoint post-processing), external integrations |
/kuroco-app-builder |
Use this skill in phase 2 of overall app construction |
/kuroco-auth-design |
Design decisions on access scope such as "show only one's own posts" (self_only implementation is covered by this skill) |