Add ExcludeAll option for tool filtering in VirtualMCPServer aggregation
Problem
The current WorkloadToolConfig.Filter field is an allow-list of tool names:
Filter: ["tool1", "tool2"]→ allows only those toolsFilter: []orFilter: nil→ allows ALL tools (no filtering applied)
There's no way to exclude all tools from a backend in VirtualMCPServer aggregation. This limits flexibility in several scenarios:
- Composite-only VirtualMCPServer: You want to expose only composite tools without any direct backend tools
- Temporary disabling: Disable all tools from a backend without removing it from the group
- Selective enablement: Keep group membership but control tool exposure at the VirtualMCPServer level
Technical Context
Using Go's nil vs empty slice distinction (nil = allow all, [] = allow none) is elegant but problematic with Kubernetes CRDs due to JSON serialization with omitempty - the distinction is lost after API server round-trips.
Proposed Solution
1. Per-workload excludeAll boolean
Add an ExcludeAll field to WorkloadToolConfig:
spec:
aggregation:
tools:
- workload: backend-a
filter: ["echo"] # Allow only echo tool
- workload: backend-b
excludeAll: true # Exclude all tools from this backend
type WorkloadToolConfig struct {
Workload string `json:"workload"`
Filter []string `json:"filter,omitempty"`
Overrides map[string]... `json:"overrides,omitempty"`
ExcludeAll bool `json:"excludeAll,omitempty"` // NEW
}
2. Global excludeAllTools at aggregation level
Add a global flag to exclude all tools from all backends, useful for composite-only VirtualMCPServers:
spec:
aggregation:
excludeAllTools: true # Exclude all backend tools globally
conflictResolution: prefix
composite:
tools:
- name: my-workflow
# ... composite tool definition
type AggregationConfig struct {
ConflictResolution string `json:"conflictResolution,omitempty"`
Tools []WorkloadToolConfig `json:"tools,omitempty"`
ExcludeAllTools bool `json:"excludeAllTools,omitempty"` // NEW
}
This enables a clean pattern for composite-only VirtualMCPServers that orchestrate backend tools without exposing them directly.
Behavior Matrix
| Config | Behavior |
|---|---|
excludeAllTools: true |
All backend tools excluded globally |
excludeAll: true (per-workload) |
All tools from that specific backend excluded |
filter: ["tool1"] |
Only listed tools allowed |
filter: [] or omitted |
All tools allowed (current behavior) |
Use Case Example
Expose only a composite workflow tool, hiding the underlying backend tools:
apiVersion: mcp.toolhive.stacklok.com/v1alpha1
kind: VirtualMCPServer
metadata:
name: workflow-only-vmcp
spec:
groupRef:
name: my-backends
aggregation:
excludeAllTools: true # Hide all direct backend tools
composite:
tools:
- name: analyze-and-report
description: "Runs analysis workflow across multiple backends"
steps:
- name: fetch-data
tool: backend-a/fetch
- name: process
tool: backend-b/process
dependsOn: [fetch-data]
Clients see only analyze-and-report, not the underlying fetch or process tools.
Hey, can do this task ?
@ignorant05 of course!