Week 3 · MCP 实战

任务管理
MCP 化

把自己做的看板系统接入 Model Context Protocol,让 Claude Code 用自然语言直接操控真实任务数据。

🔌 MCP Server · chorvy-planner v1.0

Chorvy Planner / 看板系统速览

在讲 MCP 化之前,先快速认识一下被改造的对象——我做的一款个人产品经理日程管理看板工具。

📋 看板拖拽 日期列 + Backlog
🔀 双模式 Work / Life 切换
📅 多视图 日看板 / 周 / 月
🤖 AI 助手 自然语言导入任务
☁️ 云同步 Backend 后端
🔄 周期任务 自动生成重复任务
🔍 全局搜索 实时关键词筛选
⌨️ 快捷键 N / B / T / 1-2-3
↩️ 撤销 操作可回退
📊 日报 AI 生成每日总结
技术栈:前端使用原生 HTML/CSS/JS(无框架),数据存储为 Backend 的单行 JSON blob(user_data 表,字段 user_id + content),一个 appData 对象包含 work.taskslife.taskstagsrecurringRules 等全部数据。GitHub Actions 定时 ping 防止 Backend 免费项目自动暂停。

为什么要 MCP 化?

已经有 Web 界面了,为什么还要做一层 MCP Server?

之前:Web 手动操作
打开浏览器 → 登录 → 点击新建
→ 填写标题 / 日期 / 优先级
→ 保存 → 重复以上步骤
→ 批量加 10 条任务 ≈ 5分钟
之后:自然语言操控
Claude Code ← "帮我加三条任务:
明天上午对齐需求,下午出原型,
后天写 PRD"
→ 3 秒搞定,自动推算日期
💬

自然语言交互

不用记字段名和日期格式。说「下周一」Claude 自己算出 ISO 日期,说「紧急」自动映射到 p_must 标签 ID。

批量操作

一句话加多条任务,batch_add_tasks 只做一次 Backend 读写,比逐条快得多。

🧠

上下文理解

Claude 看得到你的任务列表,可以做周报总结、找过期任务、分析工作负载——这些 Web 界面做不到。

整体架构 / How It Works

MCP Server 作为中间层,在 Claude Code 和 Backend 之间建立了一条自然语言到数据库操作的通道。

Interface
💻
Claude Code
用户用自然语言
描述任务操作
Terminal CLI
MCP Server
🔌
chorvy-planner
解析意图,调用 Tool
读写 JSON blob
index.js (Node)
Database
🗄️
Backend
单行 JSON blob
user_data 表
PostgreSQL

数据模型的关键设计

单行 JSON Blob 架构:整个 appData 对象(包含 work.tasks、life.tasks、tags、recurringRules 等)存储在 Backend user_data 表的一行中。每次操作都是:读取整个 JSON → 在内存中修改 → 用 upsert 写回。这意味着 MCP Server 需要格外注意并发安全——好在这是个人工具,单用户场景。
chorvy-mcp-server/ ├── index.js # MCP Server 核心:7 个 Tool 的实现 ├── package.json # 依赖:@modelcontextprotocol/sdk, @Backend/Backend-js └── README.md # 使用说明

7 个 MCP Tools

每个 Tool 对应一个原子操作,Claude Code 根据用户意图自动选择和编排调用。

list_tasks
列出指定日期范围或状态的任务。支持按日期、完成状态、模式(work/life)筛选。
params: { date?, status?, mode? }
add_task
新增单条任务。自动处理优先级标签 ID 映射("紧急"→p_must)和日期推算。
params: { title, date, priority?, type?, desc? }
batch_add_tasks
一次添加多条任务,只做一次 Backend 读写。当用户一句话描述多个任务时 Claude 会自动选用。
params: { tasks: [ {title, date, ...} ] }
update_task
修改已有任务的任意字段:标题、日期、优先级、描述、子任务等。
params: { task_id, updates: {...} }
complete_task
将任务标记为完成,自动记录 completedAt 时间戳。
params: { task_id }
delete_task
删除指定任务。支持通过 ID 或标题模糊匹配定位。
params: { task_id }
weekly_summary
生成本周任务的结构化摘要:完成数、未完成数、延期任务清单、完成率统计。Claude 可以在此基础上进一步分析和给出建议。
params: { week_offset? } // 0=本周, -1=上周
命名约定:MCP 创建的任务 ID 使用 mcp_ 前缀(如 mcp_1710000000000_a3f8x),方便与浏览器创建的任务区分来源,也便于调试和追踪。

核心实现细节

从鉴权到数据映射,几个值得关注的实现要点。

每次调用都鉴权

MCP Server 在每个 Tool 调用时都执行 signInWithPassword,确保拿到最新的 session。单行 JSON blob 的特性意味着每次操作是「读全量 → 改 → 写全量」。

// 每次 tool 调用的核心流程
async function withAuth(callback) {
  const { data } = await Backend.auth.signInWithPassword({
    email: CREDENTIALS.email,
    password: CREDENTIALS.password
  });

  // 读取整个 appData JSON blob
  const { data: rows } = await Backend
    .from('user_data')
    .select('content')
    .eq('user_id', data.user.id);

  const appData = rows[0].content;

  // 执行具体操作(增删改查)
  const result = await callback(appData);

  // 写回(如有修改)
  await Backend.from('user_data').upsert({
    user_id: data.user.id,
    content: appData
  }, { onConflict: 'user_id' });

  return result;
}

优先级标签映射

Web 端存储的是标签 ID(如 p_mustp_tentative),但用户通过 Claude 说的是自然语言("紧急"、"可选")。MCP Server 在读写两个方向都做了映射:

用户说的标签 IDWeb 端显示
必做 / 紧急 / mustp_must🔴 必须做
可选 / 选做 / tentativep_tentative🟡 可选做

MCP SDK 接入

// package.json 核心依赖
{
  "dependencies": {
    "@modelcontextprotocol/sdk": "latest",
    "@Backend/Backend-js": "^2"
  }
}

// index.js 注册 Tool
server.setRequestHandler(ListToolsRequestSchema, () => ({
  tools: [
    {
      name: "list_tasks",
      description: "List tasks filtered by date/status/mode",
      inputSchema: { /* JSON Schema */ }
    },
    // ... 其余 6 个 Tool
  ]
}));

配置踩坑实录

MCP Server 写好只是第一步,让 Claude Code 正确加载它才是挑战。以下是实际遇到的坑。

🔴 坑 1:配置文件放错位置

!
把 settings.json 放在了项目目录的 .claude/ 下
以为跟 VS Code 一样,每个项目有自己的 .claude/settings.json。实际上 Claude Code 在 Windows 上使用的是用户根目录下的 C:\Users\admin\.claude.json(一个扁平 JSON 文件,不是文件夹)。
⚠️ 项目级 .claude/settings.json 仅当你从该目录启动 Claude Code 时才生效。
正确做法:写入全局 .claude.json
将 MCP Server 配置添加到 C:\Users\[用户名]\.claude.json 的根级 mcpServers 对象中,跟 Notion 等已有连接器并列。

🔴 坑 2:配置嵌套层级错误

检查 .claude.json 后发现,chorvy-planner 被放在了 projects["某路径"] 的嵌套对象里,而不是根级 mcpServers。这导致它只在特定项目上下文中可见。

错误:嵌套在 projects 下
{
  "mcpServers": {
    "notion": { ... }
  },
  "projects": {
    "E:\\任务管理": {
      "mcpServers": {
        "chorvy-planner": { ... }
      }
    }
  }
}
正确:放在根级 mcpServers
{
  "mcpServers": {
    "notion": { ... },
    "chorvy-planner": {
      "command": "node",
      "args": [
        "E:\\任务管理\\index.js"
      ]
    }
  }
}

🟡 坑 3:Windows 路径转义

注意:在 JSON 的 args 数组中,Windows 路径需要双反斜杠转义:"E:\\\\任务管理\\\\chorvy-mcp-server\\\\index.js"。如果 Node 已在系统 PATH 中,command 字段直接写 "node" 即可,无需完整路径。

🟢 不需要手动启动

配置完成后,不需要手动运行 node index.js 保持 MCP Server 在后台运行。Claude Code 会在需要时自动管理进程生命周期——启动、调用、关闭全部由 Claude Code 托管。

实际使用效果

配置完成后,在 Claude Code 终端中就可以用自然语言操控任务了。

场景 1:批量添加任务

# 用户在 Claude Code 中说:
> 帮我加几条任务:明天上午产品评审,下午跟设计对齐交互稿,
  后天写 Q2 规划 PRD

# Claude 自动:
→ 调用 batch_add_tasks
  - 推算 "明天" = 2026-03-20
  - 推算 "后天" = 2026-03-21
  - 默认优先级 p_must
  - 一次 Backend 读写完成

# 刷新 Web 看板,3 条任务已出现在正确的日期列中 ✓

场景 2:查询和分析

# 用户:
> 这周有哪些任务还没做完?

# Claude 调用 list_tasks,返回结构化数据后分析:
→ 调用 list_tasks { date: "this_week", status: "pending" }

本周还有 5 条未完成任务:
  1. 📋 Q2 规划 PRD (3/21, 必做) ← 明天截止
  2. 📋 竞品分析报告 (3/19, 必做) ← ⚠️ 今天,注意
  3. ...

# 用户:
> 帮我把竞品分析标记完成

→ 调用 complete_task { task_id: "mcp_1710..." }
✓ 已完成

场景 3:周报生成

# 用户:
> 帮我生成本周工作总结

→ 调用 weekly_summary { week_offset: 0 }

# 返回结构化数据:
{
  total: 18, completed: 12, pending: 6,
  completion_rate: "66.7%",
  overdue: ["竞品分析报告", "数据埋点文档"]
}

# Claude 基于数据生成自然语言周报
指标Web 手动操作MCP + Claude Code
添加 5 条任务~3 分钟~10 秒 ↓95%
查看本周未完成手动翻看每一列一句话即可
生成周报不支持 / 手写自动生成 + 分析
批量状态更新逐个右键操作"把这三条都标完成"

手机远程操控看板

最终形态:在手机上给飞书发一条消息,任务就自动出现在看板上。整条链路串联了 Week 2 的飞书 Skill 和 Week 3 的 MCP Server。

触发
📱
飞书消息
手机发送
自然语言指令
Feishu App
路由
🤖
OpenClaw Bot
飞书渠道接收
识别意图,调 Skill
Agent
执行
💻
Claude Code
Skill 触发 CLI
调用 MCP Tools
Skill → MCP
落库
📋
看板更新
Backend 写入
Web 端实时可见
Chorvy Planner

链路拆解

1
在飞书对话框发消息给 OpenClaw Bot
比如发一句:「加个任务,明天下午跟设计团队对齐交互稿」。这可以在手机上随时随地完成——通勤、开会间隙、睡前,想到就发。
2
OpenClaw 识别意图,调用 Claude Code Skill
之前创建的 Skill 会被触发,它的核心指令是:调用本地运行的 Claude Code CLI,并将用户的自然语言指令作为输入传递过去。
💡 这个 Skill 是之前专门为「远程调用 Claude Code」而建的,它扮演的是飞书消息到 CLI 命令之间的桥梁。
3
Claude Code 执行 MCP Tool
Claude Code 收到指令后,自动识别这是一个任务操作,选择合适的 MCP Tool(add_task / batch_add_tasks 等),向 Backend 写入数据。
4
打开 Web 看板,任务已在
回到电脑前刷新 Chorvy Planner,刚才通过飞书添加的任务卡片已经出现在正确的日期列中,优先级、标签一应俱全。
三期内容串联:Week 1 学了 Skill 基础 → Week 2 实战了飞书 + OpenClaw Skill → Week 3 搭了 MCP Server。这条远程链路恰好把三者串了起来:飞书是入口,Skill 是路由,MCP 是执行层。一条消息,四段跳转,零手动操作。

回顾与收获

把一个个人看板工具 MCP 化的完整过程,和从中学到的东西。

🏗️

MCP 是桥梁

MCP Server 本质上是一个翻译层:把 Claude 的自然语言意图转化为对数据库的结构化操作。写好 Tool schema,Claude 就能自动编排调用。

📦

JSON Blob 简化了一切

单行 JSON blob 架构让 MCP Server 的实现极其简单——不用操心 SQL schema 和迁移。代价是每次读写全量数据,但对个人工具完全可接受。

🪤

配置是最大的坑

MCP Server 代码本身不复杂,80% 的调试时间花在了 Claude Code 的配置文件路径和嵌套层级上。先搞清平台差异再写代码。

🔄

Web 和 MCP 共存

MCP 不替代 Web 界面——拖拽排序、可视化视图仍然用 Web。MCP 负责快速的文本交互场景(批量添加、查询分析),两者互补。

下一步可以做什么?

潜在拓展:① 添加 move_task Tool 支持拖拽级别的日期移动;② 接入 recurring_rules 的增删改查;③ 添加 Prompt 类型的 MCP 资源,让 Claude 自动获取当天任务上下文;④ 把 MCP Server 发布为 npm 包,方便其他 Backend 用户复用。