mcpField
A
Agent MCP Gateway

Agent MCP Gateway

本地服务
github.com/roddutraAI 与智能体4147 周前更新

关于 Agent MCP Gateway

Agent MCP Gateway 是一个 MCP 网关,将多个下游 MCP 服务聚合为单一入口,并为 Agent 与子 Agent 提供基于策略的访问控制。其目的是通过按需发现工具来减少 Claude Code 等客户端的上下文占用。

主要功能

  1. 01按需发现工具,减少启动时的上下文占用
  2. 02按 Agent 配置可访问的服务与工具
  3. 03拒绝规则优先于允许规则,支持通配符
  4. 04审计日志与按 Agent、操作统计的性能指标
  5. 05配置文件热重载,无需重启

适用场景

  1. 01为多个子 Agent 分配不同的 MCP 工具权限
  2. 02在 Claude Code 中减少未使用工具定义占用的上下文
  3. 03集中管理多个 MCP 服务的访问策略与审计记录

MCP 相关

该项目是 MCP 网关,同时作为 MCP 服务向客户端暴露 list_servers、get_server_tools 与 execute_tool 等网关工具,并代理到下游 MCP 服务。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"roddutra-agent-mcp-gateway": {
"command": "uvx",
"args": [
"agent-mcp-gateway"
],
"env": {
"GATEWAY_MCP_CONFIG": "<GATEWAY_MCP_CONFIG>",
"GATEWAY_RULES": "<GATEWAY_RULES>",
"GATEWAY_DEFAULT_AGENT": "<GATEWAY_DEFAULT_AGENT>",
"GATEWAY_DEBUG": "<GATEWAY_DEBUG>"
}
}
}
}
启动命令uvx agent-mcp-gateway
需要配置的环境变量
GATEWAY_MCP_CONFIGPath to MCP servers configuration file (default: .mcp.json)
GATEWAY_RULESPath to gateway access control rules file (default: .mcp-gateway-rules.json)
GATEWAY_DEFAULT_AGENTDefault agent ID when not provided in tool calls
GATEWAY_DEBUGEnable debug mode and expose diagnostic tools (default: false)

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiagent-mcp-gateway0.2.5

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

Agent MCP Gateway

一个 Model Context Protocol (MCP) 网关,可聚合多个 MCP 服务,并为 Agent 和子 Agent 提供基于策略的访问控制。它通过按需发现工具(而不是预先加载所有工具定义),解决了 Claude Code 中 MCP 上下文窗口的浪费问题。

README 配图

状态

  • ✅ M0:基础 - 配置、策略引擎、审计日志记录、list_servers 工具
  • ✅ M1:核心 - 代理基础设施、get_server_tools、execute_tool、中间件、指标、热重载、OAuth 支持
  • 🚧 M2:生产 - HTTP 传输、健康检查(计划中)
  • 🚧 M3:开发体验 - 单 Agent 模式、配置验证 CLI、Docker(计划中)

当前版本: M1-Core 已完成(含 OAuth)

目录

概述

问题

在开发环境(Claude Code、Cursor、VS Code)中配置多个 MCP 服务时,所有服务的工具定义都会在启动时加载到每个 Agent 和子 Agent 的上下文窗口中:

  • 启动时预先消耗 5,000–50,000+ 个 token
  • 已加载的工具中,有 80–95% 从未被各个 Agent 使用
  • 实际工作所需的上下文被浪费在未使用的工具定义上
解决方案

Agent MCP Gateway 充当单个 MCP 服务,根据可配置的逐 Agent 规则代理到多个下游 MCP 服务:

  • 启动时加载 3 个网关工具(约 2k 个 token)
  • Agent 按需发现并请求特定工具
  • 上下文减少 90%+
  • 针对每个 Agent/子 Agent 的基于策略的访问控制
工作原理

Agent MCP Gateway 架构

网关位于 Agent 与下游 MCP 服务之间,仅公开 3 个轻量级工具。当 Agent 需要特定功能时,会通过网关发现可用的服务和工具;网关则根据策略规则筛选可见内容——Agent 只能看到有权访问的服务和工具。这样,每个 Agent 的上下文窗口中只保留相关工具,同时由网关负责将经过授权的请求代理到下游服务。

查看包含示例的详细图示 →(包含下游服务、工具和网关规则示例)

主要功能
  • ✅ 按需发现工具 - 仅在需要时加载工具定义
  • ✅ 逐 Agent 访问控制 - 配置每个 Agent 可访问的服务/工具
  • ✅ 轻松集成 Agent - 使用简单模板为任意 Agent 添加网关支持(参见指南)
  • ✅ 拒绝优先策略 - 明确的拒绝规则优先
  • ✅ 支持通配符 - 匹配工具名称的模式(get_*、*_user)
  • ✅ 会话隔离 - 并发请求互不干扰
  • ✅ 透明代理 - 下游服务无需感知网关
  • ✅ 审计日志记录 - 记录所有操作以供监控
  • ✅ 性能指标 - 跟踪每个 Agent/操作的延迟和错误率
  • ✅ 配置热重载 - 无需重启即可更新规则/服务
  • ✅ 线程安全操作 - 重载期间支持安全的并发访问
  • ✅ 诊断工具 - 通过 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 - 按 Agent 设置的访问策略(谁可以使用哪些服务/工具)

本地开发: 请参阅开发部分。

快速开始

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.json

详细示例请参阅配置部分;有关其他文件位置,请参阅配置文件查找。

2. 将网关添加到 MCP 客户端

Claude Code 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. 配置 Agent

网关的工具描述具有自文档说明功能,但若要正确控制访问权限,应配置 Agent 如何标识自身。请选择适合你使用场景的方法:

方法 1:多 Agent 模式(推荐)

对于权限各不相同的 Agent,请配置每个 Agent 传递其身份信息。

将以下内容添加到 Agent 的系统提示词中(例如,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 替换为 Agent 的标识符(例如,“researcher”、“backend”、“admin”)。

示例: 完整配置示例请参阅 .claude/agents/researcher.md 和 .claude/agents/mcp-developer.md。

方法 2:单 Agent 模式

对于所有 Agent 应具有相同权限的简单配置,或使用不支持配置系统提示词的 MCP 客户端(例如 Claude Desktop)时,可通过以下任一方法配置默认 Agent:

选项 A:环境变量

# Set in your MCP client configuration
export GATEWAY_DEFAULT_AGENT=developer

注意: 指定的 Agent(例如,“developer”)必须存在于 .mcp-gateway-rules.json 文件中,并具有相应权限。

选项 B:规则中的“default” Agent

{
  "agents": {
    "default": {
      "allow": {
        "servers": ["*"]
      }
    }
  },
  "defaults": {
    "deny_on_missing_agent": false
  }
}

注意: 允许访问所有服务("servers": ["*"])且不指定工具限制,将授予对所有服务上所有工具的访问权限。

使用上述任一方法时,Agent 可以在工具调用中省略 agent_id - 网关会自动使用已配置的默认 Agent。

命令行选项

# 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)
  1. GATEWAY_MCP_CONFIG 环境变量(如果已设置)
  2. 当前目录中的 .mcp.json
  3. ~/.config/agent-mcp-gateway/.mcp.json(主目录)
  4. ./config/.mcp.json(备用位置)
网关规则(.mcp-gateway-rules.json)
  1. GATEWAY_RULES 环境变量(如果已设置)
  2. 当前目录中的 .mcp-gateway-rules.json
  3. ~/.config/agent-mcp-gateway/.mcp-gateway-rules.json(主目录)
  4. ./config/.mcp-gateway-rules.json(备用位置)

提示: 首次运行时,使用 agent-mcp-gateway --init 创建主目录中的配置文件。

配置

网关需要两个配置文件:

1. MCP 服务配置

文件: mcp.json(在多个位置中搜索)

定义网关要代理到的下游 MCP 服务。使用与 Claude Code 和其他编码 Agent 兼容的标准 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}"
      }
    }
  }
}

服务描述(建议): 为每个服务添加 description 字段,有助于 AI Agent 了解各服务提供的功能以及适用场景。list_servers 始终会返回描述,让 Agent 能够根据充分的信息决定查询哪些服务以获取工具。虽然描述是可选的,但它能显著提升 Agent 发现工具和做出决策的能力。

支持的传输方式:

  • stdio - 通过 npx/uvx 使用本地服务(使用 command + args 指定)
  • http - 远程 HTTP 服务(使用 url 指定)

环境变量:

  • 使用 ${VAR_NAME} 语法替换环境变量
  • 运行前设置变量:export BRAVE_API_KEY=your-key

重要提示 - GUI 应用程序(Claude Desktop 等): 如果在 .mcp.json 中使用 ${VAR_NAME} 语法,请注意,macOS GUI 应用程序运行在隔离环境中,无法访问 shell 的环境变量。对于 Claude Desktop 等应用程序,请将 API 密钥添加到 MCP 客户端配置中网关的 env 对象:

{
  "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(在多个位置中搜索)

使用拒绝优先于允许的规则,为每个 Agent 定义访问策略:

{
  "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
  }
}

Agent 示例说明:

researcher——演示隐式授权和显式允许:

  • brave-search:仅限 brave_web_search 工具(显式允许会缩小访问范围)
  • context7:所有工具(隐式授权——允许该服务,且未指定工具规则)

backend——演示通配符允许规则及拒绝优先于允许的规则:

  • postgres:仅限 query、list_tables、list_schemas(显式允许);拒绝规则用作安全保障
  • laravel-boost:通配符允许规则(get_*、list_*、read_*、database_*、search_*)授予广泛访问权限,但即使 database_query 匹配 database_* 通配符,也会被显式拒绝(拒绝优先);同时,tinker 也会出于安全考虑被屏蔽

admin——演示服务通配符和混合访问模式:

  • notion:拒绝(服务级拒绝优先于通配符服务允许规则)
  • brave-search:仅限 brave_web_search(对一个服务进行显式限制)
  • playwright:除 browser_type 外的所有工具(隐式授权,附带显式拒绝)
  • 所有其他服务:所有工具(隐式授权——未指定工具规则)

claude-desktop——演示带有多种拒绝类型的隐式授权:

  • context7、brave-search、notion:所有工具(隐式授权)
  • playwright:除 browser_type、browser_close_all 及匹配 launch_* 的工具外的所有工具(隐式授权,附带显式拒绝和通配符拒绝)

default——最小权限原则:

  • 当未提供 agent_id 且 deny_on_missing_agent 为 false 时,作为回退策略使用
  • 默认拒绝所有服务;使用 GATEWAY_DEFAULT_AGENT 环境变量指定其他默认 Agent

策略优先级顺序:

  1. 显式拒绝规则(优先级最高)
  2. 通配符拒绝规则
  3. 显式允许规则
  4. 通配符允许规则
  5. 隐式授权(允许服务访问,但未指定工具规则时)
  6. 默认策略(拒绝)

隐式授权行为:

  • 如果 Agent 有权访问某个服务,且没有 allow.tools.{server} 条目,则默认授予该服务的所有工具访问权限
  • allow.tools.{server} 条目会将访问范围缩小到指定工具
  • deny.tools.{server} 条目会过滤掉特定工具(在步骤 1–2 中评估)
  • 规则针对特定服务,不会影响其他服务

配置灵活性:

  • 规则可以引用当前不在 .mcp.json 中的服务
  • 未定义的服务引用会被视为警告(而非错误)
  • 可为暂时移除的服务保留规则
  • 热重载会立即应用更改,无需重启

通配符模式:

  • *——匹配所有内容
  • get_*——匹配以 "get_" 开头的工具
  • *_user——匹配以 "_user" 结尾的工具

Agent 命名:

  • 使用分层名称:team.role(例如,backend.database、frontend.ui)
  • 允许使用字母数字字符、连字符、下划线和点
  • 配置你的 Agent以传递其身份:请参阅配置你的 Agent
配置验证

网关会在启动时和热重载期间验证配置。输出示例:

✓ 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 支持

当受 OAuth 保护的下游服务(Notion、GitHub)返回 HTTP 401 时,系统会自动检测并提供支持。网关使用 FastMCP 的 OAuth 支持,以透明方式处理身份验证流程——首次身份验证时会打开一次浏览器,之后会缓存令牌以供后续使用。详细设置和故障排查,请参阅 OAuth 用户指南。

OAuth 限制:

网关支持实现了**动态客户端注册(RFC 7591)**的 OAuth 服务。

  • ✅ **支持:**自动检测的 OAuth(例如 Notion MCP)
  • ❌ **不支持:**使用预注册应用的 OAuth(例如 GitHub OAuth 流程)
  • 💡 **GitHub MCP:**请改用个人访问令牌

使用 PAT 的 GitHub MCP 示例:

{
  "mcpServers": {
    "github": {
      "url": "https://api.githubcopilot.com/mcp/",
      "headers": {
        "Authorization": "Bearer ${GITHUB_PAT}"
      }
    }
  }
}

OAuth 的详细设置和故障排查,请参阅 OAuth 用户指南。

4. 环境变量参考
变量描述默认值示例
GATEWAY_MCP_CONFIGMCP 服务配置文件的路径.mcp.json,回退路径:./config/.mcp.jsonexport GATEWAY_MCP_CONFIG=./custom.json
GATEWAY_RULES网关规则配置文件的路径.mcp-gateway-rules.json,回退路径:./config/.mcp-gateway-rules.jsonexport GATEWAY_RULES=~/.claude/rules.json
GATEWAY_DEFAULT_AGENT未提供 agent_id 时使用的默认 Agent 身份(可选)无export GATEWAY_DEFAULT_AGENT=developer
GATEWAY_DEBUG启用调试模式,以公开 get_gateway_status 工具falseexport GATEWAY_DEBUG=true
GATEWAY_AUDIT_LOG审计日志文件的路径~/.cache/agent-mcp-gateway/logs/audit.jsonlexport GATEWAY_AUDIT_LOG=./audit.jsonl
GATEWAY_TRANSPORT传输协议(stdio 或 http)stdioexport GATEWAY_TRANSPORT=stdio
GATEWAY_INIT_STRATEGY初始化策略(eager 或 lazy)eagerexport GATEWAY_INIT_STRATEGY=eager

**关于 GUI 应用的说明:**macOS GUI 应用(Claude Desktop 等)在隔离环境中运行,无法访问 shell 环境变量。如果在 .mcp.json 中使用 ${VAR_NAME} 语法,请将所需的 API 密钥添加到 MCP 客户端配置中的网关 env 对象。

使用方法

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...

网关工具

网关向 Agent 提供的工具恰好有 3 个。所有工具都接受可选的 agent_id 参数,用于访问控制。未提供 agent_id 时,网关会使用回退链来确定 Agent 身份(参见 Agent 身份模式)。

**面向 Agent 开发者:**如需配置 Agent,以便正确使用这些带访问控制的网关工具,请参阅配置你的 Agent。

1. list_servers

根据策略规则,列出调用方 Agent 可用的 MCP 服务。

参数:

  • agent_id(字符串,可选)— 发起请求的 Agent 标识符(参见 Agent 身份模式)
  • 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 中配置),以帮助 Agent 了解每个服务提供的功能。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 权限进行筛选。

参数:

  • agent_id(字符串,可选)- Agent 的标识符(参见 Agent 身份模式)
  • 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(字符串,可选)- Agent 的标识符(参见 Agent 身份模式)
  • server(字符串,必需)- 下游 MCP 服务的名称
  • tool(字符串,必需)- 要执行的工具名称
  • args(对象,必需)- 传递给工具的参数
  • 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 标志)。详情请参阅安全注意事项。

参数:

返回:

{
  "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 - Agent 无权限
  • SERVER_UNAVAILABLE - 无法连接下游服务
  • TOOL_NOT_FOUND - 请求的工具不存在
  • TIMEOUT - 操作超出时间限制
  • INVALID_AGENT_ID - 缺少 Agent 标识符或标识符未知
  • FALLBACK_AGENT_NOT_IN_RULES - 配置的回退 Agent 未在网关规则中找到
  • NO_FALLBACK_CONFIGURED - 未提供 agent_id,且未配置回退 Agent
完整工作流示例

以下是一个展示典型网关工作流的最简可运行示例:

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}

此工作流展示了按需发现工具的方式——仅在需要时加载定义,而非预先加载。

Agent 身份模式

网关支持两种处理 Agent 身份的部署模式:

多 Agent 模式(推荐)

适用于不同 Agent 需要不同权限的场景(生产环境、多 Agent 系统):

{
  "agents": {
    "researcher": {"allow": {"servers": ["brave-search"]}},
    "backend": {"allow": {"servers": ["postgres"]}}
  },
  "defaults": {
    "deny_on_missing_agent": true  // Require explicit agent_id
  }
}

配置每个 Agent 传递其身份(参见配置 Agent)。

单 Agent 模式

适用于所有 Agent 应使用相同权限的场景(开发、个人使用、单 Agent 部署):

# Set default agent via environment variable
export GATEWAY_DEFAULT_AGENT=developer

或者在规则中定义一个“default” Agent:

{
  "agents": {
    "default": {
      "allow": {"servers": ["brave-search", "postgres"]}
    }
  },
  "defaults": {
    "deny_on_missing_agent": false
  }
}

Agent 可以在工具调用中省略 agent_id——网关会自动使用已配置的默认值。

技术详情:Agent 身份解析

未提供 agent_id 时,网关会按以下回退顺序处理:

  1. GATEWAY_DEFAULT_AGENT 环境变量(优先级最高)
  2. .mcp-gateway-rules.json 中名为“default”的 Agent
  3. 如果两者都未配置,则报错

deny_on_missing_agent 设置项用于控制此行为:

  • true:要求显式提供 agent_id(跳过回退顺序)
  • false:省略 agent_id 时使用回退顺序

**安全说明:**回退机制遵循最小权限原则——它绝不会隐式授予“允许所有”访问权限,只会授予明确配置的 Agent 所拥有的权限。

## 安全注意事项

规则文件位置: 仅为优化上下文,请将 .mcp-gateway-rules.json 存储在项目内。对于生产环境的访问控制,请将其存储在项目目录之外(例如 ~/.claude/mcp-gateway-rules.json),以防止 Agent 读取或修改权限。

调试模式: get_gateway_status 工具会暴露网关内部信息,且仅在 GATEWAY_DEBUG=true 时可用。请在生产环境中禁用此模式。

全面的安全指南: 有关规则文件安全、调试模式注意事项、Agent 冒充风险和生产环境最佳实践的详细信息,请参阅 安全指南。

故障排除

网关无法启动

症状: 启动时出错,或网关无法初始化

解决方案:

  • 检查配置文件是否存在: 确认 .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
  • 查看启动日志: 检查网关输出中是否有服务初始化错误
权限被拒错误

症状: Agent 尝试使用工具时出现 DENIED_BY_POLICY

解决方案:

  • 验证 agent_id: 确保 Agent 传递了正确的身份标识(检查审计日志)
  • 检查 Agent 规则: 确认 .mcp-gateway-rules.json 中存在该 Agent
  • 查看策略优先级: 请记住,拒绝规则的优先级高于允许规则
  • 使用通配符测试: 尝试使用 "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: 验证 .mcp.json 中的 OAuth 服务 URL 是否正确
热重载不起作用

症状: 配置文件的更改未生效

解决方案:

  • 检查文件监视: 确保配置文件位于预期位置
  • 查看日志: 检查网关输出中是否有重新加载错误
  • 手动重新加载: 发送 SIGHUP 信号或重启网关
  • 调试模式: 使用 get_gateway_status 检查上次重新加载的时间戳

需要更多帮助: 请参阅 安全指南、OAuth 用户指南,或在 GitHub 上提交问题。

测试

使用 MCP Inspector 测试

MCP Inspector 是一款用于测试 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 功能:

  • 查看包含架构的所有网关工具
  • 使用自定义输入测试工具
  • 检查请求/响应消息
  • 监控日志和通知
在 Inspector 中测试网关工具

1. 测试 list_servers:

{
  "agent_id": "researcher"
}

预期结果:"researcher" Agent 可访问的服务列表。

2. 测试 get_server_tools:

{
  "agent_id": "researcher",
  "server": "brave-search"
}

预期结果:来自 brave-search 服务的工具定义。

3. 测试 execute_tool:

{
  "agent_id": "researcher",
  "server": "brave-search",
  "tool": "brave_web_search",
  "args": {
    "query": "test query"
  }
}

预期结果:来自 Brave 的搜索结果(前提是已配置并运行该服务)。

故障排除:

  • 检查 Logs 窗格中的错误
  • 验证规则文件中是否存在 agent_id
  • 确认已配置下游服务
  • 查看 Message 窗格中的策略拒绝信息

开发

本地安装

克隆并以开发模式安装:

# 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.html

使用 MCP Inspector 测试:

# 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 Client 手动测试:

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())
"
添加新功能
  1. 更新规格说明:在相关的里程碑文件中编写文档
  2. 先编写测试:在 tests/ 中创建测试文件
  3. 实现功能:在 src/ 中添加代码
  4. 运行测试:uv run pytest
  5. 检查覆盖率:uv run pytest --cov=src
  6. 更新文档:在 README 和相关文件中编写文档
  7. 提交:遵循提交消息格式
代码风格
  • 遵循 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)  │
   └─────────┘   └─────────┘   └─────────┘
请求流程
  1. Agent 向网关工具发送请求,并提供 agent_id
  2. 中间件拦截请求:提取并验证 agent_id
  3. 工具进行验证:检查 PolicyEngine 是否允许访问服务器和工具
  4. 代理转发请求:ProxyManager 将请求路由到下游服务器
  5. 会话隔离:每个请求都会建立新的连接
  6. 返回结果:透明地转发给 Agent
  7. 记录审计日志:记录操作及指标
性能特点
  • 上下文缩减:90% 以上(2k 个 token,相较于 5,000-50,000+ 个)
  • 增加的延迟:<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/metrics
M3:开发者体验(计划中)

🚧 状态: 尚未实现

功能:

  • 单 Agent 模式(无需提供 agent_id)
  • 配置验证 CLI 工具
  • 包含示例的 Docker 容器
  • 交互式设置向导
  • VS Code 扩展

推出后:

# 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

文档

贡献

欢迎贡献!请:

  1. 阅读 PRD 和相关的里程碑规格说明
  2. 遵循现有代码风格和模式
  3. 为所有新功能编写测试
  4. 确保所有测试通过:uv run pytest
  5. 根据需要更新文档
  6. 提交内容清晰的拉取请求

许可证

本项目采用 MIT License 许可,详情请参阅 LICENSE 文件。

支持

如有问题或疑问:

致谢

基于以下项目构建:

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。