v0.40.0
π Toolhive v0.40.0 is live!
This release hardens Virtual MCP authorization end-to-end β explicit HTTP 403 denials, a unified authz gate, and complete capability pagination β while laying the groundwork for agentic auth (RFC 8693 token exchange, the MCP 2026-07-28 revision) and moving MCP protocol handling onto the official modelcontextprotocol/go-sdk. It also fixes network isolation silently breaking --network host workloads and closes an SSRF gap in upstream Dynamic Client Registration.
π New Features
- The embedded authorization server gains an RFC 8693 OAuth 2.0 Token Exchange grant handler, so an agent can exchange a user's token for a delegated token carrying both the user (
sub) and the acting agent (act.sub) β the foundation for agentic delegation (not yet wired into the server) (#5822). - ToolHive's request-parsing layer now understands the upcoming stateless MCP 2026-07-28 ("Modern") revision β a revision classifier, the
Mcp-Method/Mcp-Nameheader and_metavocabulary, andserver/discover/subscriptions/listenauthz registration β dormant until later slices wire it into proxy routing, with no change to existing traffic (#5834).
π Bug Fixes
- Virtual MCP now returns an explicit HTTP 403 (with a JSON-RPC error code 403 and a "denied by authorization policy" message) when a Cedar policy denies a
tools/call,resources/read, orprompts/get, instead of a misleading-32602"not found" at HTTP 200 β and records the denial asdeniedin the audit log (#5841). thv run --network hostno longer silently loses outbound connectivity: network isolation (on by default) is dropped for host/none networking with a warning, and explicitly combining--isolate-network=truewith--network hostnow fails fast with an actionable error instead of starting a broken workload (#5794).- The Virtual MCP authz gate is hardened so the gate decision, the enforced decision, and the backend forward all derive from a single argument decode, and a backend tool named
execute_tool_scriptnow fails loudly instead of being silently shadowed by the code-mode virtual tool (#5850). - Virtual MCP capability discovery now follows list pagination cursors to exhaustion, so backends advertising more than one page (>1000 tools, resources, or prompts) no longer have their extra capabilities silently dropped from routing and clients (#5851).
- Upstream Dynamic Client Registration (DCR) discovery and registration calls are now routed through a private-IP-guarded HTTP client, closing an SSRF vector (CWE-918) β safe by default and honoring the upstream's existing
allow_private_ipssetting (#5826). - Multi-upstream embedded authservers with two or more OAuth2 DCR upstreams requesting the same scopes now register a distinct client per upstream instead of silently reusing the first upstream's credentials, fixing failed or misattributed authorization (#5824).
π§Ή Misc
- Migrated MCP protocol handling from
mark3labs/mcp-goto the go-sdk-backedtoolhive-core/mcpcompatcompatibility shim (a pure, atomic import swap with no call-site logic changes), moving ToolHive onto the officialmodelcontextprotocol/go-sdk. Note: the stdio bridge currently forwards only progress/message notifications, sotools/list_changedand similar notifications are dropped β dynamic-capability servers may show stale lists until clients re-list (#5729). - Resolved temp-dir symlinks in the plugin adapter tests so
task testpasses on macOS (/varβ/private/var); product code is unchanged (#5849).
π¦ Dependencies
| Module | Version |
|---|---|
github.com/stacklok/toolhive-core |
v0.0.29 |
github.com/stacklok/toolhive-catalog |
v0.20260716.0 |
github/codeql-action |
7188fc3 |
golang.org/x/exp/jsonrpc2 |
9ea1abe |
Full commit log
What's Changed
- Add upstream identity to DCR credential cache key by @tgrunnagle in #5824
- Update github/codeql-action digest to 7188fc3 by @renovate[bot] in #5778
- Guard upstream-DCR HTTP calls against SSRF by @tgrunnagle in #5826
- Update module github.com/stacklok/toolhive-core to v0.0.29 by @renovate[bot] in #5840
- feat: migrate from mark3labs/mcp-go to toolhive-core/mcpcompat (go-sdk) by @JAORMX in #5729
- Update module github.com/stacklok/toolhive-catalog to v0.20260716.0 by @renovate[bot] in #5843
- Return HTTP 403 for authz-denied vMCP calls (#5827) by @JAORMX in #5841
- Update golang.org/x/exp/jsonrpc2 digest to 9ea1abe by @renovate[bot] in #5780
- Reconcile network isolation with network mode by @JAORMX in #5794
- Resolve temp dirs in plugin adapter tests by @jhrozek in #5849
- Add MCP 2026-07-28 revision classification and method vocabulary by @jhrozek in #5834
- Harden vMCP authz gate: single parse source and reserved-name check by @JAORMX in #5850
- Add RFC 8693 token exchange handler to the embedded AS by @jhrozek in #5822
- Follow list pagination cursors in vMCP capability discovery by @JAORMX in #5851
- Release v0.40.0 by @toolhive-release-app[bot] in #5855
Full Changelog: v0.39.0...v0.40.0