aily-local-file-mcp
by zerox-core
README.md
# feishu_mcp:个人本地开发工作台 MCP
> 部署前请先阅读 [SECURITY.md](SECURITY.md)。每台电脑必须使用自己的 `.env`、
> `MCP_AUTH_TOKEN`、授权目录、ngrok 地址和 Aily MCP 配置。不要共享或提交这些信息。
这是一个运行在你自己电脑上的 MCP(Model Context Protocol)服务。它让飞书 Aily
工作台在受控范围内访问本机项目:读写文件、查看 Git、运行构建与测试、检查 Android
或 Windows 开发环境,并安全导入二进制制品。
```text
你的 Aily 工作台 → HTTPS 隧道 → 你电脑上的 MCP → 你的项目目录与工具链
Bearer 鉴权 目录边界、审批、审计和限额
```
源代码可以通过 Git 分享;Token、ngrok authtoken、`.env`、日志、审批数据、构建输出和
个人路径不能分享。
## 10 分钟个人接入
### 1. 克隆并安装
```powershell
git clone https://github.com/zhuxice-ctrl/feishu_mcp.git
cd feishu_mcp
npm install
```
### 2. 创建自己的本地配置
复制 `.env.example` 为 `.env`,然后只填写自己的项目目录和随机生成的 Token。不要把
其他电脑的 `.env` 复制过来。
```env
# 只授权自己的项目根目录;可用逗号分隔多个目录
ALLOWED_DIRS=F:\MyProjects
# 自己生成的长随机值;不要提交、截图或发送给他人
MCP_AUTH_TOKEN=<your-own-random-token>
# 个人部署的默认安全模式
AUTH_MODE=pin
AUTH_PIN=<your-own-strong-pin>
AUTH_USER_HEADER=x-aily-user
# 公网可达的自有主机名(Cloudflare 命名隧道前置的域名,见下文)
PUBLIC_HOST=mcp.example.com
# 命令默认仍需确认
OWNER_COMMAND_POLICY=approval
```
`AUTH_MODE=none` 仅适合完全由你自己控制的个人入口;即使使用它,也应保留
`MCP_AUTH_TOKEN`。
### 3. 启动本地 MCP 与公网连接器
本地 MCP 与公网传输彼此解耦。Windows 推荐双击仓库根目录的:
```text
start-feishu-mcp.bat
```
启动器只负责本地服务:它会构建服务、检查本地健康状态并启动 `node dist/index.js`,
不会替你再启动任何隧道进程。它从 `.env` 读取 `PUBLIC_HOST` 并打印预期公网地址;
公网连接器是否健康由下面第 4 步的手动 Tunnel supervisor 或
`scripts\test-cloudflare-tunnel.ps1` 检查。你也可以手动运行:
```powershell
npm run build
npm start
```
本地健康检查:
```powershell
Invoke-RestMethod http://127.0.0.1:3000/health
```
正常时应返回 `status: ok`,并报告 42 个工具。若你使用 Clash Fake-IP,对公网
`/health` 的回访失败只说明反向探测受限;本地服务和连接器仍可正常工作。
### 4. 先选择公网传输
在配置隧道前,先确定两件事:你使用 **Cloudflare** 还是 **ngrok**,以及是否拥有一个可
专用于此 MCP 的独立域名。
| 选择 | 是否有独立 MCP 域名 | 建议 |
| --- | --- | --- |
| Cloudflare | 有 | 使用 Cloudflare 命名隧道,并分配 `mcp.<你的域名>` 等专用子域名。这是主路径。 |
| Cloudflare | 没有 | 不要默认把现有业务域名暴露给本 MCP;建议先注册专用域名,或暂时使用 ngrok。 |
| ngrok | 不限 | 使用自己的 ngrok 账号和 HTTPS 地址;适合临时接入、没有独立域名时使用,或作为 Cloudflare 的回滚方案。 |
**同一时间只能启用一个同用途的 Aily MCP 条目。** 两个条目同时提供同一批工具会使
工具路由产生歧义。切换时请遵循:先新建目标条目,验证 `ping` 与工具发现成功,最后再
关闭旧条目。
### 5. 公网传输(默认 Cloudflare 命名隧道,回滚备用 ngrok)
**主路径:Cloudflare 命名隧道 + 自有主机名。** 在 Cloudflare 控制台完成以下一次性配置
(不要在仓库或截图里放凭据、tunnel UUID 或证书 JSON):
1. 安装 cloudflared,并在你的终端完成 `cloudflared tunnel login`。
2. 创建命名隧道:`cloudflared tunnel create feishu-mcp`(记下打印的 UUID)。
3. 绑定主机名:`cloudflared tunnel route dns feishu-mcp mcp.example.com`(该子域需在
Cloudflare DNS 中被代理)。
4. 在 `%USERPROFILE%\.cloudflared\config.yml` 写外部连接配置,`ingress` 指向
`http://127.0.0.1:3000`(以 `.env` 的 `PORT` 为准),并为证书 JSON 和 config.yml
收紧 NTFS ACL。
5. 保持手动启动:运行 `scripts\start-cf-mcp.ps1`,它会在当前会话启动 supervisor;
不安装 Windows 服务,也不创建开机启动项。
把 `PUBLIC_HOST` 设置为这个自有主机名并重启本地启动器。随后运行有界健康验证(区分
本地与公网失败,退出码非零即失败):
```powershell
.\scripts\test-cloudflare-tunnel.ps1 -PublicHost mcp.example.com -Port 3000 -MetricsPort 20241 -TunnelName feishu-mcp
```
手动会话状态与停止命令:
```powershell
.\scripts\tunnel-supervisor.ps1 -Action Status
.\scripts\stop-cf-mcp.ps1
```
完整恢复说明见 [`docs/MANUAL_CLOUDFLARE_TUNNEL_RECOVERY.md`](docs/MANUAL_CLOUDFLARE_TUNNEL_RECOVERY.md)。
**回滚备用:ngrok。** 观察期内如公网中断超过 5 分钟且原因未明,可按
[CLOUDFLARE_TUNNEL_MIGRATION.md](docs/CLOUDFLARE_TUNNEL_MIGRATION.md) 一键回滚:
先运行 `scripts\stop-cf-mcp.ps1`,再在 `.env` 恢复 `NGROK_DOMAIN` 与 `NGROK_AUTHTOKEN`,
运行 `.\scripts\start-ngrok.ps1`,并把 Aily endpoint 改回旧 ngrok 地址。不要把
`mcp.example.com` 当作凭据,也不要把它复制给其他使用者。
### 测试环境(与正式环境隔离)
正式服务只使用 `.env`、`127.0.0.1:3000` 和 `mcp.zxc66.asia`。测试服务使用另一份
`.env.test`、`127.0.0.1:3001` 和 `mcp-test.zxc66.asia`,其审批数据、任务、日志、
工作区目录及 Cloudflare 凭据都必须独立。测试脚本不会读取、修改、重启或停止正式 MCP。
```powershell
# 1. 复制 .env.test.example 为 .env.test,并只填写测试值
.\scripts\start-test-mcp.ps1
# 2. 如需公网测试,再使用独立的测试 Cloudflare 配置
.\scripts\start-test-cloudflared.ps1 -ConfigPath C:\test-cloudflared\config.yml
```
完成测试后停止测试进程即可。合并或发布代码是另一项独立操作;生产仍保持 `.env` 和
3000 端口,除非你明确启动正式服务。
### 6. 在 Aily 添加 MCP
在 Aily 中添加企业自定义 MCP,Endpoint 类型选 **Streamable HTTP**。使用 Cloudflare
时将 `<你的公网主机名>` 替换为 `PUBLIC_HOST`;使用 ngrok 时替换为自己的 ngrok 域名:
```text
MCP endpoint: https://<你的公网主机名>/mcp
Authorization: Bearer <your-own-MCP_AUTH_TOKEN>
x-aily-user: <your-own-OWNER_USER_ID>
```
`Authorization` 和 `x-aily-user` 必须添加在**请求头**中。对于这个仅自己可用的个人
MCP,`Authorization` 应使用**固定值**,其参数值为 `Bearer <your-own-MCP_AUTH_TOKEN>`,
这样 Aily 才能在注册阶段发现完整工具清单。不要把真实 Token 放在展示名称、描述、图片
或普通对话中;`x-aily-user` 应固定为你的 owner 身份。
保存新 MCP 后,先重新打开 Aily 对话并调用 `ping` 或让它枚举工具;确认成功后,再关闭
旧的同用途 MCP 条目。出现 401 时,先核对 Token 是否与本机 `.env` 一致,以及是否包含
`Bearer ` 前缀。
## Android 与 Windows 本地开发环境
项目内提供 [个人 MCP 接入教学 Skill](skills/personal-mcp-onboarding/SKILL.md)。它适合
让 Aily 或 Codex 先检查你的设备,再给出**手动**安装与接入步骤。
它会按项目需要检查:
- Node.js、npm、Git、本地 MCP、ngrok;
- Android Studio、Android SDK、JDK、Gradle wrapper、`adb`;
- Visual Studio Build Tools、MSVC、Windows SDK、CMake。
它不会替你注册 ngrok、安装软件、填写 Token、修改 `.env` 或改变系统环境。示例提问:
```text
检查我的 Windows 电脑是否能运行这个 MCP,并给我手动接入 Aily 的步骤。
检查这个 Android 项目缺少哪些 SDK、JDK 和 adb 配置,只给我手动修复方法。
检查这个 Windows 原生项目需要的 MSVC、Windows SDK 和 CMake 环境。
```
## 能力概览:42 个工具
工具清单由服务在 `tools/list` 中实际返回;Aily 的文字总结可能合并或漏列工具,
应以该响应和 `/health` 为准。
| 分组 | 工具 |
|---|---|
| 连通与授权 | `ping`、`auth`、`list_allowed_directories` |
| 文件与目录 | `read_file`、`write_file`、`edit_file`、`create_directory`、`list_directory`、`move_file`、`search_files`、`search_content`、`get_file_info`、`compare_files`、`apply_patch` |
| 命令与 Git | `execute_command`、`git_status`、`git_diff` |
| 结构化 Git | `git_workflow`(固定 Git 工作流 action) |
| 网络与任务 | `web_fetch`、`todo_write`、`todo_read`、`ask_user` |
| 开发环境 | `get_development_task`、`list_development_tasks`、`read_development_task_logs`、`cancel_development_task`、`inspect_development_environment`、`plan_environment_changes`、`apply_environment_plan`、`android_development`、`windows_development`、`node_development`、`python_development`、`java_development`、`manage_development_project` |
| 本地工作流 | `list_local_workspaces`(列出受保护目录中的工作空间和配方)、`run_local_workflow`(异步执行已登记的受控验证配方) |
| 本地开发服务 | `local_dev_server`(仅 owner;启动、查询日志或停止 catalog 声明的本机/LAN 开发服务;不接受任意命令,也不会自动通过 Cloudflare 公开) |
| 工作区路由 | `workspace_context`(owner 专用:选择/恢复受信任工作区,返回确定性的 `route.recommended`:Android 走 `android_development`、固定 Node 校验走 `run_local_workflow`,并提供 `error.nextAction`) |
| 二进制制品 | `manage_binary_artifact` |
| 大文本传输 | `manage_text_transfer` |
| Android 验证 | `staging_android_verify`(按应用 Profile 执行受控的 SSH/ADB staging 验证) |
`manage_binary_artifact` 用于验证、分块接收、存储和原子落盘 PNG、ZIP 等二进制制品;
`manage_text_transfer` 用于超过单次 MCP 请求限制的 UTF-8 源码:先 `begin`(目标路径、字节数、SHA-256),再按返回的 48 KiB 上限调用 `append`,可用 `inspect` 查询断点,最后 `commit` 完成校验后的原子替换。小文件继续使用 `edit_file`;该工具只传输文本,绝不执行内容。
它不提供任意二进制执行或解压能力。二进制构建产物通常应放在制品存储或 Release,
而不是提交到 Git。
`python_development` 用于受控的 Python 版本检查、脚本运行和 pytest 验证。它会优先选择工作目录下的 `.venv`,再回退到系统 launcher,不接受任意 shell 字符串或原始 pytest flags。
## 构建与测试命令
结构化开发工具遵循 context-first 流程:
`workspace_context bootstrap/select` → 阅读声明的指令文件 →
`workspace_context mark_instructions_read` → 使用 `git_workflow`、
`java_development`、`node_development` 或 `python_development`。Node 工具还提供固定的
`npm_ci`、`npm_test`、`npm_build`、`npm_lint`、`npm_typecheck` action;Python 工具提供固定的
`python_version`、`script_run`、`pytest_run` action;
调用方不得用任意 shell 命令替代这些结构化 action。
`execute_command` 是本地 MCP 的通用命令工具;Aily 可能不会把任意 Shell 执行能力
交给智能体。Node/PNPM 验证应优先使用结构化的 `node_development`:它要求已授权的
`workdir`,且只允许 `pnpm_version`、`test_run`、`build`、`typecheck` 四个 action。
Windows 上会以完全固定的 `pnpm.cmd` 命令片段启动包管理器;调用方仍不能传入任意命令或
参数。两类工具都受目录边界、受保护
内部目录、审批、超时、输出上限、取消、并发限制和审计约束。
在 Aily 中可这样请求:
```text
请调用 node_development,action 为 typecheck,workdir 为已授权 Node 项目目录。
如果要做 Python 校验,请调用 python_development,action 为 pytest_run,workdir 为已授权 Python 项目目录。
如需审批,请在当前窗口展示审批卡;不要改用任意 shell 命令。
```
默认策略:
```env
OWNER_COMMAND_POLICY=approval
```
个人设备所有者确实需要让构建和测试直通时,才可以显式配置:
```env
OWNER_USER_ID=<your-own-owner-id>
OWNER_COMMAND_POLICY=direct
```
`direct` 仅跳过该 Owner 的普通单次命令审批;它不会放宽目录权限、内部数据保护、超时、
输出限制、取消、审计或并发限制。非 Owner 仍遵循普通审批流程。包安装和构建脚本可能
联网或产生外部副作用,不能视为可由回收站完全回滚的操作。
## 安全模型
- **传输鉴权**:`MCP_AUTH_TOKEN` 保护公网 MCP 入口,错误或缺失会返回 401。
- **工具授权**:支持 `pin`、`header` 和 `none`;公网 `header` 模式只能放在可信网关后。
- **目录白名单**:仅允许 `ALLOWED_DIRS` 中的项目目录,解析后防止路径穿越和符号链接逃逸。
- **操作确认**:文件写入、风险命令、敏感路径与首次网络来源按策略要求确认。
- **审计与限流**:操作写入审计日志,Token 仅以哈希形式记录;并发、频率、大小和时间均有上限。
- **软删除**:覆盖或移动文件会先进入项目的 `.trash/`;它不保证撤销网络、包管理器或外部系统副作用。
永远不要以管理员身份运行 MCP。不要把整个磁盘授权给日常 Aily 对话;优先只授权一个
项目根目录。
## 常见问题
### Aily 显示 401 或没有工具
检查顺序:本地 `/health` 是否正常、ngrok 是否在线、Aily endpoint 是否为 `/mcp`、
`Authorization` 是否为固定请求头且值为 `Bearer <your token>`。Aily 的描述栏不会
代替真实请求头值。
### Aily 的文字回答只列出一部分工具
服务的 `/health` 与 `tools/list` 当前应返回 42 个工具。Aily 可能因平台安全策略只把
其中一部分交给智能体;如果没有 `execute_command`,请使用 `node_development` 完成四个
受限的 PNPM 操作;如果要验证 Python 脚本或 pytest,请使用 `python_development`,而不要
要求智能体改用任意 Shell。
### 启动器报告公网 health 超时
在 Clash Fake-IP 等本机 DNS 场景可能发生。确认 `http://127.0.0.1:3000/health` 和 ngrok
隧道状态;启动器不会因为该公网回访警告停止健康的本地服务。
### Android 或 Windows 构建环境缺失
使用 [个人 MCP 接入教学 Skill](skills/personal-mcp-onboarding/SKILL.md) 先检测,再按
Android Studio SDK Manager 或 Visual Studio Installer 的手动步骤安装相应组件。
## 项目结构
```text
feishu_mcp/
├── src/ # MCP 服务、鉴权、工具和安全边界
├── scripts/ # Windows 启动器与辅助脚本
├── skills/
│ └── personal-mcp-onboarding/ # 个人电脑接入教学 Skill
├── docs/ # 设计、计划与接入参考
├── test/ # Node 测试
├── .env.example # 本地配置模板,不含真实密钥
├── start-feishu-mcp.bat # Windows 启动入口
└── SECURITY.md # 安全部署要求
```
## 开发与验证
```powershell
npm install
npm run build
npm run typecheck
```
运行某一组测试时使用 Node 内置测试运行器,例如:
```powershell
node --test test/launcher.test.mjs
```
完整配置项以 `.env.example` 和 `src/config.ts` 为准;详细 Aily 接入说明见
[docs/aily-integration-guide.md](docs/aily-integration-guide.md)。
## License
MIT
This server cannot be deployed
Maintenance
ActivityActive
ResponsivenessNo issues