Update stacklok/toolhive to v0.42.0 - #1086
Conversation
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @renovate[bot]'s task in 12m 41s —— View job Upstream release docs: toolhive v0.42.0Pushed as commit Phases
Summary of changes
Notes for reviewers
|
- Add guide for the new thv ai-plugin surface (Claude Code, Codex) - Add sync, upgrade, and signature verification sections to the skills management guide behind the experimental TOOLHIVE_SKILLS_LOCK_ENABLED gate - Document that Cedar authorization now evaluates the post-mutation request - Sweep removed config-CRD status fields (referencingWorkloads, REFERENCES column) out of K8s guides; replace with workload-side queries Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Claude finished @renovate[bot]'s task in 6m 29s —— View job Editorial review of upstream release docs: toolhive v0.42.0Pushed as commit
Findings and fixes1. 2. 3. Not changedThe other four files ( |
- ai-plugins: default build tag is <name>, not <name>:<version> - skills-management: distinguish sync exit codes 1, 2, and 3 - migrate-to-v1beta1: reflect that MCPWebhookConfig and MCPTelemetryConfig never had referenceCount, and MCPTelemetryConfig never had the printer column Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
|
||
| The `status.referencingServers` field (a plain `[]string`) has been replaced | ||
| with `status.referencingWorkloads` (an array of `{kind, name}` objects) on four | ||
| The `status.referencingServers` field (a plain `[]string`) was replaced with |
There was a problem hiding this comment.
This isn't true anymore as status.referencingWorkloads was removed this release. @copilot
Co-authored-by: ChrisJBurns <29541485+ChrisJBurns@users.noreply.github.com>
|
@claude Remove the Sigstore signing work for skills. We’re going to add the documentation when the flag is removed. |
|
Claude finished @samuv's task in 3m 54s —— View job Removed the experimental skills signing docs ✅Pushed as commit
What changedRemoved everything this PR added to
The file is now byte-identical to Left untouched (auto-generated)The CLI reference pages are auto-generated from the ToolHive source and per the repo's
If you'd like those removed from the site too before an upstream release makes that happen, that needs an upstream change (e.g. marking the commands |
The lock-file, sync, upgrade, and Sigstore signature verification content is gated behind TOOLHIVE_SKILLS_LOCK_ENABLED. Remove it until the flag is dropped and the feature is documented as generally available. Co-authored-by: Samuele V <4377202+samuv@users.noreply.github.com>
456d1bb
|
@claude the new ai plugins page was added with zero inbound links. This breaks the user journey; consider where this fits in the current journey and make sure the progression is maintained. Also assess spots that refer to the ToolHive CLI as managing just MCP servers and skills that need to be updated to include plugins. The insertion of the page was too tactical and not holistic. |
|
Claude finished @danbarr's task in 3m 4s —— View job Integrate the AI plugins page into the user journey ✅Pushed as commit
What was wrong
…yet ChangesRestored forward momentum (inbound links):
Updated CLI-scoped descriptions that named only MCP servers and skills:
Scope noteI deliberately left the platform-wide taglines ("run, govern, and connect MCP servers and agent skills" in |
The AI-tool plugins guide was reachable only from the sidebar, with no inbound prose links, so the CLI journey skipped past it. Add forward links from the CLI index, skills management, and client configuration pages, and update CLI-scoped descriptions that named only MCP servers and skills to include plugins. Co-authored-by: Dan Barr <6922515+danbarr@users.noreply.github.com>
6997454
This PR contains the following updates:
v0.41.0→v0.42.0After this PR opens,
.github/workflows/upstream-release-docs.ymladds source-verified content edits for the new release. Forstacklok/toolhive, the same workflow also syncs reference assets (CLI help, Swagger) and regenerates the CRD MDX pages.Release Notes
stacklok/toolhive (stacklok/toolhive)
v0.42.0Compare Source
🚀 Toolhive v0.42.0 is live!
AI-tool plugin management goes end to end —
thv ai-plugingains a full CLI, REST API, and registry catalog — and the skills supply chain gets Sigstore signature verification at install, sync, and upgrade time. Alongside that, a large batch of MCP dual-era correctness fixes lands: multiple clients can finally share a stdio server, and vMCP stops flapping between the Modern and Legacy revisions.status.referencingWorkloadsandstatus.referenceCount(and theReferencesprinter column) are gone from all six config CRDs; replace any automation reading them with a workload field query (migration guide)pkg/telemetry/providerswas deleted and two long-publishedoptimizerdecconstants were removed (migration guide)Migration guide: Config CRD status fields removed
Who is affected: anyone reading
status.referencingWorkloadsorstatus.referenceCountfromMCPOIDCConfig,MCPAuthzConfig,MCPExternalAuthConfig,MCPToolConfig,MCPWebhookConfig, orMCPTelemetryConfig—kubectlusers relying on theREFERENCEScolumn, scripts and GitOps assertions usingjsonpath/jqon those paths, Chainsaw/kuttl tests, kube-state-metrics custom-resource-state configs and the dashboards built on them, and Go code reading.Status.ReferencingWorkloads/.Status.ReferenceCount.MCPWebhookConfigandMCPTelemetryConfigonly ever hadreferencingWorkloads.MCPTelemetryConfignever had aReferencesprinter column, so itskubectl getoutput is unchanged.Upgrade safety: these were derived values computed from workload specs — the source of truth (
spec.*ConfigRefon workloads) is untouched, so nothing unrecoverable is lost. Applying the new schema does not rewrite or reject existing stored objects; residual values stay inert in etcd until each object's status is next written. No storage-version bump, no CRD delete/recreate, no migration job. Deletion protection is unchanged — every config controller still recomputes referrers live at deletion time and setsDeletionBlocked=Truewith reasonReferencedByWorkloads.Before
After
To list referrers, query the workloads by their config-ref:
The reference paths per config kind, exactly as the operator's own indexers define them:
MCPOIDCConfigspec.oidcConfigRef.name;spec.incomingAuth.oidcConfigRef.name(vMCP)MCPAuthzConfigspec.authzConfigRef.name;spec.incomingAuth.authzConfigRef.name(vMCP)MCPTelemetryConfigspec.telemetryConfigRef.nameMCPExternalAuthConfigspec.externalAuthConfigRef.name, orspec.authServerRef.namewhenspec.authServerRef.kind == "MCPExternalAuthConfig"MCPToolConfigspec.toolConfigRef.nameMCPWebhookConfigspec.webhookConfigRef.nameNote
kubectl --field-selectorwill not work for these paths — the operator's indexes are controller-runtime cache indexes, not API-server field selectors. Use-o json | jqor-o custom-columns.Migration steps
kubectl get mcpoidcconfigs,mcpauthzconfigs,mcpexternalauthconfigs,mcptoolconfigs,mcpwebhookconfigs,mcptelemetryconfigs -A -o json > /tmp/thv-config-refs-pre-0.42.jsonreferenceCount,referencingWorkloads, and theReferences/REFERENCEScolumn — shell scripts,kubectl wait --for=jsonpath=, Chainsaw/kuttl assertions, Argo CD/Flux health checks, kube-state-metrics configs, Grafana panels, Kyverno/Gatekeeper rules.kubectl -n NS get mcpoidcconfig my-oidc -o jsonpath='{.status.conditions[?(@.type=="DeletionBlocked")].message}'helm upgradetheoperator-crdschart, then theoperatorchart. No pre/post hooks needed.kubectl -n toolhive-system get mcpoidcconfigshowsNAME SOURCE VALID AGE, and deletion of a referenced config still leaves it withDeletionBlocked=True..Status.ReferencingWorkloads/.Status.ReferenceCountreads. TheWorkloadReferencetype (Kind,Name) is still exported if you want to keep your own list shape.PR: #5631 — completes the cleanup tracked in #5607
Migration guide: Cedar policy now sees the post-mutation request
Who is affected: only workloads configured with at least one mutating webhook and either Cedar authorization or any consumer of audit / telemetry / usage metrics. Both are shipped, supported, non-mutually-exclusive configurations —
thv run --webhook-config <file with a mutating: entry> --authz-config <file>, orMCPWebhookConfig.spec.mutatingin the operator. Workloads with no mutating webhook see zero change; the republish is gated on the body actually having changed.What was wrong:
ParsingMiddlewareparses the request body once and refuses to parse again. The mutating webhook replacedr.Bodybut passed the request through unchanged, so Cedar evaluated policy against the tool name and arguments that arrived while the backend executed the ones that ran. The audit half was reachable in the default configuration: the event type andtarget.nameresolve through the parsed-request holder regardless ofincludeRequestData(which defaults tofalse), so the audit trail named a request that never executed. Telemetry and usage metrics drifted the same way.Security framing, stated precisely: before v0.42.0, a client could reach a tool or argument set Cedar would have denied by sending a permitted request shape that the webhook rewrote into a forbidden one. A second bug narrowed this in practice:
r.ContentLengthwas not refreshed alongsider.Body, so a mutation that shrank the body failed at the reverse proxy and one that grew it was truncated into invalid JSON. The bypass was live for length-preserving rewrites — which is exactly case/format normalization, and a webhook can pad JSON whitespace to hold length constant. That staleContent-Lengthis also fixed here.Before
After
Migration steps
--webhook-configwith amutating:entry (orMCPWebhookConfig.spec.mutating). If not, stop — no action needed.method,params.name, and/orparams.arguments.MCP::Tool::"<name>") and everywhen { context.arg_* }clause. Policies that were passing only because they never saw the rewrite will now deny, and vice versa.typeortarget.name— for mutated requests those values change on upgrade.Gaps this deliberately does not close, all documented rather than fixed:
includeRequestData: true, the recorded request payload is still the pre-mutation body (audit readsr.Bodybefore the webhook), so event type/target name are post-mutation while the payload is not.Mcp-Method/Mcp-Nameheaders forwarded to the backend still name the original tool. A conformant Modern backend rejects the mismatch, so it fails closed — but a mutating webhook should not rename tools on the Modern path.ParsingMiddlewareand still decide against the request as received, so--toolsfiltering remains bypassable by a webhook rename. Tracked in #6134.PR: #6136 — Fixes #6133
Migration guide: Recovered panics are no longer logged
This is an unintended regression, not a design decision. It is called out here because it costs you diagnostics silently, and a one-line fix is expected in a patch release.
Who is affected: any operator who relies on ToolHive's logs to diagnose a recovered HTTP panic — including log-based alerts, log-derived metrics, and support bundles. Everyone running without Sentry configured (the default) is affected most.
What changed:
pkg/recoverybecame a thin shim overtoolhive-core/recovery. Core'sMiddlewarerecovers panics silently unless a logger is injected viaWithLogger, and ToolHive's shim passes onlyWithPanicHandler. The OTel span error recording and Sentry issue reporting are genuinely preserved — same span status (codes.Error,"panic recovered"), same sanitization, same raw value to Sentry, same ordering — but theslog.Errorline and its stack trace are gone, and no other middleware picks them up.Before (v0.41.0)
After (v0.42.0)
Migration steps
Panic recovered, they will stop firing. Do not interpret the silence as "no panics" — re-point them at the 500-response rate or at Sentry until the log line returns.ReportPanicstill sends the raw panic value, so panics remain visible as Sentry Issues with full context.RecordErrorplus an error status, so OTel-based panic detection keeps working.msg="panic recovered"withpanic,method,path, andstackattributes) rather than the old single formatted string, so write any new log parser against that shape.PR: #6145
Migration guide: Go API changes
Who is affected: only out-of-tree Go code importing ToolHive packages. No CLI, REST API, or CRD surface changes here, and no in-tree caller is affected.
pkg/telemetry/providerswas deleted (#6146)The package and its
/otlpand/prometheussubpackages were removed and consumed fromtoolhive-coreinstead. The graduation is verbatim — every non-test file is byte-identical apart from two self-referential import paths — so all 12 options (WithServiceName,WithServiceVersion,WithOTLPEndpoint,WithHeaders,WithInsecure,WithCACertPath,WithTracingEnabled,WithMetricsEnabled,WithSamplingRate,WithEnablePrometheusMetricsPath,WithCustomAttributes,WithExtraSpanProcessors) plusNewCompositeProvider,ProviderOption, andCompositeProviderkeep identical names and signatures. Nothing about emitted telemetry changes — resource attributes, service-name defaulting, OTLP exporter/TLS config, and Prometheus exporter registration all behave as before.Before
After
Two
optimizerdecconstants were removed (#6175)pkg/vmcp/session/optimizerdecno longer exportsCallToolArgToolNameorCallToolArgParameters. Both have been part of the published API since v0.15.0. They existed to read thecall_tooltarget out of a raw arguments map, a pattern that is now known-unsafe:encoding/jsonfalls back to case-insensitive field matching, so a map index and a struct decode resolve different key sets.Before
After
registry.Providergained three methods (#6135)ListAvailablePlugins(),GetPlugin(namespace, name), andSearchPlugins(query)were added to the interface. Implementations that embedregistry.BaseProviderpick up no-op defaults and need no change; anything satisfying the old method set directly will no longer compile.Migration: embed
registry.BaseProviderin your provider struct, or implement the three methods.🔄 Deprecations
pkg/audit's MCP event constants,LevelAudit, andNewAuditLoggerare now transitional aliases forgithub.com/stacklok/toolhive-core/auditand will be removed once the migration's cleanup wave rewrites imports per subtree — prefer thetoolhive-core/auditsymbols in new code (#6148)🆕 New Features
thv ai-plugincommand group —build,validate,push,install,list,info,uninstall, plus local build management viabuildsandbuilds remove— targeting Claude Code and Codex (#5782)/api/v1beta/plugins(10 endpoints) with a matching Go HTTP client inpkg/plugins/client, so the CLI, API, and external tooling share one contract (#5782)thv ai-plugin install <name>now resolves a plain name against the configured registry instead of failing with a 404 hint, and new catalog routes let you browse and search plugins in a registry (#6135)provenance:on first use and rejecting unsigned artifacts unless you pass--allow-unsigned(#6129)thv skill syncre-verifies each managed skill's stored Sigstore bundle offline against the lock file's recorded identity, treating a failed re-verification as drift so a CI gate catches signature changes exactly like content changes (#6131)thv skill upgraderefuses to move a skill to an artifact signed by a different identity — or to an unsigned one — reportingsigner-change-blockedunless you explicitly rotate trust with--allow-signer-change(#6132)The skills signing features above are all behind the experimental
TOOLHIVE_SKILLS_LOCK_ENABLEDgate and apply only to project-scoped installs. With the gate unset,thv skill installbehaves exactly as in v0.41.0. Note that git (gitsign) provenance is recorded asprovisional: truebecause the embedded Rekor transparency-log proof is not yet validated — signing time is checked only against the Fulcio certificate's own ~10-minute validity window. OCI provenance is not provisional.🐛 Bug Fixes
duplicate "initialize" received, which also unblocks vMCP aggregating stdio backends (#6153)initializeon a live connection behind the transparent proxy now receives a fresh session instead of a hard failure, because the proxy no longer forwards a session ID oninitialize(#6152)github-mcp-serverv1.6.0 no longer oscillate between the Modern and Legacy revisions and fail roughly half their health checks — a Modern promotion must now win a confirmingserver/discoverprobe rather than trusting the negotiated version alone (#6158)io.modelcontextprotocol/logLevel_metakey that replaced the removedlogging/setLevelRPC (#6140)_meta(trace ids, custom fields) onresources/readresults, matching what the Modern path already delivered (#6180)find_tool'stool_keywordsinput now actually affects results instead of being decoded and dropped, and it drives the lexical BM25 arm whiletool_descriptiondrives semantic matching (#6124)call_toolnow accepts the common LLM malformation wheretool_nameis nested insideparameters, and a genuinely missingtool_nameproduces an error that states the expected shape and lists the parameter names received (#6150)server.jsonunder%LOCALAPPDATA%are now protected with an explicit DACL granting only the ToolHive user and SYSTEM, and are ownership-validated before being trusted — POSIX mode bits are advisory on NTFS, so any local account with Modify could previously rewrite thenpipe://discovery URL and redirect the next MCP client (#5951)call_tooltarget through the same decoder dispatch uses, closing three case-sensitivity divergences that could skip a policy check or drop arguments (#6175)🧹 Misc
pkg/telemetry/providers(~2,900 LOC) is deleted in favour of the verbatim graduation intoolhive-core, with no change to emitted telemetry (#6146)pkg/recoverybecomes a thin shim overtoolhive-core/recovery, keeping ToolHive's OTel and Sentry wiring through a panic-handler hook (#6145)toolhive-core's semconv preset instead of a local literal; the boundaries are unchanged (#6144)LevelAudit, andNewAuditLoggerbecome aliases overtoolhive-core/auditwith byte-identical values, so the audit wire format is untouched (#6148)ida-pro-mcpe2e image by digest after an upstream rebuild pulled in the breaking mcp Python SDK 2.0.0, and addedtest/e2e/images/**to the lifecycle suite's trigger filter so an image change can no longer skip the tests that consume it (#6159)mcp-server-timee2e image by digest for the same upstream breakage, unblocking the proxy suites (#6160)timeout waiting for process kube-apiserver to stopflake — 32 of the job's last 51 failures — by awaiting manager shutdown before tearing down envtest (#6179)📦 Dependencies
github.com/stacklok/toolhive-coregithub.com/stacklok/toolhive-cataloggithub.com/tailscale/hujsonb80ff77coverallsapp/github-action8d6379egithub/codeql-actionf205ea1anthropics/claude-code-actiontoolhive-corewas bumped across #6144, #6146, and #6180 rather than by a dependency PR; v0.0.38 also carries transitive bumps to aws-sdk-go-v2, go-containerregistry, moby/client, prometheus, and otel.👋 Welcome to our newest contributor: @Tanguille 🎉
Full commit log
What's Changed
New Contributors
Full Changelog: stacklok/toolhive@v0.41.0...v0.42.0
🔗 Full changelog: stacklok/toolhive@v0.41.0...v0.42.0
Configuration
📅 Schedule: (in timezone America/New_York)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Never, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.
Docs update for
toolhivev0.42.0At a glance
stacklok/toolhivev0.41.0→v0.42.0Summary of changes
docs/toolhive/guides-cli/ai-plugins.mdxforthe new
thv ai-pluginsurface (build, validate, push, install, list, info,uninstall, builds), including the manifest format, Claude Code / Codex
install paths, and troubleshooting.
sidebars.ts.docs/toolhive/guides-cli/skills-management.mdxwith three newsections covering the experimental lock file: pin-and-reconcile with
thv skill sync, upgrades withthv skill upgrade, and Sigstore signatureverification (
--allow-unsigned,--allow-signer-change, coveragedifferences between OCI and Git installs). Added a matching troubleshooting
entry.
docs/toolhive/guides-cli/webhooks.mdxdocumenting that Cedar policies,audit events, telemetry, and usage metrics see the post-mutation request,
plus the new 400/500 fail-closed responses and the tool-filter and header
gaps to be aware of.
(
status.referencingWorkloads,status.referenceCount, and theREFERENCESprinter column) out of three K8s guides and theMCPAuthzConfigCRD intro, replacing them with workload-sidejqquerieswhere a "which workloads reference this?" pattern was needed. Updated the
CRD intro at the source (
scripts/lib/crd-intros.mjs) and synced thegenerated
mcpauthzconfig.mdx.referencingServers/referencingWorkloadssection ofdocs/toolhive/guides-k8s/migrate-to-v1beta1.mdxso readers of that migration guide learn that both fields are now gone and
see the current workload-query pattern.
Run cost
How this PR was built
Two Claude Opus sessions run per release: a generation pass
(
upstream-release-docsskill, 6 phases) followed by a fresh-context editorial pass (
docs-review). Prettier/ESLintauto-fixes are applied after.
Auto-synced paths — do not hand-edit these in review:
static/api-specs/docs/toolhive/reference/cli/(toolhive only)docs/toolhive/reference/crds/If a "Gaps needing human context" section is present above,
each entry includes a paste-ready Helper prompt for local
Claude a reviewer can use to resolve the gap.