Skip to content

Update module github.com/stacklok/toolhive to v0.20.0#122

Open
renovate[bot] wants to merge 1 commit intomainfrom
renovate/github.com-stacklok-toolhive-0.x
Open

Update module github.com/stacklok/toolhive to v0.20.0#122
renovate[bot] wants to merge 1 commit intomainfrom
renovate/github.com-stacklok-toolhive-0.x

Conversation

@renovate
Copy link
Copy Markdown
Contributor

@renovate renovate bot commented Apr 14, 2026

This PR contains the following updates:

Package Change Age Confidence
github.com/stacklok/toolhive v0.19.0v0.20.0 age confidence

Release Notes

stacklok/toolhive (github.com/stacklok/toolhive)

v0.20.0

Compare Source

ToolHive v0.20.0 Release Notes

Released: 2026-04-14
Full Changelog: v0.19.0...v0.20.0


Breaking Changes

1. GroupRef changed from bare string to typed struct (#​4809)

Impact: All users deploying MCPServer, MCPRemoteProxy, MCPServerEntry, or VirtualMCPServer CRDs with a groupRef field.

The groupRef field on all four CRD types changed from a bare string to a typed MCPGroupRef struct:

# Before (v0.19.0)
groupRef: my-group

# After (v0.20.0)
groupRef:
  name: my-group

Existing resources with the old format will fail validation against the new CRD schema after upgrading.

See Migration Guide: GroupRef below.

2. protectedResourceAllowPrivateIP / jwksAllowPrivateIP field separation (#​4784)

Impact: Users who set jwksAllowPrivateIP: true and relied on the (unintended) side effect of it also enabling private IPs for the protected resource endpoint.

Previously, setting jwksAllowPrivateIP: true silently also enabled private IPs for the protected resource endpoint due to a mapping bug in the converter. After this fix, the two fields are independent. Users who need both must now set both fields explicitly.


Deprecations

1. spec.config.groupRef on VirtualMCPServer (#​4809)

The inline string path spec.config.groupRef is deprecated in favor of the new top-level spec.groupRef struct field. The deprecated path still works via ResolveGroupName() but should be migrated.

2. Inline spec.config.telemetry on VirtualMCPServer (#​4801)

Inline telemetry configuration via spec.config.telemetry is deprecated in favor of spec.telemetryConfigRef, which references shared MCPTelemetryConfig resources. The inline field continues to work, but the ref approach enables Kubernetes-native secret references for OTLP auth headers, CA bundle ConfigMap references, and per-server serviceName overrides.


New Features

Stateless streamable-HTTP remote server support (#​4515)

Adds --stateless flag to thv run for proxying MCP servers that only accept POST requests (no SSE streams). When set:

  • GET, HEAD, and DELETE requests return 405 at the proxy instead of being forwarded
  • Health checks use a POST-based JSON-RPC ping instead of SSE
thv run https://example.com/mcp --name my-server --transport streamable-http --stateless
Non-standard OAuth scope parameter support (#​4712)

Adds --remote-auth-scope-param-name CLI flag to override the query parameter name used for scopes in the OAuth authorization URL. This enables authentication with providers like Slack that use non-standard scope parameters (e.g., user_scope instead of scope).

thv run https://mcp.slack.com/mcp \
  --name slack \
  --transport streamable-http \
  --remote-auth-client-id <client-id> \
  --remote-auth-callback-port 3118 \
  --remote-auth-authorize-url "https://slack.com/oauth/v2_user/authorize" \
  --remote-auth-token-url "https://slack.com/api/oauth.v2.user.access" \
  --remote-auth-scope-param-name user_scope
TelemetryConfigRef for VirtualMCPServer (#​4801)

VirtualMCPServer now supports spec.telemetryConfigRef to reference shared MCPTelemetryConfig resources, consistent with MCPServer and MCPRemoteProxy. Features:

  • CEL validation enforcing mutual exclusivity with inline config.telemetry
  • TelemetryConfigHash in status for change detection and rolling updates
  • MCPTelemetryConfig watch triggers reconciliation on config changes
  • CA bundle volumes and sensitive header env vars in deployment builder
apiVersion: toolhive.stacklok.com/v1alpha1
kind: VirtualMCPServer
metadata:
  name: my-vmcp
spec:
  telemetryConfigRef:
    name: shared-telemetry-config
New MCP client support
Client PR Type
Kimi Code CLI #​4788 MCP client
Factory.ai (Droid) #​4795 MCP client
New skill-supporting clients
Client PR Skill paths
VS Code / VS Code Insiders #​4773 ~/.copilot/skills/, <project>/.github/skills/
Goose, Gemini CLI, Amp #​4799 ~/.agents/skills/, <project>/.agents/skills/
Kiro #​4803 ~/.kiro/skills/, <project>/.kiro/skills/
Cline, Roo Code, Windsurf, Mistral Vibe, Trae, Antigravity #​4804 Various native paths per client
OpenAPI spec for skills registry endpoints (#​4800)

The v0.1 skills browsing endpoints now appear in the OpenAPI spec at /api/openapi.json:

  • GET /registry/{registryName}/v0.1/x/dev.toolhive/skills
  • GET /registry/{registryName}/v0.1/x/dev.toolhive/skills/{namespace}/{skillName}

Bug Fixes

protectedResourceAllowPrivateIP was a no-op on VirtualMCPServer (#​4784)

The protectedResourceAllowPrivateIP CRD field was defined but never propagated through the OIDC resolver, making it silently ignored. Additionally, the converter incorrectly mapped it from jwksAllowPrivateIP. Both issues are now fixed.

Note: The field remains a no-op for MCPServer and MCPRemoteProxy (tracked in #​4787).

Skill install failure when clients share directories (#​4796)

VS Code and VS Code Insiders both use ~/.copilot/skills/ as their skills path. Installing without --clients expanded to all clients, and the second client targeting the same directory failed. A deduplication helper now prevents duplicate filesystem operations while still recording all clients in the database.

Health check timeout silently capped at 5s (#​4791)

A hardcoded context.WithTimeout(ctx, 5*time.Second) in checkMCPStatus silently capped TOOLHIVE_HEALTH_CHECK_PING_TIMEOUT at 5 seconds, regardless of the configured value. The redundant timeout is removed since MCPPinger implementations enforce their own timeouts. Also removes two dead zero-value guards that were unreachable.

VirtualMCPServer rejected tokens from its own auth server (#​4805)

When clients omitted the optional RFC 8707 resource parameter, the token handler issued tokens with an empty aud claim. The OIDC validator then rejected these tokens because it requires a matching audience. Now, when AllowedAudiences contains exactly one entry and no resource parameter is present, the handler defaults to granting that audience.


Security

OTEL HTTP exporter memory exhaustion fix (#​4683)

Updated go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp from v1.41.0 to v1.43.0 to address CVE-2026-39882 — a vulnerability where OTLP HTTP exporters read full HTTP response bodies into memory without a size cap, enabling memory exhaustion when the collector endpoint is attacker-controlled or MitM'd.


Dependency Updates

Package Change PR
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.41.0 → v1.43.0 #​4683, #​4684
helm/helm → v3.20.2 #​4756
thv-registry-api image v1.0.1 → v1.1.1 #​4806

Internal / Refactoring

Change PR
Remove redundant storage.Load from NotifyBackendExpired #​4779
Regression guard for auth context propagation through Close() #​4781
Add Audience to authserver test client fixture #​4814
Isolate TestParseGitReference from ambient env #​4813
Add ConfigMap content assertions to vMCP telemetry integration tests #​4807
Add more Claude rules #​4782

Migration Guides

Migration Guide: GroupRef

Affected resources: MCPServer, MCPRemoteProxy, MCPServerEntry, VirtualMCPServer

Steps:

  1. Update all YAML manifests to use the new struct format:

    # Before
    spec:
      groupRef: my-group
    
    # After
    spec:
      groupRef:
        name: my-group
  2. For VirtualMCPServer, move spec.config.groupRef to the new top-level spec.groupRef field:

    # Before
    spec:
      config:
        groupRef: my-group
    
    # After (preferred)
    spec:
      groupRef:
        name: my-group

    The deprecated spec.config.groupRef string path still works via ResolveGroupName() but should be migrated.

  3. Apply the new CRDs:

    kubectl apply -f deploy/charts/operator-crds/files/crds/
  4. Delete and re-apply affected resources:

    # For each affected resource type
    kubectl get mcpservers -A -o yaml > mcpservers-backup.yaml
    # Edit the backup to use new format, then:
    kubectl delete mcpservers --all -A
    kubectl apply -f mcpservers-backup.yaml

    Repeat for mcpremoteproxies, mcpserverentries, and virtualmcpservers.

Migration Guide: protectedResourceAllowPrivateIP

Affected users: Those who set jwksAllowPrivateIP: true and relied on it also enabling private IPs for the protected resource endpoint.

Before (v0.19.0): Setting jwksAllowPrivateIP: true unintentionally also enabled private IPs for the protected resource endpoint.

After (v0.20.0): The two fields are independent. If you need private IPs for both JWKS and protected resource endpoints, set both explicitly:

spec:
  config:
    incomingAuth:
      oidc:
        jwksAllowPrivateIP: true
        protectedResourceAllowPrivateIP: true
Migration Guide: TelemetryConfigRef (recommended)

Affected users: VirtualMCPServer users who want to share telemetry configuration across resources.

# 1. Create a shared MCPTelemetryConfig
apiVersion: toolhive.stacklok.com/v1alpha1
kind: MCPTelemetryConfig
metadata:
  name: shared-otel
spec:
  endpoint: https://otel-collector.monitoring:4318
  serviceName: my-vmcp

# 2. Reference it from VirtualMCPServer
apiVersion: toolhive.stacklok.com/v1alpha1
kind: VirtualMCPServer
metadata:
  name: my-vmcp
spec:
  telemetryConfigRef:
    name: shared-otel
  # Remove spec.config.telemetry if present — CEL validation
  # enforces mutual exclusivity

New Contributors

What's Changed

New Contributors

Full Changelog: stacklok/toolhive@v0.19.0...v0.20.0


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate
Copy link
Copy Markdown
Contributor Author

renovate bot commented Apr 14, 2026

ℹ️ Artifact update notice

File name: go.mod

In order to perform the update(s) described in the table above, Renovate ran the go get command, which resulted in the following additional change(s):

  • 5 additional dependencies were updated

Details:

Package Change
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.41.0 -> v1.43.0
go.opentelemetry.io/proto/otlp v1.9.0 -> v1.10.0
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 -> v0.0.0-20260401024825-9d38bb4040a9
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d -> v0.0.0-20260401024825-9d38bb4040a9
google.golang.org/grpc v1.79.3 -> v1.80.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants