13. External tool services

[!ref] Full details in the User Manual, "External tool services".

13.1 Service-entry fields

Field Type Description
name string Name (also the tool prefix, e.g. notion.*)
protocol enum http (Streamable HTTP, the default when adding a service manually) / sse (legacy) / stdio. If you pick the wrong one, the connection negotiates a fallback automatically: when the server is reachable but rejects the handshake (e.g. 405 / Bad Request), the other HTTP transport is tried and the one that actually worked is written back to the config; if the server can't be reached at all (refused / timeout / EOF), no fallback is attempted
lazy_load bool Whether this service's tools are lazily loaded. Defaults to following the global "Tool category lazy loading"; turn it off explicitly and this service's tools stay resident. Persisted as mcp_lazy_load (keyed by backend name)
endpoint string URL — for HTTP / SSE; unused for stdio
command string Command to launch on stdio (e.g. npx -y @some/mcp-server)
args array Command-line arguments for the stdio channel
env map Environment variables for the stdio child process (credentials, tokens, …)
credential string Bearer token or API key (HTTP / SSE)
oauth object OAuth 2.1 + PKCE config (authorizationEndpoint / tokenEndpoint / clientId / scope / clientSecret?); endpoints can be auto-discovered via .well-known
enabled bool Active
timeout_ms int Request timeout
retry object max=3, base=500ms, jitter=0.3

Credential storage (VAULT): credential / env / oauth.refresh_token and refresh metadata are not written to the main config file and not logged; they live in a GM-encrypted credential vault (SM4-GCM + HKDF-SM3, bound to machineID). Existing plaintext credentials are passively migrated on next use.

13.1.1 OAuth flow fields

Field Description
authorizationEndpoint OAuth authorization endpoint
tokenEndpoint OAuth token endpoint
clientId Client ID
clientSecret Optional; absent = public client (PKCE only)
scope Requested scopes
redirectUri Local loopback: http://127.0.0.1:<port>/cb
pkce.codeVerifier / pkce.codeChallenge S256
accessTokenExpiresAt Auto-refreshed before expiry (startup / background) using refresh_token

13.1.2 Health-board fields

MCP Config → Health Board — sourced from the zMCP gateway /admin/metrics ring buffer:

Field Description
backend MCP backend name
calls Calls in window
failRate Failure rate
p50Ms / p95Ms Response latency percentiles (ms)
lastError / lastErrorAt Most recent failure message and timestamp

13.2 Tool naming rules

Source Name
Built-in tools No prefix (e.g. read, git.status)
Security analysis sec.* prefix
External services <name>.* prefix (e.g. notion.search)
Messaging outbound channels.* prefix
Skill invocation skill.invoke

13.3 Error drawer entries

Field Description
Time Trigger time
Tool Tool name
Status / Class HTTP status / exception class
Summary One-line description
Detail Raw server response (up to 4 KB)
Retries Auto-retry attempts

Absent-backend fallback: when a backend is momentarily absent / not ready, tools/call used to return an "unknown tool" protocol error; unknown tools are now handled gracefully and the backend is reconnected / self-healed on demand, recovering automatically once ready — no longer taking tools down wholesale.