Files
homaroma/LLM_MCP_GUIDE.md
2026-10-01 05:49:58 +07:00

211 lines
8.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DBK Platform MCP Guide for LLMs
This guide explains how to use the DBK Platform MCP tools safely and consistently. The tools operate on the active tenant's data and configuration; do not infer another tenant's catalog, brand, or enabled integrations from an example.
> HomAroma is the reference tenant. See [`docs/PLATFORM_OVERVIEW.md`](docs/PLATFORM_OVERVIEW.md) for platform terminology.
## Core Rules
- Prefer the dedicated block tools over the generic `add_page_section` / `update_page_section` tools when available.
- Use `update_page_translations` when you need to set several languages for a page title in one call.
- Treat localized fields and plain strings differently.
- Read back the page after edits when you need confirmation.
## Finding a Page
- Use `get_dynamic_page_detail` with the page slug when you already know the slug.
- Use `list_dynamic_pages_metadata` when you need to search all pages quickly.
- The dynamic page detail response includes the page `id`, which is the `pageId` you use for section tools.
## Create Page Response Contract
Use `create_page_with_section` only when the slug does not exist. It atomically
creates a new page and its first section; it does not update an existing page.
If it returns `PAGE_SLUG_EXISTS`, use the returned `pageId` with
`add_page_section`.
To add another block to an existing page:
1. Call `get_dynamic_page_detail` with the slug.
2. Call `get_page_block_schema` for the desired block type.
3. Call `add_page_section` with the returned page `id`.
4. Call `reorder_page_sections` if the new block must move relative to existing blocks.
5. Read the page back with `get_dynamic_page_detail`.
`create_dynamic_page` now returns a structured response that is easy for LLMs to parse:
- `success`
- `operation`
- `pageId`
- `slug`
- `title`
- `isPublished`
- `diagnostic`
- `page`
Use `diagnostic` as the human-readable explanation, not as the only signal of success.
## Section Tool Mapping
- `update_hero_article`
- `update_rich_text`
- `update_scent_notes_breakdown`
- `update_quote_callout`
- `update_product_carousel`
- `update_accordion`
- `update_contact_info`
- `update_contact_form`
These tools return a normalized response with:
- `success`
- `tool`
- `sectionType`
- `sectionId`
- `updatedFields`
- `appliedPayload`
- `notes`
- `section`
## Payload Shape Cheat Sheet
### Localized string
Use this when a field can be translated:
```json
{ "th": "ข้อความภาษาไทย", "en": "English text" }
```
### Plain string
Use one string only for URLs, slugs, IDs, and booleans/numbers as appropriate.
## Block-Specific Rules
### `HERO_ARTICLE`
- Localized: `title`, `subtitle`, `author`, `category`
- Plain string: `publishDate`, `date`, `imageUrl`, `backgroundImageUrl`, `overlayColor`
- The image is passed as a URL string in `imageUrl`
### `RICH_TEXT`
- `title` is optional and localized
- `content` is required and localized
- HTML is allowed in `content`
### `ARTICLE_MEDIA`
- `body` is required, localized plain text; do not send HTML
- `heading`, `imageAlt`, and `imageCaption` are localized
- `imageUrl` is a plain URL or website-relative media path
- `imageAlt` is required whenever `imageUrl` is present
- `imagePosition` accepts `left`, `right`, or `top`
- `width` accepts `narrow`, `standard`, or `wide`
- `background` accepts `default` or `muted`
### Article composition blocks
- `ARTICLE_HEADER`: article title, subtitle, category, author, date, and optional cover image
- `ARTICLE_GALLERY`: 2–8 images with required localized alt text; layouts are `grid` or `featured`
- `ARTICLE_FACTS`: 1–8 concise facts or key takeaways
- `ARTICLE_VIDEO`: HTTPS YouTube, Vimeo, or direct video URL; embed HTML is not accepted
- `ARTICLE_REFERENCES`: 1–20 references with optional verified HTTPS URLs and notes
- `ARTICLE_TABLE`: responsive technical comparison with 2–6 columns
- `ARTICLE_DOWNLOAD`: 1–10 verified HTTPS documents
- `ARTICLE_CTA`: one primary action and an optional secondary action
- Reuse `QUOTE_CALLOUT`, `ACCORDION`, and `PRODUCT_CAROUSEL` instead of creating duplicate article-only variants
### `SCENT_NOTES_BREAKDOWN`
- `title` and `description` are localized
- Each note item may be a plain string or a localized string object
- `heartNotes` and `middleNotes` are mirrored by the backend
### `QUOTE_CALLOUT`
- `quote` is required and localized
- `author` and `role` are optional localized fields
### `PRODUCT_CAROUSEL`
- `title` and `description` are localized
- `collectionId`, `limit`, `showPrice`, `showAddToCart`, and `products` are plain values
- If `products` is omitted, the backend can auto-populate products on read-back
### `ACCORDION`
- `title` is optional and localized
- `categories` is required
- Each category needs:
- localized `name`
- optional `icon`
- at least one question
- Each question needs localized `q` and `a`
### `CONTACT_INFO`
- `title` is optional and localized
- `address` and `hours` are localized
- `email` and `line` are plain strings
### `CONTACT_FORM`
- `title` and `subtitle` are localized
- There are no extra fields
## Recommended Flow
1. Determine whether the page already exists.
2. For a new page, use `create_page_with_section` for the page and first block.
3. For an existing page, get its id and use `add_page_section`.
4. Create or update the page title translations.
5. Update existing sections using the dedicated block tool when possible.
6. Read back the page with `get_dynamic_page_detail`.
7. If a section has auto-populated fields, trust the read-back result over the raw update payload.
## Translating Page Builder Blocks
Translate one language and one block at a time. This keeps the context compact and prevents a full payload replacement from overwriting existing languages.
1. Call `get_page_translation_status` with `pageId` and the target `lang`.
2. Pick one incomplete `sectionId`.
3. Call `get_page_section_translation` with that `sectionId` and target `lang`. The default fallback supplies source text for untranslated fields and lists those fields in `fallbackPaths`.
4. Translate the fields listed in `fallbackPaths`; preserve the payload's object and array shape.
5. Call `update_section_translation` with `translations` and the `updatedAt` value as `expectedUpdatedAt`.
6. Read the block again with `get_page_section_translation` and confirm `fallbackPaths` is empty.
`update_section_translation` changes only the requested language in registered localized fields. It preserves other languages, URLs, IDs, layout configuration, and other non-translatable values. A `SECTION_VERSION_CONFLICT` response means the block changed after it was read; fetch it again before retrying.
Use `get_page_section` with `lang=all` only when every stored language map is genuinely needed. A specific language returns resolved strings and uses fallback by default.
## Editing Footer Menus
`footer-explore` and `footer-support` are flat menus shared by Admin, Backend, MCP, and Website. They are not Page Builder sections and do not use the Mega Menu tree tools.
1. Call `get_footer_menu` with `menuName` and the target `lang`.
2. Keep the returned `version`.
3. Preview one item-level mutation with `dryRun=true` and `expectedVersion`.
4. Apply only after the preview is correct.
5. Read the menu again and verify the result.
Use `update_footer_menu_item_translation` for one language at a time. Use `reorder_footer_menu_items` only with the complete list of current item IDs. If the backend returns `MENU_VERSION_CONFLICT`, discard the old version and read the menu again.
An allowed Footer menu may not exist before its first item is saved. In that case, `get_footer_menu` returns `exists=false` and `version=null`. Run `add_footer_menu_item` with `dryRun=true`; a `willCreateMenu=true` preview confirms that the actual add will create the active menu and first item atomically.
Do not use legacy `update_footer_content` for menu arrays. It remains available only for the Footer brand description and social links. Website Collections come from Categories, not a Footer menu.
## What to Expect
- `PRODUCT_CAROUSEL` may return products even when you did not send them.
- `SCENT_NOTES_BREAKDOWN` may show mirrored note groups in the response.
- `create_dynamic_page` should now return a clear success/error contract.
## Safe Usage Tips
- Do not guess the field shape from the UI alone.
- If a field is a URL, send a URL string.
- If a field is translated, send a localized object.
- If you are unsure, inspect an existing page with `get_dynamic_page_detail` first.