Skip to main content
Glama
README.md
# youdao-note-mcp

有道云笔记的 MCP 服务。本地以 **stdio** 暴露给 MCP 客户端(WorkBuddy / Claude Desktop 等),
内部桥接到有道官方的 **MCP over SSE** 端点。

## 为什么是桥接,而不是直接对接

调研结论(2026-09 实测):

| 路径 | 现状 |
| --- | --- |
| 有道云笔记 旧版 OpenAPI(OAuth 1.0/2.0 申请 ConsumerKey) | **已停止新增申请**,官网顶部明示,只能走邮件申请商务合作 |
| 官方 MCP 端点 `https://open.mail.163.com/api/ynote/mcp/sse` | ✅ 在役。无 Key 访问返回 `401 {"error":10002,"desc":"authentication failed"}` |
| API Key 来源 | https://mopen.163.com/ (网易智能开发者平台)→ 手机号登录 → API 管理 |

官方端点本身就是 MCP,所以本项目**不做协议转换**,只做三件有价值的事:

1. **本地 stdio 化** —— 客户端配 stdio 最稳,不必直连远端 SSE;
2. **运行时动态发现工具** —— 上游工具是运行时拉取后透传的,官方改版/加工具不用改代码;
3. **可观测与容错** —— 鉴权、连接、调用失败都收敛成结构化中文提示,而不是抛一个看不懂的异常。

## 架构

```
MCP 客户端
   │  stdio (JSON-RPC)
   ▼
youdao_note_mcp.server        ← 元工具 + 透传路由
   │  MCP over SSE (x-api-key)
   ▼
open.mail.163.com/api/ynote/mcp/sse   ← 有道官方
```

暴露两类工具:

- **上游透传工具**:运行时发现,名称/描述/入参 schema 与官方完全一致;
- **本地元工具**(永远可用,即使没配 Key):
  - `yn_status` —— 配置与连接体检,报错时先调它;
  - `yn_list_tools` —— 列出上游实际暴露的工具及其 schema;
  - `yn_refresh_tools` —— 刷新工具缓存。

## 安装

**方式一:uvx 直接跑(推荐,无需安装)**

```bash
uvx --from git+https://github.com/Lancenas/youdao-note-mcp.git youdao-note-mcp
```

**方式二:pip 安装**

```bash
pip install git+https://github.com/Lancenas/youdao-note-mcp.git
# 装完得到可执行命令 youdao-note-mcp
```

**方式三:本地开发**

```bash
git clone https://github.com/Lancenas/youdao-note-mcp.git
cd youdao-note-mcp
pip install -e .
```

## 获取 API Key

1. 打开 https://mopen.163.com/
2. 用**手机号**登录(前提:有道云笔记账号已绑定手机号)
3. 在「API 管理」中取 Key

> Key 只能访问该账号自己的笔记,无法跨账号。

## 配置到 MCP 客户端

在 MCP 配置文件的 `mcpServers` 下加(以 WorkBuddy 为例:
侧边栏 **插件** → 右上角 **MCP 服务器** → **配置 MCP**):

用 uvx(无需先安装):

```json
{
  "youdao-note": {
    "command": "uvx",
    "args": ["--from", "git+https://github.com/Lancenas/youdao-note-mcp.git", "youdao-note-mcp"],
    "env": {
      "YOUDAONOTE_API_KEY": "你的Key"
    }
  }
}
```

已 pip 安装过则用更简单的形式:

```json
{
  "youdao-note": {
    "command": "youdao-note-mcp",
    "env": {
      "YOUDAONOTE_API_KEY": "你的Key"
    }
  }
}
```

> ⚠️ Key 只填在**你自己本机**的配置里,不要提交到任何仓库。
> `.env` 已在 `.gitignore` 中排除,`.env.example` 只含占位符。

环境变量说明见 `.env.example`。

## 使用

配置好并重启客户端后,直接用自然语言即可,无需记工具名:

- 「列出我有道云笔记根目录的内容」
- 「搜索我笔记里关于 MCP 的内容」
- 「帮我新建一篇笔记,标题《xxx》,内容是……」

出问题先让 AI 调 `yn_status`,它会一次性给出 Key 是否配置、上游是否连上、
工具数量、最近一次错误。

## 自测

```bash
python tests/smoke_test.py
```

用内置的手写 mock SSE 上游跑端到端,覆盖三个场景:
**A** 有 Key 的完整链路(工具发现 + 透传调用)、**B** 无 Key 的降级、**C** 错误 Key 的鉴权失败。
当前 13 项检查全部通过。

## 真实环境验证(2026-09-21,已用真实 Key 打通)

- **工具发现**:官方暴露 **21 个工具**,全部被动态发现并透传,入参 schema(含 `required`、
  字段说明)完整保留 —— 这是选 low-level API 而非高层 `add_tool()` 才拿到的效果。
- **读**:`listNotes(parentId="0")` 正常返回;`getNoteTextContent` 读回内容与写入逐字一致。
- **写**:`createNote` → 读回校验 → `deleteNote` → `searchNotes` 复查剩余 0 条(不留垃圾)。

官方工具覆盖面:

| 类别 | 工具 |
| --- | --- |
| 笔记 CRUD | `createNote` `renameNote` `moveNote` `deleteNote` `createDir` `createAnyNote` |
| 内容读写 | `getNoteTextContent` `updateMarkdownNote` |
| 检索 | `listNotes` `searchNotes` |
| 收藏 | `getRecentFavoriteNotes` |
| 待办 | `listTodos` `createTodo` `updateTodo` `deleteTodo` `listTodoGroups` `createTodoGroup` `updateTodoGroup` `deleteTodoGroup` |
| 剪藏 | `clipWebPage` `clipperSaveWithImages` |

## 已知约束

- ⚠️ **`deleteNote` 是软删除,笔记会进有道云笔记回收站**。删除后用 `searchNotes` /
  `listNotes` 复查会是 0 条,但用户在客户端的「回收站」里仍然看得到。
  官方 MCP 未提供任何回收站相关工具(21 个工具里没有 trash / restore / purge),
  因此**无法通过 MCP 彻底清除**,需要用户在客户端手动清空回收站。
  写自动化清理脚本时要如实说明这一点,别承诺"删干净了"。
- **实体名带后缀**:`listNotes` 返回的笔记名自带 `.note`、`.md` 等后缀
  (如 `标题.note`),按标题匹配时要考虑这一点。
- **上游偶发连接失败**:实测出现过首次 `listNotes` 连接失败、第二次才成功的情况。
  本实现对可重试失败自动重连重试一次,已覆盖该场景;连续两次失败才会报错。
  另注:官方把鉴权失败也归在 `connect` 类型里(返回 401),看 `last_error` 里的
  `401 Unauthorized` 即可区分。

- **无常驻连接**:每个 tool call 都会重新走一次 SSE 握手。这是刻意的——
  mcp 2.x 的 runner 给每个请求套了 anyio cancel scope,跨请求持有 SSE 连接会触发
  `Attempted to exit a cancel scope that isn't the current tasks's current cancel scope`
  并让整个 server 挂掉。工具列表本身有缓存,不受影响。

## 托管到云开发 / 上架腾讯云 MCP 市场

本项目是 stdio 形态,云端市场需要 HTTP 形态。腾讯云开发(CloudBase)提供
`cloudbase-mcp-transformer`,可把 stdio 转成远程 Streamable HTTP 并托管。

`deploy/cloudbase/` 下已备好三个上架必需文件:

| 文件 | 作用 |
| --- | --- |
| `Dockerfile` | 安装本服务 + transformer,`CMD` 执行 stdio → Streamable HTTP 转换 |
| `mcp-meta.json` | 市场元数据。其中 `env_params` 声明 `YOUDAONOTE_API_KEY`,由使用者在连接时填自己的 Key(不是打包进镜像) |
| `DOC.md` | 市场展示文档(功能清单 + 环境变量说明) |

**已实测(2026-09-21,真实 Key)**:本地跑 transformer 转换后通过
`http://127.0.0.1:3000/messages` 连接,得到 **24 个工具(21 上游 + 3 元工具)**,
`yn_status` 返回 `api_key_configured: true` —— 即容器环境变量能被 stdio 子进程继承,
使用者填的 Key 可正常透传。

部署与上架(需腾讯云账号,无法自动化):

```bash
npm i -g @cloudbase/cli@latest
tcb login
cd deploy/cloudbase
tcb cloudrun deploy
```

> 注意:腾讯云 **MCP 广场**的上架申请目前仅面向企业级 MCP,个人开发者暂不开放;
> 云开发 MCP 市场无此限制。

## 许可

MIT © Lancenas