Skip to content
Draft
Show file tree
Hide file tree
Changes from 7 commits
Commits
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: 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;
}
}
15 changes: 15 additions & 0 deletions code_samples/mcp/src/Mcp/ExampleTools.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php declare(strict_types=1);

namespace App\mcp\src\Mcp;

use Ibexa\Contracts\Mcp\Attribute\McpTool;
use Ibexa\Contracts\Mcp\McpCapabilityInterface;

final readonly class ExampleTools implements McpCapabilityInterface
{
#[McpTool(servers: ['example'], description: 'Greet a user by name')]
public function greet(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": "dev-main",
Comment thread
adriendupuis marked this conversation as resolved.
Outdated
"ibexa/migrations": "5.0.x-dev",
"ibexa/cart": "5.0.x-dev",
"ibexa/installer": "5.0.x-dev",
Expand Down
15 changes: 15 additions & 0 deletions docs/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/mcp/mcp.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/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/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([
("mcp/mcp_guide", "MCP Servers guide", "TODO."),
"mcp/mcp_config",
], columns=2) =]]
228 changes: 228 additions & 0 deletions docs/mcp/mcp_config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
---
description: TODO.
month_change: true
---

TODO: built-in MCP servers VS custom MCP servers

# Set up an MCP server

Check notice on line 8 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L8

[Ibexa.ArticlesInHeadings] Avoid articles in headings.
Raw output
{"message": "[Ibexa.ArticlesInHeadings] Avoid articles in headings.", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 8, "column": 10}}}, "severity": "INFO"}

## JWT

Check notice on line 10 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L10

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

MCP servers use JWT for authentication.

TODO: [Enable authorization header in `config/packages/lexik_jwt_authentication.yaml`](development_security.md#jwt-authentication).

In `config/packages/security.yaml`, uncomment the `ibexa_jwt_mcp` firewall.

TODO: Config to get a JWT token in the first place. Through [REST](rest_api_authentication.md#jwt-authentication), GraphQL or something else?

## MCP Server configuration

Check notice on line 20 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L20

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

MCP servers are configured per repository then enabled per SiteAccess scope.

Check notice on line 22 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L22

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 22, "column": 13}}}, "severity": "INFO"}

```yaml
ibexa:
repositories:
<repository_identifier>:
mcp:
<server_identifier>:
path: <server_route_path>
enabled: true
# Server options…
discovery_cache: <cache_pool_service>
session:
type: <psr16|file|memory>
# Session options…
system:
<siteaccess_scope>:
mcp:
servers:
- <server_identifier>
```

TODO: `ddev php bin/console debug:router --siteaccess=<within_scope_siteaccess>` should list some `ibexa.mcp.<server_identifier> GET|POST|DELETE|OPTIONS <server_route_path>`

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`

Check notice on line 46 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L46

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 46, "column": 33}}}, "severity": "INFO"}

### MCP server options

Check notice on line 48 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L48

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

| Option | Type | Required | Default | Description |
|-------------------|---------|----------|---------|-----------------------------------------------|
| `path` | string | Yes | | MCP server endpoint path |
| `enabled` | boolean | No | `false` | Whether the server is enabled |

Check notice on line 53 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L53

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 53, "column": 73}}}, "severity": "INFO"}
| `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 |

Check failure on line 57 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L57

[Ibexa.Spellcheck] Did you really mean 'ou'?
Raw output
{"message": "[Ibexa.Spellcheck] Did you really mean 'ou'?", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 57, "column": 60}}}, "severity": "ERROR"}
| `session` | object | Yes | | Session storage configuration |

Notice that a server is disabled by default, it needs to be explicitly enabled.

Check notice on line 60 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L60

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 60, "column": 22}}}, "severity": "INFO"}

### MCP server discovery cache

Check notice on line 62 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L62

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

TODO

### MCP server session storage

Check notice on line 66 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L66

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

#### 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

Check notice on line 78 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L78

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

Sessions are stored using a PSR-16 compatible cache implementation. Requires service option pointing to a valid cache service ID.

Check notice on line 80 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L80

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 80, "column": 10}}}, "severity": "INFO"}

Check notice on line 80 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L80

[Ibexa.ByUsing] Prefer 'by using' or 'with' to plain 'using'.
Raw output
{"message": "[Ibexa.ByUsing] Prefer 'by using' or 'with' to plain 'using'.", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 80, "column": 14}}}, "severity": "INFO"}

```yaml
session:
type: psr16
service: cache.redis.mcp
prefix: 'mcp_<server_identifier>_'
services:
cache.redis.mcp:
public: true
class: Symfony\Component\Cache\Adapter\RedisTagAwareAdapter
parent: cache.adapter.redis
tags:
- name: cache.pool

Check notice on line 93 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L93

[Ibexa.Lists] Verify list formatting: Full sentences should start with uppercase and end with a period. Sentence fragments should start with lowercase and have no period.
Raw output
{"message": "[Ibexa.Lists] Verify list formatting: Full sentences should start with uppercase and end with a period. Sentence fragments should start with lowercase and have no period.", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 93, "column": 1}}}, "severity": "INFO"}
clearer: cache.app_clearer
provider: 'redis://mcp.redis:6379'
namespace: 'mcp'
```

#### File

Sessions are persisted to the filesystem. Requires directory option to be set.

Check notice on line 101 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L101

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 101, "column": 10}}}, "severity": "INFO"}

```yaml
session:
type: file
directory: '%kernel.cache_dir%/mcp/sessions'
```

#### Memory

Sessions are stored in memory. Suitable for development and STDIO transport.

Check notice on line 111 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L111

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 111, "column": 10}}}, "severity": "INFO"}

TODO: Might not work with DDEV or Docker

```yaml
session:
type: memory
```

## MCP server capabilities

Check notice on line 120 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L120

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

TODO: `Ibexa\Contracts\Mcp\McpCapabilityInterface`

TODO: `Ibexa\Contracts\Mcp\Attribute` namespace

## Example

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:

``` 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):

Check notice on line 145 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L145

[Ibexa.ByUsing] Prefer 'by using' or 'with' to plain 'using'.
Raw output
{"message": "[Ibexa.ByUsing] Prefer 'by using' or 'with' to plain 'using'.", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 145, "column": 44}}}, "severity": "INFO"}

``` 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.

Check notice on line 151 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L151

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 151, "column": 65}}}, "severity": "INFO"}

- 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

Check notice on line 154 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L154

[Ibexa.Lists] Verify list formatting: Full sentences should start with uppercase and end with a period. Sentence fragments should start with lowercase and have no period.
Raw output
{"message": "[Ibexa.Lists] Verify list formatting: Full sentences should start with uppercase and end with a period. Sentence fragments should start with lowercase and have no period.", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 154, "column": 1}}}, "severity": "INFO"}
- Validate the MCP Session ID

Check notice on line 155 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L155

[Ibexa.Lists] Verify list formatting: Full sentences should start with uppercase and end with a period. Sentence fragments should start with lowercase and have no period.
Raw output
{"message": "[Ibexa.Lists] Verify list formatting: Full sentences should start with uppercase and end with a period. Sentence fragments should start with lowercase and have no period.", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 155, "column": 1}}}, "severity": "INFO"}
- List the available tools

Check notice on line 156 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L156

[Ibexa.Lists] Verify list formatting: Full sentences should start with uppercase and end with a period. Sentence fragments should start with lowercase and have no period.
Raw output
{"message": "[Ibexa.Lists] Verify list formatting: Full sentences should start with uppercase and end with a period. Sentence fragments should start with lowercase and have no period.", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 156, "column": 1}}}, "severity": "INFO"}
- 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) =]]
```

```

Check failure on line 167 in docs/mcp/mcp_config.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_config.md#L167

[Ibexa.CodeBlockLanguages] Always provide a language with a code block.
Raw output
{"message": "[Ibexa.CodeBlockLanguages] Always provide a language with a code block.", "location": {"path": "docs/mcp/mcp_config.md", "range": {"start": {"line": 167, "column": 1}}}, "severity": "ERROR"}
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.
21 changes: 21 additions & 0 deletions docs/mcp/mcp_guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
description: TODO.
month_change: true
---

# Model Context Protocol and [[= product_name_base =]] MCP Servers

Check notice on line 6 in docs/mcp/mcp_guide.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_guide.md#L6

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

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

Check notice on line 17 in docs/mcp/mcp_guide.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_guide.md#L17

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/mcp/mcp_guide.md", "range": {"start": {"line": 17, "column": 62}}}, "severity": "INFO"}

MCP servers are configured per repository then enabled per SiteAccess scope, allowing for flexible configurations adapted to different contexts.

Check notice on line 19 in docs/mcp/mcp_guide.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/mcp/mcp_guide.md#L19

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/mcp/mcp_guide.md", "range": {"start": {"line": 19, "column": 13}}}, "severity": "INFO"}

MCP servers have their own session storage mechanism, TODO: why, benefit,…
Loading
Loading