Skip to content

Commit 3045d10

Browse files
ChrisJBurnsclaude
andcommitted
Update docs for ToolHive v0.17.0
Breaking changes: - Update CRD phase values from Running to Ready for MCPServer, EmbeddingServer, and MCPRegistry across quickstarts, guides, and integration pages - Migrate MCPRegistry examples from v1 flat registries[] format to v2 sources[]/registries[] with configYAML recommended path - Remove PVC source type (no longer supported) - Remove Syncing phase from MCPRegistry status documentation - Remove auto-injection note for Kubernetes discovery sources New features: - Add MCPServerEntry (zero-infrastructure catalog entries) docs to K8s intro and vMCP configuration pages - Add caBundleRef for OTLP endpoints to telemetry guide - Add authServerRef for separating embedded auth from external token exchange to auth guide - Update standalone registry server config to v2 format Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 202f5f2 commit 3045d10

10 files changed

Lines changed: 551 additions & 305 deletions

File tree

docs/toolhive/guides-k8s/auth-k8s.mdx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,36 @@ spec:
652652
kubectl apply -f mcp-server-embedded-auth.yaml
653653
```
654654

655+
:::tip[Combining embedded auth with outgoing token exchange]
656+
657+
If you need both an embedded auth server for incoming client authentication
658+
**and** an outgoing token exchange (such as AWS STS) on the same MCPServer, use
659+
the dedicated `authServerRef` field instead of `externalAuthConfigRef` for the
660+
embedded auth server. This separates the two configurations so they don't
661+
compete for the same field:
662+
663+
```yaml
664+
spec:
665+
# Dedicated field for the embedded auth server
666+
authServerRef:
667+
kind: MCPExternalAuthConfig
668+
name: embedded-auth-server
669+
# Outgoing token exchange (e.g., AWS STS)
670+
externalAuthConfigRef:
671+
name: aws-sts-config
672+
kind: MCPExternalAuthConfig
673+
oidcConfig:
674+
type: inline
675+
inline:
676+
issuer: 'https://mcp.example.com'
677+
```
678+
679+
Both `authServerRef` and `externalAuthConfigRef` cannot point to an
680+
`embeddedAuthServer` type simultaneously. The same `authServerRef` field is
681+
available on MCPRemoteProxy resources.
682+
683+
:::
684+
655685
:::note
656686

657687
The `oidcConfig` issuer must match the `issuer` in your `MCPExternalAuthConfig`.

docs/toolhive/guides-k8s/intro.mdx

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,25 +70,28 @@ or Gateway. To learn how to expose your MCP servers and connect clients, see
7070
The operator introduces three resource types for MCP workloads. Choose based on
7171
where your MCP server runs and how many servers you need to manage:
7272

73-
| Resource | Use when |
74-
| -------------------- | ----------------------------------------------------------------------------------------------------------------- |
75-
| **MCPServer** | Running an MCP server as a container inside your cluster |
76-
| **MCPRemoteProxy** | Connecting to an MCP server hosted outside your cluster (SaaS tools, external APIs, remote endpoints) |
77-
| **VirtualMCPServer** | Aggregating multiple MCPServer and/or MCPRemoteProxy resources behind a single endpoint for a team or application |
73+
| Resource | Use when |
74+
| -------------------- | -------------------------------------------------------------------------------------------------------- |
75+
| **MCPServer** | Running an MCP server as a container inside your cluster |
76+
| **MCPRemoteProxy** | Connecting to an MCP server hosted outside your cluster (SaaS tools, external APIs, remote endpoints) |
77+
| **MCPServerEntry** | Declaring a remote MCP server as a lightweight catalog entry without deploying proxy pods |
78+
| **VirtualMCPServer** | Aggregating multiple MCPServer, MCPRemoteProxy, and/or MCPServerEntry resources behind a single endpoint |
7879

7980
Most teams start with `MCPServer` for container-based servers, add
8081
`MCPRemoteProxy` for external SaaS tools, and graduate to `VirtualMCPServer`
81-
when managing five or more servers or needing centralized authentication.
82+
when managing five or more servers or needing centralized authentication. Use
83+
`MCPServerEntry` instead of `MCPRemoteProxy` when you want to include a remote
84+
server in vMCP discovery without the overhead of running a proxy pod.
8285

8386
The operator also provides shared configuration CRDs that you reference from
8487
workload resources:
8588

86-
| Resource | Purpose |
87-
| ------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------- |
88-
| [**MCPOIDCConfig**](./auth-k8s.mdx#set-up-shared-oidc-configuration-with-mcpoidcconfig) | Shared OIDC authentication settings, referenced via `oidcConfigRef` |
89-
| [**MCPTelemetryConfig**](./telemetry-and-metrics.mdx#shared-telemetry-configuration-recommended) | Shared telemetry/observability settings, referenced via `telemetryConfigRef` |
90-
| [**MCPToolConfig**](./customize-tools.mdx) | Tool filtering and renaming, referenced via `toolConfigRef` |
91-
| [**MCPExternalAuthConfig**](./auth-k8s.mdx#set-up-embedded-authorization-server-authentication) | Token exchange or embedded auth server configuration, referenced via `externalAuthConfigRef` |
89+
| Resource | Purpose |
90+
| ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- |
91+
| [**MCPOIDCConfig**](./auth-k8s.mdx#set-up-shared-oidc-configuration-with-mcpoidcconfig) | Shared OIDC authentication settings, referenced via `oidcConfigRef` |
92+
| [**MCPTelemetryConfig**](./telemetry-and-metrics.mdx#shared-telemetry-configuration-recommended) | Shared telemetry/observability settings, referenced via `telemetryConfigRef` |
93+
| [**MCPToolConfig**](./customize-tools.mdx) | Tool filtering and renaming, referenced via `toolConfigRef` |
94+
| [**MCPExternalAuthConfig**](./auth-k8s.mdx#set-up-embedded-authorization-server-authentication) | Token exchange or embedded auth server configuration, referenced via `externalAuthConfigRef` or `authServerRef` |
9295

9396
## Installation
9497

docs/toolhive/guides-k8s/quickstart.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ kubectl get mcpservers -n toolhive-system
171171
You should see:
172172

173173
```text
174-
NAME STATUS URL AGE
175-
fetch Running http://mcp-fetch-proxy.toolhive-system.svc.cluster.local:8080 30s
174+
NAME STATUS URL AGE
175+
fetch Ready http://mcp-fetch-proxy.toolhive-system.svc.cluster.local:8080 30s
176176
```
177177

178178
If the status is "Pending", wait a few moments and check again. If it remains

docs/toolhive/guides-k8s/telemetry-and-metrics.mdx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,40 @@ spec:
146146
enabled: true
147147
```
148148

149+
#### Custom CA certificates for OTLP endpoints
150+
151+
If your OTLP collector uses TLS with certificates signed by an internal or
152+
private CA, add a `caBundleRef` to your MCPTelemetryConfig. The operator mounts
153+
the referenced ConfigMap into the pod and configures the OTLP exporters to trust
154+
the custom CA alongside the system CA pool.
155+
156+
```yaml title="telemetry-with-ca-bundle.yaml"
157+
apiVersion: toolhive.stacklok.dev/v1alpha1
158+
kind: MCPTelemetryConfig
159+
metadata:
160+
name: shared-otel
161+
namespace: toolhive-system
162+
spec:
163+
openTelemetry:
164+
enabled: true
165+
endpoint: otel-collector.internal:4318
166+
caBundleRef:
167+
configMapRef:
168+
name: otel-ca-bundle
169+
key: ca.crt
170+
tracing:
171+
enabled: true
172+
metrics:
173+
enabled: true
174+
```
175+
176+
:::note
177+
178+
`caBundleRef` cannot be used when `insecure` is set to `true` — they are
179+
mutually exclusive.
180+
181+
:::
182+
149183
### Inline telemetry configuration
150184

151185
:::warning[Deprecated]

docs/toolhive/guides-registry/configuration.mdx

Lines changed: 63 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ pointing to a YAML configuration file.
99

1010
## Configuration file structure
1111

12-
```yaml title="config.yaml"
13-
# Registry name/identifier (optional, defaults to "default")
14-
registryName: my-registry
12+
The configuration file uses a v2 format that separates **data sources** (where
13+
registry data comes from) from **registry views** (logical registries that
14+
aggregate one or more sources).
1515

16-
# Registries configuration (required, can have multiple registries)
17-
registries:
16+
```yaml title="config.yaml"
17+
# Data sources (required, at least one)
18+
sources:
1819
- name: toolhive
1920
# Data format: upstream or toolhive (see below)
2021
format: upstream
@@ -25,12 +26,12 @@ registries:
2526
branch: main
2627
path: pkg/catalog/toolhive/data/registry-upstream.json
2728

28-
# Per-registry automatic sync policy (required for synced registries)
29+
# Per-source automatic sync policy (required for synced sources)
2930
syncPolicy:
3031
# Sync interval (e.g., "30m", "1h", "24h")
3132
interval: '30m'
3233

33-
# Optional: Per-registry server filtering
34+
# Optional: Per-source server filtering
3435
filter:
3536
names:
3637
include: ['official/*']
@@ -39,6 +40,12 @@ registries:
3940
include: ['production']
4041
exclude: ['experimental']
4142

43+
# Registry views (required, at least one)
44+
# Each view references sources by name
45+
registries:
46+
- name: default
47+
sources: ['toolhive']
48+
4249
# Authentication configuration (required)
4350
# See authentication.mdx for detailed configuration options
4451
auth:
@@ -80,10 +87,11 @@ The `format` field specifies the JSON schema format for the registry data:
8087
[ToolHive-native format](../reference/registry-schema-toolhive.mdx), used by
8188
the built-in ToolHive registry.
8289

83-
## Registries
90+
## Sources
8491

85-
The server supports five registry types, each with its own configuration
86-
options. You can configure multiple registries in a single server instance.
92+
The server supports multiple source types, each with its own configuration
93+
options. You can configure multiple sources in a single server instance and
94+
aggregate them into registry views.
8795

8896
### Git repository source
8997

@@ -99,7 +107,7 @@ on every container restart, adding startup latency and increasing network usage.
99107
:::
100108

101109
```yaml title="config-git.yaml"
102-
registries:
110+
sources:
103111
- name: toolhive
104112
format: toolhive
105113
git:
@@ -108,6 +116,9 @@ registries:
108116
path: pkg/catalog/toolhive/data/registry-legacy.json
109117
syncPolicy:
110118
interval: '30m'
119+
registries:
120+
- name: default
121+
sources: ['toolhive']
111122
```
112123
113124
**Configuration options:**
@@ -134,7 +145,7 @@ To access private Git repositories, configure the `auth` section with your
134145
credentials:
135146

136147
```yaml title="config-git-private.yaml"
137-
registries:
148+
sources:
138149
- name: private-registry
139150
format: toolhive
140151
git:
@@ -148,6 +159,9 @@ registries:
148159
# highlight-end
149160
syncPolicy:
150161
interval: '30m'
162+
registries:
163+
- name: default
164+
sources: ['private-registry']
151165
```
152166

153167
**Authentication options:**
@@ -214,13 +228,16 @@ Sync from upstream MCP Registry APIs. Supports federation and aggregation
214228
scenarios.
215229

216230
```yaml title="config-api.yaml"
217-
registries:
231+
sources:
218232
- name: mcp-upstream
219233
format: upstream
220234
api:
221235
endpoint: https://registry.modelcontextprotocol.io
222236
syncPolicy:
223237
interval: '1h'
238+
registries:
239+
- name: default
240+
sources: ['mcp-upstream']
224241
```
225242

226243
**Configuration options:**
@@ -241,26 +258,32 @@ etc.) to the endpoint URL.
241258
Read from filesystem. Ideal for local development and testing.
242259

243260
```yaml title="config-file.yaml"
244-
registries:
261+
sources:
245262
- name: local
246263
format: upstream
247264
file:
248265
path: /data/registry.json
249266
syncPolicy:
250267
interval: '15m'
268+
registries:
269+
- name: default
270+
sources: ['local']
251271
```
252272

253273
Alternatively, the source can be a custom URL.
254274

255-
```yaml title="config-file.yaml"
256-
registries:
275+
```yaml title="config-url.yaml"
276+
sources:
257277
- name: remote
258278
format: upstream
259279
file:
260280
url: https://www.example.com/registry.json
261281
timeout: 5s
262282
syncPolicy:
263283
interval: '15m'
284+
registries:
285+
- name: default
286+
sources: ['remote']
264287
```
265288

266289
The fields `file` and `url` are mutually exclusive.
@@ -280,10 +303,13 @@ API-managed registry for directly publishing and deleting MCP servers via the
280303
API. Does not sync from external sources.
281304

282305
```yaml title="config-managed.yaml"
283-
registries:
306+
sources:
284307
- name: internal
285308
format: upstream
286309
managed: {}
310+
registries:
311+
- name: default
312+
sources: ['internal']
287313
```
288314

289315
**Configuration options:**
@@ -307,15 +333,11 @@ endpoint documentation and request/response examples.
307333
Discovers MCP servers from running Kubernetes deployments. Automatically creates
308334
registry entries for deployed MCP servers in your cluster.
309335

310-
:::note[Operator-managed registry]
311-
312-
When using the ToolHive operator, a single Kubernetes registry named `default`
313-
is automatically created and managed. You cannot configure additional Kubernetes
314-
registries through the `MCPRegistry` CR or configuration file, as only one
315-
Kubernetes registry instance is supported per Registry Server instance.
336+
:::note[Operator deployments]
316337

317-
The configuration example below is for reference when running the Registry
318-
Server standalone (without the operator).
338+
When using the ToolHive operator with the `configYAML` path, you must explicitly
339+
declare Kubernetes discovery sources in your configuration. Only one Kubernetes
340+
source is supported per Registry Server instance.
319341

320342
:::
321343

@@ -326,10 +348,13 @@ By default, the Registry server discovers resources in all namespaces
326348
details and RBAC requirements.
327349

328350
```yaml title="config-kubernetes.yaml"
351+
sources:
352+
- name: k8s
353+
format: upstream
354+
kubernetes: {}
329355
registries:
330356
- name: default
331-
format: toolhive
332-
kubernetes: {}
357+
sources: ['k8s']
333358
```
334359

335360
**Configuration options:**
@@ -431,12 +456,12 @@ resources via a Service Account, check the details in the
431456

432457
## Sync policy
433458

434-
Configure automatic synchronization of registry data on a per-registry basis.
435-
Only applicable to synced registries (Git, API, File). Not required for managed
436-
or Kubernetes registries.
459+
Configure automatic synchronization of registry data on a per-source basis. Only
460+
applicable to synced sources (Git, API, File). Not required for managed or
461+
Kubernetes sources.
437462

438463
```yaml
439-
registries:
464+
sources:
440465
- name: toolhive
441466
git:
442467
repository: https://github.com/stacklok/toolhive-catalog.git
@@ -448,22 +473,22 @@ registries:
448473
```
449474

450475
The `interval` field specifies how often the server should fetch updates from
451-
the registry. Use Go duration format (e.g., `"30m"`, `"1h"`, `"24h"`).
476+
the source. Use Go duration format (e.g., `"30m"`, `"1h"`, `"24h"`).
452477

453478
:::note
454479

455-
Sync policy is per-registry and must be specified within each registry
456-
configuration. Managed and Kubernetes registries do not require sync policies.
480+
Sync policy is per-source and must be specified within each source
481+
configuration. Managed and Kubernetes sources do not require sync policies.
457482

458483
:::
459484

460485
## Server filtering
461486

462-
Optionally filter which servers are exposed through the API on a per-registry
463-
basis. Only applicable to synced registries (Git, API, File).
487+
Optionally filter which servers are exposed through the API on a per-source
488+
basis. Only applicable to synced sources (Git, API, File).
464489

465490
```yaml
466-
registries:
491+
sources:
467492
- name: toolhive
468493
git:
469494
repository: https://github.com/stacklok/toolhive-catalog.git
@@ -489,7 +514,7 @@ registries:
489514

490515
:::note
491516

492-
Filters are per-registry and specified within each registry configuration.
517+
Filters are per-source and specified within each source configuration.
493518

494519
:::
495520

0 commit comments

Comments
 (0)