Extending the bundle

← Extending the bundle

Ashterix

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.