CyberStrikeAI MCP 联邦完全指南:内置 MCP、独立 HTTP 服务与外部工具联邦的接入、加固与排障
【免费下载链接】CyberStrikeAIThe system of action for AI-native cybersecurity—where intent becomes governed execution, evidence becomes operational memory, and every operation improves the next.项目地址: https://gitcode.com/GitHub_Trending/cy/CyberStrikeAI
MCP(Model Context Protocol)是 CyberStrikeAI 中 Agent 调用工具的主要协议层。本篇指南以docs/zh-CN/mcp-federation.md为骨架,结合仓库源码深入讲解 CyberStrikeAI 的三层 MCP 体系——内置 MCP Server、独立 HTTP MCP 服务与外部 MCP 联邦:从 YAML 配置、Web 管理 API、stdio/HTTP/SSE 三种传输模式,到连接恢复、熔断限流、工具暴露策略与安全审查清单,读完你便能独立完成外部 MCP 的接入、调试与生产加固。
MCP 联邦架构总览
CyberStrikeAI 的 MCP 能力分三层,分别对应不同的部署与集成场景:
- 内置 MCP:Web 服务进程内部创建的 MCP Server,随服务自动注册并暴露给前端和 Agent,通常无需额外配置;
- 独立 HTTP MCP 服务:以
mcp:配置段开启的独立监听端点,供外部程序通过 MCP 协议直接调用平台能力; - 外部 MCP 联邦:通过
external_mcp:配置段或 Web 管理页面接入的第三方 MCP 服务(stdio / SSE / HTTP),其工具经过拉取、命名隔离、授权与监控后进入 Agent 的工具池。
从源码结构看,这三层分别由 internal/mcp/server.go(内置 Server)、internal/mcp/external_manager.go(外部 MCP 管理器)与 internal/einomcp/mcp_tools.go(Eino 工具桥接)支撑,前端与 Agent 统一通过应用内部调用,无需感知底层传输差异。
内置 MCP:零配置的工具注册
Web 服务内部会创建 MCP Server 并注册以下工具类别:
- YAML 命令工具(加载自
tools/目录下的工具定义,如 tools/nmap.yaml、tools/sqlmap.yaml); - 内置安全执行工具(
execute/exec等命令执行类); - 知识库工具(检索
knowledge_base/语料); - 项目事实工具(项目黑板的读写与查询);
- C2 工具;
- WebShell 工具;
- 批量任务工具;
- 视觉分析工具(
analyze_image,需 config.example.yaml 中vision.enabled: true且配置 VL 模型才注册)。
在 internal/mcp/server.go 中,RegisterTool(tool Tool, handler ToolHandler)是工具注册的统一入口,RegisterPrompt、RegisterResource则用于注册 MCP 协议层面的提示词与资源。前端和 Agent 通常通过应用内部调用这些工具,不需要额外配置;只有在需要把平台能力暴露给外部程序时,才需要启用下一节的独立 HTTP MCP 服务。
独立 HTTP MCP 服务:把平台能力开放给外部程序
如果希望外部程序(如 Claude Desktop、Cursor、其他 Agent 框架)通过 MCP 协议直接调用 CyberStrikeAI 的能力,可启用独立 HTTP MCP 服务,配置如下(摘自 config.example.yaml 并补齐注释):
mcp: enabled: false # 是否启用 MCP 服务器(http 模式) host: 127.0.0.1 # MCP 服务器监听地址;需要远程访问时再显式修改并配置网络层访问控制 port: 8081 # MCP 服务器端口 auth_header: "X-MCP-Token" # 可选的全局服务凭证 Header;普通调用请使用用户 Authorization: Bearer Token auth_header_value: "" # 全局服务凭证值,仅 allow_global_access=true 时生效 allow_global_access: false # 高风险兼容模式:静态密钥映射为全局服务身份;默认请使用用户 Bearer Token原文档给出的示例将host: 0.0.0.0与auth_header_value: "random-secret"组合使用,适合明确需要对外暴露的场景;而示例配置默认保持enabled: false、host: 127.0.0.1与allow_global_access: false,即默认只允许本机、且不开启静态密钥的全局访问模式。
生产环境必须设置auth_header_value,并限制网络访问(防火墙、安全组层面仅放行可信 IP)。这一点与配置注释的语义一致:allow_global_access属于“高风险兼容模式”,它把静态密钥映射为全局服务身份;常规推荐做法是使用用户级Authorization: Bearer Token,配合平台的 RBAC(docs/zh-CN/rbac.md)做身份与权限控制,而不是用一把全局密钥。
Web 内 MCP 端点:复用登录态的内部集成
除了独立监听端口,Web 服务还提供登录后可访问的 MCP 端点:
POST /api/mcp该端点复用 Web 认证(用户会话),适合内部页面或受控集成调用,无需单独发放 MCP Token。其路由定义可以在 internal/handler/openapi.go 的 OpenAPI 描述中看到,与/api/external-mcp系列管理接口并列。使用场景包括:平台自带 Web 控制台内部的工具调用、以及通过浏览器扩展等已登录组件的受控集成。
外部 MCP 联邦:配置、管理 API 与完整字段
外部 MCP 是联邦的核心,配置写在external_mcp段:
external_mcp: servers: {}每个 server 的完整配置字段定义在 internal/config/config.go,遵循官方 MCP 配置格式,兼容 Claude Desktop / Cursor / VS Code 的写法:
external_mcp: servers: my-tool-server: type: stdio # "stdio" | "sse" | "http"(Streamable HTTP);stdio 可省略,有 command 时自动推断 command: /path/to/server # stdio 模式:启动命令 args: [] # 命令参数 env: {} # 子进程环境变量 url: "" # HTTP/SSE 模式:服务地址 headers: {} # HTTP/SSE 模式:自定义请求头(如认证) description: "" # 服务器描述 timeout: 30 # 连接超时(秒),默认 30 external_mcp_enable: true # 是否启用(false 时仅保留配置不连接) tool_enabled: {} # 每个工具的启用状态(细粒度开关) # 官方标准字段 disabled: false # 官方 disabled 字段(与 external_mcp_enable 取反) autoApprove: [] # 自动批准的工具列表(官方字段) # SDK 高级配置(对应 MCP Go SDK 传输层参数) max_retries: 5 # Streamable HTTP 断线重连次数(默认 5) terminate_duration: 5 # stdio 进程优雅关闭等待秒数(默认 5) keep_alive: 0 # 客户端心跳间隔秒数(0 = 禁用)所有字符串字段均支持${VAR}与${VAR:-default}环境变量展开语法(源码注释明确标注,见 internal/config/config.go),适合把 Token、密钥放在环境变量中而不落盘到 YAML。
除了写配置文件,也可以通过 Web 的MCP 管理页面新增、启动、停止和删除外部 MCP(界面截图见 images/mcp-management.png,对应前端 MCP 管理入口)。管理页面的每个操作会同步写回 YAML 配置文件,写回前会先创建config.yaml.backup备份(见 internal/handler/external_mcp.go 的saveConfig实现),降低误操作风险。
管理 API 一览
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/external-mcp | 列出全部外部 MCP 配置、状态(connected/disconnected/disabled/error/connecting)与工具数量 |
| GET | /api/external-mcp/stats | 汇总统计:total / enabled / disabled / connected |
| GET | /api/external-mcp/:name | 查询单个外部 MCP 详情 |
| PUT | /api/external-mcp/:name | 新增或更新配置(校验通过后自动连接) |
| POST | /api/external-mcp/:name/start | 启动客户端(立即返回,后台异步连接) |
| POST | /api/external-mcp/:name/stop | 停止客户端 |
| DELETE | /api/external-mcp/:name | 删除配置并关闭客户端 |
上述路由与行为在 internal/handler/external_mcp.go 中有完整实现,并在 internal/handler/external_mcp_test.go 中有对应测试覆盖(含 stdio、http、非法配置、删除、启动/停止等场景)。注意几点:
PUT校验规则(validateConfig):HTTP 模式必须给url,stdio 模式必须给command,否则返回 400;不支持的传输类型也会被拒绝;- 无
mcp:write权限的会话在查询配置时,env与headers中的敏感值会被打码为***(internal/handler/external_mcp.go); - 每次 upsert / delete 都会写入平台审计日志(Category
external_mcp),便于事后追溯,这也是原文档安全建议中“变更外部 MCP 后查看审计日志”的实现基础。
传输模式:stdio 与 HTTP/SSE 的接入关注点
stdio:适合本机命令启动的工具服务
stdio MCP 由平台拉起一个子进程,通过标准输入/输出与 MCP 协议通信。接入时关注:
- 命令路径必须存在:
command需为绝对路径或 PATH 内可解析的可执行文件; - 工作目录正确:部分 MCP Server 依赖相对路径读取配置,启动目录不对会导致初始化失败;
- 环境变量完整:通过
env字段补全服务所需的 Key;同样支持${VAR}展开; - 进程退出会导致工具不可用:stdio 子进程的生命周期与连接绑定,进程异常退出后工具立即失效;
- 日志中查看启动失败原因:启动失败会以
error状态呈现,GET /api/external-mcp返回的error字段携带具体原因;连接被拒绝(connection refused/dial tcp)会被记录为 Warn 级“目标服务可能尚未启动”,这是正常现象,服务就绪后可通过界面手动连接或等待自动重试(见 internal/mcp/external_manager.go 的StartAllEnabled)。
平台为每个已连接的外部 MCP 提供工具列表缓存(TTL 60 秒,见 internal/mcp/external_manager.go),避免每次请求都打远程ListTools;连接断开时还会降级使用缓存列表,保证临时断网期间 Agent 的工具集不瞬间清空。
HTTP / SSE:适合远端或长期运行服务
HTTP(Streamable HTTP)与 SSE 模式适合部署在远端或长期运行的服务。接入时关注:
- URL 可达:从平台所在主机能访问到目标地址;
- 认证头正确:通过
headers配置Authorization等请求头; - TLS 证书可信:使用自签证书的服务需要先解决平台侧证书信任问题;
- 代理和防火墙放行:平台与远端之间的网络策略需放行对应端口与协议;
- 服务端协议版本兼容:MCP 协议版本不匹配会导致 Initialize 握手失败,日志中会出现明确的初始化错误。
传输类型判定逻辑在ExternalMCPServerConfig.GetTransportType()(internal/config/config.go):优先读type字段,否则根据command(→ stdio)或url(→ http)自动推断。客户端统一由官方 MCP Go SDK 的 lazy client 创建(newLazySDKClient),连接在 Initialize 时完成,doConnect默认超时 30 秒(internal/mcp/external_manager.go)。
外部 MCP 生命周期:七步全流程
外部 MCP 的生命周期不是简单的“添加 URL”,而是包含注册、连接、拉取、暴露、执行、恢复、移除的完整状态机:
- 注册配置:名称、类型(stdio/sse/http)、命令或 URL、环境变量写入
external_mcp.servers,并可通过external_mcp_enable控制是否立即启用; - 启动连接:stdio 拉起子进程,HTTP/SSE 建立客户端并完成 Initialize 握手;状态先置为
connecting(前端立即可见),实际连接在后台异步进行; - 拉取工具列表:调用
ListTools获取工具名、描述与 JSON Schema,写入平台工具缓存与工具数量统计;空工具列表会记录 Warn 提示(internal/mcp/external_manager.go); - 暴露给 Agent:工具以
服务器名::工具名的格式进入平台工具池(命名空间隔离,见GetAllTools的前缀拼接),并受角色、tool_search、HITL 策略共同约束; - 执行工具:参数校验、调用远端、记录执行状态与监控统计;超长结果受
tool_wait_timeout_seconds(默认 300 秒)限制,到时返回execution_id由后台继续执行,Agent 可用wait_tool_execution继续等待、cancel_tool_execution取消(internal/mcp/external_manager.go); - 连接恢复:进程退出或网络失败后,通过指数退避自动重连(详见下节);
- 停止/删除:关闭客户端、清空工具缓存与重连状态,并从配置中移除;停止时工具数量立即置 0。
排错时要确认卡在哪一步:是配置没写入、连接握手失败、工具没拉取到、被策略隐藏,还是执行环节超时——对应到上一步的产物(配置存在性、客户端状态、tool_count、工具可见性、execution_id),能快速定位故障层级。
连接恢复与韧性机制:断连自愈、熔断与并发控制
外部 MCP 的可用性保障在 internal/mcp/connection_recovery.go 与 internal/mcp/external_manager.go 中实现,包含四层机制:
自动重连与指数退避
- 检测到
ListTools/CallTool失败且错误属于传输断开类型(EOF、client is closing、connection reset、broken pipe等,context.Canceled与超时除外),会标记客户端为 disconnected 并调度重连(isConnectionDeadError/handleConnectionDead,internal/mcp/connection_recovery.go); - 重连采用指数退避:最短间隔 30 秒,上限 5 分钟(
externalReconnectMinInterval/externalReconnectMaxBackoff,见 internal/mcp/connection_recovery.go); - 同一时刻同一 MCP 只允许一个重连 goroutine(
reconnecting去重),已停用的服务不触发自动重连。
熔断(Circuit Breaker)
- 单个外部 MCP 连续失败达到阈值后进入熔断冷却期,冷却期内调用直接快速失败并提示“已临时熔断,预计 X 后重试”(
checkExternalMCPCircuit,internal/mcp/external_manager.go); - 成功调用会清零连续失败计数并关闭熔断;阈值与冷却时间可配置(见下)。
并发控制(信号量)
- 每个外部 MCP 有独立的并发信号量,另有全局信号量兜底(默认单服务 2、全局 16,internal/mcp/external_manager.go);
- 获取信号量时遵循上下文取消,避免调用方超时后仍占用并发额度。
相关配置项(config.example.yaml 的agent段)
agent: tool_wait_timeout_seconds: 300 # 工具本轮最多等待(秒);到时返回 execution_id,worker 继续后台执行 external_mcp_max_concurrent_per_server: 5 # 单个外部 MCP server 同时运行的工具数;0=默认2;负数=不限制 external_mcp_max_concurrent_total: 16 # 所有外部 MCP 工具全局并发上限;0=默认16;负数=不限制 external_mcp_circuit_failure_threshold: 15 # 单个外部 MCP server 连续失败多少次后熔断;0=默认3;负数=关闭熔断 external_mcp_circuit_cooldown_seconds: 60 # 熔断冷却秒数;0=默认60这些参数会通过ConfigureResilience写入管理器运行时状态(含默认值归一化逻辑,normalizeExternalMCPResilienceConfig)。对高负载或不可靠的外部服务,建议显式调大并发上限并调整熔断阈值,避免默认值过于保守或过于激进。
工具暴露策略:用 tool_search 控制上下文成本
工具过多会增加上下文成本和误选概率,尤其在多代理场景。CyberStrikeAI 通过tool_search机制实现“常用工具常驻、其余按需解锁”:
multi_agent: eino_middleware: tool_search_enable: true tool_search_min_tools: 20 tool_search_always_visible: 12 tool_search_always_visible_tools: - read_file - glob - grep - tool_search参数语义(见 config.example.yaml 的详细注释):
tool_search_enable: true:当工具总数达到tool_search_min_tools(默认 20)时启用动态工具搜索,仅前 N 个工具常驻上下文,其余按正则按需解锁,省 token、减误选;tool_search_always_visible: 12:始终直接暴露给模型的工具个数,顺序与角色工具列表一致;tool_search_always_visible_tools:后端内置常驻工具白名单(优先级高于数量策略),配置示例中的 read_file / glob / grep / tool_search 等为默认推荐集;实际默认白名单还包含 analyze_image、write_file、edit_file、execute、task、transfer_to_agent、webshell_、batch_task_、record_vulnerability 等平台关键工具。
外部 MCP 接入后,其工具默认进入动态池(不常驻),由tool_search按名称/描述命中后解锁——这既控制了上下文成本,也天然降低了“外部工具被误选”的概率。工具是否对当前 Agent 可见还受角色权限与 HITL 策略影响,排查“工具看不到”时这三层都要检查。
工具命名规范:提升命中率、降低误调用
工具名应:
- 稳定:不随版本随意变更,避免 Agent 记忆失效;
- 小写或 snake_case:与平台内置工具风格一致,便于
tool_search正则匹配; - 表达动作和对象:动词 + 对象,让 LLM 一眼理解用途;
- 避免和内置工具重名:重名会与平台工具产生冲突(外部工具统一带
服务器名::前缀可缓解,但内部命名仍需注意)。
不建议:
run execute scan tool1建议:
burp_send_to_repeater asset_lookup_domain cloud_list_public_buckets好的工具名会提升tool_search命中率,也降低 Agent 误调用风险——名称本身就是最廉价的“接口文档”。
安全建议与外部 MCP 安全审查清单
安全基线建议
- 外部 MCP 只接入可信服务:不可信来源的工具描述、参数 schema 都可能被用于诱导 Agent;
- 远端 MCP 必须认证:通过
headers配置 Token / API Key,避免裸奔在网络上; - 高风险工具不要常驻上下文:利用
tool_search把外部工具放入动态池,仅在需要时解锁; - 外部 MCP 的文件系统和命令执行能力要单独评估:一个能读写本机文件、能执行任意命令的 stdio 服务,等于给 Agent 发了一把万能钥匙;
- 变更外部 MCP 后查看审计日志:管理端 upsert / delete 均写入平台审计(
audit服务的external_mcp分类),配合 docs/zh-CN/audit-and-monitoring.md 审计查询接口可回溯谁在何时改了什么。
接入前安全审查清单
接入任何一个外部 MCP 前,先回答以下问题:
- 它能读写本机文件吗?
- 它能执行命令吗?
- 它会访问哪些网络?
- 它是否把请求发给第三方?
- 它的工具描述是否可信?
- 它的输出是否可能包含 prompt injection?
- 它是否需要独立运行用户或容器隔离?
只要答案不清楚,就不要放进生产环境常驻工具池。对外部服务能力边界存疑时,优先以独立系统用户或容器运行 stdio 服务,缩小权限面;对输出包含不可信文本的服务(如扫描器结果、网页抓取),要考虑 prompt injection 对后续 Agent 推理的污染风险。
调试排查:从状态到根因的五步法
外部 MCP 接入出问题时,按以下顺序排查(对应 docs/zh-CN/troubleshooting.md 的通用排障思路):
GET /api/external-mcp/stats查看状态:先确认 total / enabled / connected 是否符合预期,判断是配置问题还是连接问题;- 检查服务日志:连接失败、Initialize 错误、重连尝试都会记录在平台日志中;
connection refused通常表示目标未启动; - 单独运行 stdio 命令:在命令行手动执行
command args,验证进程能否独立启动、协议是否正常握手; - 用 curl 测试 HTTP/SSE 地址:直接请求目标 URL 确认可达性、认证头与协议版本兼容性;
- 检查工具是否被角色或 tool_search 策略隐藏:即使连接成功、工具已拉取,角色权限或
tool_search白名单也可能导致工具对当前 Agent 不可见;确认tool_count正常后,检查角色配置(roles/ 下的 YAML)与multi_agent.eino_middleware.tool_search_*配置。
结合生命周期七步定位:stats状态对应第 2 步(连接)、tool_count对应第 3 步(拉取)、工具可见性对应第 4 步(暴露)、execution_id与执行记录对应第 5 步(执行)。
源码锚点速查
以下文件是深入理解 MCP 联邦的实现入口:
- 外部 MCP Manager(注册/启动/停止/调用/统计/熔断/并发控制):internal/mcp/external_manager.go
- 连接恢复(断连检测、指数退避重连):internal/mcp/connection_recovery.go
- MCP 工具适配(工具定义到 Eino InvokableTool 的桥接):internal/einomcp/mcp_tools.go
- 外部 MCP Handler(管理 API 与配置持久化):internal/handler/external_mcp.go
- 工具调用通知(Eino run loop 与工具结果的 UI 联动):internal/einomcp/tool_invoke_notify.go
- 内置 MCP Server(工具/提示词/资源注册):internal/mcp/server.go
- 外部 MCP 配置结构体(字段定义与环境变量展开):internal/config/config.go
- 完整配置示例(mcp / external_mcp / agent 弹性参数 / tool_search):config.example.yaml
- 管理 API 测试用例:internal/handler/external_mcp_test.go
【免费下载链接】CyberStrikeAIThe system of action for AI-native cybersecurity—where intent becomes governed execution, evidence becomes operational memory, and every operation improves the next.项目地址: https://gitcode.com/GitHub_Trending/cy/CyberStrikeAI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考