内容
# MCP-RTM
> 模型上下文协议服务器,用于集成Remember The Milk
一个模型上下文协议(MCP)服务器,用于连接AI助手(如Claude)到您的Remember The Milk任务,实现通过任何MCP兼容客户端进行自然语言任务管理。
## 这是什么?
该项目通过[模型上下文协议](https://modelcontextprotocol.io/)在AI助手和Remember The Milk之间提供了一个桥梁。设置完成后,您可以:
- 请求Claude使用自然语言向您的RTM列表添加任务
- 通过描述任务完成任务
- 使用筛选器查询任务
- 设置优先级、截止日期、标签,并通过对话管理任务列表
服务器处理RTM身份验证、时间线管理,并通过标准化的MCP工具和资源公开您的任务数据。
## 功能
- 🔐 **OAuth身份验证** - 通过网页门户安全连接RTM账户
- 🛠️ **30+ MCP工具** - 完整的RTM API覆盖(任务、列表、标签、笔记、位置、设置)
- 📚 **MCP资源** - 只读访问列表、标签和位置数据
- 📝 **MCP提示** - 常见工作流的预配置模板
- 🔔 **Webhook支持** - 来自RTM的实时更新(可选)
- 🔄 **每用户速率限制** - 按照RTM最佳实践自动限制
- 🐳 **Docker就绪** - 轻松部署到Railway或任何容器平台
- ⚡ **Turbo构建系统** - 适用于单体仓库开发的快速缓存构建
## 先决条件
- Node.js 20+
- pnpm 9+
- Docker(用于本地开发)
- Remember The Milk账户
- [RTM API密钥](https://www.rememberthemilk.com/services/api/)(免费)
## 快速入门
### 1. 克隆和安装
```bash
git clone https://github.com/allen-n/rtm-mcp.git
cd rtm-mcp
pnpm install
```
### 2. 配置环境
```bash
cp .env.example .env
```
编辑 `.env` 并添加您的凭证:
```bash
# 从 https://www.rememberthemilk.com/services/api/ 获取这些信息
RTM_API_KEY=您的_api_key_在此
RTM_SHARED_SECRET=您的_shared_secret_在此
# 为BetterAuth生成一个随机密钥
BETTER_AUTH_SECRET=$(openssl rand -hex 32)
# 为Webhook验证生成一个随机密钥(可选)
RTM_WEBHOOK_SECRET=$(openssl rand -hex 32)
# 本地Postgres默认值(更改如果您已经运行Postgres)
POSTGRES_USER=rtm
POSTGRES_PASSWORD=rtm
POSTGRES_DB=rtmdb
POSTGRES_PORT=5433
POSTGRES_SSL=false
```
`.env.example`中的其余默认值(`NEXT_PUBLIC_API_BASE`、`APP_BASE_URL`等)已经为本地开发设置好。当使用Docker Compose运行时,`API_BASE_INTERNAL`将在`docker-compose.yml`中自动设置。
### 3. 使用Docker Compose启动(推荐)
本地运行最简单的方法是使用Docker Compose,它镜像生产设置:
```bash
# 启动所有服务(postgres、migrations、mcp server、web portal)
docker compose up --build
# 或启动特定服务
docker compose up -d postgres # 仅数据库
docker compose up --build mcp # MCP服务器 + 依赖项
docker compose up --build web # 网页门户 + 依赖项
```
这将:
- 在端口5432启动PostgreSQL
- 自动运行数据库迁移
- 在`http://localhost:8787`启动MCP服务器
- 在`http://localhost:3000`启动网页门户
### 4. 替代:本地开发
如果您更喜欢本地运行服务(更快热重载):
```bash
# 只需使用Docker启动Postgres
docker compose up -d postgres
# 运行迁移
pnpm migrate
# 使用Turbo启动所有服务(并行、缓存构建)
pnpm dev
# 或启动个别服务
pnpm dev:mcp # 仅MCP服务器
pnpm dev:web # 仅网页门户
```
MCP服务器运行在`http://localhost:8787`
网页门户运行在`http://localhost:3000`
### 5. 连接您的RTM账户
1. 访问`http://localhost:3000`(网页门户)
2. 使用邮箱/密码创建账户
3. 点击“连接RTM”以链接您的Remember The Milk账户
4. 在RTM上授权应用程序
5. 连接成功后,您将看到成功消息!
### 6. 配置您的MCP客户端(共享JSON)
连接RTM并在仪表盘设置中创建API密钥后,请为主要MCP客户端使用此配置:
- Claude Desktop
- Cursor
- Cline / Roo Code / Windsurf
- Continue
```json
{
"mcpServers": {
"rtm": {
"url": "http://localhost:8787/mcp/json",
"headers": {
"x-api-key": "您的_API密钥"
}
}
}
}
```
在生产环境中,请将`http://localhost:8787`替换为您的部署API基址(例如`https://api.yourdomain.com`)。
### 7. 使用MCP Inspector测试
```bash
npx @modelcontextprotocol/inspector http://localhost:8787/mcp
```
## 项目结构
```
mcp-rtm/
├── apps/
│ ├── mcp-server/ # MCP服务器(Hono + MCP SDK)
│ │ ├── src/
│ │ │ ├── mcp.ts # MCP工具/资源定义
│ │ │ ├── http.ts # HTTP服务器设置
│ │ │ └── routes/ # 身份验证和Webhook处理程序
│ │ ├── Dockerfile # 容器构建
│ │ └── railway.json # Railway部署配置
│ └── web/ # Next.js网页门户
│ ├── Dockerfile
│ └── railway.json
├── packages/
│ ├── auth/ # BetterAuth配置
│ ├── db/ # Kysely + 迁移
│ │ └── Dockerfile # 迁移运行器
│ └── rtm-client/ # RTM API客户端,带有速率限制
├── docker-compose.yml # 本地开发设置
└── turbo.json # Turbo构建配置
```
## 身份验证
该项目使用[BetterAuth](https://www.better-auth.com/)进行身份验证:
- **邮箱/密码**:主要身份验证方法。用户通过网页门户使用邮箱和密码注册。
- **会话管理**:会话持续7天,自动续期。
- **API密钥**:用于编程MCP访问(适用于与Claude Desktop或其他MCP客户端集成)。
网页门户处理用户注册和RTM OAuth连接。连接后,用户可以使用其API密钥与MCP服务器一起使用。
### OAuth提供商(可选)
社交登录(GitHub,Google)受支持,但默认情况下禁用。要启用,请取消注释`packages/auth/src/server.ts`中的`socialProviders`部分并设置所需的环境变量。
## 可用的MCP工具
连接后,以下工具可用于AI助手:
### 任务管理
| 工具 | 描述 |
| ----------------- | ----------------------------------------------------- |
| `get_tasks` | 使用RTM筛选器语法检索任务 |
| `add_task` | 创建任务(支持智能添加:`!1 ^tomorrow #tag`) |
| `complete_task` | 标记任务完成 |
| `uncomplete_task` | 标记已完成的任务为未完成 |
| `delete_task` | 永久删除任务 |
| `rename_task` | 更改任务名称 |
| `move_task` | 在列表之间移动任务 |
| `postpone_task` | 将截止日期推迟一天 |
### 任务属性
| 工具 | 描述 |
| ---------------- | ----------------------------------------------- |
| `set_priority` | 设置优先级(1=最高,2,3,N=无) |
| `set_due_date` | 设置/清除截止日期(支持自然语言) |
| `set_start_date` | 设置/清除开始日期 |
| `set_recurrence` | 设置重复模式(例如,“每周”) |
| `set_estimate` | 设置时间估计(例如,“30分钟”) |
| `set_url` | 附加URL到任务 |
| `set_location` | 设置任务位置 |
### 标签
| 工具 | 描述 |
| ------------- | ---------------------------- |
| `get_tags` | 获取您账户中的所有标签 |
| `add_tags` | 向任务添加标签 |
| `remove_tags` | 从任务中删除标签 |
| `set_tags` | 替换任务上的所有标签 |
### 笔记
| 工具 | 描述 |
| ------------- | --------------------- |
| `add_note` | 向任务添加笔记 |
| `edit_note` | 编辑现有笔记 |
| `delete_note` | 删除笔记 |
### 列表
| 工具 | 描述 |
| -------------- | --------------------------------- |
| `get_lists` | 获取所有列表 |
| `create_list` | 创建新列表(或智能列表) |
| `rename_list` | 重命名列表 |
| `archive_list` | 存档列表 |
| `delete_list` | 永久删除列表 |
### 其他
| 工具 | 描述 |
| --------------- | ----------------------- |
| `get_locations` | 获取所有保存的位置 |
| `get_settings` | 获取用户的RTM设置 |
## HTTP端点
### MCP协议
- `POST /mcp` - 流式HTTP MCP端点(需要`Accept: application/json, text/event-stream`)
- `POST /mcp/json` - 仅限JSON的兼容性端点,供不支持SSE的客户端使用
### REST API & 文档
- `GET /api/v1/tools` - 列出所有工具及其架构
- `POST /api/v1/invoke` - 按名称调用工具
- `GET /api/v1/skills.md` - AI代理的详细使用指南
- `GET /llms.txt` - 快速MCP使用指南
- `GET /` 且 `Accept: text/markdown`(或`text/md`)- 在网页域上返回`llms.txt`
- `GET /api/v1/openapi.json` - REST API的OpenAPI规范
- `GET /api/v1/docs` - 交互式Swagger UI
### 健康检查 & 身份验证
- `GET /health` - 健康检查端点
- `GET /rtm/start` - 启动RTM OAuth流程
- `GET /rtm/callback` - RTM OAuth回调
## 开发
### 构建系统
该项目使用[Turbo](https://turbo.build/)进行快速缓存构建:
```bash
# 构建所有内容(尊重依赖顺序)
pnpm build
# 构建特定应用
pnpm --filter @apps/mcp-server build
# 并行运行所有开发服务器
pnpm dev
```
### 运行测试
```bash
# 运行所有测试
pnpm test
# 监视模式
pnpm test:watch
# 测试特定包
pnpm --filter @packages/rtm-client test
```
### 数据库迁移
```bash
# 运行待处理迁移
pnpm migrate
# 在架构更改后刷新生成的Kysely类型
pnpm --filter @packages/db generate
# 创建新迁移
# 在packages/db/src/migrations/中添加新文件,格式为<UTC_Timestamp>_description.ts
```
### Docker Compose服务
| 服务 | 描述 | 端口 |
| ------------ | -------------------------------- | ---- |
| `postgres` | PostgreSQL数据库 | 5432 |
| `migrations` | 运行数据库迁移(退出后) | - |
| `mcp` | MCP服务器 | 8787 |
| `web` | Next.js网页门户 | 3000 |
```bash
# 重建并重启特定服务
docker compose up --build mcp
# 查看日志
docker compose logs -f mcp
# 重置数据库(删除卷)
docker compose down -v
docker compose up -d postgres
```
## 部署(Railway)
该项目设计用于[Railway](https://railway.app/)部署,包含三个服务:
### 服务配置
| 服务 | 根目录 | 监视模式 |
| -------------- | -------------- | ----------------------------------- |
| **mcp-server** | `/` | `apps/mcp-server/**`, `packages/**` |
| **web** | `/` | `apps/web/**`, `packages/**` |
| **postgres** | - | Railway托管PostgreSQL |
每个应用程序都有一个`railway.json`,用于配置构建和部署。
### 环境变量
#### 此项目中环境变量的工作方式
网页门户使用Next.js,它有两个环境变量类别:
- **`NEXT_PUBLIC_*`变量** 在客户端JavaScript包中内联到**构建时**。它们必须在`next build`运行时存在。在Dockerfile中,它们被声明为`ARG`,以便Railway(和Docker)可以在构建期间注入它们。
- **`API_BASE_INTERNAL`** 也在**构建时**评估(Next.js `rewrites()`在`next build`期间运行)。它被声明为Dockerfile中的`ARG`,原因相同。
- MCP服务器是一个普通的Node.js/Hono进程,它在**运行时**读取所有环境变量。不需要特殊的构建时注入。
#### MCP服务器(`mcp-server`)
| 变量 | 描述 | 开发默认值 | 生产示例 |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | ----------------------------------------- |
| `RTM_API_KEY` | RTM API密钥 | — | `abc123...` |
| `RTM_SHARED_SECRET` | RTM共享密钥 | — | `xyz789...` |
| `RTM_CALLBACK_URL` | RTM OAuth回调URL | `http://localhost:8787/rtm/callback` | `https://api.yourdomain.com/rtm/callback` |
| `RTM_WEBHOOK_SECRET` | Webhook HMAC验证的随机密钥 | — | `openssl rand -hex 32` |
| `DATABASE_URL` | PostgreSQL连接字符串 | `postgres://rtm:rtm@localhost:5433/rtmdb` | `${{Postgres.DATABASE_URL}}` |
| `BETTER_AUTH_SECRET` | 身份验证加密密钥 | — | `openssl rand -hex 32` |
| `BETTER_AUTH_URL` | 身份验证基址(与`APP_BASE_URL`相同) | `http://localhost:8787` | `https://api.yourdomain.com` |
| `APP_BASE_URL` | 服务器的公共URL | `http://localhost:8787` | `https://api.yourdomain.com` |
| `WEB_APP_URL` | 网页门户URL - 用于BetterAuth `trustedOrigins`和Hono CORS。 **必须与浏览器发送的确切来源匹配**(方案 + 域,无尾部斜杠)。 | `http://localhost:3000` | `https://yourdomain.com` |
| `PORT` | 服务器端口。 **Railway自动设置此项** - 请勿在Railway中覆盖它。 | `8787` | _(由Railway设置)_ |
| `NODE_ENV` | 环境 | `development` | `production` |
| `LOG_LEVEL` | 日志详细程度 | `info` | `info` |
| `MCP_SERVER_NAME` | MCP协议中的服务器名称 | `rtm-mcp-server` | `rtm-mcp-server` |
| `MCP_SERVER_VERSION` | 服务器版本 | `1.0.0` | `1.0.0` |
| `MCP_TRANSPORT` | 传输模式 | `http` | `http` |
#### 网页门户(`web`)
浏览器的身份验证请求会发送到相同的源(`/api/auth/*`),并通过 `next.config.mjs` 中的 `rewrites()` 函数被 Next.js 代理到 MCP 服务器。这样可以完全避免 CORS 问题。
| 变量 | 描述 | 开发默认值 | 生产环境示例 |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | ------------------------------------------ |
| `NEXT_PUBLIC_API_BASE` | MCP 服务器的**公开** URL。在**构建时**内联到客户端 JS(Dockerfile `ARG`)。如果未设置 `API_BASE_INTERNAL`,也用作备用代理目标。 | `http://localhost:8787` | `https://api.yourdomain.com` |
| `NEXT_PUBLIC_SITE_URL` | 网页门户的公开 URL(用于元数据) | `http://localhost:3000` | `https://yourdomain.com` |
| `API_BASE_INTERNAL` | MCP 服务器的**内部/私有** URL,用于 Next.js 服务器代理身份验证请求。在**构建时**评估(Dockerfile `ARG`)。使用容器主机名(Docker)或 Railway 私有网络 URL,以保持流量在内部。 | 本地不需要(回落到 `NEXT_PUBLIC_API_BASE`) | `http://<service>.railway.internal:<port>` |
> **注意事项 — `API_BASE_INTERNAL` 必须使用 `http://` 而不是 `https://`。** Railway 私有网络不使用 TLS。端口必须与 Railway 分配的端口匹配(请在 mcp 服务部署日志中检查实际端口,例如 `8080`)。
#### PostgreSQL
使用 Railway 的托管 PostgreSQL。在其他服务中引用其变量:
- `${{Postgres.DATABASE_URL}}`
### 部署步骤
1. **创建 Railway 项目**
```bash
railway login
railway init
```
2. **添加 PostgreSQL**
- 在 Railway 仪表板中,点击 "+ 新建" → "数据库" → "PostgreSQL"
3. **添加 MCP 服务器服务**
- 点击 "+ 新建" → "GitHub 仓库" → 选择您的仓库
- 设置根目录:`/`
- Railway 自动检测 `apps/mcp-server/railway.json`
- 添加所有 MCP 服务器环境变量(参见上表)
- **不要设置 `PORT`** — Railway 自动分配它
- 设置自定义域名(例如 `api.yourdomain.com`)
4. **添加网页服务**
- 点击 "+ 新建" → "GitHub 仓库" → 选择您的仓库
- 设置根目录:`/`
- Railway 自动检测 `apps/web/railway.json`
- 添加所有网页门户环境变量(参见上表)
- 对于 `API_BASE_INTERNAL`,使用 MCP 服务器的**私有网络** URL。在 mcp 服务设置 → 网络 → 私有中找到它。格式为 `http://<name>.railway.internal:<port>`。端口是 Railway 分配给 mcp 服务的端口(请检查其部署日志 — 通常为 `8080`,除非被覆盖)。
- 设置自定义域名(例如 `yourdomain.com`)
5. **配置监视模式**
在 Railway 服务设置中,确保启用了 "Config as Code",以便尊重 `railway.json` 中的 `watchPatterns`。
6. **部署**
```bash
railway up
```
或推送到 GitHub,Railway 将自动部署。
### 域名设置
推荐的域名结构:
- MCP 服务器:`api.yourdomain.com`
- 网页门户:`yourdomain.com`
设置域名后,请确保这些变量一致:
| 变量 | 必须匹配 |
| --------------------------------------- | ----------------------------------------------- |
| `RTM_CALLBACK_URL` | `https://api.yourdomain.com/rtm/callback` |
| `BETTER_AUTH_URL` | `https://api.yourdomain.com` |
| `APP_BASE_URL` | `https://api.yourdomain.com` |
| `WEB_APP_URL` (在 mcp 服务上) | `https://yourdomain.com` (确切的浏览器源) |
| `NEXT_PUBLIC_API_BASE` (在网页服务上) | `https://api.yourdomain.com` |
| `API_BASE_INTERNAL` (在网页服务上) | `http://<name>.railway.internal:<port>` |
### 故障排除
| 症状 | 可能原因 |
| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 生产环境中的身份验证请求命中 `localhost:8787` | `NEXT_PUBLIC_API_BASE` 在**构建时**未设置。重新部署网页服务 — Railway 在 Dockerfile 声明 `ARG NEXT_PUBLIC_API_BASE` 后,会将服务变量作为 Docker 构建参数自动传递。 |
| 身份验证端点的 CORS 错误 | 网页应用直接向 API 发出跨源请求。身份验证应通过 Next.js 重写(同源)代理。检查 `packages/auth/src/client.ts` 是否未设置 `baseURL`。 |
| Next.js 代理的 `ECONNREFUSED` | `API_BASE_INTERNAL` 错误。验证:(1)使用 `http://` 而不是 `https://`,(2)端口与 Railway 分配的端口匹配(检查 mcp 部署日志),(3)mcp 服务上启用了私有网络。 |
| 注册/登录时的 `403 Forbidden` / "Invalid origin" | mcp 服务上的 `WEB_APP_URL` 与浏览器的源不匹配。必须与确切的方案 + 域名匹配(例如 `https://yourdomain.com`,不能有尾随斜杠)。 |
| `api.yourdomain.com` 上的 `502 Bad Gateway` | mcp 服务的 `PORT` 环境变量与 Railway 分配的端口冲突。**删除 Railway 中 mcp 服务的任何 `PORT` 覆盖**,让 Railway 自动设置它。 |
## API 速率限制
Remember The Milk 大约每秒允许 1 个用户请求。`rtm-client` 包实现了每用户自动速率限制,在请求之间有 1100ms 的间隔(使用 [Bottleneck](https://www.npmjs.com/package/bottleneck))。
## 架构决策
### 时间线管理
RTM 需要用于写操作的"时间线"。按照 RTM 的最佳实践,我们:
- 为每个用户会话创建新的时间线
- 缓存时间线 24 小时
- 自动刷新过期时间线
### 每用户速率限制
速率限制按用户(而非全局)实施,以确保多个用户活动时公平访问。每个用户都有自己的请求队列。
### monorepo 结构
使用 pnpm 工作区 + Turbo:
- 在 MCP 服务器和网页门户之间共享代码
- 重用身份验证和数据库包
- 维护 RTM 客户端的单一源代码
- 启用快速、缓存的构建
## 资源
- [模型上下文协议文档](https://modelcontextprotocol.io/)
- [Remember The Milk API](https://www.rememberthemilk.com/services/api/)
- [BetterAuth 文档](https://www.better-auth.com/)
- [Kysely 文档](https://kysely.dev/)
- [Railway 文档](https://docs.railway.com/)
- [Turbo 文档](https://turbo.build/)
## 许可证
MIT
---
**有疑问?** 打开一个问题或查看 [讨论](https://github.com/allen-n/rtm-mcp/discussions) 标签。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器