docs: rewrite JsonRpcBundle docs, add SDK docs, move them under docs/api
uk/docs/api/mcp-bundle/developers/README.md
новий файл +71
−0
1
+
# Для розробників
2
+
3
+
Як MCP Bundle працює всередині: принципи, компоненти, шлях запиту і що кешується. Бандл — розширення [JsonRpcBundle](/docs/api/json-rpc-bundle/developers) і дотримується загальних положень для розширень ядра.
4
+
5
+
## Принципи
6
+
7
+
1. **Тонкий адаптер над JsonRpcBundle.** Як і REST Bundle, цей бандл додає протокол, а не другий сервер. Бізнес-логіка лишається в RPC-сервісах (`IRpcService`); виклик інструмента — звичайний RPC-запит, який виконує ядро.
8
+
2. **Перевикористовувати, а не дублювати.** Карта сервісів, групи й версії API, переклади, узгодження мови, безпека на токенах, пули кешу, імпорт маршрутів і виконання запитів беруться з ядра. Коли в ядрі бракує точки розширення, її додають у ядро: так з'явилися `IApiRouteImport` у 10.4.1 і `RpcExecutor` у 10.4.2.
9
+
3. **Маршрут — джерело істини.** Група API береться з імпорту маршрутів (`api_group`), версія — із сегмента `{ver}`. Конфігурація лише налаштовує сервер групи.
10
+
4. **Публікація = членство в групі API.** Кожен метод групи стає інструментом; ні allowlist, ні окремої реєстрації для MCP немає.
11
+
5. **Протокол реалізує офіційний SDK.** Handshake, сесії, stateless-протокол 2026-07-28, перевірка аргументів за `inputSchema`, batch, middleware CORS і DNS rebinding — це `mcp/sdk` (^0.8.1). Бандл будує сервер SDK на кожен запит і підключає до нього RPC-методи.
12
+
6. **Падати голосно.** Метод, чия назва не є коректною назвою MCP-інструмента, ламає свою групу (HTTP 500 з поясненням у debug), а не зникає зі списку мовчки.
13
+
14
+
## Компоненти
15
+
16
+
| Компонент | Роль |
17
+
| --- | --- |
18
+
| `Routing\McpRouteImport` | Реєструє `config/router.yaml` у завантажувачі маршрутів ядра (`IApiRouteImport`): кожен імпорт отримує назви `<group>_ufo_mcp_*` і атрибут `_mcp_name_prefix` |
19
+
| `Controller\McpController` | Три дії: MCP-ендпоінт, `server.json`, маніфести клієнтів |
20
+
| `EventListener\McpRequestListener` | Слухач `kernel.controller` лише для `McpController`: група API, доступність (404), токен (401/403) |
21
+
| `Server\McpHandler` | Узгодження мови, транспорт, сервер SDK, `Content-Language` / `Vary` |
22
+
| `Server\Transport\StreamableHttpTransportFactory` | Streamable HTTP-транспорт SDK з CORS, захистом від DNS rebinding і лімітом тіла запиту групи |
23
+
| `Server\McpServerFactory` | Сервер SDK для одного запиту: ідентичність, `instructions`, сховище сесій, інструмент на кожен метод групи й версії |
24
+
| `Server\Session\RpcCacheSessionStore` | Сесії протоколу із сесіями в пулі кешу ядра `rpc.cache.pool` |
25
+
| `Tool\ToolSchemaFactory` | MCP `Tool` з метаданих `Service` ядра: перевірка назви, тексти, `inputSchema`, `outputSchema`, анотації; кешується в `RpcMetadataCache` ядра |
26
+
| `Tool\RpcToolHandler`, `Tool\RpcToolExecutor` | `tools/call` → `RpcExecutor` ядра → `CallToolResult` |
27
+
| `Server\RequestPrepare\Holders\RpcFromMcp` | Носій запиту (`IRpcRequestCarrier`): `RpcRequest` з інструмента, аргументів і версії |
28
+
| `DocAdapters\Outputs\ServerJsonAdapter` | `server.json` для MCP Registry |
29
+
| `ClientManifest\*` | Маніфести клієнтів (Claude Code, Cursor, Gemini CLI, OpenAI), тегований locator |
30
+
| `ConfigService\McpConfig`, `McpGroupConfig`, `McpServerInfoConfig` | Типізоване подання конфігурації `ufo_mcp`; група без запису отримує загальні налаштування |
31
+
| `Security\McpAccessPolicyInterface`, `Availability\McpAvailabilityCheckerInterface` | Точки розширення — див. [Розширення](/docs/api/mcp-bundle/developers/extensions) |
32
+
33
+
## Шлях запиту
34
+
35
+
```
36
+
HTTP request — маршрут з config/router.yaml, імпортований для кожної групи API
37
+
→ McpRequestListener (kernel.controller, лише McpController)
38
+
ApiGroupContext ← api_group / _mcp_name_prefix маршруту
39
+
404: група вимкнена (McpAvailabilityCheckerInterface) або {ver} немає серед версій групи в ServiceMap
40
+
OPTIONS (CORS preflight) — без токена
41
+
IRpcSecurity ядра: isValidApiRequest() для ендпоінта, isValidDocRequest() для server.json / маніфестів
42
+
401 (немає токена) / 403 (недійсний) як {"error": "..."}
43
+
→ McpController::mcpAction → McpHandler::handle()
44
+
RpcLocaleNegotiator ядра → мова запиту
45
+
StreamableHttpTransportFactory → PSR-7 запит + транспорт SDK (CORS, DNS rebinding, max_body_bytes)
46
+
McpServerFactory::create($ver, $locale) → Server SDK (інструменти з ServiceMap::getServices($ver) групи)
47
+
SDK: initialize / ping / tools/list / tools/call / DELETE сесії ...
48
+
Content-Language, Vary: Accept-Language
49
+
→ tools/call → RpcToolHandler → RpcToolExecutor
50
+
RpcFromMcp(service, arguments, version) → RpcExecutor::execute() ядра
51
+
(той самий конвеєр, що й /rpc; виняток проходить через rpc.error, відповідь — завжди RpcResponse)
52
+
RpcRequestHandler::responseToArray() ядра → CallToolResult (text + structuredContent | isError)
53
+
→ kernel.terminate: PostResponseQueue ядра запускає rpc.post_response для кожного виконаного виклику
54
+
```
55
+
56
+
Детальніше про етапи ядра — [Життєвий цикл](/docs/api/json-rpc-bundle/developers/lifecycle).
57
+
58
+
## Що будується на кожен запит, що кешується
59
+
60
+
* Сервер SDK і список інструментів створюються для кожного HTTP-запиту: між запитами сервер не зберігає стану, сесії живуть у пулі кешу.
61
+
* Кожен `Tool` кешується в `RpcMetadataCache` ядра (`cache.system`) з ключем за групою, версією, методом і мовою. Кеш скидається при кожному перезбиранні контейнера і вимкнений у debug — те саме правило, що ядро застосовує до власної документації.
62
+
* Compiler pass свідомо не використовується: контейнер не відстежує класи DTO, а для побудови схем потрібні сервіси застосунку.
63
+
* Сесії (лише для протоколу із сесіями) живуть у `rpc.cache.pool` під ключем `ufo_mcp_<group>_<session id>` з `session_ttl` на кожен запис.
64
+
65
+
## Що є в розділі
66
+
67
+
* [Розширення](/docs/api/mcp-bundle/developers/extensions) — точки розширення бандла і ядра.
68
+
* [Тести](/docs/api/mcp-bundle/developers/testing) — набори тестів, фікстури, покриття, MCP Inspector.
69
+
* [Відомі помилки](/docs/api/mcp-bundle/developers/known_issues/open) — що працює не так, як очікується, і як це обійти.
70
+
71
+
Помилки й пропозиції — в [issue tracker](https://github.com/UFO-Tech/mcp-bundle/issues) репозиторію бандла.