Repository navigation
Releases: stacklok/toolhive
Release list
v0.59.0
What's Changed
- Add Windows Claude Desktop credential helper by @stantheman0128 in #6516
- Fix stale Windows shim test and PATH comment by @aponcedeleonch in #6958
- Run release jobs after verify-release by @eleftherias in #6959
- Add Context7 ownership verification by @danbarr in #6962
- Enable TLS for operator-wide Redis defaults by @Sanskarzz in #6838
- Expand Context7 library configuration by @danbarr in #6963
- Require approval before creating a release tag by @eleftherias in #6961
- Re-check upstream DCR registrations while running by @aron-muon in #6948
- Add exchange grant storage with memory backend by @jhrozek in #6968
- Bump toolhive-core to v0.0.58 by @jerm-dro in #6971
- Add configured delegate client metadata by @jhrozek in #6952
- Replace removed catalog servers in examples by @danbarr in #6976
- Release v0.59.0 by @toolhive-release-app[bot] in #6977
Full Changelog: v0.58.0...v0.59.0
v0.58.0
What's Changed
- Add opt-in at+jwt typ for embedded AS access tokens by @jhrozek in #6942
- Refuse refresh grants whose upstream credential is dead by @tgrunnagle in #6930
- Stop serving delegate clients removed from config by @jhrozek in #6945
- Fix authserver test build on main by @jhrozek in #6950
- Rename embedded-auth ConfigMap ref helpers by @jhrozek in #6951
- Skip upstream identity capture when sub_id is off by @jhrozek in #6956
- Update k8s.io/utils digest to ca04ba5 by @renovate[bot] in #6933
- Release v0.58.0 by @toolhive-release-app[bot] in #6957
Full Changelog: v0.57.0...v0.58.0
v0.57.0
What's Changed
- Parse SKILL.md with maintained YAML fork by @rdimitrov in #6919
- Let delegate clients change policy on restart by @jhrozek in #6918
- Let embedders refuse refresh grants on dead upstreams by @tgrunnagle in #6902
- Mount workload auth secrets in inline mode by @hellouz818 in #6905
- Support authorization_details on token exchange by @jhrozek in #6921
- Reject request bodies on non-POST methods by @peppescg in #6806
- Add dcrConfig.registrationProbe with an authorization-endpoint strategy by @aron-muon in #6834
- Add opt-in upstream subject identifiers by @jhrozek in #6908
- Move remaining YAML parsing to go.yaml.in/yaml/v3 by @rdimitrov in #6920
- Classify MCPRemoteProxy pods by container readiness, not phase alone by @feiiiiii5 in #6765
- Decouple authserver identity from host auth types by @jhrozek in #6923
- test(vmcp): pin that the health path never opens a standalone GET stream by @jstar0 in #6520
- Wire OIDC transport flags into thv run auth middleware config by @7487 in #6529
- Fix vMCP incoming OIDC client secret resolution by @xianshujun in #6904
- Update docker images by @renovate[bot] in #6934
- Update issue triage model to Sonnet 5.5 by @eleftherias in #6943
- Read required environment variable prompts as a whole line by @feiiiiii5 in #6781
- Add backend-scoped vMCP authorization by @Sanskarzz in #6487
- Update github actions by @renovate[bot] in #6935
- Update go modules by @renovate[bot] in #6936
- Show upstream display name on consent page by @tgrunnagle in #6929
- Release v0.57.0 by @toolhive-release-app[bot] in #6947
New Contributors
- @7487 made their first contribution in #6529
- @xianshujun made their first contribution in #6904
Full Changelog: v0.56.0...v0.57.0
v0.56.0
What's Changed
- Add OSS Scanner audit configuration by @rdimitrov in #6874
- Make unit tests pass as root and without a container runtime by @rdimitrov in #6875
- Cover the embedded auth server in threat model by @jhrozek in #6879
- Add native Go fuzz targets for untrusted parsers by @rdimitrov in #6877
- Decode IPv4 in IPv4-compatible and SIIT addresses by @rdimitrov in #6878
- Let embedders skip consent for preauthorized clients by @jhrozek in #6882
- Cap DCR clients and expire unused ones after 24h by @tgrunnagle in #6863
- Expose DCR client cap and register rate limit in CRD by @tgrunnagle in #6867
- Enable Claude Code gateway model discovery by @jerm-dro in #6862
- Answer 401 when a token session holds no upstream access token by @alex-feel in #6846
- Verify row ownership in Redis upstream token read by @hellouz818 in #6876
- Add coverage for -32601 under HTTP error statuses by @hellouz818 in #6873
- Test client response posts across handlers by @jstar0 in #5885
- Fix field names in external-auth examples by @3nesdeniz in #6330
- Add auth server TLS listener and SPIFFE middleware by @jhrozek in #6843
- Start auth server TLS listener in vMCP by @jhrozek in #6891
- Explain LLM gateway model-discovery failures by @jerm-dro in #6884
- Fix Claude Desktop paths and managed check on Linux by @jerm-dro in #6883
- Release v0.56.0 by @toolhive-release-app[bot] in #6917
New Contributors
- @3nesdeniz made their first contribution in #6330
Full Changelog: v0.55.2...v0.56.0
v0.55.2
Security
Rootless Podman host-access endpoints blocked by the egress proxy (GHSA-2x65-h9w3-h7hc, Medium)
With network isolation on rootless Podman, a workload could reach host services through the Squid or Envoy egress proxy using host.containers.internal or the address it maps to. ToolHive's protected set only covered Docker's host names and bridge gateways, and Podman's host-access address is not necessarily a bridge gateway.
On Podman, ToolHive now reads the DNS sidecar's runtime-generated /etc/hosts at deployment. It adds every address mapped to host.containers.internal, host.docker.internal, or gateway.docker.internal to the protected set, alongside all bridge gateways. Both proxies block those names and addresses unless --allow-docker-gateway is set.
What changes for operators
- On Podman, deployment fails before the proxy or MCP container starts if
host.containers.internalis missing from the runtime's hosts file (for example withno_hosts = trueincontainers.conf), or if the hosts data cannot be read. This applies even with--allow-docker-gateway. - The protected set is a deployment-time snapshot. Redeploy workloads after changing Podman's host mappings, rootless networking mode, or bridge networks.
What's Changed
- Use postflight_steps for the thv Homebrew cask hook by @rdimitrov in #6870
- Update go modules to v0.0.57 by @renovate[bot] in #6869
- Release v0.55.2 by @toolhive-release-app[bot] in #6871
Full Changelog: v0.55.1...v0.55.2
v0.55.1
What's Changed
- Fix flaky ignore overlay tests from shared artifact dir by @rdimitrov in #6854
- Publish thv to Homebrew as a cask by @rdimitrov in #6859
- Fix Podman client creation with compat transport by @rdimitrov in #6860
- Drop Go patch pin, bump toolhive-catalog, stop e2e pings by @rdimitrov in #6866
- Release v0.55.1 by @toolhive-release-app[bot] in #6868
Full Changelog: v0.55.0...v0.55.1
v0.55.0
What's Changed
- Return release notes via structured output by @rdimitrov in #6826
- Bump x/net and x/text in the Go SDK module by @rdimitrov in #6828
- Add dcrConfig.rotationKey to re-register upstream DCR clients by @aron-muon in #6825
- Allow omitting scope on upstream token refresh by @hellouz818 in #6832
- Close terminated vMCP sessions instead of waiting for eviction by @hellouz818 in #6807
- Clarify session eviction cleanup guarantees by @JAORMX in #6833
- Expose group-based upstream filter via vMCP CRD by @hellouz818 in #6740
- Re-register DCR clients the upstream evicted by @peppescg in #6822
- Add TLS listener config and SPIFFE X.509 authority capability by @jhrozek in #6760
- Codify conventions stated in recent code reviews by @alex-feel in #6812
- Support Pi in LLM gateway setup by @jerm-dro in #6818
- Honor PI_CODING_AGENT_DIR for Pi MCP and skills by @jerm-dro in #6839
- Grant pods/attach only for stdio transport by @hellouz818 in #6841
- Add thv client connector for Claude Desktop by @jerm-dro in #6840
- Update github actions by @renovate[bot] in #6849
- Update go modules by @renovate[bot] in #6850
- Update golang.org/x/exp/jsonrpc2 digest to f0251eb by @renovate[bot] in #6848
- Update docker images by @renovate[bot] in #6851
- Fix codespell hits in vMCP resource validation by @rdimitrov in #6853
- Release v0.55.0 by @toolhive-release-app[bot] in #6855
Full Changelog: v0.54.0...v0.55.0
v0.54.0
What's Changed
- Update module github.com/stacklok/toolhive-catalog to v0.20261013.0 by @renovate[bot] in #6816
- Extract exact-ID decode from DecodeMessage by @jhrozek in #6820
- Add Pi coding agent as a supported MCP client by @danbarr in #6819
- Add SPIFFE file bundle source by @jhrozek in #6759
- Refresh upstream tokens when the ID token expires by @tgrunnagle in #6773
- Narrow OIDC referrer watches to ref changes by @Sriram-PR in #6706
- Fix lint in RSA client key validation by @rdimitrov in #6824
- Release v0.54.0 by @toolhive-release-app[bot] in #6823
New Contributors
- @Sriram-PR made their first contribution in #6706
Full Changelog: v0.53.0...v0.54.0
v0.53.0
🚀 Toolhive v0.53.0 is live!
This release adds group-based upstream selection to the vMCP embedded auth server, and stops the operator from acting on spec.permissionProfile as a security fix. It also makes vMCP keep a backend's valid tools when one of its items can't be decoded, and makes MCPRemoteProxy report config failures correctly.
🔄 Deprecations
MCPServer.spec.permissionProfileis deprecated and the Kubernetes operator now ignores it. The field still exists in thev1beta1CRD so existing manifests keep applying, but it never restricted pods in Kubernetes. UsepodTemplateSpecsecurity contexts andNetworkPolicyresources instead. MCPServers that set the field get aPermissionProfileUnsupportedWarning event. No removal version has been announced yet. (security fix, commit d5aa374)
🆕 New Features
- vMCP operators using the embedded auth server can set an upstream filter in
authserver-config.yaml. It picks which extra upstream providers each user goes through, based on group claims from the first upstream, so users skip OAuth legs for services they have no account on. The feature is opt-in and fails closed when the group claim is missing. CRD support follows in #6740. (#6739)
🐛 Bug Fixes
- The operator no longer passes
spec.permissionProfileto the runner as a profile name or file path. Before, a crafted value could make the operator read arbitrary local files. Theconfigmapprofile volume is no longer mounted, andthv export --format k8sno longer emits the field. MCPServers that set the field may roll their proxy pods once after upgrading. (d5aa374) - When a referenced config fails to resolve, MCPRemoteProxy now reports
Ready=Falsewith a message naming the failing handler and an up-to-dateobservedGeneration. Before, it could showPhase: Failedwhile still reporting a staleReady=True. (#6776) - vMCP now skips individual
tools/list,resources/list, resource-template and prompt items it cannot decode, and logs a warning naming the backend and the item. Before, one bad item hid all of that backend's capabilities. This applies to the Modern list path only; the Legacy path is tracked in #6814. (#6772) - Tools whose top-level schema
typeis a JSON Schema type array (for example["object","null"]) are now kept, with the schema passed through unchanged, because toolhive-core is bumped to v0.0.52. (#6815)
📦 Dependencies
| Module | Version |
|---|---|
github.com/stacklok/toolhive-core |
v0.0.52 |
ghcr.io/modelcontextprotocol/inspector (default thv inspector image) |
2.10.1 |
github.com/go-chi/chi/v5 |
v5.4.0 |
github.com/aws/aws-sdk-go-v2 |
v1.47.3 |
github.com/aws/aws-sdk-go-v2/config |
v1.33.9 |
github.com/aws/aws-sdk-go-v2/service/sts |
v1.51.4 |
github.com/pressly/goose/v3 |
v3.29.0 |
github.com/prometheus/common |
v0.72.1 |
github.com/onsi/ginkgo/v2 |
v2.33.1 |
github.com/alicebob/miniredis/v2 |
v2.40.0 |
golang.org/x/crypto |
v0.58.0 |
golang.org/x/mod |
v0.42.0 |
golang.org/x/net |
v0.61.0 |
golang.org/x/sync |
v0.24.0 |
golang.org/x/sys |
v0.49.0 |
golang.org/x/term |
v0.47.0 |
golang.org/x/exp/jsonrpc2 |
faecfb2 |
oras.land/oras-go/v2 |
v2.6.3 |
python (e2e test image) |
3.15-slim |
GitHub Actions (create-github-app-token, download-artifact, setup-node, upload-artifact, claude-code-action, codeql-action, goreleaser-action, kind-action) |
latest patch/minor |
👋 Welcome to our newest contributor: @feiiiiii5 🎉
Full commit log
What's Changed
- Update github actions by @renovate[bot] in #6775
- Add group-based upstream filter for vMCP auth by @hellouz818 in #6739
- Update docker images by @renovate[bot] in #6778
- Update golang.org/x/exp/jsonrpc2 digest to faecfb2 by @renovate[bot] in #6774
- Record config-handler failures on the MCPRemoteProxy status by @feiiiiii5 in #6776
- Update go modules by @renovate[bot] in #6777
- Skip undecodable items in Modern list responses by @reyortiz3 in #6772
- Bump toolhive-core to v0.0.52 by @reyortiz3 in #6815
- Release v0.53.0 by @toolhive-release-app[bot] in #6817
New Contributors
- @feiiiiii5 made their first contribution in #6776
Full Changelog: v0.52.0...v0.53.0
🔗 Full changelog: v0.52.0...v0.53.0
v0.52.0
🚀 Toolhive v0.52.0 is live!
This release adds TLS for Redis session storage (runtime and operator), makes thv llm setup and teardown safer by default, and fixes several authorization, OAuth and operator issues.
⚠️ Breaking Changes
thv llm teardownnow purges cached tokens by default — a full teardown deletes cached OIDC tokens and fails if cleanup fails; pass--keep-tokensto keep the old behavior (migration guide) (#6733)DCRCredentialStoregained a method — out-of-tree implementations ofpkg/authserver/storage.DCRCredentialStoreno longer compile until they addUpdateDCRCredentialsIfUnchanged(migration guide) (#6758)
Migration guide: thv llm teardown purges cached tokens by default
Affects CLI users and scripts that run thv llm teardown. Cleanup is local only: tokens are deleted from the secrets provider, not revoked at the identity provider.
Before
# Tokens survived teardown unless you opted in
thv llm teardown
thv llm teardown --purge-tokensAfter
# Full teardown (no configured tools remain) purges cached tokens
thv llm teardown
# Keep tokens for a later setup
thv llm teardown --keep-tokens
# Targeted teardown still keeps tokens; --purge-tokens deletes them even when other tools remain
thv llm teardown <tool> --purge-tokensMigration steps
- If a script relied on tokens surviving a full teardown so a later
thv llm setupcould skip re-authentication, add--keep-tokens. - Teardown now exits non-zero if the secrets provider is unavailable or token listing or deletion fails (these were warnings before). Handle the failure, or pass
--keep-tokensto skip the purge. --keep-tokensand--purge-tokensare mutually exclusive.- Go callers:
llm.Teardownhas new parameters andllm.PurgeTokensnow returns an error.
Migration guide: DCRCredentialStore gained a method
Affects only Go code outside this repository that implements DCRCredentialStore (including hand-written mocks). The built-in memory and Redis stores are already updated.
Before
type DCRCredentialStore interface {
StoreDCRCredentialsIfAbsent(...)
UpdateDCRCredentialsIfPresent(...)
// ...
}After
type DCRCredentialStore interface {
// ...existing methods...
UpdateDCRCredentialsIfUnchanged(ctx context.Context, creds *DCRCredentials, expected *DCRCredentials) error
}Migration steps
- Add
UpdateDCRCredentialsIfUnchanged(ctx, creds, expected)to your implementation. - Overwrite the row at
creds.Keyonly if the stored row still equalsexpected. - Return a wrapped
ErrNotFoundif the row is absent and the newErrDCRCredentialsChangedif it differs; write nothing in either case. - Reject a nil
expected, or one whoseKeydiffers fromcreds.Key.
PR: #6758
🆕 New Features
- Redis session storage supports TLS in the proxy runner, vMCP and their rate limiters, with system roots or a private CA bundle (#6731)
MCPServer,MCPRemoteProxyandVirtualMCPServeracceptspec.sessionStorage.tls, includingcaCertSecretReffor a private CA; a startup WARN is now logged when Redis session storage runs without TLS, so log-based alerting may fire for existing plaintext setups (#6767)thv llm setupnow configures Claude Code for one-hour prompt caching by default; re-run setup to pick it up, or use--short-prompt-cacheto opt out (#6515)
🐛 Bug Fixes
spec.secretsonMCPServeraccepts multiple keys of the same Secret; re-apply theoperator-crdschart (#6690)- The token-exchange issuer policy no longer rejects an omitted
allowMayActwith a wildcard delegate; re-apply theoperator-crdschart (#6532) - Config resources are deleted promptly once their last referrer goes away instead of lingering up to 30 seconds (#6768)
- Cedar policies can use extension claims from RFC 7662 introspection (such as
roles); policies that referenced these claims will now see real values, so review any that were written around them being absent (#6707) - Authz-filtered
tools/list,prompts/listandresources/listresponses keep the members the backend sent (including MCP 2026-07-28resultType), always carryCache-Control: private, no-store, and reject ambiguous duplicate or aliased annotation members (#6709) - The embedded auth server no longer cuts off slow upstream identity-provider token endpoints at 10 seconds, which could leave a revoked refresh token stored (#6755)
🧹 Misc
- Add a shared JWT claim string-array decoder; Cedar behavior is unchanged (#6738)
- Clarify priority-conflict documentation and strengthen regression coverage (#6716)
- Clarify operator Helm values descriptions (#6771)
- Reduce Podman network normalization complexity (#6809)
- Drop the ping step from the remote MCP server e2e test (#6766)
- Use exact version comments on artifact actions (#6761)
- Add alex-feel to MAINTAINERS (#6808)
📦 Dependencies
| Module | Version |
|---|---|
charm.land/bubbletea/v2 |
v2.1.0 |
github.com/aws/aws-sdk-go-v2 |
v1.47.2 |
github.com/aws/aws-sdk-go-v2/config |
v1.33.8 |
github.com/aws/aws-sdk-go-v2/service/sts |
v1.51.3 |
github.com/cenkalti/backoff/v7 |
v7.0.1 |
github.com/getsentry/sentry-go (+ otel, otel/otlp) |
v0.50.0 |
github.com/go-git/go-git/v5 |
v5.19.3 |
github.com/go-git/go-billy/v5 |
v5.9.2 |
github.com/Microsoft/go-winio |
v0.6.3 |
github.com/moby/moby/client |
v0.6.2 |
github.com/moby/moby/api |
v1.56.1 |
github.com/prometheus/common |
v0.72.0 |
github.com/redis/go-redis/v9 |
v9.23.0 |
github.com/shirou/gopsutil/v4 |
v4.26.9 |
github.com/spiffe/go-spiffe/v2 |
v2.9.0 |
github.com/stacklok/toolhive-catalog |
v0.20261005.0 |
github.com/stacklok/toolhive-core |
v0.0.51 |
github.com/tidwall/gjson |
v1.20.0 |
go.opentelemetry.io/otel (and SDK/exporters) |
v1.47.0 |
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp |
v0.72.0 |
modernc.org/sqlite |
v1.60.1 |
sigs.k8s.io/controller-runtime |
v0.25.2 |
ghcr.io/modelcontextprotocol/inspector |
2.9.0 |
anchore/sbom-action |
v0.24.3 |
anthropics/claude-code-action |
v1.0.241 |
Full commit log
What's Changed
- Guard token exchange may_act CEL by @kocaemre in #6532
- Preserve custom claims from RFC 7662 introspection by @lorenzozanee in #6707
- Clarify priority conflicts and strengthen regression coverage by @JAORMX in #6716
- fix(operator): allow multiple keys of one Secret in spec.secrets by @lightsabit in #6690
- Purge LLM tokens on full teardown by @danbarr in #6733
- Update docker images by @renovate[bot] in #6750
- Update github actions by @renovate[bot] in #6747
- Default Claude Code prompt cache to one hour by @Sanskarzz in #6515
- Add compare-and-set update for DCR credentials by @tgrunnagle in #6758
- Use exact version comments on artifact actions by @jhrozek in #6761
- Update go modules by @renovate[bot] in #6749
- Update go modules by @renovate[bot] in #6764
- Add TLS to Redis session storage by @Sanskarzz in #6731
- Drop ping from remote MCP server e2e test by @jhrozek in #6766
- Remove the 10s header timeout from the upstream IdP client by @alex-feel in #6755
- Preserve list result members in authz filters by @alex-feel in #6709
- Clarify operator Helm values descriptions by @danbarr in #6771
- Add operator support for Redis session storage TLS by @peppescg in #6767
- Add shared JWT claim string-array decoder by @hellouz818 in #6738
- Add alex-feel to MAINTAINERS by @jhrozek in #6808
- Unblock config deletion when referrers go away by @jhrozek in #6768
- Reduce Podman network normalization complexity by @ChrisJBurns in https://github.com/stacklok/toolhive/pull...