docs: rewrite JsonRpcBundle docs, add SDK docs, move them under docs/api
en/docs/api/mcp-bundle/README.md
new file +93
ā0
1
+
# MCP Bundle
2
+
3
+
:::block class="floatinginfobox"
4
+
<include>(docs/api/mcp-bundle/.info.md)
5
+
:::
6
+
7
+
An MCP server ([Model Context Protocol](https://modelcontextprotocol.io)) for [JsonRpcBundle](/docs/api/json-rpc-bundle): the methods of your JSON-RPC API become tools that AI agents (Claude Code, Cursor, Gemini CLI, OpenAI) call over Streamable HTTP.
8
+
9
+
It is a thin adapter, like [REST Bundle](/docs/api/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`.
10
+
11
+
## From method to tool
12
+
13
+
::::columns
14
+
:::col
15
+
**Your code**
16
+
17
+
```php
18
+
use Ufo\JsonRpcBundle\ApiMethod\Interfaces\IRpcService;
19
+
use Ufo\McpBundle\Attribute\McpTool;
20
+
use Ufo\RpcObject\RPC;
21
+
22
+
#[RPC\Info('Catalog')]
23
+
#[RPC\APIGroups(['mcp'], withDefault: false)]
24
+
final class CatalogProcedure implements IRpcService
25
+
{
26
+
/**
27
+
* Search products by name.
28
+
* @param string $query Part of the product name
29
+
*/
30
+
#[McpTool(readOnlyHint: true)]
31
+
public function search(string $query, int $limit = 10): array
32
+
{
33
+
// ...
34
+
}
35
+
}
36
+
```
37
+
:::
38
+
39
+
:::col
40
+
**`tools/list` on `/mcp`** (abridged)
41
+
42
+
```json
43
+
{
44
+
"name": "Catalog.search",
45
+
"description": "Search products by name.",
46
+
"inputSchema": {
47
+
"type": "object",
48
+
"properties": {
49
+
"query": {"type": "string", "description": "Part of the product name"},
50
+
"limit": {"type": "integer", "default": 10}
51
+
},
52
+
"additionalProperties": false,
53
+
"required": ["query"]
54
+
},
55
+
"annotations": {"readOnlyHint": true}
56
+
}
57
+
```
58
+
:::
59
+
::::
60
+
61
+
Nothing else to write:
62
+
63
+
* `POST /mcp` is an MCP server with the `Catalog.search` tool, protected by the RPC token;
64
+
* `GET /mcp/manifest/claude.json` returns a ready Claude Code connection config (likewise `cursor`, `gemini`, `openai`);
65
+
* `GET /mcp/server.json` is the document for publishing in the MCP Registry.
66
+
67
+
## Features
68
+
69
+
* **The API group decides what becomes a tool.** Every method of a [group](/docs/api/json-rpc-bundle/functionality/groups) is a tool named after the RPC method. Several endpoints (`/mcp`, `/mcp/internal`, ā¦) side by side, each with its own methods ([Configuration](/docs/api/mcp-bundle/config)).
70
+
* **API versions.** `/mcp/v2` serves [version](/docs/api/json-rpc-bundle/functionality/versions) 2 of the group.
71
+
* **The core does the work.** A tool call goes through the JsonRpcBundle `RpcExecutor` ([Tools](/docs/api/mcp-bundle/tools)).
72
+
* **Schemas and texts for agents.** `inputSchema` / `outputSchema` from method metadata; titles and descriptions from the core translations by `Accept-Language`, including per group; `#[McpTool]` hints.
73
+
* **Both MCP protocol eras** on one URL: session-based (sessions in the core cache pool) and stateless 2026-07-28 ([HTTP and security](/docs/api/mcp-bundle/http_security)).
74
+
* **The same security.** Core RPC tokens (401/403), 404 for a disabled group or a missing version, CORS, DNS rebinding protection, request body limit.
75
+
* **Discovery.** `server.json` for the MCP Registry and client manifests ([server.json and manifests](/docs/api/mcp-bundle/discovery)).
76
+
* **Extensibility.** Availability check, access policy, custom client manifests ([For developers](/docs/api/mcp-bundle/developers/extensions)).
77
+
78
+
## Limitations
79
+
80
+
* No OAuth: access is the RPC token in a header ([HTTP and security](/docs/api/mcp-bundle/http_security)).
81
+
* Tools only: no MCP resources or prompts. The SDK declares the `logging` and `completions` capabilities by default, but the bundle does not use them.
82
+
* No server-initiated messages (`GET` on the endpoint answers 405) and no [asynchronous](/docs/api/json-rpc-bundle/functionality/async) or [webhook](/docs/api/json-rpc-bundle/functionality/callback) calls through MCP.
83
+
84
+
:::info
85
+
<include>(change_log/latest.md)
86
+
:::
87
+
88
+
## Getting started
89
+
90
+
1. [Install the bundle](/docs/api/mcp-bundle/installation) and add the MCP routes.
91
+
2. Add RPC methods to the endpoint's group and check `tools/list`.
92
+
3. Configure the [group's server](/docs/api/mcp-bundle/config) and, if needed, [CORS and hosts](/docs/api/mcp-bundle/http_security).
93
+
4. Connect a client using a [manifest](/docs/api/mcp-bundle/discovery).
en/docs/api/mcp-bundle/.info.md
new file +65
ā0
1
+
:::::columns border="1" zebra="1"
2
+
::::row
3
+
:::col width="40%"
4
+
Download
5
+
:::
6
+
7
+
:::col
8
+
[Packagist](https://packagist.org/packages/ufo-tech/mcp-bundle)<br>
9
+
[GitHub](https://github.com/UFO-Tech/mcp-bundle)
10
+
:::
11
+
::::
12
+
13
+
::::row
14
+
:::col width="40%"
15
+
Current version
16
+
:::
17
+
18
+
:::col
19
+
[](https://packagist.org/packages/ufo-tech/mcp-bundle)
20
+
:::
21
+
::::
22
+
23
+
::::row
24
+
:::col width="40%"
25
+
Category
26
+
:::
27
+
28
+
:::col
29
+
API
30
+
:::
31
+
::::
32
+
33
+
::::row
34
+
:::col width="40%"
35
+
Type
36
+
:::
37
+
38
+
:::col
39
+
Symfony Bundle
40
+
:::
41
+
::::
42
+
43
+
::::row
44
+
:::col width="40%"
45
+
Dependencies
46
+
:::
47
+
48
+
:::col
49
+

50
+

51
+

52
+
:::
53
+
::::
54
+
55
+
::::row
56
+
:::col width="40%"
57
+
Other information
58
+
:::
59
+
60
+
:::col
61
+

62
+

63
+
:::
64
+
::::
65
+
:::::
en/docs/api/mcp-bundle/change_log/latest.md
new file +1
ā0
1
+
<include>(1.0.0.md)
en/docs/api/mcp-bundle/change_log/1.0.0.md
new file +25
ā0
1
+
## Version 1.0 (2026-10-19)
2
+
3
+
First release: the RPC methods of an API group as MCP tools over Streamable HTTP.
4
+
5
+
### Key changes
6
+
7
+
* [An endpoint per route import](/docs/api/mcp-bundle/config): `api_group` is the core API group, `/mcp/v2` is API version 2; route names contain the group (`mcp_ufo_mcp_endpoint`, ā¦).
8
+
* [Tools](/docs/api/mcp-bundle/tools): every method of the group; titles and descriptions from the core translations (including `translations/rpc/<group>.<locale>.yaml`) by `Accept-Language`; self-contained `inputSchema` / `outputSchema`; `#[McpTool]` hints.
9
+
* `tools/call` through the core `RpcExecutor`: `structuredContent: {"result": ā¦}` plus the same JSON as text; errors are the core RPC error with `isError: true`; `rpc.post_response` after the response is sent, once per call (also in a batch).
10
+
* [HTTP and security](/docs/api/mcp-bundle/http_security): the session-based protocol (sessions in the core cache pool) and stateless 2026-07-28 on one URL; core tokens (401/403); 404 for a disabled group or a missing version; CORS, DNS rebinding protection, `max_body_bytes`.
11
+
* [Discovery](/docs/api/mcp-bundle/discovery): `server.json` for the MCP Registry, manifests for Claude Code, Cursor, Gemini CLI, OpenAI.
12
+
13
+
### What to keep in mind
14
+
15
+
Only applies to applications that used the bundle from `dev-main` before 1.0.0:
16
+
17
+
* The `session_directory` option (bundle-wide and per group) was removed, sessions live in the core cache pool; remove the key, otherwise "Unrecognized option". `groups` may now be empty.
18
+
* Route names contain the group (`<group>_ufo_mcp_endpoint`); a manual `name_prefix` in YAML imports is no longer needed.
19
+
* Titles and descriptions come only from the core translations: `ToolTextResolverInterface` and `Ufo\McpBundle\I18n\*` were removed.
20
+
* Classes moved from `Ufo\McpBundle\Services\*` to `Server\*`, `Server\Transport\*`, `Tool\*`; the group, availability and token checks moved from `McpController` to `EventListener\McpRequestListener`.
21
+
22
+
### Environment changes
23
+
24
+
* PHP >= 8.4, Symfony ^7.2 | ^8.0 (through JsonRpcBundle).
25
+
* `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.