UFO 项目 MCP 配置完全指南:从分层 YAML 结构到服务器生命周期管理
UFO 项目 MCP 配置完全指南从分层 YAML 结构到服务器生命周期管理【免费下载链接】UFOUFO³: Weaving the Digital Agent Galaxy项目地址: https://gitcode.com/GitHub_Trending/uf/UFO本篇技术指南系统讲解 UFO 项目中 MCPModel 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: ... ...四层含义Agent NameAgent 名称顶层标识例如HostAgent、AppAgent、ConstellationAgent、HardwareAgent、LinuxAgent。仓库自带配置文件还包含MobileAgent见 config/ufo/mcp.yaml用于 Android 设备自动化。Sub-Type子类型上下文相关配置例如default兜底或具体的应用程序名WINWORD.EXE、EXCEL.EXE、POWERPNT.EXE、explorer.exe。Tool Type工具类型data_collection数据采集框架自动调用、LLM 不可选或action动作执行LLM 每步主动选择。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✅ 是服务器类型local、http或stdioresetboolean❌ 否是否重置服务器状态默认falsestart_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()三个生命周期方法并暴露config、namespace、server三个属性。create_mcp_server()会根据type断言合法性后实例化对应类并调用start()见 ufo/client/mcp/mcp_server_manager.pytype不在映射表中的配置会直接抛出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.pyregister_instance直接注册已创建的FastMCP实例register_factory注册工厂函数实现懒初始化——get()时若实例不存在则调用工厂函数现场创建。工厂还可以通过MCPRegistry.register_factory_decorator(server_name)装饰器注册。UFO 内置的本地服务器模块位于 ufo/client/mcp/local_servers/包括ui_mcp_server、word_wincom_mcp_server、excel_wincom_mcp_server、ppt_wincom_mcp_server、pdf_reader_mcp_server、cli_mcp_server、constellation_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✅ 是服务器主机名或 IPportinteger✅ 是服务器端口号pathstring✅ 是MCP 端点的 URL 路径HTTP 服务器运行在远程机器上通过 REST API 访问。其start()实现会拼接http://{host}:{port}{path}生成 URL默认值分别为localhost、8000、/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(commandcommand, argsstart_args, envenv, cwdcwd)见 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: falseWord 专属配置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 APIinsert_table、select_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: truePowerPoint 专属配置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多设备协同 AgentConstellationAgent: default: action: - namespace: ConstellationEditor type: local start_args: [] reset: false可用工具创建任务、分配设备、查看任务状态。HardwareAgent远程硬件监控 AgentHardwareAgent: 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.py、linux_mcp_server.py、mobile_mcp_server.py。LinuxAgentLinux 系统 AgentLinuxAgent: default: action: - namespace: BashExecutor type: http host: localhost port: 8010 path: /mcp reset: false可用工具Bash 命令执行。MobileAgentAndroid 设备 Agent虽然配置文档正文未展开但仓库自带的 config/ufo/mcp.yaml 已给出MobileAgent的完整配置MobileDataCollectorHTTP端口 8020带${UFO_MCP_API_KEY}认证负责 Android 设备观测MobileActionExecutorHTTP端口 8021同样带认证负责点击、滑动、启动应用等控制操作。它是HTTP 远程 环境变量认证组合的现成范例。配置示例三种典型组合示例 1纯本地 AgentSimpleAgent: 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多上下文 AgentMultiContextAgent: # 默认配置 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.exe与Code.exe在default基础上各自追加专属采集器与执行器且对有状态执行器开启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 # 切勿提交到仓库仓库对此有双重保障MobileAgent的auth使用${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_CONFIG、MCP_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不支持的类型使用local、http或stdioMissing host for http serverHTTP 服务器缺少 host添加host和portDuplicate namespace同一命名空间被使用两次使用唯一命名空间此外运行时还有一层防线MCPServerManager.create_mcp_server()对未知type的断言会直接中断启动见 ufo/client/mcp/mcp_server_manager.pyLocalMCPServer.start()对未注册的 namespace 会抛出带明确提示的ValueError。调试配置启用调试日志import logging logging.basicConfig(levellogging.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(fServer: {namespace}, Type: {type(server).__name__})_servers_mapping是MCPServerManager的类级字典以 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.yamlMCP_SERVERS: - name: ui_collector module: ufo.mcp.ui_server新格式mcp.yamlHostAgent: default: data_collection: - namespace: UICollector type: local新旧格式的关键差异旧格式是扁平列表 module 引用新格式是按 Agent 分层的 namespace 映射。仓库提供了两条迁移路径自动迁移工具ufo/tools/convert_config.py 可将旧版agent_mcp.yaml直接转换为mcp.yaml文件内标注了agent_mcp.yaml → mcp.yaml的映射规则运行时回退即使未迁移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),仅供参考