Skip to content

MCP Servers updates#3248

Draft
adriendupuis wants to merge 7 commits into
5.0from
mcp-update
Draft

MCP Servers updates#3248
adriendupuis wants to merge 7 commits into
5.0from
mcp-update

Conversation

@adriendupuis

@adriendupuis adriendupuis commented Jun 17, 2026

Copy link
Copy Markdown
Contributor
Question Answer
JIRA Ticket
Versions
Edition

Checklist

  • Text renders correctly
  • Text has been checked with vale
  • Description metadata is up to date
  • Redirects cover removed/moved pages
  • Code samples are working
  • PHP code samples have been fixed with PHP CS fixer
  • Added link to this PR in relevant JIRA ticket or code PR

@github-actions

Copy link
Copy Markdown

Preview of modified files

Preview of modified Markdown:

@github-actions

Copy link
Copy Markdown

code_samples/ change report

Before (on target branch)After (in current PR)

code_samples/mcp/config/packages/mcp.yaml


code_samples/mcp/config/packages/mcp.yaml

docs/ai/mcp/mcp_usage.md@96:``` yaml
docs/ai/mcp/mcp_usage.md@97:[[= include_code('code_samples/mcp/config/packages/mcp.yaml') =]]
docs/ai/mcp/mcp_usage.md@98:```
docs/ai/mcp/mcp_usage.md@98:``` yaml
docs/ai/mcp/mcp_usage.md@99:[[= include_code('code_samples/mcp/config/packages/mcp.yaml') =]]
docs/ai/mcp/mcp_usage.md@100:```

001⫶ibexa:
002⫶ repositories:
003⫶ default:
004⫶ mcp:
005⫶ example:
006⫶ path: /mcp/example
007⫶ enabled: true
008⫶ description: 'Example MCP Server'
009⫶ instructions: 'Use this server to greet someone.'
010⫶ discovery_cache: cache.tagaware.filesystem
011⫶ session:
012⫶ type: psr16

001⫶ibexa:
002⫶ repositories:
003⫶ default:
004⫶ mcp:
005⫶ example:
006⫶ path: /mcp/example
007⫶ enabled: true
008⫶ description: 'Example MCP Server'
009⫶ instructions: 'Use this server to greet someone.'
010⫶ discovery_cache: cache.tagaware.filesystem
011⫶ session:
012⫶ type: psr16
013⫶                        directory: cache.tagaware.filesystem
014⫶ system:
015⫶ default:
016⫶ mcp:
017⫶ servers:
018⫶ - example
013⫶                        service: cache.tagaware.filesystem
014⫶ allowed_hosts:
015⫶ - '127.0.0.1'
016⫶ system:
017⫶ default:
018⫶ mcp:
019⫶ servers:
020⫶ - example


code_samples/mcp/mcp.matrix.yaml

docs/ai/mcp/mcp_config.md@61:``` yaml
docs/ai/mcp/mcp_config.md@62:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 1, 8) =]]


code_samples/mcp/mcp.matrix.yaml

docs/ai/mcp/mcp_config.md@61:``` yaml
docs/ai/mcp/mcp_config.md@62:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 1, 8) =]]
docs/ai/mcp/mcp_config.md@63:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 12, 15) =]]
docs/ai/mcp/mcp_config.md@64:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 29, 33) =]]
docs/ai/mcp/mcp_config.md@63:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 12, 17) =]]
docs/ai/mcp/mcp_config.md@64:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 31, 35) =]]
docs/ai/mcp/mcp_config.md@65:```

001⫶ibexa:
002⫶ repositories:
003⫶ <repository_identifier>:
004⫶ mcp:
005⫶ <server_identifier>:
006⫶ path: <server_route_path>
007⫶ enabled: true
008⫶ # Server options…
009⫶ discovery_cache: <cache_pool_service>
010⫶ session:
011⫶ type: <psr16|file>
012⫶ # Session options…
docs/ai/mcp/mcp_config.md@65:```

001⫶ibexa:
002⫶ repositories:
003⫶ <repository_identifier>:
004⫶ mcp:
005⫶ <server_identifier>:
006⫶ path: <server_route_path>
007⫶ enabled: true
008⫶ # Server options…
009⫶ discovery_cache: <cache_pool_service>
010⫶ session:
011⫶ type: <psr16|file>
012⫶ # Session options…
013⫶    system:
014⫶ <siteaccess_scope>:
015⫶ mcp:
016⫶ servers:
017⫶ - <server_identifier>

docs/ai/mcp/mcp_config.md@117:``` yaml hl_lines="5-7"
docs/ai/mcp/mcp_config.md@118:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 4, 7) =]]
docs/ai/mcp/mcp_config.md@119:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 9, 11) =]]
docs/ai/mcp/mcp_config.md@120: # …
docs/ai/mcp/mcp_config.md@121:```
013⫶                    allowed_hosts:
014⫶ - '<domain_name>'
015⫶ system:
016⫶ <siteaccess_scope>:
017⫶ mcp:
018⫶ servers:
019⫶ - <server_identifier>

docs/ai/mcp/mcp_config.md@133:``` yaml hl_lines="5-7"
docs/ai/mcp/mcp_config.md@134:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 4, 7) =]]
docs/ai/mcp/mcp_config.md@135:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 9, 11) =]]
docs/ai/mcp/mcp_config.md@136: # …
docs/ai/mcp/mcp_config.md@137:```

001⫶ mcp:
002⫶ <server_identifier>:
003⫶ path: <server_route_path>
004⫶ enabled: true
005❇️ tools:
006❇️ - Ibexa\Mcp\Tool\TranslationTools
007❇️ - Ibexa\Mcp\Tool\SeoTools
008⫶ # …


001⫶ mcp:
002⫶ <server_identifier>:
003⫶ path: <server_route_path>
004⫶ enabled: true
005❇️ tools:
006❇️ - Ibexa\Mcp\Tool\TranslationTools
007❇️ - Ibexa\Mcp\Tool\SeoTools
008⫶ # …

docs/ai/mcp/mcp_config.md@130:``` yaml
docs/ai/mcp/mcp_config.md@131:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 17, 17) =]]
docs/ai/mcp/mcp_config.md@132:```
docs/ai/mcp/mcp_config.md@146:``` yaml
docs/ai/mcp/mcp_config.md@147:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 19, 19) =]]
docs/ai/mcp/mcp_config.md@148:```

001⫶ discovery_cache: cache.redis.mcp


001⫶ discovery_cache: cache.redis.mcp

docs/ai/mcp/mcp_config.md@165:``` yaml
docs/ai/mcp/mcp_config.md@166:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 18, 21) =]]
docs/ai/mcp/mcp_config.md@167:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 34, 43) =]]
docs/ai/mcp/mcp_config.md@168:```
docs/ai/mcp/mcp_config.md@181:``` yaml
docs/ai/mcp/mcp_config.md@182:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 20, 23) =]]
docs/ai/mcp/mcp_config.md@183:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 36, 45) =]]
docs/ai/mcp/mcp_config.md@184:```

001⫶ session:
002⫶ type: psr16
003⫶ service: cache.redis.mcp
004⫶ prefix: 'mcp_<server_identifier>_'
005⫶services:
006⫶ cache.redis.mcp:
007⫶ public: true
008⫶ class: Symfony\Component\Cache\Adapter\RedisTagAwareAdapter
009⫶ parent: cache.adapter.redis
010⫶ tags:
011⫶ - name: cache.pool
012⫶ clearer: cache.app_clearer
013⫶ provider: 'redis://mcp.redis:6379'
014⫶ namespace: 'mcp'


001⫶ session:
002⫶ type: psr16
003⫶ service: cache.redis.mcp
004⫶ prefix: 'mcp_<server_identifier>_'
005⫶services:
006⫶ cache.redis.mcp:
007⫶ public: true
008⫶ class: Symfony\Component\Cache\Adapter\RedisTagAwareAdapter
009⫶ parent: cache.adapter.redis
010⫶ tags:
011⫶ - name: cache.pool
012⫶ clearer: cache.app_clearer
013⫶ provider: 'redis://mcp.redis:6379'
014⫶ namespace: 'mcp'

docs/ai/mcp/mcp_config.md@178:``` yaml
docs/ai/mcp/mcp_config.md@179:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 23, 25) =]]
docs/ai/mcp/mcp_config.md@180:```
docs/ai/mcp/mcp_config.md@194:``` yaml
docs/ai/mcp/mcp_config.md@195:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 25, 27) =]]
docs/ai/mcp/mcp_config.md@196:```

001⫶ session:
002⫶ type: file
003⫶ directory: '%kernel.cache_dir%/mcp/sessions'


001⫶ session:
002⫶ type: file
003⫶ directory: '%kernel.cache_dir%/mcp/sessions'

docs/ai/mcp/mcp_config.md@206:``` yaml
docs/ai/mcp/mcp_config.md@207:[[= include_code('code_samples/mcp/mcp.matrix.yaml', 16, 16) =]]
docs/ai/mcp/mcp_config.md@208: - 'admin.example.com'
docs/ai/mcp/mcp_config.md@209: - '127.0.0.1'
docs/ai/mcp/mcp_config.md@210: - 'my-ddev-project.ddev.site'
docs/ai/mcp/mcp_config.md@211:```

001⫶ allowed_hosts:
002⫶ - 'admin.example.com'
003⫶ - '127.0.0.1'
004⫶ - 'my-ddev-project.ddev.site'


code_samples/mcp/mcp.sh


code_samples/mcp/mcp.sh

docs/ai/mcp/mcp_usage.md@164:``` bash
docs/ai/mcp/mcp_usage.md@165:[[= include_code('code_samples/mcp/mcp.sh', 5, 7) =]]
docs/ai/mcp/mcp_usage.md@166:```
docs/ai/mcp/mcp_usage.md@168:``` bash
docs/ai/mcp/mcp_usage.md@169:[[= include_code('code_samples/mcp/mcp.sh', 5, 7) =]]
docs/ai/mcp/mcp_usage.md@170:```

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


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

docs/ai/mcp/mcp_usage.md@170:``` bash
docs/ai/mcp/mcp_usage.md@171:[[= include_code('code_samples/mcp/mcp.sh', 9, 23) =]]
docs/ai/mcp/mcp_usage.md@172:```
docs/ai/mcp/mcp_usage.md@174:``` bash
docs/ai/mcp/mcp_usage.md@175:[[= include_code('code_samples/mcp/mcp.sh', 9, 23) =]]
docs/ai/mcp/mcp_usage.md@176:```

001⫶curl -s -X 'POST' \
002⫶ "$baseUrl/api/ibexa/v2/user/token/jwt" \
003⫶ -H 'Content-Type: application/vnd.ibexa.api.JWTInput+json' \
004⫶ -H 'Accept: application/vnd.ibexa.api.JWT+json' \
005⫶ -d "{
006⫶ \"JWTInput\": {
007⫶ \"_media-type\": \"application/vnd.ibexa.api.JWTInput+json\",
008⫶ \"username\": \"$username\",
009⫶ \"password\": \"$password\"
010⫶ }
011⫶ }" > response.tmp.txt
012⫶
013⫶cat response.tmp.txt | jq
014⫶jwtToken=$(cat response.tmp.txt | jq -r .JWT.token)
015⫶rm response.tmp.txt


001⫶curl -s -X 'POST' \
002⫶ "$baseUrl/api/ibexa/v2/user/token/jwt" \
003⫶ -H 'Content-Type: application/vnd.ibexa.api.JWTInput+json' \
004⫶ -H 'Accept: application/vnd.ibexa.api.JWT+json' \
005⫶ -d "{
006⫶ \"JWTInput\": {
007⫶ \"_media-type\": \"application/vnd.ibexa.api.JWTInput+json\",
008⫶ \"username\": \"$username\",
009⫶ \"password\": \"$password\"
010⫶ }
011⫶ }" > response.tmp.txt
012⫶
013⫶cat response.tmp.txt | jq
014⫶jwtToken=$(cat response.tmp.txt | jq -r .JWT.token)
015⫶rm response.tmp.txt

docs/ai/mcp/mcp_usage.md@174:``` json
docs/ai/mcp/mcp_usage.md@175:[[= include_code('code_samples/mcp/mcp.sh.output.txt', 1, 7) =]]
docs/ai/mcp/mcp_usage.md@176:```
docs/ai/mcp/mcp_usage.md@178:``` json
docs/ai/mcp/mcp_usage.md@179:[[= include_code('code_samples/mcp/mcp.sh.output.txt', 1, 7) =]]
docs/ai/mcp/mcp_usage.md@180:```

001⫶{
002⫶ "JWT": {
003⫶ "_media-type": "application/vnd.ibexa.api.JWT+json",
004⫶ "_token": "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ.abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz1234567890ABCD.EFGHIJKL-MNOPQRSTUVWXYZ12345678901234567890",
005⫶ "token": "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ.abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz1234567890ABCD.EFGHIJKL-MNOPQRSTUVWXYZ12345678901234567890"
006⫶ }
007⫶}


001⫶{
002⫶ "JWT": {
003⫶ "_media-type": "application/vnd.ibexa.api.JWT+json",
004⫶ "_token": "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ.abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz1234567890ABCD.EFGHIJKL-MNOPQRSTUVWXYZ12345678901234567890",
005⫶ "token": "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ.abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz1234567890ABCD.EFGHIJKL-MNOPQRSTUVWXYZ12345678901234567890"
006⫶ }
007⫶}

docs/ai/mcp/mcp_usage.md@180:``` bash
docs/ai/mcp/mcp_usage.md@181:[[= include_code('code_samples/mcp/mcp.sh', 21, 44) =]]
docs/ai/mcp/mcp_usage.md@182:```
docs/ai/mcp/mcp_usage.md@184:``` bash
docs/ai/mcp/mcp_usage.md@185:[[= include_code('code_samples/mcp/mcp.sh', 21, 44) =]]
docs/ai/mcp/mcp_usage.md@186:```

001⫶cat response.tmp.txt | jq
002⫶jwtToken=$(cat response.tmp.txt | jq -r .JWT.token)
003⫶rm response.tmp.txt
004⫶
005⫶curl -s -i -X 'POST' "$baseUrl/mcp/example" \
006⫶ -H "Authorization: Bearer $jwtToken" \
007⫶ -d '{
008⫶ "jsonrpc": "2.0",
009⫶ "id": 1,
010⫶ "method": "initialize",
011⫶ "params": {
012⫶ "protocolVersion": "2025-03-26",
013⫶ "capabilities": {},
014⫶ "clientInfo": {
015⫶ "name": "test-curl-client",
016⫶ "version": "1.0.0"
017⫶ }
018⫶ }
019⫶ }' > response.tmp.txt
020⫶
021⫶sed '$d' response.tmp.txt
022⫶tail -n 1 response.tmp.txt | jq

001⫶cat response.tmp.txt | jq
002⫶jwtToken=$(cat response.tmp.txt | jq -r .JWT.token)
003⫶rm response.tmp.txt
004⫶
005⫶curl -s -i -X 'POST' "$baseUrl/mcp/example" \
006⫶ -H "Authorization: Bearer $jwtToken" \
007⫶ -d '{
008⫶ "jsonrpc": "2.0",
009⫶ "id": 1,
010⫶ "method": "initialize",
011⫶ "params": {
012⫶ "protocolVersion": "2025-03-26",
013⫶ "capabilities": {},
014⫶ "clientInfo": {
015⫶ "name": "test-curl-client",
016⫶ "version": "1.0.0"
017⫶ }
018⫶ }
019⫶ }' > response.tmp.txt
020⫶
021⫶sed '$d' response.tmp.txt
022⫶tail -n 1 response.tmp.txt | jq
023⫶mcpSessionId=$(cat response.tmp.txt | grep 'Mcp-Session-Id:' | sed 's/Mcp-Session-Id: \([0-9a-f-]*\).*/\1/')
023⫶mcpSessionId=$(cat response.tmp.txt | grep -i 'Mcp-Session-Id:' | sed 's/Mcp-Session-Id: \([0-9a-f-]*\).*/\1/i')
024⫶rm response.tmp.txt

024⫶rm response.tmp.txt

docs/ai/mcp/mcp_usage.md@184:``` http
docs/ai/mcp/mcp_usage.md@185:[[= include_code('code_samples/mcp/mcp.sh.output.txt', 8, 16) =]]
docs/ai/mcp/mcp_usage.md@186:```
docs/ai/mcp/mcp_usage.md@188:``` http
docs/ai/mcp/mcp_usage.md@189:[[= include_code('code_samples/mcp/mcp.sh.output.txt', 8, 16) =]]
docs/ai/mcp/mcp_usage.md@190:```

001⫶HTTP/1.1 200 OK
002⫶Access-Control-Allow-Headers: Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID, Authorization, Accept
003⫶Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS
004⫶Access-Control-Allow-Origin: *
005⫶Access-Control-Expose-Headers: Mcp-Session-Id
006⫶Cache-Control: no-cache, private
007⫶Content-Type: application/json
008⫶Date: Tue, 28 Apr 2026 09:53:27 GMT
009⫶Mcp-Session-Id: 12345678-9abc-def0-1234-56789abcdef0


001⫶HTTP/1.1 200 OK
002⫶Access-Control-Allow-Headers: Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID, Authorization, Accept
003⫶Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS
004⫶Access-Control-Allow-Origin: *
005⫶Access-Control-Expose-Headers: Mcp-Session-Id
006⫶Cache-Control: no-cache, private
007⫶Content-Type: application/json
008⫶Date: Tue, 28 Apr 2026 09:53:27 GMT
009⫶Mcp-Session-Id: 12345678-9abc-def0-1234-56789abcdef0

docs/ai/mcp/mcp_usage.md@188:``` json
docs/ai/mcp/mcp_usage.md@189:[[= include_code('code_samples/mcp/mcp.sh.output.txt', 26, 51) =]]
docs/ai/mcp/mcp_usage.md@190:```
docs/ai/mcp/mcp_usage.md@192:``` json
docs/ai/mcp/mcp_usage.md@193:[[= include_code('code_samples/mcp/mcp.sh.output.txt', 26, 51) =]]
docs/ai/mcp/mcp_usage.md@194:```

001⫶{
002⫶ "jsonrpc": "2.0",
003⫶ "id": 1,
004⫶ "result": {
005⫶ "protocolVersion": "2025-06-18",
006⫶ "capabilities": {
007⫶ "logging": {},
008⫶ "completions": {},
009⫶ "prompts": {
010⫶ "listChanged": true
011⫶ },
012⫶ "resources": {
013⫶ "listChanged": true
014⫶ },
015⫶ "tools": {
016⫶ "listChanged": true
017⫶ }
018⫶ },
019⫶ "serverInfo": {
020⫶ "name": "example",
021⫶ "version": "1.0.0",
022⫶ "description": "Example MCP Server"
023⫶ },
024⫶ "instructions": "Use this server to greet someone."
025⫶ }
026⫶}


001⫶{
002⫶ "jsonrpc": "2.0",
003⫶ "id": 1,
004⫶ "result": {
005⫶ "protocolVersion": "2025-06-18",
006⫶ "capabilities": {
007⫶ "logging": {},
008⫶ "completions": {},
009⫶ "prompts": {
010⫶ "listChanged": true
011⫶ },
012⫶ "resources": {
013⫶ "listChanged": true
014⫶ },
015⫶ "tools": {
016⫶ "listChanged": true
017⫶ }
018⫶ },
019⫶ "serverInfo": {
020⫶ "name": "example",
021⫶ "version": "1.0.0",
022⫶ "description": "Example MCP Server"
023⫶ },
024⫶ "instructions": "Use this server to greet someone."
025⫶ }
026⫶}

docs/ai/mcp/mcp_usage.md@194:``` bash
docs/ai/mcp/mcp_usage.md@195:[[= include_code('code_samples/mcp/mcp.sh', 46, 52) =]]
docs/ai/mcp/mcp_usage.md@196:```
docs/ai/mcp/mcp_usage.md@198:``` bash
docs/ai/mcp/mcp_usage.md@199:[[= include_code('code_samples/mcp/mcp.sh', 46, 52) =]]
docs/ai/mcp/mcp_usage.md@200:```

001⫶curl -s -i -X 'POST' "$baseUrl/mcp/example" \
002⫶ -H "Authorization: Bearer $jwtToken" \
003⫶ -H "Mcp-Session-Id: $mcpSessionId" \
004⫶ -d '{
005⫶ "jsonrpc": "2.0",
006⫶ "method": "notifications/initialized"
007⫶ }'


001⫶curl -s -i -X 'POST' "$baseUrl/mcp/example" \
002⫶ -H "Authorization: Bearer $jwtToken" \
003⫶ -H "Mcp-Session-Id: $mcpSessionId" \
004⫶ -d '{
005⫶ "jsonrpc": "2.0",
006⫶ "method": "notifications/initialized"
007⫶ }'

docs/ai/mcp/mcp_usage.md@198:``` http
docs/ai/mcp/mcp_usage.md@199:[[= include_code('code_samples/mcp/mcp.sh.output.txt', 52, 56) =]]
docs/ai/mcp/mcp_usage.md@200:```
docs/ai/mcp/mcp_usage.md@202:``` http
docs/ai/mcp/mcp_usage.md@203:[[= include_code('code_samples/mcp/mcp.sh.output.txt', 52, 56) =]]
docs/ai/mcp/mcp_usage.md@204:```

001⫶HTTP/1.1 202 Accepted
002⫶Access-Control-Allow-Headers: Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID, Authorization, Accept
003⫶Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS
004⫶Access-Control-Allow-Origin: *
005⫶Access-Control-Expose-Headers: Mcp-Session-Id


001⫶HTTP/1.1 202 Accepted
002⫶Access-Control-Allow-Headers: Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID, Authorization, Accept
003⫶Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS
004⫶Access-Control-Allow-Origin: *
005⫶Access-Control-Expose-Headers: Mcp-Session-Id

docs/ai/mcp/mcp_usage.md@204:``` bash
docs/ai/mcp/mcp_usage.md@205:[[= include_code('code_samples/mcp/mcp.sh', 54, 61) =]]
docs/ai/mcp/mcp_usage.md@206:```
docs/ai/mcp/mcp_usage.md@208:``` bash
docs/ai/mcp/mcp_usage.md@209:[[= include_code('code_samples/mcp/mcp.sh', 54, 61) =]]
docs/ai/mcp/mcp_usage.md@210:```

001⫶curl -s -X 'POST' "$baseUrl/mcp/example" \
002⫶ -H "Authorization: Bearer $jwtToken" \
003⫶ -H "Mcp-Session-Id: $mcpSessionId" \
004⫶ -d '{
005⫶ "jsonrpc": "2.0",
006⫶ "id": 2,
007⫶ "method": "tools/list"
008⫶ }' | jq


001⫶curl -s -X 'POST' "$baseUrl/mcp/example" \
002⫶ -H "Authorization: Bearer $jwtToken" \
003⫶ -H "Mcp-Session-Id: $mcpSessionId" \
004⫶ -d '{
005⫶ "jsonrpc": "2.0",
006⫶ "id": 2,
007⫶ "method": "tools/list"
008⫶ }' | jq

docs/ai/mcp/mcp_usage.md@208:``` json
docs/ai/mcp/mcp_usage.md@209:[[= include_code('code_samples/mcp/mcp.sh.output.txt', 69, 128) =]]
docs/ai/mcp/mcp_usage.md@210:```
docs/ai/mcp/mcp_usage.md@212:``` json
docs/ai/mcp/mcp_usage.md@213:[[= include_code('code_samples/mcp/mcp.sh.output.txt', 69, 128) =]]
docs/ai/mcp/mcp_usage.md@214:```

001⫶{
002⫶ "jsonrpc": "2.0",
003⫶ "id": 2,
004⫶ "result": {
005⫶ "tools": [
006⫶ {
007⫶ "name": "greet",
008⫶ "inputSchema": {
009⫶ "type": "object",
010⫶ "properties": {
011⫶ "name": {
012⫶ "type": "string",
013⫶ "description": "The name of the person to greet"
014⫶ }
015⫶ },
016⫶ "required": [
017⫶ "name"
018⫶ ]
019⫶ },
020⫶ "description": "Greet a user by name",
021⫶ "annotations": {
022⫶ "readOnlyHint": true,
023⫶ "destructiveHint": false,
024⫶ "idempotentHint": true,
025⫶ "openWorldHint": false
026⫶ },
027⫶ "icons": [
028⫶ {
029⫶ "src": "https://openmoji.org/data/color/svg/1F44B.svg"
030⫶ }
031⫶ ],
032⫶ "outputSchema": {
033⫶ "type": "object",
034⫶ "properties": {
035⫶ "general": {
036⫶ "type": "string",
037⫶ "description": "the safe way to greet someone"
038⫶ },
039⫶ "close": {
040⫶ "type": "string",
041⫶ "description": "when you're close to the person, like friends or relatives"
042⫶ },
043⫶ "morning": {
044⫶ "type": "string",
045⫶ "description": "when it's in the morning"
046⫶ },
047⫶ "afternoon": {
048⫶ "type": "string",
049⫶ "description": "when it's the afternoon"
050⫶ },
051⫶ "evening": {
052⫶ "type": "string",
053⫶ "description": "when it's late in the day"
054⫶ }
055⫶ }
056⫶ }
057⫶ }
058⫶ ]
059⫶ }
060⫶}


001⫶{
002⫶ "jsonrpc": "2.0",
003⫶ "id": 2,
004⫶ "result": {
005⫶ "tools": [
006⫶ {
007⫶ "name": "greet",
008⫶ "inputSchema": {
009⫶ "type": "object",
010⫶ "properties": {
011⫶ "name": {
012⫶ "type": "string",
013⫶ "description": "The name of the person to greet"
014⫶ }
015⫶ },
016⫶ "required": [
017⫶ "name"
018⫶ ]
019⫶ },
020⫶ "description": "Greet a user by name",
021⫶ "annotations": {
022⫶ "readOnlyHint": true,
023⫶ "destructiveHint": false,
024⫶ "idempotentHint": true,
025⫶ "openWorldHint": false
026⫶ },
027⫶ "icons": [
028⫶ {
029⫶ "src": "https://openmoji.org/data/color/svg/1F44B.svg"
030⫶ }
031⫶ ],
032⫶ "outputSchema": {
033⫶ "type": "object",
034⫶ "properties": {
035⫶ "general": {
036⫶ "type": "string",
037⫶ "description": "the safe way to greet someone"
038⫶ },
039⫶ "close": {
040⫶ "type": "string",
041⫶ "description": "when you're close to the person, like friends or relatives"
042⫶ },
043⫶ "morning": {
044⫶ "type": "string",
045⫶ "description": "when it's in the morning"
046⫶ },
047⫶ "afternoon": {
048⫶ "type": "string",
049⫶ "description": "when it's the afternoon"
050⫶ },
051⫶ "evening": {
052⫶ "type": "string",
053⫶ "description": "when it's late in the day"
054⫶ }
055⫶ }
056⫶ }
057⫶ }
058⫶ ]
059⫶ }
060⫶}

docs/ai/mcp/mcp_usage.md@214:``` bash
docs/ai/mcp/mcp_usage.md@215:[[= include_code('code_samples/mcp/mcp.sh', 63, 76) =]]
docs/ai/mcp/mcp_usage.md@216:```
docs/ai/mcp/mcp_usage.md@218:``` bash
docs/ai/mcp/mcp_usage.md@219:[[= include_code('code_samples/mcp/mcp.sh', 63, 76) =]]
docs/ai/mcp/mcp_usage.md@220:```

001⫶curl -s -X 'POST' "$baseUrl/mcp/example" \
002⫶ -H "Authorization: Bearer $jwtToken" \
003⫶ -H "Mcp-Session-Id: $mcpSessionId" \
004⫶ -d '{
005⫶ "jsonrpc": "2.0",
006⫶ "id": 3,
007⫶ "method": "tools/call",
008⫶ "params": {
009⫶ "name": "greet",
010⫶ "arguments": {
011⫶ "name": "World"
012⫶ }
013⫶ }
014⫶ }' | jq


001⫶curl -s -X 'POST' "$baseUrl/mcp/example" \
002⫶ -H "Authorization: Bearer $jwtToken" \
003⫶ -H "Mcp-Session-Id: $mcpSessionId" \
004⫶ -d '{
005⫶ "jsonrpc": "2.0",
006⫶ "id": 3,
007⫶ "method": "tools/call",
008⫶ "params": {
009⫶ "name": "greet",
010⫶ "arguments": {
011⫶ "name": "World"
012⫶ }
013⫶ }
014⫶ }' | jq

docs/ai/mcp/mcp_usage.md@218:``` json
docs/ai/mcp/mcp_usage.md@219:[[= include_code('code_samples/mcp/mcp.sh.output.txt', 129, 148) =]]
docs/ai/mcp/mcp_usage.md@220:```
docs/ai/mcp/mcp_usage.md@222:``` json
docs/ai/mcp/mcp_usage.md@223:[[= include_code('code_samples/mcp/mcp.sh.output.txt', 129, 148) =]]
docs/ai/mcp/mcp_usage.md@224:```

001⫶{
002⫶ "jsonrpc": "2.0",
003⫶ "id": 3,
004⫶ "result": {
005⫶ "content": [
006⫶ {
007⫶ "type": "text",
008⫶ "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}"
009⫶ }
010⫶ ],
011⫶ "isError": false,
012⫶ "structuredContent": {
013⫶ "general": "Hello, World!",
014⫶ "close": "Hey, World!",
015⫶ "morning": "Good morning, World!",
016⫶ "afternoon": "Good afternoon, World!",
017⫶ "evening": "Good evening, World!"
018⫶ }
019⫶ }
020⫶}


001⫶{
002⫶ "jsonrpc": "2.0",
003⫶ "id": 3,
004⫶ "result": {
005⫶ "content": [
006⫶ {
007⫶ "type": "text",
008⫶ "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}"
009⫶ }
010⫶ ],
011⫶ "isError": false,
012⫶ "structuredContent": {
013⫶ "general": "Hello, World!",
014⫶ "close": "Hey, World!",
015⫶ "morning": "Good morning, World!",
016⫶ "afternoon": "Good afternoon, World!",
017⫶ "evening": "Good evening, World!"
018⫶ }
019⫶ }
020⫶}

docs/ai/mcp/mcp_usage.md@224:``` bash
docs/ai/mcp/mcp_usage.md@225:[[= include_code('code_samples/mcp/mcp.sh', 78, 85) =]]
docs/ai/mcp/mcp_usage.md@226:```
docs/ai/mcp/mcp_usage.md@228:``` bash
docs/ai/mcp/mcp_usage.md@229:[[= include_code('code_samples/mcp/mcp.sh', 78, 85) =]]
docs/ai/mcp/mcp_usage.md@230:```

001⫶curl -s -X 'POST' "$baseUrl/mcp/example" \
002⫶ -H "Authorization: Bearer $jwtToken" \
003⫶ -H "Mcp-Session-Id: $mcpSessionId" \
004⫶ -d '{
005⫶ "jsonrpc": "2.0",
006⫶ "id": 4,
007⫶ "method": "prompts/list"
008⫶ }' | jq


001⫶curl -s -X 'POST' "$baseUrl/mcp/example" \
002⫶ -H "Authorization: Bearer $jwtToken" \
003⫶ -H "Mcp-Session-Id: $mcpSessionId" \
004⫶ -d '{
005⫶ "jsonrpc": "2.0",
006⫶ "id": 4,
007⫶ "method": "prompts/list"
008⫶ }' | jq

docs/ai/mcp/mcp_usage.md@228:``` json
docs/ai/mcp/mcp_usage.md@229:[[= include_code('code_samples/mcp/mcp.sh.output.txt', 149, 172) =]]
docs/ai/mcp/mcp_usage.md@230:```
docs/ai/mcp/mcp_usage.md@232:``` json
docs/ai/mcp/mcp_usage.md@233:[[= include_code('code_samples/mcp/mcp.sh.output.txt', 149, 172) =]]
docs/ai/mcp/mcp_usage.md@234:```

001⫶{
002⫶ "jsonrpc": "2.0",
003⫶ "id": 4,
004⫶ "result": {
005⫶ "prompts": [
006⫶ {
007⫶ "name": "greet",
008⫶ "description": "Prompt to be greeted by the `greet` tool",
009⫶ "arguments": [
010⫶ {
011⫶ "name": "name",
012⫶ "description": "The name you want to be greeted by",
013⫶ "required": true
014⫶ }
015⫶ ],
016⫶ "icons": [
017⫶ {
018⫶ "src": "https://openmoji.org/data/color/svg/1F91D.svg"
019⫶ }
020⫶ ]
021⫶ }
022⫶ ]
023⫶ }
024⫶}


001⫶{
002⫶ "jsonrpc": "2.0",
003⫶ "id": 4,
004⫶ "result": {
005⫶ "prompts": [
006⫶ {
007⫶ "name": "greet",
008⫶ "description": "Prompt to be greeted by the `greet` tool",
009⫶ "arguments": [
010⫶ {
011⫶ "name": "name",
012⫶ "description": "The name you want to be greeted by",
013⫶ "required": true
014⫶ }
015⫶ ],
016⫶ "icons": [
017⫶ {
018⫶ "src": "https://openmoji.org/data/color/svg/1F91D.svg"
019⫶ }
020⫶ ]
021⫶ }
022⫶ ]
023⫶ }
024⫶}

docs/ai/mcp/mcp_usage.md@234:``` bash
docs/ai/mcp/mcp_usage.md@235:[[= include_code('code_samples/mcp/mcp.sh', 87, 100) =]]
docs/ai/mcp/mcp_usage.md@236:```
docs/ai/mcp/mcp_usage.md@238:``` bash
docs/ai/mcp/mcp_usage.md@239:[[= include_code('code_samples/mcp/mcp.sh', 87, 100) =]]
docs/ai/mcp/mcp_usage.md@240:```

001⫶curl -s -X 'POST' "$baseUrl/mcp/example" \
002⫶ -H "Authorization: Bearer $jwtToken" \
003⫶ -H "Mcp-Session-Id: $mcpSessionId" \
004⫶ -d '{
005⫶ "jsonrpc": "2.0",
006⫶ "id": 5,
007⫶ "method": "prompts/get",
008⫶ "params": {
009⫶ "name": "greet",
010⫶ "arguments": {
011⫶ "name": "Firstname Lastname"
012⫶ }
013⫶ }
014⫶ }' | jq


001⫶curl -s -X 'POST' "$baseUrl/mcp/example" \
002⫶ -H "Authorization: Bearer $jwtToken" \
003⫶ -H "Mcp-Session-Id: $mcpSessionId" \
004⫶ -d '{
005⫶ "jsonrpc": "2.0",
006⫶ "id": 5,
007⫶ "method": "prompts/get",
008⫶ "params": {
009⫶ "name": "greet",
010⫶ "arguments": {
011⫶ "name": "Firstname Lastname"
012⫶ }
013⫶ }
014⫶ }' | jq

docs/ai/mcp/mcp_usage.md@238:``` json
docs/ai/mcp/mcp_usage.md@239:[[= include_code('code_samples/mcp/mcp.sh.output.txt', 173, 187) =]]
docs/ai/mcp/mcp_usage.md@240:```
docs/ai/mcp/mcp_usage.md@242:``` json
docs/ai/mcp/mcp_usage.md@243:[[= include_code('code_samples/mcp/mcp.sh.output.txt', 173, 187) =]]
docs/ai/mcp/mcp_usage.md@244:```

001⫶{
002⫶ "jsonrpc": "2.0",
003⫶ "id": 5,
004⫶ "result": {
005⫶ "messages": [
006⫶ {
007⫶ "role": "user",
008⫶ "content": {
009⫶ "type": "text",
010⫶ "text": "Hi. My name is Firstname Lastname. Please, greet me."
011⫶ }
012⫶ }
013⫶ ]
014⫶ }
015⫶}


code_samples/mcp/src/Mcp/ExampleCapabilities.php


001⫶{
002⫶ "jsonrpc": "2.0",
003⫶ "id": 5,
004⫶ "result": {
005⫶ "messages": [
006⫶ {
007⫶ "role": "user",
008⫶ "content": {
009⫶ "type": "text",
010⫶ "text": "Hi. My name is Firstname Lastname. Please, greet me."
011⫶ }
012⫶ }
013⫶ ]
014⫶ }
015⫶}


code_samples/mcp/src/Mcp/ExampleCapabilities.php

docs/ai/mcp/mcp_usage.md@115:``` php
docs/ai/mcp/mcp_usage.md@116:[[= include_code('code_samples/mcp/src/Mcp/ExampleCapabilities.php') =]]
docs/ai/mcp/mcp_usage.md@117:```
docs/ai/mcp/mcp_usage.md@119:``` php
docs/ai/mcp/mcp_usage.md@120:[[= include_code('code_samples/mcp/src/Mcp/ExampleCapabilities.php') =]]
docs/ai/mcp/mcp_usage.md@121:```

001⫶<?php declare(strict_types=1);
002⫶
003⫶namespace App\Mcp;
004⫶
005⫶use Ibexa\Contracts\Mcp\Attribute\McpPrompt;
006⫶use Ibexa\Contracts\Mcp\Attribute\McpTool;
007⫶use Ibexa\Contracts\Mcp\McpCapabilityInterface;
008⫶use Mcp\Schema\Icon;
009⫶use Mcp\Schema\ToolAnnotations;
010⫶
011⫶final readonly class ExampleCapabilities implements McpCapabilityInterface
012⫶{
013⫶ /**
014⫶ * @param string $name The name of the person to greet
015⫶ *
016⫶ * @return array<string, string>
017⫶ */
018⫶ #[McpTool(
019⫶ servers: ['example'],
020⫶ name: 'greet',

001⫶<?php declare(strict_types=1);
002⫶
003⫶namespace App\Mcp;
004⫶
005⫶use Ibexa\Contracts\Mcp\Attribute\McpPrompt;
006⫶use Ibexa\Contracts\Mcp\Attribute\McpTool;
007⫶use Ibexa\Contracts\Mcp\McpCapabilityInterface;
008⫶use Mcp\Schema\Icon;
009⫶use Mcp\Schema\ToolAnnotations;
010⫶
011⫶final readonly class ExampleCapabilities implements McpCapabilityInterface
012⫶{
013⫶ /**
014⫶ * @param string $name The name of the person to greet
015⫶ *
016⫶ * @return array<string, string>
017⫶ */
018⫶ #[McpTool(
019⫶ servers: ['example'],
020⫶ name: 'greet',
021⫶        description: 'Greet a user by name',
022⫶ annotations: new ToolAnnotations(
023⫶ readOnlyHint: true,
024⫶ destructiveHint: false,
025⫶ idempotentHint: true,
026⫶ openWorldHint: false,
027⫶ ),
028⫶ icons: [new Icon(
029⫶ src: 'https://openmoji.org/data/color/svg/1F44B.svg',
030⫶ )],
031⫶ outputSchema: [
032⫶ 'type' => 'object',
033⫶ 'properties' => [
034⫶ 'general' => [
035⫶ 'type' => 'string',
036⫶ 'description' => 'the safe way to greet someone',
037⫶ ],
038⫶ 'close' => [
039⫶ 'type' => 'string',
040⫶ 'description' => 'when you\'re close to the person, like friends or relatives',
041⫶ ],
042⫶ 'morning' => [
043⫶ 'type' => 'string',
044⫶ 'description' => 'when it\'s in the morning',
045⫶ ],
046⫶ 'afternoon' => [
047⫶ 'type' => 'string',
048⫶ 'description' => 'when it\'s the afternoon',
049⫶ ],
050⫶ 'evening' => [
051⫶ 'type' => 'string',
052⫶ 'description' => 'when it\'s late in the day',
053⫶ ],
054⫶ ],
055⫶ ],
056⫶ )]
057⫶ public function greetByName(string $name): array
058⫶ {
059⫶ return [
060⫶ 'general' => sprintf('Hello, %s!', $name),
061⫶ 'close' => sprintf('Hey, %s!', $name),
062⫶ 'morning' => sprintf('Good morning, %s!', $name),
063⫶ 'afternoon' => sprintf('Good afternoon, %s!', $name),
064⫶ 'evening' => sprintf('Good evening, %s!', $name),
065⫶ ];
066⫶ }
067⫶
068⫶ /**
069⫶ * @param string $name The name you want to be greeted by
070⫶ *
071⫶ * @return array<string, mixed>
072⫶ */
073⫶ #[McpPrompt(
074⫶ servers: ['example'],
075⫶ name: 'greet',
076⫶ description: 'Prompt to invoke the `greet` tool',
077⫶ icons: [new Icon(
078⫶ src: 'https://openmoji.org/data/color/svg/1F91D.svg',
079⫶ )],
080⫶ )]
081⫶ public function getGreetPrompt(string $name): array
082⫶ {
083⫶ return [
084⫶ 'role' => 'user',
085⫶ 'content' => [
086⫶ 'type' => 'text',
087⫶ 'text' => "Hi. My name is $name. Please, greet me.",
088⫶ ],
089⫶ ];
090⫶ }
091⫶}
021⫶        title: 'User greeting',
022⫶ description: 'Greet a user by name',
023⫶ annotations: new ToolAnnotations(
024⫶ readOnlyHint: true,
025⫶ destructiveHint: false,
026⫶ idempotentHint: true,
027⫶ openWorldHint: false,
028⫶ ),
029⫶ icons: [new Icon(
030⫶ src: 'https://openmoji.org/data/color/svg/1F44B.svg',
031⫶ )],
032⫶ outputSchema: [
033⫶ 'type' => 'object',
034⫶ 'properties' => [
035⫶ 'general' => [
036⫶ 'type' => 'string',
037⫶ 'description' => 'the safe way to greet someone',
038⫶ ],
039⫶ 'close' => [
040⫶ 'type' => 'string',
041⫶ 'description' => 'when you\'re close to the person, like friends or relatives',
042⫶ ],
043⫶ 'morning' => [
044⫶ 'type' => 'string',
045⫶ 'description' => 'when it\'s in the morning',
046⫶ ],
047⫶ 'afternoon' => [
048⫶ 'type' => 'string',
049⫶ 'description' => 'when it\'s the afternoon',
050⫶ ],
051⫶ 'evening' => [
052⫶ 'type' => 'string',
053⫶ 'description' => 'when it\'s late in the day',
054⫶ ],
055⫶ ],
056⫶ ],
057⫶ )]
058⫶ public function greetByName(string $name): array
059⫶ {
060⫶ return [
061⫶ 'general' => sprintf('Hello, %s!', $name),
062⫶ 'close' => sprintf('Hey, %s!', $name),
063⫶ 'morning' => sprintf('Good morning, %s!', $name),
064⫶ 'afternoon' => sprintf('Good afternoon, %s!', $name),
065⫶ 'evening' => sprintf('Good evening, %s!', $name),
066⫶ ];
067⫶ }
068⫶
069⫶ /**
070⫶ * @param string $name The name you want to be greeted by
071⫶ *
072⫶ * @return array<string, mixed>
073⫶ */
074⫶ #[McpPrompt(
075⫶ servers: ['example'],
076⫶ name: 'greet',
077⫶ title: 'Be greeted',
078⫶ description: 'Prompt to invoke the `greet` tool',
079⫶ icons: [new Icon(
080⫶ src: 'https://openmoji.org/data/color/svg/1F91D.svg',
081⫶ )],
082⫶ )]
083⫶ public function getGreetPrompt(string $name): array
084⫶ {
085⫶ return [
086⫶ 'role' => 'user',
087⫶ 'content' => [
088⫶ 'type' => 'text',
089⫶ 'text' => "Hi. My name is $name. Please, greet me.",
090⫶ ],
091⫶ ];
092⫶ }
093⫶}


Download colorized diff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant