first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:52:23 +03:00
commit 880f412e2c
2662 changed files with 866266 additions and 0 deletions

495
docs/mcp/filtering.mdx Normal file
View File

@@ -0,0 +1,495 @@
---
title: "Tool Filtering"
sidebarTitle: "Filtering"
description: "Control which MCP tools are available at the client, request, and virtual key levels."
icon: "filter"
---
## Overview
Bifrost provides **three levels of tool filtering** to control which MCP tools are available:
1. **Client Configuration** - Set which tools a client can execute (`tools_to_execute`)
2. **Request Headers** - Filter tools per-request via HTTP headers or context
3. **Virtual Key Configuration** - Control tools per-VK (Gateway only)
These levels stack: a tool must pass all applicable filters to be available.
```mermaid
graph LR
All["<b>Available<br/>Tools</b>"]
Client["<b>Client Config</b><br/>tools_to_execute"]
Request["<b>Request<br/>Headers</b>"]
VK["<b>Virtual Key<br/>Filter</b>"]
Final["<b>Tools<br/>for LLM</b>"]
All --> Client
Client --> Request
Request --> VK
VK --> Final
style All fill:#EEEEEE,stroke:#424242,stroke-width:2.5px,color:#1A1A1A
style Client fill:#E3F2FD,stroke:#0D47A1,stroke-width:2.5px,color:#1A1A1A
style Request fill:#F3E5F5,stroke:#4A148C,stroke-width:2.5px,color:#1A1A1A
style VK fill:#E8F5E9,stroke:#1B5E20,stroke-width:2.5px,color:#1A1A1A
style Final fill:#FFFDE7,stroke:#F57F17,stroke-width:2.5px,color:#1A1A1A
```
---
## Level 1: Client Configuration
The `tools_to_execute` field on each MCP client config defines the **baseline** of available tools.
### Semantics
| Value | Behavior |
|-------|----------|
| `["*"]` | All tools from this client are available |
| `[]` or omitted | No tools available (deny-by-default) |
| `["tool1", "tool2"]` | Only specified tools are available |
### Configuration
<Tabs>
<Tab title="Gateway">
```bash
curl -X POST http://localhost:8080/api/mcp/client \
-H "Content-Type: application/json" \
-d '{
"name": "filesystem",
"connection_type": "stdio",
"stdio_config": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-filesystem"]
},
"tools_to_execute": ["read_file", "list_directory"]
}'
```
</Tab>
<Tab title="Go SDK">
```go
mcpConfig := &schemas.MCPConfig{
ClientConfigs: []schemas.MCPClientConfig{
{
Name: "filesystem",
ConnectionType: schemas.MCPConnectionTypeSTDIO,
StdioConfig: &schemas.MCPStdioConfig{
Command: "npx",
Args: []string{"-y", "@anthropic/mcp-filesystem"},
},
ToolsToExecute: []string{"read_file", "list_directory"}, // Only these tools
},
},
}
```
</Tab>
<Tab title="config.json">
```json
{
"mcp": {
"client_configs": [
{
"name": "filesystem",
"connection_type": "stdio",
"stdio_config": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-filesystem"]
},
"tools_to_execute": ["read_file", "list_directory"]
}
]
}
}
```
</Tab>
</Tabs>
---
## Level 2: Request-Level Filtering
Filter tools dynamically on a per-request basis using headers (Gateway) or context values (SDK).
### Available Filters
| Filter | Purpose |
|--------|---------|
| `mcp-include-clients` | Only include tools from specified clients |
| `mcp-include-tools` | Only include specified tools (format: `clientName-toolName`) |
### Gateway Headers
```bash
# Include only specific clients
curl -X POST http://localhost:8080/v1/chat/completions \
-H "x-bf-mcp-include-clients: filesystem,web_search" \
-d '...'
# Include only specific tools
curl -X POST http://localhost:8080/v1/chat/completions \
-H "x-bf-mcp-include-tools: filesystem-read_file,web_search-search" \
-d '...'
# Include all tools from one client, specific tools from another
curl -X POST http://localhost:8080/v1/chat/completions \
-H "x-bf-mcp-include-tools: filesystem-*,web_search-search" \
-d '...'
# Include internal tools registered via RegisterTool()
curl -X POST http://localhost:8080/v1/chat/completions \
-H "x-bf-mcp-include-tools: bifrostInternal-echo,bifrostInternal-calculator" \
-d '...'
# Empty clients filter blocks ALL tools - no tools available to LLM
curl -X POST http://localhost:8080/v1/chat/completions \
-H "x-bf-mcp-include-clients:" \
-d '...'
# Result: No MCP tools available (deny-all)
# Empty tools filter also blocks ALL tools
curl -X POST http://localhost:8080/v1/chat/completions \
-H "x-bf-mcp-include-tools:" \
-d '...'
# Result: No MCP tools available (deny-all)
```
### Go SDK Context Values
```go
// Include only specific clients
ctx := context.WithValue(context.Background(),
schemas.BifrostContextKey("mcp-include-clients"),
[]string{"filesystem", "web_search"})
// Include only specific tools
ctx = context.WithValue(ctx,
schemas.BifrostContextKey("mcp-include-tools"),
[]string{"filesystem-read_file", "web_search-search"})
// Wildcard for all tools from a client
ctx = context.WithValue(ctx,
schemas.BifrostContextKey("mcp-include-tools"),
[]string{"filesystem-*", "web_search-search"})
// Include all internal tools (registered via RegisterTool)
ctx = context.WithValue(ctx,
schemas.BifrostContextKey("mcp-include-tools"),
[]string{"bifrostInternal-*"})
response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), request)
// Empty include-clients blocks ALL tools - no tools available
ctx = context.WithValue(context.Background(),
schemas.BifrostContextKey("mcp-include-clients"),
[]string{}) // Empty slice = deny-all
// Result: No MCP tools available to LLM
// Empty include-tools also blocks ALL tools
ctx = context.WithValue(context.Background(),
schemas.BifrostContextKey("mcp-include-tools"),
[]string{}) // Empty slice = deny-all
// Result: No MCP tools available to LLM
```
### Wildcard Support
| Pattern | Meaning |
|---------|---------|
| `*` (in include-clients) | Include all clients |
| `clientName-*` (in include-tools) | Include all tools from that client |
| `clientName-toolName` | Include specific tool |
### Tool Naming Convention
**Important:** All MCP tools follow a consistent naming convention using the **prefixed format** `clientName-toolName`:
- **External MCP Clients** (HTTP, SSE, STDIO): Tools use the format `clientName-toolName`
- Example: `filesystem-read_file`, `web_search-search`
- The `clientName` is the name configured for the MCP client
- **Internal (In-Process) Tools**: Tools registered via `RegisterTool()` use the prefix `bifrostInternal-`
- Example: `bifrostInternal-echo`, `bifrostInternal-my_custom_tool`
- These tools are registered via `RegisterTool()` in the SDK
This consistent naming convention ensures clear separation between tools from different clients and prevents naming conflicts across all MCP client types.
---
## Level 3: Virtual Key Filtering (Gateway Only)
Virtual Keys can have their own MCP tool access configuration, which **takes precedence** over request-level headers.
<Note>
When a Virtual Key has no MCP configurations, **no MCP tools are available** (deny-by-default). You must explicitly add MCP client configurations to allow tools. When a Virtual Key has MCP configurations, it generates the `x-bf-mcp-include-tools` header automatically, overriding any manually sent header.
</Note>
### Configuration
<Tabs>
<Tab title="Web UI">
1. Navigate to **Virtual Keys** in the governance section
2. Create or edit a Virtual Key
3. In **MCP Client Configurations**, add the clients and tools this VK can access
<Frame>
<img src="/media/ui-virtual-key-mcp-filter.png" alt="Virtual Key MCP Configuration" />
</Frame>
</Tab>
<Tab title="API">
```bash
curl -X POST http://localhost:8080/api/governance/virtual-keys \
-H "Content-Type: application/json" \
-d '{
"name": "support-team-key",
"mcp_configs": [
{
"mcp_client_name": "knowledge_base",
"tools_to_execute": ["search", "get_article"]
},
{
"mcp_client_name": "ticketing",
"tools_to_execute": ["*"]
}
]
}'
```
</Tab>
<Tab title="config.json">
```json
{
"governance": {
"virtual_keys": [
{
"name": "support-team-key",
"mcp_configs": [
{
"mcp_client_name": "knowledge_base",
"tools_to_execute": ["search", "get_article"]
},
{
"mcp_client_name": "ticketing",
"tools_to_execute": ["*"]
}
]
}
]
}
}
```
</Tab>
</Tabs>
### Virtual Key MCP Config Semantics
| Configuration | Result |
|---------------|--------|
| `tools_to_execute: ["*"]` | All tools from this client |
| `tools_to_execute: []` | No tools from this client |
| `tools_to_execute: ["a", "b"]` | Only specified tools |
| Client not configured | All tools blocked from that client |
Learn more in [MCP Tool Filtering for Virtual Keys](../features/governance/mcp-tools).
---
## Filtering Logic
### How Filters Combine
1. **Client config** is the baseline (must include the tool)
2. **Request filters** further narrow down (if specified)
3. **VK filters** override request filters (if VK has MCP configs)
### Example Scenario
**Setup:**
- Client `filesystem` has `tools_to_execute: ["read_file", "write_file", "delete_file"]`
- Virtual Key `prod-key` has `mcp_configs: [{ mcp_client_name: "filesystem", tools_to_execute: ["read_file"] }]`
**Request with `prod-key`:**
```bash
curl -X POST http://localhost:8080/v1/chat/completions \
-H "Authorization: Bearer vk_prod_key" \
-H "x-bf-mcp-include-tools: filesystem-write_file" \ # This is IGNORED
-d '...'
```
**Result:** Only `read_file` is available (VK config overrides request header)
**Request without VK (if allowed):**
```bash
curl -X POST http://localhost:8080/v1/chat/completions \
-H "x-bf-mcp-include-tools: filesystem-write_file" \
-d '...'
```
**Result:** Only `write_file` is available (request header applies)
---
## Common Patterns
### Read-Only Access
Allow only read operations:
```json
{
"tools_to_execute": ["read_file", "list_directory", "get_file_info"]
}
```
### Environment-Based Filtering
Use different VKs for different environments:
```json
{
"virtual_keys": [
{
"name": "development",
"mcp_configs": [
{ "mcp_client_name": "filesystem", "tools_to_execute": ["*"] },
{ "mcp_client_name": "database", "tools_to_execute": ["*"] }
]
},
{
"name": "production",
"mcp_configs": [
{ "mcp_client_name": "filesystem", "tools_to_execute": ["read_file"] },
{ "mcp_client_name": "database", "tools_to_execute": ["query"] }
]
}
]
}
```
### Per-User Tool Access
Create VKs for different user roles:
```json
{
"virtual_keys": [
{
"name": "viewer-role",
"mcp_configs": [
{ "mcp_client_name": "documents", "tools_to_execute": ["view", "search"] }
]
},
{
"name": "editor-role",
"mcp_configs": [
{ "mcp_client_name": "documents", "tools_to_execute": ["view", "search", "edit", "create"] }
]
},
{
"name": "admin-role",
"mcp_configs": [
{ "mcp_client_name": "documents", "tools_to_execute": ["*"] }
]
}
]
}
```
---
## Advanced: Context-Based Filtering
For SDK users, filtering can be applied at the context level, enabling per-request tool customization:
### Go SDK Context Filtering
```go
import (
"context"
"github.com/maximhq/bifrost/core/schemas"
)
// Filter to specific clients
ctx := context.WithValue(
context.Background(),
schemas.BifrostContextKey("mcp-include-clients"),
[]string{"filesystem", "web_search"},
)
// Or filter to specific tools
ctx = context.WithValue(
ctx,
schemas.BifrostContextKey("mcp-include-tools"),
[]string{"filesystem-read_file", "web_search-search"},
)
// Request will only see filtered tools
response, _ := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), request)
```
### Filter Precedence
When multiple filters apply, they combine as an intersection (AND logic):
```
Client Config Tools ∩ Request Filters ∩ VK Filters = Available Tools
```
**Example:**
- Client config allows: [read_file, write_file, delete_file]
- Request header specifies: [read_file, write_file]
- VK config restricts to: [read_file]
- **Result:** Only [read_file] available
---
## Debugging Tool Availability
### Check Available Tools
**Gateway API:**
```bash
curl http://localhost:8080/api/mcp/clients
```
**Response shows tools per client:**
```json
[
{
"config": { "name": "filesystem", "tools_to_execute": ["read_file", "write_file"] },
"tools": [
{ "name": "read_file", "description": "Read file contents" },
{ "name": "write_file", "description": "Write to file" }
],
"state": "connected"
}
]
```
### Check What LLM Receives
The tools included in a chat request depend on all active filters. To see what tools are available for a specific request, check the request body sent to the LLM provider in your logs or observability platform.
---
## Next Steps
<CardGroup cols={2}>
<Card title="Virtual Key MCP Tools" icon="key" href="../features/governance/mcp-tools">
Detailed VK tool configuration
</Card>
<Card title="Agent Mode" icon="robot" href="./agent-mode">
Configure auto-execution for filtered tools
</Card>
</CardGroup>