Skip to content

Commit 090ba49

Browse files
committed
Update diagrams and topology documentation
1 parent 2cbce09 commit 090ba49

File tree

2 files changed

+111
-51
lines changed

2 files changed

+111
-51
lines changed

docs/toolhive/guides-cli/custom-permissions.md renamed to docs/toolhive/guides-cli/custom-permissions.mdx

Lines changed: 108 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ description:
66
sidebar_position: 50
77
---
88

9+
import Tabs from '@theme/Tabs';
10+
import TabItem from '@theme/TabItem';
11+
912
ToolHive includes a permission system that lets you control an MCP server's
1013
access to your host's file system and to network resources. This is crucial for
1114
maintaining security and ensuring that MCP servers operate within defined
@@ -174,62 +177,123 @@ thv run --isolate-network --permission-profile </path/to/custom-profile.json> <s
174177

175178
## Network isolation
176179

177-
To enforce the network access rules defined in your permission profile, you must
178-
use the `--isolate-network` flag when running the MCP server:
180+
To enforce the network access rules defined in your permission profile, use the
181+
`--isolate-network` flag when running the MCP server:
179182

180183
```bash
181184
thv run --isolate-network --permission-profile </path/to/custom-profile.json> <server-name>
182185
```
183186

184-
When network isolation is enabled, ToolHive creates a secure network
185-
architecture around your MCP server. Along with the main MCP server container,
186-
ToolHive launches:
187+
When you enable network isolation, ToolHive creates a secure network
188+
architecture around your MCP server. This architecture includes several
189+
components that work together to control network access.
190+
191+
### Network architecture components
192+
193+
Along with the main MCP server container, ToolHive launches additional
194+
containers to manage network traffic:
195+
196+
- An egress proxy container that filters outgoing network traffic
197+
- A DNS container that provides controlled domain name resolution
198+
- An ingress proxy container that handles incoming requests (only for MCP
199+
servers using SSE or Streamable HTTP transport; stdio MCP servers don't need
200+
this since they don't expose ports)
201+
202+
### Network topology
203+
204+
ToolHive creates two separate networks in the container runtime:
205+
206+
- A shared external network (`toolhive-external`) that connects to your host's
207+
network
208+
- An internal network (`toolhive-<server-name>-internal`) for each MCP server
209+
that isolates it from external access
210+
211+
The MCP server container connects only to the internal network, while the proxy
212+
and DNS containers connect to both networks. This design ensures that all
213+
network traffic flows through controlled points, allowing ToolHive to enforce
214+
the access rules you specify in your permission profile.
187215

188-
- **An egress Squid proxy container** that filters outgoing network traffic
189-
- **A dnsmasq container** that provides controlled DNS resolution
190-
- **An ingress Squid proxy container** that proxies incoming SSE requests from
191-
the ToolHive proxy process (only for MCP servers using SSE transport; stdio
192-
MCP servers don't need this since they don't expose ports)
216+
The following diagrams show how network traffic flows through the isolation
217+
architecture for different transport types:
193218

194-
This multi-container setup ensures that all network traffic flows through
195-
controlled proxy points, allowing ToolHive to enforce the network access rules
196-
specified in your permission profile.
219+
<Tabs groupId='transport'>
220+
<TabItem value='stdio' label='Transport: Standard Input/Output (stdio)' default>
221+
222+
For MCP servers using stdio transport, the ToolHive proxy process communicates
223+
directly with the MCP server container through standard input and output. All
224+
outbound network requests from the MCP server flow through the egress proxy and
225+
DNS containers:
197226

198227
```mermaid
199-
graph TB
200-
subgraph "Host network"
201-
Client[MCP client]
202-
THVProxy[ToolHive SSE proxy]
203-
end
204-
205-
subgraph "Docker networks"
206-
subgraph "toolhive-external"
207-
IngressProxy["Ingress proxy<br>(squid)"]
208-
end
209-
210-
subgraph "toolhive-{name}-internal"
211-
MCPServer[MCP server<br>container]
212-
EgressProxy["Egress proxy<br>(squid)"]
213-
DNSContainer["DNS container<br/>(dnsmasq)"]
214-
end
215-
end
216-
217-
External[External resources]
218-
219-
%% Traffic Flow
220-
Client -->|SSE/HTTP request| THVProxy
221-
THVProxy -->|Forward| IngressProxy
222-
IngressProxy -->|Reverse proxy| MCPServer
223-
MCPServer -->|Outbound requests| EgressProxy
224-
EgressProxy -->|Filtered traffic| External
225-
MCPServer -.->|DNS queries| DNSContainer
228+
architecture-beta
229+
service mcp_client(server)[MCP client]
230+
service toolhive_proxy(server)[ToolHive HTTP proxy process]
231+
232+
group container_runtime(server)[Container runtime]
233+
group thv_internal(server)[Isolated network] in container_runtime
234+
service egress(server)[Egress proxy container] in container_runtime
235+
service mcp_server(server)[MCP server container] in thv_internal
236+
service dns_container(server)[DNS container] in container_runtime
237+
238+
group external(internet)[External Resources]
239+
service external_service(internet)[External service] in external
240+
service external_dns(internet)[External DNS] in external
241+
242+
junction outbound in container_runtime
243+
244+
mcp_client:R --> L:toolhive_proxy
245+
toolhive_proxy:R --> L:mcp_server
246+
mcp_server:R -- L:outbound
247+
egress:B <-- T:outbound
248+
dns_container:T <-- B:outbound
249+
egress:R --> L:external_service
250+
dns_container:R --> L:external_dns
226251
```
227252

228-
:::note
253+
</TabItem>
254+
<TabItem value='sse' label='Transport: SSE or Streamable HTTP'>
255+
256+
For MCP servers using SSE or Streamable HTTP transport, ToolHive includes an
257+
additional ingress proxy container. This proxy handles incoming HTTP requests
258+
and ensures the MCP server remains isolated from direct external access:
259+
260+
```mermaid
261+
architecture-beta
262+
service mcp_client(server)[MCP client]
263+
service toolhive_proxy(server)[ToolHive HTTP proxy process]
264+
265+
group container_runtime[Container runtime]
266+
group thv_internal[Isolated network] in container_runtime
267+
service ingress(server)[Ingress proxy container] in container_runtime
268+
service egress(server)[Egress proxy container] in container_runtime
269+
service mcp_server(server)[MCP server container] in thv_internal
270+
service dns_container(server)[DNS container] in container_runtime
271+
272+
group external[External resources]
273+
service external_service(internet)[External service] in external
274+
service external_dns(internet)[External DNS] in external
275+
276+
junction outbound in container_runtime
277+
278+
mcp_client:R --> L:toolhive_proxy
279+
toolhive_proxy:R --> L:ingress
280+
ingress:R --> L:mcp_server
281+
mcp_server:R -- L:outbound
282+
egress:B <-- T:outbound
283+
dns_container:T <-- B:outbound
284+
egress:R --> L:external_service
285+
dns_container:R --> L:external_dns
286+
```
287+
288+
</TabItem>
289+
</Tabs>
290+
291+
:::important
229292

230-
Network isolation currently supports only HTTP and HTTPS protocols. Other
231-
protocols like TCP sockets for database connections will not work with network
232-
isolation enabled.
293+
Network isolation supports HTTP and HTTPS protocols. If your MCP server needs to
294+
use other protocols (like direct TCP connections for database access), you'll
295+
need to run it without the `--isolate-network` flag and rely on the container's
296+
built-in isolation instead.
233297

234298
:::
235299

docs/toolhive/index.mdx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,11 @@ configurations.
6767
flowchart LR
6868
subgraph container["**Docker/Podman**"]
6969
direction LR
70-
subgraph container1["Container"]
71-
mcp1["MCP Server"]
72-
end
73-
subgraph container2["Container"]
74-
mcp2["MCP Server"]
75-
end
70+
mcp1["MCP server<br>container"]
71+
mcp2["MCP server<br>container"]
7672
end
7773
proxy1["SSE proxy"] -- stdio --> mcp1
78-
proxy2["SSE proxy"] -- stdio --> mcp2
74+
proxy2["SSE proxy"] -- SSE --> mcp2
7975
T["ToolHive CLI"] -- Socket API --> container
8076
C["Client"] -- HTTP/SSE --> proxy1 & proxy2
8177
T ~~~ C

0 commit comments

Comments
 (0)