From 148d07cf234a3a1e2c88577d358ded5cb4466bba Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Thu, 26 Mar 2026 11:00:36 +0100 Subject: [PATCH 01/12] MCP Servers doc draft --- code_samples/mcp/config/packages/mcp.yaml | 18 ++ code_samples/mcp/mcp.sh | 60 +++++ .../mcp/src/Command/McpServerListCommand.php | 26 ++ code_samples/mcp/src/Mcp/ExampleTools.php | 15 ++ docs/mcp/mcp.md | 12 + docs/mcp/mcp_config.md | 225 ++++++++++++++++++ docs/mcp/mcp_guide.md | 21 ++ mkdocs.yml | 15 +- 8 files changed, 387 insertions(+), 5 deletions(-) create mode 100644 code_samples/mcp/config/packages/mcp.yaml create mode 100644 code_samples/mcp/mcp.sh create mode 100644 code_samples/mcp/src/Command/McpServerListCommand.php create mode 100644 code_samples/mcp/src/Mcp/ExampleTools.php create mode 100644 docs/mcp/mcp.md create mode 100644 docs/mcp/mcp_config.md create mode 100644 docs/mcp/mcp_guide.md diff --git a/code_samples/mcp/config/packages/mcp.yaml b/code_samples/mcp/config/packages/mcp.yaml new file mode 100644 index 0000000000..137ecb0e69 --- /dev/null +++ b/code_samples/mcp/config/packages/mcp.yaml @@ -0,0 +1,18 @@ +ibexa: + repositories: + default: + mcp: + example: + path: /mcp/example + enabled: true + description: 'Example MCP Server' + instructions: 'Use this server to greet someone.' + discovery_cache: cache.tagaware.filesystem + session: + type: file + directory: '%kernel.cache_dir%/mcp/sessions' + system: + default: + mcp: + servers: + - example diff --git a/code_samples/mcp/mcp.sh b/code_samples/mcp/mcp.sh new file mode 100644 index 0000000000..fd87978832 --- /dev/null +++ b/code_samples/mcp/mcp.sh @@ -0,0 +1,60 @@ +baseUrl='http://localhost' # Adapt to your test case + +jwtToken=`curl -s -X 'POST' \ + "$baseUrl/api/ibexa/v2/user/token/jwt" \ + -H 'Content-Type: application/json' \ + -d '{ + "JWTInput": { + "_media-type": "application/vnd.ibexa.api.JWTInput", + "username": "admin", + "password": "publish" + } + }' | jq -r .JWT.token` + +mcpSessionId=`curl -s -i -X 'POST' "$baseUrl/mcp/example" \ + -H "Authorization: Bearer $jwtToken" \ + -d '{ + "jsonrpc": "2.0", + "id": 1, + "method": "initialize", + "params": { + "protocolVersion": "2025-03-26", + "capabilities": {}, + "clientInfo": { + "name": "test-curl-client", + "version": "1.0.0" + } + } + }' | grep 'Mcp-Session-Id:' | sed 's/Mcp-Session-Id: \([0-9a-f-]*\).*/\1/'` + +curl -s -i -X 'POST' "$baseUrl/mcp/example" \ + -H "Authorization: Bearer $jwtToken" \ + -H "Mcp-Session-Id: $mcpSessionId" \ + -d '{ + "jsonrpc": "2.0", + "method": "notifications/initialized" + }' + +curl -s -X 'POST' "$baseUrl/mcp/example" \ + -H "Authorization: Bearer $jwtToken" \ + -H "Mcp-Session-Id: $mcpSessionId" \ + -d '{ + "jsonrpc": "2.0", + "id": 2, + "method": "tools/list" + }' | jq + +curl -s -X 'POST' "$baseUrl/mcp/example" \ + -H "Authorization: Bearer $jwtToken" \ + -H "Mcp-Session-Id: $mcpSessionId" \ + -d '{ + "jsonrpc": "2.0", + "id": 3, + "method": "tools/call", + "params": { + "name": "greet", + "arguments": { + "name": "World" + } + } + }' | jq diff --git a/code_samples/mcp/src/Command/McpServerListCommand.php b/code_samples/mcp/src/Command/McpServerListCommand.php new file mode 100644 index 0000000000..c3b48dbce9 --- /dev/null +++ b/code_samples/mcp/src/Command/McpServerListCommand.php @@ -0,0 +1,26 @@ +configRegistry->getServerConfigurations() as $serverConfiguration) { + $io->title($serverConfiguration->identifier); + dump($serverConfiguration); + } + + return Command::SUCCESS; + } +} diff --git a/code_samples/mcp/src/Mcp/ExampleTools.php b/code_samples/mcp/src/Mcp/ExampleTools.php new file mode 100644 index 0000000000..ee19659065 --- /dev/null +++ b/code_samples/mcp/src/Mcp/ExampleTools.php @@ -0,0 +1,15 @@ +: + mcp: + : + path: + enabled: true + # Server options… + discovery_cache: + session: + type: + # Session options… + system: + : + mcp: + servers: + - +``` + +TODO: `ddev php bin/console debug:router --siteaccess=` should list some `ibexa.mcp. GET|POST|DELETE|OPTIONS ` + +TODO: Maybe explain that routes are built automatically from MCP server `path` configs thank to `config/routes/ibexa_mcp.yaml` and `\Ibexa\Bundle\Mcp\Routing\McpRouteLoader` + +### MCP server options + +| Option | Type | Required | Default | Description | +|-------------------|---------|----------|---------|-----------------------------------------------| +| `path` | string | Yes | | MCP server endpoint path | +| `enabled` | boolean | No | `false` | Whether the server is enabled | +| `version` | string | No | `1.0.0` | MCP server version | +| `description` | string | No | `null` | Human-readable server description | +| `instructions` | string | No | `null` | Instructions dedicated for LLM interaction | +| `discovery_cache` | string | Yes | | PSR-6 ou PSR-16 cache pool service identifier | +| `session` | object | Yes | | Session storage configuration | + +Notice that a server is disabled by default, it needs to be explicitly enabled. + +### MCP server discovery cache + +TODO + +### MCP server session storage + +#### Options + +| Option | Type | Default | Description | +|-----------|---------|----------|---------------------------------------------------| +| `type` | enum | `memory` | Session store type: `psr16`, `file`, or `memory` | +| `service` | string | `null` | PSR-16 cache service ID for `psr16` session store | +| `prefix` | string | `mcp_` | Key prefix for `psr16` session store | +| `directory` | string | `null` | Directory path for `file` session store | +| `ttl` | integer | `3600` | Session TTL in seconds | + +#### PSR-16 + +Sessions are stored using a PSR-16 compatible cache implementation. Requires service option pointing to a valid cache service ID. + +```yaml + session: + type: psr16 + service: cache.redis.mcp + prefix: 'mcp__' +services: + cache.redis.mcp: + public: true + class: Symfony\Component\Cache\Adapter\RedisTagAwareAdapter + parent: cache.adapter.redis + tags: + - name: cache.pool + clearer: cache.app_clearer + provider: 'redis://mcp.redis:6379' + namespace: 'mcp' +``` + +#### File + +Sessions are persisted to the filesystem. Requires directory option to be set. + +```yaml + session: + type: file + directory: '%kernel.cache_dir%/mcp/sessions' +``` + +#### Memory + +Sessions are stored in memory. Suitable for development and STDIO transport. + +TODO: Might not work with DDEV or Docker + +```yaml + session: + type: memory +``` + +## MCP server capabilities + +TODO: `Ibexa\Contracts\Mcp\McpCapabilityInterface` + +TODO: `Ibexa\Contracts\Mcp\Attribute` namespace + +## Example + +This example introduce an `example` MCP server with a single `greet` tool, enabled on all SiteAccesses. + +In a new `config/packages/mcp.yaml` file, the configuration of the MCP server: + +``` yaml +[[= include_file('code_samples/mcp/config/packages/mcp.yaml') =]] +``` + +Then, a `McpCapabilityInterface`containing a `greet` function with a `McpTool` attribute associating with the `example` server: + +``` php +[[= include_file('code_samples/mcp/src/Mcp/ExampleTools.php') =]] +``` + +To check the server configuration, a short command using the MCP server configuration registry (injected through `McpServerConfigurationRegistryInterface` and autowiring): + +``` php +[[= include_file('code_samples/mcp/src/Command/McpServerListCommand.php') =]] +``` + +To test the `example` MCP server, a sequence of `curl` commands is used to simulate an AI to MCP server communication. + +- Ask for a [JWT token through REST](/api/rest_api/rest_api_reference/rest_api_reference.html#tag/User-Token/operation/api_usertokenjwt_post) +- Initialize a connection to the MCP server +- Validate the MCP Session ID +- List the available tools +- Call a tool + +`jq`, `grep`, and `sed` are also used to parse or display outputs. + +The [initialization](https://modelcontextprotocol.io/specification/draft/basic/lifecycle#initialization): + +``` bash +[[= include_file('code_samples/mcp/mcp.sh', 0, 36) =]] +``` + +``` +HTTP/1.1 202 Accepted +Access-Control-Allow-Headers: Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID, Authorization, Accept +Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS +Access-Control-Expose-Headers: Mcp-Session-Id +``` + +The [list of tools](https://modelcontextprotocol.io/specification/draft/server/tools#listing-tools): + +``` bash +[[= include_file('code_samples/mcp/mcp.sh', 37, 45) =]] +``` + +```json +{ + "jsonrpc": "2.0", + "id": 2, + "result": { + "tools": [ + { + "name": "greet", + "inputSchema": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ] + }, + "description": "Greet a user by name" + } + ] + } +} +``` + +The `greet` [tool usage](https://modelcontextprotocol.io/specification/draft/server/tools#calling-tools): + +``` bash +[[= include_file('code_samples/mcp/mcp.sh', 46) =]] +``` + +```json +{ + "jsonrpc": "2.0", + "id": 3, + "result": { + "content": [ + { + "type": "text", + "text": "Hello, World!" + } + ], + "isError": false + } +} +``` + +TODO: Connect an AI client to the MCP server. [Copilot CLI MCP server addition](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers) is strangely asking for some OAuth ID even with a proper JWT/Bearer header. diff --git a/docs/mcp/mcp_guide.md b/docs/mcp/mcp_guide.md new file mode 100644 index 0000000000..534320c74a --- /dev/null +++ b/docs/mcp/mcp_guide.md @@ -0,0 +1,21 @@ +--- +description: TODO. +month_change: true +--- + +# Model Context Protocol and [[= product_name_base =]] MCP Servers + +[Model Context Protocol (MCP)](https://en.wikipedia.org/wiki/Model_Context_Protocol) is a protocol standardizing interactions between AIs and systems. + +While [AI actions](ai_actions_guide.md) integrate AI to the back office, +[[= product_name =]]'s MCP servers offer a web interface usable by AIs outside the system. + +`ibexa/mcp` package provides built-in MCP servers and a PHP API to create custom ones. + +TODO: About built-in MCP servers (translations agents, SEO optimization agents,…) + +MCP servers capabilities (tools, prompts, and resources) can be created and associated to MCP servers thanks to a PHP API mainly based on attributes. + +MCP servers are configured per repository then enabled per SiteAccess scope, allowing for flexible configurations adapted to different contexts. + +MCP servers have their own session storage mechanism, TODO: why, benefit,… diff --git a/mkdocs.yml b/mkdocs.yml index 158817bf9a..24aab393d6 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -346,11 +346,16 @@ nav: - Add login form: templating/layout/add_login_form.md - Add navigation menu: templating/layout/add_navigation_menu.md - Add search form to front page: templating/layout/add_search_form.md - - AI Actions: - - AI Actions: ai_actions/ai_actions.md - - AI Actions guide: ai_actions/ai_actions_guide.md - - Configure AI Actions: ai_actions/configure_ai_actions.md - - Extend AI Actions: ai_actions/extend_ai_actions.md + - AI: + - AI Actions: + - AI Actions: ai_actions/ai_actions.md + - AI Actions guide: ai_actions/ai_actions_guide.md + - Configure AI Actions: ai_actions/configure_ai_actions.md + - Extend AI Actions: ai_actions/extend_ai_actions.md + - MCP Servers: + - MCP Servers: mcp/mcp.md + - MCP Servers guide: mcp/mcp_guide.md + - Configure MCP Servers: mcp/mcp_config.md - PIM (Product management): - PIM (Product management): pim/pim.md - PIM guide: pim/pim_guide.md From 7307f02ad84cf4ec0bc34f5db3d7ce49d5fc9c18 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Thu, 26 Mar 2026 11:20:18 +0100 Subject: [PATCH 02/12] Fix MkDocs variable VS `cards` mcp_guide.md heading `# Model Context Protocol and [[= product_name_base =]] MCP Servers` was used as-is, without the variable replaced. --- docs/mcp/mcp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mcp/mcp.md b/docs/mcp/mcp.md index 58217fb62f..b61bcf8add 100644 --- a/docs/mcp/mcp.md +++ b/docs/mcp/mcp.md @@ -7,6 +7,6 @@ month_change: true # MCP Servers [[= cards([ -"mcp/mcp_guide", +("mcp/mcp_guide", "MCP Servers guide", "TODO."), "mcp/mcp_config", ], columns=2) =]] From c2215e56c9275656fced8365e0546286e4af7b08 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Thu, 26 Mar 2026 11:20:43 +0100 Subject: [PATCH 03/12] composer.json: Add ibexa/mcp --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 1f8cb44b1e..961e030d76 100644 --- a/composer.json +++ b/composer.json @@ -34,6 +34,7 @@ "ibexa/core-persistence": "5.0.x-dev", "ibexa/connector-ai": "5.0.x-dev", "ibexa/connector-openai": "5.0.x-dev", + "ibexa/mcp": "dev-main", "ibexa/migrations": "5.0.x-dev", "ibexa/cart": "5.0.x-dev", "ibexa/installer": "5.0.x-dev", From d1b50e21e64e08a99284840dd533dfbe1f998013 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Thu, 26 Mar 2026 11:23:41 +0100 Subject: [PATCH 04/12] =?UTF-8?q?mcp=5Fconfig.md:=20Fix=20spelling=20authe?= =?UTF-8?q?ntification=20=E2=86=92=20authentication?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/mcp/mcp_config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mcp/mcp_config.md b/docs/mcp/mcp_config.md index 4541737ef4..e4d93e3d64 100644 --- a/docs/mcp/mcp_config.md +++ b/docs/mcp/mcp_config.md @@ -9,7 +9,7 @@ TODO: built-in MCP servers VS custom MCP servers ## JWT -MCP servers use JWT for authentification. +MCP servers use JWT for authentication. TODO: [Enable authorization header in `config/packages/lexik_jwt_authentication.yaml`](development_security.md#jwt-authentication). From 3b4d89ffc412631b8d2a5e044f38cb3bf26e9109 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Thu, 26 Mar 2026 11:35:21 +0100 Subject: [PATCH 05/12] mcp_config.md: Continue example intro --- docs/mcp/mcp_config.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/mcp/mcp_config.md b/docs/mcp/mcp_config.md index e4d93e3d64..e7889d6bd6 100644 --- a/docs/mcp/mcp_config.md +++ b/docs/mcp/mcp_config.md @@ -67,8 +67,8 @@ TODO #### Options -| Option | Type | Default | Description | -|-----------|---------|----------|---------------------------------------------------| +| Option | Type | Default | Description | +|-------------|---------|----------|---------------------------------------------------| | `type` | enum | `memory` | Session store type: `psr16`, `file`, or `memory` | | `service` | string | `null` | PSR-16 cache service ID for `psr16` session store | | `prefix` | string | `mcp_` | Key prefix for `psr16` session store | @@ -125,7 +125,10 @@ TODO: `Ibexa\Contracts\Mcp\Attribute` namespace ## Example -This example introduce an `example` MCP server with a single `greet` tool, enabled on all SiteAccesses. +This example introduce an `example` MCP server with a single `greet` tool. +It's enabled on all SiteAccesses. +It's accessible with the path `/mcp/example` (for example, on `http://localhost/mcp/example` and `http://localhost/admin/mcp/example`). +It uses files for both discovery cache and session storage. In a new `config/packages/mcp.yaml` file, the configuration of the MCP server: From a40d3dc235c211dd5c9af47b73e56446407c5315 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Thu, 26 Mar 2026 11:47:23 +0100 Subject: [PATCH 06/12] mcp.md: Short intro to the cards --- docs/mcp/mcp.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/mcp/mcp.md b/docs/mcp/mcp.md index b61bcf8add..b328047e4e 100644 --- a/docs/mcp/mcp.md +++ b/docs/mcp/mcp.md @@ -6,6 +6,9 @@ month_change: true # MCP Servers +MCP servers allow AI interactions with the system. +Learn more about this protocol and [[= product_name_base =]] MCP Servers: + [[= cards([ ("mcp/mcp_guide", "MCP Servers guide", "TODO."), "mcp/mcp_config", From 9ba2f81ee9036f855205545ab169793b76ff4ac2 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Thu, 26 Mar 2026 16:38:41 +0100 Subject: [PATCH 07/12] Replace backticks with '$()' syntax for command substitution. Apply SonarCloud Code Analysis warning's suggestion --- code_samples/mcp/mcp.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code_samples/mcp/mcp.sh b/code_samples/mcp/mcp.sh index fd87978832..7a0d943fb4 100644 --- a/code_samples/mcp/mcp.sh +++ b/code_samples/mcp/mcp.sh @@ -1,6 +1,6 @@ baseUrl='http://localhost' # Adapt to your test case -jwtToken=`curl -s -X 'POST' \ +jwtToken=$(curl -s -X 'POST' \ "$baseUrl/api/ibexa/v2/user/token/jwt" \ -H 'Content-Type: application/json' \ -d '{ @@ -9,9 +9,9 @@ jwtToken=`curl -s -X 'POST' \ "username": "admin", "password": "publish" } - }' | jq -r .JWT.token` + }' | jq -r .JWT.token) -mcpSessionId=`curl -s -i -X 'POST' "$baseUrl/mcp/example" \ +mcpSessionId=$(curl -s -i -X 'POST' "$baseUrl/mcp/example" \ -H "Authorization: Bearer $jwtToken" \ -d '{ "jsonrpc": "2.0", @@ -25,7 +25,7 @@ mcpSessionId=`curl -s -i -X 'POST' "$baseUrl/mcp/example" \ "version": "1.0.0" } } - }' | grep 'Mcp-Session-Id:' | sed 's/Mcp-Session-Id: \([0-9a-f-]*\).*/\1/'` + }' | grep 'Mcp-Session-Id:' | sed 's/Mcp-Session-Id: \([0-9a-f-]*\).*/\1/') curl -s -i -X 'POST' "$baseUrl/mcp/example" \ -H "Authorization: Bearer $jwtToken" \ From 618984f455a8dec19b6e82f4abcaa804e5a067e5 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Wed, 8 Apr 2026 17:58:17 +0200 Subject: [PATCH 08/12] Group AI features --- docs/ai/ai.md | 19 ++++++++++++++++++ docs/{ => ai}/ai_actions/ai_actions.md | 7 +++---- docs/{ => ai}/ai_actions/ai_actions_guide.md | 0 .../ai_actions/configure_ai_actions.md | 0 docs/{ => ai}/ai_actions/extend_ai_actions.md | 0 .../ai_actions/img/action_handler_options.png | Bin .../ai_actions/img/ai_actions_list.png | Bin docs/{ => ai}/ai_actions/img/ai_assistant.png | Bin .../ai_actions/img/alt_text_use_ai.png | Bin .../ai_actions/img/connect_api_token.png | Bin .../img/diagram_source/AI Actions.drawio | 0 .../ai_actions/img/guide_ai_actions.png | Bin .../ai_actions/img/transcribe_audio.png | Bin docs/{ => ai}/mcp/mcp.md | 4 ++-- docs/{ => ai}/mcp/mcp_config.md | 0 docs/{ => ai}/mcp/mcp_guide.md | 2 +- docs/product_guides/product_guides.md | 2 ++ mkdocs.yml | 15 +++++++------- plugins.yml | 7 ++++++- 19 files changed, 41 insertions(+), 15 deletions(-) create mode 100644 docs/ai/ai.md rename docs/{ => ai}/ai_actions/ai_actions.md (92%) rename docs/{ => ai}/ai_actions/ai_actions_guide.md (100%) rename docs/{ => ai}/ai_actions/configure_ai_actions.md (100%) rename docs/{ => ai}/ai_actions/extend_ai_actions.md (100%) rename docs/{ => ai}/ai_actions/img/action_handler_options.png (100%) rename docs/{ => ai}/ai_actions/img/ai_actions_list.png (100%) rename docs/{ => ai}/ai_actions/img/ai_assistant.png (100%) rename docs/{ => ai}/ai_actions/img/alt_text_use_ai.png (100%) rename docs/{ => ai}/ai_actions/img/connect_api_token.png (100%) rename docs/{ => ai}/ai_actions/img/diagram_source/AI Actions.drawio (100%) rename docs/{ => ai}/ai_actions/img/guide_ai_actions.png (100%) rename docs/{ => ai}/ai_actions/img/transcribe_audio.png (100%) rename docs/{ => ai}/mcp/mcp.md (76%) rename docs/{ => ai}/mcp/mcp_config.md (100%) rename docs/{ => ai}/mcp/mcp_guide.md (93%) diff --git a/docs/ai/ai.md b/docs/ai/ai.md new file mode 100644 index 0000000000..195d7d9c7f --- /dev/null +++ b/docs/ai/ai.md @@ -0,0 +1,19 @@ +--- +description: AI interactions with Ibexa DXP +page_type: landing_page +month_change: true +--- + +# Artificial Intelligence (AI) + +[[= product_name =]] embed AI capabilities, for example, +to make recommendations to product customers and content readers with [Raptor connector][[#(raptor_connector_guide.md)#]], +or to help editors in the back office with [AI Actions](ai_actions_guide.md). +It's also opened to external AI capabilities with the exposition of [Model Context Protocol (MCP) servers](mcp_guide.md) to allow agents to interact with the system. +It's extensible. For example, new AI actions or MCP servers can be implemented. +To go further, an AI can learn to use the REST API, or learn the PHP API and help you in your development. + +[[= cards([ + "ai/ai_actions/ai_actions", + "ai/mcp/mcp", +], columns=2) =]] diff --git a/docs/ai_actions/ai_actions.md b/docs/ai/ai_actions/ai_actions.md similarity index 92% rename from docs/ai_actions/ai_actions.md rename to docs/ai/ai_actions/ai_actions.md index 1c02575b98..626ec0db87 100644 --- a/docs/ai_actions/ai_actions.md +++ b/docs/ai/ai_actions/ai_actions.md @@ -14,8 +14,8 @@ You can also extend it to perform other tasks or support additional AI services. ## Getting Started [[= cards([ -"ai_actions/ai_actions_guide", -"ai_actions/configure_ai_actions", +"ai/ai_actions/ai_actions_guide", +"ai/ai_actions/configure_ai_actions", ("content_management/taxonomy/taxonomy#taxonomy-suggestions", "Taxonomy suggestions", "Learn how to use AI to suggest tags and categories"), ("permissions/policies#ai-actions", "Policies", "Learn about the available AI Actions policies"), ("https://doc.ibexa.co/projects/userguide/en/5.0/ai_actions/work_with_ai_actions/"), @@ -24,7 +24,7 @@ You can also extend it to perform other tasks or support additional AI services. ## Development [[= cards([ -"ai_actions/extend_ai_actions", +"ai/ai_actions/extend_ai_actions", "api/event_reference/ai_action_events", ("https://doc.ibexa.co/en/5.0/api/rest_api/rest_api_reference/rest_api_reference.html#tag/Connector-AI", "REST API Reference", "See the available endpoints for AI Actions"), "templating/twig_function_reference/ai_actions_twig_functions", @@ -32,4 +32,3 @@ You can also extend it to perform other tasks or support additional AI services. "search/ai_actions_search_reference/action_configuration_sort_clauses", ("content_management/data_migration/importing_data#ai-action-configurations", "Importing AI actions", "Learn how to manage Action Configurations using data migrations"), ], columns=4) =]] - diff --git a/docs/ai_actions/ai_actions_guide.md b/docs/ai/ai_actions/ai_actions_guide.md similarity index 100% rename from docs/ai_actions/ai_actions_guide.md rename to docs/ai/ai_actions/ai_actions_guide.md diff --git a/docs/ai_actions/configure_ai_actions.md b/docs/ai/ai_actions/configure_ai_actions.md similarity index 100% rename from docs/ai_actions/configure_ai_actions.md rename to docs/ai/ai_actions/configure_ai_actions.md diff --git a/docs/ai_actions/extend_ai_actions.md b/docs/ai/ai_actions/extend_ai_actions.md similarity index 100% rename from docs/ai_actions/extend_ai_actions.md rename to docs/ai/ai_actions/extend_ai_actions.md diff --git a/docs/ai_actions/img/action_handler_options.png b/docs/ai/ai_actions/img/action_handler_options.png similarity index 100% rename from docs/ai_actions/img/action_handler_options.png rename to docs/ai/ai_actions/img/action_handler_options.png diff --git a/docs/ai_actions/img/ai_actions_list.png b/docs/ai/ai_actions/img/ai_actions_list.png similarity index 100% rename from docs/ai_actions/img/ai_actions_list.png rename to docs/ai/ai_actions/img/ai_actions_list.png diff --git a/docs/ai_actions/img/ai_assistant.png b/docs/ai/ai_actions/img/ai_assistant.png similarity index 100% rename from docs/ai_actions/img/ai_assistant.png rename to docs/ai/ai_actions/img/ai_assistant.png diff --git a/docs/ai_actions/img/alt_text_use_ai.png b/docs/ai/ai_actions/img/alt_text_use_ai.png similarity index 100% rename from docs/ai_actions/img/alt_text_use_ai.png rename to docs/ai/ai_actions/img/alt_text_use_ai.png diff --git a/docs/ai_actions/img/connect_api_token.png b/docs/ai/ai_actions/img/connect_api_token.png similarity index 100% rename from docs/ai_actions/img/connect_api_token.png rename to docs/ai/ai_actions/img/connect_api_token.png diff --git a/docs/ai_actions/img/diagram_source/AI Actions.drawio b/docs/ai/ai_actions/img/diagram_source/AI Actions.drawio similarity index 100% rename from docs/ai_actions/img/diagram_source/AI Actions.drawio rename to docs/ai/ai_actions/img/diagram_source/AI Actions.drawio diff --git a/docs/ai_actions/img/guide_ai_actions.png b/docs/ai/ai_actions/img/guide_ai_actions.png similarity index 100% rename from docs/ai_actions/img/guide_ai_actions.png rename to docs/ai/ai_actions/img/guide_ai_actions.png diff --git a/docs/ai_actions/img/transcribe_audio.png b/docs/ai/ai_actions/img/transcribe_audio.png similarity index 100% rename from docs/ai_actions/img/transcribe_audio.png rename to docs/ai/ai_actions/img/transcribe_audio.png diff --git a/docs/mcp/mcp.md b/docs/ai/mcp/mcp.md similarity index 76% rename from docs/mcp/mcp.md rename to docs/ai/mcp/mcp.md index b328047e4e..a996203011 100644 --- a/docs/mcp/mcp.md +++ b/docs/ai/mcp/mcp.md @@ -10,6 +10,6 @@ MCP servers allow AI interactions with the system. Learn more about this protocol and [[= product_name_base =]] MCP Servers: [[= cards([ -("mcp/mcp_guide", "MCP Servers guide", "TODO."), -"mcp/mcp_config", + ("mcp/mcp_guide", "MCP Servers guide", "TODO."), + "mcp/mcp_config", ], columns=2) =]] diff --git a/docs/mcp/mcp_config.md b/docs/ai/mcp/mcp_config.md similarity index 100% rename from docs/mcp/mcp_config.md rename to docs/ai/mcp/mcp_config.md diff --git a/docs/mcp/mcp_guide.md b/docs/ai/mcp/mcp_guide.md similarity index 93% rename from docs/mcp/mcp_guide.md rename to docs/ai/mcp/mcp_guide.md index 534320c74a..fd23d09f91 100644 --- a/docs/mcp/mcp_guide.md +++ b/docs/ai/mcp/mcp_guide.md @@ -3,7 +3,7 @@ description: TODO. month_change: true --- -# Model Context Protocol and [[= product_name_base =]] MCP Servers +# Model Context Protocol and Ibexa MCP Servers [Model Context Protocol (MCP)](https://en.wikipedia.org/wiki/Model_Context_Protocol) is a protocol standardizing interactions between AIs and systems. diff --git a/docs/product_guides/product_guides.md b/docs/product_guides/product_guides.md index 1c2359f5b2..5bc085b809 100644 --- a/docs/product_guides/product_guides.md +++ b/docs/product_guides/product_guides.md @@ -23,4 +23,6 @@ Discover the primary ones with the help of product guides. Condensed content all "commerce/shopping_list/shopping_list_guide", "ibexa_cloud/ibexa_cloud_guide", "cdp/cdp_guide", + "ai/ai_actions/ai_actions_guide", + "ai/mcp/mcp_guide", ], columns=4) =]] diff --git a/mkdocs.yml b/mkdocs.yml index 24aab393d6..0d9dd3636b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -347,15 +347,16 @@ nav: - Add navigation menu: templating/layout/add_navigation_menu.md - Add search form to front page: templating/layout/add_search_form.md - AI: + - AI: ai/ai.md - AI Actions: - - AI Actions: ai_actions/ai_actions.md - - AI Actions guide: ai_actions/ai_actions_guide.md - - Configure AI Actions: ai_actions/configure_ai_actions.md - - Extend AI Actions: ai_actions/extend_ai_actions.md + - AI Actions: ai/ai_actions/ai_actions.md + - AI Actions guide: ai/ai_actions/ai_actions_guide.md + - Configure AI Actions: ai/ai_actions/configure_ai_actions.md + - Extend AI Actions: ai/ai_actions/extend_ai_actions.md - MCP Servers: - - MCP Servers: mcp/mcp.md - - MCP Servers guide: mcp/mcp_guide.md - - Configure MCP Servers: mcp/mcp_config.md + - MCP Servers: ai/mcp/mcp.md + - MCP Servers guide: ai/mcp/mcp_guide.md + - Configure MCP Servers: ai/mcp/mcp_config.md - PIM (Product management): - PIM (Product management): pim/pim.md - PIM guide: pim/pim_guide.md diff --git a/plugins.yml b/plugins.yml index 32e5e94c06..fc5687355e 100644 --- a/plugins.yml +++ b/plugins.yml @@ -563,6 +563,11 @@ plugins: 'getting_started/install_on_ibexa_cloud.md': 'ibexa_cloud/install_on_ibexa_cloud.md' 'infrastructure_and_maintenance/clustering/ddev_and_ibexa_cloud.md': 'ibexa_cloud/ddev_and_ibexa_cloud.md' - 'ai_actions/install_ai_actions.md': 'ai_actions/configure_ai_actions.md' 'discounts/install_discounts.md': 'discounts/configure_discounts.md' 'content_management/collaborative_editing/install_collaborative_editing.md': 'content_management/collaborative_editing/configure_collaborative_editing.md' + + 'ai_actions/ai_actions.md': 'ai/ai_actions/ai_actions.md' + 'ai_actions/ai_actions_guide.md': 'ai/ai_actions/ai_actions_guide.md' + 'ai_actions/install_ai_actions.md': 'ai/ai_actions/configure_ai_actions.md' + 'ai_actions/configure_ai_actions.md': 'ai/ai_actions/configure_ai_actions.md' + 'ai_actions/extend_ai_actions.md': 'ai/ai_actions/extend_ai_actions.md' From 81def20366e87bcbbd090c360d2d612ca1561153 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Wed, 8 Apr 2026 18:00:01 +0200 Subject: [PATCH 09/12] Apply suggestion from @adriendupuis --- docs/ai/mcp/mcp_guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ai/mcp/mcp_guide.md b/docs/ai/mcp/mcp_guide.md index fd23d09f91..092fbe21ca 100644 --- a/docs/ai/mcp/mcp_guide.md +++ b/docs/ai/mcp/mcp_guide.md @@ -5,7 +5,7 @@ month_change: true # Model Context Protocol and Ibexa MCP Servers -[Model Context Protocol (MCP)](https://en.wikipedia.org/wiki/Model_Context_Protocol) is a protocol standardizing interactions between AIs and systems. +[Model Context Protocol (MCP)](https://modelcontextprotocol.io/docs/getting-started/intro) is a protocol standardizing interactions between AIs and systems. While [AI actions](ai_actions_guide.md) integrate AI to the back office, [[= product_name =]]'s MCP servers offer a web interface usable by AIs outside the system. From acd92917f1f40c0478c4104233f7e33dbe6478fe Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Wed, 8 Apr 2026 18:11:53 +0200 Subject: [PATCH 10/12] ai_actions_guide.md: Fix link to REST API Ref --- docs/ai/ai_actions/ai_actions_guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ai/ai_actions/ai_actions_guide.md b/docs/ai/ai_actions/ai_actions_guide.md index 8fe4a6377b..cfc6636781 100644 --- a/docs/ai/ai_actions/ai_actions_guide.md +++ b/docs/ai/ai_actions/ai_actions_guide.md @@ -115,7 +115,7 @@ Procedures are straightforward and intuitive, ensuring that users can quickly ac AI Actions feature exposes a REST API interface that allows for programmatic execution of AI actions. With the API, developers can automate tasks and execute actions on batches of content by integrating them into workflows. -For more information, see the [AI actions section in the REST API Reference](../api/rest_api/rest_api_reference/rest_api_reference.html#ai-actions-execute-ai-action). +For more information, see the [AI actions section in the REST API Reference](/api/rest_api/rest_api_reference/rest_api_reference.html#ai-actions-execute-ai-action). ## Capabilities From c3dca5fd8d54d7b1b2b499e4afa4d0ff51fe374f Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Wed, 8 Apr 2026 18:12:57 +0200 Subject: [PATCH 11/12] mcp.md: Update links after move to ai/ --- docs/ai/mcp/mcp.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ai/mcp/mcp.md b/docs/ai/mcp/mcp.md index a996203011..24fcab72fe 100644 --- a/docs/ai/mcp/mcp.md +++ b/docs/ai/mcp/mcp.md @@ -10,6 +10,6 @@ MCP servers allow AI interactions with the system. Learn more about this protocol and [[= product_name_base =]] MCP Servers: [[= cards([ - ("mcp/mcp_guide", "MCP Servers guide", "TODO."), - "mcp/mcp_config", + ("ai/mcp/mcp_guide", "MCP Servers guide", "TODO."), + "ai/mcp/mcp_config", ], columns=2) =]] From c0e0b7e3b6fcaf4c9a6b19d5ae90b6cb29235bc6 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Wed, 8 Apr 2026 19:23:28 +0200 Subject: [PATCH 12/12] extend_ai_actions.md: Fix link to REST API Ref --- docs/ai/ai_actions/extend_ai_actions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ai/ai_actions/extend_ai_actions.md b/docs/ai/ai_actions/extend_ai_actions.md index 4bbe4f198e..5eda773773 100644 --- a/docs/ai/ai_actions/extend_ai_actions.md +++ b/docs/ai/ai_actions/extend_ai_actions.md @@ -244,7 +244,7 @@ The Action Type options provided in the Action Context dictate whether the times ### Integrate with the REST API At this point the custom Action Type can already be executed by using the PHP API. -To integrate it with the [AI Actions execute endpoint](../api/rest_api/rest_api_reference/rest_api_reference.html#ai-actions-execute-ai-action) you need to create additional classes responsible for parsing the request and response data. +To integrate it with the [AI Actions execute endpoint](/api/rest_api/rest_api_reference/rest_api_reference.html#ai-actions-execute-ai-action) you need to create additional classes responsible for parsing the request and response data. See [adding custom media type](adding_custom_media_type.md) and [creating new REST resource](creating_new_rest_resource.md) to learn more about extending the REST API. #### Handle input data