Skip to content

Commit 49dfc07

Browse files
committed
docs(k8s): org-scoped GitHub example for MCPToolConfig\n- Rename tools per org (acme/foocorp)\n- Update filters to use overridden names\n- Add concise notes on empty filter and override filtering
1 parent 02803cc commit 49dfc07

File tree

1 file changed

+83
-115
lines changed

1 file changed

+83
-115
lines changed

docs/toolhive/guides-k8s/tool-config.mdx

Lines changed: 83 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -28,196 +28,164 @@ apiVersion: toolhive.stacklok.dev/v1alpha1
2828
kind: MCPToolConfig
2929
metadata:
3030
name: basic-tool-filter
31-
namespace: default
31+
namespace: toolhive-system
3232
spec:
3333
toolsFilter:
3434
- read_file
3535
- write_file
3636
- list_directory
3737
```
3838
39+
:::note[Empty filter] If `toolsFilter` is omitted or empty, all tools are
40+
allowed. :::
41+
3942
## Rename tools and override descriptions
4043

41-
You can rename tools to match your team's conventions and refine their
42-
descriptions:
44+
You can rename tools to clearly distinguish different deployments or scopes, and
45+
refine their descriptions to add usage guidance.
46+
47+
A common pattern is running the same MCP server multiple times for different
48+
scopes (for example, separate GitHub orgs, repos, or environments). Renaming
49+
tools makes intent obvious and helps prevent mistakes.
4350

4451
```yaml title="toolconfig-with-overrides.yaml"
4552
apiVersion: toolhive.stacklok.dev/v1alpha1
4653
kind: MCPToolConfig
4754
metadata:
4855
name: github-tools-config
49-
namespace: default
56+
namespace: toolhive-system
5057
spec:
58+
# Only expose GitHub PR-related tools
5159
toolsFilter:
5260
- create_pull_request
5361
- get_pull_request
5462
- list_pull_requests
5563
- merge_pull_request
64+
65+
# You can override name, description, or both (they are independent)
5666
toolsOverride:
67+
# Override only the name
5768
create_pull_request:
5869
name: github_create_pr
59-
description: Create a new GitHub pull request
70+
71+
# Override only the description (keep the original name)
6072
get_pull_request:
61-
name: github_get_pr
62-
description: Retrieve details of a GitHub pull request
73+
description: Retrieve details of a specific GitHub pull request
74+
75+
# Override both name and description
6376
list_pull_requests:
6477
name: github_list_prs
6578
description: List pull requests in a repository
79+
6680
merge_pull_request:
6781
name: github_merge_pr
6882
description: Merge a GitHub pull request
6983
```
7084

71-
The key in the `toolsOverride` object is the _original tool name_, while the
72-
`name` field contains the _new name_ that clients will see.
85+
The key in the `toolsOverride` map is the original tool name; the `name` field is the user-visible (overridden) name.
86+
87+
:::info[Override fields]
88+
You can override name or description independently. Leave one unset to keep the original value from the MCP server. Both fields cannot be empty at the same time.
89+
:::
90+
91+
:::tip[When to rename?]
92+
If you run the same server for different scopes (for example, prod vs. sandbox), use distinct tool names like `github_prod_create_pr` and `github_sandbox_create_pr` to make intent clear to clients.
93+
:::
7394

7495
## Reference the configuration from an MCP server
7596

76-
Add toolConfigRef to your MCPServer. toolConfigRef overrides spec.tools
77-
(deprecated).
97+
Add `toolConfigRef` to your `MCPServer`. `toolConfigRef` takes precedence over
98+
the deprecated `spec.tools` field on `MCPServer`.
7899

79100
```yaml {12-13} title="mcpserver-with-toolconfig.yaml"
80101
apiVersion: toolhive.stacklok.dev/v1alpha1
81102
kind: MCPServer
82103
metadata:
83-
name: mkp
104+
name: github
84105
namespace: toolhive-system
85106
spec:
86-
image: ghcr.io/stackloklabs/mkp/server:0.2.3
87-
transport: streamable-http
88-
targetPort: 8080
107+
image: ghcr.io/github/github-mcp-server
108+
transport: stdio
89109
port: 8080
90-
serviceAccount: mkp-sa
91110
toolConfigRef:
92-
name: mkp-tools
93-
args:
94-
- '--read-write=true'
111+
name: github-tools-config
95112
```
96113

97-
## End‑to‑end example (cluster‑scoped RBAC)
114+
:::note[Filtering and overrides together] When you use `toolsFilter` and
115+
`toolsOverride` together, filter by the user-visible (overridden) names. Tool
116+
calls using overridden names are forwarded to the actual tool. :::
117+
118+
## Example: org-scoped tool names
98119

99-
The following manifest shows a minimal, end‑to‑end setup that runs the MKP
100-
server inside the cluster, grants it wide permissions (for demo only), defines
101-
an MCPToolConfig, and references it from the server:
120+
Run the GitHub MCP twice, once per organization, and rename tools so intent is
121+
clear to clients.
102122

103-
```yaml title="mkp-with-toolconfig.yaml"
104-
apiVersion: v1
105-
kind: ServiceAccount
123+
```yaml title="github-org-scoped-tools.yaml"
124+
apiVersion: toolhive.stacklok.dev/v1alpha1
125+
kind: MCPToolConfig
106126
metadata:
107-
name: mkp-sa
127+
name: github-acme-tools
108128
namespace: toolhive-system
109-
---
110-
apiVersion: rbac.authorization.k8s.io/v1
111-
kind: ClusterRole
112-
metadata:
113-
name: mkp-cluster-role
114-
rules:
115-
- apiGroups: ['*']
116-
resources: ['*']
117-
verbs: ['*']
118-
---
119-
apiVersion: rbac.authorization.k8s.io/v1
120-
kind: ClusterRoleBinding
121-
metadata:
122-
name: mkp-cluster-role-binding
123-
roleRef:
124-
apiGroup: rbac.authorization.k8s.io
125-
kind: ClusterRole
126-
name: mkp-cluster-role
127-
subjects:
128-
- kind: ServiceAccount
129-
name: mkp-sa
130-
namespace: toolhive-system
129+
spec:
130+
toolsFilter:
131+
- github_acme_create_pr
132+
- github_acme_get_pr
133+
toolsOverride:
134+
create_pull_request:
135+
name: github_acme_create_pr
136+
get_pull_request:
137+
name: github_acme_get_pr
131138
---
132139
apiVersion: toolhive.stacklok.dev/v1alpha1
133140
kind: MCPToolConfig
134141
metadata:
135-
name: mkp-tools
142+
name: github-foocorp-tools
136143
namespace: toolhive-system
137144
spec:
138145
toolsFilter:
139-
- homelab_k8s_apply_resource
140-
- homelab_k8s_delete_resource
141-
- homelab_k8s_get_resource
142-
- homelab_k8s_list_resources
143-
- homelab_k8s_post_resource
146+
- github_foocorp_create_pr
147+
- github_foocorp_get_pr
144148
toolsOverride:
145-
apply_resource:
146-
name: homelab_k8s_apply_resource
147-
description: |
148-
Apply (create or update) a Kubernetes resource.
149-
Required:
150-
- resource: plural resource name (e.g., deployments, services)
151-
- version: API version (e.g., v1, v1beta1)
152-
- manifest: full resource manifest (apiVersion, kind, metadata, spec)
153-
Optional:
154-
- group: API group (e.g., apps, networking.k8s.io)
155-
- resource_type: clustered|namespaced (default inferred from resource; use namespaced and provide namespace when required)
156-
- namespace: target namespace for namespaced resources
157-
delete_resource:
158-
name: homelab_k8s_delete_resource
159-
description: |
160-
Delete a Kubernetes resource.
161-
Required:
162-
- resource, version, name
163-
Optional:
164-
- group, namespace (for namespaced resources)
165-
get_resource:
166-
name: homelab_k8s_get_resource
167-
description: |
168-
Get a Kubernetes resource or its subresource (e.g., status, scale, logs).
169-
- For pod logs, supported parameters include: container, previous, sinceSeconds, sinceTime, timestamps, limitBytes, tailLines.
170-
- For subresources, set subresource: status|scale|logs etc.
171-
- For namespaced resources, set namespace.
172-
list_resources:
173-
name: homelab_k8s_list_resources
174-
description: |
175-
List Kubernetes resources with flexible filtering.
176-
Supported parameters:
177-
- namespace (for namespaced resources)
178-
- label_selector
179-
- include_annotations (bool), include_annotation_keys, exclude_annotation_keys (wildcards supported with *)
180-
- limit (0 = no limit), continue (for pagination)
181-
post_resource:
182-
name: homelab_k8s_post_resource
183-
description: |
184-
Post to a Kubernetes resource or subresource (e.g., exec).
185-
- Provide body according to subresource.
186-
- For exec, body fields: command (string or array), container (optional), timeout (seconds, optional).
187-
- For namespaced resources, set namespace.
149+
create_pull_request:
150+
name: github_foocorp_create_pr
151+
get_pull_request:
152+
name: github_foocorp_get_pr
188153
---
189154
apiVersion: toolhive.stacklok.dev/v1alpha1
190155
kind: MCPServer
191156
metadata:
192-
name: mkp
157+
name: github-acme
193158
namespace: toolhive-system
194159
spec:
195-
image: ghcr.io/stackloklabs/mkp/server:0.2.3
196-
transport: streamable-http
197-
targetPort: 8080
160+
image: ghcr.io/github/github-mcp-server
161+
transport: stdio
198162
port: 8080
199-
serviceAccount: mkp-sa
163+
# (Use credentials that scope access to the acme-org here)
200164
toolConfigRef:
201-
name: mkp-tools
202-
args:
203-
- '--read-write=true'
165+
name: github-acme-tools
166+
---
167+
apiVersion: toolhive.stacklok.dev/v1alpha1
168+
kind: MCPServer
169+
metadata:
170+
name: github-foocorp
171+
namespace: toolhive-system
172+
spec:
173+
image: ghcr.io/github/github-mcp-server
174+
transport: stdio
175+
port: 8080
176+
# (Use credentials that scope access to the foo-corp org here)
177+
toolConfigRef:
178+
name: github-foocorp-tools
204179
```
205180

206-
:::warning[Least privilege]
207-
208-
The ClusterRole above is intentionally broad for demonstration. In production,
209-
scope permissions to the minimum your workflows require.
210-
211-
:::
212-
213181
## Inspect status and troubleshoot
214182

215183
Use kubectl to inspect status and track change propagation:
216184

217185
```bash
218186
kubectl -n toolhive-system get mcptoolconfigs
219-
kubectl -n toolhive-system get mcptoolconfig mkp-tools -o yaml
220-
kubectl -n toolhive-system get mcpserver mkp -o yaml
187+
kubectl -n toolhive-system get mcptoolconfig github-tools-config -o yaml
188+
kubectl -n toolhive-system get mcpserver github -o yaml
221189
```
222190

223191
- If an MCPToolConfig is still referenced, deletion is blocked by a finalizer.

0 commit comments

Comments
 (0)