Skip to content
Draft
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
148d07c
MCP Servers doc draft
adriendupuis Mar 26, 2026
7307f02
Fix MkDocs variable VS `cards`
adriendupuis Mar 26, 2026
c2215e5
composer.json: Add ibexa/mcp
adriendupuis Mar 26, 2026
d1b50e2
mcp_config.md: Fix spelling authentification → authentication
adriendupuis Mar 26, 2026
3b4d89f
mcp_config.md: Continue example intro
adriendupuis Mar 26, 2026
a40d3dc
mcp.md: Short intro to the cards
adriendupuis Mar 26, 2026
9ba2f81
Replace backticks with '$()' syntax for command substitution.
adriendupuis Mar 26, 2026
618984f
Group AI features
adriendupuis Apr 8, 2026
81def20
Apply suggestion from @adriendupuis
adriendupuis Apr 8, 2026
acd9291
ai_actions_guide.md: Fix link to REST API Ref
adriendupuis Apr 8, 2026
c3dca5f
mcp.md: Update links after move to ai/
adriendupuis Apr 8, 2026
fff74f7
Merge branch '5.0' into mcp
adriendupuis Apr 8, 2026
c0e0b7e
extend_ai_actions.md: Fix link to REST API Ref
adriendupuis Apr 8, 2026
ad3cc47
PHP API Ref
adriendupuis Apr 17, 2026
0836df3
Move to tools in server config
adriendupuis Apr 17, 2026
736edd1
Move to tools in server config
adriendupuis Apr 20, 2026
6107946
PHP & JS CS Fixes
adriendupuis Apr 20, 2026
a6953e1
Add MCP Inspector test
adriendupuis Apr 20, 2026
a73386b
Add MCP Inspector test
adriendupuis Apr 20, 2026
ec27fdf
Merge branch '5.0' into mcp
adriendupuis Apr 20, 2026
b588db3
Apply suggestion from @adriendupuis
adriendupuis Apr 20, 2026
266ea8b
Apply suggestions from code review
adriendupuis Apr 21, 2026
910c49c
Continue MCP servers doc
adriendupuis Apr 22, 2026
d101b58
ExampleTools.php: move servers to top
adriendupuis Apr 22, 2026
71e80cb
MCP: Continue with prompts
adriendupuis Apr 22, 2026
c9e1c82
Merge branch '5.0' into mcp
adriendupuis Apr 22, 2026
181fb77
PHP & JS CS Fixes
adriendupuis Apr 22, 2026
d8cc209
Fix missingType.iterableValue
adriendupuis Apr 22, 2026
a5ba48b
mcp_guide.md: Fix anchor
adriendupuis Apr 22, 2026
f4d55f8
Rework JWT doc for REST and MCP
adriendupuis Apr 23, 2026
12a15be
Rework JWT doc for REST and MCP
adriendupuis Apr 23, 2026
e568133
Added code for testing YAML samples
mnocon Apr 23, 2026
546acd6
Rework JWT doc for REST and MCP
adriendupuis Apr 23, 2026
05f0f5c
Rework JWT doc for REST and MCP
adriendupuis Apr 23, 2026
686c428
Generated baseline
mnocon Apr 23, 2026
b201298
Rework JWT doc for MCP
adriendupuis Apr 23, 2026
90c44f2
Rework JWT doc for MCP
adriendupuis Apr 23, 2026
39b4645
Rework JWT doc for MCP
adriendupuis Apr 23, 2026
71f5890
Fixes - first batch
mnocon Apr 23, 2026
b144d93
Fixes - batch 2
mnocon Apr 23, 2026
ad17a4b
fixup! Added code for testing YAML samples
mnocon Apr 23, 2026
648fa58
Selfreview
mnocon Apr 23, 2026
5806a08
Copilot CLI example
adriendupuis Apr 23, 2026
a116dea
MCP servers: change menu entry
adriendupuis Apr 23, 2026
781e516
Rename example PHP class
adriendupuis Apr 24, 2026
8284cc9
Update example to illustrate outputSchema
adriendupuis Apr 24, 2026
6399410
Merge branch '5.0' into mcp
adriendupuis Apr 24, 2026
6e90953
PHP & JS CS Fixes
adriendupuis Apr 24, 2026
d5615d9
security_checklist.md + JWT
adriendupuis Apr 24, 2026
2fd9ba5
ai.md: apply some vale suggestions, rewording
adriendupuis Apr 25, 2026
29bf219
mcp_config.md: apply some vale suggestions, rewording
adriendupuis Apr 25, 2026
bdee1e1
MCP server practice
adriendupuis Apr 25, 2026
208b65e
MCP server user account
adriendupuis Apr 25, 2026
1c58dcc
More about tool inputSchema
adriendupuis Apr 27, 2026
24b2b81
More about icons and _meta
adriendupuis Apr 27, 2026
a214f9f
PHP & JS CS Fixes
adriendupuis Apr 27, 2026
1e881eb
Merge branch '5.0' into mcp
adriendupuis Apr 27, 2026
f3185a3
Merge remote-tracking branch 'origin/test-yamls' into mcp
adriendupuis Apr 27, 2026
5ea4811
About storage
adriendupuis Apr 27, 2026
f986db5
About repo
adriendupuis Apr 27, 2026
3f4a393
start moving config samples from Markdown to a YAML file
adriendupuis Apr 27, 2026
a52c164
finish moving config samples from Markdown to a YAML file
adriendupuis Apr 27, 2026
3fa7efb
Revert "Merge remote-tracking branch 'origin/test-yamls' into mcp"
adriendupuis Apr 27, 2026
282a02c
More verbose curl script
adriendupuis Apr 28, 2026
178ca6a
mcp_config: remove repetition
adriendupuis Apr 28, 2026
adb2947
Merge branch '5.0' into mcp
adriendupuis Apr 29, 2026
56c2261
include_file → include_code
adriendupuis Apr 29, 2026
a28ab1e
meta desc
adriendupuis Apr 29, 2026
80a7de9
REST doc example to get a JWT token
adriendupuis Apr 30, 2026
7b3fca4
cURL → curl
adriendupuis Apr 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions code_samples/mcp/config/packages/mcp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
ibexa:
repositories:
default:
mcp:
example:
path: /mcp/example
enabled: true
description: 'Example MCP Server'
instructions: 'Use this server to greet someone.'
tools:
- App\Mcp\ExampleTools
Comment thread
adriendupuis marked this conversation as resolved.
Outdated
discovery_cache: cache.tagaware.filesystem
session:
type: file
directory: '%kernel.cache_dir%/mcp/sessions'
system:
default:
mcp:
servers:
- example
60 changes: 60 additions & 0 deletions code_samples/mcp/mcp.sh
Original file line number Diff line number Diff line change
@@ -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
26 changes: 26 additions & 0 deletions code_samples/mcp/src/Command/McpServerListCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php declare(strict_types=1);

namespace App\mcp\src\Command;

use Ibexa\Contracts\Mcp\McpServerConfigurationRegistryInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(name: 'app:mcp:server_list', description: 'List MCP servers')]
class McpServerListCommand
{
public function __construct(private readonly McpServerConfigurationRegistryInterface $configRegistry)
{
}

public function __invoke(SymfonyStyle $io): int
{
foreach($this->configRegistry->getServerConfigurations() as $serverConfiguration) {
$io->title($serverConfiguration->identifier);
dump($serverConfiguration);
}

return Command::SUCCESS;
}
}
29 changes: 29 additions & 0 deletions code_samples/mcp/src/Mcp/ExampleTools.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php declare(strict_types=1);

namespace App\Mcp;

use Ibexa\Contracts\Mcp\Attribute\McpTool;
use Ibexa\Contracts\Mcp\McpCapabilityInterface;
use Mcp\Schema\Icon;
use Mcp\Schema\ToolAnnotations;

final readonly class ExampleTools implements McpCapabilityInterface
{
#[McpTool(
name: 'greet',
description: 'Greet a user by name',
icons: [new Icon(
src: 'https://openmoji.org/data/color/svg/1F44B.svg',
)],
annotations: new ToolAnnotations(
readOnlyHint: true,
destructiveHint: false,
idempotentHint: true,
openWorldHint: false,
),
)]
Comment thread
adriendupuis marked this conversation as resolved.
Outdated
public function greetByName(string $name): string
{
return sprintf('Hello, %s!', $name);
}
}
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "5.0.x-dev",
"ibexa/migrations": "5.0.x-dev",
"ibexa/cart": "5.0.x-dev",
"ibexa/installer": "5.0.x-dev",
Expand Down
19 changes: 19 additions & 0 deletions docs/ai/ai.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
description: AI interactions with Ibexa DXP

Check failure on line 2 in docs/ai/ai.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/ai/ai.md#L2

[Ibexa.VariablesGlobal] Use global variable '[[= product_name_base =]]' instead of 'Ibexa'
Raw output
{"message": "[Ibexa.VariablesGlobal] Use global variable '[[= product_name_base =]]' instead of 'Ibexa'", "location": {"path": "docs/ai/ai.md", "range": {"start": {"line": 2, "column": 35}}}, "severity": "ERROR"}
page_type: landing_page
month_change: true
---

# Artificial Intelligence (AI)

Check notice on line 7 in docs/ai/ai.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/ai/ai.md#L7

[Ibexa.SentenceCapitalizationInHeadings] Use sentence-style capitalization in headings
Raw output
{"message": "[Ibexa.SentenceCapitalizationInHeadings] Use sentence-style capitalization in headings", "location": {"path": "docs/ai/ai.md", "range": {"start": {"line": 7, "column": 3}}}, "severity": "INFO"}

[[= 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.

Check notice on line 13 in docs/ai/ai.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/ai/ai.md#L13

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/ai/ai.md", "range": {"start": {"line": 13, "column": 65}}}, "severity": "INFO"}
To go further, an AI can learn to use the REST API, or learn the PHP API and help you in your development.

Check warning on line 14 in docs/ai/ai.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/ai/ai.md#L14

[Ibexa.OxfordComma] Use a comma before the last 'and' or 'or' in a list of four or more items.
Raw output
{"message": "[Ibexa.OxfordComma] Use a comma before the last 'and' or 'or' in a list of four or more items.", "location": {"path": "docs/ai/ai.md", "range": {"start": {"line": 14, "column": 1}}}, "severity": "WARNING"}

[[= cards([
"ai/ai_actions/ai_actions",
"ai/mcp/mcp",
], columns=2) =]]
Original file line number Diff line number Diff line change
Expand Up @@ -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/"),
Expand All @@ -24,12 +24,11 @@ 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",
"search/ai_actions_search_reference/action_configuration_criteria",
"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) =]]

Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Binary file added docs/ai/mcp/img/mcp-inspector-config.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/ai/mcp/img/mcp-inspector-greet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions docs/ai/mcp/mcp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
description: TODO.
page_type: landing_page
month_change: true
---

# MCP Servers

Check notice on line 7 in docs/ai/mcp/mcp.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/ai/mcp/mcp.md#L7

[Ibexa.SentenceCapitalizationInHeadings] Use sentence-style capitalization in headings
Raw output
{"message": "[Ibexa.SentenceCapitalizationInHeadings] Use sentence-style capitalization in headings", "location": {"path": "docs/ai/mcp/mcp.md", "range": {"start": {"line": 7, "column": 3}}}, "severity": "INFO"}

MCP servers allow AI interactions with the system.
Learn more about this protocol and [[= product_name_base =]] MCP Servers:

[[= cards([
("ai/mcp/mcp_guide", "MCP Servers guide", "TODO."),
"ai/mcp/mcp_config",
], columns=2) =]]
Loading
Loading