Skip to content
Open
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
30 changes: 30 additions & 0 deletions docs/toolhive/guides-k8s/auth-k8s.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,36 @@ spec:
kubectl apply -f mcp-server-embedded-auth.yaml
```

:::tip[Combining embedded auth with outgoing token exchange]

If you need both an embedded auth server for incoming client authentication
**and** an outgoing token exchange (such as AWS STS) on the same MCPServer, use
the dedicated `authServerRef` field instead of `externalAuthConfigRef` for the
embedded auth server. This separates the two configurations so they don't
compete for the same field:

```yaml
spec:
# Dedicated field for the embedded auth server
authServerRef:
kind: MCPExternalAuthConfig
name: embedded-auth-server
# Outgoing token exchange (e.g., AWS STS)
externalAuthConfigRef:
name: aws-sts-config
kind: MCPExternalAuthConfig
oidcConfig:
type: inline
inline:
issuer: 'https://mcp.example.com'
```

Both `authServerRef` and `externalAuthConfigRef` cannot point to an
`embeddedAuthServer` type simultaneously. The same `authServerRef` field is
available on MCPRemoteProxy resources.

:::

:::note

The `oidcConfig` issuer must match the `issuer` in your `MCPExternalAuthConfig`.
Expand Down
29 changes: 16 additions & 13 deletions docs/toolhive/guides-k8s/intro.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -67,28 +67,31 @@ or Gateway. To learn how to expose your MCP servers and connect clients, see

## Which resource type should I use?

The operator introduces three resource types for MCP workloads. Choose based on
The operator introduces four resource types for MCP workloads. Choose based on
where your MCP server runs and how many servers you need to manage:

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

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

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

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

## Installation

Expand Down
4 changes: 2 additions & 2 deletions docs/toolhive/guides-k8s/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ kubectl get mcpservers -n toolhive-system
You should see:

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

If the status is "Pending", wait a few moments and check again. If it remains
Expand Down
34 changes: 34 additions & 0 deletions docs/toolhive/guides-k8s/telemetry-and-metrics.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,40 @@ spec:
enabled: true
```

#### Custom CA certificates for OTLP endpoints

If your OTLP collector uses TLS with certificates signed by an internal or
private CA, add a `caBundleRef` to your MCPTelemetryConfig. The operator mounts
the referenced ConfigMap into the pod and configures the OTLP exporters to trust
the custom CA alongside the system CA pool.

```yaml title="telemetry-with-ca-bundle.yaml"
apiVersion: toolhive.stacklok.dev/v1alpha1
kind: MCPTelemetryConfig
metadata:
name: shared-otel
namespace: toolhive-system
spec:
openTelemetry:
enabled: true
endpoint: otel-collector.internal:4318
caBundleRef:
configMapRef:
name: otel-ca-bundle
key: ca.crt
tracing:
enabled: true
metrics:
enabled: true
```

:::note

`caBundleRef` cannot be used when `insecure` is set to `true` — they are
mutually exclusive.

:::

### Inline telemetry configuration

:::warning[Deprecated]
Expand Down
Loading