代理MCP网关
A. 模型上下文协议(MCP) 聚合多个MCP服务器并为代理和子代理提供基于策略的访问控制的网关。通过启用按需工具发现而不是预先加载所有工具定义,解决了Claude Code的MCP上下文窗口浪费问题。
状态
- ✅ M0:基础 -配置、策略引擎、审计日志记录,
list_servers工具 - ✅ M1:核心 -代理基础设施,
get_server_tools,execute_tool、中间件、指标、热重载、OAuth支持 - 🚧 M2:生产 -HTTP传输、健康检查(计划中)
- 🚧 M3:DX -单代理模式、配置验证CLI、Docker(计划中)
当前版本: M1核心完成(使用OAuth)
目录
概述
问题
当在开发环境中配置多个MCP服务器(Claude Code、Cursor、VS Code)时,所有服务器的所有工具定义在启动时都会加载到每个代理和子代理的上下文窗口中:
- 预付5000-50000多个代币
- 80-95%的加载工具从未被单个代理使用过
- 实际工作所需的上下文被浪费在未使用的工具定义上
解决方案
代理MCP网关充当单个MCP服务器,根据可配置的每个代理规则代理多个下游MCP服务器:
- 3网关工具 启动时加载(约2k个令牌)
- 代理按需发现并请求特定工具
- 90%+上下文减少
- 每个代理/子代理的基于策略的访问控制
运作原理
Agent MCP Gateway Architecture
网关位于代理和下游MCP服务器之间,只暴露了3个轻量级工具。当代理需要特定功能时,它会通过网关发现可用的服务器和工具,网关会根据策略规则过滤可见性——代理只看到他们有权访问的服务器和刀具。这将每个代理的上下文窗口缩小到只有相关的工具,而网关则处理向下游服务器代理授权请求。
查看带有示例的详细图表→ (包括下游服务器、工具和网关规则示例)
主要特点
- ✅ 按需工具发现 -仅在需要时加载工具定义
- ✅ 每个代理访问控制 -配置每个代理可以访问的服务器/工具
- ✅ 轻松集成代理 -为任何代理添加网关支持的简单模板(请参阅指南)
- ✅ 先拒绝后允许策略 -明确的拒绝规则优先
- ✅ 通配符支持 -工具名称的模式匹配(
get_*,*_user) - ✅ 会话隔离 -并发请求不会干扰
- ✅ 透明代理 -下游服务器不知道网关
- ✅ 审计日志 -记录所有操作以供监控
- ✅ 性能指标 -跟踪每个代理/操作的延迟和错误率
- ✅ 热配置重新加载 -无需重新启动即可更新规则/服务器
- ✅ 线程安全操作 -重新加载期间的安全并发访问
- ✅ 诊断工具 -通过以下方式进行健康监测
get_gateway_status(仅调试模式)
安装
# Creates ~/.config/agent-mcp-gateway/ with template configuration files
uvx agent-mcp-gateway --init这将生成两个可自定义的模板文件:
mcp.json-您的下游MCP服务器(Brave、Postgres等)mcp-gateway-rules.json-每个代理的访问策略(谁可以使用哪些服务器/工具)
对于当地发展: 看 发展 部分。
快速开始
1.配置网关文件
运行后 uvx agent-mcp-gateway --init (参见 安装),编辑生成的模板文件:
# Define your downstream MCP servers
nano ~/.config/agent-mcp-gateway/.mcp.json
# Define agent access policies
nano ~/.config/agent-mcp-gateway/.mcp-gateway-rules.json2.将网关添加到MCP客户端
克劳德代码CLI:
claude mcp add agent-mcp-gateway uvx agent-mcp-gateway手动配置:
{
"mcpServers": {
"agent-mcp-gateway": {
"command": "uvx",
"args": ["agent-mcp-gateway"],
"env": {
"GATEWAY_MCP_CONFIG": "~/.config/agent-mcp-gateway/.mcp.json",
"GATEWAY_RULES": "~/.config/agent-mcp-gateway/.mcp-gateway-rules.json",
"GATEWAY_DEFAULT_AGENT": "developer"
}
}
}
}注: 这 env 如果使用默认配置位置,变量是可选的。看 环境变量引用 对于所有选项。
3.配置您的代理
网关的工具描述是自文档化的,但为了进行适当的访问控制,您应该配置代理如何识别自己。选择适合您用例的方法:
方法1:多代理模式(推荐)
对于具有不同权限的不同代理,配置每个代理以传递其身份。
将此添加到代理的系统提示中 (例如。, CLAUDE.md, .claude/agents/agent-name.md):
## MCP Gateway Access
**Available Tools (via agent-mcp-gateway):**
You have access to MCP servers through the agent-mcp-gateway. The specific servers and tools available to you are determined by the gateway's access control rules.
**Tool Discovery Process:**
When you need to use tools from downstream MCP servers:
1. Use `agent_id: "YOUR_AGENT_NAME"` in ALL gateway tool calls for proper access control
2. Call `list_servers` to discover which servers you have access to
3. Call `get_server_tools` with the specific server name to discover available tools
4. Use `execute_tool` to invoke tools with appropriate parameters
5. If you cannot access a tool you need, immediately notify the user
**Important:** Always include `agent_id: "YOUR_AGENT_NAME"` in your gateway tool calls. This ensures proper access control and audit logging.替换 YOUR_AGENT_NAME 使用代理的标识符(例如,“研究员”、“后端”、“管理员”)。
示例: 看 .claude/agents/researcher.md 和 .claude/agents/mcp-developer.md 查看完整的配置示例。
方法2:单代理模式
对于所有代理都应具有相同权限的更简单的设置,或者在使用没有系统提示配置的MCP客户端时(例如Claude Desktop),请使用以下任一方法配置默认代理:
选项A:环境变量
# Set in your MCP client configuration
export GATEWAY_DEFAULT_AGENT=developer注: 指定的代理(例如“开发人员”)必须存在于您的 .mcp-gateway-rules.json 具有适当权限的文件。
选项B:规则中的“默认”代理
{
"agents": {
"default": {
"allow": {
"servers": ["*"]
}
}
},
"defaults": {
"deny_on_missing_agent": false
}
}注: 允许所有服务器("servers": ["*"])在不指定工具限制的情况下,授予对所有服务器上所有工具的访问权限。
无论哪种方法,代理都可以省略 agent_id 在工具调用中,网关会自动使用您配置的默认代理。
命令行选项
# Show version
agent-mcp-gateway --version
# Initialize config directory (first-time setup)
agent-mcp-gateway --init
# Enable debug mode (exposes get_gateway_status diagnostic tool)
agent-mcp-gateway --debug
# Show help
agent-mcp-gateway --help配置文件发现
网关按以下顺序搜索配置文件:
MCP服务器配置(.MCP.json)
GATEWAY_MCP_CONFIG环境变量(如果设置).mcp.json在当前目录中~/.config/agent-mcp-gateway/.mcp.json(主目录)./config/.mcp.json(回退)
网关规则(.mcp网关规则.json)
GATEWAY_RULES环境变量(如果设置).mcp-gateway-rules.json在当前目录中~/.config/agent-mcp-gateway/.mcp-gateway-rules.json(主目录)./config/.mcp-gateway-rules.json(回退)
提示: 使用 agent-mcp-gateway --init 在首次运行时创建主目录配置。
配置
网关需要两个配置文件:
1.MCP服务器配置
文件: mcp.json (搜索于 多个地点)
定义网关将代理到的下游MCP服务器。使用与Claude Code和其他编码代理兼容的标准MCP配置格式:
{
"mcpServers": {
"brave-search": {
"description": "Web search via Brave Search API",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-brave-search"],
"env": {
"BRAVE_API_KEY": "${BRAVE_API_KEY}"
}
},
"postgres": {
"description": "PostgreSQL database access and query execution",
"command": "uvx",
"args": ["mcp-server-postgres"],
"env": {
"DATABASE_URL": "${DATABASE_URL}"
}
},
"remote-server": {
"description": "Custom remote API integration",
"url": "https://example.com/mcp",
"transport": "http",
"headers": {
"Authorization": "Bearer ${API_TOKEN}"
}
}
}
}服务器说明(推荐): 添加a description 每个服务器的字段有助于AI代理了解每个服务器提供的内容以及何时使用 list_servers,使代理能够就查询哪些服务器以获取工具做出明智的决定。虽然是可选的,但描述显著改善了代理工具的发现和决策。
支持的交通工具:
stdio-通过npx/uvx指定的本地服务器command+args)http-远程HTTP服务器(指定为url)
环境变量:
- 使用
${VAR_NAME}环境变量替换语法 - 运行前设置变量:
export BRAVE_API_KEY=your-key
重要信息-GUI应用程序(Claude Desktop等): 如果你使用 ${VAR_NAME} 语法在 .mcp.json,请注意,macOS GUI应用程序在隔离环境中运行,无法访问shell的环境变量。对于Claude Desktop和类似的应用程序,将API密钥添加到网关的 env MCP客户端配置中的对象:
{
"mcpServers": {
"agent-mcp-gateway": {
"command": "uvx",
"args": ["agent-mcp-gateway"],
"env": {
"BRAVE_API_KEY": "your-actual-key-here",
"DATABASE_URL": "postgresql://...",
"GATEWAY_DEFAULT_AGENT": "claude-desktop"
}
}
}
}(如果直接在中硬编码值 .mcp.json 没有 ${VAR_NAME} 语法,这不是必需的。)
2.网关规则配置
文件: mcp-gateway-rules.json (搜索于 多个地点)
在允许优先级之前使用拒绝定义每个代理的访问策略:
{
"agents": {
"researcher": {
"allow": {
"servers": ["brave-search", "context7"],
"tools": {
"brave-search": ["brave_web_search"]
}
}
},
"backend": {
"allow": {
"servers": ["postgres", "laravel-boost"],
"tools": {
"postgres": ["query", "list_tables", "list_schemas"],
"laravel-boost": ["get_*", "list_*", "read_*", "database_*", "search_*"]
}
},
"deny": {
"tools": {
"postgres": ["drop_*", "delete_*"],
"laravel-boost": ["database_query", "tinker"]
}
}
},
"admin": {
"allow": {
"servers": ["*"],
"tools": {
"brave-search": ["brave_web_search"]
}
},
"deny": {
"servers": ["notion"],
"tools": {
"playwright": ["browser_type"]
}
}
},
"claude-desktop": {
"allow": {
"servers": ["context7", "brave-search", "notion", "playwright"]
},
"deny": {
"tools": {
"playwright": ["browser_type", "browser_close_all", "launch_*"]
}
}
},
"default": {
"deny": {
"servers": ["*"]
}
}
},
"defaults": {
"deny_on_missing_agent": false
}
}代理示例说明:
研究员 -演示隐式授予+显式允许:
brave-search:仅brave_web_search工具(明确允许缩小访问范围)context7:所有工具(隐式授权-允许服务器,未指定工具规则)
后端 -演示通配符允许,在允许优先级之前先拒绝:
postgres:仅query,list_tables,list_schemas(明确允许);否认规则是安全网laravel-boost:通配符允许(get_*,list_*,read_*,database_*,search_*)授予广泛的访问权限,但database_query尽管匹配,但明确拒绝database_*通配符(拒绝获胜),以及tinker作为安全措施被封锁
管理员 -演示服务器通配符+混合访问模式:
notion:DENIED(服务器级拒绝覆盖通配符服务器允许)brave-search:仅brave_web_search(对一台服务器的明确限制)playwright:除以下工具外的所有工具browser_type(隐式授予,显式拒绝)- 所有其他服务器:所有工具(隐式授权-未指定工具规则)
克劳德桌面 -演示具有多个拒绝类型的隐式授予:
context7,brave-search,notion:所有工具(隐式授权)playwright:除以下工具外的所有工具browser_type,browser_close_all,以及工具匹配launch_*(隐式授予,显式+通配符拒绝)
默认 -最小特权原则:
- 在以下情况下用作回退
agent_id未提供和deny_on_missing_agent是false - 默认情况下拒绝所有服务器;使用
GATEWAY_DEFAULT_AGENT环境变量,用于指定不同的默认代理
策略优先级顺序:
- 显式拒绝规则(最高优先级)
- 通配符拒绝规则
- 明确的允许规则
- 通配符允许规则
- 隐式授权(如果服务器允许但未指定工具规则)
- 默认策略(拒绝)
隐性资助行为:
- 如果代理具有服务器访问权限,则否
allow.tools.{server}条目,该服务器中的所有工具都被隐式授予 allow.tools.{server}条目仅限制对指定工具的访问deny.tools.{server}条目过滤掉特定工具(在步骤1-2中评估)- 规则是特定于服务器的,不会影响其他服务器
配置灵活性:
- 规则可以引用当前不在的服务器
.mcp.json - 未定义的服务器引用被视为警告(而非错误)
- 允许保留临时删除的服务器的规则
- 热重新加载会立即应用更改,而无需重新启动
通配符模式:
*-匹配一切get_*-匹配以“get\_”开头的工具*_user-匹配以“\_user”结尾的工具
代理命名:
- 使用分层名称:
team.role(例如。,backend.database,frontend.ui) - 允许使用字母数字字符、连字符、下划线和点
- 配置您的代理 传递他们的身份:请参阅 配置您的代理
配置验证
网关在启动和热重新加载期间验证配置。输出示例:
✓ Configuration loaded from .mcp.json
⚠ Warning: Agent 'researcher' references undefined server 'unknown-server'
ℹ These rules will be ignored until the server is added验证行为:
- 结构错误(JSON无效,缺少必填字段)→ 启动/重新加载失败
- 未定义的服务器引用→ 记录警告,继续使用有效规则
- 策略冲突→ 在允许优先级自动解决之前拒绝
3.下游服务器的OAuth支持
当服务器返回HTTP 401时,通过自动检测自动支持OAuth保护的下游服务器(Notion、GitHub)。网关使用FastMCP的OAuth支持来透明地处理身份验证流——浏览器打开一次进行初始身份验证,然后缓存令牌以供将来使用。看 OAuth用户指南 了解详细的设置和故障排除。
OAuth限制:
网关支持实现以下功能的OAuth服务器 动态客户端注册(RFC 7591).
- ✅ 支持: 具有自动检测功能的OAuth(例如,Notion MCP)
- ❌ 不支持: 带有预注册应用程序的OAuth(例如GitHub OAuth流)
- 💡 对于GitHub MCP: 请改用个人访问令牌
GitHub MCP与PAT示例:
{
"mcpServers": {
"github": {
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "Bearer ${GITHUB_PAT}"
}
}
}
}有关OAuth设置和故障排除的详细信息,请参阅 OAuth用户指南.
4.环境变量参考
| 变量 | 描述 | 默认值 | 示例 |
|---|---|---|---|
GATEWAY_MCP_CONFIG | MCP服务器配置文件的路径 | .mcp.json,回退: ./config/.mcp.json | export GATEWAY_MCP_CONFIG=./custom.json |
GATEWAY_RULES | 网关规则配置文件的路径 | .mcp-gateway-rules.json,回退: ./config/.mcp-gateway-rules.json | export GATEWAY_RULES=~/.claude/rules.json |
GATEWAY_DEFAULT_AGENT | 默认代理身份 agent_id 未提供(可选) | 无 | export GATEWAY_DEFAULT_AGENT=developer |
GATEWAY_DEBUG | 启用调试模式以公开 get_gateway_status 工具 | false | export GATEWAY_DEBUG=true |
GATEWAY_AUDIT_LOG | 审核日志文件的路径 | ~/.cache/agent-mcp-gateway/logs/audit.jsonl | export GATEWAY_AUDIT_LOG=./audit.jsonl |
GATEWAY_TRANSPORT | 传输协议(stdio或http) | stdio | export GATEWAY_TRANSPORT=stdio |
GATEWAY_INIT_STRATEGY | 初始化策略(渴望或懒惰) | eager | export GATEWAY_INIT_STRATEGY=eager |
关于GUI应用程序的说明: macOS GUI应用程序(Claude Desktop等)在隔离环境中运行,无法访问shell环境变量。如果使用 ${VAR_NAME} 语法在 .mcp.json,将所需的API密钥添加到网关的 env MCP客户端配置中的对象。
用法
MCP客户端启动时,网关会自动运行。看 快速开始 将其添加到MCP客户端配置中。
自定义配置路径 可以通过MCP客户端配置中的环境变量指定:
{
"mcpServers": {
"agent-mcp-gateway": {
"command": "uvx",
"args": ["agent-mcp-gateway"],
"env": {
"GATEWAY_MCP_CONFIG": "/path/to/custom-mcp.json",
"GATEWAY_RULES": "/path/to/custom-rules.json"
}
}
}
}看 环境变量引用 所有可用选项。
启动输出
Loading MCP server configuration from: .mcp.json
Loading gateway rules from: .mcp-gateway-rules.json
Audit log will be written to: ~/.cache/agent-mcp-gateway/logs/audit.jsonl
Initializing proxy connections to downstream servers...
- 2 proxy client(s) initialized
* brave-search: ready
* postgres: ready
- Metrics collector initialized
- Access control middleware registered
Agent MCP Gateway initialized successfully
- 2 MCP server(s) configured
- 3 agent(s) configured
- Default policy: deny unknown agents
- 3 gateway tools available: list_servers, get_server_tools, execute_tool
(4 tools if GATEWAY_DEBUG=true: includes get_gateway_status)
Gateway is ready. Running with stdio transport...网关工具
网关向代理提供了3个工具。所有工具都接受可选 agent_id 访问控制参数。当 agent_id 如果未提供,网关将使用回退链来确定代理身份(请参阅 代理身份模式).
对于代理商开发人员: 要配置您的代理以正确使用这些具有访问控制的网关工具,请参阅 配置您的代理.
1. list_servers
根据策略规则列出呼叫代理可用的MCP服务器。
参数:
agent_id(string,可选)-发出请求的代理的标识符(请参见 代理身份模式)include_metadata(布尔值,可选)-包括传输、命令和url等技术细节(默认值:false)
退货:
[
{
"name": "brave-search",
"description": "Web search via Brave Search API"
},
{
"name": "postgres",
"description": "PostgreSQL database access and query execution"
}
]随着 include_metadata=true:
[
{
"name": "brave-search",
"description": "Web search via Brave Search API",
"transport": "stdio",
"command": "npx"
},
{
"name": "postgres",
"description": "PostgreSQL database access and query execution",
"transport": "stdio",
"command": "uvx"
}
]注: 始终包含服务器描述(在中配置时 .mcp.json)帮助代理了解每台服务器提供的内容。这 include_metadata 标志仅控制是否包含技术细节(传输、命令、url)。
例子:
# Basic usage - returns names and descriptions
result = await client.call_tool("list_servers", {
"agent_id": "researcher"
})
# With technical metadata
result = await client.call_tool("list_servers", {
"agent_id": "researcher",
"include_metadata": True
})2. get_server_tools
从特定的MCP服务器检索工具定义,并按代理权限进行筛选。
参数:
agent_id(string,可选)-代理的标识符(请参见 代理身份模式)server(字符串,必填)-下游MCP服务器的名称names(字符串,可选)-以逗号分隔的工具名称列表(例如。,"tool1,tool2,tool3")或单个工具名称pattern(字符串,可选)-工具名称的通配符模式(例如。,"get_*")max_schema_tokens(整数,可选)-模式的令牌预算限制
退货:
{
"tools": [
{
"name": "brave_web_search",
"description": "Search the web using Brave Search",
"inputSchema": {
"type": "object",
"properties": {
"query": {"type": "string"}
},
"required": ["query"]
}
}
],
"server": "brave-search",
"total_available": 5,
"returned": 1,
"tokens_used": 150
}例子:
# Get all allowed tools
tools = await client.call_tool("get_server_tools", {
"agent_id": "researcher",
"server": "brave-search"
})
# Get specific tools by name (comma-separated)
tools = await client.call_tool("get_server_tools", {
"agent_id": "researcher",
"server": "brave-search",
"names": "brave_web_search,brave_local_search"
})
# Get specific tools by pattern
tools = await client.call_tool("get_server_tools", {
"agent_id": "backend",
"server": "postgres",
"pattern": "get_*"
})
# Limit token usage
tools = await client.call_tool("get_server_tools", {
"agent_id": "researcher",
"server": "brave-search",
"max_schema_tokens": 1000
})3. execute_tool
在下游MCP服务器上执行具有透明结果转发的工具。
参数:
agent_id(string,可选)-代理的标识符(请参见 代理身份模式)server(字符串,必填)-下游MCP服务器的名称tool(string,必填)-要执行的工具的名称args(object,必填)-传递给工具的参数timeout_ms(整数,可选)-超时(毫秒)
退货:
{
"content": [
{
"type": "text",
"text": "Search results: ..."
}
],
"isError": false
}例子:
# Execute a tool
result = await client.call_tool("execute_tool", {
"agent_id": "researcher",
"server": "brave-search",
"tool": "brave_web_search",
"args": {
"query": "FastMCP documentation"
}
})
# With timeout
result = await client.call_tool("execute_tool", {
"agent_id": "backend",
"server": "postgres",
"tool": "query",
"args": {
"sql": "SELECT * FROM users LIMIT 10"
},
"timeout_ms": 5000
})4. get_gateway_status (仅调试模式)
返回全面的网关运行状况和诊断信息。
重要提示: 此工具仅在启用调试模式时可用(通过 GATEWAY_DEBUG=true 环境变量或 --debug CLI标志)。看 安全注意事项 了解详情。
参数:
agent_id(string,可选)-代理的标识符(请参见 代理身份模式)
退货:
{
"reload_status": {
"mcp_config": {
"last_attempt": "2025-10-30T10:30:00Z",
"last_success": "2025-10-30T10:30:00Z",
"last_error": null,
"attempt_count": 1,
"success_count": 1
},
"gateway_rules": {
"last_attempt": "2025-10-30T10:35:00Z",
"last_success": "2025-10-30T10:35:00Z",
"last_error": null,
"attempt_count": 2,
"success_count": 2,
"last_warnings": []
}
},
"policy_state": {
"total_agents": 3,
"agent_ids": ["researcher", "backend", "admin"],
"defaults": {"deny_on_missing_agent": true}
},
"available_servers": ["brave-search", "postgres"],
"config_paths": {
"mcp_config": "/path/to/.mcp.json",
"gateway_rules": "/path/to/.mcp-gateway-rules.json"
},
"message": "Gateway is operational. Check reload_status for hot reload health."
}例子:
# Check gateway health and reload status (requires GATEWAY_DEBUG=true)
status = await client.call_tool("get_gateway_status", {
"agent_id": "admin"
})
# Verify last reload was successful
if status["reload_status"]["gateway_rules"]["last_error"]:
print("Warning: Last rule reload failed!")错误处理
所有工具都会返回结构化错误,并显示明确的消息:
{
"error": {
"code": "DENIED_BY_POLICY",
"message": "Agent 'frontend' denied access to tool 'drop_table'",
"rule": "agents.frontend.deny.tools.postgres[0]"
}
}错误代码:
DENIED_BY_POLICY-代理缺少权限SERVER_UNAVAILABLE-下游服务器无法访问TOOL_NOT_FOUND-请求的工具不存在TIMEOUT-操作超出时间限制INVALID_AGENT_ID-代理标识符缺失或未知FALLBACK_AGENT_NOT_IN_RULES-在网关规则中找不到配置的回退代理NO_FALLBACK_CONFIGURED-未提供agent_id,也未配置回退代理
完整工作流示例
以下是一个展示典型网关工作流程的最小工作示例:
from fastmcp import Client
async def gateway_workflow():
async with Client('agent-mcp-gateway') as client:
# 1. Discover available servers
servers = await client.call_tool('list_servers', {
'agent_id': 'researcher'
})
# Response: [{"name": "brave-search", "description": "Web search..."}]
# 2. Get tools from specific server
tools = await client.call_tool('get_server_tools', {
'agent_id': 'researcher',
'server': 'brave-search'
})
# Response: {"tools": [...], "server": "brave-search", ...}
# 3. Execute a tool
result = await client.call_tool('execute_tool', {
'agent_id': 'researcher',
'server': 'brave-search',
'tool': 'brave_web_search',
'args': {'query': 'MCP protocol documentation'}
})
# Response: {"content": [...search results...], "isError": false}此工作流演示了按需工具发现——仅在需要时加载定义,而不是预先加载。
代理身份模式
网关支持两种部署模式来处理代理身份:
多代理模式(推荐)
当不同的代理需要不同的权限时使用(生产、多代理系统):
{
"agents": {
"researcher": {"allow": {"servers": ["brave-search"]}},
"backend": {"allow": {"servers": ["postgres"]}}
},
"defaults": {
"deny_on_missing_agent": true // Require explicit agent_id
}
}配置每个代理以传递其身份(请参阅 配置您的代理).
单代理模式
当所有代理都应具有相同权限时使用(开发、个人使用、单代理部署):
# Set default agent via environment variable
export GATEWAY_DEFAULT_AGENT=developer或者在规则中定义一个“默认”代理:
{
"agents": {
"default": {
"allow": {"servers": ["brave-search", "postgres"]}
}
},
"defaults": {
"deny_on_missing_agent": false
}
}代理可以省略 agent_id 在工具调用中,网关会自动使用配置的默认值。
Technical Details: Agent Identity Resolution
当 agent_id 如果未提供,网关将使用此回退链:
GATEWAY_DEFAULT_AGENT环境变量(最高优先级)- 名为“默认”的代理
.mcp-gateway-rules.json - 如果两者都没有配置,则出错
这 deny_on_missing_agent 设置控制此行为:
true:要求明确agent_id(绕过回退链)false:在以下情况下使用回退链agent_id省略
安全说明: 回退机制遵循最小特权原则——它从不授予隐式的“允许所有”访问权限,只授予显式配置的代理的权限。
安全注意事项
规则文件位置: 商店 .mcp-gateway-rules.json 在项目中仅用于上下文优化。对于生产访问控制。, ~/.claude/mcp-gateway-rules.json)以防止代理读取/修改权限。
调试模式: 这 get_gateway_status 该工具公开网关内部,仅在以下情况下可用 GATEWAY_DEBUG=true。在生产环境中禁用。
有关全面的安全指导: 看 安全指南 有关规则文件安全性、调试模式注意事项、代理模拟风险和生产最佳实践的详细信息。
故障排除
网关无法启动
症状: 启动时出错或网关初始化失败
解决:
- 检查配置文件是否存在: 验证
.mcp.json和.mcp-gateway-rules.json位于预期位置 - 验证JSON语法: 使用
python -m json.tool < .mcp.json检查语法错误 - 检查Python版本: 确保已安装Python 3.12+(
python --version) - 验证依赖关系: 跑
uv sync确保所有软件包都已安装
无法连接到下游服务器
症状: SERVER_UNAVAILABLE 调用工具时出错
解决:
- 验证服务器配置: 检查服务器是否在中正确定义
.mcp.json - 测试stdio服务器: 确保命令可用(
npx --version,uvx --version) - 检查环境变量: 验证是否设置了API密钥和凭据
- 测试HTTP服务器: 尝试直接在浏览器中访问服务器URL
- 查看启动日志: 在网关输出中查找服务器初始化错误
权限被拒绝错误
症状: DENIED_BY_POLICY 当代理试图使用工具时
解决:
- 验证代理_id: 确保代理传递正确的身份(检查审核日志)
- 检查代理规则: 确认代理存在于
.mcp-gateway-rules.json - 审查政策优先级: 记住拒绝规则优先于允许规则
- 使用通配符进行测试: 尝试
"tools": {"server-name": ["*"]}暂时授予广泛的访问权限 - 启用调试模式: 使用
GATEWAY_DEBUG=true并致电get_gateway_status检查政策状态
OAuth身份验证问题
症状: 浏览器未打开或OAuth流失败
请参阅中的详细故障排除 OAuth用户指南.
快速修复:
- 清除令牌缓存:
rm -rf ~/.fastmcp/oauth-mcp-client-cache/ - 测试浏览器:
python -m webbrowser https://example.com - 检查服务器URL: 验证中的OAuth服务器URL是否正确
.mcp.json
热重载不工作
症状: 对配置文件的更改不会生效
解决:
- 检查文件监视: 确保配置文件位于预期位置
- 审核日志: 查找网关输出中的重新加载错误
- 手动重新加载: 发送SIGHUP信号或重启网关
- 调试模式: 使用
get_gateway_status检查上次重新加载时间戳
测试
MCP检验员测试
这 MCP检查员 是一个用于测试MCP服务器的交互式工具。
# Basic usage
npx @modelcontextprotocol/inspector uvx agent-mcp-gateway
# With custom config paths
GATEWAY_MCP_CONFIG=~/.config/agent-mcp-gateway/.mcp.json \
GATEWAY_RULES=~/.config/agent-mcp-gateway/.mcp-gateway-rules.json \
GATEWAY_DEFAULT_AGENT=researcher \
npx @modelcontextprotocol/inspector uvx agent-mcp-gateway
# With debug mode
GATEWAY_DEBUG=true npx @modelcontextprotocol/inspector uvx agent-mcp-gateway检查员特征:
- 查看所有具有模式的网关工具
- 具有自定义输入的测试工具
- 检查请求/响应消息
- 监控日志和通知
在Inspector中测试网关工具
1.测试 list_servers:
{
"agent_id": "researcher"
}预期:“研究人员”代理可以访问的服务器列表。
2.测试 get_server_tools:
{
"agent_id": "researcher",
"server": "brave-search"
}预期:来自勇敢搜索服务器的工具定义。
3.测试 execute_tool:
{
"agent_id": "researcher",
"server": "brave-search",
"tool": "brave_web_search",
"args": {
"query": "test query"
}
}预期:来自Brave的搜索结果(如果服务器已配置并正在运行)。
故障排除:
- 检查 日志窗格 对于错误
- 验证
agent_id存在于规则文件中 - 确认下游服务器已配置
- 审查 消息面板 政策否认
发展
本地安装
在开发模式下克隆和安装:
# Clone repository
git clone https://github.com/roddutra/agent-mcp-gateway.git
cd agent-mcp-gateway
# Install dependencies
uv sync
# Create local config files from examples
cp config/.mcp.json.example .mcp.json
cp config/.mcp-gateway-rules.json.example .mcp-gateway-rules.json
# Run locally
uv run python main.py --help将本地网关添加到MCP客户端
# Claude Code CLI
claude mcp add agent-mcp-gateway \
uv run --directory /path/to/agent-mcp-gateway python main.py
# Or manual configuration
{
"mcpServers": {
"agent-mcp-gateway": {
"command": "uv",
"args": ["run", "--directory", "/path/to/agent-mcp-gateway", "python", "main.py"],
"env": {
"GATEWAY_DEFAULT_AGENT": "developer"
}
}
}
}注: 这 --directory 旗帜告诉 uv run 在运行之前更改到项目目录,确保它找到 pyproject.toml 以及网关配置文件。
项目结构
agent-mcp-gateway/
├── src/ # Core gateway implementation
├── tests/ # Test suite
├── config/ # Configuration examples
├── docs/ # Documentation and specifications
├── main.py # Entry point
└── pyproject.toml # Python dependencies在发展中奔跑
# Run locally
uv run python main.py
# With debug mode
uv run python main.py --debug测试
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=src --cov-report=term
# Run specific test file
uv run pytest tests/test_gateway.py -v
# Run tests in watch mode
uv run pytest-watch
# Generate HTML coverage report
uv run pytest --cov=src --cov-report=html
open htmlcov/index.htmlMCP检验员测试:
# Basic usage (uses local config files)
npx @modelcontextprotocol/inspector uv run python main.py
# With debug mode
npx @modelcontextprotocol/inspector uv run python main.py --debug
# With custom config paths
GATEWAY_MCP_CONFIG=.mcp.json \
GATEWAY_RULES=.mcp-gateway-rules.json \
GATEWAY_DEFAULT_AGENT=researcher \
npx @modelcontextprotocol/inspector uv run python main.py使用FastMCP客户端进行手动测试:
uv run python -c "
import asyncio
from fastmcp import Client
async def test():
async with Client('main.py') as client:
result = await client.call_tool('list_servers', {'agent_id': 'researcher'})
print(result)
asyncio.run(test())
"添加新功能
- 更新规格:相关里程碑文件中的文件
- 先写测试:在中创建测试文件
tests/ - 实现功能:添加代码
src/ - 运行测试:
uv run pytest - 检查覆盖范围:
uv run pytest --cov=src - 更新文档:README文件和相关文件
- 提交:遵循提交消息格式
代码风格
- 遵循M0/M1代码中的现有模式
- 全程使用类型提示
- 为所有公共函数编写文档字符串
- 保持功能的专注性和可测试性
- 为所有新功能添加测试
建筑
构件图
┌─────────────────────────────────────────────────────────┐
│ Agent / Client │
└─────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Agent MCP Gateway │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Gateway Tools (3 tools, ~2k tokens) │ │
│ │ • list_servers │ │
│ │ • get_server_tools │ │
│ │ • execute_tool │ │
│ └───────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ AgentAccessControl Middleware │ │
│ │ • Extract agent_id │ │
│ │ • Validate permissions │ │
│ └─────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ PolicyEngine │ │
│ │ • Deny-before-allow precedence │ │
│ │ • Wildcard matching │ │
│ └─────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ ProxyManager │ │
│ │ • Session isolation │ │
│ │ • Connection pooling │ │
│ └─────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ AuditLogger & MetricsCollector │ │
│ └─────────────────────────────────────────────────┘ │
└──────────────────────┬──────────────────────────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Server │ │ Server │ │ Server │
│ A │ │ B │ │ C │
│ (stdio) │ │ (stdio) │ │ (HTTP) │
└─────────┘ └─────────┘ └─────────┘请求流
- 代理发送请求 使用网关工具
agent_id - 中间件拦截:提取并验证
agent_id - 工具验证:检查PolicyEngine的服务器/工具访问权限
- 代理转发:ProxyManager路由到下游服务器
- 会话已隔离:每个请求都会获得新的连接
- 结果返回:透明转发给代理人
- 审计记录:用指标记录操作
性能特征
- 上下文缩减:90%+(2k个代币对5000-50000+个代币)
- 增加了延迟:\<100ms(P95)
- 网关开销:每次操作\<30ms
- 会话隔离:根据请求自动执行
- 并发请求:完全支持
未来功能
M2:生产(计划)
🚧 状态: 尚未实施
特征:
- \[\]网关服务器的HTTP传输
- \[\]健康检查端点
- \[\]增强的错误处理
- \[\]指标导出API
- \[\]连接池优化
- \[\]速率限制
可用时:
# Run with HTTP transport
export GATEWAY_TRANSPORT=http
export GATEWAY_PORT=8080
uv run python main.py
# Health check endpoint
curl http://localhost:8080/health
# Metrics endpoint
curl http://localhost:8080/metricsM3:开发人员体验(计划中)
🚧 状态: 尚未实施
特征:
- \[\]单代理模式(绕过agent_id要求)
- \[\]配置验证CLI工具
- \[\]带有示例的Docker容器
- \[\]交互式设置向导
- \[\]VS代码扩展名
可用时:
# Single-agent mode (no agent_id required)
export GATEWAY_DEFAULT_AGENT=developer
uv run python main.py
# Validate configs
uv run python -m src.cli validate
# Run with Docker
docker run -v ./config:/config agent-mcp-gateway文档
贡献
欢迎投稿!拜托:
- 阅读 产品需求文档 以及相关里程碑规范
- 遵循现有的代码样式和模式
- 为所有新功能编写测试
- 确保所有测试通过:
uv run pytest - 根据需要更新文档
- 提交带有清晰描述的拉取请求
许可证
此项目根据MIT许可证获得许可-请参阅 许可证 文件以获取详细信息。
支持
对于问题和疑问:
致谢
内置:
