Skip to content

Tool Discovery Service: the xDS extension resources that add, update and remove MCP tools, OpenAPI sources, dynamic servers and toolkits at runtime.

TDS delivers MCP tools, OpenAPI tool sources, dynamic MCP servers and code-mode toolkits to a running MCP gateway as xDS extension resources. Tool catalogs change without replacing listeners, routes or TLS.

Enabling TDS on a gateway

TDS rides the same delta ADS stream as every other resource, so the bootstrap must configure dynamic_resources. On the gateway itself, set tds.config_name in the MCP gateway filter:

typed_config:
  "@type": type.googleapis.com/arion.extensions.filters.http.mcp.mcp_gateway.v3.McpGateway
  server_info:
    name: tenant-a-mcp
    version: "1.0.0"
  tools_mode: {}
  tds:
    config_name: main
  tools: []           # static tools may coexist with TDS-delivered ones

Arion subscribes to all four TDS type URLs with a wildcard when the first TDS-enabled gateway loads. Resources delivered over TDS land in that gateway's registry next to any statically configured tools, OpenAPI sources and dynamic servers.

Scopes and resource IDs

Every TDS resource is addressed to one gateway scope:

PieceValue
Scope{server_info.name}/{tds.config_name}, for example tenant-a-mcp/main
Resource ID{server_info.name}/{tds.config_name}/{resource_name}, for example tenant-a-mcp/main/weather.get_forecast

server_info.name and tds.config_name must not contain /; the resource name may. The resource name is canonical for every type. If the payload's own name or namespace differs, Arion uses the resource name, so a later remove targets the same key.

TypeResource name
Toolnamespace.name. A name that does not parse as a qualified name is NACKed.
OpenApiToolSourceThe source's namespace
DynamicMcpServerThe server's namespace
ToolkitThe toolkit's name

Two gateways are isolated as long as their scopes differ: the same config_name under different server_info.name values never shares resources. For TDS-enabled gateways, Arion rejects duplicate server_info.name values in one runtime, which prevents accidental fan-out.

Resource payloads

Tool

Type URL: type.googleapis.com/arion.extensions.filters.http.mcp.mcp_gateway.v3.Tool

FieldTypeRequiredDefaultDescription
namespacestringyes—Tool namespace; overridden by the resource name if they differ.
namestringyes—Local tool name; overridden by the resource name if they differ.
descriptionstringyes—Description shown to MCP clients and used by tool search.
input_schemaDataSourcenoempty objectJSON Schema for the tool's arguments.
output_schemaDataSourcenounsetJSON Schema for the result.
rest_backendRestBackendone of—Execute by calling a REST upstream.
mcp_server_backendMcpServerBackendone of—Proxy the call to an upstream MCP server (transport: Sse or StreamableHttp, plus url).
function_graph_backendobjectone of—Reserved backend kind; carries no fields.
rbacToolRbacnounsetPer-tool JWT access rules.
embeddinglist of floatno[]Precomputed embedding vector for search. When it is omitted and remote embeddings are configured, Arion embeds the tool on the next search.
disclosure_modeenumnoPROGRESSIVEEAGER lists the tool in tools/list; PROGRESSIVE leaves it to search.

RestBackend fields: method, path, query_params (a list of name/source), cluster, body_template (DataSource) or body_json (string), and upstream_policy (authority, timeout, retry_policy).

OpenApiToolSource

Type URL: type.googleapis.com/arion.extensions.filters.http.mcp.mcp_gateway.v3.OpenApiToolSource

FieldTypeRequiredDefaultDescription
specDataSourceyes—OpenAPI 3.x document, JSON or YAML. A filename is read on the Arion host when the resource arrives.
namespacestringyes—Namespace of every derived tool; overridden by the resource name if they differ.
clusterstringyes—Cluster every derived tool calls.
upstream_policyHttpUpstreamPolicynounsetApplied to every derived tool.
rbacToolRbacnounsetApplied to every derived tool.
tool_disclosure_modeenumnoPROGRESSIVEDisclosure mode of every derived tool.
path_prefixstringnopath of servers[0].urlBase path for every operation.
skip_unsupported_operationsboolnofalseSkip operations that cannot become tools instead of rejecting the resource.
include_operations, exclude_operationslist of stringnoemptyGlob filters on operationId and METHOD /path; see OpenAPI tools.

DynamicMcpServer

Type URL: type.googleapis.com/arion.extensions.filters.http.mcp.mcp_gateway.v3.DynamicMcpServer

FieldTypeRequiredDefaultDescription
namespacestringyes—Namespace of the discovered tools, registered as {namespace}.{upstream_tool}. Overridden by the resource name if they differ.
descriptionstringnoemptyDescription of the server.
transportenumnoSseSse or StreamableHttp; only StreamableHttp is implemented.
urlstringyes—Absolute http or https URL of the upstream MCP endpoint.
cache_durationdurationnounsetMinimum interval between refreshes. When unset, a successful first fetch is cached indefinitely.
rbacToolRbacnounsetAccess rules applied to every tool materialized from this server.
tool_disclosure_modeenumnoPROGRESSIVEDisclosure mode of every tool materialized from this server.

Toolkit

Type URL: type.googleapis.com/arion.extensions.filters.http.mcp.mcp_gateway.v3.Toolkit

Consumed only by gateways in code mode; tools-mode gateways ACK and ignore it.

FieldTypeRequiredDefaultDescription
namestringyes—Toolkit name; always replaced by the resource name.
descriptionstringyes—The kind of task the toolkit is for.
instructionsstringyes—Guidance on composing the tools.
toolslist of {namespace, name}yes—At least two distinct tool references.

ToolRbac fields: action (ALLOW or DENY) and permissions, a list where each entry is a jwt_header or jwt_claim matcher with field and value. See tool authorization.

Update and remove semantics

EventEffect
Tool updateValidates the tool through the same path as static config, then adds or replaces it in every registry of the scope. It can replace a static tool with the same qualified name. It is NACKed if an OpenAPI source or a dynamic server owns the namespace. An embedding failure does not fail the update.
Tool removeRemoves the static or TDS-delivered tool with that qualified name. A static definition does not come back until the configuration reloads. Tools derived from an OpenAPI source or a dynamic server are not touched.
OpenApiToolSource updateExpands the document and replaces every tool in the namespace with the result. An invalid document is NACKed, and the registry keeps its previous tools.
OpenApiToolSource removeEvicts every tool derived from the source.
DynamicMcpServer updateAdds or replaces the server, fetches its tools/list straight away, and materializes the tools. Replacing a server evicts its previous tools. A failed fetch NACKs the update.
DynamicMcpServer removeRemoves the server and evicts every tool materialized from it.
Toolkit updateAdds or replaces the toolkit in every code-mode registry of the scope.
Toolkit removeRemoves the toolkit.

Malformed resource IDs and undecodable or invalid payloads are NACKed. An update or remove for a scope with no live gateway is ACKed as a no-op, so a control plane can publish resources before the matching listener exists.

Continue

Start typing to search the site.

↑ ↓ to move Enter to open Esc to close