Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 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
5f6b1e9
Merge branch '5.0' into mcp
adriendupuis May 4, 2026
df84f07
mcp_config: split MCP Inspector test into sub-sections
adriendupuis May 4, 2026
83abc90
mcp_config: Emphasis on cache clearing
adriendupuis May 5, 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
18 changes: 18 additions & 0 deletions code_samples/mcp/config/packages/mcp.yaml
Original file line number Diff line number Diff line change
@@ -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: psr16
directory: cache.tagaware.filesystem
system:
default:
mcp:
servers:
- example
12 changes: 12 additions & 0 deletions code_samples/mcp/http.mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"mcpServers": {
"ibexa-example": {
"type": "http",
"url": "http://localhost/mcp/example",
"headers": {
"Authorization": "Bearer <JWT token>"
},
"tools": ["*"]
}
}
}
21 changes: 21 additions & 0 deletions code_samples/mcp/mcp-ibexa-example-wrapper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash
set -e

baseUrl='http://localhost' # Adapt to your test case

jwtToken=$(curl -s -X 'POST' \
"$baseUrl/api/ibexa/v2/user/token/jwt" \
-H 'Content-Type: application/vnd.ibexa.api.JWTInput+json' \
-H 'Accept: application/vnd.ibexa.api.JWT+json' \
-d '{
"JWTInput": {
"_media-type": "application/vnd.ibexa.api.JWTInput+json",
"username": "ibexa-example",
"password": "Ibexa-3xample"
}
}' | jq -r .JWT.token)

exec npx -y supergateway \
--streamableHttp "$baseUrl/mcp/example" \
--oauth2Bearer "$jwtToken" \
--logLevel none
43 changes: 43 additions & 0 deletions code_samples/mcp/mcp.matrix.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
ibexa:
repositories:
<repository_identifier>:
mcp:
<server_identifier>:
path: <server_route_path>
enabled: true
# Server options…
tools:
- Ibexa\Mcp\Tool\TranslationTools
- Ibexa\Mcp\Tool\SeoTools
discovery_cache: <cache_pool_service>
session:
type: <psr16|file|memory>
# Session options…
mcp_psr16:
discovery_cache: cache.redis.mcp
session:
type: psr16
service: cache.redis.mcp
prefix: 'mcp_<server_identifier>_'
mcp_file:
session:
type: file
directory: '%kernel.cache_dir%/mcp/sessions'
mcp_memory:
session:
type: memory
system:
<siteaccess_scope>:
mcp:
servers:
- <server_identifier>
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'
100 changes: 100 additions & 0 deletions code_samples/mcp/mcp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/bin/bash
set -e
set +x

baseUrl='http://localhost' # Adapt to your test case
username='ibexa-example'
password='Ibexa-3xample'

curl -s -X 'POST' \
"$baseUrl/api/ibexa/v2/user/token/jwt" \
-H 'Content-Type: application/vnd.ibexa.api.JWTInput+json' \
-H 'Accept: application/vnd.ibexa.api.JWT+json' \
-d "{
\"JWTInput\": {
\"_media-type\": \"application/vnd.ibexa.api.JWTInput+json\",
\"username\": \"$username\",
\"password\": \"$password\"
}
}" > response.tmp.txt

cat response.tmp.txt | jq
jwtToken=$(cat response.tmp.txt | jq -r .JWT.token)
rm response.tmp.txt

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"
}
}
}' > response.tmp.txt

sed '$d' response.tmp.txt
tail -n 1 response.tmp.txt | jq
mcpSessionId=$(cat response.tmp.txt | grep 'Mcp-Session-Id:' | sed 's/Mcp-Session-Id: \([0-9a-f-]*\).*/\1/')
rm response.tmp.txt

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

curl -s -X 'POST' "$baseUrl/mcp/example" \
-H "Authorization: Bearer $jwtToken" \
-H "Mcp-Session-Id: $mcpSessionId" \
-d '{
"jsonrpc": "2.0",
"id": 4,
"method": "prompts/list"
}' | jq

curl -s -X 'POST' "$baseUrl/mcp/example" \
-H "Authorization: Bearer $jwtToken" \
-H "Mcp-Session-Id: $mcpSessionId" \
-d '{
"jsonrpc": "2.0",
"id": 5,
"method": "prompts/get",
"params": {
"name": "greet",
"arguments": {
"name": "Firstname Lastname"
}
}
}' | jq
187 changes: 187 additions & 0 deletions code_samples/mcp/mcp.sh.output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
{
"JWT": {
"_media-type": "application/vnd.ibexa.api.JWT+json",
"_token": "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ.abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz1234567890ABCD.EFGHIJKL-MNOPQRSTUVWXYZ12345678901234567890",
"token": "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ.abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz1234567890ABCD.EFGHIJKL-MNOPQRSTUVWXYZ12345678901234567890"
}
}
HTTP/1.1 200 OK
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-Allow-Origin: *
Access-Control-Expose-Headers: Mcp-Session-Id
Cache-Control: no-cache, private
Content-Type: application/json
Date: Tue, 28 Apr 2026 09:53:27 GMT
Mcp-Session-Id: 12345678-9abc-def0-1234-56789abcdef0
Server: Apache/2.4.66 (Debian)
Vary: cookie,authorization
X-Cache-Debug: 1
X-Debug-Token: 123456
X-Debug-Token-Link: http://localhost/_profiler/123456
X-Powered-By: Ibexa Commerce v5
X-Robots-Tag: noindex
Transfer-Encoding: chunked

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-06-18",
"capabilities": {
"logging": {},
"completions": {},
"prompts": {
"listChanged": true
},
"resources": {
"listChanged": true
},
"tools": {
"listChanged": true
}
},
"serverInfo": {
"name": "example",
"version": "1.0.0",
"description": "Example MCP Server"
},
"instructions": "Use this server to greet someone."
}
}
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-Allow-Origin: *
Access-Control-Expose-Headers: Mcp-Session-Id
Cache-Control: no-cache, private
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Date: Fri, 24 Apr 2026 11:16:27 GMT
Server: Apache/2.4.66 (Debian)
Vary: cookie,authorization
X-Cache-Debug: 1
X-Debug-Token: 7890ab
X-Debug-Token-Link: http://localhost/_profiler/7890ab
X-Powered-By: Ibexa Commerce v5
X-Robots-Tag: noindex

{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "greet",
"inputSchema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The name of the person to greet"
}
},
"required": [
"name"
]
},
"description": "Greet a user by name",
"annotations": {
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": false
},
"icons": [
{
"src": "https://openmoji.org/data/color/svg/1F44B.svg"
}
],
"outputSchema": {
"type": "object",
"properties": {
"general": {
"type": "string",
"description": "the safe way to greet someone"
},
"close": {
"type": "string",
"description": "when you're close to the person, like friends or relatives"
},
"morning": {
"type": "string",
"description": "when it's in the morning"
},
"afternoon": {
"type": "string",
"description": "when it's the afternoon"
},
"evening": {
"type": "string",
"description": "when it's late in the day"
}
}
}
}
]
}
}
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "{\n \"general\": \"Hello, World!\",\n \"close\": \"Hey, World!\",\n \"morning\": \"Good morning, World!\",\n \"afternoon\": \"Good afternoon, World!\",\n \"evening\": \"Good evening, World!\"\n}"
}
],
"isError": false,
"structuredContent": {
"general": "Hello, World!",
"close": "Hey, World!",
"morning": "Good morning, World!",
"afternoon": "Good afternoon, World!",
"evening": "Good evening, World!"
}
}
}
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"prompts": [
{
"name": "greet",
"description": "Prompt to be greeted by the `greet` tool",
"arguments": [
{
"name": "name",
"description": "The name you want to be greeted by",
"required": true
}
],
"icons": [
{
"src": "https://openmoji.org/data/color/svg/1F91D.svg"
}
]
}
]
}
}
{
"jsonrpc": "2.0",
"id": 5,
"result": {
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": "Hi. My name is Firstname Lastname. Please, greet me."
}
}
]
}
}
Loading
Loading