Skip to main content

Declarative Tool Servers

The tool_servers top-level config block declares config-managed MCP tool-server metadata. The CLI parses, validates, merges, and exposes these declarations through the hosted MCP inspection tools and resources. They are distinct from providers.targets[].mcp, which is part of runtime provider routing.

The current runtime does not spawn, connect to, or dispatch calls to tool_servers[] declarations. Fields such as containment, trust state, and labels are metadata on this surface; declaring them is not proof that an external tool server is running or that the gateway enforces those settings.

This surface is also different from the Gateway MCP Surface, which exposes Keeptrusts itself from a published agent hostname.

Boundary separation

SurfacePurposeLifecycle
providers.targets[].mcpRuntime bridge for routing LLM traffic through an MCP providerRuntime target config
tool_serversValidated metadata for a separately operated tool serverConfig-managed declaration

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.example.com/mcp"
auth:
type: bearer
header_name: Authorization
secret_key_ref:
env: CODE_SEARCH_BEARER_TOKEN
trust_state: approved
mutability_class: read_only
containment:
network_policy: egress_restricted
timeout_ms: 30000
max_concurrent_calls: 5
labels:
team: platform
environment: production

Fields

Required

FieldTypeDescription
idstringUnique identifier. Must not collide with any providers.targets[].id.
namestringHuman-readable display name. Must be present and non-empty.
transportobjectConnection details — see Transport options.

Optional

FieldTypeDefaultDescription
descriptionstringPurpose description for audit and discovery.
trust_stateenumpendingOne of pending, approved.
mutability_classenumunknownOne of read_only, mutating, unknown.
containmentobjectbuilt-in defaultsExecution boundary constraints.
labelsmapArbitrary string metadata exposed by inspection surfaces.

Transport options

stdio

Describes a tool server that would be launched as a subprocess by an executor that consumes this declaration. The current gateway parser does not launch it.

transport:
kind: stdio
command: "/usr/local/bin/my-tool-server"
args: ["--port", "0"]
FieldRequiredDescription
kindyesMust be stdio.
commandyesPath to the executable.
argsnoCommand-line arguments.

sse

Describes a Server-Sent Events endpoint. The current gateway parser validates the URL field but does not open the connection.

transport:
kind: sse
url: "https://tool-stream.example.com/events"
auth:
type: bearer
header_name: Authorization
secret_key_ref:
env: TOOL_SSE_TOKEN
FieldRequiredDescription
kindyesMust be sse.
urlyesSSE endpoint URL.
authnoAuth settings for HTTP-based transports.

streamable_http

Describes an MCP Streamable HTTP endpoint. The current gateway parser validates the URL field but does not open the connection.

transport:
kind: streamable_http
url: "https://tool-http.example.com/mcp"
auth:
type: bearer
header_name: Authorization
secret_key_ref:
env: TOOL_HTTP_TOKEN
FieldRequiredDescription
kindyesMust be streamable_http.
urlyesStreamable HTTP endpoint URL.
authnoAuth settings for HTTP-based transports.

Transport auth

The current parser records a transport-scoped auth object with these fields:

FieldDescription
typeFree-form auth type label such as bearer
header_nameOptional header name for HTTP transports
secret_key_ref.env or secret_key_ref.storeSecret reference used by the transport

Trust state

ValueMeaning
pendingDeclaration carries a pending trust label.
approvedDeclaration carries an approved trust label.

Trust state is declarative. Operators set it in config.

Containment settings

containment:
network_policy: egress_restricted # unrestricted | egress_restricted | isolated
timeout_ms: 30000
max_concurrent_calls: 5

Defaults:

  • network_policy: egress_restricted
  • timeout_ms: 30000
  • max_concurrent_calls: 5

The parser validates these ranges and exposes the values through MCP inspection surfaces. This declaration path does not currently enforce them during tool execution.

Labels

Labels are arbitrary key-value strings retained with the declaration. The current parser and inspection tools expose them, but this config block does not itself install an ABAC rule or make a tool server available.

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

ErrorCauseFix
conflated tool_server and provider targetA tool_servers[].id matches a providers.targets[].idUse distinct IDs for tool servers and provider targets.
transport.kind missing or invalidThe kind field is absent or not one of stdio, sse, streamable_httpSpecify a valid transport kind.
trust_state must be one of: pending, approvedUnsupported trust-state enumUse pending or approved.
mutability_class must be one of: read_only, mutating, unknownUnsupported mutability enumUse one of the accepted parser values.
transport.command required for stdiostdio transport is missing the command fieldAdd command with the path to the executable.
transport.url requiredsse or streamable_http transport is missing urlAdd the endpoint URL.
containment.network_policy must be one of: unrestricted, egress_restricted, isolatedUnsupported containment modeUse one of the accepted parser values.

Next steps