news 2026/9/16 21:51:40

UFO 项目 MCP 配置完全指南:从分层 YAML 结构到服务器生命周期管理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UFO 项目 MCP 配置完全指南:从分层 YAML 结构到服务器生命周期管理

UFO 项目 MCP 配置完全指南:从分层 YAML 结构到服务器生命周期管理

【免费下载链接】UFOUFO³: Weaving the Digital Agent Galaxy项目地址: https://gitcode.com/GitHub_Trending/uf/UFO

本篇技术指南系统讲解 UFO 项目中 MCP(Model Context Protocol)的配置文件设计与实战使用。UFO 通过一份位于config/ufo/mcp.yaml的分层 YAML 配置,将不同 Agent(如 HostAgent、AppAgent、HardwareAgent)映射到各自的 MCP 服务器,从而统一管理"数据采集"与"动作执行"两类工具。读完本文,你将掌握四层配置层级、local/http/stdio 三种服务器类型的字段语义、内置 Agent 的完整配置样例、加载与校验方式,以及从旧版配置迁移的完整路径,能够独立为自定义 Agent 编写可运行、可维护的 MCP 配置。

MCP 配置在 UFO 中的定位

MCP 是 UFO 中 Agent 与外部工具交互的统一协议层:Agent 负责决策"做什么",MCP 服务器负责实现"怎么做"。而mcp.yaml正是将两者绑定在一起的"映射表"——它为每个 Agent 声明可用的数据采集服务器(只读观察)与动作服务器(状态变更)。

配置文件的默认位置为:

config/ufo/mcp.yaml

从源码结构看,该路径由两处共同确认:系统配置项的默认值mcp_servers_config: str = "config/ufo/mcp.yaml"(见 config/config_schemas.py),以及配置加载器ufo/config/__init__.py中"优先读取新位置config/ufo/mcp.yaml、回退到旧位置ufo/config/agent_mcp.yaml"的加载逻辑(见 ufo/config/init.py)。

配置结构:四层层级模型

MCP 配置采用层级 YAML 结构,自上而下共四层:

AgentName: # 第 1 层:Agent 名称 SubType: # 第 2 层:子类型(如 "default"、"WINWORD.EXE") data_collection: # 第 3 层:工具类型(数据采集服务器) - namespace: ... # 第 4 层:服务器列表 type: ... # 服务器类型(local/http/stdio) ... # 其他服务器配置 action: # 第 3 层:工具类型(动作服务器) - namespace: ... type: ... ...

四层含义

  1. Agent Name(Agent 名称):顶层标识,例如HostAgentAppAgentConstellationAgentHardwareAgentLinuxAgent。仓库自带配置文件还包含MobileAgent(见 config/ufo/mcp.yaml),用于 Android 设备自动化。
  2. Sub-Type(子类型):上下文相关配置,例如default(兜底)或具体的应用程序名WINWORD.EXEEXCEL.EXEPOWERPNT.EXEexplorer.exe
  3. Tool Type(工具类型)data_collection(数据采集,框架自动调用、LLM 不可选)或action(动作执行,LLM 每步主动选择)。
  4. Server List(服务器列表):一个数组,包含若干 MCP 服务器配置,每个配置以namespace唯一标识。

层级关系可以形象地表示为:

AgentName └─ SubType ├─ data_collection │ ├─ Server 1 │ ├─ Server 2 │ └─ ... └─ action ├─ Server 1 ├─ Server 2 └─ ...

Default 子类型约定:始终定义一个default子类型作为兜底配置。如果找不到特定子类型,Agent 会自动回退到default。这一"继承默认、按需覆盖"的机制正是配置哲学中hierarchical原则的体现,也是 AppAgent 能同时服务 Word、Excel、PowerPoint 等多个应用场景的关键。

服务器配置字段详解

通用字段(所有服务器共享)

字段类型必填说明
namespacestring✅ 是服务器唯一标识符
typestring✅ 是服务器类型:localhttpstdio
resetboolean❌ 否是否重置服务器状态(默认:false
start_argsarray❌ 否传递给服务器初始化的参数

在源码层面,MCPServerManager通过_server_type_mapping字典把type字段直接映射到三个实现类(见 ufo/client/mcp/mcp_server_manager.py):

_server_type_mapping: Dict[str, Callable[[Dict[str, Any]], BaseMCPServer]] = { "http": HTTPMCPServer, "local": LocalMCPServer, "stdio": StdioMCPServer, }

三者都继承自抽象基类BaseMCPServer,统一实现start()stop()reset()三个生命周期方法,并暴露confignamespaceserver三个属性。create_mcp_server()会根据type断言合法性后实例化对应类并调用start()(见 ufo/client/mcp/mcp_server_manager.py),type不在映射表中的配置会直接抛出Unsupported server type断言错误。

Local(进程内)服务器字段

- namespace: UICollector type: local start_args: [] reset: false
字段说明
start_args传递给服务器工厂函数的参数

Local 服务器从MCPRegistry中按namespace取出FastMCP实例,在 Agent 进程内运行(in-process),无 IPC 开销、启动最快。其启动逻辑见 ufo/client/mcp/mcp_server_manager.py:调用MCPRegistry.get(server_namespace, ...),若 registry 中没有对应名称则抛出KeyError并提示"本地服务器注册表中找不到该名称"。

MCPRegistry是集中的服务器注册表,支持两种注册方式(见 ufo/client/mcp/mcp_registry.py):

  • register_instance:直接注册已创建的FastMCP实例;
  • register_factory:注册工厂函数,实现懒初始化——get()时若实例不存在,则调用工厂函数现场创建。工厂还可以通过@MCPRegistry.register_factory_decorator("server_name")装饰器注册。

UFO 内置的本地服务器模块位于 ufo/client/mcp/local_servers/,包括ui_mcp_serverword_wincom_mcp_serverexcel_wincom_mcp_serverppt_wincom_mcp_serverpdf_reader_mcp_servercli_mcp_serverconstellation_mcp_server等。注意:local_servers/__init__.py定义了WINDOWS_ONLY_SERVERS集合,ui_mcp_server及四个 Windows COM 服务器在非 Windows 平台上会被自动跳过(见 ufo/client/mcp/local_servers/init.py),因此 UI 类 local 服务器是 Windows 专属能力。

HTTP(远程)服务器字段

- namespace: HardwareCollector type: http host: "localhost" port: 8006 path: "/mcp" reset: false
字段类型必填说明
hoststring✅ 是服务器主机名或 IP
portinteger✅ 是服务器端口号
pathstring✅ 是MCP 端点的 URL 路径

HTTP 服务器运行在远程机器上,通过 REST API 访问。其start()实现会拼接http://{host}:{port}{path}生成 URL(默认值分别为localhost8000/mcp),并支持可选的auth字段:若auth包含未解析的环境变量占位符(如${UFO_MCP_API_KEY}),会抛出ValueError提示"HTTP MCP auth 包含未解析的环境变量";只有合法的非空字符串才会构建带认证的StreamableHttpTransport(见 ufo/client/mcp/mcp_server_manager.py)。仓库的MobileAgent配置就使用了auth: "${UFO_MCP_API_KEY}"的写法(见 config/ufo/mcp.yaml)。

由于 HTTP 服务器通常由外部进程托管,其stop()reset()均为占位实现(reset 会打印"HTTP MCP server reset is not supported"提示),本质上被视为无状态服务。

Stdio(子进程)服务器字段

- namespace: CustomProcessor type: stdio command: "python" start_args: ["-m", "custom_mcp_server"] env: {"API_KEY": "secret"} cwd: "/path/to/server" reset: false
字段类型必填说明
commandstring✅ 是可执行命令
start_argsarray❌ 否命令行参数
envobject❌ 否环境变量
cwdstring❌ 否工作目录

Stdio 服务器以子进程方式运行,通过 stdin/stdout 与 Agent 双向通信,实现进程隔离与干净的资源管理。其start()直接构造StdioTransport(command=command, args=start_args, env=env, cwd=cwd)(见 ufo/client/mcp/mcp_server_manager.py),默认命令为python、默认工作目录为.。适合需要沙箱隔离或语言无关的自定义服务器场景。

内置 Agent 的 MCP 配置

HostAgent(系统级 Agent)

面向操作系统全局自动化:

HostAgent: default: data_collection: - namespace: UICollector type: local start_args: [] reset: false action: - namespace: HostUIExecutor type: local start_args: [] reset: false - namespace: CommandLineExecutor type: local start_args: [] reset: false

可用工具

  • 数据采集:UI 检测、截屏
  • 动作:系统级点击、窗口管理、CLI 执行

AppAgent(应用级 Agent)

面向具体应用程序的自动化。同一 Agent 可通过不同 SubType 复用default基础能力并叠加专属执行器。

默认配置
AppAgent: default: data_collection: - namespace: UICollector type: local start_args: [] reset: false action: - namespace: AppUIExecutor type: local start_args: [] reset: false - namespace: CommandLineExecutor type: local start_args: [] reset: false
Word 专属配置
AppAgent: WINWORD.EXE: data_collection: - namespace: UICollector type: local start_args: [] reset: false action: - namespace: AppUIExecutor type: local start_args: [] reset: false - namespace: WordCOMExecutor type: local start_args: [] reset: true # 切换文档时重置 COM 状态

可用工具:数据采集与 default 相同;动作包含 App UI 自动化 + Word COM API(insert_tableselect_text等)。

Reset 标志:对有状态工具(如 COM 执行器)设置reset: true,防止跨上下文(如不同文档之间)的状态泄漏。

Excel 专属配置
AppAgent: EXCEL.EXE: data_collection: - namespace: UICollector type: local reset: false action: - namespace: AppUIExecutor type: local reset: false - namespace: ExcelCOMExecutor type: local reset: true
PowerPoint 专属配置
AppAgent: POWERPNT.EXE: data_collection: - namespace: UICollector type: local reset: false action: - namespace: AppUIExecutor type: local reset: false - namespace: PowerPointCOMExecutor type: local reset: true
文件资源管理器配置
AppAgent: explorer.exe: data_collection: - namespace: UICollector type: local reset: false action: - namespace: AppUIExecutor type: local reset: false - namespace: PDFReaderExecutor type: local reset: true

以上配置与仓库中的 config/ufo/mcp.yaml 完全一致。从架构角度看,AppAgent 的每个 SubType 都采用了"GUI 自动化(AppUIExecutor)+ API 自动化(COM Executor)"双模式组合:LLM 在每一步根据可靠性、速度与可用性动态选择走 API(快、确定)还是走 GUI(处理 API 无法覆盖的视觉元素)。例如插入表格用WordCOMExecutor::insert_table,而切换到 Design 标签页则回退到AppUIExecutor::click_input

ConstellationAgent(多设备协同 Agent)

ConstellationAgent: default: action: - namespace: ConstellationEditor type: local start_args: [] reset: false

可用工具:创建任务、分配设备、查看任务状态。

HardwareAgent(远程硬件监控 Agent)

HardwareAgent: default: data_collection: - namespace: HardwareCollector type: http host: "localhost" port: 8006 path: "/mcp" reset: false action: - namespace: HardwareExecutor type: http host: "localhost" port: 8006 path: "/mcp" reset: false

可用工具

  • 数据采集:CPU 信息、内存信息、磁盘信息
  • 动作:硬件控制命令

远程部署:使用远程服务器时,需确保目标机器上已运行 HTTP MCP 服务器,部署指南见 Remote Servers。仓库中对应的服务端实现位于 ufo/client/mcp/http_servers/(hardware_mcp_server.pylinux_mcp_server.pymobile_mcp_server.py)。

LinuxAgent(Linux 系统 Agent)

LinuxAgent: default: action: - namespace: BashExecutor type: http host: "localhost" port: 8010 path: "/mcp" reset: false

可用工具:Bash 命令执行。

MobileAgent(Android 设备 Agent)

虽然配置文档正文未展开,但仓库自带的 config/ufo/mcp.yaml 已给出MobileAgent的完整配置:MobileDataCollector(HTTP,端口 8020,带${UFO_MCP_API_KEY}认证)负责 Android 设备观测,MobileActionExecutor(HTTP,端口 8021,同样带认证)负责点击、滑动、启动应用等控制操作。它是"HTTP 远程 + 环境变量认证"组合的现成范例。

配置示例:三种典型组合

示例 1:纯本地 Agent

SimpleAgent: default: data_collection: - namespace: UICollector type: local reset: false action: - namespace: SimpleExecutor type: local reset: false

适用于完全依赖内置本地工具的场景,零网络依赖。

示例 2:混合 Agent(本地 + 远程)

HybridAgent: default: data_collection: # 本地 UI 检测 - namespace: UICollector type: local reset: false # 远程硬件监控 - namespace: HardwareCollector type: http host: "192.168.1.100" port: 8006 path: "/mcp" reset: false action: # 本地 UI 自动化 - namespace: UIExecutor type: local reset: false # 远程命令执行 - namespace: RemoteExecutor type: http host: "192.168.1.100" port: 8007 path: "/mcp" reset: false

展示如何在同一 Agent 内同时挂载本地与远程服务器,实现"就近处理 + 分布式扩展"。

示例 3:多上下文 Agent

MultiContextAgent: # 默认配置 default: data_collection: - namespace: BasicCollector type: local action: - namespace: BasicExecutor type: local # Chrome 专属 chrome.exe: data_collection: - namespace: BasicCollector type: local - namespace: WebCollector type: local action: - namespace: BasicExecutor type: local - namespace: BrowserExecutor type: local reset: true # VS Code 专属 Code.exe: data_collection: - namespace: BasicCollector type: local - namespace: IDECollector type: local action: - namespace: BasicExecutor type: local - namespace: CodeExecutor type: local reset: true

充分利用"default 兜底 + 子类型覆盖"机制:chrome.exeCode.exedefault基础上各自追加专属采集器与执行器,且对有状态执行器开启reset

最佳实践

1. 使用描述性命名空间

# ✅ 良好:清晰且具描述性 namespace: WindowsUICollector namespace: ExcelCOMExecutor namespace: LinuxBashExecutor # ❌ 糟糕:通用且含义不明 namespace: Collector1 namespace: Server namespace: Tools

清晰的namespace不仅便于人类阅读维护,也直接影响调试日志的可读性(如Registered MCP server 'UICollector' ...)。

2. 按用途分组服务器

# ✅ 良好:逻辑分组 HostAgent: default: data_collection: - namespace: UICollector # 所有 UI 相关 - namespace: ScreenshotTaker action: - namespace: UIExecutor # 所有 UI 动作 - namespace: WindowManager # ❌ 糟糕:目的混杂 HostAgent: default: data_collection: - namespace: UICollector - namespace: HardwareMonitor # 用途不同

3. 重置有状态服务器

# ✅ 良好:重置 COM 服务器 WordCOMExecutor: type: local reset: true # 防止状态泄漏 # ❌ 糟糕:不重置可能引发问题 WordCOMExecutor: type: local reset: false # 可能残留上一个文档的状态

4. 验证远程服务器可用性

# 使用远程服务器时,确保其可达 HardwareCollector: type: http host: "192.168.1.100" # ✅ 验证该主机可达 port: 8006 # ✅ 验证端口开放 path: "/mcp" # ✅ 验证端点存在

5. 用环境变量管理密钥

# ✅ 良好:使用环境变量 - namespace: SecureAPI type: http host: "${API_HOST}" port: "${API_PORT}" auth: token: "${API_TOKEN}" # ❌ 糟糕:硬编码密钥 - namespace: SecureAPI type: http host: "api.example.com" auth: token: "secret123" # 切勿提交到仓库!

仓库对此有双重保障:MobileAgentauth使用${UFO_MCP_API_KEY}占位符(见 config/ufo/mcp.yaml),而 ufo/client/mcp/mcp_server_manager.py 中定义了_UNRESOLVED_ENV_VAR_PATTERN正则,专门检测未解析的环境变量并拒绝启动——从配置到运行时都杜绝了密钥硬编码的隐患。

加载配置

从文件加载

import yaml from pathlib import Path # 加载 MCP 配置 config_path = Path("config/ufo/mcp.yaml") with open(config_path) as f: mcp_config = yaml.safe_load(f) # 访问 Agent 配置 host_agent_config = mcp_config["HostAgent"]["default"]

以编程方式加载

from ufo.config import get_config # 获取完整配置 configs = get_config() # 访问 MCP 部分 mcp_config = configs.get("mcp", {}) # 获取指定 Agent host_agent = mcp_config.get("HostAgent", {}).get("default", {})

注意:在get_config()中,MCP 配置是作为mcp键嵌入到整体配置字典中的。其加载逻辑见 ufo/config/init.py:优先读取config/ufo/mcp.yaml,若不存在则回退到旧位置ufo/config/agent_mcp.yaml。此外,系统级开关由 config/config_schemas.py 中的字段控制:

系统配置项默认值作用
use_mcptrue是否启用 MCP 工具
mcp_servers_configconfig/ufo/mcp.yamlMCP 配置文件路径
mcp_preferred_apps空列表优先使用 MCP 的应用列表
mcp_fallback_to_uitrueMCP 失败时是否回退到 UI 操作
mcp_instructions_pathufo/config/mcp_instructionsMCP 使用说明文件路径
mcp_tool_timeout30MCP 工具调用超时(秒)
mcp_log_executionfalse是否记录工具执行日志

这些配置均可通过环境变量(如MCP_SERVERS_CONFIGMCP_TOOL_TIMEOUT)覆盖,映射关系见 config/config_schemas.py。

配置校验

Schema 校验

UFO 在加载 MCP 配置时会进行校验:

from ufo.config.config_schemas import MCPConfigSchema # 校验配置 try: MCPConfigSchema.validate(mcp_config) print("✅ Configuration is valid") except ValidationError as e: print(f"❌ Configuration error: {e}")

常见校验错误

错误原因解决方案
Missing required field: namespace服务器缺少命名空间添加namespace字段
Invalid server type: unknown不支持的类型使用localhttpstdio
Missing host for http serverHTTP 服务器缺少 host添加hostport
Duplicate namespace同一命名空间被使用两次使用唯一命名空间

此外,运行时还有一层防线:MCPServerManager.create_mcp_server()对未知type的断言会直接中断启动(见 ufo/client/mcp/mcp_server_manager.py);LocalMCPServer.start()对未注册的 namespace 会抛出带明确提示的ValueError

调试配置

启用调试日志

import logging logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger("ufo.client.mcp") # 将显示服务器创建与注册过程 # DEBUG: Creating MCP server 'UICollector' of type local # DEBUG: Registered MCP server 'UICollector' with 15 tools

这两条日志分别对应MCPServerManager中的创建与注册流程:create_mcp_server()内调用server_instance.start()后,随即调用register_server(),后者会打印Registered MCP server '{namespace}' of type {type(server).__name__}(见 ufo/client/mcp/mcp_server_manager.py)。

查看已加载的服务器

from ufo.client.mcp.mcp_server_manager import MCPServerManager # 列出所有已注册服务器 servers = MCPServerManager._servers_mapping for namespace, server in servers.items(): print(f"Server: {namespace}, Type: {type(server).__name__}")

_servers_mappingMCPServerManager的类级字典,以 namespace 为键、BaseMCPServer实例为值;get_server(namespace)提供了无副作用的查询入口。

测试服务器连通性

async def test_server(config): """测试 MCP 服务器是否可访问。""" try: server = MCPServerManager.create_mcp_server(config) print(f"✅ Server '{config['namespace']}' is accessible") # 列出工具 if hasattr(server, 'server'): from fastmcp.client import Client async with Client(server.server) as client: tools = await client.list_tools() print(f" Tools: {[tool.name for tool in tools]}") except Exception as e: print(f"❌ Server '{config['namespace']}' failed: {e}")

迁移指南:从旧版配置格式升级

如果正在从旧版 UFO 配置迁移:

旧格式(config.yaml):

MCP_SERVERS: - name: ui_collector module: ufo.mcp.ui_server

新格式(mcp.yaml):

HostAgent: default: data_collection: - namespace: UICollector type: local

新旧格式的关键差异:旧格式是"扁平列表 + module 引用",新格式是"按 Agent 分层的 namespace 映射"。仓库提供了两条迁移路径:

  1. 自动迁移工具:ufo/tools/convert_config.py 可将旧版agent_mcp.yaml直接转换为mcp.yaml(文件内标注了agent_mcp.yaml → mcp.yaml的映射规则);
  2. 运行时回退:即使未迁移,ufo/config/init.py 也会在找不到新路径时自动读取旧路径ufo/config/agent_mcp.yaml,保证平滑过渡。

详细迁移说明见 Configuration Migration Guide。

相关文档

  • MCP Overview — MCP 高层架构与概念
  • Data Collection Servers — 数据采集服务器配置
  • Action Servers — 动作服务器配置
  • Local Servers — 内置本地 MCP 服务器清单
  • Remote Servers — HTTP 与 Stdio 部署
  • MCP Reference — 完整字段速查
  • Creating Custom MCP Servers Tutorial — 构建自定义服务器
  • Configuration Guide — 通用配置指南
  • HostAgent Overview — HostAgent 配置示例
  • AppAgent Overview — AppAgent 配置示例

配置哲学

MCP 配置遵循约定优于配置(convention over configuration)原则:

  • 合理的默认值— 最小化必需的配置项;
  • 需要时显式— 需要定制时提供完全控制;
  • 类型安全— 加载时即校验,尽早捕获错误;
  • 层级化— 从默认配置继承,按需覆盖。

结合源码实现可以进一步看到这套哲学如何落地:配置通过config/ufo/mcp.yaml单文件声明,由ufo/config/__init__.py统一加载为mcp键;运行时由MCPServerManager依据type分派到LocalMCPServer/HTTPMCPServer/StdioMCPServer;本地服务器经由MCPRegistry的实例/工厂双通道按需获取,实现"声明式配置 + 懒加载实例化"的完整链路。掌握这一链路后,你可以轻松为新的 Agent 编写 MCP 配置,或将自定义 MCP 服务器无缝接入 UFO 的工具体系。

【免费下载链接】UFOUFO³: Weaving the Digital Agent Galaxy项目地址: https://gitcode.com/GitHub_Trending/uf/UFO

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 21:51:35

同一首歌换6副耳机听感差异有多大?五维实测解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/16 21:47:11

浏览器里的AI视频剪辑管线:WebAssembly+WebGPU端侧推理实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/16 21:46:53

解决Oracle用户crontab的PAM configuration鉴权报错

凌晨两点被电话叫醒,值班的兄弟说Oracle的备份任务连续两晚没跑,登上服务器一看,oracle用户执行crontab -l直接甩出一行报错:You (oracle) are not allowed to access to (crontab) because of pam configuration。这不是Oracle自…

作者头像 李华
网站建设 2026/9/16 21:46:42

SSM文物管理系统实战:动态SQL、事务边界与MySQL优化

简介:本资源是一套基于SSM(SpringSpringMVCMyBatis)框架开发的B/S架构文物管理系统,面向Java Web初学者与课程设计实践者,解决中小型文博单位或高校实训中文物信息数字化管理、用户分权操作及交互式内容展示等核心需求…

作者头像 李华
网站建设 2026/9/16 21:45:57

性能调优方法论与实战:从慢SQL到JVM调优的系统化指南

性能调优这件事,干得多了就会发现它其实不是玄学,而是一套可以重复执行的工程方法。很多人一遇到系统变慢就直接翻代码、加缓存、上机器,折腾一宿没效果,第二天又回滚。我做了这么多年性能优化,踩过的坑比写过的代码还…

作者头像 李华