UFO 项目 LinuxAgent MCP 命令体系实战:execute_command 与 get_system_info 完整指南
【免费下载链接】UFOUFO³: Weaving the Digital Agent Galaxy项目地址: https://gitcode.com/GitHub_Trending/uf/UFO
导读
在 UFO 开源仓库(UFO³: Weaving the Digital Agent Galaxy)中,LinuxAgent是一个专为 Linux 命令行环境设计的轻量级单智能体,它通过MCP(Model Context Protocol)工具与 Linux 系统交互。本文以仓库文档 documents/docs/linux/commands.md 为核心,深入剖析 LinuxAgent 的两大原子工具——execute_command(通用 Shell 命令执行)与get_system_info(系统信息采集),并结合 linux_mcp_server.py 源码揭示其安全模型与实现原理。读完本文,你将掌握:如何通过Command消息与命令调度器驱动 LinuxAgent 执行 CLI 任务、如何解读结构化返回结果与退出码、如何基于顺序/条件/错误恢复策略组合命令完成多轮迭代任务,以及 MCP 服务器层的命令白名单、危险模式拦截与 API 密钥认证机制。
LinuxAgent 命令架构
MCP Server 集成
LinuxAgent 与 Linux 系统的所有交互均通过Linux MCP Server提供的 MCP 工具完成。这些工具是 CLI 任务执行的原子构建块,把系统相关的操作全部隔离在 MCP 服务器层:
这种架构带来两个直接收益:
- 可测试性:命令可以被 mock,Agent 层的单元测试无需真实执行 Shell 命令;
- 可移植性:MCP 服务器可以远程部署,Agent 与具体操作系统解耦。
从源码看,该 MCP 服务器的实现位于 ufo/client/mcp/http_servers/linux_mcp_server.py,基于fastmcp构建,默认以streamable-http传输方式运行在localhost:8010。
Command Dispatcher
命令通过Command消息统一封装后交给调度器(Command Dispatcher)执行。Command是 aip/messages.py 中定义的 Pydantic 模型,包含四个字段:
tool_name:要执行的工具名称(如execute_command);parameters:工具参数字典(如{"command": "df -h", "timeout": 30});tool_type:工具类型,取值data_collection或action;call_id:可选的调用唯一标识,用于与执行结果Result的call_id对应。
典型用法:
from aip.messages import Command # Create command command = Command( tool_name="execute_command", parameters={"command": "df -h", "timeout": 30}, tool_type="action" ) # Execute command via dispatcher results = await command_dispatcher.execute_commands([command]) execution_result = results[0].result调度器支持一次提交多个Command,返回对应的Result列表;每个Result包含status(success/failure/skipped/none)、error、result(实际结果载荷)等字段,见 aip/messages.py。
execute_command:通用 Shell 命令执行
用途:执行任意的(白名单内的)Shell 命令并捕获结构化结果。
工具规范
tool_name = "execute_command" parameters = { "command": "df -h", # Shell command to execute "timeout": 30, # Execution timeout (seconds, default: 30) "cwd": "/home/user" # Optional working directory }参数说明(结合源码 linux_mcp_server.py):
command(必填):要执行的命令字符串;api_key(必填):API 密钥,必须与服务器端环境变量UFO_MCP_API_KEY一致,否则认证失败;timeout(可选,默认 30):最长执行秒数,服务器会将其钳制在1–120秒范围内;cwd(可选):执行时的工作目录,必须是存在的绝对路径,服务器会先解析并校验,防止路径穿越。
执行流程
结果结构
命令执行结果统一结构化为:
{ "success": True, # Boolean indicating success "exit_code": 0, # Process exit code "stdout": "Filesystem Size Used Avail Use% Mounted on\n/dev/sda1 100G 50G 46G 52% /\n", "stderr": "" # Standard error output }其中success由exit_code == 0推导得出,stdout/stderr均以 UTF-8 解码(errors="replace",避免编码异常导致整体失败)。当校验或执行异常时,返回{"success": False, "error": "..."}形式。
常见用例
| Use Case | Command Example | Description |
|---|---|---|
| File Operations | ls -la /home/user | List directory contents |
| Text Processing | grep "error" /var/log/syslog | Search log files |
| System Monitoring | top -bn1 | Check system processes |
| Disk Management | df -h | Check disk space |
| Network Operations | ping -c 4 example.com | Test network connectivity |
| Archive Creation | tar -czf backup.tar.gz /data | Create compressed archives |
| Package Management | apt list --installed | List installed packages |
注意:上表中的命令示例对应文档语义。在当前仓库的实际实现中,
execute_command采用严格白名单策略,仅允许一组只读/诊断型基础命令(如ls、cat、grep、find、df、ps、ping等),并以shell=False方式执行,详见下文「源码级安全模型」一节。
错误处理
退出码解读(Unix 惯例):
- 0:成功
- 1-125:命令特定错误
- 126:命令不可执行
- 127:命令未找到
- 128+n:被信号 n 终止
错误结果示例:
{ "success": False, "error": "Command not found: invalid_cmd" }另外,当命令执行超过timeout时,服务器会杀掉子进程并返回Timeout after {timeout}s.的错误信息,避免悬挂进程。
安全注意事项
!!!warning "Command Safety" MCP 服务器会拦截危险命令,包括:
- `rm -rf /` - 递归删除根目录 - Fork bombs - `:(){ :|:& };:` - `mkfs` - 文件系统格式化 - `dd if=/dev/zero` - 设备覆写 - `shutdown`、`reboot` - 系统关机 命令以用户权限执行,不自动提权。超时保护可防止进程悬挂。get_system_info:系统信息采集
用途:用标准命令收集基础 Linux 系统信息。
工具规范
tool_name = "get_system_info" parameters = {} # No parameters required除必填的api_key外,无需其他参数。服务器端使用固定参数列表执行命令(无用户输入、无 shell 解释),天然避免注入。
采集的信息
| Info Type | Command | Data Returned |
|---|---|---|
| uname | uname -a | System and kernel information |
| uptime | uptime | System uptime and load averages |
| memory | free -h | Memory usage statistics (human-readable) |
| disk | df -h | Disk space for all mounted filesystems |
执行流程
结果示例
{ "uname": "Linux hostname 5.15.0-91-generic #101-Ubuntu SMP x86_64 GNU/Linux", "uptime": " 14:23:45 up 5 days, 3:12, 2 users, load average: 0.52, 0.58, 0.59", "memory": " total used free shared buff/cache available\nMem: 15Gi 8.2Gi 1.5Gi 256Mi 5.8Gi 7.0Gi\nSwap: 8.0Gi 512Mi 7.5Gi", "disk": "Filesystem Size Used Avail Use% Mounted on\n/dev/sda1 100G 50G 46G 52% /\n/dev/sdb1 500G 200G 276G 42% /data" }单个命令执行失败不会导致整体失败,对应键会填充Error: <exception>文本,便于后续诊断。
命令执行流水线
原子构建块
execute_command与get_system_info是 LinuxAgent 的两个原子操作,它们在 CONTINUE 状态下被反复编排:
系统操作隔离
将系统操作隔离在 MCP 服务器层后,架构实现了清晰分层:Agent 层专注于 LLM 推理与工作流编排,MCP 层处理系统相关的命令执行。这提供了可测试性(命令可 mock)与可移植性(MCP 服务器可远程部署)。
命令组合:从单条命令到多轮任务
LinuxAgent 在 CONTINUE 状态下逐轮执行命令,每轮结果写入内存(memory),供下一轮决策使用。以下三种组合模式来自 commands.md 的实战范式。
顺序执行
基于上一轮结果决定本轮命令:
# Round 1: Check disk space { "action": { "tool": "execute_command", "arguments": {"command": "df -h /data"} } } # Result: 276GB available # Round 2: Create backup (informed by Round 1 result) { "action": { "tool": "execute_command", "arguments": { "command": "tar -czf /data/backup.tar.gz /home/user" } } }条件执行
LLM 依据命令结果(特别是exit_code)做分支决策:
# Round 1: Check if file exists { "action": { "tool": "execute_command", "arguments": {"command": "ls /data/backup.tar.gz"} } } # Result: exit_code=2 (file not found) # Round 2: File doesn't exist, create it { "thought": "Backup doesn't exist, creating new one", "action": { "tool": "execute_command", "arguments": {"command": "tar -czf /data/backup.tar.gz /home/user"} } }错误恢复
主方案失败时切换到备选方案:
# Round 1: Try privileged command { "action": { "tool": "execute_command", "arguments": {"command": "systemctl restart nginx"} } } # Result: success=False, error="Permission denied" # Round 2: Switch to user-level alternative { "thought": "Don't have sudo access, using alternative approach", "action": { "tool": "execute_command", "arguments": {"command": "kill -HUP $(cat /var/run/nginx.pid)"} } }源码级安全模型:linux_mcp_server.py 深入剖析
ufo/client/mcp/http_servers/linux_mcp_server.py 是 Linux MCP Server 的完整实现,其安全模型远比文档列举的"危险命令拦截"更严格,共分四层:
1. 命令白名单(Allow-list)
服务器维护ALLOWED_SHELL_COMMANDS集合(linux_mcp_server.py#L116-L170),只放行只读/诊断型基础命令,例如文件类(ls、pwd、cat、head、tail)、搜索类(grep、find、which)、文本处理类(wc、sort、uniq、cut、tr)、系统信息类(uname、uptime、free、df、ps)、网络诊断类(ping、traceroute、nslookup、dig)以及echo、date、stat、diff等。校验时对基础命令做os.path.basename归一化,防止/usr/bin/bash这类路径绕过。
2. 危险模式扫描(Dangerous-pattern scan)
_DANGEROUS_PATTERNS(linux_mcp_server.py#L173-L189)拦截:Shell 元字符;|&``、命令替换$(/${、find -exec/-execdir、反向 Shell 特征/dev/tcp/、/dev/udp/、I/O 重定向>/<` 以及换行/空字节注入。
3. 逐命令参数策略(Argument policies)
对python/python3只允许--version/-V(防止python3 -c执行任意代码),对find禁止-exec、-delete、-ok、-fprint*等副作用参数(linux_mcp_server.py#L192-L238)。
4. 执行与传输层防护
shell=False:通过asyncio.create_subprocess_exec直接执行 token 列表,Shell 元字符永远不会被解释(linux_mcp_server.py#L417-L425);- API 密钥认证:
_validate_api_key使用hmac.compare_digest做常数时间比较,且未配置UFO_MCP_API_KEY时默认拒绝所有请求(fail-closed)(linux_mcp_server.py#L308-L320); - cwd 校验:
_validate_cwd解析绝对路径并确保目录存在,防止路径穿越(linux_mcp_server.py#L323-L338); - DNS-rebinding 防护:
LocalhostGuardMiddleware拒绝 Host/Origin 非本地的请求,拦截跨域fetch(linux_mcp_server.py#L69-L110)。
服务器启动入口(linux_mcp_server.py#L492-L524)在未设置UFO_MCP_API_KEY时直接报错退出,可用如下方式启动:
export UFO_MCP_API_KEY='<your-secret-key>' python -m ufo.client.mcp.http_servers.linux_mcp_server --port 8010提示:
create_bash_mcp_server默认绑定localhost;如需远程访问可指定--host 0.0.0.0,但源码会打印显式警告——这会暴露到所有网络接口,仅在确实需要远程调用时才应启用。
最佳实践
工具使用
- 需要快速概览系统状态时,优先用
get_system_info(一次调用拿到 uname/uptime/内存/磁盘); - 自定义或复杂操作使用
execute_command; - 务必检查
success字段和exit_code判断是否真正成功; - 尽量解析
stdout中的结构化数据(如df -h的输出); - 合理设置
timeout,防止命令悬挂拖死整个任务循环。
安全
!!!warning "Security Best Practices" MCP 服务器自带防护,但仍需谨慎:
- 危险命令会被自动拦截 - 命令仅以用户权限执行 - 尽量不使用 sudo(需要用户交互) - 日志输出前应对输出做脱敏(可能包含敏感数据)错误处理
- 先检查
success再认定命令成功; - 解析
stderr获取错误细节; - 对瞬时错误实现重试;
- 主方案失败时提供替代方案(错误恢复模式)。
与其他 Agent 命令对比
| Agent | Command Types | Execution Layer | Result Format |
|---|---|---|---|
| LinuxAgent | CLI + SysInfo | MCP server | success/exit_code/stdout/stderr |
| AppAgent | UI + API | Automator + MCP | UI state + API responses |
| HostAgent | Desktop + Shell | Automator + MCP | Desktop state + results |
LinuxAgent 的命令集刻意保持精简:
- execute_command:通用命令执行
- get_system_info:标准化系统信息
这种简洁性正对应 CLI 环境以文本和命令驱动为本质的特点。从状态机角度看,命令执行发生在 CONTINUE 状态的三阶段流水线中(LLM 决策 → 命令执行 → 内存更新),LLM 返回的status决定下一轮状态是 CONTINUE、FINISH 还是 FAIL,相关实现见 ufo/agents/states/linux_agent_state.py 与策略文档 documents/docs/linux/strategy.md。
延伸阅读
- State Machine - 理解命令执行如何融入 3 态 FSM
- Processing Strategy - 命令如何集成进三阶段流水线
- LinuxAgent Overview - 回到 LinuxAgent 架构总览
- MCP Overview - MCP 服务器实现细节
- linux_mcp_server.py - 本主题核心源码
- aip/messages.py -
Command/Result消息模型定义
【免费下载链接】UFOUFO³: Weaving the Digital Agent Galaxy项目地址: https://gitcode.com/GitHub_Trending/uf/UFO
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考