The bus resolves a server.tool name, routes to a connection, validates args
against the input schema, applies a per-server rate limit, opens a trace span,
and calls. Retries happen on failure unless the tool is annotated destructive.
Remote transports speak the Model Context Protocol through the official
mcp SDK (v1.3.0, ADR-0008). The bus connects non-lazy servers on start();
a failing server is isolated (warning, never blocks the bus), and lazy: true
servers connect on first use.
| Transport | Use |
|---|---|
stdio | Local MCP server subprocess (production-ready) |
http | MCP Streamable HTTP — the production remote path |
sse | Legacy HTTP+SSE bridge (deprecated by the MCP spec; warns on connect) |
websocket | Placeholder — the MCP protocol defines no websocket transport; connect() raises NotImplementedError |
inprocess | Built-in server, no network |
Remote failures are wrapped in stable error codes: invalid server config
raises MCP_CONFIG_INVALID, connect/handshake/IO failures raise
MCP_CONN_FAILED (retryable), and a remote tool reporting a tool-level error
raises TOOL_EXEC_FAILED.
Hanflow ships seven built-in MCP servers: code_exec, filesystem,
http_request, shell, vector_search, web_fetch, web_search. The default
config wires web_search as in-process.
mcp_servers:
web_search: { transport: inprocess }
filesystem:
transport: stdio
command: node
args: ["./mcp/fs-server.js"]
- id: search
type: Tool
config:
tool: web_search.search
args: { query: "{{input.q}}" }
Tool names must be in server.tool form. Destructive tools are not retried.