-
Notifications
You must be signed in to change notification settings - Fork 201
Comparing changes
Open a pull request
base repository: stacklok/toolhive
base: v0.13.0
head repository: stacklok/toolhive
compare: v0.13.1
- 12 commits
- 71 files changed
- 13 contributors
Commits on Mar 27, 2026
-
Update diagrams and links in README (#4397)
* Refresh diagrams and favicon Signed-off-by: Dan Barr <6922515+danbarr@users.noreply.github.com> * Update README links Signed-off-by: Dan Barr <6922515+danbarr@users.noreply.github.com> --------- Signed-off-by: Dan Barr <6922515+danbarr@users.noreply.github.com> Co-authored-by: Dan Barr <6922515+danbarr@users.noreply.github.com>
Configuration menu - View commit details
-
Copy full SHA for bc24877 - Browse repository at this point
Copy the full SHA bc24877View commit details -
Add edited trigger to PR size labeler workflow (#4398)
- Re-run the workflow when the submitter edits their PR description with the justification. Signed-off-by: Dan Barr <6922515+danbarr@users.noreply.github.com> Co-authored-by: Dan Barr <6922515+danbarr@users.noreply.github.com>
Configuration menu - View commit details
-
Copy full SHA for 9ee7873 - Browse repository at this point
Copy the full SHA 9ee7873View commit details -
Fix macOS symlink test failures and upgrade phonenumbers dependency (#…
…4399) On macOS, t.TempDir() returns paths under /var/folders which is a symlink to /private/var. This caused two test failures: - skillsvc tests failed because the skill extractor rejects paths containing symlinks; fix by resolving via EvalSymlinks using the existing tempDir(t) helper - health_test unix socket test failed because the resolved path exceeded macOS's 104-char socket path limit; fix by using os.MkdirTemp with a short prefix Also upgrades github.com/nyaruka/phonenumbers from v1.1.6 to v1.6.12 to resolve GHSA-fmjh-f678-cv3x (Medium). Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for e52f3e9 - Browse repository at this point
Copy the full SHA e52f3e9View commit details -
Inject Redis session storage config into vMCP ConfigMap (#4387)
Add SessionStorageConfig to pkg/vmcp/config.Config and populate it in the VirtualMCPServer converter when spec.sessionStorage.provider is "redis". This allows vMCP pods to discover Redis connection parameters (address, db, keyPrefix) at startup via the existing config injection path. The Redis password is excluded from the config type and is injected separately as the THV_SESSION_REDIS_PASSWORD environment variable by the deployment builder. Closes: #4214 Co-authored-by: taskbot <taskbot@users.noreply.github.com>
Configuration menu - View commit details
-
Copy full SHA for 3561c5d - Browse repository at this point
Copy the full SHA 3561c5dView commit details -
fix: make experimental MCP server initialization non-fatal to thv ser…
…ve (#4393) Make experimental MCP server initialization non-fatal to thv serve Move mcpserver.New() inside the goroutine so that a failure in MCP server creation (e.g. registry authentication error) only terminates the goroutine instead of crashing the entire thv serve process. The main HTTP API server continues running normally. Fixes #4392 Made-with: Cursor
Configuration menu - View commit details
-
Copy full SHA for e1ade3c - Browse repository at this point
Copy the full SHA e1ade3cView commit details -
Add tests for horizontal scaling operator behaviors (#4388)
* Inject Redis session storage config into vMCP ConfigMap Add SessionStorageConfig to pkg/vmcp/config.Config and populate it in the VirtualMCPServer converter when spec.sessionStorage.provider is "redis". This allows vMCP pods to discover Redis connection parameters (address, db, keyPrefix) at startup via the existing config injection path. The Redis password is excluded from the config type and is injected separately as the THV_SESSION_REDIS_PASSWORD environment variable by the deployment builder. Closes: #4214 * Add tests for horizontal scaling operator behaviors Unit tests (controllers package): - TestConfigMapContent_SessionStorage: verifies that ensureVmcpConfigConfigMap produces a ConfigMap YAML with the sessionStorage section populated when provider=redis, and absent when nil or memory. - TestDeploymentForVirtualMCPServer_WithRedisPassword: verifies that deploymentForVirtualMCPServer injects THV_SESSION_REDIS_PASSWORD as a SecretKeyRef env var and never as a plaintext value. Integration tests (envtest with real CRDs + controller loop): - MCPServer: ScalingConfig (backend_replicas + session_redis) is written to the RunConfig ConfigMap when backendReplicas and Redis sessionStorage are set; omitted when absent. - VirtualMCPServer: spec.replicas is reflected in Deployment.Spec.Replicas; nil replicas produces a nil Deployment replicas field for HPA compatibility. E2E tests (Kind cluster via thv-operator-e2e-test-run): - VirtualMCPServer created with replicas=2 runs 2 ready pods and sets SessionStorageWarning condition when no Redis is configured. - Scale lifecycle (1→2→1): verifies Deployment replicas update in-place, 2 pods come up, SessionStorageWarning fires on scale-up and clears on scale-down. Closes: #4220 Fix ignored AddToScheme errors in unit tests Replace `_ = *.AddToScheme(scheme)` with `require.NoError(t, *.AddToScheme(scheme))` in virtualmcpserver_deployment_test.go and virtualmcpserver_vmcpconfig_test.go so that scheme registration failures cause an immediate, clear test failure rather than a confusing error later with a partially configured scheme. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix HPA-compat integration test: use spec change to trigger reconciliation Annotation changes do not increment metadata.generation on Kubernetes resources. The previous trigger used `vmcp.Annotations["test/trigger-reconcile"] = "true"`, which left generation unchanged, so `triggerGeneration = vmcp.Generation + 1` was always one ahead of ObservedGeneration and the Eventually timed out. Fix: trigger via `vmcp.Spec.ServiceType = "ClusterIP"` (the default value, semantically a no-op) which IS a spec change and DOES increment Generation. After the Update, controller-runtime populates the object in-place with the server response, so `vmcp.Generation` is already the post-increment value. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: taskbot <taskbot@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for a771117 - Browse repository at this point
Copy the full SHA a771117View commit details -
Guard against invalid PIDs in process operations (#4401)
Guard against invalid PIDs in process ops On Unix, kill(0, sig) sends the signal to every process in the calling process's group. KillProcess(0) would SIGTERM thv itself and any child processes sharing its group. FindProcess(0) falsely reports "alive" via kill(0, 0). Both can be reached when a status file contains PID 0 due to crashes or races during proxy startup. Fixes #4400 Signed-off-by: Greg Katz <gkatz@indeed.com> Co-authored-by: Claude <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 3f776f0 - Browse repository at this point
Copy the full SHA 3f776f0View commit details -
Return JSON 404 for OAuth discovery when auth is off (#4366)
Return JSON 404 for OAuth discovery when auth is not configured Claude Code v2.1.83 sends GET /.well-known/oauth-protected-resource before connecting to any HTTP MCP server. When auth is not configured, no .well-known handler was registered, so the request fell through to the MCP catch-all handler whose headerValidatingMiddleware rejected it with HTTP 406 and a JSON-RPC error body (where "error" is an object). Claude Code expects "error" as a string for OAuth errors, causing Zod validation failure and a spurious "needs authentication" prompt. Always register a .well-known prefix handler. When AuthInfoHandler is nil, it returns HTTP 404 with {"error":"not_found"} — a clean signal that no auth metadata exists and the client should proceed without authentication. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>Configuration menu - View commit details
-
Copy full SHA for 2a89245 - Browse repository at this point
Copy the full SHA 2a89245View commit details -
feat: add authorizationEndpointBaseUrl override to embedded auth serv…
…er (#4396) Add optional authorizationEndpointBaseUrl field to EmbeddedAuthServerConfig that overrides only the authorization_endpoint in the OAuth discovery document When set, the discovery document advertises {authorizationEndpointBaseUrl}/oauth/authorize instead of {issuer}/oauth/authorize; all other endpoints (token, registration, JWKS) remain derived from issuer This enables deployments where the browser-facing authorization endpoint needs to be on a different host than the issuer used for backend-to-backend calls
Configuration menu - View commit details
-
Copy full SHA for d57d73b - Browse repository at this point
Copy the full SHA d57d73bView commit details -
Support RFC 8414 path-based issuer discovery URLs (#4406)
PR #4348 (f64d807) replaced the /.well-known/ catch-all mux pattern with explicit exact registrations to prevent the auth server from intercepting /.well-known/oauth-protected-resource. This broke RFC 8414 Section 3.1 discovery for path-based issuers: clients construct /.well-known/oauth-authorization-server/{issuer-path} but the exact pattern only matched /.well-known/oauth-authorization-server. Register trailing-slash prefix variants on both the http.ServeMux (Routes()) and chi router (WellKnownRoutes) so subpaths are routed to the discovery handlers. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for e62f833 - Browse repository at this point
Copy the full SHA e62f833View commit details -
Block Docker gateway addresses in egress proxy by default (#4395)
## Why Containerized MCP servers can reach host services via `host.docker.internal`, `gateway.docker.internal`, and the Docker bridge gateway IP (`172.17.0.1`). This enables lateral movement from a compromised or malicious MCP server to services running on the host, bypassing the container network boundary. The existing `insecure_allow_all` permission flag does not protect against this: users enabling it intend to open general internet access, not necessarily host access. These are distinct threat surfaces and warrant separate opt-ins. ## What changed The Squid egress proxy config now emits ACL deny rules for the three Docker gateway addresses **before** any allow rules. Squid evaluates access control in first-match-wins order, so placing the deny first ensures it cannot be bypassed by a subsequent `http_access allow all`. A new `--allow-docker-gateway` CLI flag (default `false`) provides an explicit opt-in for the small number of MCP servers that legitimately need host access. The flag threads through the full call chain: ``` --allow-docker-gateway (run_flags.go) → RunConfig.AllowDockerGateway (config.go) → runtime.Setup() (setup.go) → DeployWorkloadOptions.AllowDockerGateway (types.go) → createEgressSquidContainer() (client.go) → createTempEgressSquidConf() (squid.go) ``` Generated Squid config with default settings (blocking active): ```squid acl docker_gateway_hosts dstdomain host.docker.internal gateway.docker.internal acl docker_gateway_ip dst 172.17.0.1 http_access deny docker_gateway_hosts http_access deny docker_gateway_ip http_access allow all # (or ACL-based allow rules) http_access deny all ```
Configuration menu - View commit details
-
Copy full SHA for 887b39c - Browse repository at this point
Copy the full SHA 887b39cView commit details -
* Update VERSION for release Release-Triggered-By: jerm-dro * Update Chart.yaml for release Release-Triggered-By: jerm-dro * Update Chart.yaml for release Release-Triggered-By: jerm-dro * Update Chart.yaml for release Release-Triggered-By: jerm-dro * Update Chart.yaml for release Release-Triggered-By: jerm-dro * Update values.yaml for release Release-Triggered-By: jerm-dro * Update values.yaml for release Release-Triggered-By: jerm-dro * Update values.yaml for release Release-Triggered-By: jerm-dro * Update VERSION for release Release-Triggered-By: jerm-dro * Update Chart.yaml for release Release-Triggered-By: jerm-dro * Update README.md for release Release-Triggered-By: jerm-dro * Update Chart.yaml for release Release-Triggered-By: jerm-dro * Update README.md for release Release-Triggered-By: jerm-dro * Update values.yaml for release Release-Triggered-By: jerm-dro
Configuration menu - View commit details
-
Copy full SHA for 70845b5 - Browse repository at this point
Copy the full SHA 70845b5View commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff v0.13.0...v0.13.1