docs: English JsonRpcBundle docs, REST and MCP Bundle sections, package cards
en/docs/api/mcp-bundle/README.md
+1
−1
MCP Bundle
<include>(docs/api/mcp-bundle/.info.md)
<include>(docs/api/mcp-bundle/.info.md)
An MCP server (Model Context Protocol) for JsonRpcBundle: the methods of your JSON-RPC API become tools that AI agents (Claude Code, Cursor, Gemini CLI, OpenAI) call over Streamable HTTP.
It is a thin adapter, like REST Bundle: business logic stays in the RPC services, and every tool call is a regular RPC request executed by JsonRpcBundle. Parameter conversion, DTOs, validation, caching, locking, events and the error format are the same as on /rpc.
From method to tool
Your code
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 on /mcp (abridged)
{
"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}
}
Nothing else to write:
POST /mcpis an MCP server with theCatalog.searchtool, protected by the RPC token;GET /mcp/manifest/claude.jsonreturns a ready Claude Code connection config (likewisecursor,gemini,openai);GET /mcp/server.jsonis the document for publishing in the MCP Registry.
Features
- The API group decides what becomes a tool. Every method of a group is a tool named after the RPC method. Several endpoints (
/mcp,/mcp/internal, …) side by side, each with its own methods (Configuration). - API versions.
/mcp/v2serves version 2 of the group. - The core does the work. A tool call goes through the JsonRpcBundle
RpcExecutor(Tools). - Schemas and texts for agents.
inputSchema/outputSchemafrom method metadata; titles and descriptions from the core translations byAccept-Language, including per group;#[McpTool]hints. - Both MCP protocol eras on one URL: session-based (sessions in the core cache pool) and stateless 2026-07-28 (HTTP and security).
- The same security. Core RPC tokens (401/403), 404 for a disabled group or a missing version, CORS, DNS rebinding protection, request body limit.
- Discovery.
server.jsonfor the MCP Registry and client manifests (server.json and manifests). - Extensibility. Availability check, access policy, custom client manifests (For developers).
Limitations
- No OAuth: access is the RPC token in a header (HTTP and security).
- Tools only: no MCP resources or prompts. The SDK declares the
loggingandcompletionscapabilities by default, but the bundle does not use them. - No server-initiated messages (
GETon the endpoint answers 405) and no asynchronous or webhook calls through MCP.
<include>(change_log/latest.md)
Getting started
- Install the bundle and add the MCP routes.
- Add RPC methods to the endpoint's group and check
tools/list. - Configure the group's server and, if needed, CORS and hosts.
- Connect a client using a manifest.
en/docs/api/mcp-bundle/.info.md
+17
−62
composer require ufo-tech/mcp-bundle
- PHP 8.4+
- Symfony 7.2+ · 8
- Built on JsonRpcBundle 10.4.3+ ·
mcp/sdk0.8 - Protocol MCP · Streamable HTTP
- Type Symfony Bundle
- Category API · AI
- License MIT