Skip to content

v0.6.0

Choose a tag to compare

@Rendeverance Rendeverance released this 23 Jul 07:41

******** MAJOR UPDATE ********

ToolFunnel v0.6.0: both protocol eras, and the transparent wrap

The 2026-07-28 MCP revision is a breaking change. It removes the initialize handshake and sessions that every existing MCP client and server is built on. This release makes ToolFunnel speak BOTH protocols, in BOTH directions. And on top of that sits the new headline feature...

One command turns ToolFunnel into a transparent wrapper for a single MCP server:

toolfunnel wrap my-server
  • All four combinations work: legacy client to modern server, modern client to legacy server, or matched pairs. No configuration.
  • Invisible from both sides. The client sees the wrapped server's own identity, tools, results, errors and notifications, byte for byte. Verified against real published servers. The server sees your real client, not ToolFunnel.
  • Mid-call user prompts (elicitation) from a legacy server are translated into the modern retry pattern and back, tested end to end against real elicitation servers. Resource subscriptions survive a crash and reconnect. Progress tokens flow through. Cancels are translated into the server's own request ids, so abandoned calls actually stop.
  • The policy gate and per-tool switches still apply to every wrapped call.

Use it to keep an unmaintained server alive past the cutover, to hand a modern-only server to older tooling, or to put a policy gate in front of a server you didn't write.

Dual-era everywhere

  • ToolFunnel answers legacy and modern clients on the same endpoint at the same time. Each request is served in the era it arrives in. server/discover, subscriptions/listen, per-request metadata, header validation and the new result fields are all in.
  • As a client, ToolFunnel probes each attached server and speaks whichever era it understands.
  • legacyPin pins any upstream to the old protocol, per server, with loud warnings. Off by default.
  • Two optional hardening switches: "serveLegacy": false in toolfunnel.json makes the gateway refuse legacy-era clients once yours have moved to the new protocol (smaller attack surface; loud warning, off by default), and "modernOnly": true on an upstream refuses to speak legacy to that server instead of negotiating down. Defaults unchanged: both eras served, both directions.

Also in this release

  • Identity settings: toolfunnel.json now sets the client identity ToolFunnel presents to upstream servers (clientName/clientVersion) alongside the existing server identity. A new Settings tab in the web UI edits it all. Under a wrap on stdio, your real client's identity is mirrored upstream automatically.
  • toolfunnel_howto gains wrap and configure topics, so a plain agent with no special prompt can learn wrapping and the complete no-code configuration map from inside the protocol. legacyPin gets a UI toggle. The wrap security notice now shows in the UI as well as the CLI.
  • Wrapped servers may use outside paths. Wrapping suspends the path-isolation guard for the wrapped server only, with a clear warning and a manual section on locking it back down. Funnel mode keeps the guard.
  • Tool calls now wait up to 120 s, configurable per upstream with "timeoutMs", and a tool that reports progress keeps its call alive indefinitely. Slow tools (builds, searches, image generation) work through the gateway exactly as they do directly. The 10 s window now applies only to handshakes and listings, where a slow answer means a dead server - and that window is also configurable per upstream with "requestTimeoutMs", for servers that boot slowly. A session restore that needs 30 s to answer can now be attached at all.
  • Shell tools no longer block. A long-running shell tool used to stall the whole process; it now runs asynchronously and concurrent clients keep being served.
  • Every start prints the resolved config home, with a relocation hint when it defaulted to the package root. Running from a git clone can no longer write config into the repo without saying so.
  • CLI flags work in any position: toolfunnel --config-dir X wrap Y and toolfunnel wrap Y --config-dir X are equivalent. A mistyped command now refuses loudly instead of silently starting a server.
  • "Discover tools" works on a disabled upstream, so you can inspect before enabling.
  • Server-initiated pings are answered. Upstream keepalives no longer die at the gateway.
  • Hardening under the hood: cancel translation for in-flight calls (a cancelled call now correctly receives no response), subscription replay across reloads, identity continuity across reconnect windows, health-endpoint privacy while wrapped, a cap on concurrent listen streams. The test suite grew from 27 to 35 files, including wire-level tests over real spawned processes, a multi-client concurrency test, and interop tests against the official MCP SDK client.

Notes

  • Built against the 28-July release candidate; final-specification reconciliation follows as a point release.
  • The elicitation bridge currently serves modern clients. A legacy client behind a wrap has mid-call prompts declined automatically, never hung. Server-to-client sampling and roots requests are answered method-not-found for now.
  • Upgrading from 0.5.0: no config changes required. Everything you have keeps working.