Declarative Tool Servers
The tool_servers top-level config block declares durable MCP tool servers that the gateway manages for governed execution. These are long-lived server registrations — distinct from the ephemeral providers.targets[].mcp runtime bridge used for provider routing.
Use this page when
- You need to register a persistent MCP tool server for governed tool execution.
- You want to understand how
tool_serversdiffers fromproviders.targets[].mcp. - You are configuring transport, trust state, containment, or ABAC labels for a tool server.
- You need to troubleshoot tool server validation errors during config parsing.
Primary audience
- Primary: Technical Engineers, AI Agents
- Secondary: Technical Leaders
Boundary separation
| Surface | Purpose | Lifecycle |
|---|---|---|
providers.targets[].mcp | Runtime bridge for routing LLM traffic through an MCP provider | Ephemeral, per-request |
tool_servers | Durable registration of a governed tool server | Long-lived, config-managed |
The two surfaces are intentionally separate. A tool server declared under tool_servers is not a provider target and cannot appear in the providers block. The gateway rejects configs that conflate the two (matching IDs across both blocks).
Config structure
tool_servers:
- id: "code-search"
name: "Code Search MCP"
description: "Semantic code search over the monorepo"
transport:
kind: streamable_http
url: "https://code-search.internal:8443/mcp"
headers:
Authorization:
secret_key_ref: code-search-bearer-token
trust_state: verified
mutability_class: read_only
containment:
network_egress: deny
filesystem_write: deny
max_execution_seconds: 30
labels:
team: platform
environment: production
Fields
Required
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier. Must not collide with any providers.targets[].id. |
transport | object | Connection details — see Transport options. |
Optional
| Field | Type | Default | Description |
|---|---|---|---|
name | string | — | Human-readable display name. |
description | string | — | Purpose description for audit and discovery. |
trust_state | enum | unverified | One of unverified, verified, certified. Controls gateway enforcement level. |
mutability_class | enum | unknown | One of read_only, write, unknown. Informs containment decisions. |
containment | object | — | Execution boundary constraints. |
labels | map | — | Key-value pairs for ABAC binding and policy matching. |
Transport options
stdio
Launches the tool server as a subprocess.
transport:
kind: stdio
command: "/usr/local/bin/my-tool-server"
args: ["--port", "0"]
env:
API_KEY:
secret_key_ref: my-tool-api-key
| Field | Required | Description |
|---|---|---|
kind | yes | Must be stdio. |
command | yes | Path to the executable. |
args | no | Command-line arguments. |
env | no | Environment variables. Values may use secret_key_ref. |
sse
Connects to a Server-Sent Events endpoint.
transport:
kind: sse
url: "https://tool.internal:9090/events"
headers:
Authorization:
secret_key_ref: tool-sse-token
| Field | Required | Description |
|---|---|---|
kind | yes | Must be sse. |
url | yes | SSE endpoint URL. |
headers | no | HTTP headers. Values may use secret_key_ref. |
streamable_http
Connects via bidirectional HTTP streaming (MCP Streamable HTTP transport).
transport:
kind: streamable_http
url: "https://tool.internal:8443/mcp"
headers:
Authorization:
secret_key_ref: tool-http-token
| Field | Required | Description |
|---|---|---|
kind | yes | Must be streamable_http. |
url | yes | Streamable HTTP endpoint URL. |
headers | no | HTTP headers. Values may use secret_key_ref. |
Trust state
| Value | Meaning |
|---|---|
unverified | Server identity not confirmed. Gateway applies maximum enforcement. |
verified | Server identity confirmed through out-of-band process. Standard enforcement. |
certified | Server passed formal certification. Reduced enforcement where policy allows. |
Trust state is declarative — the gateway does not automatically verify servers. Operators set this based on their own verification processes.
Containment settings
containment:
network_egress: deny # deny | allow | scoped
filesystem_write: deny # deny | allow | scoped
max_execution_seconds: 30
These settings inform gateway-side enforcement. When a tool invocation would violate containment, the gateway blocks the call and emits a governance event.
Labels for ABAC binding
Labels are arbitrary key-value strings used for Attribute-Based Access Control binding. Policy rules can match against labels to scope tool server availability.
labels:
team: data-engineering
sensitivity: pii
region: eu-west-1
Merge behavior
When multiple config sources are composed (e.g., base + overlay), tool servers merge by id. A later declaration with the same id fully replaces the earlier one — there is no partial field merge.
Common errors
| Error | Cause | Fix |
|---|---|---|
conflated tool_server and provider target | A tool_servers[].id matches a providers.targets[].id | Use distinct IDs for tool servers and provider targets. |
transport.kind missing or invalid | The kind field is absent or not one of stdio, sse, streamable_http | Specify a valid transport kind. |
inline secret not allowed | A plaintext secret appears where secret_key_ref is required | Replace inline values with secret_key_ref references. |
transport.command required for stdio | stdio transport is missing the command field | Add command with the path to the executable. |
transport.url required | sse or streamable_http transport is missing url | Add the endpoint URL. |
Related
- Config Variables — managing the values that
secret_key_refresolves - Declarative Knowledge Sources —
knowledge_sourcescan reference tool servers viatool_server_ref - Multi-Provider Fallback — runtime provider routing (separate concern)