关于 universal-host-manager-mcp
universal-host-manager-mcp 是用于管理 Linux 和 macOS 主机的 MCP 服务,面向需要通过 MCP 客户端远程操作主机的用户。它提供 OAuth 认证、工作区范围内的文件工具,以及可执行任意 shell 命令的工具。
主要功能
- 01支持 Linux 和 macOS
- 02Streamable HTTP 传输
- 03Auth0 OAuth 认证
- 04工作区范围内的文件读写与目录列表
- 05命令超时和输出截断
- 06磁盘、内存及进程指标
适用场景
- 01通过 MCP 客户端管理远程主机
- 02读取或写入工作区中的文件
- 03查看磁盘、内存和进程信息
- 04运行带超时限制的 shell 命令
MCP 相关
它通过 Streamable HTTP 向 MCP 客户端提供主机管理工具,包括 shell 命令执行、受工作区限制的文件操作和系统指标查询。远程使用可配置 Auth0 OAuth。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx universal-host-manager-mcpHOSTInterface to bind toPORTPort to listen onMCP_WORKSPACE_DIRDirectory that read_file/write_file/list_dir are restricted toAUTH0_DOMAIN密钥Auth0 tenant domain, e.g. your-tenant.eu.auth0.comAUTH0_CLIENT_ID密钥Auth0 application client IDAUTH0_CLIENT_SECRET密钥Auth0 application client secretAUTH0_AUDIENCE密钥Auth0 API audience/identifierALLOW_INSECURE_NO_AUTH密钥Set to true only for local-only testing without Auth0本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Universal Host Manager MCP
一个跨平台的 Model Context Protocol 服务,可通过 ChatGPT 和 Claude 等 MCP 客户端管理 Linux 或 macOS 主机。
它使用 FastMCP Streamable HTTP 传输、Auth0 OAuth、受限文件工具、输出限制和命令超时。
注意
此项目支持执行任意 shell 命令。身份验证决定谁可以使用它,但不能让命令变得无害。部署前请阅读 SECURITY.md。
功能
- 支持 Linux 和 macOS
- Streamable HTTP 端点
- Auth0 OAuth 集成
- 文件读取、写入和目录列表均限制在
MCP_WORKSPACE_DIR内 - 可配置命令超时和输出截断
- 文件大小限制和解码回退
- 未配置身份验证时,启动会失败关闭
- systemd 和 launchd 服务示例
工具
| 工具 | 参数 | 用途 |
|---|---|---|
run_command | command: str、timeout: int | 以工作区为工作目录执行任意 shell 命令 |
read_file | path: str | 读取工作区内的文本文件 |
write_file | path: str、content: str | 在工作区内写入 UTF-8 文本 |
list_dir | path: str = "." | 列出工作区内的目录 |
system_metrics | 无 | 报告磁盘、内存和占用资源最多的进程信息 |
工作区边界适用于文件工具,不会对 run_command 进行沙箱隔离;命令保留服务操作系统用户的全部权限。
要求
- Python 3.10+
- Linux 或 macOS
- 远程使用需要 Auth0 账户
- 供远程 MCP 客户端使用的 HTTPS 端点
安装
PyPI(推荐)
pip install universal-host-manager-mcp
接下来:运行 uhm-setup 以生成 .env ——请参阅下方的配置。
uv / pipx
无需污染项目环境:
uvx --from universal-host-manager-mcp uhm-setup
这会将程序安装到临时环境中,运行设置向导,并在当前目录下写入 .env。此后,以同样的方式运行服务本身:uvx universal-host-manager-mcp。
从源代码安装(用于开发)
git clone https://github.com/Abktya/universal-host-manager-mcp.git
cd universal-host-manager-mcp
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
接下来:运行 uhm-setup 以生成 .env ——请参阅下方的配置。
配置
最简单的方法是使用与服务一同安装的交互式设置向导:
uhm-setup
在你希望存放配置的目录中运行该向导。之后必须从同一目录启动服务,这样它才能找到 .env。
首次测试时,请选择 1 — 仅本地测试。按 Enter 接受端口 8765;端口提示要求输入数字,而不是 y 或 n。此模式:
- 默认创建单独的
workspace目录; - 仅监听
127.0.0.1,因此其他计算机无法连接; - 无需域名、隧道或 Auth0 帐户;
- 仅在本地测试期间启用无需身份验证的访问。
向导还提供 Cloudflare Tunnel、ngrok 静态域名和用于远程使用的现有 HTTPS URL。远程模式需要 Auth0;如果跳过 Auth0,向导不会写入具有误导性且无法使用的配置。它会验证域名和 URL,然后以 600 权限写入 .env,并在此之前将现有文件备份为 .env.bak。
如果已激活虚拟环境,请通过该环境安装并运行这两个命令:
python -m pip install universal-host-manager-mcp
uhm-setup
universal-host-manager-mcp
在 macOS/Linux 上,使用以下命令验证该命令是否属于当前激活的环境:
command -v uhm-setup
command -v universal-host-manager-mcp
python -m pip show universal-host-manager-mcp
前两个路径通常应指向 .venv/bin 内。如果虚拟环境处于激活状态,但路径指向 /opt/homebrew/bin,请使用 python -m pip install universal-host-manager-mcp 重新安装。
更喜欢手动配置?创建一个 .env 文件(如果从源代码安装,请复制 .env.example),并明确限制工作区:
HOST=127.0.0.1
PORT=8765
MCP_BASE_URL=https://mcp.example.com
MCP_WORKSPACE_DIR=/home/youruser/workspace
AUTH0_DOMAIN=your-tenant.eu.auth0.com
AUTH0_CLIENT_ID=replace_me
AUTH0_CLIENT_SECRET=replace_me
AUTH0_AUDIENCE=https://mcp.example.com/
切勿提交 .env。
Auth0 设置
本项目使用 FastMCP 的 Auth0Provider 固定客户端 OAuth 集成。
-
打开 auth0.com,创建账户,然后打开 Auth0 控制面板。
-
转到 Applications → APIs → Create API。
-
将公开 MCP URL 用作 Identifier(受众),例如
https://mcp.example.com/。将签名算法保留为 RS256。 -
转到 Applications → Applications → Create Application,输入名称,选择 Regular Web Application,然后创建应用程序。
-
将 Application Ownership 设置为 First-party。打开 Application > API Access,选择创建的 API,并启用 User-delegated Access。
-
在 Auth0 的 Integrate into your application 页面中,点击
.env代码块上方的 Copy。向导可以从剪贴板或粘贴的代码块中导入AUTH0_DOMAIN、AUTH0_CLIENT_ID和AUTH0_CLIENT_SECRET。如果 Auth0 显示MASKED,请在应用程序的 Settings 选项卡中显示并复制真实的 Client Secret;掩码后的密钥不会被接受。 -
按照向导提示,将 API 的 Identifier 复制到
AUTH0_AUDIENCE。此项特意单独设置,因为 Auth0 应用程序的.env代码块不包含 API 受众。 -
在 Auth0 应用程序的 Settings 中,按如下方式使用 MCP 服务的公开来源(不含
/mcp):Auth0 字段 值 Application Ownership First-party Application Type Regular Web Application Application Login URI 留空 Allowed Callback URLs https://mcp.example.com/auth/callbackAllowed Logout URLs https://mcp.example.comAllowed Web Origins https://mcp.example.comAllowed Origins (CORS) https://mcp.example.comAllow Cross-Origin Authentication 关闭/禁用 Cross-Origin Verification Fallback URL 留空 API Identifier / Audience https://mcp.example.com/Signing Algorithm RS256 Application > API Access 为创建的 API 启用 User-delegated Access MCP endpoint (entered in the AI client, not Auth0) https://mcp.example.com/mcp -
保存 Auth0 应用程序设置,然后运行向导。切勿分享 Client Secret,也不要将
.env提交到 Git。
上面的回调地址是 FastMCP 的固定上游回调。不要将 Claude、ChatGPT 或 Grok 的回调 URL 填入 Auth0:这些产品是下游 MCP 客户端,FastMCP 会在 MCP 客户端注册期间单独验证它们的重定向 URI。将每个产品连接到 https://mcp.example.com/mcp。
Auth0 的 Python 快速入门还会展示 AUTH0_SECRET、APP_BASE_URL、PORT 和示例 Flask 代码。它们属于 Auth0 独立示例 Web 应用,本 MCP 服务不会使用;导入复制的代码块时,向导会安全地忽略这些内容。
客户端说明:
- ChatGPT 支持通过 CIMD 和 DCR 注册 MCP OAuth 客户端。服务允许使用
https://chatgpt.com/connector_platform_oauth_redirect;请在 ChatGPT 开发者模式下添加公开的/mcp端点。 - Claude 自定义连接器接受公开的
/mcp端点,并会在连接时启动 OAuth。 - Grok 自定义连接器接受可公开访问的 MCP 服务 URL,并完成所需的身份验证。Grok 是否可用可能取决于当前的 Grok 套餐和工作区控制设置。
FastMCP 还通过 Auth0MCPProvider 支持 Auth0 原生 MCP/DCR 路径。本仓库目前使用手动管理的固定客户端 Auth0Provider 路径。
运行
universal-host-manager-mcp
(在已激活 .venv 的源码检出目录中运行,效果相同——通过 pip install -e . 安装控制台脚本。)
使用默认端口时,Streamable HTTP 端点为:
http://127.0.0.1:8765/mcp
如需在本地进行有意不使用 Auth0 的测试:
ALLOW_INSECURE_NO_AUTH=true universal-host-manager-mcp
请勿在可从公网访问的端点上使用不安全模式。
启动服务(远程模式还需启动隧道)后,请验证:
curl -i https://mcp.example.com/mcp
# Expected without a token: HTTP 401
curl -i https://mcp.example.com/.well-known/oauth-authorization-server
# Expected: HTTP 200
服务和隧道必须保持运行;关闭任一进程都会导致隧道端点不可用。
Cloudflare 隧道
安装 cloudflared,完成身份验证并创建命名隧道:
cloudflared tunnel login
cloudflared tunnel create universal-host-manager-mcp
cloudflared tunnel route dns universal-host-manager-mcp mcp.example.com
创建 ~/.cloudflared/config.yml:
tunnel: YOUR_TUNNEL_ID
credentials-file: /home/youruser/.cloudflared/YOUR_TUNNEL_ID.json
ingress:
- hostname: mcp.example.com
service: http://127.0.0.1:8765
- service: http_status:404
验证并运行:
cloudflared tunnel ingress validate
cloudflared tunnel run universal-host-manager-mcp
请保持 universal-host-manager-mcp 和 cloudflared 均在运行。关闭任一进程都会使公共端点离线。设置向导可以创建可执行的 uhm-enable-autostart.sh 安装程序。它会为这两个进程写入 Linux systemd-user 服务或 macOS LaunchAgents,并显示一条可运行的命令。
你的远程 MCP URL 为:
https://mcp.example.com/mcp
设置 MCP_BASE_URL=https://mcp.example.com;不要在 MCP_BASE_URL 中包含 /mcp。
没有域名?使用 ngrok 的免费静态域名
Auth0 OAuth 需要稳定的 HTTPS URL,但你无需拥有域名也能获得一个。与 ngrok 过去每次重启都会变化的随机 URL 或 Cloudflare 无需登录的快速隧道(存在同样问题)不同,ngrok 免费套餐为每个账户提供 一个永不变化的静态子域名,且无需付费。
-
在 ngrok.com 创建免费账户。在 macOS 上使用
brew install ngrok/ngrok/ngrok安装;在 Ubuntu 上使用sudo snap install ngrok。其他 Linux 发行版可参考 ngrok 官方下载说明。 -
打开 ngrok authtoken 页面,复制令牌并运行:
ngrok config add-authtoken YOUR_NGROK_TOKEN使用 authtoken,而不是域名 ID。切勿分享令牌;如果令牌泄露,请在控制面板中重置。
-
在 ngrok 控制面板中认领你的免费静态域名(Domains → New Domain)。你会获得类似
your-name.ngrok-free.dev的域名。 -
在包含
.env的目录中启动universal-host-manager-mcp。 -
在另一个终端中启动隧道:
ngrok http --url=your-name.ngrok-free.dev 8765**两个进程都必须保持运行。**关闭任一进程都会使公共端点离线。向导可以创建
uhm-enable-autostart.sh,为这两个进程安装 Linux systemd-user 服务或 macOS LaunchAgents。 -
在
.env中设置MCP_BASE_URL=https://your-name.ngrok-free.dev(保持HOST=127.0.0.1;ngrok 会转发到本地端口,而服务仅监听回环接口)。 -
在 Auth0 中,将应用程序的回调 URL 设置为
https://your-name.ngrok-free.dev/auth/callback;将 Web 来源和注销 URL 设置为https://your-name.ngrok-free.dev(参见 Auth0 设置)。
你的远程 MCP URL 为:
https://your-name.ngrok-free.dev/mcp
这适用于个人使用或少量客户端的场景。对于大规模生产流量,ngrok 免费套餐设有连接数/带宽限制——如果需求超出限额,请查看其定价页面,或切换到上文基于域名的 Cloudflare 隧道配置。
AWS EC2 部署
以下步骤将在 EC2 实例上部署服务,并安全地向远程 MCP 客户端开放访问。
1. 启动实例
- AMI:Ubuntu 24.04 LTS(以下命令适用于 Ubuntu/
apt;在 Amazon Linux 2023 上请改用sudo dnf install -y python3-pip) - 实例类型:对于典型的管理工作负载,
t3.micro/t3.small已足够 - 安全组:仅允许来自你自己 IP 的入站 SSH(22)。如果使用下方的 Cloudflare 隧道选项,则无需开放其他入站端口。
2. 安装服务
通过 SSH 登录实例,然后从 PyPI 安装:
sudo apt update && sudo apt install -y python3-pip python3-venv
python3 -m venv ~/uhm-venv
source ~/uhm-venv/bin/activate
pip install universal-host-manager-mcp
3. 配置
mkdir -p ~/workspace
cat > ~/.env << 'EOF'
HOST=127.0.0.1
PORT=8765
MCP_BASE_URL=https://mcp.example.com
MCP_WORKSPACE_DIR=/home/ubuntu/workspace
AUTH0_DOMAIN=your-tenant.eu.auth0.com
AUTH0_CLIENT_ID=replace_me
AUTH0_CLIENT_SECRET=replace_me
AUTH0_AUDIENCE=https://mcp.example.com/
EOF
chmod 600 ~/.env
保持 HOST=127.0.0.1。服务绝不能直接监听实例的公共接口——互联网访问完全由下文所述的隧道或负载均衡器处理,而不是通过开放实例自身的端口。
4. 网络:获取指向实例的 HTTPS URL
Auth0 OAuth 要求使用 HTTPS。选择一种方案:
选项 A — Cloudflare Tunnel(推荐,无需开放入站端口)
在 EC2 实例上执行上文 Cloudflare Tunnel 部分中的步骤。由于隧道是仅出站连接,你无需开放 SSH 之外的任何入站端口,也不需要弹性 IP;实例甚至可以位于 NAT 网关后的私有子网中。
没有自己的域名?请改为在 EC2 实例上执行上文 没有域名?使用 ngrok 的免费静态域名 中的步骤——同样仅建立出站连接、无需开放入站端口。
选项 B — 使用 ACM 证书的 Application Load Balancer
- 为你的域名申请 ACM 证书,并将其附加到 ALB
- 在 ALB 上创建 HTTPS(443)侦听器,并将流量转发到实例的
PORT - 实例上的安全组:仅允许来自 ALB 安全组的入站
PORT流量,绝不要允许来自0.0.0.0/0的流量 - 将 DNS 指向 ALB,并将
MCP_BASE_URL设置为该主机名
5. 作为 systemd 服务运行
复用随附的单元文件(参见下文的后台服务):
sudo cp examples/mcp-manager.service /etc/systemd/system/
# edit User=, WorkingDirectory=, EnvironmentFile= and ExecStart= to point at
# ~/uhm-venv/bin/universal-host-manager-mcp and ~/.env
sudo systemctl daemon-reload
sudo systemctl enable --now mcp-manager
sudo systemctl status mcp-manager --no-pager
6. 弹性 IP
这两种网络方案都不需要弹性 IP。无论实例的地址是什么,Cloudflare Tunnel 都会建立出站连接;ALB 则通过实例 ID 或私有 IP 注册目标,因此也不需要弹性 IP。只有在你的设置中有其他部分依赖此实例的固定公共 IP 时,才添加弹性 IP。
ChatGPT 和 Claude
将公共 Streamable HTTP URL 添加到客户端的 MCP/连接器配置中:
https://mcp.example.com/mcp
客户端打开授权流程时,请完成 Auth0 登录。设置界面和支持的连接器选项可能会发生变化,因此请参阅客户端当前的文档,不要使用过时的 SSE 说明。
多个客户端可以连接到同一个正在运行的 HTTP 服务。每个客户端都要独立进行身份验证;无需单独的服务进程或端口。
后台服务
Linux systemd
复制并编辑随附的单元文件:
sudo cp examples/mcp-manager.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now mcp-manager
sudo systemctl status mcp-manager --no-pager
此示例使用了 systemd 加固指令。请根据 MCP 服务实际需要的资源,调整 ReadWritePaths、ProtectHome、用户、路径和权限。
macOS launchd
编辑 examples/com.user.mcpmanager.plist 中的路径,然后:
cp examples/com.user.mcpmanager.plist ~/Library/LaunchAgents/
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.user.mcpmanager.plist
launchctl kickstart -k gui/$(id -u)/com.user.mcpmanager
macOS 远程访问就绪检查
对于远程 macOS 安装,uhm-setup 最后会询问:
Run macOS Remote Access Readiness Test now? [Y/n]
请在 Mac 旁边时运行此检查。仅选择你预计会远程使用的功能。向导可以测试工作区的读写访问权限,触发只读的 Google Chrome Automation 请求,并打开受保护文件、辅助功能和屏幕录制对应的 macOS“隐私与安全性”面板。打开应用或普通 URL 本身不需要额外的隐私权限。
macOS 有意要求用户批准 TCC 隐私提示。向导不会绕过或点击这些提示,而是显示确切的服务可执行文件路径,请你批准每项选定的权限,并输出就绪报告。如果在无人值守使用前未准备好某项权限,后续远程任务可能会卡在需要有人操作 Mac 的对话框上。
完全磁盘访问权限、自动化、辅助功能和类似授权可能与相关的可执行文件或安装路径绑定。重新创建虚拟环境、切换 Python 版本或在其他位置重新安装后,可能需要再次批准。更改隐私权限后,请重启 MCP LaunchAgent,再依赖其进行远程访问。
配置
| 变量 | 默认值 | 描述 |
|---|---|---|
HOST | 127.0.0.1 | 监听地址 |
PORT | 8765 | 监听端口 |
MCP_BASE_URL | 本地 URL | 公共 OAuth 基础 URL,不含 /mcp |
MCP_WORKSPACE_DIR | 用户主目录 | 文件工具和命令工作目录的边界 |
MAX_OUTPUT_CHARS | 64000 | 工具输出返回的最大字符数 |
DEFAULT_CMD_TIMEOUT | 300 | 默认命令超时时间(秒) |
MAX_CMD_TIMEOUT | 1800 | 接受的最大命令超时时间 |
MAX_READ_BYTES | 5000000 | read_file 可读取的最大文件大小 |
MAX_WRITE_BYTES | 5000000 | write_file 可写入的最大内容大小 |
LOG_LEVEL | INFO | Python 日志级别 |
LOG_COMMANDS | false | 记录 run_command 的命令文本(可能包含机密),而非仅记录超时时间 |
FASTMCP_CHECK_FOR_UPDATES | off(除非设置此项,否则会强制关闭) | FastMCP 启动时进行的 PyPI 更新检查 |
ALLOW_INSECURE_NO_AUTH | false | 明确绕过本地开发环境的身份验证 |
测试
pip install -e ".[dev]"
pytest tests/
每次推送时,CI 都会针对 fastmcp 2.13、3.x 和 4.x 运行测试套件(参见上方徽章),因为 @mcp.tool() 的返回类型在不同主版本之间有所变化;测试通过小型版本无关辅助函数(tests/conftest.py::call_tool)调用工具,以覆盖所有三个版本。
下载
使用 Git 克隆:
git clone https://github.com/Abktya/universal-host-manager-mcp.git
或者在 GitHub 上选择 Code → Download ZIP。
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。