# NJWL MCP 当前有效接入规范

版本：2026-10-21。本文是当前执行说明，旧版“仅登记、无发布”“大陆共用 ubuntu”“HTTP 维护尚未开放”等描述已停用。历史文件只用于追溯，不再作为操作指令。工具实际返回的身份、范围和审批状态优先于历史文字。

## 先确定自己连接的是什么

| 通道 | 身份来源 | 已接通的维护能力 |
| --- | --- | --- |
| 原生 `njwl_hk` | 香港 SSH 实际账号 | 所登记项目的文件读取、候选分片、审批发布、精确终端命令审批 |
| 原生 `njwl_cn` | 大陆 SSH 实际账号 | 与香港相同的工具，项目和授权独立 |
| HTTP `https://chenben.ai/mcp` | SSO 用户及 OAuth client_id | 资料库，以及香港 ERAZE 的既有受控文件交付；不能把原生 SSH 新能力当作 HTTP 已开放能力 |

浏览器说明地址为 https://chenben.ai/mcp/guide 。协议地址为无尾部斜杠的 https://chenben.ai/mcp 。旧 https://chenben.ai/knowledge/mcp 继续兼容，令牌资源与新地址隔离。

不要尝试向业务站点猜测 PUT、upload、deploy 接口。业务 API 只读不代表维护账号无权，也不代表存在维护通道。调用 `tools/list` 确认本次连接实际提供什么；只有资料工具时，不能声称已经接入服务器维护。

## 原生 MCP：身份与首次接入

1. 已配置本机直接使用 `njwl_hk`、`njwl_cn`，无需为新聊天注册新账号。本机共用 `gpt@mi14`。SSH 别名分别为 `njwl-hk`、`njwl-cn`；香港和大陆的 UID 不同，以实时查询为准。
2. `list_projects` 读取当前节点、实际账号、UID、项目 ID 与目录。禁止借用 ubuntu、其他设备账号或伪造 SUDO_USER。
3. 项目不存在：`request_project(project_id, project_name, roots, reason, request_id)`，提交准确目录，等待批准。不能擅自把父目录当项目范围。
4. 已有项目但无登记权限：`request_access`，随后 `access_status`。此权限仍只表示登记、提交留痕，不自动授予源码读取。
5. 普通维护者首次读写源码：`request_file_access(project_id, reason, request_id)`，等待管理员批准。当前节点已有管理员身份可按既有项目范围读取与暂存；发布和终端仍须单独审批。
6. 香港审批页 https://njwl.ai/sso/#mcp ，大陆页 https://njwl.ai/sso/#mcp-cn 。审批通知由“公司官网认证”机器人私聊陈本。大陆以大陆回执为准，不继承香港授权。

客户端名称和型号是声明，不是身份认证。原生 MCP 的真实权限依据是 SSH 账号、UID、维护者策略和节点；四小时发布另限该原生 MCP 连接会话。断开重连后重新申请，不能把客户端声明当作 OAuth client_id。

支持 stdio MCP 的客户端可参考以下配置；前提是该设备自己的 SSH 别名与账号已经登记可用。不同客户端的配置文件外层格式以其设置页为准，不复制别人的私钥。更改后重连并重新发现工具。

```json
{
  "mcpServers": {
    "njwl_hk": {
      "command": "ssh",
      "args": ["-T", "njwl-hk", "/usr/bin/python3", "-I", "/usr/local/lib/njwl-agent-changes/mcp-server.py"]
    },
    "njwl_cn": {
      "command": "ssh",
      "args": ["-T", "njwl-cn", "/usr/bin/python3", "-I", "/usr/local/lib/njwl-agent-changes/mcp-server.py"]
    }
  }
}
```

## 原生 MCP：完整文件维护流程

1. `list_project_files(project_id, path)` 列出目录。`path` 是服务器绝对路径。
2. `read_project_file(project_id, path, offset)` 分片读取文件。首次 offset=0；解码 `data_base64`，沿返回的 `next_offset` 继续至 eof。返回的 SHA256 是整个文件哈希。
3. 阅读项目 AGENTS.md；调用 `begin_task` 登记要变更的每个精确文件路径，保存 `registration_id`。不要只登记父目录后上传未登记文件。现有登记工具每任务最多30条路径；更多文件拆成明确批次。
4. 本地准备候选，计算每个文件的字节数和 SHA256。调用 `prepare_candidate(project_id, registration_id, manifest, request_id)`。

```json
{
  "/opt/example/web/app.js": {
    "size": 12345,
    "sha256": "替换为文件实际64位小写SHA256"
  }
}
```

5. 保存返回的 `operation_id`（nop- 开头）。常规额度为单文件200000字节、合计600000字节、4文件；超额返回 `awaiting_upload_approval` 和 `upload_approval_id`。先审批本批清单，才允许传文件正文。此项不授予发布或终端权限。
6. `upload_file_chunk(project_id, operation_id, path, offset, data_base64)` 顺序上传。每片原始字节最多65536；同偏移同内容可以重试，不能改内容。`operation_status` 的 progress 用于续传。
7. `finalize_candidate(project_id, operation_id)` 核对全部大小、哈希与线上基线，形成不可变候选及差异。此时没有修改线上文件。
8. `request_file_publish(project_id, operation_id)` 申请发布。在管理台查看计划、清单、哈希和差异预览；预览截断时应进一步核对完整候选。管理员选择“批准本次”或“批准四小时”。
9. 批准仍不是执行。调用 `execute_operation(project_id, operation_id)`，再用 `operation_status` 核对。`published` 表示已写文件并核对哈希，不代表浏览器验收、服务重启或数据库迁移完成。
10. 检查页面与功能；调用 `submit_task` 记录实际验证。它本身不执行发布；服务器发现本登记下已经成功的原生发布回执时，记录为“已发布”，否则仍为“已完成未发布”。交接同时附 operation_id 与实际发布结果。

新文件的父目录须已存在。上传支持二进制，不对所有项目擅自执行构建。单文件保护上限10MiB、单批50MiB；超出应拆分可审查交付。不得上传密钥、运行配置、数据库、隐藏目录、依赖缓存。路径穿越、软链接、硬链接、特殊文件被拒绝。

MCP 操作之间串行核对；直接 SSH 或业务进程不参与该锁。发布前后核对基线与哈希，外部并发写入仍须安排维护协调。失败时核对回滚结果与备份，不凭审批状态断言全部文件已恢复。

## 原生 MCP：终端命令审批

先 `begin_task` 登记真实涉及的源码路径，再调用 `request_terminal`：

```json
{
  "project_id": "填写实时返回的项目ID",
  "registration_id": "填写本次登记号",
  "argv": ["/usr/bin/node", "--check", "/opt/example/web/app.js"],
  "cwd": "/opt/example/web",
  "timeout": 30,
  "reason": "检查本次候选发布后的JavaScript语法",
  "request_id": "本次稳定且唯一的请求编号"
}
```

审批卡片和管理台列出完整 argv、工作目录、实际执行账号、写入范围、超时及计划哈希。命令参数直接按数组执行，默认不经过 shell；确需脚本时把解释器和完整脚本显式放入 argv 供审查。不得把秘密放进命令或申请理由，因为这些内容会进入审批与日志。

管理员批准此精确命令一次后，客户端调用 `execute_operation`。终端授权不继承四小时发布窗口。执行以当前 SSH 普通用户进行，禁 sudo 提权、外网和 Unix socket；系统只读，写入限登记路径，并受该 Linux 用户原有文件权限限制。超时最多60秒、内存512MiB、进程64、输出64KiB；达到时间或输出限制会停止任务。

已配置的服务启用使用下文 request_publish_and_activate。其他安装依赖、访问网络、重启系统服务或管理员操作仍需具体受控适配器和审批范围；普通终端不提供 root shell。文件发布由受控写入工具执行，不依赖终端提权。

`operation_status` 返回退出码和有界日志。`running` 只表示已经开始，不能当成功；进程或连接中断时，不换新编号重复执行，先核查原操作与服务状态。已批准但未执行的操作可在审批历史中撤销。撤销不回滚已发布文件，也不追溯撤销已启动命令。

## 四小时、通知与审计

原生发布窗口绑定当前 SSH 账号/UID/维护者、MCP 连接会话、节点、项目及当前项目目录。固定四小时，不滚动续期。窗口内新候选仍须登记、上传、完成候选、申请发布和执行；每次检查线上基线，完成后推送实际结果。管理员可撤销窗口，过期、撤销或连接变化后重新审批。窗口不授予终端、其他项目或另一节点权限。

原生上传超额按本批清单单独审批。HTTP ERAZE 仍保留既有“本批/四小时累计上传额度”及“本次/四小时发布”规则，不能把两套工具参数混用。

审批、候选、执行状态和哈希保存在服务器。候选和回滚备份不在公开网站。执行通知只发送结果摘要，不发送终端输出或文件正文。失败、超时和中断需如实记录；不得补造历史执行或把哈希一致当作真人验收。

## 发布并启用服务（原生 MCP v0.7）

重连后应发现18项工具；list_projects 的 service_activation 是本节点已安装的固定适配器。当前香港 ruku 支持 njwl-ruku.service 平滑重载，大陆尚无启用适配器。未列出的项目不能猜服务名或通过普通终端操作服务。

需要加载后端代码时，在 finalize_candidate 后使用 request_publish_and_activate(project_id, operation_id)，代替 request_file_publish。飞书和后台将明确显示“发布并启用”、服务名、方法、空闲检查和健康核验。批准本次或四小时后，客户端调用 execute_operation。审批本身不执行。

四小时范围除现有SSH身份、当前MCP会话、节点、项目外，还绑定相同启用适配器和服务配置哈希。旧“仅文件发布”窗口不包含启用；适配器或服务配置改变需重新批准。每次执行仍推送机器人结果，可在后台撤销未执行授权。

执行顺序：获取维护锁 → 检查排队/运行任务为空 → 核对候选和线上基线 → 备份并发布 → 平滑重载 → 核验新工作进程与启动源码哈希 → 解除维护锁。维护期间新业务请求返回503和Retry-After；已有任务忙碌时不发布、不重载，可稍后重试同一个operation_id。

成功必须同时满足 status=published 和 activation_result.status=active。仅status=published不代表启用成功。activation_result.status=failed表示文件已发布但启用核验失败，先查operation_status和服务状态，禁止换编号盲目重复发布/重载。running或activating表示结果尚未确认，不能当成功。只读版本核验不等于真实单据操作验收。

不能对已有纯文件审批追加启用权限。已发布但未启用的旧版本：重新登记当前准确文件，按当前内容建立候选并申请发布并启用；如已有登记则按实际状态衔接，不能覆盖别人进行中的登记。当前不会自动运行数据库迁移，不开放任意systemctl、sudo或Shell命令。

新增项目适配器由管理员配置固定服务、维护锁或排空机制、健康检查及回滚方案后开放；不可仅凭项目目录推导服务名。HTTP /mcp 暂不提供此原生工具，必须以当前tools/list为准。

## HTTP ERAZE：继续使用现有流程

正式资源地址：`https://chenben.ai/mcp`。从元数据发现授权端点，授权服务仍位于 `https://chenben.ai/knowledge`。使用 OAuth 授权码、S256 PKCE、DCR；authorize、token、refresh 的 resource 必须一致。切换资源地址需重新授权，不能用旧资源刷新令牌换取新资源令牌；尽量复用原 client_id，避免无意创建新设备审批。

本机回调使用已允许的 loopback 地址和实际监听端口，不能硬编码另一客户端旧端口。consent 提交必须遵守服务端 Origin 校验；不要删除该校验。access token 失效后按协议刷新，并持久化最新轮换的 refresh token；以返回的 expires_in 为准，不把短期令牌时长当成设备授权时长。

流程：list_projects → request_access（首次）→ access_status → begin_task → upload_candidate（常规文本）或 request_upload_capacity → upload_candidate_chunk → finalize_candidate → request_publish → task_status。仅操作返回的允许路径。

HTTP ERAZE 常规额度：单文件200000字节、合计600000字节、4文件；分片最多128KiB。超额先申报 manifest；可选仅本批或四小时累计额度。单文件上限10MiB、单批50MiB/256文件、四小时累计最大200MiB/1024文件。四小时累计额度首次分片预占本批规模，失败/取消不返还，重试不重复占用。

HTTP `request_publish` 在有效发布窗口内会直接发布，与原生“批准后再 execute_operation”不同。当前允许的 ERAZE 文件及图片路径，以该通道 list_projects 返回为准；图片只允许 audit-thumbs/ 直接子目录的 PNG/JPEG/WebP。当前 HTTP 通道不能直接使用上述原生终端工具，也没有自动获得大陆项目写权限。

## 新设备和交接给下一个 AI

必须查询实际运行设备厂商、型号、操作系统，记录稳定设备编号。Windows 可查询 Win32_ComputerSystem 的 Manufacturer/Model；Linux 查询可读 DMI 信息；失败写 unknown 和原因，不从IP或账号猜测。OAuth client_name 中写清软件、设备标签、型号和设备编号；模型单独上报，未知就写未上报。

交接时只交项目ID、节点、文件清单、registration_id、operation_id/HTTP task_id、审批编号、真实验证结果、未完成项和本指南地址。不要复制私钥、SSO cookie、token或其他设备身份。新AI先 list_projects 和 tools/list，再决定使用哪一条流程。

旧安装包、旧 README 中的入口猜测和权限描述已退出当前流程。本文没有放宽其他项目的 AGENTS.md、SSO身份水印、生产审查及用户权限要求。
