From 17f80df69cb9b8987dff8ac1ce930ad3f16fc570 Mon Sep 17 00:00:00 2001 From: Dan Barr <6922515+danbarr@users.noreply.github.com> Date: Wed, 1 Jul 2026 12:59:46 -0400 Subject: [PATCH 1/2] Refresh MCP guides after PR #1001 image bumps Validated the six guides touched by the Docker image version bumps against real thv CLI runs and the toolhive operator, plus two more guides that shared the same stale patterns. Fixes found along the way: - Remove GITHUB_DYNAMIC_TOOLSETS, removed upstream in github-mcp-server v1.5.0 - Remove --save-trace from playwright.mdx, not a real flag - Add missing --allow-docker-gateway flag for the host.docker.internal example in fetch.mdx - Update network isolation framing across context7, fetch, filesystem, github, grafana, k8s, and osv guides now that thv run isolates by default; drop now-redundant --isolate-network from examples - Rework playwright.mdx to use PLAYWRIGHT_MCP_* environment variables instead of raw CLI args, swap the origin-filtering example for session persistence and Kubernetes backend scale-out, and correct the security framing around --allowed-origins --- docs/toolhive/guides-mcp/context7.mdx | 21 +-- docs/toolhive/guides-mcp/fetch.mdx | 20 ++- docs/toolhive/guides-mcp/filesystem.mdx | 11 +- docs/toolhive/guides-mcp/github.mdx | 25 +-- docs/toolhive/guides-mcp/grafana.mdx | 15 +- docs/toolhive/guides-mcp/k8s.mdx | 17 +- docs/toolhive/guides-mcp/osv.mdx | 15 +- docs/toolhive/guides-mcp/playwright.mdx | 202 ++++++++++++++---------- 8 files changed, 180 insertions(+), 146 deletions(-) diff --git a/docs/toolhive/guides-mcp/context7.mdx b/docs/toolhive/guides-mcp/context7.mdx index 99a5efdb..3148839a 100644 --- a/docs/toolhive/guides-mcp/context7.mdx +++ b/docs/toolhive/guides-mcp/context7.mdx @@ -71,19 +71,15 @@ thv run context7-remote ``` Alternatively, run the local containerized MCP server with the default -configuration (you don't need an API key for basic usage): +configuration (you don't need an API key for basic usage). ToolHive +[isolates the server's network access](../guides-cli/network-isolation.mdx) by +default, using the registry's default profile, which restricts access to +`context7.com`: ```bash thv run context7 ``` -Enable [network isolation](../guides-cli/network-isolation.mdx) using the -default profile from the registry to restrict the server's network access: - -```bash -thv run --isolate-network context7 -``` - If you have a Context7 API key for higher rate limits, create a secret named `context7` containing your API key and run the server with the `--secret` flag: @@ -92,12 +88,6 @@ thv secret set context7 thv run --secret context7,target=CONTEXT7_API_KEY context7 ``` -Combine API key with network isolation: - -```bash -thv run --secret context7,target=CONTEXT7_API_KEY --isolate-network context7 -``` - @@ -174,4 +164,5 @@ Here are practical prompts you can use with the Context7 MCP server: - Register for an API key at [context7.com/dashboard](https://context7.com/dashboard) if you plan to make frequent requests or need higher rate limits. -- Enable network isolation to restrict the server's outbound access. +- Network isolation restricts the server's outbound access to `context7.com` by + default. diff --git a/docs/toolhive/guides-mcp/fetch.mdx b/docs/toolhive/guides-mcp/fetch.mdx index 2014ea4a..f8509dad 100644 --- a/docs/toolhive/guides-mcp/fetch.mdx +++ b/docs/toolhive/guides-mcp/fetch.mdx @@ -33,13 +33,16 @@ allowed hosts and ports. -Run with the default configuration: +Run with the default configuration. ToolHive +[isolates the server's network access](../guides-cli/network-isolation.mdx) by +default; the registry's default profile for `fetch` allows all outbound HTTPS +traffic, since the server needs to reach arbitrary websites: ```bash thv run fetch ``` -To control which website resources the server can access, create a custom +To restrict which website resources the server can access, create a custom permission profile: ```json title="fetch-profile.json" @@ -58,11 +61,13 @@ permission profile: } ``` -Then run the server with the profile and -[enable network isolation](../guides-cli/network-isolation.mdx): +Docker gateway addresses like `host.docker.internal` are blocked by an explicit +deny in the egress proxy by default, even when they're listed in `allow_host`. +Add the `--allow-docker-gateway` flag to remove that deny, then run the server +with the profile: ```bash -thv run --isolate-network --permission-profile fetch-profile.json fetch +thv run --allow-docker-gateway --permission-profile fetch-profile.json fetch ``` @@ -102,7 +107,8 @@ Here are some sample prompts you can use to interact with the Fetch MCP server: ## Recommended practices -- Use network isolation to restrict the server's outbound network access to the - specific hosts and ports required for your use case. +- Customize the network isolation permission profile to restrict the server's + outbound network access to the specific hosts and ports required for your use + case, since the default profile allows all outbound HTTPS traffic. - Enable [telemetry](../guides-cli/telemetry-and-metrics.mdx) to monitor tool usage including URL access for security and auditing purposes. diff --git a/docs/toolhive/guides-mcp/filesystem.mdx b/docs/toolhive/guides-mcp/filesystem.mdx index 08245f28..0b3f86b3 100644 --- a/docs/toolhive/guides-mcp/filesystem.mdx +++ b/docs/toolhive/guides-mcp/filesystem.mdx @@ -95,10 +95,11 @@ thv run \ :::tip -Since the server does not require any network access, add the -`--isolate-network --permission-profile none` flags to completely restrict its -outbound network access (see the -[network isolation guide](../guides-cli/network-isolation.mdx)). +The server does not require any network access, and ToolHive +[isolates its network access](../guides-cli/network-isolation.mdx) by default +using the registry's profile, which already blocks all outbound traffic. No +extra flags are needed, but you can pass `--permission-profile none` explicitly +if you want to make that restriction obvious in your command. ::: @@ -168,5 +169,5 @@ server: minimize resource usage and improve performance. - Use read-only mounts for directories or files that do not need to be modified by the AI agent to prevent accidental changes. -- Enable network isolation to restrict the server's outbound network access, +- Network isolation blocks the server's outbound network access by default, since the filesystem MCP server does not require any network connectivity. diff --git a/docs/toolhive/guides-mcp/github.mdx b/docs/toolhive/guides-mcp/github.mdx index f670f439..f4745bf0 100644 --- a/docs/toolhive/guides-mcp/github.mdx +++ b/docs/toolhive/guides-mcp/github.mdx @@ -70,13 +70,10 @@ gh auth token | thv secret set github thv run --secret github,target=GITHUB_PERSONAL_ACCESS_TOKEN github ``` -Enable [network isolation](../guides-cli/network-isolation.mdx) using the -default profile from the registry (appropriate for `github.com`) to restrict the -server's network access: - -```bash -thv run --isolate-network github -``` +ToolHive +[isolates the server's network access](../guides-cli/network-isolation.mdx) by +default, using the registry's default profile, which restricts access to +`*.github.com` and `*.githubusercontent.com`. Limit the active toolsets (useful to avoid context overload) and enable read-only mode. Refer to the @@ -87,12 +84,6 @@ for the current list of toolsets. thv run -e GITHUB_TOOLSETS=repos,issues,pull_requests -e GITHUB_READ_ONLY=1 github ``` -Enable the MCP server's dynamic tool discovery feature (currently in beta): - -```bash -thv run -e GITHUB_DYNAMIC_TOOLSETS=1 github -``` - :::info[GitHub Enterprise] Create a custom permission profile for your GitHub Enterprise instance: @@ -114,7 +105,7 @@ Then run the server with the profile: ```bash thv run \ -e GITHUB_HOST=https://github.your-enterprise.com \ - --isolate-network --permission-profile github-enterprise-profile.json \ + --permission-profile github-enterprise-profile.json \ github ``` @@ -204,6 +195,6 @@ Here are some sample prompts you can use to interact with the GitHub MCP server: for your use case. - Regularly rotate your GitHub personal access token and update the secret in ToolHive. -- Enable network isolation to restrict the server's outbound network access. -- Limit the active toolsets to reduce context overload and improve performance, - or use dynamic tool discovery if supported by your client. +- Network isolation restricts the server's outbound access to `*.github.com` and + `*.githubusercontent.com` by default. +- Limit the active toolsets to reduce context overload and improve performance. diff --git a/docs/toolhive/guides-mcp/grafana.mdx b/docs/toolhive/guides-mcp/grafana.mdx index 2d296865..d2ad421a 100644 --- a/docs/toolhive/guides-mcp/grafana.mdx +++ b/docs/toolhive/guides-mcp/grafana.mdx @@ -82,9 +82,11 @@ thv run \ grafana ``` -Enable [network isolation](../guides-cli/network-isolation.mdx) to restrict the -server's network access. Create a permission profile with your Grafana instance -domain: +ToolHive +[isolates the server's network access](../guides-cli/network-isolation.mdx) by +default, but since the registry can't predict your Grafana instance's domain, +the default profile allows all outbound HTTPS traffic. Create a permission +profile with your Grafana instance domain to restrict access: ```json title="grafana-profile.json" { @@ -104,7 +106,7 @@ Then run with the custom profile: thv run \ -e GRAFANA_URL=https://myinstance.grafana.net \ --secret grafana-token,target=GRAFANA_SERVICE_ACCOUNT_TOKEN \ - --isolate-network --permission-profile grafana-profile.json \ + --permission-profile grafana-profile.json \ grafana ``` @@ -217,8 +219,9 @@ server: RBAC scopes to limit access to only the datasources, dashboards, and features required for your specific use case. - Regularly rotate service account tokens and update the secrets in ToolHive. -- Enable network isolation to restrict the server's outbound network access to - your Grafana instance domain only. +- Customize the network isolation permission profile to restrict the server's + outbound network access to your Grafana instance domain only, since the + default profile allows all outbound HTTPS traffic. - For dashboards with large JSON configurations, use the `get_dashboard_summary` or `get_dashboard_property` tools to minimize context window usage instead of retrieving the full dashboard with `get_dashboard_by_uid`. diff --git a/docs/toolhive/guides-mcp/k8s.mdx b/docs/toolhive/guides-mcp/k8s.mdx index 228f3d8b..d33cc424 100644 --- a/docs/toolhive/guides-mcp/k8s.mdx +++ b/docs/toolhive/guides-mcp/k8s.mdx @@ -88,9 +88,11 @@ thv run --volume $HOME/.kube:/home/nonroot/.kube:ro \ k8s ``` -Enable [network isolation](../guides-cli/network-isolation.mdx) to restrict -network access to your Kubernetes cluster only. Create a custom permission -profile: +ToolHive +[isolates the server's network access](../guides-cli/network-isolation.mdx) by +default, but since the registry can't predict your cluster's API server +endpoint, the default profile allows all outbound HTTPS traffic. Create a custom +permission profile to restrict network access to your cluster only: ```json title="k8s-cluster-profile.json" { @@ -104,11 +106,11 @@ profile: } ``` -Then run with network isolation: +Then run with the custom profile: ```bash thv run --volume $HOME/.kube:/home/nonroot/.kube:ro \ - --isolate-network --permission-profile k8s-cluster-profile.json \ + --permission-profile k8s-cluster-profile.json \ k8s ``` @@ -208,8 +210,9 @@ server: (`--read-write=true`) when necessary and in controlled environments. - **Implement proper RBAC**: When using service accounts, follow the principle of least privilege and grant only the minimum permissions required. -- **Enable network isolation**: Restrict network access to your Kubernetes API - endpoints only, especially in production environments. +- **Customize network isolation**: Restrict network access to your Kubernetes + API endpoints only, especially in production environments, since the default + profile allows all outbound HTTPS traffic. - **Monitor resource usage**: The server includes built-in rate limiting, but monitor your cluster's API server load when using with AI agents. - **Disable resource discovery in large clusters**: Use diff --git a/docs/toolhive/guides-mcp/osv.mdx b/docs/toolhive/guides-mcp/osv.mdx index f3bb10a1..33e5c075 100644 --- a/docs/toolhive/guides-mcp/osv.mdx +++ b/docs/toolhive/guides-mcp/osv.mdx @@ -52,13 +52,10 @@ Run with the default configuration: thv run osv ``` -Enable [network isolation](../guides-cli/network-isolation.mdx) using the -default profile from the registry to restrict the server's network access to -only the OSV API: - -```bash -thv run --isolate-network osv -``` +ToolHive +[isolates the server's network access](../guides-cli/network-isolation.mdx) by +default, using the registry's default profile, which restricts access to only +the OSV API (`api.osv.dev`). @@ -109,8 +106,8 @@ Here are some sample prompts you can use to interact with the OSV MCP server: - **Use batch queries** when checking multiple packages to reduce API calls and improve performance. The batch query tool can handle multiple packages in a single request. -- **Enable network isolation** to restrict the server's network access to only - the OSV API endpoints, improving security posture. +- **Network isolation** restricts the server's network access to only the OSV + API endpoints by default, improving security posture. - **Specify ecosystems accurately** (npm, PyPI, Go, Maven, etc.) to ensure accurate vulnerability matching and reduce false positives. - **Use package URLs (PURLs)** when available for more precise package diff --git a/docs/toolhive/guides-mcp/playwright.mdx b/docs/toolhive/guides-mcp/playwright.mdx index 491eaf15..3f7e1071 100644 --- a/docs/toolhive/guides-mcp/playwright.mdx +++ b/docs/toolhive/guides-mcp/playwright.mdx @@ -37,22 +37,38 @@ Key features include: ## Usage -The Playwright MCP server supports numerous command-line arguments to customize -its behavior. Common options include: - -- **Custom viewport**: Set `--viewport-size` to specify browser dimensions - (e.g., `1920,1080`) -- **Device emulation**: Use `--device` to emulate mobile devices (e.g., - `"iPhone 15"`) -- **Network isolation**: Configure `--allowed-origins` and `--blocked-origins` - to control which websites the browser can access -- **Output directory**: Specify `--output-dir` to save screenshots, PDFs, and - other files to a custom location; mount a host directory for persistence (see - examples below) - -Refer to the +The Playwright MCP server supports numerous options to customize its behavior, +each available as both a command-line argument and an equivalent +`PLAYWRIGHT_MCP_*` environment variable. Common options include: + +- **Custom viewport**: Set `--viewport-size` or `PLAYWRIGHT_MCP_VIEWPORT_SIZE` + to specify browser dimensions (e.g., `1920x1080`) +- **Device emulation**: Use `--device` or `PLAYWRIGHT_MCP_DEVICE` to emulate + mobile devices (e.g., `"iPhone 15"`) +- **Session persistence**: Set `--user-data-dir` or + `PLAYWRIGHT_MCP_USER_DATA_DIR` to a mounted volume to keep login state and + cookies across container restarts; use `--isolated` or + `PLAYWRIGHT_MCP_ISOLATED` to run fresh, throwaway sessions instead +- **Output directory**: Specify `--output-dir` or `PLAYWRIGHT_MCP_OUTPUT_DIR` to + save screenshots, PDFs, and other files to a custom location; mount a host + directory for persistence (see examples below) +- **Timeouts**: Increase `--timeout-action` or `PLAYWRIGHT_MCP_TIMEOUT_ACTION` + and `--timeout-navigation` or `PLAYWRIGHT_MCP_TIMEOUT_NAVIGATION` for + slow-loading pages +- **Image responses**: Set `--image-responses` or + `PLAYWRIGHT_MCP_IMAGE_RESPONSES` to `omit` to stop sending screenshots to the + client and reduce context usage +- **HTTPS errors**: Use `--ignore-https-errors` or + `PLAYWRIGHT_MCP_IGNORE_HTTPS_ERRORS` when testing internal sites with + self-signed certificates + +The environment variable form is generally easier to use with ToolHive's `-e` +flag (CLI) or `env` field (Kubernetes), so the examples below use it, but you +can pass the equivalent command-line arguments instead if you prefer. Refer to +the [Playwright MCP server documentation](https://github.com/microsoft/playwright-mcp?tab=readme-ov-file#configuration) -for the full list of configuration options and their descriptions. +for the full list of configuration options and their environment variable +equivalents. :::note[Limitations] @@ -67,12 +83,15 @@ headless mode. Select the `playwright` MCP server in the ToolHive registry. The server runs with default settings that work for most use cases. -To customize the server's behavior, add command-line arguments in the **Command -arguments** section. +To customize the server's behavior, configure the available options in the +**Environment Variables** section (for example, `PLAYWRIGHT_MCP_DEVICE` or +`PLAYWRIGHT_MCP_OUTPUT_DIR`). You can add command-line arguments in the +**Command arguments** section instead if you prefer. To save browser output files like screenshots and traces, mount a host directory -in the **Storage volumes** section and add the `--output-dir ` -command argument as shown in the screenshot below. +in the **Storage volumes** section and set the `PLAYWRIGHT_MCP_OUTPUT_DIR` +environment variable (or the `--output-dir` command argument, as shown in the +screenshot below) to the matching container path. @@ -142,19 +169,20 @@ spec: transport: streamable-http mcpPort: 8931 proxyPort: 8080 - args: - - '--port' - - '8931' - - '--host' - - '0.0.0.0' - - '--allowed-hosts' - - '*' + env: + - name: PLAYWRIGHT_MCP_PORT + value: '8931' + - name: PLAYWRIGHT_MCP_HOST + value: '0.0.0.0' + - name: PLAYWRIGHT_MCP_ALLOWED_HOSTS + value: '*' ``` :::note[Important] -Don't remove the `--port 8931`, `--host 0.0.0.0`, or `--allowed-hosts "*"` -arguments. They are required to run the server using Streamable HTTP. +Don't remove the `PLAYWRIGHT_MCP_PORT`, `PLAYWRIGHT_MCP_HOST`, or +`PLAYWRIGHT_MCP_ALLOWED_HOSTS` environment variables. They're required to run +the server using Streamable HTTP. ::: @@ -164,35 +192,10 @@ Apply the manifest to your Kubernetes cluster: kubectl apply -f playwright.yaml ``` -For production deployments with network restrictions, add the -`--allowed-origins` argument with a list of trusted domains: - -```yaml {18-19} title="playwright-restricted.yaml" -apiVersion: toolhive.stacklok.dev/v1beta1 -kind: MCPServer -metadata: - name: playwright - namespace: toolhive-system -spec: - image: mcr.microsoft.com/playwright/mcp:v0.0.77 - transport: streamable-http - mcpPort: 8931 - proxyPort: 8080 - args: - - '--port' - - '8931' - - '--host' - - '0.0.0.0' - - '--allowed-hosts' - - '*' - - '--allowed-origins' - - 'example.com;trusted-domain.org' -``` - Mount a persistent volume to save browser output files like screenshots and traces: -```yaml {18-19,24-27,30-33} title="playwright-with-volume.yaml" +```yaml {18-21,24-27,29-33} title="playwright-with-volume.yaml" apiVersion: toolhive.stacklok.dev/v1beta1 kind: MCPServer metadata: @@ -203,17 +206,17 @@ spec: transport: streamable-http mcpPort: 8931 proxyPort: 8080 - args: - - '--port' - - '8931' - - '--host' - - '0.0.0.0' - - '--allowed-hosts' - - '*' - - '--output-dir' - - '/browser-output' - - '--save-trace' - - '--save-session' + env: + - name: PLAYWRIGHT_MCP_PORT + value: '8931' + - name: PLAYWRIGHT_MCP_HOST + value: '0.0.0.0' + - name: PLAYWRIGHT_MCP_ALLOWED_HOSTS + value: '*' + - name: PLAYWRIGHT_MCP_OUTPUT_DIR + value: '/browser-output' + - name: PLAYWRIGHT_MCP_SAVE_SESSION + value: 'true' podTemplateSpec: spec: volumes: @@ -228,6 +231,48 @@ spec: readOnly: false ``` +To serve multiple concurrent users, scale out the backend and configure Redis +session storage so each user's requests consistently reach the same pod. +Playwright's default browser profile persists in that pod's own filesystem, so +login state and cookies stick around for the life of the pod without needing a +mounted volume: + +```yaml {18-26} title="playwright-scaled.yaml" +apiVersion: toolhive.stacklok.dev/v1beta1 +kind: MCPServer +metadata: + name: playwright + namespace: toolhive-system +spec: + image: mcr.microsoft.com/playwright/mcp:v0.0.77 + transport: streamable-http + mcpPort: 8931 + proxyPort: 8080 + env: + - name: PLAYWRIGHT_MCP_PORT + value: '8931' + - name: PLAYWRIGHT_MCP_HOST + value: '0.0.0.0' + - name: PLAYWRIGHT_MCP_ALLOWED_HOSTS + value: '*' + backendReplicas: 3 + sessionStorage: + provider: redis + address: redis.toolhive-system.svc.cluster.local:6379 + db: 0 + keyPrefix: playwright-sessions + passwordRef: + name: redis-password + key: password +``` + +Sessions aren't migrated between pods, so if a backend pod restarts, its +in-progress sessions (and any login state in its profile) are lost and clients +must reconnect. See +[Horizontal scaling](../guides-k8s/run-mcp-k8s.mdx#horizontal-scaling) and +[Redis session storage](../guides-k8s/redis-session-storage.mdx) for the full +setup, including deploying Redis. + @@ -258,9 +303,6 @@ server: than visual characteristics. - **Leverage browser profiles**: For workflows requiring authentication, use persistent profiles or storage state files to maintain login sessions. -- **Enable network restrictions**: Use `--allowed-origins` and - `--blocked-origins` to limit which domains the browser can access, especially - in production environments. - **Monitor resource usage**: Browser automation can be resource-intensive; consider using headless mode and limiting concurrent sessions. - **Handle dynamic content**: Use the `browser_wait_for` tool when dealing with From 84c75c535053a5c1ae686d4f511e64460cb81494 Mon Sep 17 00:00:00 2001 From: Dan Barr <6922515+danbarr@users.noreply.github.com> Date: Wed, 1 Jul 2026 13:13:58 -0400 Subject: [PATCH 2/2] Fix github.mdx wildcard syntax per Copilot review ToolHive permission profiles use a leading-dot prefix for subdomain matching (.github.com) and don't support asterisk wildcards. Using *.github.com in prose risked readers copying invalid syntax into a real permission profile. --- docs/toolhive/guides-mcp/github.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/toolhive/guides-mcp/github.mdx b/docs/toolhive/guides-mcp/github.mdx index f4745bf0..94b8f591 100644 --- a/docs/toolhive/guides-mcp/github.mdx +++ b/docs/toolhive/guides-mcp/github.mdx @@ -73,7 +73,7 @@ thv run --secret github,target=GITHUB_PERSONAL_ACCESS_TOKEN github ToolHive [isolates the server's network access](../guides-cli/network-isolation.mdx) by default, using the registry's default profile, which restricts access to -`*.github.com` and `*.githubusercontent.com`. +subdomains of `github.com` and `githubusercontent.com`. Limit the active toolsets (useful to avoid context overload) and enable read-only mode. Refer to the @@ -195,6 +195,6 @@ Here are some sample prompts you can use to interact with the GitHub MCP server: for your use case. - Regularly rotate your GitHub personal access token and update the secret in ToolHive. -- Network isolation restricts the server's outbound access to `*.github.com` and - `*.githubusercontent.com` by default. +- Network isolation restricts the server's outbound access to subdomains of + `github.com` and `githubusercontent.com` by default. - Limit the active toolsets to reduce context overload and improve performance.