顯示具有 obsidian/plugin 標籤的文章。 顯示所有文章
顯示具有 obsidian/plugin 標籤的文章。 顯示所有文章

2026-05-21

obsidian-blogger mcp 發佈組合技

Obsidian × MCP × Blogger — 無頭發佈組合技實錄

本文由 AI(Shadow Monarch)協助撰寫,內容基於實際程式碼修改與端到端測試結果。

當 Obsidian 插件不跟你對話時,那就自己開一條 MCP 專屬通道。

如果你需要在 Obsidian 外(透過 AI Agent 或自動化腳本)觸發插件功能,很可能會撞到一個尷尬的牆:Obsidian 的指令執行 API 只傳 commandId,不帶任何參數,也無法處理對話框(dialog)

這篇文章記錄了我們如何繞過這個限制,實作一套從 MCP → REST API → Obsidian 插件 → Blogger 的完整發佈管線。


背景

obsidian-blogger 是一個能將 Obsidian 筆記直接發佈到 Google Blogger 的插件。它原本的發佈指令 google-blogger2:defaultPublish 是這樣註冊的:

// 原始實作 — 使用 editorCallback
this.addCommand({
  id: 'defaultPublish',
  name: 'Publish current note to Blogger',
  editorCallback: (_editor, _view) => {
    doClientPublish(this);
  },
});

當你在 Obsidian 內按快捷鍵或點指令面板時,這完全沒問題。但當我們想透過 MCP(Model Context Protocol) 來觸發它時,問題出現了。


問題:command_execute 的先天限制

Obsidian Local REST API 提供了一個 command_execute 工具,可以透過程式執行任何 Obsidian 指令。但它的簽章長這樣:

command_execute({ commandId: string })

只有 commandId,沒有第二個參數。

這意味著:

  1. 無法傳遞資料 — 不能指定要發佈哪個檔案,插件只能自己抓 active file
  2. 無法處理對話框 — 如果指令彈出 modal 或 prompt,Agent 無法回應
  3. 無法處理 checkCallback — 需要條件判斷才能執行的指令會直接失敗

實測結果

測試 google-blogger2:defaultPublish 時,雖然 API 回傳了 { "message": "OK" },但實際上什麼都沒發生。沒有發佈,沒有錯誤訊息,什麼都沒有。


偵查:到底差在哪裡?

比對 Obsidian 的 addCommand API 文件後,發現 editorCallbackcallback 在執行上有微妙的差異:

回呼類型 何時可用 簽章 適用場景
callback 任何時候 () => void 不需編輯器也可執行
editorCallback 僅有 Markdown 編輯器焦點時 (editor: Editor, view: MarkdownView) => void 需要操作編輯器內容
checkCallback 條件滿足時 (checking: boolean) => boolean 需要動態判斷是否可用

關鍵洞察:command_execute 在觸發指令時,並不會自動給予編輯器焦點。因此使用 editorCallback 註冊的指令,在透過 REST API 執行時,Obsidian 內部可能無法正確將它視為「可執行」狀態。

解法很簡單:新增一個專門給 MCP 用的指令,改用 callback 註冊


解法:開一條 MCP 專屬通道

src/main.ts 中加入一個新的指令:

this.addCommand({
  id: 'mcpPublish',
  name: 'Publish via MCP (no dialogs)',
  callback: () => {
    doClientPublish(this);
  },
});

關鍵差異只有一行:callback: () => { ... } 取代了 editorCallback: (_editor, _view) => { ... }

由於 doClientPublish 內部已經是透過 plugin.app.workspace.getActiveFile() 取得當前檔案,而不是靠 editorCallback 的參數,所以兩者的執行邏輯完全一樣 — 差別只在 Obsidian 願不願意讓它在無編輯器焦點的狀態下執行

重構後生效

重新建置外掛:

pnpm run build

然後在 Obsidian 中重新載入插件。新的指令 google-blogger2:mcpPublish 就會出現在指令清單中。


組合技:端到端流程

AI Agent / MCP Client
    │
    ├─ command_execute("google-blogger2:mcpPublish")
    │
    ▼
Obsidian Local REST API (HTTP port 27123)
    │
    ├─ 接收 commandId
    │
    ▼
Obsidian 插件系統
    │
    ├─ 找到 blogger plugin 的 mcpPublish 指令
    │
    ▼
callback() → doClientPublish(plugin)
    │
    ├─ getActiveFile() → 取得目前開啟的檔案
    │
    ▼
publishPost(file)
    │
    ├─ 解析 frontmatter、轉換 Markdown
    │
    ▼
Blogger API (Google)
    │
    ├─ POST /blogger/v3/blogs/{blogId}/posts
    │
    ▼
結果回寫至 frontmatter
    ├─ postId, url, blogger.published/updated
    ├─ tags: [obsidian-blogger/post, obsidian-blogger/draft]
    │
    ▼
✅ 發佈完成

實測驗證

執行 command_execute("google-blogger2:mcpPublish") 後,檔案的 frontmatter 自動更新為:

profileName: Just E!
postId: "7373519934638137794"
url: https://elf-here-us.blogspot.com/
blogger:
  published: 2026-05-21T02:25:41+08:00
  updated: 2026-05-21T02:25:41+08:00
tags:
  - obsidian-blogger/post
  - obsidian-blogger/draft

所有欄位都正確寫入,表示發佈流程完全成功


這個組合技的適用範圍

這套「加一條 MCP 專屬指令」的模式,不只適用於 obsidian-blogger。任何 Obsidian 插件只要遇到以下情境,都可以套用:

情境 說明
指令需要對話框 插件彈出 modal 要求使用者輸入 → 拆成兩個指令:一個是原本的 UI 版,另一個是 MCP 版跳過對話框,使用預設值或 active file 的內容
指令使用 editorCallback 如同本文案例,改成 callback 讓 REST API 能正常觸發
指令有 checkCallback 檢查條件無法滿足 → 新增無條件執行的 callback 版本
需要傳遞資料 command_execute 無法帶參數 → 改用 vault_patch 先在 frontmatter 寫入設定,再觸發指令讀取

重要原則

  • 保留原始指令 — 不要刪除原本的 defaultPublish,因為使用者在 Obsidian UI 內還是需要它
  • 命名清楚 — 新的 MCP 指令名稱要標明用途,例如 mcpPublishmcpPublishLive
  • 跳過對話框 — MCP 版的指令不應彈出任何 UI,所有的決策應該基於 frontmatter 或預設值

已知限制

  • 一次只能發佈一個檔案 — 因為依賴 getActiveFile(),無法批次發佈
  • 無法選擇目標 Blogger 部落格 — 使用上次設定的 profile,無法臨時切換
  • 如果沒有開啟任何檔案getActiveFile() 回傳 null,會拋出錯誤

這些限制在一般使用場景下問題不大,但如果需要更進階的批次發佈或動態設定,就需要更深入的改造了。


總結

這次探索的核心收穫其實很簡單:

command_execute 不能帶參數、不能處理對話框、也不能保證編輯器焦點。但我們可以用一條 callback 指令,繞過所有這些限制。

如果你正在開發 Obsidian 插件,想要讓它可以被外部工具(AI Agent、自動化腳本、快捷鍵啟動器)呼叫,只要在 onload 裡面多註冊一個 callback 版本的指令就好 — 不需要動到原本的架構,也不需要引入額外的相依套件。

這就是 Obsidian × MCP 組合技的精髓:看懂 API 的限制,找到最小的繞道路徑


相關連結

obsidian mcp 三種工具比較

Obsidian MCP 三種工具實戰比較

本文由 AI(@bluelovers/opencode-arise / Shadow Monarch)協助撰寫,內容基於實際工具測試結果。建議讀者在使用前自行驗證最新版本的功能變化。

從外掛到純本地,三種串接 Obsidian 與 MCP 的方式各有什麼優劣?

如果你正在研究如何讓 AI Agent 讀寫 Obsidian 筆記,可能會發現市面上至少有三種不同的 MCP 工具。它們名字很像,底層技術也相似,但實際用起來卻各有取捨。

這篇文章會從實際測試的角度,帶你快速看懂這三個工具的定位、能力與限制。


三個工具一句話版

工具 一句話
obsidian-local-rest-api 裝在 Obsidian 裡的外掛,開啟 REST API + MCP 兩種通道
mcp-obsidian 包裝上面那個外掛的 MCP 介面,定位是 MCP-only
mcpvault 反其道而行 — 不靠外掛,直接指定本機路徑讀寫 vault

1. obsidian-local-rest-api — 最完整的 API 通道

實測心得

這是我測試過功能最完整的選項。因為它直接暴露 Obsidian 的底層 API,所以能做的事情最多:

  • 讀寫任何檔案類型(.md.json、圖片等)
  • 精確定位編輯(heading / block reference / frontmatter 三種 target)
  • 可編輯 heading 行本身(targetScope: marker
  • 可執行 Obsidian 內部指令
  • 可取得當前開啟的檔案
  • 可在 UI 中開啟檔案
  • 可搜尋全文(支援 JsonLogic 結構化查詢)

但也有一些麻煩的地方:

  1. 需要 Obsidian 在背景執行 — 如果 Obsidian 沒開,工具就直接斷線
  2. 需要安裝外掛 — 對某些管控嚴格的環境可能不便
  3. HTTPS 自簽憑證問題 — 像我的環境就遇到 SSE error: self signed certificate,最後只能切 HTTP 模式使用

小結

如果你想找一個功能最強、操作最靈活的方案,這就是你要的。代價是你必須讓 Obsidian 一直開著,而且得接受那個自簽憑證的小麻煩。


2. mcp-obsidian — 純 MCP 包裝層

這個工具本質上就是第一項的 MCP-only 版本。它做的事情就是幫你把 obsidian-local-rest-api 的 REST 端點包裝成 MCP 工具。

在我們測試的環境中,已經被新的 mcp-obsidian-local-rest-api 工具集取代 — 新版的工具數量更多、功能更完整,而且直接對應到 REST API 的所有能力。

如果你是新使用者,直接使用新版工具即可,不需要回頭用這個舊版包裝。


3. mcpvault — 不裝外掛的另類選擇

這是最讓我驚喜的一個選項。它的設計哲學完全不同:

它是怎麼運作的?

一般的 MCP 工具需要透過 HTTP 跟某個服務溝通,但 mcpvault 直接讀取你硬碟上的 Obsidian vault 資料夾。你在 MCP 設定檔裡面給它一個路徑,它就自己去處理剩下的。

優點

  • 不需要 Obsidian 執行中 — 即使 Obsidian 關著,工具照樣能讀寫
  • 不需要安裝外掛 — 對某些不允許安裝社群外掛的環境特別有用
  • 有移動/重新命名功能 — 這是前兩個工具完全做不到的
  • 有標籤管理功能 — 可直接 add/remove/list 標籤,還有全 vault 標籤統計
  • 批次讀取 — 一次最多讀取 10 個筆記
  • 操作安全機制 — 刪除和移動檔案需要二次確認

缺點

  • 僅支援 .md 檔案 — 想讀 .json、圖片?不行
  • 沒有精確編輯 — 只能做字串取代,無法定位到特定 heading 或 block
  • 沒有 UI 互動 — 不能在 Obsidian 中開啟檔案、不能執行指令
  • 限本機 — 無法裝在遠端伺服器上(因為需要直接存取檔案系統)

小結

如果你只是想要批次整理筆記、管理標籤、搬動檔案,而且不想要 Obsidian 一直開著,mcpvault 是很棒的輕量選擇。但如果你需要精確編輯內容或與 Obsidian UI 互動,它就不太夠用了。


功能對照總表

面向 local-rest-api mcpvault
需 Obsidian 運行 ✅ 必須 ❌ 不需要
需安裝外掛 ✅ 必須 ❌ 不需要
可裝在遠端 ✅ 可以 ❌ 限本機
建立/覆寫檔案 ✅ vault_write ✅ write_note
附加/插入內容 ✅ vault_append ✅ write_note 三種 mode
精確 section 編輯 ✅ vault_patch ❌ 僅字串取代
編輯 heading 行 ✅ targetScope:marker ❌ 無法
批次讀取 ❌ 無 ✅ read_multiple_notes
移動/重新命名 ❌ 無 ✅ move_note + move_file
Frontmatter 獨立更新 ❌ 需 patch ✅ update_frontmatter
標籤管理 ❌ 無 ✅ manage_tags + list_all_tags
Vault 統計 ❌ 無 ✅ get_vault_stats
檔案結構探索 ✅ document_map ❌ 無
執行 Obsidian 指令 ✅ command_execute ❌ 無
UI 開啟檔案 ✅ open_file ❌ 無
取得當前檔案 ✅ active_file_path ❌ 無
週期筆記 ✅ periodic_note ❌ 無
.md 檔案 ✅ 可以 ❌ 僅限 .md
操作安全確認 ❌ 無 ✅ 二次確認機制

註:mcp-obsidian(舊版)已被新版 mcp-obsidian-local-rest-api 取代,功能上完全被新工具覆蓋,故不特別列入比較。


所以該選哪一個?

這其實不是選擇題。這兩個工具是互補關係,而不是競爭關係:

你需要做的事                 → 推薦工具
──────────────────────────────────────────
精確編輯筆記內容              → local-rest-api
搜尋與讀取筆記                → 兩者皆可
批次搬移/重新命名大量筆記      → mcpvault
管理筆記標籤                  → mcpvault
與 Obsidian UI 互動           → local-rest-api
操作 JSON 或其他非 md 檔案    → local-rest-api
不開 Obsidian 也能讀寫        → mcpvault
需要遠端存取 vault            → local-rest-api

如果你只能選一個,我會建議先以 local-rest-api 為主 — 因為它的功能涵蓋面最廣,精確編輯的能力是 mcpvault 無法取代的。等真的遇到需要搬檔案或整理標籤的情境時,再把 mcpvault 補上就好。


附錄:關於 HTTPS 自簽憑證

如果你跟我一樣遇到 SSE error: self signed certificate,這裡有幾個解法:

  1. 切換 HTTP 模式(最簡單) — 在 MCP 設定中把 protocol 改為 http,port 改為 27123
  2. 將自簽憑證加入信任(較安全) — 匯出 obsidian-local-rest-api 產生的憑證,加入系統信任清單
  3. 使用環境變數跳過驗證(不建議) — NODE_TLS_REJECT_UNAUTHORIZED=0,僅限開發環境

參考連結