MCP Bundle
composer require ufo-tech/mcp-bundle
- PHP 8.4+
- Symfony 7.2+ · 8
- Основа JsonRpcBundle 10.4.3+ ·
mcp/sdk0.8 - Протокол MCP · Streamable HTTP
- Тип Symfony Bundle
- Категорія API · AI
- Ліцензія MIT
MCP-сервер (Model Context Protocol) для JsonRpcBundle: методи вашого JSON-RPC API стають інструментами (tools), які AI-агенти — Claude Code, Cursor, Gemini CLI, OpenAI — викликають через Streamable HTTP.
Це тонкий адаптер, як і REST Bundle: бізнес-логіка лишається в RPC-сервісах, а кожен виклик інструмента — звичайний RPC-запит, який виконує JsonRpcBundle. Перетворення параметрів, DTO, валідація, кеш, блокування, події та формат помилок — ті самі, що й на /rpc.
Від методу до інструмента
Ваш код
use Ufo\JsonRpcBundle\ApiMethod\Interfaces\IRpcService;
use Ufo\McpBundle\Attribute\McpTool;
use Ufo\RpcObject\RPC;
#[RPC\Info('Catalog')]
#[RPC\APIGroups(['mcp'], withDefault: false)]
final class CatalogProcedure implements IRpcService
{
/**
* Search products by name.
* @param string $query Part of the product name
*/
#[McpTool(readOnlyHint: true)]
public function search(string $query, int $limit = 10): array
{
// ...
}
}
tools/list на /mcp (скорочено)
{
"name": "Catalog.search",
"description": "Search products by name.",
"inputSchema": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Part of the product name"},
"limit": {"type": "integer", "default": 10}
},
"additionalProperties": false,
"required": ["query"]
},
"annotations": {"readOnlyHint": true}
}
Більше нічого писати не треба:
POST /mcp— MCP-сервер з інструментомCatalog.search, захищений RPC-токеном;GET /mcp/manifest/claude.jsonвіддає готову конфігурацію Claude Code для підключення (так самоcursor,gemini,openai);GET /mcp/server.json— документ для публікації в MCP Registry.
Можливості
- Що стає інструментом — визначає група API. Кожен метод групи — інструмент з назвою RPC-методу. Кілька ендпоінтів (
/mcp,/mcp/internal, …) поруч, кожен зі своїми методами (Налаштування). - Версії API.
/mcp/v2обслуговує версію 2 групи. - Роботу робить ядро. Виклик інструмента проходить через
RpcExecutorJsonRpcBundle (Інструменти). - Схеми й тексти для агентів.
inputSchema/outputSchemaз метаданих методів; назви й описи з перекладів ядра заAccept-Language, зокрема окремо для групи; підказки#[McpTool]. - Обидві епохи протоколу MCP на одному URL: із сесіями (сесії в кеш-пулі ядра) і stateless 2026-07-28 (HTTP і безпека).
- Та сама безпека. RPC-токени ядра (401/403), 404 для вимкненої групи чи відсутньої версії, CORS, захист від DNS rebinding, ліміт тіла запиту.
- Discovery.
server.jsonдля MCP Registry і маніфести клієнтів (server.json і маніфести). - Розширюваність. Перевірка доступності, політика доступу, власні маніфести клієнтів (Для розробників).
Обмеження
- Без OAuth: доступ — RPC-токен у заголовку (HTTP і безпека).
- Лише tools: без MCP resources і prompts. SDK типово оголошує capabilities
loggingіcompletions, але бандл їх не використовує. - Без повідомлень з ініціативи сервера (
GETна ендпоінт відповідає 405) і без асинхронних викликів чи webhook через MCP.
Версія 1.0 (2026-10-19)
Перший реліз: RPC-методи групи API як MCP-інструменти через Streamable HTTP.
Ключові зміни
- Ендпоінт на кожен імпорт маршрутів:
api_group— група API ядра,/mcp/v2— версія API 2; назви маршрутів містять групу (mcp_ufo_mcp_endpoint, …). - Інструменти: кожен метод групи; назви й описи з перекладів ядра (зокрема
translations/rpc/<group>.<locale>.yaml) заAccept-Language; самодостатніinputSchema/outputSchema; підказки#[McpTool]. tools/callчерезRpcExecutorядра:structuredContent: {"result": …}і той самий JSON текстом; помилки — RPC-помилка ядра зisError: true;rpc.post_responseпісля відправлення відповіді, один раз на виклик (і в batch).- HTTP і безпека: протокол із сесіями (сесії в кеш-пулі ядра) і stateless 2026-07-28 на одному URL; токени ядра (401/403); 404 для вимкненої групи чи відсутньої версії; CORS, захист від DNS rebinding,
max_body_bytes. - Discovery:
server.jsonдля MCP Registry, маніфести для Claude Code, Cursor, Gemini CLI, OpenAI.
Що врахувати
Стосується лише застосунків, що використовували бандл з dev-main до 1.0.0:
- Опцію
session_directory(загальну і для групи) прибрано — сесії в кеш-пулі ядра; приберіть ключ, інакше «Unrecognized option».groupsтепер може бути порожнім. - Назви маршрутів містять групу (
<group>_ufo_mcp_endpoint); ручнийname_prefixу YAML-імпортах не потрібен. - Назви й описи беруться лише з перекладів ядра:
ToolTextResolverInterfaceіUfo\McpBundle\I18n\*прибрано. - Класи перенесено з
Ufo\McpBundle\Services\*доServer\*,Server\Transport\*,Tool\*; перевірки групи, доступності й токена — зMcpControllerдоEventListener\McpRequestListener.
Зміни оточення
- PHP >= 8.4, Symfony ^7.2 | ^8.0 (через JsonRpcBundle).
ufo-tech/json-rpc-bundle^10.4.3,mcp/sdk^0.8.1,symfony/psr-http-message-bridge^7.2 | ^8.0,symfony/yaml^7.2 | ^8.0,nyholm/psr7^1.8.
З чого почати
- Встановіть бандл і додайте маршрути MCP.
- Додайте RPC-методи в групу ендпоінта — і перевірте
tools/list. - Налаштуйте сервер групи і, за потреби, CORS і хости.
- Підключіть клієнта за маніфестом.