docs: rewrite JsonRpcBundle docs, add SDK docs, move them under docs/api
en/docs/api/mcp-bundle/developers/extensions.md
new file +75
ā0
1
+
# Extending the bundle
2
+
3
+
Everything below is a regular Symfony service override or a tagged service; the bundle itself does not need changes.
4
+
5
+
| What | How | For |
6
+
| --- | --- | --- |
7
+
| `Availability\McpAvailabilityCheckerInterface` | service alias | Whether a group answers at all (otherwise 404) |
8
+
| `Security\McpAccessPolicyInterface` | service alias | CORS origins and the host allowlist for DNS rebinding protection |
9
+
| `ClientManifest\McpClientManifestGeneratorInterface` | tag `ufo_mcp.client_manifest_generator` with a `key` | A manifest for another client |
10
+
| `translations/rpc/<group>.<locale>.yaml` | core translations | Texts for the agent without code changes |
11
+
| `#[McpTool]` | attribute on a method | `ToolAnnotations` hints |
12
+
13
+
## Group availability
14
+
15
+
`McpAvailabilityCheckerInterface::isEnabled(string $group): bool` decides whether a group answers at all (otherwise 404). The default `DefaultMcpAvailabilityChecker` reads `enabled` (`ufo_mcp.groups.<group>.enabled` falling back to `ufo_mcp.enabled`). Replace it for a feature flag, a per-tenant switch or a maintenance window:
16
+
17
+
```php
18
+
use Ufo\McpBundle\Availability\McpAvailabilityCheckerInterface;
19
+
20
+
final readonly class FeatureFlagAvailability implements McpAvailabilityCheckerInterface
21
+
{
22
+
public function __construct(private FeatureFlags $flags) {}
23
+
24
+
public function isEnabled(string $group): bool
25
+
{
26
+
return $this->flags->isOn('mcp.'.$group);
27
+
}
28
+
}
29
+
```
30
+
31
+
```yaml
32
+
# config/services.yaml
33
+
services:
34
+
Ufo\McpBundle\Availability\McpAvailabilityCheckerInterface: '@App\Mcp\FeatureFlagAvailability'
35
+
```
36
+
37
+
Your implementation fully replaces the configuration check; if you need both, call the default one yourself.
38
+
39
+
## Hosts and origins
40
+
41
+
`McpAccessPolicyInterface`: see [CORS and DNS rebinding](/docs/api/mcp-bundle/http_security).
42
+
43
+
## A manifest for another client
44
+
45
+
```php
46
+
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
47
+
use Ufo\McpBundle\ClientManifest\McpClientManifestGeneratorHolder;
48
+
use Ufo\McpBundle\ClientManifest\McpClientManifestGeneratorInterface;
49
+
use Ufo\McpBundle\ConfigService\McpGroupConfig;
50
+
51
+
#[AutoconfigureTag(McpClientManifestGeneratorHolder::TAG, ['key' => 'acme'])]
52
+
final class AcmeAgentManifestGenerator implements McpClientManifestGeneratorInterface
53
+
{
54
+
public function generate(McpGroupConfig $group, string $endpointUrl, string $tokenHeaderName): array
55
+
{
56
+
return [
57
+
'servers' => [
58
+
$group->name => ['url' => $endpointUrl, 'headers' => [$tokenHeaderName => '<UFO_MCP_TOKEN>']],
59
+
],
60
+
];
61
+
}
62
+
}
63
+
```
64
+
65
+
The manifest is served at `<prefix>/manifest/acme.json` in the format that client's config file expects. The key must match `[\w-]+` and must not clash with the built-in ones (`claude`, `cursor`, `gemini`, `openai`). `$endpointUrl` is the absolute endpoint URL from the request, `$tokenHeaderName` is `ufo_json_rpc.security.token_name`. Do not put a real token into a manifest.
66
+
67
+
## Texts for the agent
68
+
69
+
Group translations (`translations/rpc/<group>.<locale>.yaml`) describe a method for an AI agent differently from the OpenRPC documentation, without code changes; see [Title and description](/docs/api/mcp-bundle/tools). An extension bundle can ship its own translations through the core `ufo_json_rpc.translations.paths`.
70
+
71
+
## Everything the core offers
72
+
73
+
A tool call is a core RPC request, so the [JsonRpcBundle extension points](/docs/api/json-rpc-bundle/developers) work unchanged: [event](/docs/api/json-rpc-bundle/functionality/events) listeners (`rpc.request`, `rpc.pre_execute`, `rpc.post_execute`, `rpc.pre_response`, `rpc.post_response`, `rpc.error`), parameter converters, token validators and per-group token providers, the response cache pool.
74
+
75
+
Other ecosystem packages are on the [JsonRpcBundle Extensions](/docs/api/json-rpc-bundle/developers/extensions) page.