Skip to main content
Glama
README.md
# Draftly (wps-mcp)

**简体中文** | [English](README.en.md)

在 WPS Office(Mac)里跑一个真正能操作当前文档的 AI 聊天侧边栏,基于官方 JS 加载项对象模型 API +
[Claude Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk)。不是键盘/鼠标模拟,
是通过 MCP 工具直接调用 WPS 文字 / 表格 / 演示的对象模型(`Application.CreateTaskPane` 等)。

## 前置条件

- macOS,装了 WPS Office(Mac 版),至少完整打开过一次
- Node.js 20 及以上
- 已安装并登录 [Claude Code](https://claude.com/claude-code) CLI(`claude login`)——
  Draftly 不管理自己的 API Key,靠本机已登录的 Claude Code CLI 复用你的账号登录态。换一台机器
  / 换一个人用,都要先在那台机器上装好并登录 `claude` CLI。

## 安装

```bash
git clone <this-repo>
cd wps-mcp
bash scripts/install.sh
```

脚本是幂等的,改了代码之后重跑一次就是升级流程。它会:

1. `npm install` 装依赖
2. 生成本地共享密钥(`.bridge-token`,见下面"安全模型")
3. 把加载项文件复制到 WPS 的加载项目录
   (`~/Library/Containers/com.kingsoft.wpsoffice.mac/Data/.kingsoft/wps/jsaddons/wps-mcp_`)
4. 安装一个 `launchd` LaunchAgent,让桥接服务随登录自动启动、崩了自动重启

装完之后:

1. **完整重启一次 WPS Office**(首次安装、或者 `ribbon.xml` 有更新时必须重启——功能区按钮定义
   WPS 只在启动时读一次,不支持热更新;`taskpane.html`/`main.js` 的更新则会自动热更新,不用重启)
2. WPS 里找 "WPS-MCP" 功能区标签,点 "Draftly" 按钮打开侧边栏
3. 连不上就看日志:`tail -f ~/Library/Logs/wps-mcp.log`

卸载:

```bash
launchctl bootout gui/$(id -u)/com.wps-mcp.bridge
rm ~/Library/LaunchAgents/com.wps-mcp.bridge.plist
rm -rf ~/Library/Containers/com.kingsoft.wpsoffice.mac/Data/.kingsoft/wps/jsaddons/wps-mcp_
```

## 安全模型

桥接服务监听本机 `127.0.0.1:58892`,处理 WebSocket 和 HTTP 请求。所有会产生副作用的入口
(两条 WebSocket、`/tool`、`/mcp`)都要求 URL 上带 `?token=`,这个 token 是安装时随机生成、
落盘到项目根目录 `.bridge-token`(不进版本库)的本地共享密钥,同一份值会被烤进部署到 WPS 里的
`js/token.js`。没有这层校验,你电脑上开着的**任何一个网页**都能直接连上这个端口冒充加载项/面板,
用 MCP 工具改你正在编辑的文档——这不是理论风险,浏览器不会对 WebSocket 连接做同源限制。

## 架构速览

- `addin/` —— WPS JS 加载项:`ribbon.xml`(功能区)、`main.js`(对象模型桥接)、`taskpane.html`(聊天面板 UI)
- `server/bridge.js` —— 本地 WebSocket/HTTP 桥接,加载项与 MCP server 之间的枢纽
- `server/agent.js` —— 聊天面板的 `/agent` WS 处理,用 Claude Agent SDK 的 `query()` 驱动对话
- `server/tools.js` + `server/index.js` —— MCP server(stdio),把 `wps_word_*`/`wps_et_*`/`wps_wpp_*`
  工具调用转发到桥接层

`server/index.js` 会自动探测端口占用:如果 58892 已经被一个常驻实例占了,会转成轻量 stdio 中继,
把工具调用转发过去,而不是抢端口——这样 Agent SDK 自己 spawn 的 MCP server 子进程不会跟常驻服务冲突。

## 开发

```bash
npm test   # node --test,全仓库单测
```

严格 TDD:改行为之前先写一个会失败的测试。纯逻辑(session/host 处理、流式累加器等)都抽成了
DOM/WS 无关的模块,方便单测;WS/DOM 胶水代码保持薄,靠人读。

## 已知限制

- 目前只做了 macOS 版 WPS Office,且假设它安装在标准 Container 路径下
- 多用户场景没做——每个用户都要自己装好并登录 `claude` CLI,Draftly 不做统一鉴权/计费
- 品牌名 "Draftly" 是占位名,正式对外发布前建议再确认一下商标可用性

## License

[GPL-3.0](LICENSE)。基于本项目的修改版本,再分发时也必须以 GPL-3.0 开源。

TDQS

C2.9/5.0

Scored across 86 tools

Disambiguation4/5

工具通过 wps_word/wps_et/wps_wpp 前缀区分三大宿主,且动作+对象命名清晰,绝大多数工具边界明确。但存在少数易混点:wps_et_read_range 不传 cell 与 wps_et_get_selection 都会读取当前选区,另有一组 status/probe 诊断工具职责相近,可能造成误选。

Naming Consistency4/5

整体保持 wps_<host>_<verb>_<noun> 的 snake_case 模式,如 wps_word_get_revisions、wps_wpp_add_slide,规律性强。少数例外如 wps_status、wps_reload_addin 缺少宿主前缀,wps_word_new 用 new 而非 create,略有偏差。

Tool Count1/5

86 个工具远超典型 MCP 工具集规模,即使按 Word/ET/PPT 三个宿主拆分,每个子集仍超过 25 个,整体命名空间对 agent 造成很大选择与记忆负担;其中还包含多个 probe 诊断类工具,进一步膨胀数量。

Completeness3/5

Word 的覆盖很完整(新建、读写、表格、批注、修订、分节页码、目录等),ET 与 PPT 也覆盖大量核心操作。但存在明显缺口:没有 wps_et_new/wps_wpp_new 来新建表格和演示文稿,ET 缺少导出 PDF,PPT 明确不提供形状动画,且工作簿的工作表管理(增删/重命名)也缺失。