Skip to content

IBX-11536: MCP Servers#3106

Draft
adriendupuis wants to merge 13 commits into5.0from
mcp
Draft

IBX-11536: MCP Servers#3106
adriendupuis wants to merge 13 commits into5.0from
mcp

Conversation

@adriendupuis
Copy link
Copy Markdown
Contributor

@adriendupuis adriendupuis commented Mar 26, 2026

Question Answer
JIRA Ticket IBX-11068 > IBX-11536
Versions (TBC)
Edition All? (TBC)

Document built-in MCP Servers and how to create custom ones.

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

github-actions bot commented Mar 26, 2026

"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",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't test if the alias exist yet but at some point this constraint will have to use it.

Suggested change
"ibexa/mcp": "dev-main",
"ibexa/mcp": "5.0.x-dev",

Apply SonarCloud Code Analysis warning's suggestion
@adriendupuis adriendupuis changed the title IBX-11068: MCP Servers IBX-11536: MCP Servers Mar 27, 2026
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 8, 2026

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 8, 2026

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_config.md@135:``` yaml
docs/ai/mcp/mcp_config.md@136:[[= include_file('code_samples/mcp/config/packages/mcp.yaml') =]]
docs/ai/mcp/mcp_config.md@137:```

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: file
013⫶ directory: '%kernel.cache_dir%/mcp/sessions'
014⫶ system:
015⫶ default:
016⫶ mcp:
017⫶ servers:
018⫶ - example


code_samples/mcp/mcp.sh


code_samples/mcp/mcp.sh

docs/ai/mcp/mcp_config.md@163:``` bash
docs/ai/mcp/mcp_config.md@164:[[= include_file('code_samples/mcp/mcp.sh', 0, 36) =]]
docs/ai/mcp/mcp_config.md@165:```

001⫶baseUrl='http://localhost' # Adapt to your test case
002⫶
003⫶jwtToken=$(curl -s -X 'POST' \
004⫶ "$baseUrl/api/ibexa/v2/user/token/jwt" \
005⫶ -H 'Content-Type: application/json' \
006⫶ -d '{
007⫶ "JWTInput": {
008⫶ "_media-type": "application/vnd.ibexa.api.JWTInput",
009⫶ "username": "admin",
010⫶ "password": "publish"
011⫶ }
012⫶ }' | jq -r .JWT.token)
013⫶
014⫶mcpSessionId=$(curl -s -i -X 'POST' "$baseUrl/mcp/example" \
015⫶ -H "Authorization: Bearer $jwtToken" \
016⫶ -d '{
017⫶ "jsonrpc": "2.0",
018⫶ "id": 1,
019⫶ "method": "initialize",
020⫶ "params": {
021⫶ "protocolVersion": "2025-03-26",
022⫶ "capabilities": {},
023⫶ "clientInfo": {
024⫶ "name": "test-curl-client",
025⫶ "version": "1.0.0"
026⫶ }
027⫶ }
028⫶ }' | grep 'Mcp-Session-Id:' | sed 's/Mcp-Session-Id: \([0-9a-f-]*\).*/\1/')
029⫶
030⫶curl -s -i -X 'POST' "$baseUrl/mcp/example" \
031⫶ -H "Authorization: Bearer $jwtToken" \
032⫶ -H "Mcp-Session-Id: $mcpSessionId" \
033⫶ -d '{
034⫶ "jsonrpc": "2.0",
035⫶ "method": "notifications/initialized"
036⫶ }'

docs/ai/mcp/mcp_config.md@176:``` bash
docs/ai/mcp/mcp_config.md@177:[[= include_file('code_samples/mcp/mcp.sh', 37, 45) =]]
docs/ai/mcp/mcp_config.md@178:```

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_config.md@208:``` bash
docs/ai/mcp/mcp_config.md@209:[[= include_file('code_samples/mcp/mcp.sh', 46) =]]
docs/ai/mcp/mcp_config.md@210:```




code_samples/mcp/src/Command/McpServerListCommand.php


code_samples/mcp/src/Command/McpServerListCommand.php

docs/ai/mcp/mcp_config.md@147:``` php
docs/ai/mcp/mcp_config.md@148:[[= include_file('code_samples/mcp/src/Command/McpServerListCommand.php') =]]
docs/ai/mcp/mcp_config.md@149:```

001⫶<?php declare(strict_types=1);
002⫶
003⫶namespace App\mcp\src\Command;
004⫶
005⫶use Ibexa\Contracts\Mcp\McpServerConfigurationRegistryInterface;
006⫶use Symfony\Component\Console\Attribute\AsCommand;
007⫶use Symfony\Component\Console\Command\Command;
008⫶use Symfony\Component\Console\Style\SymfonyStyle;
009⫶
010⫶#[AsCommand(name: 'app:mcp:server_list', description: 'List MCP servers')]
011⫶class McpServerListCommand
012⫶{
013⫶ public function __construct(private readonly McpServerConfigurationRegistryInterface $configRegistry)
014⫶ {
015⫶ }
016⫶
017⫶ public function __invoke(SymfonyStyle $io): int
018⫶ {
019⫶ foreach($this->configRegistry->getServerConfigurations() as $serverConfiguration) {
020⫶ $io->title($serverConfiguration->identifier);
021⫶ dump($serverConfiguration);
022⫶ }
023⫶
024⫶ return Command::SUCCESS;
025⫶ }
026⫶}


code_samples/mcp/src/Mcp/ExampleTools.php


code_samples/mcp/src/Mcp/ExampleTools.php

docs/ai/mcp/mcp_config.md@141:``` php
docs/ai/mcp/mcp_config.md@142:[[= include_file('code_samples/mcp/src/Mcp/ExampleTools.php') =]]
docs/ai/mcp/mcp_config.md@143:```

001⫶<?php declare(strict_types=1);
002⫶
003⫶namespace App\mcp\src\Mcp;
004⫶
005⫶use Ibexa\Contracts\Mcp\Attribute\McpTool;
006⫶use Ibexa\Contracts\Mcp\McpCapabilityInterface;
007⫶
008⫶final readonly class ExampleTools implements McpCapabilityInterface
009⫶{
010⫶ #[McpTool(servers: ['example'], description: 'Greet a user by name')]
011⫶ public function greet(string $name): string
012⫶ {
013⫶ return sprintf('Hello, %s!', $name);
014⫶ }
015⫶}

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