> ## Documentation Index
> Fetch the complete documentation index at: https://docs.frontic.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Frontic Tools

The **Frontic Tools** MCP server connects AI coding assistants directly to your Frontic projects, letting you build storefronts and configure your Frontic API from your IDE. Pair it with the [Frontic Docs](https://docs.frontic.com/reference/mcp/frontic-docs.md) MCP server so the agent can also answer "how does X work?" questions without leaving the editor.

![Frontic MCP Server Hero](https://mintcdn.com/frontic/34vlQbUxJTTktEkF/images/hero-mcp.png?fit=max\&auto=format\&n=34vlQbUxJTTktEkF\&q=85\&s=be3cd285767b47d3b78a25ae4d9fb853)

## Overview

Connect your favorite AI coding assistants directly to your Frontic Commerce projects through secure OAuth authentication. Build a frontend AND the corresponding Frontic API - all from your coding agent or IDE of choice.

> [card] Claude Code
>
> Full project management and content creation workflows

> [card] Claude Desktop
>
> Interactive Frontic operations from your desktop

> [card] Cursor
>
> Integrated development experience with AI assistance

The MCP server provides tools across these categories:

> [card] Project & Resource Discovery
>
> Browse projects, list each resource kind, inspect storage records, and preview Fetch API responses

> [card] Blocks, Listings, Pages & Trees
>
> Create and manage blocks, listings, pages, and menu trees that define your API

> [card] Storage Management
>
> Create Data Storages, then add, rename, and remove top-level fields

> [card] Project Configuration
>
> Explore domains, scopes, regions, and locales

> [card] Browse Data
>
> Search storage records and raw feed records

> [card] Integrations
>
> Inspect connected integrations and their feed schemas before mapping

> [card] Data Syncs & Value Composer
>
> Create data syncs, configure field mappings, and preview composer operations

> [card] Context Documents
>
> Manage skills, rules, guides, and other context documents

> [card] Shopware Insights
>
> Read the promotions and sales channels of a connected Shopware store

## Setup

The fastest path is the CLI - pick your package manager:

```bash frontic theme={"theme":"css-variables"}
frontic mcp init --client cursor
```

```bash pnpm theme={"theme":"css-variables"}
pnpm dlx @frontic/cli@latest mcp init --client cursor
```

```bash npm theme={"theme":"css-variables"}
npx @frontic/cli@latest mcp init --client cursor
```

```bash yarn theme={"theme":"css-variables"}
yarn dlx @frontic/cli@latest mcp init --client cursor
```

```bash bun theme={"theme":"css-variables"}
bunx @frontic/cli@latest mcp init --client cursor
```

Swap `cursor` for `claude`, `windsurf`, `vscode`, or `codex`. The CLI prompts whether to install Frontic Tools, Frontic Docs, or both - the recommended default is both. See the [Frontic CLI reference](https://docs.frontic.com/reference/frontic-cli.md#frontic-mcp-init) for full options.

If you'd rather edit the config yourself, drop this entry into your client's MCP config file:

```json theme={"theme":"css-variables"}
{
  "mcpServers": {
    "frontic-tools": {
      "type": "http",
      "url": "https://mcp.frontic.com/mcp"
    }
  }
}
```

> [!NOTE]
>
> The first time you connect, you'll be prompted to authenticate via OAuth. The token carries your Frontic account's permissions - whatever role you have on a project, the MCP can do on that project, and nothing more.

### Client-specific configuration

> [accordion] Claude Code
>
> Add to `.mcp.json` at your project root - Claude Code reads project MCP config from this file:
>
> ```json theme={"theme":"css-variables"}
> {
>   "mcpServers": {
>     "frontic-tools": {
>       "type": "http",
>       "url": "https://mcp.frontic.com/mcp"
>     }
>   }
> }
> ```

> [accordion] Claude Desktop
>
> Edit the Claude Desktop config file:
>
> * **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
> * **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
>
> ```json theme={"theme":"css-variables"}
> {
>   "mcpServers": {
>     "frontic-tools": {
>       "type": "http",
>       "url": "https://mcp.frontic.com/mcp"
>     }
>   }
> }
> ```

> [accordion] Cursor
>
> Add to `.cursor/mcp.json` in your project root, or Cursor's global settings:
>
> ```json theme={"theme":"css-variables"}
> {
>   "mcpServers": {
>     "frontic-tools": {
>       "type": "http",
>       "url": "https://mcp.frontic.com/mcp"
>     }
>   }
> }
> ```

## Common Workflows

Most tools are a step in a chain, and the chain is what gets work done. These four cover
almost everything people build through the MCP server.

**1. Build a backend from zero**

`list_projects` to find the project, then `create_storage` for the [Data Storage](https://docs.frontic.com/data-integration/data-storages.md)
and `update_storage` to add its fields. Wrap it in a [Detail Block](https://docs.frontic.com/api-builder/blocks.md)
with `create_block`, expose a collection with `create_listing`, and route it with
`create_page`. Finish with `preview_fetch_response` to see exactly what the frontend
will receive.

**2. Map a feed into a storage**

`list_integrations` to find the connected system, then `get_integration_feed` for the
flat field list in dot-path notation. Shape the storage to match, then `create_data_sync` -
which creates the sync shell only. Call `get_data_sync` for the field tree, map the
fields with `update_data_sync_value_configs`, and dry-run the result with
`preview_composer_record` before anything is persisted. Verify with `search_storage_records`
once the sync has run.

**3. Build a navigation menu**

`list_storages` for the source data and `list_blocks` to find an item block worth
reusing - multiple [Menu Trees](https://docs.frontic.com/api-builder/trees.md) can share one. `create_tree`
builds the hierarchy, `update_tree` narrows it with query conditions.

**4. Debug what the frontend receives**

`preview_fetch_response` for the served payload, `search_storage_records` for the
stored values behind it - filtered by scope, region, and locale to see contextualized
output. When you need a storage's real keys and slugs rather than a search,
`list_storage_record_examples` returns up to five records with their system fields.

## Example Prompts

Once connected, try these prompts to explore the MCP server's capabilities:

Have your agent list your projects and inspect the main one

List all my Frontic projects and show me the resources in my main project.

Ask the agent to map out your Data Storages and their fields

What storages and data structures are available in my project?

Let the agent build a Search Listing with filters and sorting

Create a product listing with filters for category and price, sorted by newest first.

Tell the agent to scaffold a hero block with the standard fields

Create a hero block with fields for title, subtitle, background image, and CTA button.

Have the agent assemble a homepage from existing primitives

Create a homepage with a hero section at the top and a featured products listing below.

Get the agent to plan and set up a basic storefront end to end

Help me set up a basic storefront with a homepage, product listing page, and the necessary blocks.

Have the agent extend a Data Storage schema with a new translatable field

Add a translatable `shortDescription` string field to the Products storage.

Have the agent create a Products storage and connect a feed

Create a Products storage and connect it to the Shopify Products feed.

Have the agent set up a content storage from scratch

Set up a content storage for blog articles.

Have the agent add a relation field linking two storages

Add a `relatedProducts` relation field to the Products storage that links back to Products via the `sku` field.

Walk the integration → feed → data sync workflow end to end

Show me the field schema of my Shopify Products feed and use it to map the Products data sync.

Ask the agent to inspect your data syncs and their field mappings

Show me all data syncs and their field mappings for my project.

Have the agent preview a Value Composer transformation on a sample record

Preview how the Value Composer transforms a sample product record.

Ask the agent what the connected Shopware store is running

List the sales channels and active promotions of my Shopware store.

Ask the agent to walk your scope, region, and domain hierarchy

List all scopes, regions, and domains in my project to understand the context hierarchy.

## Available Tools

### What each tool may do

Every tool declares whether it only reads, as an MCP annotation. Clients that act on those
annotations can run the reading tools without stopping to ask and keep prompting for the
rest; for clients that want it spelled out, the allow-list below does the same thing
explicitly.

| May do | Tools |
| - | - |
| **Reads only** | every `get_*`, `list_*`, `search_*`, and `preview_*` tool |
| **Writes** | every `create_*` tool, and the `update_*` tools that change configuration |
| **Destroys data** | `delete_resource`, `update_storage` |

The `preview_*` tools count as reads because all three are dry-runs - they show you the
transformed value or the API response without persisting anything.

`update_storage` sits with `delete_resource` because its field operations include deleting a
field, and deleting a field takes the stored values with it. Adding and renaming fields is
safe; removing one is not reversible.

> [accordion] Auto-approve the read-only tools in Claude Code
>
> Add to `.claude/settings.json` in your project. Everything not listed still prompts:
>
> ```json theme={"theme":"css-variables"}
> {
>   "permissions": {
>     "allow": [
>         "mcp__frontic-tools__get_context_document",
>         "mcp__frontic-tools__get_data_sync",
>         "mcp__frontic-tools__get_integration_feed",
>         "mcp__frontic-tools__get_project",
>         "mcp__frontic-tools__list_blocks",
>         "mcp__frontic-tools__list_composer_operations",
>         "mcp__frontic-tools__list_context_documents",
>         "mcp__frontic-tools__list_data_syncs",
>         "mcp__frontic-tools__list_domains",
>         "mcp__frontic-tools__list_integrations",
>         "mcp__frontic-tools__list_listings",
>         "mcp__frontic-tools__list_locales",
>         "mcp__frontic-tools__list_pages",
>         "mcp__frontic-tools__list_projects",
>         "mcp__frontic-tools__list_regions",
>         "mcp__frontic-tools__list_scopes",
>         "mcp__frontic-tools__list_shopware_promotions",
>         "mcp__frontic-tools__list_shopware_sales_channels",
>         "mcp__frontic-tools__list_storage_record_examples",
>         "mcp__frontic-tools__list_storages",
>         "mcp__frontic-tools__list_trees",
>         "mcp__frontic-tools__preview_composer_record",
>         "mcp__frontic-tools__preview_composer_value",
>         "mcp__frontic-tools__preview_fetch_response",
>         "mcp__frontic-tools__search_feed_records",
>         "mcp__frontic-tools__search_storage_records"
>     ]
>   }
> }
> ```

### Project & Resource Discovery

#### `list_projects`

Browse all your Frontic projects with their names, IDs, data types, and configured locales. Use it when you don't already know which project you're working against - once a project is selected, the resource tools take its ID directly.

**Parameters**

**mode** `enum` (default: content)

Output format: 'content' (default) returns project data directly in the response, 'resource' returns MCP resource URIs that can be fetched separately. Use 'content' in most cases.
One of: `resource`, `content`

#### `preview_fetch_response`

Get a sample Fetch API response for a block, listing, tree, or page - exactly what the frontend receives when calling the Frontic API. Useful for understanding the response shape before building your frontend.

**Parameters**

**type** `enum` *required*

Resource type to get the example for. Can be "block", "listing", "tree" or "page". If you pass the wrong type for a given name, the tool will auto-correct to match the resource's actual mode.
One of: `block`, `listing`, `tree`, `page`

**name** `string`

The type name of the block, listing, or tree (e.g., 'ProductCard', 'CategoryListing', 'CategoryNavigation'). Use list\_blocks, list\_listings or list\_trees to find available names if unsure. Not needed for pages - use the slug parameter instead.

**parameters** `string`

JSON object with entry point parameters. For blocks: \{"key": "\<record-uuid>"} (omit to return any result). For listings: depends on configuration, e.g., \{"categoryId": "\<id>"} - most listings require at least one parameter. For trees: optional \{"key": "\<record-uuid>"} to start from a subtree, \{"depth": \<n>} to limit depth (1-20). Use list\_storage\_record\_examples to find real record IDs.

**slug** `string`

Only required for pages. The full URL of the page - e.g. "myshop.com/shoes/sneakers/nike-air-max-90", "myshop.com/fr-FR/Women/Clothing"

**projectId** `string` *required*

Project ID in which the resource exists.

#### `delete_resource`

Permanently delete a block, listing, page, storage, or tree from the project. This action cannot be undone.

**Parameters**

**projectId** `string` *required*

The unique identifier of the project containing the resource to delete

**type** `enum` *required*

Entity type: "block" for content components, "listing" for listings, "page" for website pages, "storage" for data storages "tree" for trees
One of: `block`, `listing`, `page`, `storage`, `tree`

**id** `string` *required*

The unique identifier of the specific resource to delete

### Block Management

#### `list_blocks`

Single-record endpoints with their fields, parameters, and `storageId`

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

#### `create_block`

Create a new block - a reusable content component that defines which fields are exposed in Fetch API responses. Blocks serve single-record endpoints.

**Parameters**

**projectId** `string` *required*

The unique identifier of the project in which the block should be created

**name** `string` *required*

The name of the block. IMPORTANT: Always use normal capitalized words with spaces (e.g., 'Product Card', 'Hero Banner', 'Cart Summary'). Never use PascalCase or concatenated words - the platform derives the URL slug and API type name from this value, and incorrect casing breaks namespacing.

**description** `string` *required*

A brief description of the block's purpose (e.g., 'Serves product detail data including name, price, images, and description').

**storageId** `string` *required*

Must reference a valid storage ID from the available storages.

**useVariants** `boolean` (default: false)

If the storage used in storageId is of type "commerce", you can choose to retrieve product variants from this block. This will determine the fetchMode for this block. It will make the block return variant records. The default is to return product records.

#### `update_block`

Update an existing block by adding or removing fields, and control its active status.

**Parameters**

**projectId** `string` *required*

The unique identifier of the project containing the block

**blockId** `string` *required*

The unique identifier of the block to modify

**fields** `object[]`

Optional array of field operations. Each field can have "add" or "delete" operation, allowing mixed operations in a single call. Omit this parameter if you only want to change the active status.

**Fields**

**operation** `enum` *required*

The operation for this field: "add" to add a new field, "delete" to remove an existing field
One of: `add`, `delete`

**name** `string` *required*

Name of the block field. For "add" operation, this will be the new field name. For "delete" operation, this must match an existing field name.

**fieldType** `enum`

The type of field to add. Required for "add" operations. Options: "field" (storage-based), "block" (nested block), "resultList", "variantList", "productPrice" (only possible for blocks with fetchMode=product), "pageRoute"
One of: `field`, `block`, `resultList`, `variantList`, `productPrice`, `pageRoute`

**storageFieldId** `string`

Required for fieldType="field". The ID of the field from the block's storage to link to.

**nestedBlockId** `string`

Required for fieldType="block", "resultList", or "variantList". The ID of the nested block to embed.

**blockParameterValues** `object[]`

Optional parameter values for nested blocks. Maps parent block fields to nested block parameters.

**Fields**

**blockFieldId** `string` *required*

The ID of the block field to pass as value

**source** `enum`

The source type for the block parameter value
One of: `blockField`, `static`, `storageSchemaField`

**reference** `string` *required*

The static value or block field ID or block field name or storage field ID for the block parameter value source

**path** `string`

The path in the block field or storage field for the block parameter value source, if it is a composite field

**priceStrategy** `enum`

Required for fieldType="productPrice". Strategy for selecting price from variants.
One of: `first`, `lowest`, `highest`

**pageId** `string`

Required for fieldType="pageRoute". The ID of the target page to link to.

**pageKeyBlockFieldId** `string`

Required for fieldType="pageRoute". The ID of the block field that provides the key value that is used to get the correct page value.

**pageKeyStorageSchemaFieldId** `string`

Required for fieldType="pageRoute". The ID of the storage schema field used as the page key.

**pageKeyPath** `string`

Optional for fieldType="pageRoute". Path in the key field if it is a composite field (e.g., "name.en").

**active** `boolean`

Optional. Set whether the block is active (enabled) or inactive (disabled). When inactive, the block cannot be used in pages or other blocks.

### Listing Management

#### `list_listings`

Collections with their search, filter, and sort fields, parameters, and query conditions

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

#### `create_listing`

Create a new listing - a searchable, filterable, sortable collection that performs search queries on a block index.

**Parameters**

**projectId** `string` *required*

The unique identifier of the project in which the listing should be created

**name** `string` *required*

The name of the listing. IMPORTANT: Always use normal capitalized words with spaces (e.g., 'Product List', 'Category Grid', 'Search Results'). Never use PascalCase or concatenated words - the platform derives the URL slug and API type name from this value.

**description** `string` *required*

A brief description of the listing's purpose (e.g., 'Searchable product collection with category filtering and price sorting').

**storageId** `string` *required*

Must reference a valid storage ID from the available storages.

**resultStrategy** `enum` *required*

Choose if the listing should return only the first result or all results. Use "first" for single item searches, "all" for listing multiple items (e.g. product listings in categories).
One of: `all`, `first`

**nestedBlockId** `string` *required*

Must reference a valid block ID from the available blocks. This block will be used to render each item in the listing.

#### `update_listing`

Configure all aspects of an existing listing: search fields, filter fields, sort fields, parameters, query conditions, search settings, and pagination.

**Parameters**

**projectId** `string` *required*

The unique identifier of the project containing the listing

**listingId** `string` *required*

The unique identifier of the listing to modify

**fields** `object[]`

Optional array of field operations for search/filter/sort fields. Each field can have "add", "update", or "delete" operation.

**Fields**

**operation** `enum` *required*

The operation for this field: "add" to add a new field, "update" to modify an existing field, "delete" to remove an existing field
One of: `add`, `update`, `delete`

**type** `enum` *required*

The type of field: "search" for text search, "filter" for filtering/faceting, "sort" for sorting
One of: `search`, `filter`, `sort`

**name** `string` *required*

Name of the field. For "add" operation, this will be the new field name. For "update" and "delete" operations, this must match an existing field name.

**source** `enum`

Required for "add" operations. Source of the field: "blockField" (from listing's nested block) or "storageField" (from storage referenced in storageId). Always prefer block fields over storage fields.
One of: `blockField`, `storageField`

**path** `string`

Optional path of the field, if it is nested/composite (e.g. if the field you want to use is vendor.label, then the path is "label")

**isFacetted** `boolean`

Required for type="filter" add operations. Whether the filter field is facetted (shows available options)

**isAggregated** `boolean`

Optional for type="filter" add operations. Whether to aggregate values for this filter field. Defaults to true if not specified.

**ranges** `object[]`

Optional for type="filter". Numeric ranges for the filter field

**Fields**

**from** `number` *required*

Start of the range

**to** `number` *required*

End of the range

**sort** `enum`

Required for type="sort" add operations. The sorting direction: "asc" (ascending) or "desc" (descending)
One of: `asc`, `desc`

**isDefault** `boolean`

Required for type="sort" add operations. Indicates if this is the default sort field. Only one sort field can be default.

**parameters** `object[]`

Optional array of parameter operations. Parameters can be referenced in query conditions.

**Fields**

**operation** `enum` *required*

The operation for this parameter: "add", "update", or "delete"
One of: `add`, `update`, `delete`

**name** `string` *required*

Name of the parameter. For "update" and "delete" operations, this must match an existing parameter name.

**dataType** `string`

Required for "add" operations. The data type of the parameter (e.g., "string", "int", "bool")

**required** `boolean`

Required for "add" operations. Whether the parameter is required

**isArray** `boolean`

Required for "add" operations. Whether the parameter is an array

**minItems** `number`

Optional minimum number of items (for array parameters)

**maxItems** `number`

Optional maximum number of items (for array parameters)

**defaultValue** `string`

Optional default value for the parameter

**conditions** `object[]`

Optional array of query condition operations. Conditions filter which records appear in the listing.

**Fields**

**operation** `enum` *required*

The operation for this condition: "add" to add a new condition, "delete" to remove by index
One of: `add`, `delete`

**index** `number`

Required for "delete" operation. The index of the condition to delete (0-based)

**before** `object`

Required for simple comparison conditions. The left-hand side of the condition (field to check). Omit for pure group conditions.

**Fields**

**type** `enum` *required*

Source type: "blockField" or "storageField" (will be normalized to storageSchemaField)
One of: `blockField`, `storageField`

**reference** `string` *required*

UUID of the field to compare

**path** `string`

Optional path if the field is composite (e.g., "name.en")

**operator** `enum`

Required for simple comparison conditions. The comparison operator. Omit for pure group conditions.
One of: `like`, `notLike`, `equals`, `notEquals`, `gt`, `gte`, `lt`, `lte`

**after** `object`

Required for simple comparison conditions. The right-hand side of the condition (value to compare against). Omit for pure group conditions.

**Fields**

**type** `enum` *required*

Value type: "blockParameter" (reference to parameter) or "value" (static value)
One of: `blockParameter`, `value`

**reference** `string` *required*

For blockParameter: parameter name. For value: the static value

**rules** `any[]`

Array of nested conditions for complex AND/OR logic. Required for pure group conditions. Each rule follows the same structure and can itself be either a simple condition or a group.

**group** `enum`

Required when rules are present. Logical operator ("and" or "or") for combining nested rules.
One of: `and`, `or`

**isSearchFuzzy** `boolean`

Optional. Enable fuzzy search for better matching of similar terms. Defaults to true if not specified.

**perPageDefault** `number`

Optional. Default number of items per page for pagination. Must be at least 1. Defaults to 24 if not specified.

**perPageMax** `number`

Optional. Maximum number of items per page that can be requested. Must be at least 1. Defaults to 48 if not specified.

**active** `boolean`

Optional. Set whether the listing is active (enabled) or inactive (disabled). When inactive, the listing cannot be used in the storefront.

### Page Management

#### `list_pages`

URL routing patterns with their block and that block's `storageId`

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

#### `create_page`

Create a page - a URL routing pattern that generates SEO-friendly routes from block data records.

**Parameters**

**projectId** `string` *required*

The unique identifier of the project in which the page should be created

**name** `string` *required*

The name of the page (max 100 characters). IMPORTANT: Always use normal capitalized words with spaces (e.g., 'Product Detail', 'Category Page'). Never use PascalCase or concatenated words.

**blockId** `string` *required*

Must reference a valid block ID from the available blocks. This must be a block, not a listing.

**slugBlockFieldId** `string` *required*

The ID of the block field to use as the URL slug. This field will be used to generate the URL path for each page.

**slugBlockFieldPath** `string`

The path in the slug block field referenced in slugBlockFieldId, if it is a composite field (e.g., "label" if the slugBlockFieldId references the composite field "cover" and the full path would be "cover.label"). Leave empty for simple fields.

**urlConflictStrategy** `enum`

Strategy for handling URL conflicts: "suffix" adds the conflict suffix to make URLs unique, "discard" skips records with conflicting URLs. Defaults to "suffix".
One of: `suffix`, `discard`

**urlConflictSuffixBlockFieldId** `string`

Only required for urlConflictStrategy="suffix". The ID of the block field to use as suffix when URL conflicts occur (e.g., when multiple items would generate the same URL slug). It often makes sense to use a unique identifier for the item, like a unique id or product-number etc.

**urlConflictSuffixBlockFieldPath** `string`

Only relevant for urlConflictStrategy="suffix". The path in the URL conflict suffix block field referenced in urlConflictSuffixBlockFieldId, if it is a composite field (e.g., "label" if the slugBlockFieldId references the composite field "cover" and the full path would be "cover.label"). Leave empty for simple fields.

**pageRecordDeleteStrategy** `enum`

Behavior when a source record is deleted: "temporaryRedirect" (302), "permanentRedirect" (301), "notFound" (404), or "delete" (removes the page URL completely). Defaults to "notFound".
One of: `temporaryRedirect`, `permanentRedirect`, `notFound`, `delete`

**useForSitemap** `boolean`

Indicates if the URLs of this page should be included in generated sitemaps. Defaults to false.

#### `update_page`

Update an existing page's URL generation settings like slug source, conflict strategy, and delete behavior.

**Parameters**

**projectId** `string` *required*

The unique identifier of the project containing the page

**pageId** `string` *required*

The unique identifier of the page to update

**slugBlockFieldId** `string`

Optional: The ID of the block field to use as the URL slug. Only provide if you want to change it.

**slugBlockFieldPath** `string`

Optional: The path in the slug block field, if it is a composite field (e.g., "label" for "cover.label"). Use empty string "" for simple fields. Only provide if you want to change it.

**urlConflictSuffixBlockFieldId** `string`

Optional: The ID of the block field to use as suffix when URL conflicts occur. Required if you set urlConflictStrategy to "suffix". It often makes sense to use a unique identifier like a product number.

**urlConflictSuffixBlockFieldPath** `string`

Optional: The path in the URL conflict suffix block field, if it is a composite field. Use empty string "" for simple fields. Only provide if you want to change it.

**urlConflictStrategy** `enum`

Optional: Strategy for handling URL conflicts: "suffix" adds the conflict suffix to make URLs unique, "discard" skips records with conflicting URLs. Set to null to clear the value. If set to "suffix", you must also provide urlConflictSuffixBlockFieldId.

**pageRecordDeleteStrategy** `enum`

Optional: Behavior when a source record is deleted: "temporaryRedirect" (302), "permanentRedirect" (301), "notFound" (404), or "delete" (removes the page URL completely). Set to null to clear the value.

**useForSitemap** `boolean`

Indicates if the URLs of this page should be included in generated sitemaps..

### Tree Management

#### `list_trees`

Hierarchical collections with their `storageId`, query conditions, and nested item block

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

#### `create_tree`

Create a [Menu Tree](https://docs.frontic.com/api-builder/trees.md) - a hierarchical collection of records (navigation menus, category trees, support article hierarchies). Each tree references a connected Data Storage and a Detail Block that defines the node shape. Multiple trees can share the same block; the agent prefers reusing an existing block over creating a new one.

**Parameters**

**projectId** `string` *required*

The unique identifier of the project in which the tree should be created

**name** `string` *required*

The name of the tree. IMPORTANT: Always use normal capitalized words with spaces (e.g., 'Category Menu', 'Footer Navigation', 'Support Links'). Never use PascalCase or concatenated words - the platform derives the URL slug and API type name from this value.

**description** `string` *required*

A brief description of the tree's purpose (e.g., 'Main category navigation for headers').

**storageId** `string` *required*

Must reference a valid storage ID from the available storages.

**nestedBlockId** `string` *required*

Must reference a valid block ID from the available blocks. This block will be used to render each item in the tree.

#### `update_tree`

Configure an existing tree's query conditions - the business-logic filters that narrow which records the tree includes. Use it after `create_tree` to make a tree more specific.

**Parameters**

**projectId** `string` *required*

The unique identifier of the project containing the tree

**treeId** `string` *required*

The unique identifier of the tree to modify

**conditions** `object[]`

Optional array of query condition operations. Conditions filter which records appear in the tree.

**Fields**

**operation** `enum` *required*

The operation for this condition: "add" to add a new condition, "delete" to remove by index
One of: `add`, `delete`

**index** `number`

Required for "delete" operation. The index of the condition to delete (0-based)

**before** `object`

Required for simple comparison conditions. The left-hand side of the condition (field to check). Omit for pure group conditions.

**Fields**

**type** `enum` *required*

Source type: "storageSchemaField"
One of: `storageSchemaField`

**reference** `string` *required*

UUID of the field to compare

**path** `string`

Optional path if the field is composite (e.g., "name.en")

**operator** `enum`

Required for simple comparison conditions. The comparison operator. Omit for pure group conditions.
One of: `like`, `notLike`, `equals`, `notEquals`, `gt`, `gte`, `lt`, `lte`

**after** `object`

Required for simple comparison conditions. The right-hand side of the condition (value to compare against). Omit for pure group conditions.

**Fields**

**type** `enum` *required*

Value type: "value" (static value)
One of: `value`

**reference** `string` *required*

the static value

**rules** `any[]`

Array of nested conditions for complex AND/OR logic. Required for pure group conditions. Each rule follows the same structure and can itself be either a simple condition or a group.

**group** `enum`

Required when rules are present. Logical operator ("and" or "or") for combining nested rules.
One of: `and`, `or`

**active** `boolean`

Optional. Set whether the tree is active (enabled) or inactive (disabled). When inactive, the tree cannot be used in the storefront.

### Storage Management

#### `list_storages`

Data schemas with their fields

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

#### `create_storage`

Create a new [Data Storage](https://docs.frontic.com/data-integration/data-storages.md) with a name and schema type.

* `default` creates a regular Content storage for content or reference data.
* `commerce` creates a Products storage for product catalog data and adds commerce-specific system fields for variants, prices, parent keys, and options.

After creating the storage, use `update_storage` to add custom fields.

**Parameters**

**projectId** `string` *required*

The unique identifier of the project in which the storage should be created

**name** `string` *required*

The name of the storage. IMPORTANT: Always use normal capitalized words with spaces (e.g., 'Products', 'Blog Articles', 'Brands'). Never use PascalCase or concatenated words.

**type** `enum` *required*

Storage type. Use "default" for regular content/reference data and "commerce" for product catalog data with commerce-specific default fields.
One of: `default`, `commerce`

#### `update_storage`

Update an existing [Data Storage](https://docs.frontic.com/data-integration/data-storages.md) by adding, renaming, or removing top-level fields. Removing a field deletes the values stored in it, which is why this tool is marked as destroying data. Field type is fixed at creation - to change a field's type you delete and recreate it.

Multiple operations can be batched in a single call and run sequentially, so a later operation can target a field added or renamed earlier in the same call.

The tool works on top-level fields only - nested sub-fields of composite types aren't editable through this tool. To create a new storage from scratch through MCP, use `create_storage`.

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

**storageId** `string` *required*

Storage ID

**fields** `object[]` *required*

Ordered list of field operations. Operations run sequentially, so later operations can target fields created or renamed earlier in the same call.

**Fields**

**operation** `enum` *required*

Field operation: "add" creates a new top-level storage field, "update" modifies an existing field, "delete" removes one.
One of: `add`, `update`, `delete`

**fieldId** `string`

Existing storage field ID to update or delete. Prefer this when available from list\_storages.

**fieldName** `string`

Existing storage field name to update or delete when fieldId is unknown. Only top-level field names are supported.

**name** `string`

New field name for "add", or the replacement name when renaming an existing field during "update".

**type** `string`

Data type key for "add" operations, e.g. "string", "integer", "boolean", or a custom composite type key. If relation is provided and type is omitted, "any" is used automatically.

**description** `string`

Optional field description for add or update operations.

**isArray** `boolean`

Whether the field stores multiple values. For add operations, defaults to false.

**sharedAcrossVariants** `boolean`

Whether the field is shared across variants. For add operations, defaults to false.

**isTranslatable** `boolean`

Whether the field is translatable. For add operations, defaults to false.

**isScoped** `boolean`

Whether the field is scope-aware. For add operations, defaults to false.

**relation** `object`

Optional relation configuration. The source field must already exist in the current storage.

**Fields**

**sourceFieldName** `string` *required*

Source field name in the current storage used as the relation key

**sourceFieldPath** `string`

Optional path in the source field when it is composite, e.g. "code".

**targetStorageId** `string` *required*

Target storage ID

**targetFieldName** `string` *required*

Field name in the target storage to match against

**targetFieldPath** `string`

Optional path in the target field when it is composite, e.g. "slug".

**mockModule** `string`

Optional mock generator module, e.g. "faker.datatype.string".

**mockModuleParams** `string`

Optional mock generator parameters string.

**mockMin** `integer`

Optional minimum array size for generated mock data.

**mockMax** `integer`

Optional maximum array size for generated mock data.

### Project Configuration

Explore the context hierarchy of your project. `get_project` returns the whole configuration in one call: the project, its scopes with their regions and locales, and its domains with each domain's scope, region, and locale resolved into names rather than left as IDs. The `list_*` tools enumerate one resource kind at a time.

* **Domains** map a scope, region, and locale combination to URL routing.
* **Scopes** are data segmentation layers (e.g., B2B vs B2C). Every project has at least the default `public` scope. A scoped field can return different values per scope - for example, `true` in scope A and `false` in scope B.
* **Regions** are subdivisions of a scope (e.g., EU, US, APAC). Each region holds a currency and one or more locales, determining which prices to show.
* **Locales** determine which translation to return for translatable fields. If a field is set as translatable, the response value matches the translation for that locale. `list_locales` is the complete list: a locale that no region exposes appears there and not in `get_project`.

#### `get_project`

How one project is configured, in a single call: the project itself, its scopes with their regions and locales, and its domains with each domain's scope, region, and locale resolved into names and keys rather than left as IDs. Start here when you already know which project you are working on, and reach for `list_projects` only when you do not.

`fetchApi` carries the hostname and the [version key](https://docs.frontic.com/releases/release-flow.md#version-keys) of the API version this project serves. Send the key as the `fs-version` header on [Fetch API](https://docs.frontic.com/reference/fetch-api.md) calls: without it the Fetch API serves the public version. `environments` lists the project's other API versions and drafts, each with its own version key, and an entry only carries a key when one is set - the public version has none, because sending no `fs-version` header is how a caller reaches it.

`list_locales` remains the complete locale list. A locale that no region exposes appears there and not here.

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

#### `list_domains`

List all domains configured in a project

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

#### `list_scopes`

List all scopes in a project

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

#### `list_regions`

List all regions within a scope

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

**scopeId** `string` *required*

Scope ID

#### `list_locales`

List all configured locales in a project

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

### Browse Data

Search and inspect the actual data in your project - both transformed storage records and raw feed records from integrations.

#### `list_storage_record_examples`

List up to five example records from a storage, each carrying the system fields the record has (`key`, `active`, `parentKey`, `position`, plus `price` and `options` on Products storages). Use it to learn a storage's real shape - slugs, keys, field values - before writing query conditions against it.

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

**storageId** `string` *required*

ID of the storage to read - usually the one connected to the block, listing or page. list\_blocks, list\_listings, list\_trees and list\_pages show each resource's storageId.

**fields** `string[]`

Storage fields to return next to the system fields, e.g. \["slug"] for a page or \["categoryId"] for a listing parameter. Only records with a value in every one of them are returned. System fields come with every example.

**variants** `boolean`

Commerce storages only: true returns variant records instead of parent products. Default false.

#### `search_storage_records`

Search records in a storage to see the transformed values blocks and listings serve to the frontend. Useful for verifying data after a sync, debugging unexpected output, or pulling a realistic sample for a composer dry-run with `preview_composer_value` or `preview_composer_record`. Filter by scope, region, and locale to see contextualized values like scoped pricing or translated content.

By default `records[]` contains bare payload objects - exactly what the user stored, no wrapper. Pass `includeMetadata: true` to get each record wrapped with its `id`, `sourceId`, `parentSourceId`, `createdAt`, and `updatedAt`. Opt in when you need to know when a record was updated/created or walk parent–child relationships in a follow-up call.

`metadata.parentSourceId` is the storage-tree parent - distinct from any `parentKey` a user happens to have inside their own payload. That namespacing is why metadata is opt-in rather than always-on.

`availableFilters` and `metaSearchResult` (pagination + total count) are always returned alongside `records[]`, regardless of `includeMetadata`.

Omit `conditions` entirely to return all records.

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

**storageId** `string` *required*

Storage ID

**request** `object` *required*

**Fields**

**searchVariants** `boolean`

Search product variants instead of parent products. Only applicable to commerce-type storages.

**conditions** `object`

Filter conditions. Pass an `and` or `or` array of \{field, operator, value} items - NOT a field-keyed object. Example: \{"and": \[\{"field": "slug", "operator": "like", "value": "polizei"}]}. The field-keyed shape \{"slug": \{"like": "..."}} is silently ignored by the backend and returns all records.

**Fields**

**and** `object[]`

All items must match (logical AND).

**Fields**

**field** `string` *required*

Field name to filter on, as it appears in availableFilters (e.g. "slug", "name", "parentKey").

**operator** `enum` *required*

Comparison operator. "like"/"notLike" accept raw substrings (no SQL wildcards - the backend wraps them). "empty" matches a missing, null or empty-string value, "notEmpty" the opposite.
One of: `equals`, `notEquals`, `gt`, `lt`, `gte`, `lte`, `like`, `notLike`, `empty`, `notEmpty`

**value** `string | number | boolean | string[]`

Value to compare against. Strings, numbers, booleans, or string arrays (for IN-style matches). Not needed for "empty" and "notEmpty".

**or** `object[]`

Any item must match (logical OR).

**Fields**

**field** `string` *required*

Field name to filter on, as it appears in availableFilters (e.g. "slug", "name", "parentKey").

**operator** `enum` *required*

Comparison operator. "like"/"notLike" accept raw substrings (no SQL wildcards - the backend wraps them). "empty" matches a missing, null or empty-string value, "notEmpty" the opposite.
One of: `equals`, `notEquals`, `gt`, `lt`, `gte`, `lte`, `like`, `notLike`, `empty`, `notEmpty`

**value** `string | number | boolean | string[]`

Value to compare against. Strings, numbers, booleans, or string arrays (for IN-style matches). Not needed for "empty" and "notEmpty".

**sorting** `object[]`

Sort order for results as array of \{field, direction: 'ASC'|'DESC'}.

**Fields**

**field** `string` *required*

**direction** `enum` *required*

One of: `ASC`, `DESC`

**page** `integer`

Page number for pagination (1-based). Defaults to 1.

**limit** `integer`

Maximum records to return per page. Defaults to server limit.

**scopeId** `string`

Scope ID for scope-contextualized field values (e.g., B2B pricing). Falls back to default scope if omitted.

**regionId** `string`

Region ID within the scope for region-specific values. Falls back to default region if omitted.

**localeId** `string`

Locale ID for translated field values (e.g., German product descriptions). Falls back to default locale if omitted.

**includeMetadata** `boolean` (default: false)

Include storage metadata (id, sourceId, parentSourceId, createdAt, updatedAt) on each record. Default false returns the bare payload - what the user actually stored - under records\[]. Opt in when you need to reference a record by its sourceId, parentSourceId, or id, e.g. for follow-up tool calls or debugging tree relationships.

#### `search_feed_records`

Search feed records from an integration to see the connector-normalized data before the composer transforms it. Every commerce platform names fields differently (Shopify: flat keys; Shopware: dot-notation; commercetools: deeply nested objects), so inspecting an actual feed record is the only reliable way to know what's available and how it's shaped.

Same metadata contract as `search_storage_records`: bare payloads by default, full envelope (`id`, `sourceId`, `parentSourceId`, `createdAt`, `updatedAt`) when you pass `includeMetadata: true`. `availableFilters` and `metaSearchResult` are always returned.

**Parameters**

**feedId** `string` *required*

Feed ID

**integrationId** `string` *required*

Integration ID

**channelId** `string`

Integration channel ID. Omit to use the integration's default channel. Read the ids from list\_integrations.

**translationId** `string`

Integration translation ID, which belongs to a channel. Omit to use the chosen channel's first translation.

**sourceId** `string`

Filter by a specific record source ID to find a single record. Finds a parent record unless `variants` is set. Use this for targeted lookups when you know the record identifier.

**parentSourceId** `string`

Filter by parent record source ID to find its variants (e.g., all variants of a main product). Only applicable to feeds with parent-child relationships. Implies a variant search.

**variants** `boolean`

Commerce feeds only: true makes `sourceId` look up a variant record instead of a parent. Not needed when filtering by `parentSourceId`, which always searches variants.

**includeMetadata** `boolean` (default: false)

Include storage metadata (id, sourceId, parentSourceId, createdAt, updatedAt) on each record. Default false returns the bare payload - what the user actually stored - under records\[]. Opt in when you need to reference a record by its sourceId, parentSourceId, or id, e.g. for follow-up tool calls or debugging tree relationships.

### Integrations

Discover and inspect connected source systems and their feed schemas. The typical workflow is `list_integrations` → pick a feed → `get_integration_feed` → use the field paths in `update_data_sync_value_configs` or composer previews.

Integrations belong to the Team rather than to a single project, so both tools here take no project and return the same results wherever you are working. The same holds for `search_feed_records` in Browse Data, which reads a feed rather than a storage.

#### `list_integrations`

Connected source systems with their channels and a compact feed inventory (id and name). Integrations belong to the Team, so this takes no project and returns the same list whichever project you are working in.

Takes no parameters.

#### `get_integration_feed`

Get the full schema for a single integration feed by feed ID. Returns the integration metadata, feed metadata (including `type`, `token`, `urls`, `methods`, `configurations`, and `refreshSupported`), and a flat field list in dot-path notation with types - for example, `title (string)`, `manufacturer (object)`, `manufacturer.name (string)`. The flat representation is what you copy into composer configs.

If the feed ID isn't found, the tool returns the list of available feed IDs across the Team's integrations so the agent can recover without a separate discovery call.

**Parameters**

**feedId** `string` *required*

Integration feed ID

### Data Syncs

#### `list_data_syncs`

List all data sync configurations, showing which integrations feed into which storages

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

#### `create_data_sync`

Create a data sync shell that connects one integration feed to one storage with a name, feed, storage, and optional scope/channel/locale mappings. New data syncs are enabled on creation; call `get_data_sync`, then `update_data_sync_value_configs`, to configure field value mappings

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

**name** `string` *required*

The name of the data sync. Always use normal capitalized words with spaces (e.g., 'Sync Products', 'Sync Categories').

**feedId** `string` *required*

Integration feed ID

**storageId** `string` *required*

Storage ID

**mappings** `object[]`

Optional scope/channel/locale mappings. This is not the storage field value-composer configuration.

**Fields**

**scopeId** `string` *required*

Project scope ID

**channelId** `string` *required*

Integration channel ID

**locales** `object[]`

Locale to integration translation mappings for this scope and channel. Leave empty when the scope has no locale mappings.

**Fields**

**localeId** `string` *required*

Project locale ID

**translationId** `string` *required*

Integration translation ID

#### `get_data_sync`

Get a single data sync with full field-level detail including value-composer configurations

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

**dataSyncId** `string` *required*

Data sync ID

#### `update_data_sync_value_configs`

Update data sync value composer field configurations by field ID

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

**dataSyncId** `string` *required*

Data sync ID

**fieldUpdates** `object[]` *required*

List of field-level config replacements. Each entry replaces one target field config by fieldId, without requiring the caller to pass all data sync fields.

**Fields**

**fieldId** `string` *required*

Storage field UUID from get\_data\_sync.storage.fields\[].id (supports nested composite fields).

**config** `object` *required*

Full replacement config for this field only. Valid examples: \{"source":"data-field","field":"name"}, \{"source":"static","value":"Default"}, \{"source":"composed","composition":\{"type":"object","properties":\{"label":\{"source":"data-field","field":"manufacturer.name"}}}}.

### Value Composer

#### `list_composer_operations`

List all available value-composer operations with type, input/output shapes, and documentation

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

#### `preview_composer_value`

Preview a computed value by running a single value-composer config against a sample record (dry-run)

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

**config** `object` *required*

Value-composer config object. Common valid examples: \{"source":"data-field","field":"name"}, \{"source":"static","value":"Default"}, \{"source":"composed","composition":\{"type":"object","properties":\{"label":\{"source":"data-field","field":"manufacturer.name"}}}}. Use list\_composer\_operations to discover operation-specific composition schemas.

**record** `object` *required*

Sample input record payload used during the dry run. You can source realistic examples from search\_feed\_records or search\_storage\_records.

**debug** `boolean` (default: false)

Include intermediate transformation steps in the response for troubleshooting composition chains. Useful when a multi-step composition produces unexpected results and you need to see which operation went wrong.

#### `preview_composer_record`

Preview a full transformed record by running all storage-field mapping configs against a sample source record

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

**storageId** `string` *required*

Storage ID

**recordConfig** `object` *required*

Object mapping storage field names/keys to value-composer configs, e.g. \{"title":\{"source":"data-field","field":"name"},"seoTitle":\{"source":"static","value":"Fallback"},"manufacturer":\{"source":"composed","composition":\{"type":"object","properties":\{"label":\{"source":"data-field","field":"manufacturer.name"}}}}}.

**record** `object` *required*

Sample source record payload for the dry run. Prefer realistic records from search\_feed\_records or search\_storage\_records.

**debug** `boolean` (default: false)

Include intermediate transformation steps in the response for troubleshooting composition chains. Useful when a multi-step composition produces unexpected results and you need to see which operation went wrong.

### Context Documents <sup>Plus</sup>

> [!NOTE]
>
> Context document tools are part of **Frontic Studio**, available on the **Plus plan**.

Manage skills, rules, commands, guides, and other context documents that provide instructions and knowledge to AI agents working with your project.

#### `list_context_documents`

List all active documents in a collection (`skills`, `rules`, `commands`, `guides`)

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

**collection** `enum` *required*

Document collection
One of: `skills`, `rules`, `commands`, `guides`

#### `get_context_document`

Fetch a single document by key, returning full markdown with YAML frontmatter

**Parameters**

**key** `string` *required*

Document key in format "collection/slug"

**projectId** `string` *required*

Project ID in which the resource exists.

#### `create_context_document`

Creates the document as a draft unless `activate` is true, which publishes it in the same call.

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

**collection** `enum` *required*

Document collection
One of: `skills`, `rules`, `commands`, `guides`

**title** `string` *required*

Document title

**description** `string` *required*

Document description

**content** `string`

Initial document content in markdown format

**activate** `boolean`

Set to true to make this document active immediately. When false or omitted, the document starts as a draft.

#### `update_context_document`

Update a document's metadata and/or content

**Parameters**

**key** `string` *required*

Document key in format "collection/slug"

**projectId** `string` *required*

Project ID in which the resource exists.

**title** `string`

New document title

**description** `string`

New document description

**content** `string`

New document content in markdown format

**status** `enum`

Set the document status. "active" makes it available to agents, "draft" hides it, "inactive" disables it. Omit to keep the current status unchanged.
One of: `active`, `draft`, `inactive`

### Shopware Insights

Read the store behind a project that has a Shopware integration configured. Both tools are read-only.

#### `list_shopware_promotions`

List active promotions with their discounts and validity window (`validFrom`/`validUntil`, ISO-8601, `null` = unbounded)

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.

#### `list_shopware_sales_channels`

List sales channels with their configuration, theme configuration, languages, and currencies

**Parameters**

**projectId** `string` *required*

Project ID in which the resource exists.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.