Releases: stacklok/toolhive
v0.26.1
What's Changed
- Make Cedar group entity type name configurable by @jhrozek in #5121
- Add authserver DCR discovery and config surface by @tgrunnagle in #5041
- fix(authserver): send scope explicitly on upstream token refresh by @dallinstevens in #5096
- test(e2e): add all-client LLM gateway e2e matrix + fix secret provider bugs by @yrobla in #5116
- Add --tls-skip-verify flag to thv llm setup, config set, and proxy start by @yrobla in #5136
- Auto-detect Docker Desktop socket on Linux by @samuv in #5122
- Consolidate ToolApplyConfig and LLMApplyConfig into pkg/llmgateway by @yrobla in #5138
- Include nested files when resolving git skills by @samuv in #5139
- Release v0.26.1 by @toolhive-release-app[bot] in #5140
New Contributors
- @dallinstevens made their first contribution in #5096
Full Changelog: v0.26.0...v0.26.1
v0.26.0
What's Changed
- Drop legacy ToolHive registry format references from docs by @rdimitrov in #5087
- Update module github.com/stacklok/toolhive-catalog to v0.20260428.0 by @renovate[bot] in #5080
- Update module github.com/shirou/gopsutil/v4 to v4.26.3 by @renovate[bot] in #5061
- Add interactive TUI dashboard for managing MCP servers by @peppescg in #4680
- Introduce LLMClientApp type to remove xcode from MCP API swagger enum by @yrobla in #5081
- Strengthen tool detection with binary presence check by @yrobla in #5083
- Add awsSts auth type support to vMCP by @tgrunnagle in #5019
- Update module github.com/moby/moby/client to v0.4.1 by @renovate[bot] in #5059
- thv llm: complete setup/teardown orchestration by @yrobla in #5068
- Align REGISTRY.md with configYAML-only MCPRegistry spec by @rdimitrov in #5088
- ci(release): mint GitHub App installation token instead of RELEASE_TOKEN PAT by @Nashon-Steffen in #5093
- Wire MCPRemoteProxy resourceOverrides.proxyDeployment.imagePullSecrets by @JAORMX in #5103
- Extract shared OAuthTokenSource into pkg/auth/tokensource by @yrobla in #5090
- fix(llm): use correct binary name for VS Code Insiders detection by @yrobla in #5109
- Preserve user fields in EmbeddingServer podTemplateSpec merge by @JAORMX in #5104
- Add explicit imagePullSecrets field to VirtualMCPServer by @JAORMX in #5107
- Add explicit imagePullSecrets field to MCPRegistry by @JAORMX in #5106
- Move llm setup/teardown orchestration to pkg/llm by @yrobla in #5112
- Add missing encoding/json import to virtualmcpserver_deployment.go by @jhrozek in #5114
- fix(test): use require instead of assert in TestBuildServerConfig to prevent nil panic by @wucm667 in #5098
- Detect imagePullSecrets drift on proxy Deployments by @jhrozek in #5113
- Add operator-level defaultImagePullSecrets across all controllers by @JAORMX in #5105
- Fix non-expiring upstream token handling and storage TTL bugs by @jhrozek in #5092
- Allow OAuth2 upstreams to omit userInfo config by @tgrunnagle in #5094
- Release v0.26.0 by @toolhive-release-app[bot] in #5131
New Contributors
- @wucm667 made their first contribution in #5098
- @toolhive-release-app[bot] made their first contribution in #5131
Full Changelog: v0.25.0...v0.26.0
v0.25.0
What's Changed
- Add thv llm command group with config types and management commands by @yrobla in #5032
- Improvements for the vmcp e2e test infrastructure by @yrobla in #5026
- pkg/llm: implement OIDC token source and thv llm token command by @yrobla in #5033
- llm: extract shared OIDC config, move business logic to pkg/llm, add E2E tests by @yrobla in #5049
- Expose hook for embedder-driven MCP elicitation by @JAORMX in #4934
- Treat 401/403 from auth-configured backends as healthy by @JAORMX in #4935
- Update dockerfile template base images by @renovate[bot] in #5058
- Update anthropics/claude-code-action digest to 567fe95 by @renovate[bot] in #5053
- Add localhost reverse proxy for LLM gateway by @yrobla in #5035
- pkg/llm: fix withPreemptiveRefresh composition and stale _AT on rotation by @yrobla in #5052
- Rename pkg/oauth to pkg/oauthproto and move DCR primitives by @tgrunnagle in #5036
- Apply request version to tag-less skill OCI install ref by @samuv in #5078
- Add
thv registry convertcommand by @rdimitrov in #5071 - Strip Content-Length when wrapping tool filter response by @danbarr in #5077
- Drop legacy registry format support by @rdimitrov in #5067
- Update aws-sdk-go-v2 monorepo by @renovate[bot] in #5057
- Update module golang.ngrok.com/ngrok/v2 to v2.1.4 by @renovate[bot] in #5062
- Classify packager errors as 400 in skill build handler by @samuv in #5076
- Add tool adapter registry and per-tool LLM gateway implementations by @yrobla in #5065
- Add pkg/oauth grant-helper primitives by @jhrozek in #5045
- Release v0.25.0 by @stacklokbot in #5084
Full Changelog: v0.24.1...v0.25.0
v0.24.1
What's Changed
- Bump releaseo_version input to v0.0.4 by @ChrisJBurns in #5007
- Honor --debug flag in vmcp by @jhrozek in #5008
- Fix Cedar upstream-claim evaluation on VirtualMCPServer by @jhrozek in #5002
- Add shared OAuth constants and expose ExchangeConfig fields by @jhrozek in #5003
- Fix MCPRegistry probe port and bump registry image to v1.3.0 by @rdimitrov in #5020
- Add JWT/OIDC and Redis session storage vMCP CLI e2e tests by @yrobla in #4998
- Update module github.com/stacklok/toolhive-catalog to v0.20260423.0 by @renovate[bot] in #5021
- Classify OCI pull errors and fall back to git for skills content API by @samuv in #5014
- Document scalability limits and constraints by @yrobla in #5025
- Introduce MutateAndPatchSpec and adopt across spec-patch sites by @jhrozek in #5004
- Gate proxyrunner StatefulSet apply by MCPServer generation by @JAORMX in #5024
- Release v0.24.1 by @stacklokbot in #5034
Full Changelog: v0.24.0...v0.24.1
v0.24.0
What's Changed
- Compare CRDs against the last release tag, not the rendered chart by @ChrisJBurns in #4987
- Enforce v1beta1 API stability by @ChrisJBurns in #4991
- Re-run api-compat workflow on label changes by @ChrisJBurns in #4993
- Add no-op companion for API Compatibility required check by @ChrisJBurns in #4995
- Introduce MutateAndPatchStatus helper for status writes by @jhrozek in #4942
- test(e2e): add vmcp optimizer tier e2e tests by @yrobla in #4963
- Mark local skill builds with an OCI descriptor annotation by @samuv in #5000
- Enable thv vmcp commands and add local vMCP architecture docs by @yrobla in #5001
- Update module github.com/stacklok/toolhive-catalog to v0.20260422.0 by @renovate[bot] in #4999
- Patch MCPServer spec instead of Update by @jhrozek in #4914
- Release v0.24.0 by @stacklokbot in #5006
Full Changelog: v0.23.1...v0.24.0
v0.23.1
What's Changed
- Propagate auth errors through stale cache fallback by @reyortiz3 in #4981
- Unify docs-website release pipeline: new assets + retire dispatch chain by @rdimitrov in #4982
- Add advisory CRD schema compatibility CI check by @ChrisJBurns in #4980
- Release v0.23.1 by @stacklokbot in #4985
Full Changelog: v0.23.0...v0.23.1
v0.23.0
🚀 Toolhive v0.23.0 is live!
A milestone release: ToolHive's CRD API graduates from v1alpha1 to v1beta1, signaling API stability — with a zero-downtime upgrade path that keeps existing v1alpha1 resources working untouched. Two targeted operator bug fixes round out the release.
🔄 Deprecations
toolhive.stacklok.dev/v1alpha1deprecated in favour oftoolhive.stacklok.dev/v1beta1— will be removed in a future release (#4849). Both versions are served simultaneously; existing resources continue to work untouched.kubectlnow prints a deprecation warning on every access to av1alpha1resource — migrate manifests toapiVersion: toolhive.stacklok.dev/v1beta1at your own pace.
Migration guide: CRD graduation to v1beta1
All 12 ToolHive CRD kinds (MCPServer, MCPGroup, MCPRegistry, MCPRemoteProxy, MCPToolConfig, MCPExternalAuthConfig, VirtualMCPServer, VirtualMCPGroup, VirtualMCPCompositeToolDefinition, and their peers) are now served at both v1alpha1 and v1beta1. The schemas are identical — only the version string differs — so there is no data-format migration to perform.
Who is affected: anyone with manifests pinned to apiVersion: toolhive.stacklok.dev/v1alpha1.
Before
apiVersion: toolhive.stacklok.dev/v1alpha1
kind: MCPServer
metadata:
name: my-server
spec:
# ...After
apiVersion: toolhive.stacklok.dev/v1beta1
kind: MCPServer
metadata:
name: my-server
spec:
# ...Migration steps
- Upgrade the operator and CRDs charts to v0.23.0 — no resource deletion or recreation is required. All existing
v1alpha1resources survive the upgrade with unchanged Deployment UIDs. - Update your manifests to use
apiVersion: toolhive.stacklok.dev/v1beta1and re-apply them. Kubernetes stores the new version in etcd; the object'sstatus.storedVersionswill advance to includev1beta1. - Once all stored objects have been re-applied at
v1beta1, a future release will drop thev1alpha1entry from the CRDs. Migrate at your convenience before then.
🆕 New Features
- CRDs now serve
toolhive.stacklok.dev/v1beta1as the storage version, withv1alpha1kept served-and-deprecated for zero-downtime upgrades (#4849). - Server-scoped Cedar policies like
resource in MCP::"<server-name>"now work — resource entities (Tool, Prompt, Resource) carry the MCP server as a parent UID so Cedar'sinoperator can traverse the hierarchy (#4965).
🐛 Bug Fixes
MCPExternalAuthConfigupstream providers withredirectUriomitted now get the documented{resourceUrl}/oauth/callbackdefault applied by the operator, instead of failing at runtime withredirect_uri is required. Applies to bothMCPServerandVirtualMCPServerflows (#4905).
Full commit log
What's Changed
- Set MCP parent on resource entities for server-scoped policies by @jhrozek in #4965
- Default redirectUri on upstream providers as documented in CRD by @tgrunnagle in #4905
- Graduate CRDs from v1alpha1 to v1beta1 by @ChrisJBurns in #4849
- Release v0.23.0 by @stacklokbot in #4973
🔗 Full changelog: v0.22.0...v0.23.0
v0.22.0
🚀 Toolhive v0.22.0 is live!
This release lays the groundwork for the new thv vmcp command suite (serve / validate / init with optional TEI-backed semantic optimization — currently hidden while it stabilizes), expands identity coverage for Cedar authorization across Entra, Okta, Auth0, and Keycloak token shapes, and brings a wave of quality-of-life improvements to the skills, audit, secrets, and operator flows.
🆕 New Features
- Upstream OAuth providers now accept
additionalAuthorizationParams, enabling Google'saccess_type=offlineand similar flows that require refresh tokens (#4862). - Cedar group extraction handles dual-claim (Entra
roles+groups) and dot-notation nested claims (realm_access.rolesfor Keycloak, URL-style claims for Auth0/Okta) (#4911). - Resource entities in Cedar now expose a
nameattribute, letting policies match on the real (unsanitized) resource URI (#4907). POST /api/v1beta/workloadsaccepts optionalregistryandserverfields, so clients can create a workload from a registry entry in a single call without fetching metadata first (#4872).- New
thv secret list --systemandthv secret delete --systemexpose and clean up the internal__thv_*tokens (registry OAuth, workload auth, enterprise login) (#4910). - Workloads stopped by a policy violation now surface a first-class
policy_stoppedstatus (🚫 inthv list/thv status), and restarts are gated by the active policy (#4857). thv skill install <skill>defaults to only installing into clients actually present on the system, with a clearer 400 error when no clients are detected (#4899).- Empty parent directories are cleaned up when the last skill for a client is uninstalled (#4895).
- Proxy audit middleware now distinguishes JSON-RPC application errors from HTTP-level success, logging them as
outcome=application_errorwithjsonrpc_error_code/messagemetadata (enabled by default; togglable viadetectApplicationErrors) (#4709). - Initial
thv vmcpcommand scaffolding landed (currently hidden from--help):servewith zero-config quick mode via--group,validate, andinitfor generating starter configs, plus optional Tier 1/Tier 2 semantic optimization backed by an on-demand HuggingFace TEI container (#4891, #4900, #4903, #4912, #4913, #4939, #4940).
🐛 Bug Fixes
- vMCPs whose backends all require upstream OAuth no longer get stuck in
PhaseFailed— unauthenticated backends are now treated as routable and report CRD statusunauthenticated(#4866). partialFailureMode: best_effortnow actually works — the validator was rejecting the CRD-defined enum value (#4865).- Misconfigured
OIDCConfigRef.Audiencevalues that didn't match the embedded auth server'sResourceURLnow fail fast with a clear reconciliation error instead of silently dropping every request at token validation (#4904). thv skill install io.github.stacklok/<skill>(and similar qualifiednamespace/namereferences) now fall back to the registry catalog when OCI pull fails, and first-time installs no longer fail to acquire the file lock when the skills directory doesn't yet exist (#4841).- Deployment drift checks now account for embedded-auth env vars, so operator-generated
MCPServer/MCPRemoteProxydeployments stop being incorrectly flagged as drifted (#4878). - Failed TEI container starts in
thv vmcp serveare now cleaned up instead of leaking a running container, andEmbeddingImageis defaulted consistently alongsideEmbeddingModel(#4948). - OCI skill pull failures now return
502 Bad Gateway(matching the git path) instead of400 Bad Request, and registry entries without an installable package return422 Unprocessable Entityinstead of404 Not Found(#4956, #4841).
🧹 Misc
- Default builder images bumped to current stable releases:
golang:1.26-alpine,python:3.14-slim,node:24-alpine. Existing--runtime-imageor config overrides are unaffected (#4955, #4953, #4954). - Cedar entity factory refactored so dynamic
THVGroupentities no longer clobber static ones loaded fromentities_json— parent relationships are now passed as variadicEntityUIDvalues (#4901). pkg/skills/skillsvcmonolithic file split into 13 per-concern files for production and matching test files — pure reorganisation, no API changes (#4947).thv vmcpcommand kept hidden from--helpand shell completion while it stabilizes (#4967).- Image verification mode now threaded through
WorkloadServicerather than hardcoded at two call sites (#4966). - Additional tests for Cedar group-based authorization,
pkg/vmcp/cli, and e2e coverage of the newthv vmcpcommand (#4898, #4941, #4964). - Copilot review follow-ups on the embedding manager, plus a finish-up on
defaultTEIImagerename (#4938, #4957). - Documentation updates: operator
authServerRefarchitecture, category-based Redis ACLs, README, and the new502 Bad GatewayOpenAPI annotation for skill install (#4780, #4915, #4946, #4960).
📦 Dependencies
| Module | Version |
|---|---|
github.com/moby/spdystream |
v0.5.1 |
github.com/go-git/go-git/v5 |
v5.18.0 |
github.com/sigstore/timestamp-authority/v2 |
v2.0.6 |
github.com/stacklok/toolhive-catalog |
v0.20260421.0 |
alpine (Docker) |
v3.23.4 |
github/codeql-action |
digest 95e58e9 |
anthropics/claude-code-action |
digest 5d5c10a |
actions/cache |
digest 27d5ce7 |
👋 Welcome to our newest contributor: @SAY-5 🎉
Full commit log
What's Changed
- Remove empty parent directories on skill uninstall by @samuv in #4895
- Only install skills for clients detected on the system by @samuv in #4899
- Detect JSON-RPC application errors in proxy audit middleware by @gmogmzGithub in #4709
- Update operator architecture docs for authServerRef by @tgrunnagle in #4780
- Add AdditionalAuthorizationParams to upstream OAuth configs by @jhrozek in #4862
- Replace groups parameter with variadic parents on entity factory by @jhrozek in #4901
- Fix partialFailureMode validator to accept CRD enum values by @jhrozek in #4865
- Bump github.com/moby/spdystream from 0.5.0 to 0.5.1 by @dependabot[bot] in #4906
- Validate audience matches resourceUrl for embedded auth server by @tgrunnagle in #4904
- Extract vMCP serve/validate logic into pkg/vmcp/cli/ by @yrobla in #4891
- Add name attribute alias on Resource entities by @jhrozek in #4907
- Update module github.com/stacklok/toolhive-catalog to v0.20260417.0 by @renovate[bot] in #4909
- Add unit tests for pkg/vmcp/cli serve and validate logic by @yrobla in #4898
- Add pkg/vmcp/cli/init.go for vMCP config scaffolding by @yrobla in #4903
- Add thv vmcp serve and thv vmcp validate subcommands by @yrobla in #4900
- Update README by @danbarr in #4915
- Treat unauthenticated backends as routable in vMCP health by @lorr1 in #4866
- Bump github.com/go-git/go-git/v5 from 5.17.2 to 5.18.0 by @dependabot[bot] in #4921
- Add EmbeddingServiceManager for TEI container lifecycle by @yrobla in #4912
- Fix skill install for qualified namespace/name references and missing par...
v0.21.0
🚀 ToolHive v0.21.0 is live!
This release removes deprecated CRD fields ahead of v1beta1 API promotion, adds Cedar role-based authorization support, introduces new registry API endpoints, and fixes several bugs including OTLP endpoint path encoding and operator reconcile loops.
⚠️ Breaking Changes
- Inline
telemetryfield removed from MCPServer and MCPRemoteProxy — manifests usingspec.telemetrymust migrate totelemetryConfigRefwith an MCPTelemetryConfig resource (migration guide) - Inline
oidcConfigfield removed from MCPServer and MCPRemoteProxy — manifests usingspec.oidcConfigmust migrate tooidcConfigRefwith an MCPOIDCConfig resource (migration guide) - Inline
incomingAuth.oidcConfigremoved from VirtualMCPServer — manifests usingspec.incomingAuth.oidcConfigmust migrate tooidcConfigRef(migration guide) config.groupReffallback andexternal_auth_config_refenum removed — VirtualMCPServer now requiresspec.groupRefand the snake_case enum value is gone (migration guide)thv group runno longer supports registry-based groups — usethv group createandthv run --groupinstead (migration guide)
Migration guide: Inline telemetry field removal
Affects any MCPServer, MCPRemoteProxy, or VirtualMCPServer manifest using the inline spec.telemetry block. The TelemetryConfig and OpenTelemetryConfig CRD types are also removed.
Before
apiVersion: toolhive.stacklok.com/v1alpha1
kind: MCPServer
metadata:
name: my-server
spec:
telemetry:
openTelemetry:
enabled: true
endpoint: "http://otel-collector:4318"
serviceName: "my-server"After
apiVersion: toolhive.stacklok.com/v1alpha1
kind: MCPTelemetryConfig
metadata:
name: my-telemetry
spec:
openTelemetry:
enabled: true
endpoint: "http://otel-collector:4318"
---
apiVersion: toolhive.stacklok.com/v1alpha1
kind: MCPServer
metadata:
name: my-server
spec:
telemetryConfigRef:
name: my-telemetry
serviceName: "my-server"Migration steps
- Create an
MCPTelemetryConfigresource with your existing telemetry settings - Replace
spec.telemetrywithspec.telemetryConfigRef.namepointing to the new resource - Apply both resources — the MCPTelemetryConfig can be shared across multiple servers
Migration guide: Inline oidcConfig removal (MCPServer / MCPRemoteProxy)
Affects any MCPServer or MCPRemoteProxy manifest using the inline spec.oidcConfig field.
Before
apiVersion: toolhive.stacklok.com/v1alpha1
kind: MCPServer
metadata:
name: my-server
spec:
oidcConfig:
type: kubernetes
kubernetes:
issuer: "https://idp.example.com"
audience: "my-audience"After
apiVersion: toolhive.stacklok.com/v1alpha1
kind: MCPOIDCConfig
metadata:
name: my-oidc
spec:
type: kubernetesServiceAccount
kubernetesServiceAccount:
issuer: "https://idp.example.com"
---
apiVersion: toolhive.stacklok.com/v1alpha1
kind: MCPServer
metadata:
name: my-server
spec:
oidcConfigRef:
name: my-oidc
audience: "my-audience"Migration steps
- Create an
MCPOIDCConfigresource with your existing OIDC settings - Replace
spec.oidcConfigwithspec.oidcConfigRef.namepointing to the new resource - Apply both resources — the MCPOIDCConfig can be shared across multiple servers
Migration guide: Inline oidcConfig removal (VirtualMCPServer)
Affects any VirtualMCPServer manifest using spec.incomingAuth.oidcConfig.
Before
apiVersion: toolhive.stacklok.com/v1alpha1
kind: VirtualMCPServer
metadata:
name: my-vmcp
spec:
incomingAuth:
type: oidc
oidcConfig:
type: kubernetes
kubernetes:
issuer: "https://idp.example.com"
audience: "my-audience"After
apiVersion: toolhive.stacklok.com/v1alpha1
kind: MCPOIDCConfig
metadata:
name: my-oidc
spec:
type: kubernetesServiceAccount
kubernetesServiceAccount:
issuer: "https://idp.example.com"
---
apiVersion: toolhive.stacklok.com/v1alpha1
kind: VirtualMCPServer
metadata:
name: my-vmcp
spec:
incomingAuth:
type: oidc
oidcConfigRef:
name: my-oidc
audience: "my-audience"Migration steps
- Create an
MCPOIDCConfigresource with your existing OIDC settings - Replace
spec.incomingAuth.oidcConfigwithspec.incomingAuth.oidcConfigRef.name - Apply both resources
Migration guide: config.groupRef fallback and enum removal
Affects VirtualMCPServer manifests that relied on spec.config.group as a fallback (instead of spec.groupRef) or used the snake_case external_auth_config_ref enum value.
Before
apiVersion: toolhive.stacklok.com/v1alpha1
kind: VirtualMCPServer
metadata:
name: my-vmcp
spec:
config:
group: "my-group"
outgoingAuth:
backends:
- type: external_auth_config_ref
name: my-authAfter
apiVersion: toolhive.stacklok.com/v1alpha1
kind: VirtualMCPServer
metadata:
name: my-vmcp
spec:
groupRef:
name: my-group
outgoingAuth:
backends:
- type: externalAuthConfigRef
name: my-authMigration steps
- Move
spec.config.grouptospec.groupRef.name(now required) - Replace
external_auth_config_refwithexternalAuthConfigRefinoutgoingAuth.backends[*].type - Apply the updated manifest
Migration guide: Registry-based group deployment removed
Affects users running thv group run to deploy server groups defined in registry JSON files.
Before
thv group run my-registry-groupAfter
thv group create my-group
thv run --group my-group server1
thv run --group my-group server2Migration steps
- Create a runtime group with
thv group create <name> - Run each server individually with
thv run --group <name> <server> - Runtime groups (
thv group create/list/rm) and the groups API are unaffected
🆕 New Features
- Cedar authorizer now supports a
RoleClaimNamefield for extracting IdP roles (e.g. Entra IDrolesclaim) separately from group claims (#4847) - New
oidcConfigRef.resourceUrlfield lets users specify the public URL for OAuth protected resource metadata when servers are exposed via Ingress (#4855) - New
GET /api/v1beta/skills/contentendpoint retrieves SKILL.md content from OCI, git, and registry sources without installing the skill (#4810) - New v0.1 server browse endpoints (
GET /registry/{name}/v0.1/serversandGET /registry/{name}/v0.1/servers/{serverName}/versions/latest) matching upstream MCP registry spec (#4871) - Cedar authorizer now stores
serverNameto scope policies per-MCP-server, enabling rules likeresource in MCP::"<server>"(#4861) - Introduce Starlark script engine package (
pkg/script/) as the foundation for vMCP code mode — internal only, not yet wired to the server (#4748)
🐛 Bug Fixes
- OTLP endpoint URLs with custom paths (Langfuse, LangSmith) no longer get URL-encoded slashes, fixing trace export to these backends (#4815)
- Fix VirtualMCPServer reconcile loop (~10 updates/sec) caused by non-deterministic env var ordering with 4+ MCPExternalAuthConfigs (#4783)
- OIDC discovery failure no longer blocks the local key provider in embedded auth server scenarios (#4774)
thv registry loginno longer re-prompts the browser OAuth flow after the user has already authenticated (#4893)- Skills API
?limit=Nwhere N > 200 now correctly clamps to 200 instead of silently falling back to 50 (#4802) ValidatingCache.Geton an expired entry now returns the freshly loaded value instead of(zero, false), eliminating unnecessary retries (#4798)- Restored vMCP session metadata is now persisted to Redis, preventing stale per-backend session IDs in cross-pod scenarios ([#...
v0.20.0
🚀 Toolhive v0.20.0 is live!
This release graduates groupRef to a typed struct across all CRDs, adds stateless streamable-HTTP proxy support, brings TelemetryConfigRef to VirtualMCPServer, and expands the skills ecosystem with 10 new client integrations.
⚠️ Breaking Changes
- GroupRef changed from bare string to typed struct — existing manifests with
groupRef: my-groupwill fail CRD validation; update togroupRef: { name: my-group }and re-apply (migration guide) protectedResourceAllowPrivateIP/jwksAllowPrivateIPfield separation — users who setjwksAllowPrivateIP: trueand relied on the (unintended) side effect of it also enabling private IPs for the protected resource endpoint must now set both fields explicitly (migration guide)
Migration guide: GroupRef
Affected resources: MCPServer, MCPRemoteProxy, MCPServerEntry, VirtualMCPServer — every user deploying these CRDs with a groupRef value.
Before
spec:
groupRef: my-groupAfter
spec:
groupRef:
name: my-groupMigration steps
- Update all YAML manifests, GitOps pipelines, and Helm values to use the new struct format.
- For VirtualMCPServer, move
spec.config.groupReftospec.groupRef(the old path still works viaResolveGroupName()but is deprecated). - Apply the new CRDs:
kubectl apply -f deploy/charts/operator-crds/files/crds/ - Delete and re-create affected resources (existing etcd objects have the old string format and will fail re-validation):
kubectl get mcpservers -A -o yaml > mcpservers-backup.yaml # Edit backup to use new format, then: kubectl delete mcpservers --all -A kubectl apply -f mcpservers-backup.yaml # Repeat for mcpremoteproxies, mcpserverentries, virtualmcpservers
Migration guide: protectedResourceAllowPrivateIP
Affected users: Those who set jwksAllowPrivateIP: true and relied on it also enabling private IPs for the protected resource endpoint (due to a converter bug).
Before
spec:
config:
incomingAuth:
oidc:
jwksAllowPrivateIP: true
# protectedResourceAllowPrivateIP was silently derived from jwksAllowPrivateIPAfter
spec:
config:
incomingAuth:
oidc:
jwksAllowPrivateIP: true
protectedResourceAllowPrivateIP: true # must be set explicitlyMigration steps
- If your protected resource endpoint is on a private IP and you had only
jwksAllowPrivateIP: true, addprotectedResourceAllowPrivateIP: trueto your OIDC config (inline, MCPOIDCConfig, or ConfigMap). - No manifest format changes are required — existing YAML is structurally valid.
- The failure mode is immediate and obvious (connection refused), not silent degradation.
PR: #4784
🔄 Deprecations
spec.config.groupRefon VirtualMCPServer deprecated in favour ofspec.groupRef(typed struct) — will be removed in a future release (#4809)spec.config.telemetryon VirtualMCPServer deprecated in favour ofspec.telemetryConfigRef, which enables Kubernetes-native secret references and per-server overrides — will be removed in a future release (#4801)
🆕 New Features
- Stateless streamable-HTTP remote server support via
--statelessflag — proxies MCP servers that only accept POST requests, returning spec-compliant 405 for GET/HEAD/DELETE (#4515) - Non-standard OAuth scope parameter support via
--remote-auth-scope-param-name— enables authentication with providers like Slack that useuser_scopeinstead ofscope(#4712) - TelemetryConfigRef for VirtualMCPServer — reference shared
MCPTelemetryConfigresources with CEL validation, config hash tracking, and CA bundle support, consistent with MCPServer and MCPRemoteProxy (#4801) - OpenAPI spec for v0.1 skills registry endpoints — browsing endpoints now documented at
/api/openapi.json(#4800) - New MCP client support: Kimi Code CLI (#4788), Factory.ai (Droid) (#4795)
- Skill-supporting clients: VS Code / VS Code Insiders (#4773), Goose / Gemini CLI / Amp (#4799), Kiro (#4803), Cline / Roo Code / Windsurf / Mistral Vibe / Trae / Antigravity (#4804)
🐛 Bug Fixes
protectedResourceAllowPrivateIPwas silently ignored on VirtualMCPServer — the field is now propagated through the OIDC resolver and converter correctly (#4784)- Skill install failure when multiple clients share the same directory — deduplication helper prevents duplicate filesystem operations (#4796)
- Health check timeout silently capped at 5s — removed redundant
context.WithTimeoutthat overrodeTOOLHIVE_HEALTH_CHECK_PING_TIMEOUT(#4791) - VirtualMCPServer rejected tokens from its own auth server when clients omitted the optional RFC 8707
resourceparameter — now defaults to the sole allowed audience (#4805)
🔒 Security
- Updated
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttpfrom v1.41.0 to v1.43.0 to address CVE-2026-39882 — OTLP HTTP exporters read full response bodies without a size cap, enabling memory exhaustion (#4683)
🧹 Misc
- Remove redundant
storage.LoadfromNotifyBackendExpired(#4779) - Add regression guard for auth context propagation through
Close()(#4781) - Add
Audienceto authserver test client fixture (#4814) - Isolate
TestParseGitReferencefrom ambient env (#4813) - Add ConfigMap content assertions to vMCP telemetry integration tests (#4807)
- Add more Claude rules (#4782)
📦 Dependencies
| Module | Version |
|---|---|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp |
v1.43.0 |
helm/helm |
v3.20.2 |
thv-registry-api image |
v1.1.1 |
👋 Welcome to our newest contributor: @gmogmzGithub 🎉
Full commit log
What's Changed
- Add Kimi Code CLI as a supported MCP client by @samuv in #4788
- Support stateless streamable-HTTP remote servers by @gkatz2 in #4515
- Remove redundant storage.Load from NotifyBackendExpired by @yrobla in #4779
- Add more claude rules by @yrobla in #4782
- Add VS Code and VS Code Insiders as skill-supporting clients by @samuv in #4773
- Fix skill install failure when multiple clients share the same directory by @samuv in #4796
- Add Factory.ai as a supported MCP client by @samuv in #4795
- Add regression guard for auth context propagation through Close() by @yrobla in #4781
- Propagate protectedResourceAllowPrivateIP through OIDC resolver and converter by @ChrisJBurns in #4784
- Clean up health check dead code and timeout by @gkatz2 in #4791
- Add Goose, Gemini CLI, and Amp as skill-supporting clients by @samuv in #4799
- Add OpenAPI annotations to v0.1 skills registry endpoints by @samuv in #4800
- Add Kiro as a skill-supporting client by @samuv in #4803
- Update module go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp to v1.43.0 [SECURITY] by @renovate[bot] in #4683
- Bump go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp from 1.41.0 to 1.43.0 by @dependabot[bot] in #4684
- Update dependency helm/helm to v3.20.2 by @renovate[bot] in #4756
- Add Cline, Roo Code, Windsurf, Mistral Vibe, Trae, and Antigravity as skill-supporting clients by @samuv in #4804
- Add TelemetryConfigRef support to VirtualMCPServer CRD by @ChrisJBurns in #4801
- Update registry API image to v1.1.1 by @rdimitrov in #4806
- Grant default
audwhenresourceis absent by @blkt in #4805 - Add
Audienceto authserver test client fixture by @blkt in https://gi...