Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/upstream-projects.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ projects:

- id: toolhive
repo: stacklok/toolhive
version: v0.38.0
version: v0.40.0
# toolhive is a monorepo covering the CLI, the Kubernetes
# operator, and the vMCP gateway. It also introduces cross-
# cutting features that land in concepts/, integrations/,
Expand Down
32 changes: 32 additions & 0 deletions docs/toolhive/guides-cli/network-isolation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ accepted:
thv run [--permission-profile </path/to/custom-profile.json>] <SERVER>
```

Isolation requires bridge networking. If you also pass `--network host` or
`--network none`, ToolHive drops isolation for that workload (see
[Interaction with `--network host` and `--network none`](#interaction-with---network-host-and---network-none)).

:::info[Changed in v0.30.1]

Earlier versions of ToolHive required `--isolate-network` to turn on network
Expand Down Expand Up @@ -201,6 +205,34 @@ thv run --isolate-network=false <SERVER>
The container's own network namespace still isolates it from the host; only
ToolHive's allowlist enforcement is disabled.

## Interaction with `--network host` and `--network none`

Network isolation is a bridge-network construct: the egress, DNS, and ingress
sidecars only work when the MCP container lives on a container-runtime bridge.
When you pass `--network host` or `--network none`, the container shares the
host network namespace or has no network at all, so the isolation sidecars have
no way to intercept traffic. In v0.40.0 and later, ToolHive reconciles the two
flags automatically:

| `--network` mode | `--isolate-network` source | Behavior |
| -------------------------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| bridge (unset or `bridge`) | any | Isolation as designed. |
| `host` or custom | default (implicit) | Isolation is dropped with a warning in the run log, restoring outbound connectivity for host-networked workloads. |
| `host` or custom | explicit `--isolate-network=true` | `thv run` fails fast with an error naming both flags. Drop `--network host` to keep enforced isolation, or set `--isolate-network=false` to keep host networking. |
| `none` | any | Isolation is silently dropped (`none` is already maximally confined; isolation would be redundant). |

:::info[Changed in v0.40.0]

Before v0.40.0, `thv run --network host` silently built the isolation sidecars
against an internal-only network, breaking outbound DNS and connectivity.
Isolation is now dropped for `host`/`none` modes so host-networked workloads
keep working. If you rely on host networking, no change is needed. If you
previously combined `--isolate-network` with `--network host` explicitly, pick
one: drop `--network host` to keep enforced isolation, or set
`--isolate-network=false` to keep host networking.

:::

## Example: Enable network isolation using registry defaults

Many MCP servers in the ToolHive registry have default permission profiles that
Expand Down
3 changes: 3 additions & 0 deletions docs/toolhive/reference/cli/thv_llm_config_set.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,14 @@ thv llm config set [flags]

```
--audience string OIDC audience (optional)
--bedrock-compat Persist Bedrock compatibility for Claude Code (CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 + per-tier Bedrock model IDs). Applied by "thv llm setup". Use --bedrock-compat=false to clear.
--callback-port int OIDC callback port (omit to keep current; default: ephemeral)
--client-id string OIDC client ID
--enable-1m With Bedrock compat, opt into the 1M context window by appending [1m] to opus/sonnet model IDs.
--gateway-url string LLM gateway base URL (must use HTTPS)
-h, --help help for set
--issuer string OIDC issuer URL
--models strings Model IDs to persist and apply during "thv llm setup", comma-separated or by repeating the flag, e.g. --models=us.anthropic.claude-opus-4-8,us.anthropic.claude-sonnet-5. Credential-helper clients (Claude Desktop) write these as inferenceModels; with Bedrock compat, each ID is also mapped to a Claude Code tier by matching 'haiku', 'opus', or 'sonnet' in the ID.
--proxy-port int Localhost proxy listen port (omit to keep current; default: 14000)
--tls-skip-verify Skip TLS certificate verification for the upstream gateway (local dev only; use --tls-skip-verify=false to clear)
```
Expand Down
14 changes: 13 additions & 1 deletion docs/toolhive/reference/cli/thv_llm_setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ Inline flags (--gateway-url, --issuer, --client-id, etc.) are applied for this
run and persisted to config only after login and tool patching succeed. This
lets you combine "config set" and "setup" into a single command.

For a gateway that forwards to AWS Bedrock, add --bedrock-compat to configure
Claude Code with CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 and per-tier Bedrock
model IDs (override with --models; add --enable-1m for the 1M context window on
opus/sonnet). The setting is persisted and only affects Claude Code. To add it to
an already-configured Claude Code, re-run:

thv llm setup --client claude-code --bedrock-compat

Re-running is idempotent and uses the cached token (no browser prompt).

Run "thv llm teardown" to revert all changes.

```
Expand All @@ -56,14 +66,16 @@ thv llm setup [flags]
```
--anthropic-path-prefix string Path prefix appended to the gateway URL when writing ANTHROPIC_BASE_URL for direct-mode tools (e.g. /anthropic). When omitted, the gateway is probed automatically.
--audience string OIDC audience (optional)
--bedrock-compat Configure Claude Code for a gateway that forwards to AWS Bedrock: write CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 (Bedrock rejects the experimental anthropic-beta headers) and pin per-tier Bedrock model IDs (override with --models). Persisted, so a later plain "thv llm setup" keeps it; clear with --bedrock-compat=false. Only affects Claude Code.
--callback-port int OIDC callback port (omit to keep current; default: ephemeral)
--client string Configure only this AI tool by name (e.g. claude-code, cursor, codex). Omit to configure all detected tools.
--client-id string OIDC client ID
--enable-1m With --bedrock-compat, append the [1m] suffix to the opus and sonnet model IDs to opt into the 1M-token context window on Bedrock (never haiku, which is 200K). Off by default.
--gateway-url string LLM gateway base URL (must use HTTPS)
-h, --help help for setup
--issuer string OIDC issuer URL
--lazy Skip the interactive OIDC login and defer it until the first time a configured tool accesses the gateway. Tool config and persisted settings are written normally. Useful for unattended provisioning (e.g. an MDM profile).
--models strings Explicit model IDs to expose to credential-helper clients (Claude Desktop's inferenceModels). Repeat or comma-separate. Omit to rely on the gateway's own model discovery once it is available.
--models strings Model IDs to configure, comma-separated or by repeating the flag, e.g. --models=us.anthropic.claude-opus-4-8,us.anthropic.claude-sonnet-5. For credential-helper clients (Claude Desktop) these become inferenceModels. With --bedrock-compat, each ID is also mapped to a Claude Code tier by matching 'haiku', 'opus', or 'sonnet' in the ID (IDs matching no tier are ignored with a warning). Omit to use the built-in Bedrock defaults / gateway model discovery.
--proxy-port int Localhost proxy listen port (omit to keep current; default: 14000)
--skip-browser Print the OIDC authorization URL instead of opening a browser, then wait for the callback. Use in headless/SSH/CI environments where no system browser is available.
--tls-skip-verify Skip TLS certificate verification for the upstream gateway (local dev only). For direct-mode tools (Claude Code, Gemini CLI) this sets NODE_TLS_REJECT_UNAUTHORIZED=0, disabling TLS for ALL of that tool's outbound connections. For proxy-mode tools only the proxy-to-gateway connection is affected.
Expand Down
4 changes: 2 additions & 2 deletions docs/toolhive/reference/cli/thv_run.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,12 @@ thv run [flags] SERVER_OR_IMAGE_OR_PROTOCOL [-- ARGS...]
--host string Host for the HTTP proxy to listen on (IP or hostname) (default "127.0.0.1")
--ignore-globally Load global ignore patterns from ~/.config/toolhive/thvignore (default true)
--image-verification string Set image verification mode (warn, enabled, disabled) (default "warn")
--isolate-network Isolate the container network from the host. Use --isolate-network=false to opt out. (default true)
--isolate-network Isolate the container network from the host. Use --isolate-network=false to opt out. Not enforced with --network host or --network none (isolation requires bridge networking). (default true)
--jwks-allow-private-ip Allow JWKS/OIDC endpoints on private IP addresses (use with caution) (default false)
--jwks-auth-token-file string Path to file containing bearer token for authenticating JWKS/OIDC requests
-l, --label stringArray Set labels on the container (format: key=value)
--name string Name of the MCP server (default to auto-generated from image)
--network string Connect the container to a network (e.g., 'host' for host networking)
--network string Connect the container to a network (e.g., 'host' for host networking). Note: 'host' and 'none' cannot enforce network isolation, so isolation is dropped for those modes.
--oidc-audience string Expected audience for the token
--oidc-client-id string OIDC client ID
--oidc-client-secret string OIDC client secret (optional, for introspection)
Expand Down
16 changes: 10 additions & 6 deletions static/api-specs/toolhive-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -469,10 +469,14 @@ components:
allow_private_ips:
description: |-
AllowPrivateIPs permits the upstream provider's HTTP client to connect to
private IP ranges (RFC-1918, link-local). Use only when the upstream is
hosted inside the same cluster and has no public endpoint. HTTP-scheme
restrictions are unchanged — HTTPS is still required for non-localhost hosts.
Defaults to false.
private IP ranges (RFC-1918, link-local). When DCRConfig is set, this
also gates the DCR discovery and registration calls made on this
upstream's behalf (see pkg/authserver/runner/dcr_adapter.go), so a
single flag covers the whole upstream rather than needing a separate
DCR-specific setting. Use only when the upstream is hosted inside the
same cluster and has no public endpoint. HTTP-scheme restrictions are
unchanged — HTTPS is still required for non-localhost hosts. Defaults
to false.
type: boolean
authorization_endpoint:
description: AuthorizationEndpoint is the URL for the OAuth authorization
Expand Down Expand Up @@ -2294,13 +2298,13 @@ components:
uniqueItems: false
registryBaseUrl:
description: RegistryBaseURL is the base URL of the package registry (used
by npm, pypi, nuget; not used by oci, mcpb)
by npm, pypi, nuget, cargo; not used by oci, mcpb)
example: https://registry.npmjs.org
format: uri
type: string
registryType:
description: RegistryType indicates how to download packages (e.g., "npm",
"pypi", "oci", "nuget", "mcpb")
"pypi", "cargo", "oci", "nuget", "mcpb")
example: npm
minLength: 1
type: string
Expand Down
7 changes: 7 additions & 0 deletions static/api-specs/upstream-registry.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@
"items": {
"$ref": "https://raw.githubusercontent.com/stacklok/toolhive-core/main/registry/types/data/skill.schema.json"
}
},
"plugins": {
"type": "array",
"description": "Array of plugins in the registry",
"items": {
"$ref": "https://raw.githubusercontent.com/stacklok/toolhive-core/main/registry/types/data/plugin.schema.json"
}
}
}
}
Expand Down