Skip to main content
Oleksii Mazurenko

← 博客Obsidian · MCP · Cloudflare

Obsidian 搬进了我的 AI 中枢:一个连接通往所有服务,还有智能体画的图

我的 Obsidian 仓库现在放在 Cloudflare 上,kosh 则是一个 MCP 连接,通往任务、笔记、Telegram、Go-Alpha、Instagram 和我的 Mac。智能体直接在仓库里画 Excalidraw 图。它是怎么搭起来的,边界又在哪里。

发布于 2026年10月31日7 分钟阅读

TL;DR

我的 Obsidian 仓库不再放在 Mac 上了。它现在在 Cloudflare 上,在 kosh-vault 里。Mac 和 iPhone 通过 Self-hosted LiveSync 插件与它同步。

kosh 是我的个人 AI 中枢。它是一个 MCP 连接,背后是我所有的服务:任务、笔记、Telegram、Go-Alpha、Instagram、Mac 上的看门狗,以及 Mac 上的 shell。

现在,智能体还会直接在仓库里画 Excalidraw 图。我打开 Obsidian,就能看到它的想法变成了一张图。我可以手动修改,智能体也能看到我的修改。

以前的痛点

问题有两个。每个下面都写着:以前怎样,现在怎样。

1. 每个服务都是一个单独的连接

以前 — 5 个连接:

Claude ──▶ 任务
Claude ──▶ Telegram
Claude ──▶ Go-Alpha
Claude ──▶ Instagram
Claude ──▶ 笔记(只能在 Mac 上)

现在 — 1 个连接:

Claude ──▶ kosh ──▶ 上面所有服务

而且每个客户端都是这样:Claude Code、claude.ai、手机。每新增一个服务,都得在每个客户端里分别添加。笔记则只能在 Mac 上让 Claude 编辑。

2. 智能体的修改要绕一大圈才能到达笔记

以前:

智能体 ──▶ GitHub ──(最多 2 分钟)──▶ Mac ──(iCloud)──▶ iPhone

现在:

智能体 ──▶ kosh-vault ──(约 1 秒)──▶ Mac 和 iPhone

以前,修改要靠 Obsidian Git 插件从 GitHub 拉取——最多两分钟,而且只有 Mac 上的 Obsidian 开着才行。要到 iPhone,还得再经过 iCloud。现在仓库在云端,Mac 可以睡眠。

仓库搬到了云端

我想要唯一的事实来源。一个不会跟着笔记本一起睡着的来源。

正好有现成的项目:livesync-workers,一个运行在 Cloudflare Workers 上的 Self-hosted LiveSync 插件后端。我 fork 了它,取名 kosh-vault。

现在,事实来源是 Durable Object 里的一个 SQLite 数据库。Mac 和 iPhone 上的 Obsidian 与它保持实时连接,每次改动大约一秒就能收到。说白了,就是跑在 WebSocket 上的 Obsidian。

Mac 可以睡眠——仓库对智能体依然可用。其他所有副本都只是跟随云端:每小时一次备份到 GitHub,以及 iCloud 里的一个只读镜像。

有一个设置,没有它“实时”就不成立:LiveSync 需要 keepReplicationActiveInBackground: true。否则,Obsidian 窗口被其他窗口挡住时同步会暂停,智能体的修改要等我看过去时才会到。

kosh:一扇门

kosh 是 Cloudflare 上的几个 Worker。名字来自哥萨克的 kosh,即扎波罗热营地(Sich)的指挥部。

在内部,每个服务仍是独立的。Telegram 和 Go-Alpha 运行在 Cloudflare Containers 里。Instagram 是普通的 Worker。笔记是 kosh-vault。但从外面看,入口只有一个:/mcp。

这在实际中意味着:

  • 中枢把所有服务的工具汇总成一个列表,保留它们原来的名字。客户端看到的只是一个连接。
  • 服务之间通过 Cloudflare 的 service bindings 通信,而不是通过带共享令牌的公开地址。
  • 第三方服务的密钥,我都粘贴在同一个连接页面上。它们加密保存,任何地方都不会再把它们显示出来。
  • 某个服务宕机时,它的工具仍留在列表里,调用会如实回答:“不可用”。

kosh 的意义就在于:我所有的服务都能通过它访问,而不用一个个单独连接。

任务就是 markdown

我唯一的任务系统,就是仓库里的笔记。一个区域,一个文件。优先级是那一行上的 Obsidian Tasks 表情符号。

智能体用 tasks_* 工具添加、移动和完成任务。每次写入都会核对内容哈希:如果文件在此期间被改过,操作就重新执行。每次修改还会作为一行记入日志。

任务看板由 kosh 自己绘制,放在一个 Excalidraw 文件里。我手动改了列表,一分钟内定时任务就会发现,并重绘看板。只有看板上的内容真正变了,它才会写入。

智能体会画图

这是最新的部分。四个工具:drawing_list、drawing_read、drawing_create、drawing_edit。

我说:“画一下这个流程是怎么运作的。”智能体就在仓库里创建一个 .excalidraw.md 文件。一秒后它就到了我的 Mac 上,Excalidraw 插件把它当作自己的文件打开。

智能体
  │ 请求修改图(drawing_edit)
  ▼
kosh
  │ 写入绘图文件
  ▼
kosh-vault(Cloudflare)
  │ LiveSync 送达,约 1 秒
  ▼
Obsidian 里打开的图随之更新

Excalidraw 插件有自己的 CLI,但它需要 Mac 上的 Obsidian 正在运行。所以 kosh 自己按插件的格式写文件——即使 Mac 在睡眠也能工作。下面每条规则都在真实插件上测试过:

  • 每个被修改的元素都会得到新版本号,且不小于以秒计的当前时间。否则,打开着的图会悄悄忽略这次修改。
  • 删除要用 isDeleted 标记。一个只是从文件里消失的元素,会留在打开的视图里,并在下次保存时回来。
  • 文字要在两处修改:JSON 里和 Text Elements 部分。以 Text Elements 为准。
  • 文件以压缩形式写入,和插件自己写的一样。这样打开的视图就没有理由再保存一次。

布局不必由智能体自己计算:有自动布局。六个分区里的 80 个方块和 118 条箭头,2.9 秒就能排好。第一张真正的图我在自己的 Obsidian 里看了,说:“对,都很好。”

实话实说:局限

最薄弱的环节,是智能体修改时正在我屏幕上打开着的图。

第一次外部修改之后,插件会再保存一次这张图。如果这次保存还没到云端,智能体又写了一次,LiveSync 里就会出现冲突。

冲突不会丢东西:LiveSync 会保留两个版本。但笔记在磁盘上会卡住不动,屏幕上还会弹出“Conflicting changes”对话框。下面是一次实测的结果——对一张打开的图连续修改:

两次修改的间隔被接受的写入冲突对话框
15 秒250
5 秒301
1 秒31
无间隔61

样本很小。这是趋势,不是统计。留出间隔也不等于保证。

所以 kosh 学会了自己合并这类冲突。它找出两个版本的共同祖先,逐个元素比较。我改了方块 C,智能体改了方块 A?两处修改都会保留,对话框大约 10 秒后自己关闭。修复后的同一测试:

两次修改的间隔被接受的写入冲突对话框
5 秒240
1 秒291 — 12 秒后自行关闭

kosh 有意不合并的情况:双方改了同一个元素。两个版本都可能是我自己的工作,所以这个对话框留给我处理。我两台设备之间的冲突,kosh 也不碰——它只处理其中一个版本由它自己写入的冲突。

我踩过的坑

  • Linter 弄坏了图。它的一条规则把分区标题改成了小写开头。Excalidraw 插件查找这些标题时区分大小写,于是再也找不到它们——每次保存都会多追加一个分区。解决办法:在 Linter 中排除 .excalidraw.md。
  • 不要在同一台 Mac 上再开第二个 Obsidian。一个使用独立主目录的测试副本弹出了系统对话框,提议重置我的钥匙串。
  • Mac 上的 shell 不是沙盒。kosh 可以以我的身份在我的笔记本上执行命令。所以凡是删除、安装、推送或涉及密钥的操作,都必须先得到我对这条具体命令的“同意”。我还可以在 Mac 本机上用一个文件关闭这个通道。
  • livesync-workers 是个年轻的项目,只有一位作者。所以我 fork 了它,并每小时备份到 GitHub。

它带给我什么

我打开任何一个 Claude 客户端,无论是在 Mac 上、浏览器里还是手机上,它都已经拥有一切:任务、笔记、Telegram、调研、Mac 的健康状态。

那些难以记在脑子里的东西,智能体会摆到画布上。我看一眼,动手改一改——智能体也能看到我的修改。

一个连接,一个事实来源,用一张图代替一堵文字墙。

发现错误了吗?

本文里有事实错误、别扭的翻译,或者哪里读起来不对?告诉我——用你自己的语言。