# host_server_mcp **Repository Path**: awol2010ex/host_server_mcp ## Basic Information - **Project Name**: host_server_mcp - **Description**: 本机文件访问与脚本执行的 **MCP Streamable HTTP (SSE)** 服务,供外部 agent 安全访问本机。 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-03 - **Last Updated**: 2026-10-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # host_server_mcp 本机文件访问与脚本执行的 **MCP Streamable HTTP (SSE)** 服务,供外部 agent 安全访问本机。 * **传输**:MCP Streamable HTTP,POST 响应支持 SSE 流式,GET 可开独立 SSE 流 * **鉴权**:动态 token(`tokens.json` 热加载 + 管理 API 实时签发/吊销),支持 `Authorization: Bearer` / `X-Access-Token` / `?token=` * **沙箱**:每个 token 限定可访问根目录,路径越权与 `..` / 软链接逃逸一律拒绝;配置与 token 库本身禁止被读 * **执行安全**:解释器白名单 + 危险命令黑名单 + 正则黑名单 + 交互式/阻塞命令黑名单 + 强制超时(默认 10s)+ 输出截断 + 进程树 kill ## 构建与运行 ```bash cargo build --release # 交叉编译 cargo install cargo-zigbuild cargo zigbuild --target x86_64-unknown-linux-gnu.2.17 --release # 首次运行会生成 config.toml 与引导令牌 ./target/release/host_server_mcp --config config.toml ``` 首次启动若 `tokens.json` 不存在,会生成一条 bootstrap 令牌(read+exec,打印在控制台),请妥善保存。 ## 工具清单 | 工具 | 作用域 | 说明 | |------|--------|------| | `whoami` | read | 查看当前 token 身份、作用域、根目录、限流/超时上限 | | `list_files` | read | 列举目录文件名(支持 glob + 递归 + 深度/跳过目录限制) | | `count_file_lines` | read | 获取文件行数、字节数、修改时间、是否二进制 | | `read_file_lines` | read | 按 1-based 起止行读取文件内容(建议先 count 再分块读) | | `exec_script` | exec | 在沙箱内执行脚本并返回 stdout/stderr/退出码(默认 10s 超时) | ## 客户端接入示例 ```bash # Streamable HTTP 端点 curl -N -X POST http://127.0.0.1:8765/mcp \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}' ``` 返回头里的 `Mcp-Session-Id` 要在后续请求(含 `notifications/initialized`)中回传。 ## IDE / 客户端安装(MCP 接入) 本服务暴露的是 **MCP Streamable HTTP** 端点(`/mcp`)。Trae、Cursor、VS Code、Claude Desktop 等现代 IDE 均原生支持该类型,只需填 URL + 鉴权头即可,无需本地 stdio 进程。 ### 1. 先拿到一个 token 服务首次启动会在控制台打印一条 bootstrap 令牌,也存在 `tokens.json` 里(字段 `token`)。也可用管理 API 签发一个: ```bash curl -X POST http://127.0.0.1:8765/admin/tokens \ -H "X-Admin-Token: " -H "Content-Type: application/json" \ -d '{"id":"trae-ide","name":"Trae 本机","scopes":["read","exec"],"roots":["D:/workspace"],"rate_limit_per_min":30,"max_timeout_secs":20}' ``` 记下返回的 `token` 值(形如 `hsk_xxx`)。 ### 2. 通用配置(Streamable HTTP) 各 IDE 的 MCP 配置文件都认下面的 `mcpServers` 结构,区别只在**文件放哪**: ```json { "mcpServers": { "host-server": { "type": "streamable-http", "url": "http://127.0.0.1:8765/mcp", "headers": { "Authorization": "Bearer <上面拿到的 token>" } } } } ``` > 端口按你 `config.toml` 的 `bind` 改;局域网/容器内访问把 `127.0.0.1` 换成宿主机可达 IP。 ### 3. 各 IDE 写入位置与入口 | IDE | 配置文件位置 | 操作入口 | |-----|--------------|----------| | **Trae** | 用户级 `~/.trae/mcp.json` 或项目 `.trae/mcp.json`;或直接在 GUI 添加 | 设置 → MCP → 「+ 添加服务器」→ 选「Streamable HTTP / 手动配置」→ 粘贴上面的 JSON(填 URL 与 Authorization 头) | | **Cursor** | 项目根 `.cursor/mcp.json`(或 设置 → MCP → Add) | 写入文件后 Cursor 自动加载;或在设置里「Add new global MCP server」粘贴 | | **VS Code(Copilot / Cline)** | 项目 `.vscode/mcp.json`(VS Code 原生);Cline 用其 MCP 设置面板 | 写入 `mcp.json` 后重启窗口,在 MCP 面板点「Start」;Cline 里选「Configure MCP Servers → 手动编辑」粘贴 | | **Claude Desktop** | `claude_desktop_config.json` 的 `mcpServers` | 同上 JSON;若你的版本较旧不支持 `type: streamable-http`,请升级到支持 Streamable HTTP 的版本(参见下方 fallback) | ### 4. 验证 在 IDE 的 MCP 面板里「host-server」应显示状态 **connected / running**,并可看到工具:`whoami`、`list_files`、`count_file_lines`、`read_file_lines`、`exec_script`。点开 `whoami` 发一次调用,能回显当前 token 的身份/作用域/根目录即说明链路通了。 ### 5. 注意事项 - **远程 / 容器 / WSL**:IDE 与服务的网络要互通。`bind = "0.0.0.0:8765"` 时务必把 `allowed_hosts` 加上实际访问域名/IP,或开发环境直接 `allow_any_host = true`(仅限可信网络)。 - **防火墙**:Windows 防火墙需放行该端口的入站(尤其是 `0.0.0.0` 监听时)。 - **HTTPS**:本服务是纯 HTTP。公网/不信任网络请在前面套一层反向代理(Nginx/Caddy)做 TLS,再把 IDE 的 URL 改成 `https://...`,代理转发到 `http://127.0.0.1:8765/mcp` 并透传 `Authorization` 头。 - **旧客户端 fallback**:若某客户端只支持老的 `sse` 类型(连接 `/sse`),本服务在 `GET /mcp` 也提供 SSE 流;可把配置里的 `type` 改成 `sse`、`url` 仍指向 `http://.../mcp`(鉴权头照传)。仍不可用则建议升级客户端到支持 Streamable HTTP 的版本。 ## 管理 API(需 `admin_token`) | 方法 | 路径 | 说明 | |------|------|------| | GET | `/admin/tokens` | 列出所有 token(明文脱敏) | | POST | `/admin/tokens` | 签发新 token(body 见下) | | POST | `/admin/tokens/{id}/revoke` | 吊销(可重新启用需改库) | | DELETE | `/admin/tokens/{id}` | 删除 | | GET | `/health` | 健康检查 | 签发请求体示例: ```json { "id": "agent-a", "name": "Cursor 本机", "scopes": ["read", "exec"], "roots": ["D:/workspace"], "expires_at": "2026-12-31T23:59:59Z", "rate_limit_per_min": 30, "max_timeout_secs": 20 } ``` > 管理接口鉴权:`Authorization: Bearer ` 或 `X-Admin-Token: `。 ## 配置(config.toml) 关键字段(完整默认见 `src/main.rs` 的 `DEFAULT_CONFIG`): * `bind`:监听地址,`127.0.0.1:8765` 仅本机,`0.0.0.0:8765` 监听所有网卡。**注意**:仅改 `bind` 不够——`allow_any_host=false` 时 rmcp 会用 `allowed_hosts` 校验请求 `Host` 头,外部机器(Host 为局域网 IP)会被 403 拒绝。局域网/外部访问还需 `allow_any_host = true` 或把对应 IP/主机名加入 `allowed_hosts`。 * `default_roots`:token 未单独指定 roots 时的沙箱根目录(务必收敛) * `admin_token`:管理口令(也可用环境变量 `HOST_MCP_ADMIN_TOKEN` 覆盖) * `allow_any_host`:局域网/反代场景可置 true 跳过 Host 校验 * `exec.default_timeout_secs`:默认超时(默认 10s) * `exec.max_timeout_secs`:客户端可请求的最大超时(全局上限) * `exec.allowed_interpreters`:解释器白名单 * `exec.blocked_commands` / `blocked_patterns` / `interactive_commands`:追加黑名单(内置清单见 `src/config.rs`) * `file.*`:单文件大小、单次读取行数/字节、列表上限等 ## 安全设计要点 1. **沙箱路径解析**:所有路径 canonicalize 后与 token 的 roots 比对,`..`、软链接逃逸、越权访问均被拒绝。 2. **敏感文件保护**:`config.toml` 与 `tokens.json` 即使位于 root 内也禁止被文件工具读取。 3. **危险命令**:内置破坏性删除/格式化、系统控制、进程/服务破坏、权限/账户/注册表、远程下载执行、权限提升等黑名单;并对整段脚本做正则匹配。 4. **交互式/阻塞命令**:`top`、`tail -f`、裸 REPL 等会一直挂起的命令直接拒绝;stdin 置空让其它交互命令也立即退出。 5. **强制超时**:默认 10s,客户端可上调但受 token 上限与全局 `max_timeout_secs` 双重钳制;超时后 kill 整个进程树(Windows `taskkill /T`,Unix kill 进程组)。 6. **输出截断**:stdout/stderr 各自上限,超出截断避免打爆上下文。 7. **动态 token**:`tokens.json` 每次请求检查 mtime,外部编辑 250ms 内自动热加载;管理 API 增删改立即生效。 8. **限流**:每 token 每分钟请求上限。 ## 代码地图(Code Map) ``` src/ ├── main.rs # 入口:解析参数、生成默认配置、加载 token 库、构建 axum 路由、 │ # 挂载 MCP StreamableHttpService、启动服务、优雅关闭 ├── config.rs # 配置加载(config.toml)+ 编译后的执行规则(ExecRules) │ # 内置危险命令/正则/交互式黑名单、沙箱根目录规范化、敏感文件列表 ├── auth.rs # 动态 token 鉴权:TokenStore(热加载/签发/吊销/删除/限流)、 │ # AuthIdentity、auth_middleware(Bearer/Header/Query 提取、admin 校验) ├── fs_util.rs # 沙箱文件系统:canonicalize、resolve_path(沙箱+敏感文件)、 │ # list_files、count_lines、read_lines ├── exec.rs # 脚本执行引擎:解释器白名单、规则检查、超时+进程树 kill、 │ # 输出截断、read_capped └── mcp.rs # MCP ServerHandler:5 个工具的请求解析、作用域校验、调用上述模块 # ServerInfo/instructions 构造 ``` 数据流: ``` HTTP 请求 → axum auth_middleware(提取 token → TokenStore.verify → 注入 AuthIdentity 到 extensions) → StreamableHttpService /mcp → mcp.rs 工具处理:从 Parts.extensions 取 AuthIdentity → require_scope(read/exec) → fs_util / exec(沙箱解析 + 业务) → CallToolResult(SSE 流式或 JSON)回传 ``` 依赖:`rmcp 3.2`(Streamable HTTP transport)、`axum`、`tokio`、`schemars`、`serde`/`toml`/`regex`/`uuid`/`glob`/`dunce`/`tracing`。