From cf06ab50b637bf236d5e5d8bef62583d46e17516 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 12:37:23 +0200 Subject: [PATCH 01/51] Add MCP server feature page and reorganize AI section Co-Authored-By: Claude Opus 4.6 (1M context) --- docusaurus/docs/cms/ai/docs-mcp-server.md | 81 +++++ .../docs/cms/ai/for-content-managers.md | 24 +- docusaurus/docs/cms/ai/for-developers.md | 70 +---- docusaurus/docs/cms/features/mcp-server.md | 277 ++++++++++++++++++ 4 files changed, 382 insertions(+), 70 deletions(-) create mode 100644 docusaurus/docs/cms/ai/docs-mcp-server.md create mode 100644 docusaurus/docs/cms/features/mcp-server.md diff --git a/docusaurus/docs/cms/ai/docs-mcp-server.md b/docusaurus/docs/cms/ai/docs-mcp-server.md new file mode 100644 index 0000000000..0b57dddd5e --- /dev/null +++ b/docusaurus/docs/cms/ai/docs-mcp-server.md @@ -0,0 +1,81 @@ +--- +title: Docs MCP server +description: Connect an MCP server for the Strapi documentation to your IDE for Strapi-aware code suggestions and answers. +sidebar_label: Docs MCP server +displayed_sidebar: cmsSidebar +tags: + - ai + - MCP + - developer tools +toc_max_heading_level: 3 +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Docs MCP server + +A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for the documentation is available. The Docs MCP server exposes the Strapi documentation to AI coding tools. Connect it to your IDE to get Strapi-aware code suggestions and answers directly in your development environment. + +## Compatible tools + +The MCP server works with any tool that supports the MCP protocol, including: + +- [Cursor](https://cursor.com) +- [VS Code](https://code.visualstudio.com) with GitHub Copilot +- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) +- [Windsurf](https://codeium.com/windsurf) +- Any other MCP-compatible IDE or tool + +## Connection details + +When opening the Ask AI window, you should see a **Use MCP** dropdown in the top right corner. Click on it and choose which tool you'd like to connect: + + + +If manual MCP server configuration is required: + +1. Click the **Copy MCP URL** from the dropdown. The server URL should be: `https://strapi-docs.mcp.kapa.ai` +2. Update the MCP server configuration in your IDE: + + + + + Add to your `.cursor/mcp.json` file: + + ```json title=".cursor/mcp.json" + { + "mcpServers": { + "strapi-docs": { + "url": "https://strapi-docs.mcp.kapa.ai" + } + } + } + ``` + + + + + Add to your `.vscode/mcp.json` file: + + ```json title=".vscode/mcp.json" + { + "servers": { + "strapi-docs": { + "type": "http", + "url": "https://strapi-docs.mcp.kapa.ai" + } + } + } + ``` + + + + +Once connected, your AI coding assistant can query the Strapi documentation directly to answer questions, suggest implementations, and verify API usage. diff --git a/docusaurus/docs/cms/ai/for-content-managers.md b/docusaurus/docs/cms/ai/for-content-managers.md index 8869f65d23..7bb74666b5 100644 --- a/docusaurus/docs/cms/ai/for-content-managers.md +++ b/docusaurus/docs/cms/ai/for-content-managers.md @@ -1,11 +1,12 @@ --- -title: Strapi AI for content managers -description: Learn about AI-powered features in the Strapi admin panel, such as content-type design, automatic translations, and media metadata generation. +title: AI for content managers +description: Learn about AI-powered features in the Strapi admin panel and the built-in MCP server that lets AI clients manage your content. sidebar_label: AI for content managers displayed_sidebar: cmsSidebar tags: - ai - features +- MCP - Content-Type Builder - Internationalization (i18n) - Media Library @@ -15,13 +16,17 @@ toc_max_heading_level: 3 import StrapiAiCredits from '/docs/snippets/strapi-ai-credits.md' -# Strapi AI for content management +# AI for content managers + +This page covers the AI-powered capabilities available to content managers in Strapi: the Strapi AI features built into the admin panel, and the MCP server that lets AI clients manage your content. + +## Strapi AI Some Strapi CMS features can be enhanced with Strapi AI, helping content managers and administrators design content structures, translate content automatically, and generate asset metadata, all from the admin panel. -## Activation and configuration {#activation} +### Activation and configuration {#activation} Strapi AI is available for Growth plan users since Strapi 5.30 and works with both Strapi Cloud and self-hosted deployments. To get started: @@ -42,14 +47,15 @@ module.exports = { See [Admin panel configuration > Strapi AI](/cms/configurations/admin-panel#strapi-ai) for all configuration options. -## Available features {#features} +### Available features {#features} | Feature | Description | |---------|-------------| | [Content-Type Builder](/cms/features/content-type-builder#strapi-ai) | AI chat assistant that helps design content-type structures, explain existing schemas, and plan data models. Uses your existing content types as context. | | [Internationalization](/cms/features/internationalization#ai-powered-internationalization) | Automatically translates content from the default locale to all other configured locales when you save an entry. | | [Media Library](/cms/features/media-library#ai-powered-metadata-generation) | Generates alternative text, captions, and descriptions for uploaded images. | -## Credits and data handling {#credits} + +### Credits and data handling {#credits} Strapi AI features consume AI credits. @@ -58,3 +64,9 @@ Strapi AI features consume AI credits. All AI requests are processed through Strapi-managed infrastructure. Content is only used temporarily during each request and is not stored outside your instance. Strapi AI follows the same GDPR-aligned framework as Strapi Cloud. See [Usage information > Strapi AI data handling](/cms/usage-information#strapi-ai-data-handling) for more details. + +## Strapi MCP server + +Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that lets AI clients like Claude, Cursor, or any MCP-compatible tool manage your content through natural language. Once enabled and connected, an AI assistant can create, read, update, delete, publish, and unpublish entries directly through Strapi's Content Manager -- all gated by admin token permissions. + + diff --git a/docusaurus/docs/cms/ai/for-developers.md b/docusaurus/docs/cms/ai/for-developers.md index 90354ae4e6..f5fcf4ec07 100644 --- a/docusaurus/docs/cms/ai/for-developers.md +++ b/docusaurus/docs/cms/ai/for-developers.md @@ -104,72 +104,14 @@ This is particularly useful for understanding configuration examples, API respon - **`llms-full.txt`**: Use this when you need the AI to have access to the complete documentation content. This is a large file; make sure your model's context window can handle it. - **`llms-code.txt`**: Use this when you're working on code and want to give an AI all of Strapi's documented code examples. Each snippet includes the source page URL and anchor for traceability. -## Docs MCP server {#docs-mcp} +## MCP servers {#mcp} -A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for the documentation is available. The Docs MCP server exposes the Strapi documentation to AI coding tools. Connect it to your IDE to get Strapi-aware code suggestions and answers directly in your development environment. +The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard that lets AI tools interact with external services. Two MCP servers are available for Strapi: -### Compatible tools - -The MCP server works with any tool that supports the MCP protocol, including: - -- [Cursor](https://cursor.com) -- [VS Code](https://code.visualstudio.com) with GitHub Copilot -- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) -- [Windsurf](https://codeium.com/windsurf) -- Any other MCP-compatible IDE or tool - -### Connection details - -When opening the Ask AI window, you should see a **Use MCP** dropdown in the top right corner. Click on it and choose which tool you'd like to connect: - - - -If manual MCP server configuration is required: - -1. Click the **Copy MCP URL** from the dropdown. The server URL should be: `https://strapi-docs.mcp.kapa.ai` -2. Update the MCP server configuration in your IDE: - - - - - Add to your `.cursor/mcp.json` file: - - ```json title=".cursor/mcp.json" - { - "mcpServers": { - "strapi-docs": { - "url": "https://strapi-docs.mcp.kapa.ai" - } - } - } - ``` - - - - - Add to your `.vscode/mcp.json` file: - - ```json title=".vscode/mcp.json" - { - "servers": { - "strapi-docs": { - "type": "http", - "url": "https://strapi-docs.mcp.kapa.ai" - } - } - } - ``` - - - - -Once connected, your AI coding assistant can query the Strapi documentation directly to answer questions, suggest implementations, and verify API usage. + + + + ## Tips for better results {#tips} diff --git a/docusaurus/docs/cms/features/mcp-server.md b/docusaurus/docs/cms/features/mcp-server.md new file mode 100644 index 0000000000..e451f3f659 --- /dev/null +++ b/docusaurus/docs/cms/features/mcp-server.md @@ -0,0 +1,277 @@ +--- +title: MCP server +description: Strapi includes a built-in MCP server that exposes content management tools to AI clients like Claude, Cursor, or any MCP-compatible tool. +sidebar_label: MCP server +displayed_sidebar: cmsSidebar +tags: + - ai + - MCP + - content management + - API +toc_max_heading_level: 3 +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# MCP server + + + +Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server. Once enabled, it lets AI clients (Claude Desktop, Claude Code, Cursor, etc.) create, read, update, delete, publish, and unpublish your content directly through Strapi's Content Manager -- all gated by admin token permissions. + + + +The MCP server exposes a set of **tools** that map to your content types. An AI assistant connected to the MCP server can, for example, create a blog article, list recent entries, or publish a page -- all through natural language prompts. Which tools are available depends on the permissions granted to the admin token used for authentication. + +:::note +The MCP server is an experimental feature. It requires the `adminTokens` feature flag and a Strapi version that includes MCP support. +::: + + + + + + + + +## Configuration + +Enabling the MCP server requires two steps: turning on the `adminTokens` feature flag and enabling MCP in the server configuration. + +### Enable the feature flag + +The MCP server relies on Strapi's admin tokens feature. Enable it in the `config/features` configuration file: + + + + +```js title="config/features.js" +module.exports = { + future: { + adminTokens: true, + }, +}; +``` + + + + +```ts title="config/features.ts" +export default { + future: { + adminTokens: true, + }, +}; +``` + + + + +### Enable the MCP server + +Add the `mcp` key to the server configuration file: + + + + +```js title="config/server.js" +module.exports = ({ env }) => ({ + host: env('HOST', '0.0.0.0'), + port: env.int('PORT', 1337), + app: { + keys: env.array('APP_KEYS'), + }, + mcp: { + enabled: true, + }, +}); +``` + + + + +```ts title="config/server.ts" +import type { Core } from '@strapi/strapi'; + +const config = ({ env }: Core.Config.Shared.ConfigParams): Core.Config.Server => ({ + host: env('HOST', '0.0.0.0'), + port: env.int('PORT', 1337), + app: { + keys: env.array('APP_KEYS'), + }, + mcp: { + enabled: true, + }, +}); +export default config; +``` + + + + +Once both settings are in place, restart Strapi. The MCP endpoint becomes available at `/mcp` on your Strapi server (e.g., `http://localhost:1337/mcp`). + +## Authentication + +The MCP server authenticates requests using **admin API tokens**. Each MCP session is scoped to the permissions of the token used to connect. + +To create an admin token: + +1. In the Strapi admin panel, go to *Settings > API Tokens*. +2. Click **Create new API Token**. +3. Choose **Admin** as the token type. +4. Select the content types and actions (read, create, update, delete, publish) you want the AI client to access. +5. Save the token and copy it -- it will not be shown again. + +The token's permissions determine which MCP tools are exposed to the AI client. For instance, if the token only grants `read` on `Article`, the AI client will only see listing and reading tools for articles -- no create, update, delete, or publish tools. + +:::caution +Treat admin tokens like passwords. Do not commit them to version control or share them publicly. Use environment variables when possible. +::: + +## Connecting an AI client + +The MCP server uses the **Streamable HTTP** transport protocol. Any MCP-compatible client can connect by pointing to the `/mcp` endpoint with a `Bearer` token in the `Authorization` header. + +### Claude Desktop + +Open Claude Desktop's configuration file: + +- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` +- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` + +You can also open this file from Claude's Settings > Developer (click the Edit Config button). + +Add the Strapi MCP server to the configuration: + +```json title="claude_desktop_config.json" +{ + "mcpServers": { + "strapi-mcp": { + "type": "streamable-http", + "url": "http://localhost:1337/mcp", + "headers": { + "Authorization": "Bearer YOUR_ADMIN_TOKEN" + } + } + } +} +``` + +Restart Claude Desktop for the changes to take effect. + +### Claude Code + +Run the following command, replacing `YOUR_ADMIN_TOKEN` with the token created earlier: + +```bash +claude mcp add strapi-mcp --transport http http://localhost:1337/mcp -H "Authorization: Bearer YOUR_ADMIN_TOKEN" +``` + +Restart Claude Code, then run `/mcp` to confirm `strapi-mcp` reports as connected. + +### Cursor + +Add the server to your `.cursor/mcp.json` file: + +```json title=".cursor/mcp.json" +{ + "mcpServers": { + "strapi-mcp": { + "type": "streamable-http", + "url": "http://localhost:1337/mcp", + "headers": { + "Authorization": "Bearer YOUR_ADMIN_TOKEN" + } + } + } +} +``` + +### Other MCP clients + +Any client that supports the MCP Streamable HTTP transport can connect. The generic configuration is: + +| Setting | Value | +|---------|-------| +| Transport type | `streamable-http` | +| URL | `http://localhost:1337/mcp` (adjust host and port to your Strapi instance) | +| Authorization header | `Bearer YOUR_ADMIN_TOKEN` | + +## Available tools + +Once connected, the AI client receives a set of **content management tools** derived from your content types. The tools available depend on the admin token's permissions. + +### Tools per content type + +For each content type the token has access to, Strapi generates up to 8 tools: + +| Tool | Action | Permission required | Description | +|------|--------|-------------------|-------------| +| `list` | Read | `read` | List entries with pagination, sorting, and filtering | +| `get` | Read | `read` | Get a single entry by document ID | +| `create` | Create | `create` | Create a new entry (created as draft if Draft & Publish is enabled) | +| `update` | Update | `update` | Update an existing entry by document ID | +| `delete` | Delete | `delete` | Delete an entry by document ID | +| `publish` | Publish | `publish` | Publish a draft entry | +| `unpublish` | Unpublish | `publish` | Unpublish a published entry | +| `discard_draft` | Discard draft | `publish` | Discard draft changes and revert to the published version | + +The last 3 tools (publish, unpublish, discard_draft) are only generated for content types that have [Draft & Publish](/cms/features/draft-and-publish) enabled. + +Tool names follow the pattern `cm___`. For example, an `Article` content type with UID `api::article.article` generates tools named `cm_api_article_list`, `cm_api_article_get`, `cm_api_article_create`, etc. + +Single types follow a similar pattern but include `_single_` in the name (e.g., `cm_api_homepage_single_get`). + +### Input schemas + +Each tool has an input schema derived from your content type's attributes. The schema is dynamically adjusted per session based on the token's permissions: + +- **Field-level permissions**: If the token restricts access to certain fields, those fields are excluded from both input and output schemas. +- **Locale-level permissions**: If the token restricts access to certain locales, the `locale` parameter only accepts permitted locales. +- **Write operations**: The `data` object only includes fields the token has permission to write. Unknown fields are rejected. + +For the `list` tool, the input schema also includes parameters for pagination (`page`, `pageSize`), sorting (`sort`), and filtering (`filters`). + +### Example prompts + +Once connected, you can interact with your Strapi content using natural language: + +| Prompt | What happens | +|--------|-------------| +| "Create a new article titled 'Hello World' with body 'First post'." | Creates a draft article entry | +| "List the 5 most recent articles." | Returns paginated list, newest first | +| "Show me article with ID abc123." | Returns the full entry | +| "Update article abc123 -- change the title to 'Hello Strapi'." | Updates the title, other fields untouched | +| "Publish article abc123." | Flips the entry status to published | +| "Delete article abc123." | Removes the entry | + +## Permission boundaries + +The MCP server enforces the same permission model as the Strapi admin panel. Permissions are checked at two levels: + +1. **Tool visibility**: When an AI client connects, Strapi checks the admin token's permissions and only exposes tools the token has access to. If the token does not grant `delete` on `Article`, the AI client will not see a delete tool for articles at all. + +2. **Field and locale filtering**: Even within an exposed tool, input and output schemas are narrowed to the fields and locales the token can access. If the token grants `read` on `Article` but excludes the `body` field, the AI client will not see or receive `body` content. + +This means you can create tokens with fine-grained access: + +- A "read-only" token that only exposes listing and reading tools +- A token scoped to specific content types (e.g., articles but not categories) +- A token restricted to specific fields or locales +- A token with condition-based permissions (e.g., only update entries you own) + +:::tip +Create dedicated admin tokens for each AI client or use case. Use the most restrictive permissions that still allow the AI to accomplish its task. +::: + +## Known limitations + +The MCP server is experimental and has the following limitations: + +- **Block content**: Rich text block content is not represented in tool definitions. +- **Components**: Component fields are passed as untyped (`any`) in tool schemas. +- **Dynamic zones**: Dynamic zone fields are passed as untyped arrays in tool schemas. +- **Nested population parameters**: The `list` and `get` tools do not support nested population parameters for relations. +- **Stateless sessions**: Each MCP request creates a new server instance. There is no session persistence between requests. From a5ccd577bb1408c85adb73b31581557e8a1f8f0a Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 12:39:58 +0200 Subject: [PATCH 02/51] Use small cards for MCP server references Co-Authored-By: Claude Opus 4.6 (1M context) --- docusaurus/docs/cms/ai/for-content-managers.md | 2 +- docusaurus/docs/cms/ai/for-developers.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docusaurus/docs/cms/ai/for-content-managers.md b/docusaurus/docs/cms/ai/for-content-managers.md index 7bb74666b5..fa45976a1d 100644 --- a/docusaurus/docs/cms/ai/for-content-managers.md +++ b/docusaurus/docs/cms/ai/for-content-managers.md @@ -69,4 +69,4 @@ All AI requests are processed through Strapi-managed infrastructure. Content is Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that lets AI clients like Claude, Cursor, or any MCP-compatible tool manage your content through natural language. Once enabled and connected, an AI assistant can create, read, update, delete, publish, and unpublish entries directly through Strapi's Content Manager -- all gated by admin token permissions. - + diff --git a/docusaurus/docs/cms/ai/for-developers.md b/docusaurus/docs/cms/ai/for-developers.md index f5fcf4ec07..74376676b0 100644 --- a/docusaurus/docs/cms/ai/for-developers.md +++ b/docusaurus/docs/cms/ai/for-developers.md @@ -109,8 +109,8 @@ This is particularly useful for understanding configuration examples, API respon The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard that lets AI tools interact with external services. Two MCP servers are available for Strapi: - - + + ## Tips for better results {#tips} From c3dd43495350e4692038610a249dd69d8ee6ade6 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 12:41:21 +0200 Subject: [PATCH 03/51] Use standard cards with description for MCP server references Co-Authored-By: Claude Opus 4.6 (1M context) --- docusaurus/docs/cms/ai/for-content-managers.md | 2 +- docusaurus/docs/cms/ai/for-developers.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docusaurus/docs/cms/ai/for-content-managers.md b/docusaurus/docs/cms/ai/for-content-managers.md index fa45976a1d..6d94e802b2 100644 --- a/docusaurus/docs/cms/ai/for-content-managers.md +++ b/docusaurus/docs/cms/ai/for-content-managers.md @@ -69,4 +69,4 @@ All AI requests are processed through Strapi-managed infrastructure. Content is Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that lets AI clients like Claude, Cursor, or any MCP-compatible tool manage your content through natural language. Once enabled and connected, an AI assistant can create, read, update, delete, publish, and unpublish entries directly through Strapi's Content Manager -- all gated by admin token permissions. - + diff --git a/docusaurus/docs/cms/ai/for-developers.md b/docusaurus/docs/cms/ai/for-developers.md index 74376676b0..eda302cbb2 100644 --- a/docusaurus/docs/cms/ai/for-developers.md +++ b/docusaurus/docs/cms/ai/for-developers.md @@ -109,8 +109,8 @@ This is particularly useful for understanding configuration examples, API respon The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard that lets AI tools interact with external services. Two MCP servers are available for Strapi: - - + + ## Tips for better results {#tips} From 6e74b40c0b4eaf56e07dd1093e7cdc1a3df2c785 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 12:46:11 +0200 Subject: [PATCH 04/51] Clarify Docs MCP server reference in tips section Co-Authored-By: Claude Opus 4.6 (1M context) --- docusaurus/docs/cms/ai/for-developers.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/docusaurus/docs/cms/ai/for-developers.md b/docusaurus/docs/cms/ai/for-developers.md index eda302cbb2..516eb7172e 100644 --- a/docusaurus/docs/cms/ai/for-developers.md +++ b/docusaurus/docs/cms/ai/for-developers.md @@ -104,6 +104,15 @@ This is particularly useful for understanding configuration examples, API respon - **`llms-full.txt`**: Use this when you need the AI to have access to the complete documentation content. This is a large file; make sure your model's context window can handle it. - **`llms-code.txt`**: Use this when you're working on code and want to give an AI all of Strapi's documented code examples. Each snippet includes the source page URL and anchor for traceability. +## Tips for better results {#tips} + +The following tips will help you fine-tune your prompts to get the best results: +- Include the page URL so the assistant grounds its answer in the right context. +- Mention your Strapi version (e.g., Strapi 5) to avoid outdated suggestions. +- Pair code examples with their source page when sharing snippets from `llms-code.txt`. +- Prefer documented APIs over private internals when asking for code generation. +- Use the [Docs MCP server](/cms/ai/docs-mcp-server) in your IDE for the fastest developer experience. For docs-related questions, start your prompts with "Use the Docs MCP server to answer this question: " + ## MCP servers {#mcp} The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard that lets AI tools interact with external services. Two MCP servers are available for Strapi: @@ -113,10 +122,4 @@ The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open s -## Tips for better results {#tips} -- Include the page URL so the assistant grounds its answer in the right context. -- Mention your Strapi version (e.g., Strapi 5) to avoid outdated suggestions. -- Pair code examples with their source page when sharing snippets from `llms-code.txt`. -- Prefer documented APIs over private internals when asking for code generation. -- Use the MCP server in your IDE for the fastest developer experience. From 08dce3d2a0acf450216ef215492bc3c9fb5c7b51 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 12:58:00 +0200 Subject: [PATCH 05/51] Rewrite MCP server page following feature template Co-Authored-By: Claude Opus 4.6 (1M context) --- .../docs/cms/features/strapi-mcp-server.md | 240 ++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 docusaurus/docs/cms/features/strapi-mcp-server.md diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md new file mode 100644 index 0000000000..ef4f362f43 --- /dev/null +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -0,0 +1,240 @@ +--- +title: MCP server +displayed_sidebar: cmsSidebar +description: Expose content management tools to AI clients through a built-in MCP server. +tags: + - features + - ai + - MCP + - content management +toc_max_heading_level: 3 +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# MCP server + + + + +Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server. Once enabled, it lets AI clients create, read, update, delete, publish, and unpublish content directly through Strapi's Content Manager. All operations are gated by admin token permissions. + + + +The MCP server exposes a set of content management tools to AI clients such as Claude Desktop, Claude Code, Cursor, or any MCP-compatible tool. An AI assistant connected to the MCP server can, for example, create a blog article, list recent entries, or publish a page. Which tools are available depends on the permissions granted to the admin token used for authentication. + + + Free feature + Admin (token creator) + Server configuration + Available in both Development & Production environment + + +## Configuration + +The MCP server is configured through the server configuration file and authenticated with admin API tokens created in the admin panel. + +### Code-based configuration + +Enable the MCP server by adding the `mcp` key to the server configuration file: + + + + +```js title="config/server.js" +module.exports = ({ env }) => ({ + host: env('HOST', '0.0.0.0'), + port: env.int('PORT', 1337), + app: { + keys: env.array('APP_KEYS'), + }, + mcp: { + enabled: true, + }, +}); +``` + + + + +```ts title="config/server.ts" +import type { Core } from '@strapi/strapi'; + +const config = ({ env }: Core.Config.Shared.ConfigParams): Core.Config.Server => ({ + host: env('HOST', '0.0.0.0'), + port: env.int('PORT', 1337), + app: { + keys: env.array('APP_KEYS'), + }, + mcp: { + enabled: true, + }, +}); +export default config; +``` + + + + +Once the setting is in place, restart Strapi. The MCP endpoint becomes available at `/mcp` on your Strapi server (e.g., `http://localhost:1337/mcp`). + +### Admin panel configuration + +The MCP server authenticates requests using admin API tokens. Each MCP session is scoped to the permissions of the token used to connect. + +To create an admin token for MCP access: + +1. In the Strapi admin panel, go to *Settings > API Tokens*. +2. Click **Create new API Token**. +3. Choose **Admin** as the token type. +4. Select the content types and actions (read, create, update, delete, publish) you want the AI client to access. +5. Save the token and copy it. It will not be shown again. + +The token's permissions determine which MCP tools are exposed to the AI client. For instance, if the token only grants `read` on `Article`, the AI client will only see listing and reading tools for articles. + +:::caution +Treat admin tokens like passwords. Do not commit them to version control or share them publicly. Use environment variables when possible. +::: + +## Usage + +The MCP server uses the Streamable HTTP transport protocol. Any MCP-compatible client can connect by pointing to the `/mcp` endpoint with a `Bearer` token in the `Authorization` header. Once connected, the AI client can interact with your Strapi content using natural language prompts. + +### Connecting Claude Desktop + +Open Claude Desktop's configuration file: + +- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` +- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` + +You can also open this file from Claude's Settings > Developer (click the Edit Config button). + +Add the Strapi MCP server to the configuration: + +```json title="claude_desktop_config.json" +{ + "mcpServers": { + "strapi-mcp": { + "type": "streamable-http", + "url": "http://localhost:1337/mcp", + "headers": { + "Authorization": "Bearer YOUR_ADMIN_TOKEN" + } + } + } +} +``` + +Restart Claude Desktop for the changes to take effect. + +### Connecting Claude Code + +Run the following command, replacing `YOUR_ADMIN_TOKEN` with the token created earlier: + +```bash +claude mcp add strapi-mcp --transport http http://localhost:1337/mcp -H "Authorization: Bearer YOUR_ADMIN_TOKEN" +``` + +Restart Claude Code, then run `/mcp` to confirm `strapi-mcp` reports as connected. + +### Connecting Cursor + +Add the server to your `.cursor/mcp.json` file: + +```json title=".cursor/mcp.json" +{ + "mcpServers": { + "strapi-mcp": { + "type": "streamable-http", + "url": "http://localhost:1337/mcp", + "headers": { + "Authorization": "Bearer YOUR_ADMIN_TOKEN" + } + } + } +} +``` + +### Connecting other MCP clients + +Any client that supports the MCP Streamable HTTP transport can connect. The generic configuration is: + +| Setting | Value | +|---------|-------| +| Transport type | `streamable-http` | +| URL | `http://localhost:1337/mcp` (adjust host and port to your Strapi instance) | +| Authorization header | `Bearer YOUR_ADMIN_TOKEN` | + +### Available tools + +For each content type the token has access to, Strapi generates up to 8 tools: + +| Tool | Action | Permission required | Description | +|------|--------|-------------------|-------------| +| `list` | Read | `read` | List entries with pagination, sorting, and filtering | +| `get` | Read | `read` | Get a single entry by document ID | +| `create` | Create | `create` | Create a new entry (created as draft if Draft & Publish is enabled) | +| `update` | Update | `update` | Update an existing entry by document ID | +| `delete` | Delete | `delete` | Delete an entry by document ID | +| `publish` | Publish | `publish` | Publish a draft entry | +| `unpublish` | Unpublish | `publish` | Unpublish a published entry | +| `discard_draft` | Discard draft | `publish` | Discard draft changes and revert to the published version | + +The last 3 tools (publish, unpublish, discard_draft) are only generated for content types that have [Draft & Publish](/cms/features/draft-and-publish) enabled. + +Tool names follow the pattern `cm___`. For example, an `Article` content type with UID `api::article.article` generates tools named `cm_api_article_list`, `cm_api_article_get`, `cm_api_article_create`, etc. + +Single types follow a similar pattern but include `_single_` in the name (e.g., `cm_api_homepage_single_get`). + +### Managing content through prompts + +Once connected, you can interact with your Strapi content using natural language: + +| Prompt | What happens | +|--------|-------------| +| "Create a new article titled 'Hello World' with body 'First post'." | Creates a draft article entry | +| "List the 5 most recent articles." | Returns paginated list, newest first | +| "Show me article with ID abc123." | Returns the full entry | +| "Update article abc123, change the title to 'Hello Strapi'." | Updates the title, other fields untouched | +| "Publish article abc123." | Flips the entry status to published | +| "Delete article abc123." | Removes the entry | + +### Understanding input schemas + +Each tool has an input schema derived from your content type's attributes. The schema is dynamically adjusted per session based on the token's permissions: + +- **Field-level permissions**: If the token restricts access to certain fields, those fields are excluded from both input and output schemas. +- **Locale-level permissions**: If the token restricts access to certain locales, the `locale` parameter only accepts permitted locales. +- **Write operations**: The `data` object only includes fields the token has permission to write. Unknown fields are rejected. + +For the `list` tool, the input schema also includes parameters for pagination (`page`, `pageSize`), sorting (`sort`), and filtering (`filters`). + +### Permission boundaries + +The MCP server enforces the same permission model as the Strapi admin panel. Permissions are checked at two levels: + +1. **Tool visibility**: When an AI client connects, Strapi checks the admin token's permissions and only exposes tools the token has access to. If the token does not grant `delete` on `Article`, the AI client will not see a delete tool for articles at all. + +2. **Field and locale filtering**: Even within an exposed tool, input and output schemas are narrowed to the fields and locales the token can access. If the token grants `read` on `Article` but excludes the `body` field, the AI client will not see or receive `body` content. + +This means you can create tokens with fine-grained access: + +- A "read-only" token that only exposes listing and reading tools +- A token scoped to specific content types (e.g., articles but not categories) +- A token restricted to specific fields or locales +- A token with condition-based permissions (e.g., only update entries you own) + +:::tip +Create dedicated admin tokens for each AI client or use case. Use the most restrictive permissions that still allow the AI to accomplish its task. +::: + +## Known limitations + +The MCP server has the following limitations: + +- **Block content**: Rich text block content is not represented in tool definitions. +- **Components**: Component fields are passed as untyped (`any`) in tool schemas. +- **Dynamic zones**: Dynamic zone fields are passed as untyped arrays in tool schemas. +- **Nested population parameters**: The `list` and `get` tools do not support nested population parameters for relations. +- **Stateless sessions**: Each MCP request creates a new server instance. There is no session persistence between requests. From 8d93df424605e3a78c2f40309414a20c37accafb Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 13:02:17 +0200 Subject: [PATCH 06/51] Add MCP server and Docs MCP server to sidebar Co-Authored-By: Claude Opus 4.6 (1M context) --- docusaurus/sidebars.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docusaurus/sidebars.js b/docusaurus/sidebars.js index 431e089361..8c3591f602 100644 --- a/docusaurus/sidebars.js +++ b/docusaurus/sidebars.js @@ -92,6 +92,14 @@ const sidebars = { label: 'Media Library', id: 'cms/features/media-library', }, + { + type: 'doc', + label: 'MCP server', + id: 'cms/features/strapi-mcp-server', + customProps: { + new: true, + }, + }, { type: 'doc', label: 'Preview', @@ -171,6 +179,14 @@ const sidebars = { new: true, }, }, + { + type: 'doc', + label: 'Docs MCP server', + id: 'cms/ai/docs-mcp-server', + customProps: { + new: true, + }, + }, ], }, { // APIs From ac5fcf3caa4a8723e6073aeabc69c282cd7ff662 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 13:04:33 +0200 Subject: [PATCH 07/51] Remove adminTokens feature flag references Admin tokens are no longer behind a future flag. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../docs/cms/configurations/features.md | 19 +++++++++---------- docusaurus/docs/cms/features/admin-tokens.md | 4 +--- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/docusaurus/docs/cms/configurations/features.md b/docusaurus/docs/cms/configurations/features.md index 9fc6f0c355..52c43ff21b 100644 --- a/docusaurus/docs/cms/configurations/features.md +++ b/docusaurus/docs/cms/configurations/features.md @@ -35,16 +35,16 @@ To enable a future flag: 1. (_optional_) If the server is running, stop it with `Ctrl-C`. 2. Open the `config/features.js|ts` file or create it if the file does not exist yet. The file will export a `future` object with all the future flags to enable. -3. To enable a future flag, add its property name (see [full list](#available-future-flags)) to the `future` object and ensure the property's value is set to `true`. The following example shows how to enable the `adminTokens` future flag: +3. To enable a future flag, add its property name (see [full list](#available-future-flags)) to the `future` object and ensure the property's value is set to `true`. The following example shows how to enable the `experimental_firstPublishedAt` future flag: - ```ts title="/config/features.ts" + ```js title="/config/features.js" module.exports = ({ env }) => ({ future: { - adminTokens: env.bool('STRAPI_FUTURE_ADMIN_TOKENS', false), + experimental_firstPublishedAt: env.bool('STRAPI_FUTURE_EXPERIMENTAL_FIRST_PUBLISHED_AT', false), }, }) @@ -53,27 +53,27 @@ To enable a future flag: This example assumes that you have an `.env` environment file at the root of your application and that the file includes the following line: ```json title=".env" - STRAPI_FUTURE_ADMIN_TOKENS=true + STRAPI_FUTURE_EXPERIMENTAL_FIRST_PUBLISHED_AT=true ``` - If your environment file does not include this value, the `adminTokens` future flag property value will default to `false` and the experimental feature will not be enabled. + If your environment file does not include this value, the `experimental_firstPublishedAt` future flag property value will default to `false` and the experimental feature will not be enabled. ```ts title="/config/features.ts" - export default { + export default ({ env }) => ({ future: { - adminTokens: env.bool('STRAPI_FUTURE_ADMIN_TOKENS', false), + experimental_firstPublishedAt: env.bool('STRAPI_FUTURE_EXPERIMENTAL_FIRST_PUBLISHED_AT', false), }, - }; + }); ``` This example assumes that you have an `.env` environment file at the root of your application and that the file includes the following line: ```json title=".env" - STRAPI_FUTURE_ADMIN_TOKENS=true + STRAPI_FUTURE_EXPERIMENTAL_FIRST_PUBLISHED_AT=true ``` If your environment file does not include this value, the `experimental_firstPublishedAt` future flag property value will default to `false` and the experimental feature will not be enabled. @@ -112,5 +112,4 @@ Developers can use the following APIs to interact with future flags: | Property name | Related feature | Suggested environment variable name | | ------------- | --------------- | ---------------------------------- | | `experimental_firstPublishedAt` | [Draft & Publish](/cms/features/draft-and-publish#recording-the-first-publication-date) | `STRAPI_FUTURE_EXPERIMENTAL_FIRST_PUBLISHED_AT` | -| `adminTokens` | [Admin Tokens](/cms/features/admin-tokens) | `STRAPI_FUTURE_ADMIN_TOKENS` | diff --git a/docusaurus/docs/cms/features/admin-tokens.md b/docusaurus/docs/cms/features/admin-tokens.md index cd2bc32496..0ba1bc7fea 100644 --- a/docusaurus/docs/cms/features/admin-tokens.md +++ b/docusaurus/docs/cms/features/admin-tokens.md @@ -12,7 +12,6 @@ tags: --- # Admin Tokens - Admin tokens authenticate programmatic access to the Strapi Admin API. Each token is scoped to a subset of its owner's permissions and is designed for automation workflows such as MCP agents, CI/CD pipelines, and scripts. @@ -30,7 +29,7 @@ Admin tokens and API tokens are strictly separated: each is rejected on the othe Activated by default for Super Admin. Each lower-level role needs an explicit permission grant in Roles > Settings - Admin tokens. - Requires enabling the corresponding future flag,
see [Features configuration](/cms/configurations/features) + Available and activated by default
Available in both Development & Production environment @@ -78,7 +77,6 @@ If you're not the Strapi instance's super admin, the super admin must have grant ::: 4. Click on the **Save** button. The new Admin token will be displayed at the top of the interface, along with a copy button . - Date: Wed, 20 May 2026 18:05:49 +0200 Subject: [PATCH 08/51] WIP --- .../content/three-modes-overview.html | 197 +++++++ .../brainstorm/61754-1778237530/state/events | 14 + .../61754-1778237530/state/server-stopped | 1 + .../61754-1778237530/state/server.log | 17 + .../61754-1778237530/state/server.pid | 1 + .../plans/2026-05-07-content-width-toggle.md | 555 ++++++++++++++++++ .../specs/2026-05-08-view-modes-design.md | 211 +++++++ docusaurus/docs/cms/ai/for-developers.md | 8 +- docusaurus/docs/cms/features/mcp-server.md | 277 --------- .../docs/cms/features/strapi-mcp-server.md | 65 +- docusaurus/docs/snippets/strapi-ai-credits.md | 2 +- docusaurus/static/llms-code.txt | 149 ++++- docusaurus/static/llms-full.txt | 240 +++++++- docusaurus/static/llms.txt | 4 +- 14 files changed, 1384 insertions(+), 357 deletions(-) create mode 100644 .superpowers/brainstorm/61754-1778237530/content/three-modes-overview.html create mode 100644 .superpowers/brainstorm/61754-1778237530/state/events create mode 100644 .superpowers/brainstorm/61754-1778237530/state/server-stopped create mode 100644 .superpowers/brainstorm/61754-1778237530/state/server.log create mode 100644 .superpowers/brainstorm/61754-1778237530/state/server.pid create mode 100644 docs/superpowers/plans/2026-05-07-content-width-toggle.md create mode 100644 docs/superpowers/specs/2026-05-08-view-modes-design.md delete mode 100644 docusaurus/docs/cms/features/mcp-server.md diff --git a/.superpowers/brainstorm/61754-1778237530/content/three-modes-overview.html b/.superpowers/brainstorm/61754-1778237530/content/three-modes-overview.html new file mode 100644 index 0000000000..1f833b1d9e --- /dev/null +++ b/.superpowers/brainstorm/61754-1778237530/content/three-modes-overview.html @@ -0,0 +1,197 @@ +

Vue d'ensemble des 3 modes

+

Voici comment chaque mode transforme la page. Clique sur celui que tu veux voir en plus grand.

+ +
+ + +
+
+
+ +
+
Navigation
+
+
+
+
+
+ +
+ +
+ ELEGANT + MARKDOWN + AI +
+ +
+
+
+
+
+
+
+
+
+ +
+
Tab 1
+
Tab 2
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+

Elegant Mode

+

La doc telle qu'elle est aujourd'hui. Tous les composants visuels, tabs, cards, sidebar ouverte, WidthToggle visible.

+
+
+ + +
+
+
+ +
+
Navigation
+
+
+
+
+
+ +
+ +
+ ELEGANT + MARKDOWN + AI +
+
+
+
+
+ +
## Tab 1
+
+
+
## Tab 2
+
+
+ +
+
+
+
+
+
+
+
+

Markdown Mode

+

Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.

+
+
+ + +
+
+
+ +
+
+
+
+
+
+ +
+ +
+ ELEGANT + MARKDOWN + AI +
+ +
+
+
+
+
+
Tab 1
+
Tab 2
+
+
+
+
+
+
+ +
+
AI Assistant
+
+
Summary
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+

AI Mode

+

Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.

+
+
+ +
+ +
+

Comportements clés

+
+
+ Transitions
+ Elegant ↔ Markdown : instantané
+ AI mode : panel slide-in/out +
+
+ Persistence
+ Elegant/Markdown : localStorage
+ AI : toujours off au chargement +
+
+ Navigation
+ Changement de page en AI mode :
résumé mis à jour, chat reset +
+
+
diff --git a/.superpowers/brainstorm/61754-1778237530/state/events b/.superpowers/brainstorm/61754-1778237530/state/events new file mode 100644 index 0000000000..d7094ec9f2 --- /dev/null +++ b/.superpowers/brainstorm/61754-1778237530/state/events @@ -0,0 +1,14 @@ +{"type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Elegant Mode\n La doc telle qu'elle est aujourd'hui. Tous les composants visuels, tabs, cards, sidebar ouverte, WidthToggle visible.","choice":"elegant","id":null,"timestamp":1778238072727} +{"type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Elegant Mode\n La doc telle qu'elle est aujourd'hui. Tous les composants visuels, tabs, cards, sidebar ouverte, WidthToggle visible.","choice":"elegant","id":null,"timestamp":1778238076491} +{"type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238083463} +{"type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238084524} +{"type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238084697} +{"type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238085591} +{"type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238085751} +{"type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238087935} +{"type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238734830} +{"type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238735019} +{"type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238735706} +{"type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238737279} +{"type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238739110} +{"type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Elegant Mode\n La doc telle qu'elle est aujourd'hui. Tous les composants visuels, tabs, cards, sidebar ouverte, WidthToggle visible.","choice":"elegant","id":null,"timestamp":1778238740006} diff --git a/.superpowers/brainstorm/61754-1778237530/state/server-stopped b/.superpowers/brainstorm/61754-1778237530/state/server-stopped new file mode 100644 index 0000000000..bfa32890eb --- /dev/null +++ b/.superpowers/brainstorm/61754-1778237530/state/server-stopped @@ -0,0 +1 @@ +{"reason":"idle timeout","timestamp":1778240574260} diff --git a/.superpowers/brainstorm/61754-1778237530/state/server.log b/.superpowers/brainstorm/61754-1778237530/state/server.log new file mode 100644 index 0000000000..1cbe0ef005 --- /dev/null +++ b/.superpowers/brainstorm/61754-1778237530/state/server.log @@ -0,0 +1,17 @@ +{"type":"server-started","port":61548,"host":"127.0.0.1","url_host":"localhost","url":"http://localhost:61548","screen_dir":"/Users/piwi/code/documentation/.superpowers/brainstorm/61754-1778237530/content","state_dir":"/Users/piwi/code/documentation/.superpowers/brainstorm/61754-1778237530/state"} +{"type":"screen-added","file":"/Users/piwi/code/documentation/.superpowers/brainstorm/61754-1778237530/content/three-modes-overview.html"} +{"source":"user-event","type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Elegant Mode\n La doc telle qu'elle est aujourd'hui. Tous les composants visuels, tabs, cards, sidebar ouverte, WidthToggle visible.","choice":"elegant","id":null,"timestamp":1778238072727} +{"source":"user-event","type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Elegant Mode\n La doc telle qu'elle est aujourd'hui. Tous les composants visuels, tabs, cards, sidebar ouverte, WidthToggle visible.","choice":"elegant","id":null,"timestamp":1778238076491} +{"source":"user-event","type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238083463} +{"source":"user-event","type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238084524} +{"source":"user-event","type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238084697} +{"source":"user-event","type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238085591} +{"source":"user-event","type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238085751} +{"source":"user-event","type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238087935} +{"source":"user-event","type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238734830} +{"source":"user-event","type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238735019} +{"source":"user-event","type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238735706} +{"source":"user-event","type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238737279} +{"source":"user-event","type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238739110} +{"source":"user-event","type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Elegant Mode\n La doc telle qu'elle est aujourd'hui. Tous les composants visuels, tabs, cards, sidebar ouverte, WidthToggle visible.","choice":"elegant","id":null,"timestamp":1778238740006} +{"type":"server-stopped","reason":"idle timeout"} diff --git a/.superpowers/brainstorm/61754-1778237530/state/server.pid b/.superpowers/brainstorm/61754-1778237530/state/server.pid new file mode 100644 index 0000000000..a67c7abfdf --- /dev/null +++ b/.superpowers/brainstorm/61754-1778237530/state/server.pid @@ -0,0 +1 @@ +61765 diff --git a/docs/superpowers/plans/2026-05-07-content-width-toggle.md b/docs/superpowers/plans/2026-05-07-content-width-toggle.md new file mode 100644 index 0000000000..79b0e4f646 --- /dev/null +++ b/docs/superpowers/plans/2026-05-07-content-width-toggle.md @@ -0,0 +1,555 @@ +# Content Width Toggle Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Add a 3-position content width toggle (Default/Wide/Max) to doc pages for accessibility. + +**Architecture:** A `data-content-width` attribute on `` drives a CSS custom property `--doc-content-max-width`. An inline script prevents FOUC by reading localStorage before React hydrates. A self-contained React component manages the toggle UI. + +**Tech Stack:** React, SCSS modules, localStorage, inline SVG icons, Docusaurus swizzle (wrap) + +**Target branch:** `next` + +**Spec:** `docs/superpowers/specs/2026-05-07-content-width-toggle-design.md` + +--- + +### File Map + +| Action | File | Responsibility | +|--------|------|---------------| +| Create | `docusaurus/src/components/WidthToggle/WidthToggle.js` | Toggle component (buttons, state, localStorage, DOM attribute) | +| Create | `docusaurus/src/components/WidthToggle/widthToggle.module.scss` | Toggle styles (segmented control, dark mode) | +| Create | `docusaurus/src/theme/DocItem/Layout/index.js` | Swizzle wrap to mount WidthToggle above doc content | +| Modify | `docusaurus/src/scss/_base.scss` | Replace hardcoded max-width with CSS variable, add transition | +| Modify | `docusaurus/docusaurus.config.js` | Add anti-FOUC inline script | + +--- + +### Task 1: Switch to `next` branch + +**Files:** None + +- [ ] **Step 1: Checkout next and pull latest** + +```bash +cd /Users/piwi/code/documentation +git checkout next +git pull origin next +``` + +- [ ] **Step 2: Verify clean state** + +```bash +git status +``` + +Expected: clean working tree on `next`. + +--- + +### Task 2: Add CSS custom property for content width + +**Files:** +- Modify: `docusaurus/src/scss/_base.scss` + +- [ ] **Step 1: Add width CSS variables to `:root` block** + +In `_base.scss`, after the existing `:root` block (line 7-9), add the content width variable. Then add the `data-content-width` attribute selectors. + +Find the existing `:root` block: + +```scss +:root { + --custom-selection-background-color: var(--strapi-primary-600); +} +``` + +Replace with: + +```scss +:root { + --custom-selection-background-color: var(--strapi-primary-600); + --doc-content-max-width: 720px; +} + +[data-content-width="wide"] { + --doc-content-max-width: 960px; +} + +[data-content-width="max"] { + --doc-content-max-width: 100%; +} +``` + +- [ ] **Step 2: Replace hardcoded mobile max-width with CSS variable** + +Find the mobile rule (line 35-44): + +```scss +main { + article:first-child:not(.col):not(.custom-doc-card), + article:first-child:not(.col) + nav { + max-width: 640px; + padding-left: 0 !important; + padding-right: 0 !important; + margin-left: auto; + margin-right: auto; + } +} +``` + +Replace with: + +```scss +main { + article:first-child:not(.col):not(.custom-doc-card), + article:first-child:not(.col) + nav { + max-width: var(--doc-content-max-width); + padding-left: 0 !important; + padding-right: 0 !important; + margin-left: auto; + margin-right: auto; + transition: max-width 0.4s cubic-bezier(0.16, 1, 0.3, 1); + } +} +``` + +Note: On mobile the toggle is hidden, and `640px` was already wider than most phone screens, so using the variable (720px default) is fine -- it will be clamped by the viewport anyway. + +- [ ] **Step 3: Replace hardcoded desktop max-width values** + +Find the desktop article rule inside `@include medium-up` (lines 52-58): + +```scss + article:first-child:not(.col):not(.custom-doc-card), + article:first-child:not(.col) + nav:not(.pagination-nav) { + max-width: 720px; + padding-left: 40px !important; + padding-right: 40px !important; + } +``` + +Replace with: + +```scss + article:first-child:not(.col):not(.custom-doc-card), + article:first-child:not(.col) + nav:not(.pagination-nav) { + max-width: var(--doc-content-max-width); + padding-left: 40px !important; + padding-right: 40px !important; + } +``` + +Find the pagination-nav rule (lines 60-64): + +```scss + article:first-child:not(.col) + nav.pagination-nav { + max-width: 720px; + padding-left: 0 !important; + padding-right: 0 !important; + } +``` + +Replace with: + +```scss + article:first-child:not(.col) + nav.pagination-nav { + max-width: var(--doc-content-max-width); + padding-left: 0 !important; + padding-right: 0 !important; + } +``` + +- [ ] **Step 4: Verify the build compiles** + +```bash +cd /Users/piwi/code/documentation/docusaurus && npm run build 2>&1 | tail -5 +``` + +Expected: build succeeds. No visual change yet (default is still 720px). + +- [ ] **Step 5: Commit** + +```bash +git add docusaurus/src/scss/_base.scss +git commit -m "Add CSS custom property for doc content width" +``` + +--- + +### Task 3: Add anti-FOUC inline script + +**Files:** +- Modify: `docusaurus/docusaurus.config.js` + +- [ ] **Step 1: Add inline script to the scripts array** + +In `docusaurus.config.js`, find the end of the `scripts` array. The last entry before the closing `]` of the scripts array. Add a new entry at the **beginning** of the `scripts` array (so it runs first), right after `scripts: [`: + +Find: + +```js + scripts: [ + { + src: '/js/redirector.js', + async: false, // Load synchronously to ensure it runs before page navigation + }, +``` + +Replace with: + +```js + scripts: [ + { + // Anti-FOUC: apply saved content width before React hydrates + tagName: 'script', + innerHTML: '(function(){try{var w=localStorage.getItem("strapi-content-width");if(w)document.documentElement.dataset.contentWidth=w}catch(e){}})();', + }, + { + src: '/js/redirector.js', + async: false, // Load synchronously to ensure it runs before page navigation + }, +``` + +Note: Docusaurus `scripts` supports inline scripts via `innerHTML` + `tagName: 'script'`. This runs synchronously before any other script. + +- [ ] **Step 2: Verify the build compiles** + +```bash +cd /Users/piwi/code/documentation/docusaurus && npm run build 2>&1 | tail -5 +``` + +Expected: build succeeds. + +- [ ] **Step 3: Commit** + +```bash +git add docusaurus/docusaurus.config.js +git commit -m "Add anti-FOUC script for content width preference" +``` + +--- + +### Task 4: Create WidthToggle component + +**Files:** +- Create: `docusaurus/src/components/WidthToggle/WidthToggle.js` + +- [ ] **Step 1: Create the component file** + +```jsx +import React, { useState, useEffect, useCallback } from 'react'; +import styles from './widthToggle.module.scss'; + +const STORAGE_KEY = 'strapi-content-width'; +const WIDTHS = [ + { value: 'default', label: 'Default width', viewBox: '0 0 20 16' , + path: 'M5 1h10a2 2 0 012 2v10a2 2 0 01-2 2H5a2 2 0 01-2-2V3a2 2 0 012-2z' }, + { value: 'wide', label: 'Wide', viewBox: '0 0 20 16', + path: 'M3 1h14a2 2 0 012 2v10a2 2 0 01-2 2H3a2 2 0 01-2-2V3a2 2 0 012-2z' }, + { value: 'max', label: 'Full width', viewBox: '0 0 20 16', + path: 'M1 1h18a1 1 0 011 1v12a1 1 0 01-1 1H1a1 1 0 01-1-1V2a1 1 0 011-1z' }, +]; + +function getInitialWidth() { + if (typeof window === 'undefined') return 'default'; + try { + return localStorage.getItem(STORAGE_KEY) || 'default'; + } catch { + return 'default'; + } +} + +export default function WidthToggle() { + const [width, setWidth] = useState(getInitialWidth); + + // Sync DOM attribute on mount and changes + useEffect(() => { + if (width === 'default') { + delete document.documentElement.dataset.contentWidth; + } else { + document.documentElement.dataset.contentWidth = width; + } + }, [width]); + + const handleChange = useCallback((value) => { + setWidth(value); + try { + if (value === 'default') { + localStorage.removeItem(STORAGE_KEY); + } else { + localStorage.setItem(STORAGE_KEY, value); + } + } catch { + // localStorage unavailable + } + }, []); + + const handleKeyDown = useCallback((e) => { + const currentIndex = WIDTHS.findIndex((w) => w.value === width); + let nextIndex; + if (e.key === 'ArrowRight' || e.key === 'ArrowDown') { + e.preventDefault(); + nextIndex = (currentIndex + 1) % WIDTHS.length; + } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') { + e.preventDefault(); + nextIndex = (currentIndex - 1 + WIDTHS.length) % WIDTHS.length; + } else { + return; + } + handleChange(WIDTHS[nextIndex].value); + }, [width, handleChange]); + + return ( +
+ {WIDTHS.map((w) => { + const isActive = width === w.value; + return ( + + ); + })} +
+ ); +} +``` + +- [ ] **Step 2: Commit** + +```bash +git add docusaurus/src/components/WidthToggle/WidthToggle.js +git commit -m "Add WidthToggle component with localStorage persistence" +``` + +--- + +### Task 5: Create WidthToggle styles + +**Files:** +- Create: `docusaurus/src/components/WidthToggle/widthToggle.module.scss` + +- [ ] **Step 1: Create the SCSS module** + +```scss +@use '../../scss/mixins' as *; + +.widthToggle { + display: none; + + @include medium-up { + display: inline-flex; + align-items: center; + gap: 2px; + padding: 3px; + border-radius: 8px; + background: var(--strapi-neutral-150); + float: right; + margin-bottom: 8px; + } +} + +.button { + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 28px; + border: none; + border-radius: 6px; + background: transparent; + color: var(--ifm-color-emphasis-600); + cursor: pointer; + padding: 0; + transition: background-color 0.2s ease, color 0.2s ease; + + &:hover:not(.active) { + background: var(--strapi-neutral-200); + } + + svg { + display: block; + } +} + +.active { + background: var(--strapi-primary-600); + color: white; + + &:hover { + background: var(--strapi-primary-600); + } +} +``` + +- [ ] **Step 2: Verify the build compiles** + +```bash +cd /Users/piwi/code/documentation/docusaurus && npm run build 2>&1 | tail -5 +``` + +Expected: build succeeds (component not mounted yet, but SCSS module is valid). + +- [ ] **Step 3: Commit** + +```bash +git add docusaurus/src/components/WidthToggle/widthToggle.module.scss +git commit -m "Add WidthToggle styles with dark mode support" +``` + +--- + +### Task 6: Swizzle DocItem/Layout to mount the toggle + +**Files:** +- Create: `docusaurus/src/theme/DocItem/Layout/index.js` + +- [ ] **Step 1: Create the swizzle wrapper** + +```jsx +import React from 'react'; +import Layout from '@theme-original/DocItem/Layout'; +import WidthToggle from '@site/src/components/WidthToggle/WidthToggle'; + +export default function LayoutWrapper(props) { + return ( + <> + + + + ); +} +``` + +- [ ] **Step 2: Verify the build compiles** + +```bash +cd /Users/piwi/code/documentation/docusaurus && npm run build 2>&1 | tail -5 +``` + +Expected: build succeeds. The toggle is now mounted on every doc page. + +- [ ] **Step 3: Commit** + +```bash +git add docusaurus/src/theme/DocItem/Layout/index.js +git commit -m "Swizzle DocItem/Layout to mount width toggle" +``` + +--- + +### Task 7: Visual verification + +**Files:** None (manual testing) + +- [ ] **Step 1: Start dev server** + +```bash +cd /Users/piwi/code/documentation/docusaurus && npm run start +``` + +- [ ] **Step 2: Verify on a regular doc page** + +Open a regular doc page (e.g., http://localhost:3000/cms/intro). Check: +- Toggle appears top-right of content area +- Default button is active (blue background) +- Clicking Wide expands content to ~960px with smooth animation +- Clicking Max expands content to full available width +- Clicking Default returns to 720px +- Refresh the page: chosen width persists + +- [ ] **Step 3: Verify on an API page** + +Open an API page (e.g., http://localhost:3000/cms/api/document-service). Check: +- Toggle appears but API pages stay at full width regardless of selection +- No visual glitch or layout break + +- [ ] **Step 4: Verify dark mode** + +Toggle to dark mode via the theme switcher. Check: +- Active button has blue background, white icon (readable) +- Inactive buttons have appropriate contrast +- No color issues + +- [ ] **Step 5: Verify mobile** + +Resize browser below 996px. Check: +- Toggle is hidden +- Content is full-width as before + +- [ ] **Step 6: Verify keyboard navigation** + +Focus the toggle, use arrow keys. Check: +- Arrow Right/Down cycles forward through options +- Arrow Left/Up cycles backward +- Each option applies correctly + +--- + +### Task 8: Adjust TOC-less page padding for width modes + +**Files:** +- Modify: `docusaurus/src/scss/_base.scss` + +When wide or max width is selected, the `padding-right: 280px` on TOC-less pages should be removed so content can actually use the extra space. + +- [ ] **Step 1: Update the TOC-less padding rule** + +Find (inside `@include medium-up`): + +```scss + [class*="docMainContainer"] .row:not(:has(.col--3)) { + padding-right: 280px; + } +``` + +Replace with: + +```scss + [class*="docMainContainer"] .row:not(:has(.col--3)) { + padding-right: 280px; + } + + /** When wide or max width, remove the TOC-placeholder padding */ + [data-content-width="wide"] [class*="docMainContainer"] .row:not(:has(.col--3)), + [data-content-width="max"] [class*="docMainContainer"] .row:not(:has(.col--3)) { + padding-right: 0; + } +``` + +- [ ] **Step 2: Verify visually** + +On a page without TOC, check that Wide and Max modes use the full available space. + +- [ ] **Step 3: Commit** + +```bash +git add docusaurus/src/scss/_base.scss +git commit -m "Remove TOC-placeholder padding in wide and max width modes" +``` diff --git a/docs/superpowers/specs/2026-05-08-view-modes-design.md b/docs/superpowers/specs/2026-05-08-view-modes-design.md new file mode 100644 index 0000000000..d3804d8fc4 --- /dev/null +++ b/docs/superpowers/specs/2026-05-08-view-modes-design.md @@ -0,0 +1,211 @@ +# View Modes: Elegant / Markdown / AI + +**Date:** 2026-05-08 +**Status:** Draft +**Branch:** Created from `next` + +## Overview + +Every documentation page offers 3 viewing modes, switchable via a control above the H1: + +- **Elegant** -- the documentation as it exists today, with all visual components +- **Markdown** -- stripped-down, monospace rendering with no tabs, cards, or complex visual components +- **AI** -- a side panel occupying 50% of the viewport with a page summary and conversational AI chat + +### Goals + +1. **Accessibility / reading preference** -- some developers prefer raw markdown, others a polished site +2. **Efficiency by context** -- Elegant for discovery, Markdown for quick copy-paste, AI for deep exploration +3. **Differentiation** -- an innovative documentation experience that no one else offers + +## Architecture + +**Approach:** React Context + CSS Data Attributes + +A `ViewModeProvider` context wraps the app at the `Root.js` level. The active mode is reflected on ``. Components that need structural changes read the context via `useViewMode()`. Pure visual changes (font, spacing) are handled in CSS via the data attribute selector. + +This follows the existing pattern: `WidthToggle` already uses `data-content-width` on ``. + +### Component overview + +``` +Root.js + |-- ViewModeProvider (new) + | |-- viewMode state + | |-- localStorage sync (elegant/markdown only) + | |-- dispatches CustomEvent('view-mode-change') + | + |-- ReadingProgressBar (existing) + |-- KapaThemeInjector (existing) + | + DocItemLayout (swizzled) + |-- ViewModeSwitcher (new, above H1) + |-- WidthToggle (existing, hidden in AI mode) + |-- DocItemContent + | |-- Tabs (modified: renders flat sections in markdown mode) + | |-- Cards (modified: renders as list in markdown mode) + | |-- Admonitions (unchanged) + | |-- Code blocks (unchanged) + | + |-- AiPanel (new, mounted when viewMode === 'ai') +``` + +## Section 1: Mode Switcher + +### Component: `ViewModeSwitcher` + +Injected in the swizzled `DocItemLayout`, positioned above the H1. + +**Visual design:** +- 3 text buttons: `ELEGANT MODE`, `MARKDOWN MODE`, `AI MODE` +- Font: `var(--strapi-font-family-technical)` (JetBrains Mono), uppercase +- Size: 12-13px (consistent with breadcrumbs) +- Spacing: ~16px gap between buttons +- Active state: `color: var(--strapi-primary-600)`, `border-bottom: 2px solid var(--strapi-primary-600)` +- Inactive state: `color: var(--strapi-neutral-500)`, hover to `var(--strapi-neutral-700)` +- Style: minimal tab bar, no background + +### Persistence + +- `localStorage.setItem('strapi-view-mode', 'elegant'|'markdown')` +- AI mode is **never persisted** -- always starts as off +- Default: `'elegant'` + +### Anti-FOUC + +An inline script in `headTags` (same pattern as the existing WidthToggle anti-FOUC script) reads localStorage and applies `data-view-mode` on `` before React hydrates: + +```javascript +(function() { + var mode = localStorage.getItem('strapi-view-mode') || 'elegant'; + document.documentElement.setAttribute('data-view-mode', mode); +})(); +``` + +## Section 2: ViewModeProvider + +### React Context + +``` +ViewModeContext + state: viewMode: 'elegant' | 'markdown' | 'ai' + actions: setViewMode(mode) + hook: useViewMode() -> { viewMode, setViewMode } +``` + +**Provider behavior:** +- Reads `localStorage.strapi-view-mode` on mount, fallback to `'elegant'` +- On `setViewMode(mode)`: + - Updates React state + - Sets `document.documentElement.dataset.viewMode = mode` + - If mode is `'elegant'` or `'markdown'`: writes to localStorage + - Dispatches `CustomEvent('view-mode-change', { detail: { mode } })` + +**Sidebar integration:** +- The sidebar already listens to custom events (`sidebar-v3-toggle`) +- On receiving `view-mode-change` with `mode: 'ai'`: + - Store current sidebar state (expanded/collapsed) + - Collapse the sidebar +- On receiving `view-mode-change` with `mode !== 'ai'`: + - Restore the previously stored sidebar state + +**Location:** Added in `Root.js`, wrapping children alongside existing providers. + +## Section 3: Markdown Mode + +When `data-view-mode="markdown"` is set on ``: + +### CSS changes (global, no React logic) + +- All article content: `font-family: var(--strapi-font-family-technical)` (JetBrains Mono) +- Body font size reduced to ~14px (compensates for monospace width) +- Headings remain visually distinct but in monospace +- Card grids neutralized: `display: block` instead of `grid`/`flex` +- Decorative elements (card borders, shadows, backgrounds) simplified or removed + +### Component modifications (via `useViewMode()`) + +**Tabs (structural change required):** +- Instead of rendering a tabbed panel with tab headers, renders ALL tab panels sequentially +- Each panel is preceded by a heading `### {tab label}` +- This is the only component requiring a true structural change + +**Cards (if used as grids):** +- Rendered as a simple vertical list + +### Unchanged + +- Admonitions -- kept as-is (they exist in standard Markdown) +- Code blocks -- already monospace +- Images -- kept +- TOC -- kept +- Sidebar -- visible and functional +- WidthToggle -- visible and functional + +## Section 4: AI Mode + +### Activation flow + +1. User clicks "AI MODE" in the switcher +2. Provider sets `viewMode: 'ai'` +3. Sidebar receives `view-mode-change` event and collapses (storing previous state) +4. WidthToggle hides via CSS: `[data-view-mode="ai"] .width-toggle { display: none }` +5. `AiPanel` component mounts and slides in from the right + +### Layout + +- **Panel:** `position: fixed`, right side, `width: 50vw`, `height: calc(100vh - var(--ifm-navbar-height))` +- **Main content:** `[data-view-mode="ai"] .main-wrapper { width: 50vw }` -- stays in Elegant mode (all visual components) +- **Transition:** `transform: translateX(100%) -> translateX(0)`, `0.4s cubic-bezier(0.16, 1, 0.3, 1)` (same easing as sidebar) + +### Panel content + +1. **Header:** Title "AI Assistant" + close button (X) that deactivates AI mode +2. **Summary:** Displays the `` content of the current page. If no Tldr exists: "No summary available for this page" +3. **Separator + prompt:** "What would you like to know more about this topic?" +4. **Chat area:** Uses Kapa in embed/inline mode (to be investigated). MVP fallback: button that opens the classic Kapa modal with the page context pre-filled +5. **Input field:** Fixed at the bottom of the panel + +### Navigation behavior + +- When the page changes while AI mode is active: + - Summary updates to the new page's Tldr + - Chat history is reset + - Panel remains open + +### Deactivation flow + +1. User clicks "ELEGANT" or "MARKDOWN" in the switcher, or the close button in the panel +2. Panel slides out to the right +3. Sidebar restores its previous state +4. WidthToggle reappears + +## Section 5: Responsive + +### Mobile (< 768px) + +- Mode switcher is visible, all 3 modes available +- AI mode: panel opens in **full-screen** (`100vw`, `100vh`) overlaying the page +- A back button in the panel header returns to the page +- Elegant and Markdown modes work normally + +### Tablet (768px - 1024px) + +- All 3 modes available +- AI mode: panel takes ~60% width, content takes ~40% +- Sidebar is forced collapsed in AI mode + +### Desktop (> 1024px) + +- Nominal behavior as described above +- Panel: 50% width, content: 50% + +## Dark mode + +All 3 modes must work in both light and dark themes. The existing `@include dark { }` mixin pattern is used for all new CSS. The AI panel follows the same color token system (`--strapi-neutral-*`, `--strapi-primary-*`) that adapts automatically to the active theme. + +## Open questions + +1. **Kapa embed mode:** Does Kapa offer an inline/embed mode (not modal)? This needs investigation. If not available, the MVP fallback is a button in the panel that opens the existing Kapa modal with page context pre-filled. +2. **Naming:** "Elegant Mode" is a working name. Final name TBD before launch. +3. **Tldr coverage:** Not all pages have a `` component. Strategy for pages without one: show "No summary available" for MVP, consider build-time generation later. diff --git a/docusaurus/docs/cms/ai/for-developers.md b/docusaurus/docs/cms/ai/for-developers.md index 516eb7172e..d01f73cd33 100644 --- a/docusaurus/docs/cms/ai/for-developers.md +++ b/docusaurus/docs/cms/ai/for-developers.md @@ -107,19 +107,19 @@ This is particularly useful for understanding configuration examples, API respon ## Tips for better results {#tips} The following tips will help you fine-tune your prompts to get the best results: +- Use the [Docs MCP server](/cms/ai/docs-mcp-server) in your IDE for the fastest developer experience. For docs-related questions, start your prompts with `Use the strapi-docs MCP server to answer:`. This will ensure the tool queries docs.strapi.io instead of creating answers based on its training data. - Include the page URL so the assistant grounds its answer in the right context. - Mention your Strapi version (e.g., Strapi 5) to avoid outdated suggestions. - Pair code examples with their source page when sharing snippets from `llms-code.txt`. - Prefer documented APIs over private internals when asking for code generation. -- Use the [Docs MCP server](/cms/ai/docs-mcp-server) in your IDE for the fastest developer experience. For docs-related questions, start your prompts with "Use the Docs MCP server to answer this question: " ## MCP servers {#mcp} -The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard that lets AI tools interact with external services. Two MCP servers are available for Strapi: +The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard that lets AI tools interact with external services. 2 MCP servers are available for Strapi: - - + + diff --git a/docusaurus/docs/cms/features/mcp-server.md b/docusaurus/docs/cms/features/mcp-server.md deleted file mode 100644 index e451f3f659..0000000000 --- a/docusaurus/docs/cms/features/mcp-server.md +++ /dev/null @@ -1,277 +0,0 @@ ---- -title: MCP server -description: Strapi includes a built-in MCP server that exposes content management tools to AI clients like Claude, Cursor, or any MCP-compatible tool. -sidebar_label: MCP server -displayed_sidebar: cmsSidebar -tags: - - ai - - MCP - - content management - - API -toc_max_heading_level: 3 ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -# MCP server - - - -Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server. Once enabled, it lets AI clients (Claude Desktop, Claude Code, Cursor, etc.) create, read, update, delete, publish, and unpublish your content directly through Strapi's Content Manager -- all gated by admin token permissions. - - - -The MCP server exposes a set of **tools** that map to your content types. An AI assistant connected to the MCP server can, for example, create a blog article, list recent entries, or publish a page -- all through natural language prompts. Which tools are available depends on the permissions granted to the admin token used for authentication. - -:::note -The MCP server is an experimental feature. It requires the `adminTokens` feature flag and a Strapi version that includes MCP support. -::: - - - - - - - - -## Configuration - -Enabling the MCP server requires two steps: turning on the `adminTokens` feature flag and enabling MCP in the server configuration. - -### Enable the feature flag - -The MCP server relies on Strapi's admin tokens feature. Enable it in the `config/features` configuration file: - - - - -```js title="config/features.js" -module.exports = { - future: { - adminTokens: true, - }, -}; -``` - - - - -```ts title="config/features.ts" -export default { - future: { - adminTokens: true, - }, -}; -``` - - - - -### Enable the MCP server - -Add the `mcp` key to the server configuration file: - - - - -```js title="config/server.js" -module.exports = ({ env }) => ({ - host: env('HOST', '0.0.0.0'), - port: env.int('PORT', 1337), - app: { - keys: env.array('APP_KEYS'), - }, - mcp: { - enabled: true, - }, -}); -``` - - - - -```ts title="config/server.ts" -import type { Core } from '@strapi/strapi'; - -const config = ({ env }: Core.Config.Shared.ConfigParams): Core.Config.Server => ({ - host: env('HOST', '0.0.0.0'), - port: env.int('PORT', 1337), - app: { - keys: env.array('APP_KEYS'), - }, - mcp: { - enabled: true, - }, -}); -export default config; -``` - - - - -Once both settings are in place, restart Strapi. The MCP endpoint becomes available at `/mcp` on your Strapi server (e.g., `http://localhost:1337/mcp`). - -## Authentication - -The MCP server authenticates requests using **admin API tokens**. Each MCP session is scoped to the permissions of the token used to connect. - -To create an admin token: - -1. In the Strapi admin panel, go to *Settings > API Tokens*. -2. Click **Create new API Token**. -3. Choose **Admin** as the token type. -4. Select the content types and actions (read, create, update, delete, publish) you want the AI client to access. -5. Save the token and copy it -- it will not be shown again. - -The token's permissions determine which MCP tools are exposed to the AI client. For instance, if the token only grants `read` on `Article`, the AI client will only see listing and reading tools for articles -- no create, update, delete, or publish tools. - -:::caution -Treat admin tokens like passwords. Do not commit them to version control or share them publicly. Use environment variables when possible. -::: - -## Connecting an AI client - -The MCP server uses the **Streamable HTTP** transport protocol. Any MCP-compatible client can connect by pointing to the `/mcp` endpoint with a `Bearer` token in the `Authorization` header. - -### Claude Desktop - -Open Claude Desktop's configuration file: - -- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` -- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` - -You can also open this file from Claude's Settings > Developer (click the Edit Config button). - -Add the Strapi MCP server to the configuration: - -```json title="claude_desktop_config.json" -{ - "mcpServers": { - "strapi-mcp": { - "type": "streamable-http", - "url": "http://localhost:1337/mcp", - "headers": { - "Authorization": "Bearer YOUR_ADMIN_TOKEN" - } - } - } -} -``` - -Restart Claude Desktop for the changes to take effect. - -### Claude Code - -Run the following command, replacing `YOUR_ADMIN_TOKEN` with the token created earlier: - -```bash -claude mcp add strapi-mcp --transport http http://localhost:1337/mcp -H "Authorization: Bearer YOUR_ADMIN_TOKEN" -``` - -Restart Claude Code, then run `/mcp` to confirm `strapi-mcp` reports as connected. - -### Cursor - -Add the server to your `.cursor/mcp.json` file: - -```json title=".cursor/mcp.json" -{ - "mcpServers": { - "strapi-mcp": { - "type": "streamable-http", - "url": "http://localhost:1337/mcp", - "headers": { - "Authorization": "Bearer YOUR_ADMIN_TOKEN" - } - } - } -} -``` - -### Other MCP clients - -Any client that supports the MCP Streamable HTTP transport can connect. The generic configuration is: - -| Setting | Value | -|---------|-------| -| Transport type | `streamable-http` | -| URL | `http://localhost:1337/mcp` (adjust host and port to your Strapi instance) | -| Authorization header | `Bearer YOUR_ADMIN_TOKEN` | - -## Available tools - -Once connected, the AI client receives a set of **content management tools** derived from your content types. The tools available depend on the admin token's permissions. - -### Tools per content type - -For each content type the token has access to, Strapi generates up to 8 tools: - -| Tool | Action | Permission required | Description | -|------|--------|-------------------|-------------| -| `list` | Read | `read` | List entries with pagination, sorting, and filtering | -| `get` | Read | `read` | Get a single entry by document ID | -| `create` | Create | `create` | Create a new entry (created as draft if Draft & Publish is enabled) | -| `update` | Update | `update` | Update an existing entry by document ID | -| `delete` | Delete | `delete` | Delete an entry by document ID | -| `publish` | Publish | `publish` | Publish a draft entry | -| `unpublish` | Unpublish | `publish` | Unpublish a published entry | -| `discard_draft` | Discard draft | `publish` | Discard draft changes and revert to the published version | - -The last 3 tools (publish, unpublish, discard_draft) are only generated for content types that have [Draft & Publish](/cms/features/draft-and-publish) enabled. - -Tool names follow the pattern `cm___`. For example, an `Article` content type with UID `api::article.article` generates tools named `cm_api_article_list`, `cm_api_article_get`, `cm_api_article_create`, etc. - -Single types follow a similar pattern but include `_single_` in the name (e.g., `cm_api_homepage_single_get`). - -### Input schemas - -Each tool has an input schema derived from your content type's attributes. The schema is dynamically adjusted per session based on the token's permissions: - -- **Field-level permissions**: If the token restricts access to certain fields, those fields are excluded from both input and output schemas. -- **Locale-level permissions**: If the token restricts access to certain locales, the `locale` parameter only accepts permitted locales. -- **Write operations**: The `data` object only includes fields the token has permission to write. Unknown fields are rejected. - -For the `list` tool, the input schema also includes parameters for pagination (`page`, `pageSize`), sorting (`sort`), and filtering (`filters`). - -### Example prompts - -Once connected, you can interact with your Strapi content using natural language: - -| Prompt | What happens | -|--------|-------------| -| "Create a new article titled 'Hello World' with body 'First post'." | Creates a draft article entry | -| "List the 5 most recent articles." | Returns paginated list, newest first | -| "Show me article with ID abc123." | Returns the full entry | -| "Update article abc123 -- change the title to 'Hello Strapi'." | Updates the title, other fields untouched | -| "Publish article abc123." | Flips the entry status to published | -| "Delete article abc123." | Removes the entry | - -## Permission boundaries - -The MCP server enforces the same permission model as the Strapi admin panel. Permissions are checked at two levels: - -1. **Tool visibility**: When an AI client connects, Strapi checks the admin token's permissions and only exposes tools the token has access to. If the token does not grant `delete` on `Article`, the AI client will not see a delete tool for articles at all. - -2. **Field and locale filtering**: Even within an exposed tool, input and output schemas are narrowed to the fields and locales the token can access. If the token grants `read` on `Article` but excludes the `body` field, the AI client will not see or receive `body` content. - -This means you can create tokens with fine-grained access: - -- A "read-only" token that only exposes listing and reading tools -- A token scoped to specific content types (e.g., articles but not categories) -- A token restricted to specific fields or locales -- A token with condition-based permissions (e.g., only update entries you own) - -:::tip -Create dedicated admin tokens for each AI client or use case. Use the most restrictive permissions that still allow the AI to accomplish its task. -::: - -## Known limitations - -The MCP server is experimental and has the following limitations: - -- **Block content**: Rich text block content is not represented in tool definitions. -- **Components**: Component fields are passed as untyped (`any`) in tool schemas. -- **Dynamic zones**: Dynamic zone fields are passed as untyped arrays in tool schemas. -- **Nested population parameters**: The `list` and `get` tools do not support nested population parameters for relations. -- **Stateless sessions**: Each MCP request creates a new server instance. There is no session persistence between requests. diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index ef4f362f43..3565ddf33e 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -7,7 +7,7 @@ tags: - ai - MCP - content management -toc_max_heading_level: 3 +toc_max_heading_level: 4 --- import Tabs from '@theme/Tabs'; @@ -33,9 +33,20 @@ The MCP server exposes a set of content management tools to AI clients such as C ## Configuration -The MCP server is configured through the server configuration file and authenticated with admin API tokens created in the admin panel. +Before first use, the Strapi MCP server must be: +- configured in Strapi through the server configuration file and authenticated with Admin tokens created in the admin panel +- connected to your AI client. -### Code-based configuration +### Strapi admin panel configuration + +The MCP server authenticates requests using Admin tokens. Each MCP session is scoped to the permissions of the token used to connect: + +1. Create a new admin token (see [Creating an admin token](/cms/features/admin-tokens#creating-a-new-admin-token) on the Admin tokens feature page). +2. Copy the token as you will need it + +The token's permissions determine which MCP tools are exposed to the AI client. For instance, if the token only grants `read` on an `Article` content-type, the AI client will only see listing and reading tools for articles. + +### Strapi code-based configuration Enable the MCP server by adding the `mcp` key to the server configuration file: @@ -79,38 +90,22 @@ export default config; Once the setting is in place, restart Strapi. The MCP endpoint becomes available at `/mcp` on your Strapi server (e.g., `http://localhost:1337/mcp`). -### Admin panel configuration - -The MCP server authenticates requests using admin API tokens. Each MCP session is scoped to the permissions of the token used to connect. +### AI client configuration -To create an admin token for MCP access: +Once you enabled and configured the MCP server through Strapi's admin panel (admin tokens) and configuration filters, you must connect your AI client to the Strapi MCP server. -1. In the Strapi admin panel, go to *Settings > API Tokens*. -2. Click **Create new API Token**. -3. Choose **Admin** as the token type. -4. Select the content types and actions (read, create, update, delete, publish) you want the AI client to access. -5. Save the token and copy it. It will not be shown again. - -The token's permissions determine which MCP tools are exposed to the AI client. For instance, if the token only grants `read` on `Article`, the AI client will only see listing and reading tools for articles. - -:::caution -Treat admin tokens like passwords. Do not commit them to version control or share them publicly. Use environment variables when possible. -::: - -## Usage - -The MCP server uses the Streamable HTTP transport protocol. Any MCP-compatible client can connect by pointing to the `/mcp` endpoint with a `Bearer` token in the `Authorization` header. Once connected, the AI client can interact with your Strapi content using natural language prompts. - -### Connecting Claude Desktop +#### Connecting Claude Desktop Open Claude Desktop's configuration file: -- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` -- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` +- on macOS, the file is accessible at `~/Library/Application Support/Claude/claude_desktop_config.json` +- on Windows, the file is accessible at `%APPDATA%\Claude\claude_desktop_config.json` -You can also open this file from Claude's Settings > Developer (click the Edit Config button). +:::tip +You can also open the configuration file for Claude Desktop from Claude's settings: go to Settings > Desktop app > Developer, then click on the **Edit config** button. +::: -Add the Strapi MCP server to the configuration: +Add the Strapi MCP server to the configuration, as in the following example, replacing `YOUR_ADMIN_TOKEN` with the admin token value copied from the [admin panel](#admin-panel-configuration): ```json title="claude_desktop_config.json" { @@ -128,9 +123,9 @@ Add the Strapi MCP server to the configuration: Restart Claude Desktop for the changes to take effect. -### Connecting Claude Code +#### Connecting Claude Code -Run the following command, replacing `YOUR_ADMIN_TOKEN` with the token created earlier: +Run the following command, replacing `YOUR_ADMIN_TOKEN` with the admin token value copied from the [admin panel](#admin-panel-configuration): ```bash claude mcp add strapi-mcp --transport http http://localhost:1337/mcp -H "Authorization: Bearer YOUR_ADMIN_TOKEN" @@ -138,7 +133,7 @@ claude mcp add strapi-mcp --transport http http://localhost:1337/mcp -H "Authori Restart Claude Code, then run `/mcp` to confirm `strapi-mcp` reports as connected. -### Connecting Cursor +#### Connecting Cursor Add the server to your `.cursor/mcp.json` file: @@ -156,9 +151,9 @@ Add the server to your `.cursor/mcp.json` file: } ``` -### Connecting other MCP clients +#### Connecting other MCP clients -Any client that supports the MCP Streamable HTTP transport can connect. The generic configuration is: +Any client that supports the MCP Streamable HTTP transport can connect. The generic configuration is as follows: | Setting | Value | |---------|-------| @@ -166,6 +161,10 @@ Any client that supports the MCP Streamable HTTP transport can connect. The gene | URL | `http://localhost:1337/mcp` (adjust host and port to your Strapi instance) | | Authorization header | `Bearer YOUR_ADMIN_TOKEN` | +## Usage + +The MCP server uses the Streamable HTTP transport protocol. Any MCP-compatible client can connect by pointing to the `/mcp` endpoint with a `Bearer` token in the `Authorization` header. Once connected, the AI client can interact with your Strapi content using natural language prompts. + ### Available tools For each content type the token has access to, Strapi generates up to 8 tools: diff --git a/docusaurus/docs/snippets/strapi-ai-credits.md b/docusaurus/docs/snippets/strapi-ai-credits.md index 390f0928bc..2ebe137c71 100644 --- a/docusaurus/docs/snippets/strapi-ai-credits.md +++ b/docusaurus/docs/snippets/strapi-ai-credits.md @@ -3,7 +3,7 @@ Strapi AI includes 1,000 credits per month on the plan Lightweight actions use fewer credits, while more complex ones use more. You can check your credit usage in the of the admin panel. -Notifications are sent when your usage reaches 80%, 90%, and 100% of your monthly allowance. +Notifications are sent when your usage reaches 80%, 90%, and 100% of your monthly allowance. Overages apply. Credits are shared across all users within the same project instance. diff --git a/docusaurus/static/llms-code.txt b/docusaurus/static/llms-code.txt index 61c3e3e733..05a0005ac3 100644 --- a/docusaurus/static/llms-code.txt +++ b/docusaurus/static/llms-code.txt @@ -1873,33 +1873,12 @@ export default { -# Strapi AI for content managers -Source: https://docs.strapi.io/cms/ai/for-content-managers - -## Activation and configuration -Description: All Strapi AI features can be enabled or disabled globally through the admin panel configuration: -(Source: https://docs.strapi.io/cms/ai/for-content-managers#activation) - -Language: JavaScript -File path: /config/admin.js|ts - -```js -module.exports = { - // ... - ai: { - enabled: true, // set to false to disable all Strapi AI features - }, -}; -``` - - - -# AI for developers -Source: https://docs.strapi.io/cms/ai/for-developers +# Docs MCP server +Source: https://docs.strapi.io/cms/ai/docs-mcp-server ## Connection details Description: Add to your .cursor/mcp.json file: -(Source: https://docs.strapi.io/cms/ai/for-developers#connection-details) +(Source: https://docs.strapi.io/cms/ai/docs-mcp-server#connection-details) Language: JSON File path: .cursor/mcp.json @@ -1931,6 +1910,27 @@ File path: .vscode/mcp.json +# AI for content managers +Source: https://docs.strapi.io/cms/ai/for-content-managers + +## Activation and configuration +Description: All Strapi AI features can be enabled or disabled globally through the admin panel configuration: +(Source: https://docs.strapi.io/cms/ai/for-content-managers#activation) + +Language: JavaScript +File path: /config/admin.js|ts + +```js +module.exports = { + // ... + ai: { + enabled: true, // set to false to disable all Strapi AI features + }, +}; +``` + + + # Strapi Client Source: https://docs.strapi.io/cms/api/client @@ -23926,6 +23926,107 @@ export default async function fetchContentType( +# MCP server +Source: https://docs.strapi.io/cms/features/strapi-mcp-server + +## Code-based configuration +Description: Enable the MCP server by adding the mcp key to the server configuration file: +(Source: https://docs.strapi.io/cms/features/strapi-mcp-server#code-based-configuration) + +Language: JavaScript +File path: config/server.js + +```js +module.exports = ({ env }) => ({ + host: env('HOST', '0.0.0.0'), + port: env.int('PORT', 1337), + app: { + keys: env.array('APP_KEYS'), + }, + mcp: { + enabled: true, + }, +}); +``` + +--- +Language: TypeScript +File path: config/server.ts + +```ts +import type { Core } from '@strapi/strapi'; + +const config = ({ env }: Core.Config.Shared.ConfigParams): Core.Config.Server => ({ + host: env('HOST', '0.0.0.0'), + port: env.int('PORT', 1337), + app: { + keys: env.array('APP_KEYS'), + }, + mcp: { + enabled: true, + }, +}); +export default config; +``` + + +## Connecting Claude Desktop +Description: Add the Strapi MCP server to the configuration: +(Source: https://docs.strapi.io/cms/features/strapi-mcp-server#connecting-claude-desktop) + +Language: JSON +File path: claude_desktop_config.json + +```json +{ + "mcpServers": { + "strapi-mcp": { + "type": "streamable-http", + "url": "http://localhost:1337/mcp", + "headers": { + "Authorization": "Bearer YOUR_ADMIN_TOKEN" + } + } + } +} +``` + + +## Connecting Claude Code +Description: Run the following command, replacing YOURADMINTOKEN with the token created earlier: +(Source: https://docs.strapi.io/cms/features/strapi-mcp-server#connecting-claude-code) + +Language: JavaScript +File path: /Claude/claude_desktop_config.js + +```js +claude mcp add strapi-mcp --transport http http://localhost:1337/mcp -H "Authorization: Bearer YOUR_ADMIN_TOKEN" +``` + + +## Connecting Cursor +Description: Add the server to your .cursor/mcp.json file: +(Source: https://docs.strapi.io/cms/features/strapi-mcp-server#connecting-cursor) + +Language: JSON +File path: .cursor/mcp.json + +```json +{ + "mcpServers": { + "strapi-mcp": { + "type": "streamable-http", + "url": "http://localhost:1337/mcp", + "headers": { + "Authorization": "Bearer YOUR_ADMIN_TOKEN" + } + } + } +} +``` + + + # Users & Permissions Source: https://docs.strapi.io/cms/features/users-permissions diff --git a/docusaurus/static/llms-full.txt b/docusaurus/static/llms-full.txt index b150403f5b..9586281189 100644 --- a/docusaurus/static/llms-full.txt +++ b/docusaurus/static/llms-full.txt @@ -1861,14 +1861,45 @@ When evaluating editors, start with a plugin from the Marketplace for a quick tr -# Strapi AI for content managers +# Docs MCP server +Source: https://docs.strapi.io/cms/ai/docs-mcp-server + +# Docs MCP server + +A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for the documentation is available. The Docs MCP server exposes the Strapi documentation to AI coding tools. Connect it to your IDE to get Strapi-aware code suggestions and answers directly in your development environment. + +## Compatible tools + +The MCP server works with any tool that supports the MCP protocol, including: + +- [Cursor](https://cursor.com) +- [VS Code](https://code.visualstudio.com) with GitHub Copilot +- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) +- [Windsurf](https://codeium.com/windsurf) +- Any other MCP-compatible IDE or tool + +## Connection details + +When opening the Ask AI window, you should see a **Use MCP** dropdown in the top right corner. Click on it and choose which tool you'd like to connect: + +
+ +Once connected, your AI coding assistant can query the Strapi documentation directly to answer questions, suggest implementations, and verify API usage. + + + +# AI for content managers Source: https://docs.strapi.io/cms/ai/for-content-managers -# Strapi AI for content management +# AI for content managers + +This page covers the AI-powered capabilities available to content managers in Strapi: the Strapi AI features built into the admin panel, and the MCP server that lets AI clients manage your content. + +## Strapi AI Some Strapi CMS features can be enhanced with Strapi AI, helping content managers and administrators design content structures, translate content automatically, and generate asset metadata, all from the admin panel. -## Activation and configuration {#activation} +### Activation and configuration {#activation} Strapi AI is available for Growth plan users since Strapi 5.30 and works with both Strapi Cloud and self-hosted deployments. To get started: @@ -1889,14 +1920,15 @@ module.exports = { See [Admin panel configuration > Strapi AI](/cms/configurations/admin-panel#strapi-ai) for all configuration options. -## Available features {#features} +### Available features {#features} | Feature | Description | |---------|-------------| | [Content-Type Builder](/cms/features/content-type-builder#strapi-ai) | AI chat assistant that helps design content-type structures, explain existing schemas, and plan data models. Uses your existing content types as context. | | [Internationalization](/cms/features/internationalization#ai-powered-internationalization) | Automatically translates content from the default locale to all other configured locales when you save an entry. | | [Media Library](/cms/features/media-library#ai-powered-metadata-generation) | Generates alternative text, captions, and descriptions for uploaded images. | -## Credits and data handling {#credits} + +### Credits and data handling {#credits} Strapi AI features consume AI credits. @@ -1904,6 +1936,10 @@ All AI requests are processed through Strapi-managed infrastructure. Content is See [Usage information > Strapi AI data handling](/cms/usage-information#strapi-ai-data-handling) for more details. +## Strapi MCP server + +Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that lets AI clients like Claude, Cursor, or any MCP-compatible tool manage your content through natural language. Once enabled and connected, an AI assistant can create, read, update, delete, publish, and unpublish entries directly through Strapi's Content Manager -- all gated by admin token permissions. + # AI for developers @@ -1915,18 +1951,6 @@ The Strapi documentation site includes AI-powered tools to help developers learn :::tip AGENTS.MD files In addition to docs and product features described on the present page, the - - - -Once connected, your AI coding assistant can query the Strapi documentation directly to answer questions, suggest implementations, and verify API usage. - -## Tips for better results {#tips} - -- Include the page URL so the assistant grounds its answer in the right context. -- Mention your Strapi version (e.g., Strapi 5) to avoid outdated suggestions. -- Pair code examples with their source page when sharing snippets from `llms-code.txt`. -- Prefer documented APIs over private internals when asking for code generation. -- Use the MCP server in your IDE for the fastest developer experience. @@ -9599,6 +9623,188 @@ To access the admin panel using a specific provider instead of logging in with a +# MCP server +Source: https://docs.strapi.io/cms/features/strapi-mcp-server + +# MCP server + +The MCP server exposes a set of content management tools to AI clients such as Claude Desktop, Claude Code, Cursor, or any MCP-compatible tool. An AI assistant connected to the MCP server can, for example, create a blog article, list recent entries, or publish a page. Which tools are available depends on the permissions granted to the admin token used for authentication. + + + +## Configuration + +The MCP server is configured through the server configuration file and authenticated with Admin tokens created in the admin panel. + +### Admin panel configuration + +The MCP server authenticates requests using [Admin tokens](/cms/features/admin-tokens). Each MCP session is scoped to the permissions of the token used to connect. + +To create an admin token for MCP access: + +1. In the Strapi admin panel, go to *Settings > API Tokens*. +2. Click **Create new API Token**. +3. Choose **Admin** as the token type. +4. Select the content types and actions (read, create, update, delete, publish) you want the AI client to access. +5. Save the token and copy it. It will not be shown again. + +The token's permissions determine which MCP tools are exposed to the AI client. For instance, if the token only grants `read` on `Article`, the AI client will only see listing and reading tools for articles. + +:::caution +Treat admin tokens like passwords. Do not commit them to version control or share them publicly. Use environment variables when possible. +::: +### Code-based configuration + +Enable the MCP server by adding the `mcp` key to the server configuration file: + + + +Once the setting is in place, restart Strapi. The MCP endpoint becomes available at `/mcp` on your Strapi server (e.g., `http://localhost:1337/mcp`). + +## Usage + +The MCP server uses the Streamable HTTP transport protocol. Any MCP-compatible client can connect by pointing to the `/mcp` endpoint with a `Bearer` token in the `Authorization` header. Once connected, the AI client can interact with your Strapi content using natural language prompts. + +### Connecting Claude Desktop + +Open Claude Desktop's configuration file: + +- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` +- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` + +You can also open this file from Claude's Settings > Developer (click the Edit Config button). + +Add the Strapi MCP server to the configuration: + +```json title="claude_desktop_config.json" +{ + "mcpServers": { + "strapi-mcp": { + "type": "streamable-http", + "url": "http://localhost:1337/mcp", + "headers": { + "Authorization": "Bearer YOUR_ADMIN_TOKEN" + } + } + } +} +``` + +Restart Claude Desktop for the changes to take effect. + +### Connecting Claude Code + +Run the following command, replacing `YOUR_ADMIN_TOKEN` with the token created earlier: + +```bash +claude mcp add strapi-mcp --transport http http://localhost:1337/mcp -H "Authorization: Bearer YOUR_ADMIN_TOKEN" +``` + +Restart Claude Code, then run `/mcp` to confirm `strapi-mcp` reports as connected. + +### Connecting Cursor + +Add the server to your `.cursor/mcp.json` file: + +```json title=".cursor/mcp.json" +{ + "mcpServers": { + "strapi-mcp": { + "type": "streamable-http", + "url": "http://localhost:1337/mcp", + "headers": { + "Authorization": "Bearer YOUR_ADMIN_TOKEN" + } + } + } +} +``` + +### Connecting other MCP clients + +Any client that supports the MCP Streamable HTTP transport can connect. The generic configuration is: + +| Setting | Value | +|---------|-------| +| Transport type | `streamable-http` | +| URL | `http://localhost:1337/mcp` (adjust host and port to your Strapi instance) | +| Authorization header | `Bearer YOUR_ADMIN_TOKEN` | + +### Available tools + +For each content type the token has access to, Strapi generates up to 8 tools: + +| Tool | Action | Permission required | Description | +|------|--------|-------------------|-------------| +| `list` | Read | `read` | List entries with pagination, sorting, and filtering | +| `get` | Read | `read` | Get a single entry by document ID | +| `create` | Create | `create` | Create a new entry (created as draft if Draft & Publish is enabled) | +| `update` | Update | `update` | Update an existing entry by document ID | +| `delete` | Delete | `delete` | Delete an entry by document ID | +| `publish` | Publish | `publish` | Publish a draft entry | +| `unpublish` | Unpublish | `publish` | Unpublish a published entry | +| `discard_draft` | Discard draft | `publish` | Discard draft changes and revert to the published version | + +The last 3 tools (publish, unpublish, discard_draft) are only generated for content types that have [Draft & Publish](/cms/features/draft-and-publish) enabled. + +Tool names follow the pattern `cm___`. For example, an `Article` content type with UID `api::article.article` generates tools named `cm_api_article_list`, `cm_api_article_get`, `cm_api_article_create`, etc. + +Single types follow a similar pattern but include `_single_` in the name (e.g., `cm_api_homepage_single_get`). + +### Managing content through prompts + +Once connected, you can interact with your Strapi content using natural language: + +| Prompt | What happens | +|--------|-------------| +| "Create a new article titled 'Hello World' with body 'First post'." | Creates a draft article entry | +| "List the 5 most recent articles." | Returns paginated list, newest first | +| "Show me article with ID abc123." | Returns the full entry | +| "Update article abc123, change the title to 'Hello Strapi'." | Updates the title, other fields untouched | +| "Publish article abc123." | Flips the entry status to published | +| "Delete article abc123." | Removes the entry | + +### Understanding input schemas + +Each tool has an input schema derived from your content type's attributes. The schema is dynamically adjusted per session based on the token's permissions: + +- **Field-level permissions**: If the token restricts access to certain fields, those fields are excluded from both input and output schemas. +- **Locale-level permissions**: If the token restricts access to certain locales, the `locale` parameter only accepts permitted locales. +- **Write operations**: The `data` object only includes fields the token has permission to write. Unknown fields are rejected. + +For the `list` tool, the input schema also includes parameters for pagination (`page`, `pageSize`), sorting (`sort`), and filtering (`filters`). + +### Permission boundaries + +The MCP server enforces the same permission model as the Strapi admin panel. Permissions are checked at two levels: + +1. **Tool visibility**: When an AI client connects, Strapi checks the admin token's permissions and only exposes tools the token has access to. If the token does not grant `delete` on `Article`, the AI client will not see a delete tool for articles at all. + +2. **Field and locale filtering**: Even within an exposed tool, input and output schemas are narrowed to the fields and locales the token can access. If the token grants `read` on `Article` but excludes the `body` field, the AI client will not see or receive `body` content. + +This means you can create tokens with fine-grained access: + +- A "read-only" token that only exposes listing and reading tools +- A token scoped to specific content types (e.g., articles but not categories) +- A token restricted to specific fields or locales +- A token with condition-based permissions (e.g., only update entries you own) + +:::tip +Create dedicated admin tokens for each AI client or use case. Use the most restrictive permissions that still allow the AI to accomplish its task. +::: + +## Known limitations + +The MCP server has the following limitations: + +- **Block content**: Rich text block content is not represented in tool definitions. +- **Components**: Component fields are passed as untyped (`any`) in tool schemas. +- **Dynamic zones**: Dynamic zone fields are passed as untyped arrays in tool schemas. +- **Nested population parameters**: The `list` and `get` tools do not support nested population parameters for relations. +- **Stateless sessions**: Each MCP request creates a new server instance. There is no session persistence between requests. + + + # Users & Permissions Source: https://docs.strapi.io/cms/features/users-permissions diff --git a/docusaurus/static/llms.txt b/docusaurus/static/llms.txt index 2c293b0aa2..dd61b77a08 100644 --- a/docusaurus/static/llms.txt +++ b/docusaurus/static/llms.txt @@ -28,7 +28,8 @@ - [Logos](https://docs.strapi.io/cms/admin-panel-customization/logos): Update login and navigation logos by extending the admin app. Prefer SVG for crisp rendering; provide light/dark variants when possible for contrast. - [Theme extension](https://docs.strapi.io/cms/admin-panel-customization/theme-extension): Extend Strapi's admin panel theme. - [Customizing the rich text editor](https://docs.strapi.io/cms/admin-panel-customization/wysiwyg-editor): Learn more about the various strategies available to customize the WYSIWYG editor in Strapi's admin panel. -- [Strapi AI for content managers](https://docs.strapi.io/cms/ai/for-content-managers): Learn about AI-powered features in the Strapi admin panel, such as content-type design, automatic translations, and media metadata generation. +- [Docs MCP server](https://docs.strapi.io/cms/ai/docs-mcp-server): Connect an MCP server for the Strapi documentation to your IDE for Strapi-aware code suggestions and answers. +- [AI for content managers](https://docs.strapi.io/cms/ai/for-content-managers): Learn about AI-powered features in the Strapi admin panel and the built-in MCP server that lets AI clients manage your content. - [AI for developers](https://docs.strapi.io/cms/ai/for-developers): Use AI-powered tools on the Strapi documentation site. Chatbot, Copy Markdown, LLMs.txt files, Open with LLM, and MCP server for IDE integration. - [Strapi Client](https://docs.strapi.io/cms/api/client): The Strapi Client library simplifies interactions with your Strapi back end, providing a way to fetch, create, update, and delete content. - [Content API](https://docs.strapi.io/cms/api/content-api): Learn more about Strapi 5's Content API @@ -99,6 +100,7 @@ - [Releases](https://docs.strapi.io/cms/features/releases): Releases group entries into publishable batches to trigger simultaneous publish or unpublish actions across content types and locales. Instructions in this documentation detail creating releases, adding entries, and understanding plan limitations. - [Review Workflows](https://docs.strapi.io/cms/features/review-workflows): Review Workflows define custom multi-stage pipelines for content review, facilitating collaboration from draft to publication. This documentation walks through creating workflows and assigning stages. - [Single Sign-On (SSO)](https://docs.strapi.io/cms/features/sso): Single Sign-On (SSO) lets administrators authenticate via identity providers such as Azure AD instead of local passwords. Configuration steps in this documentation cover enabling SSO and mapping roles. +- [MCP server](https://docs.strapi.io/cms/features/strapi-mcp-server): Strapi includes a built-in Model Context Protocol (MCP) server. Once enabled, it lets AI clients create, read, update, delete, publish, and unpublish content directly through Strapi's Content Manager. All operations are gated by admin token permissions. - [Users & Permissions](https://docs.strapi.io/cms/features/users-permissions): Users & Permissions manages end-user accounts, JWT-based authentication, and role-based access to APIs. This documentation explains how to create roles, configure permissions, and secure access to your content API. - [Installation](https://docs.strapi.io/cms/installation): Learn many different options to install Strapi and getting started on using it. - [Additional resources for migrating to Strapi 5](https://docs.strapi.io/cms/migration/v4-to-v5/additional-resources/introduction): The following pages cover some dedicated topics for specific use cases when upgrading to Strapi 5. Please ensure you have read the [introduction to up... From 832296ab3aad05246e18c089a0db3350503ddbee Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 18:19:20 +0200 Subject: [PATCH 09/51] Add Tldr to Docs MCP server page Co-Authored-By: Claude Opus 4.6 (1M context) --- docusaurus/docs/cms/ai/docs-mcp-server.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/ai/docs-mcp-server.md b/docusaurus/docs/cms/ai/docs-mcp-server.md index 0b57dddd5e..fe51f00488 100644 --- a/docusaurus/docs/cms/ai/docs-mcp-server.md +++ b/docusaurus/docs/cms/ai/docs-mcp-server.md @@ -15,7 +15,13 @@ import TabItem from '@theme/TabItem'; # Docs MCP server -A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for the documentation is available. The Docs MCP server exposes the Strapi documentation to AI coding tools. Connect it to your IDE to get Strapi-aware code suggestions and answers directly in your development environment. + + +A Docs MCP server exposes the Strapi documentation to AI coding tools. Connect it to your IDE to get Strapi-aware code suggestions and answers directly in your development environment. + + + +The Docs [MCP](https://modelcontextprotocol.io) server is powered by [Kapa](https://kapa.ai) and draws from the full Strapi documentation, including guides, API references, and code examples. ## Compatible tools From bcec8e270e0b916cd10f94d21604e5f95f8caa66 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 18:27:00 +0200 Subject: [PATCH 10/51] Improve Docs MCP server page --- docusaurus/docs/cms/ai/docs-mcp-server.md | 28 ++++++++++++++++++++++- docusaurus/sidebars.js | 8 ------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/docusaurus/docs/cms/ai/docs-mcp-server.md b/docusaurus/docs/cms/ai/docs-mcp-server.md index fe51f00488..8e09458a8a 100644 --- a/docusaurus/docs/cms/ai/docs-mcp-server.md +++ b/docusaurus/docs/cms/ai/docs-mcp-server.md @@ -21,7 +21,14 @@ A Docs MCP server exposes the Strapi documentation to AI coding tools. Connect i -The Docs [MCP](https://modelcontextprotocol.io) server is powered by [Kapa](https://kapa.ai) and draws from the full Strapi documentation, including guides, API references, and code examples. +The Docs [MCP](https://modelcontextprotocol.io) (Model Context Protocol) server is powered by [Kapa](https://kapa.ai) and draws from the full Strapi documentation, including guides, API references, and code examples. The Docs MCP server is part of the [AI tools for developers](/cms/ai/for-developers) that Strapi offers. + +:::strapi MCP servers for Strapi +Strapi offers 2 different MCP servers: + +- the Docs MCP server, covered on the present page, +- and the Strapi MCP for content management, covered on its [dedicated feature page](/cms/features/strapi-mcp-server). +::: ## Compatible tools @@ -81,7 +88,26 @@ If manual MCP server configuration is required: } ``` + + + + Add to your `~/.codeium/windsurf/mcp_config.json` file: + + ```json title="~/.codeium/windsurf/mcp_config.json" + { + "mcpServers": { + "strapi-docs": { + "serverUrl": "https://strapi-docs.mcp.kapa.ai" + } + } + } + ``` + Once connected, your AI coding assistant can query the Strapi documentation directly to answer questions, suggest implementations, and verify API usage. + +:::tip +For docs-related questions, start your prompts with `Use the strapi-docs MCP server to answer:`. This will ensure the tool queries docs.strapi.io instead of returning answers based on its training data, which can be outdated. +::: \ No newline at end of file diff --git a/docusaurus/sidebars.js b/docusaurus/sidebars.js index 8c3591f602..a2c83715f7 100644 --- a/docusaurus/sidebars.js +++ b/docusaurus/sidebars.js @@ -179,14 +179,6 @@ const sidebars = { new: true, }, }, - { - type: 'doc', - label: 'Docs MCP server', - id: 'cms/ai/docs-mcp-server', - customProps: { - new: true, - }, - }, ], }, { // APIs From 0358c311b2f3b8046cf322ee055c0afd78d54cd4 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 18:27:02 +0200 Subject: [PATCH 11/51] Add Windsurf configuration to both MCP server pages Co-Authored-By: Claude Opus 4.6 (1M context) --- .../docs/cms/features/strapi-mcp-server.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 3565ddf33e..9e344e05d6 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -151,6 +151,23 @@ Add the server to your `.cursor/mcp.json` file: } ``` +#### Connecting Windsurf + +Add the server to your `~/.codeium/windsurf/mcp_config.json` file: + +```json title="~/.codeium/windsurf/mcp_config.json" +{ + "mcpServers": { + "strapi-mcp": { + "serverUrl": "http://localhost:1337/mcp", + "headers": { + "Authorization": "Bearer YOUR_ADMIN_TOKEN" + } + } + } +} +``` + #### Connecting other MCP clients Any client that supports the MCP Streamable HTTP transport can connect. The generic configuration is as follows: From 21d4c813cb1d079429d986d576e95a76621c9617 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 18:27:21 +0200 Subject: [PATCH 12/51] Move tips --- docusaurus/docs/cms/ai/for-developers.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/docusaurus/docs/cms/ai/for-developers.md b/docusaurus/docs/cms/ai/for-developers.md index d01f73cd33..e8922bf71c 100644 --- a/docusaurus/docs/cms/ai/for-developers.md +++ b/docusaurus/docs/cms/ai/for-developers.md @@ -104,15 +104,6 @@ This is particularly useful for understanding configuration examples, API respon - **`llms-full.txt`**: Use this when you need the AI to have access to the complete documentation content. This is a large file; make sure your model's context window can handle it. - **`llms-code.txt`**: Use this when you're working on code and want to give an AI all of Strapi's documented code examples. Each snippet includes the source page URL and anchor for traceability. -## Tips for better results {#tips} - -The following tips will help you fine-tune your prompts to get the best results: -- Use the [Docs MCP server](/cms/ai/docs-mcp-server) in your IDE for the fastest developer experience. For docs-related questions, start your prompts with `Use the strapi-docs MCP server to answer:`. This will ensure the tool queries docs.strapi.io instead of creating answers based on its training data. -- Include the page URL so the assistant grounds its answer in the right context. -- Mention your Strapi version (e.g., Strapi 5) to avoid outdated suggestions. -- Pair code examples with their source page when sharing snippets from `llms-code.txt`. -- Prefer documented APIs over private internals when asking for code generation. - ## MCP servers {#mcp} The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard that lets AI tools interact with external services. 2 MCP servers are available for Strapi: @@ -122,4 +113,11 @@ The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open s +## Tips for better results {#tips} +The following tips will help you fine-tune your prompts to get the best results: +- Use the [Docs MCP server](/cms/ai/docs-mcp-server) in your IDE for the fastest developer experience. For docs-related questions, start your prompts with `Use the strapi-docs MCP server to answer:`. This will ensure the tool queries docs.strapi.io instead of creating answers based on its training data. +- Include the page URL so the assistant grounds its answer in the right context. +- Mention your Strapi version (e.g., Strapi 5) to avoid outdated suggestions. +- Pair code examples with their source page when sharing snippets from `llms-code.txt`. +- Prefer documented APIs over private internals when asking for code generation. From 8a72f9573216ca12b2bc79c8f5eb35c93db9db8d Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 18:33:34 +0200 Subject: [PATCH 13/51] Fix Claude Desktop config to use mcp-remote Co-Authored-By: Claude Opus 4.6 (1M context) --- .../docs/cms/features/strapi-mcp-server.md | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 9e344e05d6..7509e8b6f7 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -48,7 +48,7 @@ The token's permissions determine which MCP tools are exposed to the AI client. ### Strapi code-based configuration -Enable the MCP server by adding the `mcp` key to the server configuration file: +Enable the MCP server by adding the `mcp` object to the server configuration file: @@ -60,9 +60,11 @@ module.exports = ({ env }) => ({ app: { keys: env.array('APP_KEYS'), }, + // highlight-start mcp: { enabled: true, }, + // highlight-end }); ``` @@ -96,26 +98,31 @@ Once you enabled and configured the MCP server through Strapi's admin panel (adm #### Connecting Claude Desktop -Open Claude Desktop's configuration file: +Open Claude Desktop's configuration file. The location varies depending on your system: -- on macOS, the file is accessible at `~/Library/Application Support/Claude/claude_desktop_config.json` -- on Windows, the file is accessible at `%APPDATA%\Claude\claude_desktop_config.json` +| OS | File location | +|----|---------------| +| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` | +| Windows | `%APPDATA%\Claude\claude_desktop_config.json` | :::tip You can also open the configuration file for Claude Desktop from Claude's settings: go to Settings > Desktop app > Developer, then click on the **Edit config** button. ::: -Add the Strapi MCP server to the configuration, as in the following example, replacing `YOUR_ADMIN_TOKEN` with the admin token value copied from the [admin panel](#admin-panel-configuration): +Add the Strapi MCP server to Claude's configuration file, as in the following example, replacing `YOUR_ADMIN_TOKEN` with the admin token value copied from the [admin panel](#strapi-admin-panel-configuration): ```json title="claude_desktop_config.json" { "mcpServers": { "strapi-mcp": { - "type": "streamable-http", - "url": "http://localhost:1337/mcp", - "headers": { - "Authorization": "Bearer YOUR_ADMIN_TOKEN" - } + "command": "npx", + "args": [ + "-y", + "mcp-remote", + "http://localhost:1337/mcp", + "--header", + "Authorization: Bearer YOUR_ADMIN_TOKEN" + ] } } } @@ -125,7 +132,7 @@ Restart Claude Desktop for the changes to take effect. #### Connecting Claude Code -Run the following command, replacing `YOUR_ADMIN_TOKEN` with the admin token value copied from the [admin panel](#admin-panel-configuration): +Run the following command, replacing `YOUR_ADMIN_TOKEN` with the admin token value copied from the [admin panel](#strapi-admin-panel-configuration): ```bash claude mcp add strapi-mcp --transport http http://localhost:1337/mcp -H "Authorization: Bearer YOUR_ADMIN_TOKEN" From 4c679daf1cf1c7c598c67475e5c595a6cf19650f Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 18:37:59 +0200 Subject: [PATCH 14/51] Add note about host & port --- .../docs/cms/features/strapi-mcp-server.md | 5 +- docusaurus/static/llms-code.txt | 26 +++--- docusaurus/static/llms-full.txt | 84 ++++++------------- docusaurus/static/llms.txt | 1 - 4 files changed, 44 insertions(+), 72 deletions(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 7509e8b6f7..14c87aa0ce 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -96,6 +96,10 @@ Once the setting is in place, restart Strapi. The MCP endpoint becomes available Once you enabled and configured the MCP server through Strapi's admin panel (admin tokens) and configuration filters, you must connect your AI client to the Strapi MCP server. +:::note +`localhost:1337/` is used in configuration examples on this page. If your Strapi server is hosted on another URL or port, please update the code accordingly. +::: + #### Connecting Claude Desktop Open Claude Desktop's configuration file. The location varies depending on your system: @@ -260,4 +264,3 @@ The MCP server has the following limitations: - **Components**: Component fields are passed as untyped (`any`) in tool schemas. - **Dynamic zones**: Dynamic zone fields are passed as untyped arrays in tool schemas. - **Nested population parameters**: The `list` and `get` tools do not support nested population parameters for relations. -- **Stateless sessions**: Each MCP request creates a new server instance. There is no session persistence between requests. diff --git a/docusaurus/static/llms-code.txt b/docusaurus/static/llms-code.txt index 05a0005ac3..b86f807783 100644 --- a/docusaurus/static/llms-code.txt +++ b/docusaurus/static/llms-code.txt @@ -17225,13 +17225,13 @@ Source: https://docs.strapi.io/cms/configurations/features Description: (optional) If the server is running, stop it with Ctrl-C. (Source: https://docs.strapi.io/cms/configurations/features#enabling-a-future-flag) -Language: TypeScript -File path: /config/features.ts +Language: JavaScript +File path: /config/features.js -```ts +```js module.exports = ({ env }) => ({ future: { - adminTokens: env.bool('STRAPI_FUTURE_ADMIN_TOKENS', false), + experimental_firstPublishedAt: env.bool('STRAPI_FUTURE_EXPERIMENTAL_FIRST_PUBLISHED_AT', false), }, }) ``` @@ -17241,7 +17241,7 @@ Language: DOTENV File path: .env ```dotenv - STRAPI_FUTURE_ADMIN_TOKENS=true + STRAPI_FUTURE_EXPERIMENTAL_FIRST_PUBLISHED_AT=true ``` --- @@ -17249,11 +17249,11 @@ Language: TypeScript File path: /config/features.ts ```ts - export default { + export default ({ env }) => ({ future: { - adminTokens: env.bool('STRAPI_FUTURE_ADMIN_TOKENS', false), + experimental_firstPublishedAt: env.bool('STRAPI_FUTURE_EXPERIMENTAL_FIRST_PUBLISHED_AT', false), }, - }; + }); ``` --- @@ -17261,7 +17261,7 @@ Language: DOTENV File path: .env ```dotenv - STRAPI_FUTURE_ADMIN_TOKENS=true + STRAPI_FUTURE_EXPERIMENTAL_FIRST_PUBLISHED_AT=true ``` Language: Bash @@ -23929,9 +23929,9 @@ export default async function fetchContentType( # MCP server Source: https://docs.strapi.io/cms/features/strapi-mcp-server -## Code-based configuration +## Strapi code-based configuration Description: Enable the MCP server by adding the mcp key to the server configuration file: -(Source: https://docs.strapi.io/cms/features/strapi-mcp-server#code-based-configuration) +(Source: https://docs.strapi.io/cms/features/strapi-mcp-server#strapi-code-based-configuration) Language: JavaScript File path: config/server.js @@ -23971,7 +23971,7 @@ export default config; ## Connecting Claude Desktop -Description: Add the Strapi MCP server to the configuration: +Description: Add the Strapi MCP server to the configuration, as in the following example, replacing YOURADMINTOKEN with the admin token value copied from the admin panel: (Source: https://docs.strapi.io/cms/features/strapi-mcp-server#connecting-claude-desktop) Language: JSON @@ -23993,7 +23993,7 @@ File path: claude_desktop_config.json ## Connecting Claude Code -Description: Run the following command, replacing YOURADMINTOKEN with the token created earlier: +Description: Run the following command, replacing YOURADMINTOKEN with the admin token value copied from the admin panel: (Source: https://docs.strapi.io/cms/features/strapi-mcp-server#connecting-claude-code) Language: JavaScript diff --git a/docusaurus/static/llms-full.txt b/docusaurus/static/llms-full.txt index 9586281189..662d513b51 100644 --- a/docusaurus/static/llms-full.txt +++ b/docusaurus/static/llms-full.txt @@ -1861,33 +1861,6 @@ When evaluating editors, start with a plugin from the Marketplace for a quick tr -# Docs MCP server -Source: https://docs.strapi.io/cms/ai/docs-mcp-server - -# Docs MCP server - -A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for the documentation is available. The Docs MCP server exposes the Strapi documentation to AI coding tools. Connect it to your IDE to get Strapi-aware code suggestions and answers directly in your development environment. - -## Compatible tools - -The MCP server works with any tool that supports the MCP protocol, including: - -- [Cursor](https://cursor.com) -- [VS Code](https://code.visualstudio.com) with GitHub Copilot -- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) -- [Windsurf](https://codeium.com/windsurf) -- Any other MCP-compatible IDE or tool - -## Connection details - -When opening the Ask AI window, you should see a **Use MCP** dropdown in the top right corner. Click on it and choose which tool you'd like to connect: - - - -Once connected, your AI coding assistant can query the Strapi documentation directly to answer questions, suggest implementations, and verify API usage. - - - # AI for content managers Source: https://docs.strapi.io/cms/ai/for-content-managers @@ -7444,7 +7417,6 @@ Developers can use the following APIs to interact with future flags: | Property name | Related feature | Suggested environment variable name | | ------------- | --------------- | ---------------------------------- | | `experimental_firstPublishedAt` | [Draft & Publish](/cms/features/draft-and-publish#recording-the-first-publication-date) | `STRAPI_FUTURE_EXPERIMENTAL_FIRST_PUBLISHED_AT` | -| `adminTokens` | [Admin Tokens](/cms/features/admin-tokens) | `STRAPI_FUTURE_ADMIN_TOKENS` | @@ -8341,8 +8313,6 @@ If you're not the Strapi instance's super admin, the super admin must have grant ::: 4. Click on the **Save** button. The new Admin token will be displayed at the top of the interface, along with a copy button . - - :::caution The plaintext token key is shown only once, immediately after creation or regeneration. The `admin.secrets.encryptionKey` configuration that makes Content API token keys persistently viewable does not apply to Admin tokens. Admin token keys are always restricted to the token owner, regardless of encryption configuration. ::: @@ -9634,26 +9604,20 @@ The MCP server exposes a set of content management tools to AI clients such as C ## Configuration -The MCP server is configured through the server configuration file and authenticated with Admin tokens created in the admin panel. +Before first use, the Strapi MCP server must be: +- configured in Strapi through the server configuration file and authenticated with Admin tokens created in the admin panel +- connected to your AI client. -### Admin panel configuration +### Strapi admin panel configuration -The MCP server authenticates requests using [Admin tokens](/cms/features/admin-tokens). Each MCP session is scoped to the permissions of the token used to connect. +The MCP server authenticates requests using Admin tokens. Each MCP session is scoped to the permissions of the token used to connect: -To create an admin token for MCP access: +1. Create a new admin token (see [Creating an admin token](/cms/features/admin-tokens#creating-a-new-admin-token) on the Admin tokens feature page). +2. Copy the token as you will need it -1. In the Strapi admin panel, go to *Settings > API Tokens*. -2. Click **Create new API Token**. -3. Choose **Admin** as the token type. -4. Select the content types and actions (read, create, update, delete, publish) you want the AI client to access. -5. Save the token and copy it. It will not be shown again. +The token's permissions determine which MCP tools are exposed to the AI client. For instance, if the token only grants `read` on an `Article` content-type, the AI client will only see listing and reading tools for articles. -The token's permissions determine which MCP tools are exposed to the AI client. For instance, if the token only grants `read` on `Article`, the AI client will only see listing and reading tools for articles. - -:::caution -Treat admin tokens like passwords. Do not commit them to version control or share them publicly. Use environment variables when possible. -::: -### Code-based configuration +### Strapi code-based configuration Enable the MCP server by adding the `mcp` key to the server configuration file: @@ -9661,20 +9625,22 @@ Enable the MCP server by adding the `mcp` key to the server configuration file: Once the setting is in place, restart Strapi. The MCP endpoint becomes available at `/mcp` on your Strapi server (e.g., `http://localhost:1337/mcp`). -## Usage +### AI client configuration -The MCP server uses the Streamable HTTP transport protocol. Any MCP-compatible client can connect by pointing to the `/mcp` endpoint with a `Bearer` token in the `Authorization` header. Once connected, the AI client can interact with your Strapi content using natural language prompts. +Once you enabled and configured the MCP server through Strapi's admin panel (admin tokens) and configuration filters, you must connect your AI client to the Strapi MCP server. -### Connecting Claude Desktop +#### Connecting Claude Desktop Open Claude Desktop's configuration file: -- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` -- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` +- on macOS, the file is accessible at `~/Library/Application Support/Claude/claude_desktop_config.json` +- on Windows, the file is accessible at `%APPDATA%\Claude\claude_desktop_config.json` -You can also open this file from Claude's Settings > Developer (click the Edit Config button). +:::tip +You can also open the configuration file for Claude Desktop from Claude's settings: go to Settings > Desktop app > Developer, then click on the **Edit config** button. +::: -Add the Strapi MCP server to the configuration: +Add the Strapi MCP server to the configuration, as in the following example, replacing `YOUR_ADMIN_TOKEN` with the admin token value copied from the [admin panel](#admin-panel-configuration): ```json title="claude_desktop_config.json" { @@ -9692,9 +9658,9 @@ Add the Strapi MCP server to the configuration: Restart Claude Desktop for the changes to take effect. -### Connecting Claude Code +#### Connecting Claude Code -Run the following command, replacing `YOUR_ADMIN_TOKEN` with the token created earlier: +Run the following command, replacing `YOUR_ADMIN_TOKEN` with the admin token value copied from the [admin panel](#admin-panel-configuration): ```bash claude mcp add strapi-mcp --transport http http://localhost:1337/mcp -H "Authorization: Bearer YOUR_ADMIN_TOKEN" @@ -9702,7 +9668,7 @@ claude mcp add strapi-mcp --transport http http://localhost:1337/mcp -H "Authori Restart Claude Code, then run `/mcp` to confirm `strapi-mcp` reports as connected. -### Connecting Cursor +#### Connecting Cursor Add the server to your `.cursor/mcp.json` file: @@ -9720,9 +9686,9 @@ Add the server to your `.cursor/mcp.json` file: } ``` -### Connecting other MCP clients +#### Connecting other MCP clients -Any client that supports the MCP Streamable HTTP transport can connect. The generic configuration is: +Any client that supports the MCP Streamable HTTP transport can connect. The generic configuration is as follows: | Setting | Value | |---------|-------| @@ -9730,6 +9696,10 @@ Any client that supports the MCP Streamable HTTP transport can connect. The gene | URL | `http://localhost:1337/mcp` (adjust host and port to your Strapi instance) | | Authorization header | `Bearer YOUR_ADMIN_TOKEN` | +## Usage + +The MCP server uses the Streamable HTTP transport protocol. Any MCP-compatible client can connect by pointing to the `/mcp` endpoint with a `Bearer` token in the `Authorization` header. Once connected, the AI client can interact with your Strapi content using natural language prompts. + ### Available tools For each content type the token has access to, Strapi generates up to 8 tools: diff --git a/docusaurus/static/llms.txt b/docusaurus/static/llms.txt index dd61b77a08..f009a05bb2 100644 --- a/docusaurus/static/llms.txt +++ b/docusaurus/static/llms.txt @@ -28,7 +28,6 @@ - [Logos](https://docs.strapi.io/cms/admin-panel-customization/logos): Update login and navigation logos by extending the admin app. Prefer SVG for crisp rendering; provide light/dark variants when possible for contrast. - [Theme extension](https://docs.strapi.io/cms/admin-panel-customization/theme-extension): Extend Strapi's admin panel theme. - [Customizing the rich text editor](https://docs.strapi.io/cms/admin-panel-customization/wysiwyg-editor): Learn more about the various strategies available to customize the WYSIWYG editor in Strapi's admin panel. -- [Docs MCP server](https://docs.strapi.io/cms/ai/docs-mcp-server): Connect an MCP server for the Strapi documentation to your IDE for Strapi-aware code suggestions and answers. - [AI for content managers](https://docs.strapi.io/cms/ai/for-content-managers): Learn about AI-powered features in the Strapi admin panel and the built-in MCP server that lets AI clients manage your content. - [AI for developers](https://docs.strapi.io/cms/ai/for-developers): Use AI-powered tools on the Strapi documentation site. Chatbot, Copy Markdown, LLMs.txt files, Open with LLM, and MCP server for IDE integration. - [Strapi Client](https://docs.strapi.io/cms/api/client): The Strapi Client library simplifies interactions with your Strapi back end, providing a way to fetch, create, update, and delete content. From 4e9226c5a2940b563ab8c53ac36b91d22f965628 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 18:43:39 +0200 Subject: [PATCH 15/51] Update sidebar --- docusaurus/sidebars.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docusaurus/sidebars.js b/docusaurus/sidebars.js index a2c83715f7..a1e98d7c9c 100644 --- a/docusaurus/sidebars.js +++ b/docusaurus/sidebars.js @@ -168,7 +168,7 @@ const sidebars = { label: 'Strapi AI for content managers', id: 'cms/ai/for-content-managers', customProps: { - new: true, + updated: true, }, }, { @@ -176,7 +176,7 @@ const sidebars = { label: 'AI for developers and docs', id: 'cms/ai/for-developers', customProps: { - new: true, + updated: true, }, }, ], From 6c206b82e90a24332c35c620fad4b8d216718239 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 18:43:47 +0200 Subject: [PATCH 16/51] Update LLM files --- docusaurus/static/llms-code.txt | 54 ++++++++++++++++++++++++++---- docusaurus/static/llms-full.txt | 58 ++++++++++++++++++++++++++------- 2 files changed, 93 insertions(+), 19 deletions(-) diff --git a/docusaurus/static/llms-code.txt b/docusaurus/static/llms-code.txt index b86f807783..0e907fb2e7 100644 --- a/docusaurus/static/llms-code.txt +++ b/docusaurus/static/llms-code.txt @@ -1908,6 +1908,20 @@ File path: .vscode/mcp.json } ``` +--- +Language: JSON +File path: ~/.codeium/windsurf/mcp_config.json + +```json + { + "mcpServers": { + "strapi-docs": { + "serverUrl": "https://strapi-docs.mcp.kapa.ai" + } + } + } +``` + # AI for content managers @@ -23930,7 +23944,7 @@ export default async function fetchContentType( Source: https://docs.strapi.io/cms/features/strapi-mcp-server ## Strapi code-based configuration -Description: Enable the MCP server by adding the mcp key to the server configuration file: +Description: Enable the MCP server by adding the mcp object to the server configuration file: (Source: https://docs.strapi.io/cms/features/strapi-mcp-server#strapi-code-based-configuration) Language: JavaScript @@ -23943,9 +23957,11 @@ module.exports = ({ env }) => ({ app: { keys: env.array('APP_KEYS'), }, + // highlight-start mcp: { enabled: true, }, + // highlight-end }); ``` @@ -23971,7 +23987,7 @@ export default config; ## Connecting Claude Desktop -Description: Add the Strapi MCP server to the configuration, as in the following example, replacing YOURADMINTOKEN with the admin token value copied from the admin panel: +Description: Add the Strapi MCP server to Claude's configuration file, as in the following example, replacing YOURADMINTOKEN with the admin token value copied from the admin panel: (Source: https://docs.strapi.io/cms/features/strapi-mcp-server#connecting-claude-desktop) Language: JSON @@ -23981,11 +23997,14 @@ File path: claude_desktop_config.json { "mcpServers": { "strapi-mcp": { - "type": "streamable-http", - "url": "http://localhost:1337/mcp", - "headers": { - "Authorization": "Bearer YOUR_ADMIN_TOKEN" - } + "command": "npx", + "args": [ + "-y", + "mcp-remote", + "http://localhost:1337/mcp", + "--header", + "Authorization: Bearer YOUR_ADMIN_TOKEN" + ] } } } @@ -24026,6 +24045,27 @@ File path: .cursor/mcp.json ``` +## Connecting Windsurf +Description: Add the server to your ~/.codeium/windsurf/mcp_config.json file: +(Source: https://docs.strapi.io/cms/features/strapi-mcp-server#connecting-windsurf) + +Language: JSON +File path: ~/.codeium/windsurf/mcp_config.json + +```json +{ + "mcpServers": { + "strapi-mcp": { + "serverUrl": "http://localhost:1337/mcp", + "headers": { + "Authorization": "Bearer YOUR_ADMIN_TOKEN" + } + } + } +} +``` + + # Users & Permissions Source: https://docs.strapi.io/cms/features/users-permissions diff --git a/docusaurus/static/llms-full.txt b/docusaurus/static/llms-full.txt index 662d513b51..7b7c40820f 100644 --- a/docusaurus/static/llms-full.txt +++ b/docusaurus/static/llms-full.txt @@ -1925,6 +1925,15 @@ The Strapi documentation site includes AI-powered tools to help developers learn :::tip AGENTS.MD files In addition to docs and product features described on the present page, the +## Tips for better results {#tips} + +The following tips will help you fine-tune your prompts to get the best results: +- Use the [Docs MCP server](/cms/ai/docs-mcp-server) in your IDE for the fastest developer experience. For docs-related questions, start your prompts with `Use the strapi-docs MCP server to answer:`. This will ensure the tool queries docs.strapi.io instead of creating answers based on its training data. +- Include the page URL so the assistant grounds its answer in the right context. +- Mention your Strapi version (e.g., Strapi 5) to avoid outdated suggestions. +- Pair code examples with their source page when sharing snippets from `llms-code.txt`. +- Prefer documented APIs over private internals when asking for code generation. + # Strapi Client @@ -9619,7 +9628,7 @@ The token's permissions determine which MCP tools are exposed to the AI client. ### Strapi code-based configuration -Enable the MCP server by adding the `mcp` key to the server configuration file: +Enable the MCP server by adding the `mcp` object to the server configuration file: @@ -9629,28 +9638,37 @@ Once the setting is in place, restart Strapi. The MCP endpoint becomes available Once you enabled and configured the MCP server through Strapi's admin panel (admin tokens) and configuration filters, you must connect your AI client to the Strapi MCP server. +:::note +`localhost:1337/` is used in configuration examples on this page. If your Strapi server is hosted on another URL or port, please update the code accordingly. +::: + #### Connecting Claude Desktop -Open Claude Desktop's configuration file: +Open Claude Desktop's configuration file. The location varies depending on your system: -- on macOS, the file is accessible at `~/Library/Application Support/Claude/claude_desktop_config.json` -- on Windows, the file is accessible at `%APPDATA%\Claude\claude_desktop_config.json` +| OS | File location | +|----|---------------| +| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` | +| Windows | `%APPDATA%\Claude\claude_desktop_config.json` | :::tip You can also open the configuration file for Claude Desktop from Claude's settings: go to Settings > Desktop app > Developer, then click on the **Edit config** button. ::: -Add the Strapi MCP server to the configuration, as in the following example, replacing `YOUR_ADMIN_TOKEN` with the admin token value copied from the [admin panel](#admin-panel-configuration): +Add the Strapi MCP server to Claude's configuration file, as in the following example, replacing `YOUR_ADMIN_TOKEN` with the admin token value copied from the [admin panel](#strapi-admin-panel-configuration): ```json title="claude_desktop_config.json" { "mcpServers": { "strapi-mcp": { - "type": "streamable-http", - "url": "http://localhost:1337/mcp", - "headers": { - "Authorization": "Bearer YOUR_ADMIN_TOKEN" - } + "command": "npx", + "args": [ + "-y", + "mcp-remote", + "http://localhost:1337/mcp", + "--header", + "Authorization: Bearer YOUR_ADMIN_TOKEN" + ] } } } @@ -9660,7 +9678,7 @@ Restart Claude Desktop for the changes to take effect. #### Connecting Claude Code -Run the following command, replacing `YOUR_ADMIN_TOKEN` with the admin token value copied from the [admin panel](#admin-panel-configuration): +Run the following command, replacing `YOUR_ADMIN_TOKEN` with the admin token value copied from the [admin panel](#strapi-admin-panel-configuration): ```bash claude mcp add strapi-mcp --transport http http://localhost:1337/mcp -H "Authorization: Bearer YOUR_ADMIN_TOKEN" @@ -9686,6 +9704,23 @@ Add the server to your `.cursor/mcp.json` file: } ``` +#### Connecting Windsurf + +Add the server to your `~/.codeium/windsurf/mcp_config.json` file: + +```json title="~/.codeium/windsurf/mcp_config.json" +{ + "mcpServers": { + "strapi-mcp": { + "serverUrl": "http://localhost:1337/mcp", + "headers": { + "Authorization": "Bearer YOUR_ADMIN_TOKEN" + } + } + } +} +``` + #### Connecting other MCP clients Any client that supports the MCP Streamable HTTP transport can connect. The generic configuration is as follows: @@ -9771,7 +9806,6 @@ The MCP server has the following limitations: - **Components**: Component fields are passed as untyped (`any`) in tool schemas. - **Dynamic zones**: Dynamic zone fields are passed as untyped arrays in tool schemas. - **Nested population parameters**: The `list` and `get` tools do not support nested population parameters for relations. -- **Stateless sessions**: Each MCP request creates a new server instance. There is no session persistence between requests. From b14f38391dc6e4a3cd1305e55cad4b1dc2391adb Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 18:46:02 +0200 Subject: [PATCH 17/51] Remove superpowers files and add to gitignore Co-Authored-By: Claude Opus 4.6 (1M context) --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 4c5f2067e3..e099ae5f53 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .claude/ +.superpowers/ +docs/superpowers/ From bdd2e62366965aad994297025274230ddb6f7ce3 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 18:47:13 +0200 Subject: [PATCH 18/51] Remove superpowers files from tracking Co-Authored-By: Claude Opus 4.6 (1M context) --- .../content/three-modes-overview.html | 197 ------- .../brainstorm/61754-1778237530/state/events | 14 - .../61754-1778237530/state/server-stopped | 1 - .../61754-1778237530/state/server.log | 17 - .../61754-1778237530/state/server.pid | 1 - .../plans/2026-05-07-content-width-toggle.md | 555 ------------------ .../specs/2026-05-08-view-modes-design.md | 211 ------- 7 files changed, 996 deletions(-) delete mode 100644 .superpowers/brainstorm/61754-1778237530/content/three-modes-overview.html delete mode 100644 .superpowers/brainstorm/61754-1778237530/state/events delete mode 100644 .superpowers/brainstorm/61754-1778237530/state/server-stopped delete mode 100644 .superpowers/brainstorm/61754-1778237530/state/server.log delete mode 100644 .superpowers/brainstorm/61754-1778237530/state/server.pid delete mode 100644 docs/superpowers/plans/2026-05-07-content-width-toggle.md delete mode 100644 docs/superpowers/specs/2026-05-08-view-modes-design.md diff --git a/.superpowers/brainstorm/61754-1778237530/content/three-modes-overview.html b/.superpowers/brainstorm/61754-1778237530/content/three-modes-overview.html deleted file mode 100644 index 1f833b1d9e..0000000000 --- a/.superpowers/brainstorm/61754-1778237530/content/three-modes-overview.html +++ /dev/null @@ -1,197 +0,0 @@ -

Vue d'ensemble des 3 modes

-

Voici comment chaque mode transforme la page. Clique sur celui que tu veux voir en plus grand.

- -
- - -
-
-
- -
-
Navigation
-
-
-
-
-
- -
- -
- ELEGANT - MARKDOWN - AI -
- -
-
-
-
-
-
-
-
-
- -
-
Tab 1
-
Tab 2
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-

Elegant Mode

-

La doc telle qu'elle est aujourd'hui. Tous les composants visuels, tabs, cards, sidebar ouverte, WidthToggle visible.

-
-
- - -
-
-
- -
-
Navigation
-
-
-
-
-
- -
- -
- ELEGANT - MARKDOWN - AI -
-
-
-
-
- -
## Tab 1
-
-
-
## Tab 2
-
-
- -
-
-
-
-
-
-
-
-

Markdown Mode

-

Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.

-
-
- - -
-
-
- -
-
-
-
-
-
- -
- -
- ELEGANT - MARKDOWN - AI -
- -
-
-
-
-
-
Tab 1
-
Tab 2
-
-
-
-
-
-
- -
-
AI Assistant
-
-
Summary
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-

AI Mode

-

Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.

-
-
- -
- -
-

Comportements clés

-
-
- Transitions
- Elegant ↔ Markdown : instantané
- AI mode : panel slide-in/out -
-
- Persistence
- Elegant/Markdown : localStorage
- AI : toujours off au chargement -
-
- Navigation
- Changement de page en AI mode :
résumé mis à jour, chat reset -
-
-
diff --git a/.superpowers/brainstorm/61754-1778237530/state/events b/.superpowers/brainstorm/61754-1778237530/state/events deleted file mode 100644 index d7094ec9f2..0000000000 --- a/.superpowers/brainstorm/61754-1778237530/state/events +++ /dev/null @@ -1,14 +0,0 @@ -{"type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Elegant Mode\n La doc telle qu'elle est aujourd'hui. Tous les composants visuels, tabs, cards, sidebar ouverte, WidthToggle visible.","choice":"elegant","id":null,"timestamp":1778238072727} -{"type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Elegant Mode\n La doc telle qu'elle est aujourd'hui. Tous les composants visuels, tabs, cards, sidebar ouverte, WidthToggle visible.","choice":"elegant","id":null,"timestamp":1778238076491} -{"type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238083463} -{"type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238084524} -{"type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238084697} -{"type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238085591} -{"type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238085751} -{"type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238087935} -{"type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238734830} -{"type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238735019} -{"type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238735706} -{"type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238737279} -{"type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238739110} -{"type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Elegant Mode\n La doc telle qu'elle est aujourd'hui. Tous les composants visuels, tabs, cards, sidebar ouverte, WidthToggle visible.","choice":"elegant","id":null,"timestamp":1778238740006} diff --git a/.superpowers/brainstorm/61754-1778237530/state/server-stopped b/.superpowers/brainstorm/61754-1778237530/state/server-stopped deleted file mode 100644 index bfa32890eb..0000000000 --- a/.superpowers/brainstorm/61754-1778237530/state/server-stopped +++ /dev/null @@ -1 +0,0 @@ -{"reason":"idle timeout","timestamp":1778240574260} diff --git a/.superpowers/brainstorm/61754-1778237530/state/server.log b/.superpowers/brainstorm/61754-1778237530/state/server.log deleted file mode 100644 index 1cbe0ef005..0000000000 --- a/.superpowers/brainstorm/61754-1778237530/state/server.log +++ /dev/null @@ -1,17 +0,0 @@ -{"type":"server-started","port":61548,"host":"127.0.0.1","url_host":"localhost","url":"http://localhost:61548","screen_dir":"/Users/piwi/code/documentation/.superpowers/brainstorm/61754-1778237530/content","state_dir":"/Users/piwi/code/documentation/.superpowers/brainstorm/61754-1778237530/state"} -{"type":"screen-added","file":"/Users/piwi/code/documentation/.superpowers/brainstorm/61754-1778237530/content/three-modes-overview.html"} -{"source":"user-event","type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Elegant Mode\n La doc telle qu'elle est aujourd'hui. Tous les composants visuels, tabs, cards, sidebar ouverte, WidthToggle visible.","choice":"elegant","id":null,"timestamp":1778238072727} -{"source":"user-event","type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Elegant Mode\n La doc telle qu'elle est aujourd'hui. Tous les composants visuels, tabs, cards, sidebar ouverte, WidthToggle visible.","choice":"elegant","id":null,"timestamp":1778238076491} -{"source":"user-event","type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238083463} -{"source":"user-event","type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238084524} -{"source":"user-event","type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238084697} -{"source":"user-event","type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238085591} -{"source":"user-event","type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238085751} -{"source":"user-event","type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238087935} -{"source":"user-event","type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238734830} -{"source":"user-event","type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238735019} -{"source":"user-event","type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238735706} -{"source":"user-event","type":"click","text":"ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n AI Assistant\n \n Summary\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n AI Mode\n Sidebar collapsée, pas de WidthToggle. ~50% page Elegant + ~50% panel AI avec résumé (Tldr) et chat Kapa inline.","choice":"ai","id":null,"timestamp":1778238737279} -{"source":"user-event","type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n ## Tab 1\n \n \n ## Tab 2\n \n \n \n \n \n \n \n \n \n \n \n Markdown Mode\n Tout en JetBrains Mono. Tabs aplatis en sections, pas de cards ni composants visuels. Admonitions conservés. WidthToggle visible.","choice":"markdown","id":null,"timestamp":1778238739110} -{"source":"user-event","type":"click","text":"Navigation\n \n \n \n \n \n \n \n \n \n ELEGANT\n MARKDOWN\n AI\n \n \n \n \n \n \n \n \n \n \n \n \n \n Tab 1\n Tab 2\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Elegant Mode\n La doc telle qu'elle est aujourd'hui. Tous les composants visuels, tabs, cards, sidebar ouverte, WidthToggle visible.","choice":"elegant","id":null,"timestamp":1778238740006} -{"type":"server-stopped","reason":"idle timeout"} diff --git a/.superpowers/brainstorm/61754-1778237530/state/server.pid b/.superpowers/brainstorm/61754-1778237530/state/server.pid deleted file mode 100644 index a67c7abfdf..0000000000 --- a/.superpowers/brainstorm/61754-1778237530/state/server.pid +++ /dev/null @@ -1 +0,0 @@ -61765 diff --git a/docs/superpowers/plans/2026-05-07-content-width-toggle.md b/docs/superpowers/plans/2026-05-07-content-width-toggle.md deleted file mode 100644 index 79b0e4f646..0000000000 --- a/docs/superpowers/plans/2026-05-07-content-width-toggle.md +++ /dev/null @@ -1,555 +0,0 @@ -# Content Width Toggle Implementation Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Add a 3-position content width toggle (Default/Wide/Max) to doc pages for accessibility. - -**Architecture:** A `data-content-width` attribute on `` drives a CSS custom property `--doc-content-max-width`. An inline script prevents FOUC by reading localStorage before React hydrates. A self-contained React component manages the toggle UI. - -**Tech Stack:** React, SCSS modules, localStorage, inline SVG icons, Docusaurus swizzle (wrap) - -**Target branch:** `next` - -**Spec:** `docs/superpowers/specs/2026-05-07-content-width-toggle-design.md` - ---- - -### File Map - -| Action | File | Responsibility | -|--------|------|---------------| -| Create | `docusaurus/src/components/WidthToggle/WidthToggle.js` | Toggle component (buttons, state, localStorage, DOM attribute) | -| Create | `docusaurus/src/components/WidthToggle/widthToggle.module.scss` | Toggle styles (segmented control, dark mode) | -| Create | `docusaurus/src/theme/DocItem/Layout/index.js` | Swizzle wrap to mount WidthToggle above doc content | -| Modify | `docusaurus/src/scss/_base.scss` | Replace hardcoded max-width with CSS variable, add transition | -| Modify | `docusaurus/docusaurus.config.js` | Add anti-FOUC inline script | - ---- - -### Task 1: Switch to `next` branch - -**Files:** None - -- [ ] **Step 1: Checkout next and pull latest** - -```bash -cd /Users/piwi/code/documentation -git checkout next -git pull origin next -``` - -- [ ] **Step 2: Verify clean state** - -```bash -git status -``` - -Expected: clean working tree on `next`. - ---- - -### Task 2: Add CSS custom property for content width - -**Files:** -- Modify: `docusaurus/src/scss/_base.scss` - -- [ ] **Step 1: Add width CSS variables to `:root` block** - -In `_base.scss`, after the existing `:root` block (line 7-9), add the content width variable. Then add the `data-content-width` attribute selectors. - -Find the existing `:root` block: - -```scss -:root { - --custom-selection-background-color: var(--strapi-primary-600); -} -``` - -Replace with: - -```scss -:root { - --custom-selection-background-color: var(--strapi-primary-600); - --doc-content-max-width: 720px; -} - -[data-content-width="wide"] { - --doc-content-max-width: 960px; -} - -[data-content-width="max"] { - --doc-content-max-width: 100%; -} -``` - -- [ ] **Step 2: Replace hardcoded mobile max-width with CSS variable** - -Find the mobile rule (line 35-44): - -```scss -main { - article:first-child:not(.col):not(.custom-doc-card), - article:first-child:not(.col) + nav { - max-width: 640px; - padding-left: 0 !important; - padding-right: 0 !important; - margin-left: auto; - margin-right: auto; - } -} -``` - -Replace with: - -```scss -main { - article:first-child:not(.col):not(.custom-doc-card), - article:first-child:not(.col) + nav { - max-width: var(--doc-content-max-width); - padding-left: 0 !important; - padding-right: 0 !important; - margin-left: auto; - margin-right: auto; - transition: max-width 0.4s cubic-bezier(0.16, 1, 0.3, 1); - } -} -``` - -Note: On mobile the toggle is hidden, and `640px` was already wider than most phone screens, so using the variable (720px default) is fine -- it will be clamped by the viewport anyway. - -- [ ] **Step 3: Replace hardcoded desktop max-width values** - -Find the desktop article rule inside `@include medium-up` (lines 52-58): - -```scss - article:first-child:not(.col):not(.custom-doc-card), - article:first-child:not(.col) + nav:not(.pagination-nav) { - max-width: 720px; - padding-left: 40px !important; - padding-right: 40px !important; - } -``` - -Replace with: - -```scss - article:first-child:not(.col):not(.custom-doc-card), - article:first-child:not(.col) + nav:not(.pagination-nav) { - max-width: var(--doc-content-max-width); - padding-left: 40px !important; - padding-right: 40px !important; - } -``` - -Find the pagination-nav rule (lines 60-64): - -```scss - article:first-child:not(.col) + nav.pagination-nav { - max-width: 720px; - padding-left: 0 !important; - padding-right: 0 !important; - } -``` - -Replace with: - -```scss - article:first-child:not(.col) + nav.pagination-nav { - max-width: var(--doc-content-max-width); - padding-left: 0 !important; - padding-right: 0 !important; - } -``` - -- [ ] **Step 4: Verify the build compiles** - -```bash -cd /Users/piwi/code/documentation/docusaurus && npm run build 2>&1 | tail -5 -``` - -Expected: build succeeds. No visual change yet (default is still 720px). - -- [ ] **Step 5: Commit** - -```bash -git add docusaurus/src/scss/_base.scss -git commit -m "Add CSS custom property for doc content width" -``` - ---- - -### Task 3: Add anti-FOUC inline script - -**Files:** -- Modify: `docusaurus/docusaurus.config.js` - -- [ ] **Step 1: Add inline script to the scripts array** - -In `docusaurus.config.js`, find the end of the `scripts` array. The last entry before the closing `]` of the scripts array. Add a new entry at the **beginning** of the `scripts` array (so it runs first), right after `scripts: [`: - -Find: - -```js - scripts: [ - { - src: '/js/redirector.js', - async: false, // Load synchronously to ensure it runs before page navigation - }, -``` - -Replace with: - -```js - scripts: [ - { - // Anti-FOUC: apply saved content width before React hydrates - tagName: 'script', - innerHTML: '(function(){try{var w=localStorage.getItem("strapi-content-width");if(w)document.documentElement.dataset.contentWidth=w}catch(e){}})();', - }, - { - src: '/js/redirector.js', - async: false, // Load synchronously to ensure it runs before page navigation - }, -``` - -Note: Docusaurus `scripts` supports inline scripts via `innerHTML` + `tagName: 'script'`. This runs synchronously before any other script. - -- [ ] **Step 2: Verify the build compiles** - -```bash -cd /Users/piwi/code/documentation/docusaurus && npm run build 2>&1 | tail -5 -``` - -Expected: build succeeds. - -- [ ] **Step 3: Commit** - -```bash -git add docusaurus/docusaurus.config.js -git commit -m "Add anti-FOUC script for content width preference" -``` - ---- - -### Task 4: Create WidthToggle component - -**Files:** -- Create: `docusaurus/src/components/WidthToggle/WidthToggle.js` - -- [ ] **Step 1: Create the component file** - -```jsx -import React, { useState, useEffect, useCallback } from 'react'; -import styles from './widthToggle.module.scss'; - -const STORAGE_KEY = 'strapi-content-width'; -const WIDTHS = [ - { value: 'default', label: 'Default width', viewBox: '0 0 20 16' , - path: 'M5 1h10a2 2 0 012 2v10a2 2 0 01-2 2H5a2 2 0 01-2-2V3a2 2 0 012-2z' }, - { value: 'wide', label: 'Wide', viewBox: '0 0 20 16', - path: 'M3 1h14a2 2 0 012 2v10a2 2 0 01-2 2H3a2 2 0 01-2-2V3a2 2 0 012-2z' }, - { value: 'max', label: 'Full width', viewBox: '0 0 20 16', - path: 'M1 1h18a1 1 0 011 1v12a1 1 0 01-1 1H1a1 1 0 01-1-1V2a1 1 0 011-1z' }, -]; - -function getInitialWidth() { - if (typeof window === 'undefined') return 'default'; - try { - return localStorage.getItem(STORAGE_KEY) || 'default'; - } catch { - return 'default'; - } -} - -export default function WidthToggle() { - const [width, setWidth] = useState(getInitialWidth); - - // Sync DOM attribute on mount and changes - useEffect(() => { - if (width === 'default') { - delete document.documentElement.dataset.contentWidth; - } else { - document.documentElement.dataset.contentWidth = width; - } - }, [width]); - - const handleChange = useCallback((value) => { - setWidth(value); - try { - if (value === 'default') { - localStorage.removeItem(STORAGE_KEY); - } else { - localStorage.setItem(STORAGE_KEY, value); - } - } catch { - // localStorage unavailable - } - }, []); - - const handleKeyDown = useCallback((e) => { - const currentIndex = WIDTHS.findIndex((w) => w.value === width); - let nextIndex; - if (e.key === 'ArrowRight' || e.key === 'ArrowDown') { - e.preventDefault(); - nextIndex = (currentIndex + 1) % WIDTHS.length; - } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') { - e.preventDefault(); - nextIndex = (currentIndex - 1 + WIDTHS.length) % WIDTHS.length; - } else { - return; - } - handleChange(WIDTHS[nextIndex].value); - }, [width, handleChange]); - - return ( -
- {WIDTHS.map((w) => { - const isActive = width === w.value; - return ( - - ); - })} -
- ); -} -``` - -- [ ] **Step 2: Commit** - -```bash -git add docusaurus/src/components/WidthToggle/WidthToggle.js -git commit -m "Add WidthToggle component with localStorage persistence" -``` - ---- - -### Task 5: Create WidthToggle styles - -**Files:** -- Create: `docusaurus/src/components/WidthToggle/widthToggle.module.scss` - -- [ ] **Step 1: Create the SCSS module** - -```scss -@use '../../scss/mixins' as *; - -.widthToggle { - display: none; - - @include medium-up { - display: inline-flex; - align-items: center; - gap: 2px; - padding: 3px; - border-radius: 8px; - background: var(--strapi-neutral-150); - float: right; - margin-bottom: 8px; - } -} - -.button { - display: flex; - align-items: center; - justify-content: center; - width: 32px; - height: 28px; - border: none; - border-radius: 6px; - background: transparent; - color: var(--ifm-color-emphasis-600); - cursor: pointer; - padding: 0; - transition: background-color 0.2s ease, color 0.2s ease; - - &:hover:not(.active) { - background: var(--strapi-neutral-200); - } - - svg { - display: block; - } -} - -.active { - background: var(--strapi-primary-600); - color: white; - - &:hover { - background: var(--strapi-primary-600); - } -} -``` - -- [ ] **Step 2: Verify the build compiles** - -```bash -cd /Users/piwi/code/documentation/docusaurus && npm run build 2>&1 | tail -5 -``` - -Expected: build succeeds (component not mounted yet, but SCSS module is valid). - -- [ ] **Step 3: Commit** - -```bash -git add docusaurus/src/components/WidthToggle/widthToggle.module.scss -git commit -m "Add WidthToggle styles with dark mode support" -``` - ---- - -### Task 6: Swizzle DocItem/Layout to mount the toggle - -**Files:** -- Create: `docusaurus/src/theme/DocItem/Layout/index.js` - -- [ ] **Step 1: Create the swizzle wrapper** - -```jsx -import React from 'react'; -import Layout from '@theme-original/DocItem/Layout'; -import WidthToggle from '@site/src/components/WidthToggle/WidthToggle'; - -export default function LayoutWrapper(props) { - return ( - <> - - - - ); -} -``` - -- [ ] **Step 2: Verify the build compiles** - -```bash -cd /Users/piwi/code/documentation/docusaurus && npm run build 2>&1 | tail -5 -``` - -Expected: build succeeds. The toggle is now mounted on every doc page. - -- [ ] **Step 3: Commit** - -```bash -git add docusaurus/src/theme/DocItem/Layout/index.js -git commit -m "Swizzle DocItem/Layout to mount width toggle" -``` - ---- - -### Task 7: Visual verification - -**Files:** None (manual testing) - -- [ ] **Step 1: Start dev server** - -```bash -cd /Users/piwi/code/documentation/docusaurus && npm run start -``` - -- [ ] **Step 2: Verify on a regular doc page** - -Open a regular doc page (e.g., http://localhost:3000/cms/intro). Check: -- Toggle appears top-right of content area -- Default button is active (blue background) -- Clicking Wide expands content to ~960px with smooth animation -- Clicking Max expands content to full available width -- Clicking Default returns to 720px -- Refresh the page: chosen width persists - -- [ ] **Step 3: Verify on an API page** - -Open an API page (e.g., http://localhost:3000/cms/api/document-service). Check: -- Toggle appears but API pages stay at full width regardless of selection -- No visual glitch or layout break - -- [ ] **Step 4: Verify dark mode** - -Toggle to dark mode via the theme switcher. Check: -- Active button has blue background, white icon (readable) -- Inactive buttons have appropriate contrast -- No color issues - -- [ ] **Step 5: Verify mobile** - -Resize browser below 996px. Check: -- Toggle is hidden -- Content is full-width as before - -- [ ] **Step 6: Verify keyboard navigation** - -Focus the toggle, use arrow keys. Check: -- Arrow Right/Down cycles forward through options -- Arrow Left/Up cycles backward -- Each option applies correctly - ---- - -### Task 8: Adjust TOC-less page padding for width modes - -**Files:** -- Modify: `docusaurus/src/scss/_base.scss` - -When wide or max width is selected, the `padding-right: 280px` on TOC-less pages should be removed so content can actually use the extra space. - -- [ ] **Step 1: Update the TOC-less padding rule** - -Find (inside `@include medium-up`): - -```scss - [class*="docMainContainer"] .row:not(:has(.col--3)) { - padding-right: 280px; - } -``` - -Replace with: - -```scss - [class*="docMainContainer"] .row:not(:has(.col--3)) { - padding-right: 280px; - } - - /** When wide or max width, remove the TOC-placeholder padding */ - [data-content-width="wide"] [class*="docMainContainer"] .row:not(:has(.col--3)), - [data-content-width="max"] [class*="docMainContainer"] .row:not(:has(.col--3)) { - padding-right: 0; - } -``` - -- [ ] **Step 2: Verify visually** - -On a page without TOC, check that Wide and Max modes use the full available space. - -- [ ] **Step 3: Commit** - -```bash -git add docusaurus/src/scss/_base.scss -git commit -m "Remove TOC-placeholder padding in wide and max width modes" -``` diff --git a/docs/superpowers/specs/2026-05-08-view-modes-design.md b/docs/superpowers/specs/2026-05-08-view-modes-design.md deleted file mode 100644 index d3804d8fc4..0000000000 --- a/docs/superpowers/specs/2026-05-08-view-modes-design.md +++ /dev/null @@ -1,211 +0,0 @@ -# View Modes: Elegant / Markdown / AI - -**Date:** 2026-05-08 -**Status:** Draft -**Branch:** Created from `next` - -## Overview - -Every documentation page offers 3 viewing modes, switchable via a control above the H1: - -- **Elegant** -- the documentation as it exists today, with all visual components -- **Markdown** -- stripped-down, monospace rendering with no tabs, cards, or complex visual components -- **AI** -- a side panel occupying 50% of the viewport with a page summary and conversational AI chat - -### Goals - -1. **Accessibility / reading preference** -- some developers prefer raw markdown, others a polished site -2. **Efficiency by context** -- Elegant for discovery, Markdown for quick copy-paste, AI for deep exploration -3. **Differentiation** -- an innovative documentation experience that no one else offers - -## Architecture - -**Approach:** React Context + CSS Data Attributes - -A `ViewModeProvider` context wraps the app at the `Root.js` level. The active mode is reflected on ``. Components that need structural changes read the context via `useViewMode()`. Pure visual changes (font, spacing) are handled in CSS via the data attribute selector. - -This follows the existing pattern: `WidthToggle` already uses `data-content-width` on ``. - -### Component overview - -``` -Root.js - |-- ViewModeProvider (new) - | |-- viewMode state - | |-- localStorage sync (elegant/markdown only) - | |-- dispatches CustomEvent('view-mode-change') - | - |-- ReadingProgressBar (existing) - |-- KapaThemeInjector (existing) - | - DocItemLayout (swizzled) - |-- ViewModeSwitcher (new, above H1) - |-- WidthToggle (existing, hidden in AI mode) - |-- DocItemContent - | |-- Tabs (modified: renders flat sections in markdown mode) - | |-- Cards (modified: renders as list in markdown mode) - | |-- Admonitions (unchanged) - | |-- Code blocks (unchanged) - | - |-- AiPanel (new, mounted when viewMode === 'ai') -``` - -## Section 1: Mode Switcher - -### Component: `ViewModeSwitcher` - -Injected in the swizzled `DocItemLayout`, positioned above the H1. - -**Visual design:** -- 3 text buttons: `ELEGANT MODE`, `MARKDOWN MODE`, `AI MODE` -- Font: `var(--strapi-font-family-technical)` (JetBrains Mono), uppercase -- Size: 12-13px (consistent with breadcrumbs) -- Spacing: ~16px gap between buttons -- Active state: `color: var(--strapi-primary-600)`, `border-bottom: 2px solid var(--strapi-primary-600)` -- Inactive state: `color: var(--strapi-neutral-500)`, hover to `var(--strapi-neutral-700)` -- Style: minimal tab bar, no background - -### Persistence - -- `localStorage.setItem('strapi-view-mode', 'elegant'|'markdown')` -- AI mode is **never persisted** -- always starts as off -- Default: `'elegant'` - -### Anti-FOUC - -An inline script in `headTags` (same pattern as the existing WidthToggle anti-FOUC script) reads localStorage and applies `data-view-mode` on `` before React hydrates: - -```javascript -(function() { - var mode = localStorage.getItem('strapi-view-mode') || 'elegant'; - document.documentElement.setAttribute('data-view-mode', mode); -})(); -``` - -## Section 2: ViewModeProvider - -### React Context - -``` -ViewModeContext - state: viewMode: 'elegant' | 'markdown' | 'ai' - actions: setViewMode(mode) - hook: useViewMode() -> { viewMode, setViewMode } -``` - -**Provider behavior:** -- Reads `localStorage.strapi-view-mode` on mount, fallback to `'elegant'` -- On `setViewMode(mode)`: - - Updates React state - - Sets `document.documentElement.dataset.viewMode = mode` - - If mode is `'elegant'` or `'markdown'`: writes to localStorage - - Dispatches `CustomEvent('view-mode-change', { detail: { mode } })` - -**Sidebar integration:** -- The sidebar already listens to custom events (`sidebar-v3-toggle`) -- On receiving `view-mode-change` with `mode: 'ai'`: - - Store current sidebar state (expanded/collapsed) - - Collapse the sidebar -- On receiving `view-mode-change` with `mode !== 'ai'`: - - Restore the previously stored sidebar state - -**Location:** Added in `Root.js`, wrapping children alongside existing providers. - -## Section 3: Markdown Mode - -When `data-view-mode="markdown"` is set on ``: - -### CSS changes (global, no React logic) - -- All article content: `font-family: var(--strapi-font-family-technical)` (JetBrains Mono) -- Body font size reduced to ~14px (compensates for monospace width) -- Headings remain visually distinct but in monospace -- Card grids neutralized: `display: block` instead of `grid`/`flex` -- Decorative elements (card borders, shadows, backgrounds) simplified or removed - -### Component modifications (via `useViewMode()`) - -**Tabs (structural change required):** -- Instead of rendering a tabbed panel with tab headers, renders ALL tab panels sequentially -- Each panel is preceded by a heading `### {tab label}` -- This is the only component requiring a true structural change - -**Cards (if used as grids):** -- Rendered as a simple vertical list - -### Unchanged - -- Admonitions -- kept as-is (they exist in standard Markdown) -- Code blocks -- already monospace -- Images -- kept -- TOC -- kept -- Sidebar -- visible and functional -- WidthToggle -- visible and functional - -## Section 4: AI Mode - -### Activation flow - -1. User clicks "AI MODE" in the switcher -2. Provider sets `viewMode: 'ai'` -3. Sidebar receives `view-mode-change` event and collapses (storing previous state) -4. WidthToggle hides via CSS: `[data-view-mode="ai"] .width-toggle { display: none }` -5. `AiPanel` component mounts and slides in from the right - -### Layout - -- **Panel:** `position: fixed`, right side, `width: 50vw`, `height: calc(100vh - var(--ifm-navbar-height))` -- **Main content:** `[data-view-mode="ai"] .main-wrapper { width: 50vw }` -- stays in Elegant mode (all visual components) -- **Transition:** `transform: translateX(100%) -> translateX(0)`, `0.4s cubic-bezier(0.16, 1, 0.3, 1)` (same easing as sidebar) - -### Panel content - -1. **Header:** Title "AI Assistant" + close button (X) that deactivates AI mode -2. **Summary:** Displays the `` content of the current page. If no Tldr exists: "No summary available for this page" -3. **Separator + prompt:** "What would you like to know more about this topic?" -4. **Chat area:** Uses Kapa in embed/inline mode (to be investigated). MVP fallback: button that opens the classic Kapa modal with the page context pre-filled -5. **Input field:** Fixed at the bottom of the panel - -### Navigation behavior - -- When the page changes while AI mode is active: - - Summary updates to the new page's Tldr - - Chat history is reset - - Panel remains open - -### Deactivation flow - -1. User clicks "ELEGANT" or "MARKDOWN" in the switcher, or the close button in the panel -2. Panel slides out to the right -3. Sidebar restores its previous state -4. WidthToggle reappears - -## Section 5: Responsive - -### Mobile (< 768px) - -- Mode switcher is visible, all 3 modes available -- AI mode: panel opens in **full-screen** (`100vw`, `100vh`) overlaying the page -- A back button in the panel header returns to the page -- Elegant and Markdown modes work normally - -### Tablet (768px - 1024px) - -- All 3 modes available -- AI mode: panel takes ~60% width, content takes ~40% -- Sidebar is forced collapsed in AI mode - -### Desktop (> 1024px) - -- Nominal behavior as described above -- Panel: 50% width, content: 50% - -## Dark mode - -All 3 modes must work in both light and dark themes. The existing `@include dark { }` mixin pattern is used for all new CSS. The AI panel follows the same color token system (`--strapi-neutral-*`, `--strapi-primary-*`) that adapts automatically to the active theme. - -## Open questions - -1. **Kapa embed mode:** Does Kapa offer an inline/embed mode (not modal)? This needs investigation. If not available, the MVP fallback is a button in the panel that opens the existing Kapa modal with page context pre-filled. -2. **Naming:** "Elegant Mode" is a working name. Final name TBD before launch. -3. **Tldr coverage:** Not all pages have a `` component. Strategy for pages without one: show "No summary available" for MVP, consider build-time generation later. From 64fb1fef37fd4fea5e41a8244ca8150b12a7377b Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 18:54:24 +0200 Subject: [PATCH 19/51] Fix broken link to strapi-mcp-server page Co-Authored-By: Claude Opus 4.6 (1M context) --- docusaurus/docs/cms/ai/for-content-managers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/ai/for-content-managers.md b/docusaurus/docs/cms/ai/for-content-managers.md index 6d94e802b2..77ea404ee6 100644 --- a/docusaurus/docs/cms/ai/for-content-managers.md +++ b/docusaurus/docs/cms/ai/for-content-managers.md @@ -69,4 +69,4 @@ All AI requests are processed through Strapi-managed infrastructure. Content is Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that lets AI clients like Claude, Cursor, or any MCP-compatible tool manage your content through natural language. Once enabled and connected, an AI assistant can create, read, update, delete, publish, and unpublish entries directly through Strapi's Content Manager -- all gated by admin token permissions. - + From 446895e1d0f0b7114937b3af1eff9fa5b53ba81f Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 19:49:11 +0200 Subject: [PATCH 20/51] Fix known limitations heading --- docusaurus/docs/cms/features/strapi-mcp-server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 14c87aa0ce..7954ee8399 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -256,7 +256,7 @@ This means you can create tokens with fine-grained access: Create dedicated admin tokens for each AI client or use case. Use the most restrictive permissions that still allow the AI to accomplish its task. ::: -## Known limitations +### Known limitations The MCP server has the following limitations: From 4e342ca992d172111cc1bf87ba6b32d143c05b84 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Wed, 20 May 2026 19:49:16 +0200 Subject: [PATCH 21/51] Fix card description --- docusaurus/docs/cms/ai/for-content-managers.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docusaurus/docs/cms/ai/for-content-managers.md b/docusaurus/docs/cms/ai/for-content-managers.md index 77ea404ee6..950ba0be6a 100644 --- a/docusaurus/docs/cms/ai/for-content-managers.md +++ b/docusaurus/docs/cms/ai/for-content-managers.md @@ -67,6 +67,6 @@ All AI requests are processed through Strapi-managed infrastructure. Content is ## Strapi MCP server -Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that lets AI clients like Claude, Cursor, or any MCP-compatible tool manage your content through natural language. Once enabled and connected, an AI assistant can create, read, update, delete, publish, and unpublish entries directly through Strapi's Content Manager -- all gated by admin token permissions. +Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that lets AI clients like Claude, Cursor, or any MCP-compatible tool manage your content through natural language. Once enabled and connected, an AI assistant can create, read, update, delete, publish, and unpublish entries directly through Strapi's Content Manager, all gated by admin token permissions. - + From d1c332bd937eb29f9f3ccb81eded42ea270bda7e Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 10:16:11 +0200 Subject: [PATCH 22/51] Update MCP server docs with advanced config, blocks schema, and stateless architecture --- docusaurus/docs/cms/faq.md | 5 +- .../docs/cms/features/strapi-mcp-server.md | 90 ++++++++++++++++-- docusaurus/static/llms-code.txt | 16 ++++ docusaurus/static/llms-full.txt | 94 ++++++++++++++++--- 4 files changed, 183 insertions(+), 22 deletions(-) diff --git a/docusaurus/docs/cms/faq.md b/docusaurus/docs/cms/faq.md index 3aaab60456..0ee43d07ac 100644 --- a/docusaurus/docs/cms/faq.md +++ b/docusaurus/docs/cms/faq.md @@ -152,5 +152,6 @@ You can see the ) server is in [development](https://github.com/strapi/strapi/discussions/25398) and will be available soon. -Meanwhile, a different [MCP server for Strapi Docs](https://docs.strapi.io/cms/ai/for-developers#docs-mcp) is already available. +Yes. Strapi includes a built-in MCP () server that exposes content management tools to AI clients. See the [MCP server feature page](/cms/features/strapi-mcp-server) for configuration and usage details. + +A separate [MCP server for Strapi Docs](/cms/ai/for-developers#mcp) is also available for querying the Strapi documentation. diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 7954ee8399..3a3e8a5a23 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -92,6 +92,24 @@ export default config; Once the setting is in place, restart Strapi. The MCP endpoint becomes available at `/mcp` on your Strapi server (e.g., `http://localhost:1337/mcp`). +#### Advanced options + +The following optional keys can be added to the `mcp` configuration object: + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | Boolean | `false` | Enable or disable the MCP server. | +| `connectTimeoutMs` | Number | `5000` | Maximum time (in ms) for the internal MCP transport to connect before the request is aborted. | +| `requestTimeoutMs` | Number | `60000` | Maximum time (in ms) for a single MCP request to complete before it times out. | + +```js title="config/server.js" +mcp: { + enabled: true, + connectTimeoutMs: 10000, // 10 seconds + requestTimeoutMs: 120000, // 2 minutes +}, +``` + ### AI client configuration Once you enabled and configured the MCP server through Strapi's admin panel (admin tokens) and configuration filters, you must connect your AI client to the Strapi MCP server. @@ -195,6 +213,8 @@ The MCP server uses the Streamable HTTP transport protocol. Any MCP-compatible c ### Available tools +#### Content-type tools + For each content type the token has access to, Strapi generates up to 8 tools: | Tool | Action | Permission required | Description | @@ -214,6 +234,16 @@ Tool names follow the pattern `cm___`. For example, an Single types follow a similar pattern but include `_single_` in the name (e.g., `cm_api_homepage_single_get`). +#### Built-in utility tools + +In addition to content-type tools, Strapi registers the following built-in tools: + +| Tool | Availability | Description | +|------|-------------|-------------| +| `log` | Development mode only | Logs a message to the Strapi server console at a specified level (`info`, `warn`, `error`, `http`, `log`). Useful for debugging MCP interactions. | + +Built-in utility tools are only available in development mode (when `autoReload` is enabled) and do not require specific content-type permissions. + ### Managing content through prompts Once connected, you can interact with your Strapi content using natural language: @@ -229,21 +259,55 @@ Once connected, you can interact with your Strapi content using natural language ### Understanding input schemas -Each tool has an input schema derived from your content type's attributes. The schema is dynamically adjusted per session based on the token's permissions: +Each tool has an input schema derived from your content type's attributes. The schema is dynamically generated per session based on the token's permissions: + +- **Field-level permissions**: If the token restricts access to certain fields, those fields are excluded from both input and output schemas. For instance, a token that can only read `title` and `slug` on an `Article` type will only see those two fields in sort, filter, and output schemas. +- **Locale-level permissions**: If the [Internationalization (i18n)](/cms/features/internationalization) plugin is installed and the token restricts access to certain locales, the `locale` parameter only accepts the permitted locales for each action. Locale restrictions are evaluated per action: a token might allow reading in `en` and `fr` but only creating in `en`. +- **Write operations**: The `data` object in `create` and `update` tools only includes fields the token has permission to write. Unknown fields are rejected (strict validation). System-managed fields (`id`, `documentId`, `createdAt`, `updatedAt`, `publishedAt`, `createdBy`, `updatedBy`) and private fields are excluded automatically. +- **Attribute type mapping**: Field schemas carry constraints from your content-type definition, such as `required`, `minLength`, `maxLength`, `min`, `max`, and `enum` values. Enumeration fields expose their allowed values in the schema so the AI client can pick valid options. + +#### Sorting + +The `list` tool accepts a `sort` parameter that supports four notations: -- **Field-level permissions**: If the token restricts access to certain fields, those fields are excluded from both input and output schemas. -- **Locale-level permissions**: If the token restricts access to certain locales, the `locale` parameter only accepts permitted locales. -- **Write operations**: The `data` object only includes fields the token has permission to write. Unknown fields are rejected. +| Notation | Example | +|----------|---------| +| String | `"title:asc"` | +| Array of strings | `["title:asc", "createdAt:desc"]` | +| Object | `{ "title": "asc" }` | +| Array of objects | `[{ "title": "asc" }, { "createdAt": "desc" }]` | -For the `list` tool, the input schema also includes parameters for pagination (`page`, `pageSize`), sorting (`sort`), and filtering (`filters`). +Sort field names are constrained to the content type's scalar attributes (strings, numbers, booleans, dates, enumerations). Relation, component, dynamic zone, media, and JSON fields cannot be sorted on. + +#### Filtering + +The `list` tool accepts a `filters` parameter using Strapi's filter syntax: + +- **Field operators**: `$eq`, `$ne`, `$in`, `$notIn`, `$lt`, `$lte`, `$gt`, `$gte`, `$contains`, `$notContains`, `$startsWith`, `$endsWith`, `$null`, `$notNull`, and their case-insensitive variants (`$eqi`, `$nei`, `$containsi`, etc.). +- **Logical operators**: `$and`, `$or` (accept arrays of filter objects), `$not` (wraps a single filter object). +- **Implicit equality**: Passing a value directly (e.g., `{ "title": "Hello" }`) is equivalent to `{ "title": { "$eq": "Hello" } }`. + +Like sort fields, filter fields are constrained to scalar attributes only. + +#### Pagination + +The `list` tool also accepts `page` (1-indexed, default: 1) and `pageSize` (default: 25, max: 100) parameters. + +#### Rich text (blocks) + +Rich text fields using the [Blocks editor](/cms/features/content-type-builder#rich-text-blocks) are represented with a structured schema in tool definitions. The schema covers all block types: paragraphs, headings (levels 1–6), quotes, code blocks (with optional language), ordered and unordered lists (including nested lists), images, and inline nodes (text with formatting marks, links). ### Permission boundaries -The MCP server enforces the same permission model as the Strapi admin panel. Permissions are checked at two levels: +The MCP server enforces the same permission model as the Strapi admin panel. Permissions are checked at multiple levels: 1. **Tool visibility**: When an AI client connects, Strapi checks the admin token's permissions and only exposes tools the token has access to. If the token does not grant `delete` on `Article`, the AI client will not see a delete tool for articles at all. -2. **Field and locale filtering**: Even within an exposed tool, input and output schemas are narrowed to the fields and locales the token can access. If the token grants `read` on `Article` but excludes the `body` field, the AI client will not see or receive `body` content. +2. **Field filtering**: Even within an exposed tool, input and output schemas are narrowed to the fields the token can access. If the token grants `read` on `Article` but excludes the `body` field, the AI client will not see or receive `body` content. Field restrictions are applied independently per action: write schemas (`create`, `update`) only include fields permitted for the corresponding action. + +3. **Locale filtering**: When the [Internationalization (i18n)](/cms/features/internationalization) plugin is installed and locale-level permissions are configured, the `locale` parameter is narrowed per action. For example, a token might allow reading content in `en` and `fr` but only creating content in `en`. If the default locale is permitted for a given action, it is applied as the Zod schema default so the AI client does not need to specify it explicitly. + +4. **Runtime enforcement**: Beyond schema-level narrowing, each handler calls Strapi's permission checker at runtime to verify access on the specific document being read, written, or published. Condition-based permissions (e.g., "only update entries you own") are enforced at this level. This means you can create tokens with fine-grained access: @@ -256,11 +320,19 @@ This means you can create tokens with fine-grained access: Create dedicated admin tokens for each AI client or use case. Use the most restrictive permissions that still allow the AI to accomplish its task. ::: +### Stateless architecture + +The MCP server uses a stateless architecture. Each POST request to the `/mcp` endpoint creates a fresh, ephemeral MCP server instance scoped to the authenticated token's permissions. There is no session persistence between requests: every request is independently authenticated and authorized. This design means the AI client does not need to manage session IDs, and permission changes (such as revoking a token or updating its permissions) take effect on the next request. + +GET and DELETE HTTP methods on the `/mcp` endpoint return a `405 Method Not Allowed` JSON-RPC error, as the MCP server only accepts POST requests. + ### Known limitations The MCP server has the following limitations: -- **Block content**: Rich text block content is not represented in tool definitions. -- **Components**: Component fields are passed as untyped (`any`) in tool schemas. +- **Components**: Component fields are passed as untyped (`any`) in tool schemas. The AI client can read and write component data, but the schema does not describe the component's internal structure. - **Dynamic zones**: Dynamic zone fields are passed as untyped arrays in tool schemas. +- **Relations**: Relation fields accept document IDs (e.g., `"z7v8zma53x01r6oceimv922b"`) as input. The advanced `connect`/`disconnect` relation syntax is not yet supported in MCP tool schemas. - **Nested population parameters**: The `list` and `get` tools do not support nested population parameters for relations. +- **Media upload**: Media fields accept existing media asset references but the MCP server cannot upload new files. Use Strapi's media library or upload API to add files first, then reference them in MCP tool calls. +- **Custom fields**: Custom fields registered via plugins are mapped to their underlying Strapi type. If the custom field registry is not populated when MCP tools are registered, the field falls back to `unknown`. diff --git a/docusaurus/static/llms-code.txt b/docusaurus/static/llms-code.txt index 0e907fb2e7..47eca924e2 100644 --- a/docusaurus/static/llms-code.txt +++ b/docusaurus/static/llms-code.txt @@ -23986,6 +23986,22 @@ export default config; ``` +## Advanced options +Description: | Option | Type | Default | Description | |--------|------|---------|-------------| | enabled | Boolean | false | Enable or disable the MCP server. +(Source: https://docs.strapi.io/cms/features/strapi-mcp-server#advanced-options) + +Language: JavaScript +File path: config/server.js + +```js +mcp: { + enabled: true, + connectTimeoutMs: 10000, // 10 seconds + requestTimeoutMs: 120000, // 2 minutes +}, +``` + + ## Connecting Claude Desktop Description: Add the Strapi MCP server to Claude's configuration file, as in the following example, replacing YOURADMINTOKEN with the admin token value copied from the admin panel: (Source: https://docs.strapi.io/cms/features/strapi-mcp-server#connecting-claude-desktop) diff --git a/docusaurus/static/llms-full.txt b/docusaurus/static/llms-full.txt index 7b7c40820f..e6e584c296 100644 --- a/docusaurus/static/llms-full.txt +++ b/docusaurus/static/llms-full.txt @@ -1911,7 +1911,7 @@ All AI requests are processed through Strapi-managed infrastructure. Content is ## Strapi MCP server -Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that lets AI clients like Claude, Cursor, or any MCP-compatible tool manage your content through natural language. Once enabled and connected, an AI assistant can create, read, update, delete, publish, and unpublish entries directly through Strapi's Content Manager -- all gated by admin token permissions. +Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that lets AI clients like Claude, Cursor, or any MCP-compatible tool manage your content through natural language. Once enabled and connected, an AI assistant can create, read, update, delete, publish, and unpublish entries directly through Strapi's Content Manager, all gated by admin token permissions. @@ -9634,6 +9634,24 @@ Enable the MCP server by adding the `mcp` object to the server configuration fil Once the setting is in place, restart Strapi. The MCP endpoint becomes available at `/mcp` on your Strapi server (e.g., `http://localhost:1337/mcp`). +#### Advanced options + +The following optional keys can be added to the `mcp` configuration object: + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | Boolean | `false` | Enable or disable the MCP server. | +| `connectTimeoutMs` | Number | `5000` | Maximum time (in ms) for the internal MCP transport to connect before the request is aborted. | +| `requestTimeoutMs` | Number | `60000` | Maximum time (in ms) for a single MCP request to complete before it times out. | + +```js title="config/server.js" +mcp: { + enabled: true, + connectTimeoutMs: 10000, // 10 seconds + requestTimeoutMs: 120000, // 2 minutes +}, +``` + ### AI client configuration Once you enabled and configured the MCP server through Strapi's admin panel (admin tokens) and configuration filters, you must connect your AI client to the Strapi MCP server. @@ -9737,6 +9755,8 @@ The MCP server uses the Streamable HTTP transport protocol. Any MCP-compatible c ### Available tools +#### Content-type tools + For each content type the token has access to, Strapi generates up to 8 tools: | Tool | Action | Permission required | Description | @@ -9756,6 +9776,16 @@ Tool names follow the pattern `cm___`. For example, an Single types follow a similar pattern but include `_single_` in the name (e.g., `cm_api_homepage_single_get`). +#### Built-in utility tools + +In addition to content-type tools, Strapi registers the following built-in tools: + +| Tool | Availability | Description | +|------|-------------|-------------| +| `log` | Development mode only | Logs a message to the Strapi server console at a specified level (`info`, `warn`, `error`, `http`, `log`). Useful for debugging MCP interactions. | + +Built-in utility tools are only available in development mode (when `autoReload` is enabled) and do not require specific content-type permissions. + ### Managing content through prompts Once connected, you can interact with your Strapi content using natural language: @@ -9771,21 +9801,55 @@ Once connected, you can interact with your Strapi content using natural language ### Understanding input schemas -Each tool has an input schema derived from your content type's attributes. The schema is dynamically adjusted per session based on the token's permissions: +Each tool has an input schema derived from your content type's attributes. The schema is dynamically generated per session based on the token's permissions: + +- **Field-level permissions**: If the token restricts access to certain fields, those fields are excluded from both input and output schemas. For instance, a token that can only read `title` and `slug` on an `Article` type will only see those two fields in sort, filter, and output schemas. +- **Locale-level permissions**: If the [Internationalization (i18n)](/cms/features/internationalization) plugin is installed and the token restricts access to certain locales, the `locale` parameter only accepts the permitted locales for each action. Locale restrictions are evaluated per action: a token might allow reading in `en` and `fr` but only creating in `en`. +- **Write operations**: The `data` object in `create` and `update` tools only includes fields the token has permission to write. Unknown fields are rejected (strict validation). System-managed fields (`id`, `documentId`, `createdAt`, `updatedAt`, `publishedAt`, `createdBy`, `updatedBy`) and private fields are excluded automatically. +- **Attribute type mapping**: Field schemas carry constraints from your content-type definition, such as `required`, `minLength`, `maxLength`, `min`, `max`, and `enum` values. Enumeration fields expose their allowed values in the schema so the AI client can pick valid options. + +#### Sorting -- **Field-level permissions**: If the token restricts access to certain fields, those fields are excluded from both input and output schemas. -- **Locale-level permissions**: If the token restricts access to certain locales, the `locale` parameter only accepts permitted locales. -- **Write operations**: The `data` object only includes fields the token has permission to write. Unknown fields are rejected. +The `list` tool accepts a `sort` parameter that supports four notations: -For the `list` tool, the input schema also includes parameters for pagination (`page`, `pageSize`), sorting (`sort`), and filtering (`filters`). +| Notation | Example | +|----------|---------| +| String | `"title:asc"` | +| Array of strings | `["title:asc", "createdAt:desc"]` | +| Object | `{ "title": "asc" }` | +| Array of objects | `[{ "title": "asc" }, { "createdAt": "desc" }]` | + +Sort field names are constrained to the content type's scalar attributes (strings, numbers, booleans, dates, enumerations). Relation, component, dynamic zone, media, and JSON fields cannot be sorted on. + +#### Filtering + +The `list` tool accepts a `filters` parameter using Strapi's filter syntax: + +- **Field operators**: `$eq`, `$ne`, `$in`, `$notIn`, `$lt`, `$lte`, `$gt`, `$gte`, `$contains`, `$notContains`, `$startsWith`, `$endsWith`, `$null`, `$notNull`, and their case-insensitive variants (`$eqi`, `$nei`, `$containsi`, etc.). +- **Logical operators**: `$and`, `$or` (accept arrays of filter objects), `$not` (wraps a single filter object). +- **Implicit equality**: Passing a value directly (e.g., `{ "title": "Hello" }`) is equivalent to `{ "title": { "$eq": "Hello" } }`. + +Like sort fields, filter fields are constrained to scalar attributes only. + +#### Pagination + +The `list` tool also accepts `page` (1-indexed, default: 1) and `pageSize` (default: 25, max: 100) parameters. + +#### Rich text (blocks) + +Rich text fields using the [Blocks editor](/cms/features/content-type-builder#rich-text-blocks) are represented with a structured schema in tool definitions. The schema covers all block types: paragraphs, headings (levels 1–6), quotes, code blocks (with optional language), ordered and unordered lists (including nested lists), images, and inline nodes (text with formatting marks, links). ### Permission boundaries -The MCP server enforces the same permission model as the Strapi admin panel. Permissions are checked at two levels: +The MCP server enforces the same permission model as the Strapi admin panel. Permissions are checked at multiple levels: 1. **Tool visibility**: When an AI client connects, Strapi checks the admin token's permissions and only exposes tools the token has access to. If the token does not grant `delete` on `Article`, the AI client will not see a delete tool for articles at all. -2. **Field and locale filtering**: Even within an exposed tool, input and output schemas are narrowed to the fields and locales the token can access. If the token grants `read` on `Article` but excludes the `body` field, the AI client will not see or receive `body` content. +2. **Field filtering**: Even within an exposed tool, input and output schemas are narrowed to the fields the token can access. If the token grants `read` on `Article` but excludes the `body` field, the AI client will not see or receive `body` content. Field restrictions are applied independently per action: write schemas (`create`, `update`) only include fields permitted for the corresponding action. + +3. **Locale filtering**: When the [Internationalization (i18n)](/cms/features/internationalization) plugin is installed and locale-level permissions are configured, the `locale` parameter is narrowed per action. For example, a token might allow reading content in `en` and `fr` but only creating content in `en`. If the default locale is permitted for a given action, it is applied as the Zod schema default so the AI client does not need to specify it explicitly. + +4. **Runtime enforcement**: Beyond schema-level narrowing, each handler calls Strapi's permission checker at runtime to verify access on the specific document being read, written, or published. Condition-based permissions (e.g., "only update entries you own") are enforced at this level. This means you can create tokens with fine-grained access: @@ -9798,14 +9862,22 @@ This means you can create tokens with fine-grained access: Create dedicated admin tokens for each AI client or use case. Use the most restrictive permissions that still allow the AI to accomplish its task. ::: -## Known limitations +### Stateless architecture + +The MCP server uses a stateless architecture. Each POST request to the `/mcp` endpoint creates a fresh, ephemeral MCP server instance scoped to the authenticated token's permissions. There is no session persistence between requests: every request is independently authenticated and authorized. This design means the AI client does not need to manage session IDs, and permission changes (such as revoking a token or updating its permissions) take effect on the next request. + +GET and DELETE HTTP methods on the `/mcp` endpoint return a `405 Method Not Allowed` JSON-RPC error, as the MCP server only accepts POST requests. + +### Known limitations The MCP server has the following limitations: -- **Block content**: Rich text block content is not represented in tool definitions. -- **Components**: Component fields are passed as untyped (`any`) in tool schemas. +- **Components**: Component fields are passed as untyped (`any`) in tool schemas. The AI client can read and write component data, but the schema does not describe the component's internal structure. - **Dynamic zones**: Dynamic zone fields are passed as untyped arrays in tool schemas. +- **Relations**: Relation fields accept document IDs (e.g., `"z7v8zma53x01r6oceimv922b"`) as input. The advanced `connect`/`disconnect` relation syntax is not yet supported in MCP tool schemas. - **Nested population parameters**: The `list` and `get` tools do not support nested population parameters for relations. +- **Media upload**: Media fields accept existing media asset references but the MCP server cannot upload new files. Use Strapi's media library or upload API to add files first, then reference them in MCP tool calls. +- **Custom fields**: Custom fields registered via plugins are mapped to their underlying Strapi type. If the custom field registry is not populated when MCP tools are registered, the field falls back to `unknown`. From d852174d317d3af1cc1b68e0a7ac018e9d69d1b8 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 10:57:47 +0200 Subject: [PATCH 23/51] Fix style, coherence, and technical accuracy issues from auto-review --- docusaurus/docs/cms/ai/docs-mcp-server.md | 6 +-- docusaurus/docs/cms/ai/for-developers.md | 4 +- .../docs/cms/features/strapi-mcp-server.md | 48 ++++++++++--------- docusaurus/sidebars.js | 5 ++ 4 files changed, 36 insertions(+), 27 deletions(-) diff --git a/docusaurus/docs/cms/ai/docs-mcp-server.md b/docusaurus/docs/cms/ai/docs-mcp-server.md index 8e09458a8a..fefd1a02c7 100644 --- a/docusaurus/docs/cms/ai/docs-mcp-server.md +++ b/docusaurus/docs/cms/ai/docs-mcp-server.md @@ -27,7 +27,7 @@ The Docs [MCP](https://modelcontextprotocol.io) (Model Context Protocol) server Strapi offers 2 different MCP servers: - the Docs MCP server, covered on the present page, -- and the Strapi MCP for content management, covered on its [dedicated feature page](/cms/features/strapi-mcp-server). +- and the Strapi MCP server for content management, covered on its [dedicated feature page](/cms/features/strapi-mcp-server). ::: ## Compatible tools @@ -55,7 +55,7 @@ When opening the Ask AI window, you should see a **Use MCP** dropdown in the top If manual MCP server configuration is required: 1. Click the **Copy MCP URL** from the dropdown. The server URL should be: `https://strapi-docs.mcp.kapa.ai` -2. Update the MCP server configuration in your IDE: +2. Add the server to your IDE's MCP configuration file: @@ -110,4 +110,4 @@ Once connected, your AI coding assistant can query the Strapi documentation dire :::tip For docs-related questions, start your prompts with `Use the strapi-docs MCP server to answer:`. This will ensure the tool queries docs.strapi.io instead of returning answers based on its training data, which can be outdated. -::: \ No newline at end of file +::: diff --git a/docusaurus/docs/cms/ai/for-developers.md b/docusaurus/docs/cms/ai/for-developers.md index e8922bf71c..37d347bf78 100644 --- a/docusaurus/docs/cms/ai/for-developers.md +++ b/docusaurus/docs/cms/ai/for-developers.md @@ -110,13 +110,13 @@ The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open s - + ## Tips for better results {#tips} The following tips will help you fine-tune your prompts to get the best results: -- Use the [Docs MCP server](/cms/ai/docs-mcp-server) in your IDE for the fastest developer experience. For docs-related questions, start your prompts with `Use the strapi-docs MCP server to answer:`. This will ensure the tool queries docs.strapi.io instead of creating answers based on its training data. +- Use the [Docs MCP server](/cms/ai/docs-mcp-server) in your IDE for the fastest developer experience. For docs-related questions, prefix your prompt with `Use the strapi-docs MCP server to answer:` so the tool queries docs.strapi.io instead of using potentially outdated training data. - Include the page URL so the assistant grounds its answer in the right context. - Mention your Strapi version (e.g., Strapi 5) to avoid outdated suggestions. - Pair code examples with their source page when sharing snippets from `llms-code.txt`. diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 3a3e8a5a23..b8383739bd 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -18,11 +18,11 @@ import TabItem from '@theme/TabItem'; -Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server. Once enabled, it lets AI clients create, read, update, delete, publish, and unpublish content directly through Strapi's Content Manager. All operations are gated by admin token permissions. +Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server. Once enabled, it lets AI clients create, read, update, delete, publish, and unpublish content directly through Strapi's Content Manager. All operations are gated by Admin token permissions. -The MCP server exposes a set of content management tools to AI clients such as Claude Desktop, Claude Code, Cursor, or any MCP-compatible tool. An AI assistant connected to the MCP server can, for example, create a blog article, list recent entries, or publish a page. Which tools are available depends on the permissions granted to the admin token used for authentication. +The MCP server exposes a set of content management tools to AI clients such as Claude Desktop, Claude Code, Cursor, or any MCP-compatible tool. An AI assistant connected to the MCP server can, for example, create a blog article, list recent entries, or publish a page. Which tools are available depends on the permissions granted to the Admin token used for authentication. Free feature @@ -34,18 +34,9 @@ The MCP server exposes a set of content management tools to AI clients such as C ## Configuration Before first use, the Strapi MCP server must be: -- configured in Strapi through the server configuration file and authenticated with Admin tokens created in the admin panel +- enabled through the server configuration file and authenticated with Admin tokens created in the admin panel - connected to your AI client. -### Strapi admin panel configuration - -The MCP server authenticates requests using Admin tokens. Each MCP session is scoped to the permissions of the token used to connect: - -1. Create a new admin token (see [Creating an admin token](/cms/features/admin-tokens#creating-a-new-admin-token) on the Admin tokens feature page). -2. Copy the token as you will need it - -The token's permissions determine which MCP tools are exposed to the AI client. For instance, if the token only grants `read` on an `Article` content-type, the AI client will only see listing and reading tools for articles. - ### Strapi code-based configuration Enable the MCP server by adding the `mcp` object to the server configuration file: @@ -110,9 +101,22 @@ mcp: { }, ``` +:::note +The timeout options are read at runtime and are not yet included in Strapi's `Server` TypeScript configuration type. If you use TypeScript, the basic `mcp: { enabled: true }` object is fully typed, but adding timeout keys may require a type assertion. +::: + +### Admin token configuration + +The MCP server authenticates requests using Admin tokens. Each MCP session is scoped to the permissions of the token used to connect: + +1. Create a new Admin token (see [Creating an Admin token](/cms/features/admin-tokens#creating-a-new-admin-token) on the Admin tokens feature page). +2. Copy the token value. You will need it when configuring the AI client. + +The token's permissions determine which MCP tools are exposed to the AI client. For instance, if the token only grants `read` on an `Article` content-type, the AI client will only see listing and reading tools for articles. + ### AI client configuration -Once you enabled and configured the MCP server through Strapi's admin panel (admin tokens) and configuration filters, you must connect your AI client to the Strapi MCP server. +Once you have enabled the MCP server through the server configuration file and created an Admin token in the admin panel, connect your AI client to the Strapi MCP server. :::note `localhost:1337/` is used in configuration examples on this page. If your Strapi server is hosted on another URL or port, please update the code accordingly. @@ -131,7 +135,7 @@ Open Claude Desktop's configuration file. The location varies depending on your You can also open the configuration file for Claude Desktop from Claude's settings: go to Settings > Desktop app > Developer, then click on the **Edit config** button. ::: -Add the Strapi MCP server to Claude's configuration file, as in the following example, replacing `YOUR_ADMIN_TOKEN` with the admin token value copied from the [admin panel](#strapi-admin-panel-configuration): +Add the Strapi MCP server to Claude's configuration file, as in the following example, replacing `YOUR_ADMIN_TOKEN` with the Admin token value copied from the [Admin token configuration](#admin-token-configuration): ```json title="claude_desktop_config.json" { @@ -154,7 +158,7 @@ Restart Claude Desktop for the changes to take effect. #### Connecting Claude Code -Run the following command, replacing `YOUR_ADMIN_TOKEN` with the admin token value copied from the [admin panel](#strapi-admin-panel-configuration): +Run the following command, replacing `YOUR_ADMIN_TOKEN` with the Admin token value copied from the [Admin token configuration](#admin-token-configuration): ```bash claude mcp add strapi-mcp --transport http http://localhost:1337/mcp -H "Authorization: Bearer YOUR_ADMIN_TOKEN" @@ -232,7 +236,7 @@ The last 3 tools (publish, unpublish, discard_draft) are only generated for cont Tool names follow the pattern `cm___`. For example, an `Article` content type with UID `api::article.article` generates tools named `cm_api_article_list`, `cm_api_article_get`, `cm_api_article_create`, etc. -Single types follow a similar pattern but include `_single_` in the name (e.g., `cm_api_homepage_single_get`). +Single types follow a similar pattern but include `_single_` in the name (e.g., `cm_api_homepage_single_get`). Because single types represent a unique entry, they do not have a `list` tool and generate up to 7 tools instead of 8. #### Built-in utility tools @@ -263,7 +267,7 @@ Each tool has an input schema derived from your content type's attributes. The s - **Field-level permissions**: If the token restricts access to certain fields, those fields are excluded from both input and output schemas. For instance, a token that can only read `title` and `slug` on an `Article` type will only see those two fields in sort, filter, and output schemas. - **Locale-level permissions**: If the [Internationalization (i18n)](/cms/features/internationalization) plugin is installed and the token restricts access to certain locales, the `locale` parameter only accepts the permitted locales for each action. Locale restrictions are evaluated per action: a token might allow reading in `en` and `fr` but only creating in `en`. -- **Write operations**: The `data` object in `create` and `update` tools only includes fields the token has permission to write. Unknown fields are rejected (strict validation). System-managed fields (`id`, `documentId`, `createdAt`, `updatedAt`, `publishedAt`, `createdBy`, `updatedBy`) and private fields are excluded automatically. +- **Write operations**: The `data` object in `create` and `update` tools only includes fields the token has permission to write. Unknown fields are rejected (strict validation). System-managed fields (`id`, `documentId`, `createdAt`, `updatedAt`, `publishedAt`, `createdBy`, `updatedBy`) are excluded automatically. Private fields are also excluded. - **Attribute type mapping**: Field schemas carry constraints from your content-type definition, such as `required`, `minLength`, `maxLength`, `min`, `max`, and `enum` values. Enumeration fields expose their allowed values in the schema so the AI client can pick valid options. #### Sorting @@ -283,7 +287,7 @@ Sort field names are constrained to the content type's scalar attributes (string The `list` tool accepts a `filters` parameter using Strapi's filter syntax: -- **Field operators**: `$eq`, `$ne`, `$in`, `$notIn`, `$lt`, `$lte`, `$gt`, `$gte`, `$contains`, `$notContains`, `$startsWith`, `$endsWith`, `$null`, `$notNull`, and their case-insensitive variants (`$eqi`, `$nei`, `$containsi`, etc.). +- **Field operators**: `$eq`, `$ne`, `$in`, `$notIn`, `$lt`, `$lte`, `$gt`, `$gte`, `$between`, `$contains`, `$notContains`, `$startsWith`, `$endsWith`, `$null`, `$notNull`, and their case-insensitive variants (`$eqi`, `$nei`, `$containsi`, `$notContainsi`, `$startsWithi`, `$endsWithi`). - **Logical operators**: `$and`, `$or` (accept arrays of filter objects), `$not` (wraps a single filter object). - **Implicit equality**: Passing a value directly (e.g., `{ "title": "Hello" }`) is equivalent to `{ "title": { "$eq": "Hello" } }`. @@ -301,9 +305,9 @@ Rich text fields using the [Blocks editor](/cms/features/content-type-builder#ri The MCP server enforces the same permission model as the Strapi admin panel. Permissions are checked at multiple levels: -1. **Tool visibility**: When an AI client connects, Strapi checks the admin token's permissions and only exposes tools the token has access to. If the token does not grant `delete` on `Article`, the AI client will not see a delete tool for articles at all. +1. **Tool visibility**: When an AI client connects, Strapi checks the Admin token's permissions and only exposes tools the token has access to. If the token does not grant `delete` on `Article`, the AI client will not see a delete tool for articles at all. -2. **Field filtering**: Even within an exposed tool, input and output schemas are narrowed to the fields the token can access. If the token grants `read` on `Article` but excludes the `body` field, the AI client will not see or receive `body` content. Field restrictions are applied independently per action: write schemas (`create`, `update`) only include fields permitted for the corresponding action. +2. **Field filtering**: Even within an exposed tool, input and output schemas are narrowed to the fields the token can access. If the token grants `read` on `Article` but excludes the `body` field, the AI client will not see or receive `body` content. Field restrictions are applied independently per action. Write schemas (`create`, `update`) only include fields permitted for the corresponding action. 3. **Locale filtering**: When the [Internationalization (i18n)](/cms/features/internationalization) plugin is installed and locale-level permissions are configured, the `locale` parameter is narrowed per action. For example, a token might allow reading content in `en` and `fr` but only creating content in `en`. If the default locale is permitted for a given action, it is applied as the Zod schema default so the AI client does not need to specify it explicitly. @@ -317,12 +321,12 @@ This means you can create tokens with fine-grained access: - A token with condition-based permissions (e.g., only update entries you own) :::tip -Create dedicated admin tokens for each AI client or use case. Use the most restrictive permissions that still allow the AI to accomplish its task. +Create dedicated Admin tokens for each AI client or use case. Use the most restrictive permissions that still allow the AI to accomplish its task. ::: ### Stateless architecture -The MCP server uses a stateless architecture. Each POST request to the `/mcp` endpoint creates a fresh, ephemeral MCP server instance scoped to the authenticated token's permissions. There is no session persistence between requests: every request is independently authenticated and authorized. This design means the AI client does not need to manage session IDs, and permission changes (such as revoking a token or updating its permissions) take effect on the next request. +The MCP server uses a stateless architecture. Each POST request to the `/mcp` endpoint creates a fresh, ephemeral MCP server instance scoped to the authenticated token's permissions. There is no session persistence between requests: every request is independently authenticated and authorized. Because there is no session state, the AI client does not need to manage session IDs, and permission changes (such as revoking a token or updating its permissions) take effect on the next request. GET and DELETE HTTP methods on the `/mcp` endpoint return a `405 Method Not Allowed` JSON-RPC error, as the MCP server only accepts POST requests. diff --git a/docusaurus/sidebars.js b/docusaurus/sidebars.js index a1e98d7c9c..70afca443e 100644 --- a/docusaurus/sidebars.js +++ b/docusaurus/sidebars.js @@ -179,6 +179,11 @@ const sidebars = { updated: true, }, }, + { + type: 'doc', + label: 'Docs MCP server', + id: 'cms/ai/docs-mcp-server', + }, ], }, { // APIs From adbfd0837f3eb55796e38190c5ab9c5a718677fd Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:13:14 +0200 Subject: [PATCH 24/51] Restore Strapi admin panel configuration section name and internal links --- docusaurus/docs/cms/features/strapi-mcp-server.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index b8383739bd..10c2c1e346 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -105,7 +105,7 @@ mcp: { The timeout options are read at runtime and are not yet included in Strapi's `Server` TypeScript configuration type. If you use TypeScript, the basic `mcp: { enabled: true }` object is fully typed, but adding timeout keys may require a type assertion. ::: -### Admin token configuration +### Strapi admin panel configuration The MCP server authenticates requests using Admin tokens. Each MCP session is scoped to the permissions of the token used to connect: @@ -135,7 +135,7 @@ Open Claude Desktop's configuration file. The location varies depending on your You can also open the configuration file for Claude Desktop from Claude's settings: go to Settings > Desktop app > Developer, then click on the **Edit config** button. ::: -Add the Strapi MCP server to Claude's configuration file, as in the following example, replacing `YOUR_ADMIN_TOKEN` with the Admin token value copied from the [Admin token configuration](#admin-token-configuration): +Add the Strapi MCP server to Claude's configuration file, as in the following example, replacing `YOUR_ADMIN_TOKEN` with the Admin token value copied from the [Strapi admin panel configuration](#strapi-admin-panel-configuration): ```json title="claude_desktop_config.json" { @@ -158,7 +158,7 @@ Restart Claude Desktop for the changes to take effect. #### Connecting Claude Code -Run the following command, replacing `YOUR_ADMIN_TOKEN` with the Admin token value copied from the [Admin token configuration](#admin-token-configuration): +Run the following command, replacing `YOUR_ADMIN_TOKEN` with the Admin token value copied from the [Strapi admin panel configuration](#strapi-admin-panel-configuration): ```bash claude mcp add strapi-mcp --transport http http://localhost:1337/mcp -H "Authorization: Bearer YOUR_ADMIN_TOKEN" From 717e57af4fd0ec53111d08355457b5c475f17807 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:13:25 +0200 Subject: [PATCH 25/51] Replace spelled-out numbers with numerals per style guide --- docusaurus/docs/cms/features/strapi-mcp-server.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 10c2c1e346..3e11d39754 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -265,14 +265,14 @@ Once connected, you can interact with your Strapi content using natural language Each tool has an input schema derived from your content type's attributes. The schema is dynamically generated per session based on the token's permissions: -- **Field-level permissions**: If the token restricts access to certain fields, those fields are excluded from both input and output schemas. For instance, a token that can only read `title` and `slug` on an `Article` type will only see those two fields in sort, filter, and output schemas. +- **Field-level permissions**: If the token restricts access to certain fields, those fields are excluded from both input and output schemas. For instance, a token that can only read `title` and `slug` on an `Article` type will only see those 2 fields in sort, filter, and output schemas. - **Locale-level permissions**: If the [Internationalization (i18n)](/cms/features/internationalization) plugin is installed and the token restricts access to certain locales, the `locale` parameter only accepts the permitted locales for each action. Locale restrictions are evaluated per action: a token might allow reading in `en` and `fr` but only creating in `en`. - **Write operations**: The `data` object in `create` and `update` tools only includes fields the token has permission to write. Unknown fields are rejected (strict validation). System-managed fields (`id`, `documentId`, `createdAt`, `updatedAt`, `publishedAt`, `createdBy`, `updatedBy`) are excluded automatically. Private fields are also excluded. - **Attribute type mapping**: Field schemas carry constraints from your content-type definition, such as `required`, `minLength`, `maxLength`, `min`, `max`, and `enum` values. Enumeration fields expose their allowed values in the schema so the AI client can pick valid options. #### Sorting -The `list` tool accepts a `sort` parameter that supports four notations: +The `list` tool accepts a `sort` parameter that supports 4 notations: | Notation | Example | |----------|---------| From 7e8aa57fcbd4c13704a01bedfa25c161067185b6 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:13:33 +0200 Subject: [PATCH 26/51] Add intro paragraphs to Available tools and Content-type tools sections --- docusaurus/docs/cms/features/strapi-mcp-server.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 3e11d39754..f1d5db4129 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -217,9 +217,11 @@ The MCP server uses the Streamable HTTP transport protocol. Any MCP-compatible c ### Available tools +The MCP server exposes 2 categories of tools: content-type tools generated from your schema, and built-in utility tools. + #### Content-type tools -For each content type the token has access to, Strapi generates up to 8 tools: +For each content type the token has access to, Strapi generates up to 8 tools: 5 for CRUD operations (list, get, create, update, delete) and 3 for [Draft & Publish](/cms/features/draft-and-publish) actions (publish, unpublish, discard draft): | Tool | Action | Permission required | Description | |------|--------|-------------------|-------------| From 7649d269efbff4922556bbefa0e58a78f7f67012 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:18:43 +0200 Subject: [PATCH 27/51] Replace i18n plugin with i18n feature in MCP server page --- docusaurus/docs/cms/features/strapi-mcp-server.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index f1d5db4129..1c8e31ddfc 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -268,7 +268,7 @@ Once connected, you can interact with your Strapi content using natural language Each tool has an input schema derived from your content type's attributes. The schema is dynamically generated per session based on the token's permissions: - **Field-level permissions**: If the token restricts access to certain fields, those fields are excluded from both input and output schemas. For instance, a token that can only read `title` and `slug` on an `Article` type will only see those 2 fields in sort, filter, and output schemas. -- **Locale-level permissions**: If the [Internationalization (i18n)](/cms/features/internationalization) plugin is installed and the token restricts access to certain locales, the `locale` parameter only accepts the permitted locales for each action. Locale restrictions are evaluated per action: a token might allow reading in `en` and `fr` but only creating in `en`. +- **Locale-level permissions**: If the [Internationalization (i18n)](/cms/features/internationalization) feature is enabled and the token restricts access to certain locales, the `locale` parameter only accepts the permitted locales for each action. Locale restrictions are evaluated per action: a token might allow reading in `en` and `fr` but only creating in `en`. - **Write operations**: The `data` object in `create` and `update` tools only includes fields the token has permission to write. Unknown fields are rejected (strict validation). System-managed fields (`id`, `documentId`, `createdAt`, `updatedAt`, `publishedAt`, `createdBy`, `updatedBy`) are excluded automatically. Private fields are also excluded. - **Attribute type mapping**: Field schemas carry constraints from your content-type definition, such as `required`, `minLength`, `maxLength`, `min`, `max`, and `enum` values. Enumeration fields expose their allowed values in the schema so the AI client can pick valid options. @@ -311,7 +311,7 @@ The MCP server enforces the same permission model as the Strapi admin panel. Per 2. **Field filtering**: Even within an exposed tool, input and output schemas are narrowed to the fields the token can access. If the token grants `read` on `Article` but excludes the `body` field, the AI client will not see or receive `body` content. Field restrictions are applied independently per action. Write schemas (`create`, `update`) only include fields permitted for the corresponding action. -3. **Locale filtering**: When the [Internationalization (i18n)](/cms/features/internationalization) plugin is installed and locale-level permissions are configured, the `locale` parameter is narrowed per action. For example, a token might allow reading content in `en` and `fr` but only creating content in `en`. If the default locale is permitted for a given action, it is applied as the Zod schema default so the AI client does not need to specify it explicitly. +3. **Locale filtering**: When the [Internationalization (i18n)](/cms/features/internationalization) feature is enabled and locale-level permissions are configured, the `locale` parameter is narrowed per action. For example, a token might allow reading content in `en` and `fr` but only creating content in `en`. If the default locale is permitted for a given action, it is applied as the Zod schema default so the AI client does not need to specify it explicitly. 4. **Runtime enforcement**: Beyond schema-level narrowing, each handler calls Strapi's permission checker at runtime to verify access on the specific document being read, written, or published. Condition-based permissions (e.g., "only update entries you own") are enforced at this level. From 377566a47a5f753404676648d76d9d88aa29d0a2 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:18:47 +0200 Subject: [PATCH 28/51] Add Strapi terminology check for i18n and core features to style checker --- agents/prompts/style-checker.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/agents/prompts/style-checker.md b/agents/prompts/style-checker.md index 211377e154..fec3a22089 100644 --- a/agents/prompts/style-checker.md +++ b/agents/prompts/style-checker.md @@ -209,6 +209,10 @@ Beyond the 12 rules, also check for: - In TabItems: `value` must be lowercase (`yarn`, `npm`), `label` must be `Yarn` or `NPM` - Do NOT flag these as inconsistencies when used correctly per context. +### Strapi terminology +- **Detect:** Internationalization (i18n) referred to as a "plugin" instead of a "feature". Since Strapi 5, i18n is a core feature, not a plugin. Also watch for other core features (Upload, Content Manager, Content-Type Builder) being called "plugins". +- **Severity:** warning + ### Cross-reference formatting - **Detect:** Standalone "See [link]." sentences that could be integrated as parentheticals into the preceding sentence (e.g., "Configure X. See [Y]." → "Configure X (see [Y]).") - **Severity:** warning From 0d95cdb65af5e47f8c0ed7bc37fc8a5b2b18f7dc Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:31:47 +0200 Subject: [PATCH 29/51] Capitalize Admin token in for-content-managers MCP section --- docusaurus/docs/cms/ai/for-content-managers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/ai/for-content-managers.md b/docusaurus/docs/cms/ai/for-content-managers.md index 950ba0be6a..527451f9f3 100644 --- a/docusaurus/docs/cms/ai/for-content-managers.md +++ b/docusaurus/docs/cms/ai/for-content-managers.md @@ -67,6 +67,6 @@ All AI requests are processed through Strapi-managed infrastructure. Content is ## Strapi MCP server -Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that lets AI clients like Claude, Cursor, or any MCP-compatible tool manage your content through natural language. Once enabled and connected, an AI assistant can create, read, update, delete, publish, and unpublish entries directly through Strapi's Content Manager, all gated by admin token permissions. +Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that lets AI clients like Claude, Cursor, or any MCP-compatible tool manage your content through natural language. Once enabled and connected, an AI assistant can create, read, update, delete, publish, and unpublish entries directly through Strapi's Content Manager, all gated by Admin token permissions. From 14e61fc68fab5d689adbd20d500cb3ed8db36043 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:31:56 +0200 Subject: [PATCH 30/51] Use canonical MCP link and Docs MCP server name in FAQ --- docusaurus/docs/cms/faq.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docusaurus/docs/cms/faq.md b/docusaurus/docs/cms/faq.md index 0ee43d07ac..392af34f91 100644 --- a/docusaurus/docs/cms/faq.md +++ b/docusaurus/docs/cms/faq.md @@ -152,6 +152,6 @@ You can see the ) server that exposes content management tools to AI clients. See the [MCP server feature page](/cms/features/strapi-mcp-server) for configuration and usage details. +Yes. Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that exposes content management tools to AI clients. See the [MCP server feature page](/cms/features/strapi-mcp-server) for configuration and usage details. -A separate [MCP server for Strapi Docs](/cms/ai/for-developers#mcp) is also available for querying the Strapi documentation. +A separate [Docs MCP server](/cms/ai/for-developers#mcp) is also available for querying the Strapi documentation. From 9c389a0ac88481401b3f2ee9439ee76d6204eeae Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:32:04 +0200 Subject: [PATCH 31/51] Fix ambiguous double it in locale filtering paragraph --- docusaurus/docs/cms/features/strapi-mcp-server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 1c8e31ddfc..da38b18f91 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -311,7 +311,7 @@ The MCP server enforces the same permission model as the Strapi admin panel. Per 2. **Field filtering**: Even within an exposed tool, input and output schemas are narrowed to the fields the token can access. If the token grants `read` on `Article` but excludes the `body` field, the AI client will not see or receive `body` content. Field restrictions are applied independently per action. Write schemas (`create`, `update`) only include fields permitted for the corresponding action. -3. **Locale filtering**: When the [Internationalization (i18n)](/cms/features/internationalization) feature is enabled and locale-level permissions are configured, the `locale` parameter is narrowed per action. For example, a token might allow reading content in `en` and `fr` but only creating content in `en`. If the default locale is permitted for a given action, it is applied as the Zod schema default so the AI client does not need to specify it explicitly. +3. **Locale filtering**: When the [Internationalization (i18n)](/cms/features/internationalization) feature is enabled and locale-level permissions are configured, the `locale` parameter is narrowed per action. For example, a token might allow reading content in `en` and `fr` but only creating content in `en`. If the default locale is permitted for a given action, that locale is applied as the Zod schema default, so the AI client does not need to specify a locale explicitly. 4. **Runtime enforcement**: Beyond schema-level narrowing, each handler calls Strapi's permission checker at runtime to verify access on the specific document being read, written, or published. Condition-based permissions (e.g., "only update entries you own") are enforced at this level. From 287b7d4822b0a59bc35f7212a2dc2389eb69d7a5 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:32:12 +0200 Subject: [PATCH 32/51] Clarify ambiguous the field in custom fields limitation --- docusaurus/docs/cms/features/strapi-mcp-server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index da38b18f91..82a694766e 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -341,4 +341,4 @@ The MCP server has the following limitations: - **Relations**: Relation fields accept document IDs (e.g., `"z7v8zma53x01r6oceimv922b"`) as input. The advanced `connect`/`disconnect` relation syntax is not yet supported in MCP tool schemas. - **Nested population parameters**: The `list` and `get` tools do not support nested population parameters for relations. - **Media upload**: Media fields accept existing media asset references but the MCP server cannot upload new files. Use Strapi's media library or upload API to add files first, then reference them in MCP tool calls. -- **Custom fields**: Custom fields registered via plugins are mapped to their underlying Strapi type. If the custom field registry is not populated when MCP tools are registered, the field falls back to `unknown`. +- **Custom fields**: Custom fields registered via plugins are mapped to their underlying Strapi type. If the custom field registry is not populated when MCP tools are registered, the custom field falls back to an `unknown` type. From f5248101ba04cb15913f8cec3126cff7f9276a50 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:32:26 +0200 Subject: [PATCH 33/51] Rename gerund headings to noun form for parallel structure --- docusaurus/docs/cms/features/strapi-mcp-server.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 82a694766e..fccb407231 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -250,7 +250,7 @@ In addition to content-type tools, Strapi registers the following built-in tools Built-in utility tools are only available in development mode (when `autoReload` is enabled) and do not require specific content-type permissions. -### Managing content through prompts +### Content management through prompts Once connected, you can interact with your Strapi content using natural language: @@ -263,7 +263,7 @@ Once connected, you can interact with your Strapi content using natural language | "Publish article abc123." | Flips the entry status to published | | "Delete article abc123." | Removes the entry | -### Understanding input schemas +### Input schemas Each tool has an input schema derived from your content type's attributes. The schema is dynamically generated per session based on the token's permissions: From ef5e126aee431c6329cbd2b8293ce024d6ee244a Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:37:17 +0200 Subject: [PATCH 34/51] Link Docs MCP server intro to Ask AI button for reader context --- docusaurus/docs/cms/ai/docs-mcp-server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/ai/docs-mcp-server.md b/docusaurus/docs/cms/ai/docs-mcp-server.md index fefd1a02c7..4afd87ef1c 100644 --- a/docusaurus/docs/cms/ai/docs-mcp-server.md +++ b/docusaurus/docs/cms/ai/docs-mcp-server.md @@ -21,7 +21,7 @@ A Docs MCP server exposes the Strapi documentation to AI coding tools. Connect i -The Docs [MCP](https://modelcontextprotocol.io) (Model Context Protocol) server is powered by [Kapa](https://kapa.ai) and draws from the full Strapi documentation, including guides, API references, and code examples. The Docs MCP server is part of the [AI tools for developers](/cms/ai/for-developers) that Strapi offers. +The Docs [MCP](https://modelcontextprotocol.io) (Model Context Protocol) server is powered by [Kapa](https://kapa.ai), the same service behind the **Ask AI** button on the documentation website. It draws from the full Strapi documentation, including guides, API references, and code examples. The Docs MCP server is part of the [AI tools for developers](/cms/ai/for-developers) that Strapi offers. :::strapi MCP servers for Strapi Strapi offers 2 different MCP servers: From 7fe924941f586b84ee0b245b5d677bcd00fecf7f Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:38:22 +0200 Subject: [PATCH 35/51] Replace informal Flips with Changes in prompt examples table --- docusaurus/docs/cms/features/strapi-mcp-server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index fccb407231..8c6389629e 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -260,7 +260,7 @@ Once connected, you can interact with your Strapi content using natural language | "List the 5 most recent articles." | Returns paginated list, newest first | | "Show me article with ID abc123." | Returns the full entry | | "Update article abc123, change the title to 'Hello Strapi'." | Updates the title, other fields untouched | -| "Publish article abc123." | Flips the entry status to published | +| "Publish article abc123." | Changes the entry status to published | | "Delete article abc123." | Removes the entry | ### Input schemas From bac7b737d0936151eb2f628309329d7c7672ade8 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:38:40 +0200 Subject: [PATCH 36/51] Link FAQ Docs MCP server to dedicated page instead of anchor --- docusaurus/docs/cms/faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/faq.md b/docusaurus/docs/cms/faq.md index 392af34f91..6f49b32171 100644 --- a/docusaurus/docs/cms/faq.md +++ b/docusaurus/docs/cms/faq.md @@ -154,4 +154,4 @@ You can see the Free feature From 634d97b992012b9def0826ee6ec25d1dc3339814 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:39:21 +0200 Subject: [PATCH 38/51] Fix Admin Tokens heading and title to sentence case --- docusaurus/docs/cms/features/admin-tokens.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docusaurus/docs/cms/features/admin-tokens.md b/docusaurus/docs/cms/features/admin-tokens.md index 0ba1bc7fea..fa49020222 100644 --- a/docusaurus/docs/cms/features/admin-tokens.md +++ b/docusaurus/docs/cms/features/admin-tokens.md @@ -1,5 +1,5 @@ --- -title: Admin Tokens +title: Admin tokens description: Learn how to use Admin tokens to authenticate programmatic access to the Strapi Admin API. toc_max_heading_level: 4 displayed_sidebar: cmsSidebar @@ -11,7 +11,7 @@ tags: - features --- -# Admin Tokens +# Admin tokens Admin tokens authenticate programmatic access to the Strapi Admin API. Each token is scoped to a subset of its owner's permissions and is designed for automation workflows such as MCP agents, CI/CD pipelines, and scripts. From 139395a9779cf9b4dd5de31f5f81f61342a9aa80 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:39:41 +0200 Subject: [PATCH 39/51] Capitalize Admin tokens consistently in admin-tokens page --- docusaurus/docs/cms/features/admin-tokens.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docusaurus/docs/cms/features/admin-tokens.md b/docusaurus/docs/cms/features/admin-tokens.md index fa49020222..392b773b43 100644 --- a/docusaurus/docs/cms/features/admin-tokens.md +++ b/docusaurus/docs/cms/features/admin-tokens.md @@ -55,7 +55,7 @@ Admin tokens are configured entirely from the admin panel. No code-based configu :::prerequisites If you're not the Strapi instance's super admin, the super admin must have granted you the following permissions: * access the Admin tokens settings page - * create (generate) admin tokens + * create (generate) Admin tokens (see [RBAC > Configuring role's permissions](/cms/features/rbac#plugins-and-settings) for details). ::: @@ -99,7 +99,7 @@ Any user with access to the Admin Tokens settings page can view Admin tokens. A When a super-admin views an Admin token owned by another user, a read-only **Owner** field appears in the token details panel. The permissions panel shows only the checkboxes within the token owner's permission scope, not the super-admin's unrestricted access. -Removing a permission from a role causes admin tokens owned by users of that role to have the corresponding permission deleted automatically. +Removing a permission from a role causes Admin tokens owned by users of that role to have the corresponding permission deleted automatically. :::caution Owner account deactivation and deletion From 01f1df2b0aa27bfb6f5f064bb022a66e640de77d Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:39:55 +0200 Subject: [PATCH 40/51] Fix FAQ heading to sentence case --- docusaurus/docs/cms/faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/faq.md b/docusaurus/docs/cms/faq.md index 6f49b32171..f8465ae0e2 100644 --- a/docusaurus/docs/cms/faq.md +++ b/docusaurus/docs/cms/faq.md @@ -23,7 +23,7 @@ tags: --- -# Frequently Asked Questions +# Frequently asked questions Below are answers and solutions to most common issues that you may experience when working with Strapi. From 926b06f9621161e253c8c40273562fcc91efdad4 Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 11:43:14 +0200 Subject: [PATCH 41/51] Standardize AI assistant to AI client in for-content-managers --- docusaurus/docs/cms/ai/for-content-managers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/ai/for-content-managers.md b/docusaurus/docs/cms/ai/for-content-managers.md index 527451f9f3..48481ca07d 100644 --- a/docusaurus/docs/cms/ai/for-content-managers.md +++ b/docusaurus/docs/cms/ai/for-content-managers.md @@ -67,6 +67,6 @@ All AI requests are processed through Strapi-managed infrastructure. Content is ## Strapi MCP server -Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that lets AI clients like Claude, Cursor, or any MCP-compatible tool manage your content through natural language. Once enabled and connected, an AI assistant can create, read, update, delete, publish, and unpublish entries directly through Strapi's Content Manager, all gated by Admin token permissions. +Strapi includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that lets AI clients like Claude, Cursor, or any MCP-compatible tool manage your content through natural language. Once enabled and connected, an AI client can create, read, update, delete, publish, and unpublish entries directly through Strapi's Content Manager, all gated by Admin token permissions. From 3e2dde01f798d7e4381bb108402967bcb398a3fd Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Thu, 21 May 2026 17:53:46 +0200 Subject: [PATCH 42/51] Update docusaurus/docs/cms/features/strapi-mcp-server.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nico André --- docusaurus/docs/cms/features/strapi-mcp-server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 5b741cadb4..83b55f14c8 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -14,7 +14,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; # MCP server - + From 420cd0ee693c69a230a1770c7153eb0f4b853a4c Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Thu, 21 May 2026 17:54:00 +0200 Subject: [PATCH 43/51] Update docusaurus/docs/cms/features/strapi-mcp-server.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nico André --- docusaurus/docs/cms/features/strapi-mcp-server.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 83b55f14c8..59ade561eb 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -71,9 +71,11 @@ const config = ({ env }: Core.Config.Shared.ConfigParams): Core.Config.Server => app: { keys: env.array('APP_KEYS'), }, + // highlight-start mcp: { enabled: true, }, + // highlight-end }); export default config; ``` From 2d25207ecd175f746841e95b682cffe806181e6f Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Thu, 21 May 2026 17:54:35 +0200 Subject: [PATCH 44/51] Update docusaurus/docs/cms/features/strapi-mcp-server.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nico André --- docusaurus/docs/cms/features/strapi-mcp-server.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 59ade561eb..4b5d891dbd 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -103,9 +103,6 @@ mcp: { }, ``` -:::note -The timeout options are read at runtime and are not yet included in Strapi's `Server` TypeScript configuration type. If you use TypeScript, the basic `mcp: { enabled: true }` object is fully typed, but adding timeout keys may require a type assertion. -::: ### Strapi admin panel configuration From 4fc2e89a817b231c7b09b762084a8d467e1f283b Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Thu, 21 May 2026 17:54:56 +0200 Subject: [PATCH 45/51] Update docusaurus/docs/cms/features/strapi-mcp-server.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nico André --- docusaurus/docs/cms/features/strapi-mcp-server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 4b5d891dbd..2988716c98 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -118,7 +118,7 @@ The token's permissions determine which MCP tools are exposed to the AI client. Once you have enabled the MCP server through the server configuration file and created an Admin token in the admin panel, connect your AI client to the Strapi MCP server. :::note -`localhost:1337/` is used in configuration examples on this page. If your Strapi server is hosted on another URL or port, please update the code accordingly. +`http://localhost:1337/` is used in configuration examples on this page. If your Strapi server is hosted on another URL or port, please update the code accordingly. ::: #### Connecting Claude Desktop From 1f83663101d97efa2aded4c0fed42cb04a8b3f75 Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Thu, 21 May 2026 17:56:37 +0200 Subject: [PATCH 46/51] Update docusaurus/docs/cms/features/strapi-mcp-server.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nico André --- docusaurus/docs/cms/features/strapi-mcp-server.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 2988716c98..063028814c 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -235,9 +235,6 @@ For each content type the token has access to, Strapi generates up to 8 tools: 5 The last 3 tools (publish, unpublish, discard_draft) are only generated for content types that have [Draft & Publish](/cms/features/draft-and-publish) enabled. -Tool names follow the pattern `cm___`. For example, an `Article` content type with UID `api::article.article` generates tools named `cm_api_article_list`, `cm_api_article_get`, `cm_api_article_create`, etc. - -Single types follow a similar pattern but include `_single_` in the name (e.g., `cm_api_homepage_single_get`). Because single types represent a unique entry, they do not have a `list` tool and generate up to 7 tools instead of 8. #### Built-in utility tools From 3a09e7468eaaa2e08a3883800afaebae38ca2d7f Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Thu, 21 May 2026 17:56:53 +0200 Subject: [PATCH 47/51] Update docusaurus/docs/cms/features/strapi-mcp-server.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nico André --- docusaurus/docs/cms/features/strapi-mcp-server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 063028814c..4dc9a317b7 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -244,7 +244,7 @@ In addition to content-type tools, Strapi registers the following built-in tools |------|-------------|-------------| | `log` | Development mode only | Logs a message to the Strapi server console at a specified level (`info`, `warn`, `error`, `http`, `log`). Useful for debugging MCP interactions. | -Built-in utility tools are only available in development mode (when `autoReload` is enabled) and do not require specific content-type permissions. +Built-in utility tools are only available in development mode (when `autoReload` is enabled) and do not require specific admin permissions. ### Content management through prompts From 7119045f5ec730ab8730343905b2a0f55fde3ec0 Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Thu, 21 May 2026 17:57:35 +0200 Subject: [PATCH 48/51] Update docusaurus/docs/cms/features/strapi-mcp-server.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nico André --- docusaurus/docs/cms/features/strapi-mcp-server.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 4dc9a317b7..e8206bf531 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -295,9 +295,6 @@ Like sort fields, filter fields are constrained to scalar attributes only. The `list` tool also accepts `page` (1-indexed, default: 1) and `pageSize` (default: 25, max: 100) parameters. -#### Rich text (blocks) - -Rich text fields using the [Blocks editor](/cms/features/content-type-builder#rich-text-blocks) are represented with a structured schema in tool definitions. The schema covers all block types: paragraphs, headings (levels 1–6), quotes, code blocks (with optional language), ordered and unordered lists (including nested lists), images, and inline nodes (text with formatting marks, links). ### Permission boundaries From a975260541703b8624b01dc839329bf916d4a362 Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Thu, 21 May 2026 18:00:19 +0200 Subject: [PATCH 49/51] Update docusaurus/docs/cms/features/strapi-mcp-server.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nico André --- docusaurus/docs/cms/features/strapi-mcp-server.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index e8206bf531..7094e58e73 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -259,14 +259,6 @@ Once connected, you can interact with your Strapi content using natural language | "Publish article abc123." | Changes the entry status to published | | "Delete article abc123." | Removes the entry | -### Input schemas - -Each tool has an input schema derived from your content type's attributes. The schema is dynamically generated per session based on the token's permissions: - -- **Field-level permissions**: If the token restricts access to certain fields, those fields are excluded from both input and output schemas. For instance, a token that can only read `title` and `slug` on an `Article` type will only see those 2 fields in sort, filter, and output schemas. -- **Locale-level permissions**: If the [Internationalization (i18n)](/cms/features/internationalization) feature is enabled and the token restricts access to certain locales, the `locale` parameter only accepts the permitted locales for each action. Locale restrictions are evaluated per action: a token might allow reading in `en` and `fr` but only creating in `en`. -- **Write operations**: The `data` object in `create` and `update` tools only includes fields the token has permission to write. Unknown fields are rejected (strict validation). System-managed fields (`id`, `documentId`, `createdAt`, `updatedAt`, `publishedAt`, `createdBy`, `updatedBy`) are excluded automatically. Private fields are also excluded. -- **Attribute type mapping**: Field schemas carry constraints from your content-type definition, such as `required`, `minLength`, `maxLength`, `min`, `max`, and `enum` values. Enumeration fields expose their allowed values in the schema so the AI client can pick valid options. #### Sorting From a19b5aee0c0fc205c6242e71670c68be7963d56d Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Thu, 21 May 2026 18:15:30 +0200 Subject: [PATCH 50/51] Add i18n usage section and locale prompt example Co-Authored-By: Claude Opus 4.6 (1M context) --- docusaurus/docs/cms/features/strapi-mcp-server.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 7094e58e73..1de2cb5331 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -258,8 +258,19 @@ Once connected, you can interact with your Strapi content using natural language | "Update article abc123, change the title to 'Hello Strapi'." | Updates the title, other fields untouched | | "Publish article abc123." | Changes the entry status to published | | "Delete article abc123." | Removes the entry | +| "Create an article in French with the title 'Bonjour le monde'." | Creates a draft article with `locale` set to `fr` | +#### Internationalization (i18n) + +When [Internationalization (i18n)](/cms/features/internationalization) is enabled on a content type, MCP tools accept an optional `locale` parameter (e.g., `"en"`, `"fr"`). If omitted, the default locale is used. + +The AI client sees which locales are available in each tool's schema, so you can ask it to create or update content in a specific language. For example, asking "Create an article in French titled 'Bonjour'" passes `locale: "fr"` to the `create` tool. Which locales are available depends on the Admin token's permissions (see [Permission boundaries](#permission-boundaries)). + +:::tip +When working with localized content, explicitly mention the target language in your prompt so the AI client passes the correct `locale` value. For instance, prefer "Create an article **in French**" over "Create an article titled 'Bonjour'" to avoid ambiguity. +::: + #### Sorting The `list` tool accepts a `sort` parameter that supports 4 notations: From ea65dd90e210af93f6b38ec80fe57e2046e4c611 Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Fri, 22 May 2026 12:08:35 +0200 Subject: [PATCH 51/51] Added beta badge --- docusaurus/docs/cms/features/strapi-mcp-server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/features/strapi-mcp-server.md b/docusaurus/docs/cms/features/strapi-mcp-server.md index 1de2cb5331..59373d5a50 100644 --- a/docusaurus/docs/cms/features/strapi-mcp-server.md +++ b/docusaurus/docs/cms/features/strapi-mcp-server.md @@ -14,7 +14,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; # MCP server - +