{“content”:”---\nname: obsidian-local-rest-api\ndescription: Connect to Obsidian Local REST API via HTTP/HTTPS from any network\n---\n\n# Obsidian Local REST API\n\n## Connection Info (from Termux/LAN)\n- API Key: 047e84eb941910b7ae221ea6b458fbd6c9b2bbfbeab654e05a59893520cd29f9\n- PC Tailscale IP: 100.83.112.84\n- LAN URL (非加密): http://100.83.112.84:27123/\n- Local URL (PC 本机): http://127.0.0.1:27123/\n\n## Test Connection (from Termux/phone)\nbash\ncurl -s --max-time 5 http://100.83.112.84:27123/ \\\n -H \"Authorization: Bearer 047e84eb941910b7ae221ea6b458fbd6c9b2bbfbeab654e05a59893520cd29f9\"\n\n\n## Enable LAN Access (bindingHost)\n\n默认情况下插件只监听 127.0.0.1,即使 UI 里有开关也不会真正监听所有接口。必须直接编辑插件的 data.json:\n\nvault 的 plugins 目录路径:\n\nH:\\My Drive\\Jakephone\\Obsidian Vault\\.obsidian\\plugins\\obsidian-local-rest-api\\\n\n\n通过 SSH 修改(PC 上执行):\npowershell\n# 读取当前配置\npowershell -Command \"(Get-Content 'H:\\My Drive\\Jakephone\\Obsidian Vault\\.obsidian\\plugins\\obsidian-local-rest-api\\data.json' | ConvertFrom-Json)\"\n\n# 添加 bindingHost 字段\n$d = Get-Content 'H:\\My Drive\\Jakephone\\Obsidian Vault\\.obsidian\\plugins\\obsidian-local-rest-api\\data.json' | ConvertFrom-Json\n$d | Add-Member -PassThru bindingHost '0.0.0.0' | ConvertTo-Json -Depth 10 | Set-Content 'H:\\My Drive\\Jakephone\\Obsidian Vault\\.obsidian\\plugins\\obsidian-local-rest-api\\data.json'\n\n\n修改后需重启 Obsidian 使其重新加载插件并监听 0.0.0.0:27123。\n\n## Launching Obsidian via SSH (Important)\n\n**❌ 直接调用 exe 不够:\npowershell\n# 这个命令会启动 Obsidian 进程,但不会正确加载 vault 和 community plugins\nStart-Process 'D:\\\\Obsidian\\\\Obsidian.exe'\n\n\n✅ 正确方式:使用桌面快捷方式 .lnk**\npowershell\n# 通过桌面快捷方式启动,Windows 会用完整用户环境加载 vault\nStart-Process 'C:\\\\Users\\\\Sozo\\\\Desktop\\\\Obsidian.lnk'\n\n等待 15 秒让 vault 和插件完全加载,然后再调用 Local REST API。\n\n## SSH 遠程啟動 Obsidian的限制總結\n\n核心問題:Obsidian 是桌面 GUI 應用,不是服務。\n\n| 啟動方式 | 是否能在 SSH 環境正常工作 |\n|----------|--------------------------|\n| Start-Process D:\\Obsidian\\Obsidian.exe | ❌ 不載入 vault 和 community plugins |\n| Start-Process 'C:\\Users\\Sozo\\Desktop\\Obsidian.lnk' | ⚠️ 需要有已登入的互動式桌面 session |\n| 手動在 PC 桌面點擊捷徑 | ✅ 正常 |\n\n驗證方法:\npowershell\n# 檢查 port 27123 是否監聽\nGet-NetTCPConnection -LocalPort 27123\n# 如果沒有輸出 = plugin 未載入,Obsidian 未正常運行\n\n\n🔧 解決方案:\n1. 接受限制 — 需要在 PC活躍時操作,或手動打開 Obsidian\n2. Cron Job 被動觸發 — 設定在 PC 大概活跃的時間窗口\n3. 考慮使用 Obsidian Sync 官方服務(8/月),脫離 Google Drive 依賴\n\n## Fallback: Write to Vault via SSH + PowerShell (when API unreachable)\n\nWhen the Local REST API is not accessible (timeout on 27123), files can be written directly via SSH to the PC:\n\n```bash\n# Write markdown content to Obsidian vault via PowerShell\ncat << 'WIKIEOF' | ssh -i ~/.ssh/id_ed25519_hermes -o ConnectTimeout=10 [email protected] \\\n \"powershell -Command \\\"[Console]::InputEncoding = [System.Text.Encoding]::UTF8; [Console]::OutputEncoding = [System.Text.Encoding]::UTF8; \\input | Out-File -FilePath ‘H:\\My Drive\\Jakephone\\Obsidian Vault\\FILENAME.md’ -Encoding UTF8\""\n# Markdown content here\nWIKIEOF\n\n\n**Key requirements:**\n- Use single-quoted 'WIKIEOF' heredoc delimiter to prevent local variable expansion\n- Obsidian vault path: `H:\\My Drive\\Jakephone\\Obsidian Vault\\`\n- File is written in UTF-8 encoding\n\n**When to use this fallback:**\n- Port 27123 (Obsidian Local REST API) is unreachable from phone\n- API returns timeout or connection refused\n- Paperclip server runs on 19789 (different service, not Obsidian API)\n\n## Troubleshooting\n- **Connection refused from LAN:** 检查 `bindingHost` 是否为 `0.0.0.0`(默认值是 `127.0.0.1`,UI 不暴露此选项)\n- **Timeout:** 检查 PC Tailscale 是否在线,防火墙是否放行 27123 端口\n- **SSL error:** 使用非加密端口 27123 而不是 27124\n- **API 不响应但端口在监听:** Obsidian 可能没完全加载 vault,等待更长时间或通过 .lnk 重新启动\n- **进程存在但插件不工作:** 直接调用 exe 会出现这个问题,用 .lnk 快捷方式重新启动\n- **Port 27123 不监听但 Obsidian 在运行:** 检查 `.obsidian\\enabled-plugins.json` 是否存在(见下)\n- **Plugin 从不加载,API 始终超时:** 很可能是 `enabled-plugins.json` 缺失(见下)\n\n### ⚡ 常見問題:`enabled-plugins.json` 缺失\n\nPlugin 已安裝(在 `community-plugins.json` 中),但 Obsidian 不載入它——症狀是 API 完全無響應,Port 27123 無監聽。\n\n**檢查方法:**\npowershell\nGet-Content ‘H:\My Drive\Jakephone\Obsidian Vault\.obsidian\enabled-plugins.json’\n\n如果檔案不存在或為空,plugin 不會載入。\n\n**修復方法:** 創建 `enabled-plugins.json`:\npowershell\n@(‘obsidian-local-rest-api’) | ConvertTo-Json | Set-Content ‘H:\My Drive\Jakephone\Obsidian Vault\.obsidian\enabled-plugins.json’ -Encoding UTF8\n\n然後重啟 Obsidian。\n\n## Key Endpoints (v3.6.1 — 验证可用)\n- `GET /` — API 信息,含 authenticated 状态\n- `GET /vault/` — 列出 vault 根目录文件(注意: trailing slash `/` 必须有)\n- `GET /vault/{path}` — 读取指定文件或目录\n- `POST /vault/{path}` — 创建或更新文件,Content-Type: text/markdown\n- `DELETE /vault/{path}` — 删除文件(HTTP 204 表示成功)\n- `GET /search/?query={q}` — 搜索笔记\n\n**注意:** 路径不要加 vault 名前缀,直接 `/vault/xxx.md` 即可。\n\n**⚠️ Canvas (.canvas) 文件的寫入限制**\n**發現(2026-04-20):API 的 POST 對 .canvas 檔案返回 HTTP 204,但並不會真正寫入。**\n症狀:寫入後 API GET 仍返回舊內容;PC 上檢查實體檔案已正確寫入(表示底層寫入成功,但 API 緩存/忽略了)。\n\n**解決方案:用 SCP + Base64 + PowerShell 寫入 Canvas 檔案:**\n\nbash\n# 1. 在 Termux 讀取並修改 canvas(通過 API GET 或本地編輯)\n# 2. 將修改後的 JSON base64 編碼\npython3 -c “import base64; print(base64.b64encode(open(‘canvas.json’).read().encode()).decode())” > canvas_b64.txt\n\n# 3. SCP 上傳 base64 檔案到 PC\nscp canvas_b64.txt [email protected]:/Users/Sozo/canvas_b64.txt\n\n# 4. PowerShell 解碼並寫入 vault\n# 先把下面內容存成 restore_canvas.ps1 然後 SCP 上傳執行\n\n\n**⚠️ UTF-8 BOM 問題(發現於 2026-04-24)**\nPowerShell 的 `WriteAllText` 預設會寫入 UTF-8 BOM(`EF BB BF`),這會導致 Obsidian 的 JSON 解析失敗(報 `Unexpected UTF-8 BOM` 錯誤)。\n**解決方案:使用 `UTF8Encoding $false` 明確指定不帶 BOM:**\n\npowershell\nbytes = [System.Convert]::FromBase64String(json = [System.Text.Encoding]::UTF8.GetString(utf8NoBom = New-Object System.Text.UTF8Encoding path = ‘H:\My Drive\Jakephone\Obsidian Vault\幸福-canvas.canvas’\n[System.IO.File]::WriteAllText(json, size = (Get-Item size bytes”\n\n\n**驗證 BOM 是否已去除:** 檔案首字節應為 `123`(`{`),而非 `239`(BOM 第一字節)\npowershell\npath)\nbytes[0..4] # 正常: 123 10 9 34 110 ...\n```\n\n**Obsidian Canvas JSON 格式關鍵欄位:**\n- 節點必要欄位: `id`, `type`, `x`, `y`, `width`, `height`\n- 邊(edge)欄位: `id`, `fromNode`, `fromSide`, `toNode`, `toSide`(⚠️ 不是 `from`/`to`)\n- 邊 ID 必須是數字(如 `e1`, `e2`),不能是字母字串(如 `e_repair_1`)\n- JSON 縮進:Obsidian 接受 TAB 或空格\n\n## 重要:文件名含空格的处理\n\n**文件是空格分隔,不是斜杠分隔。** vault 根目录列表返回的是:\n```\n\"agents hermes.md\", \"agents openclaw.md\", \"agents sozo-setup.md\"\n```\n而不是 `agents/hermes.md`。URL 中的空格必须编码为 `%20`:\n\n```bash\n# ❌ 错误 — 空格写成斜杠\ncurl ... /vault/agents/hermes.md\n\n# ✅ 正确 — 空格编码为 %20\ncurl ... /vault/agents%20hermes.md\n```\n\n**搜索不可用:** `/search/?query=` 端点返回 404(v3.6.1 此功能不可用)。必须先 `GET /vault/` 列出所有文件,再直接读取目标文件。\n\n## 批量删除重复文件(通过 curl)\n```bash\n# 删除 vault 根目录下所有带 (1) 的重复文件\nfor name in \"HERMES_WIKI_SCHEMA (1).md\" \"agents hermes (1).md\" \"agents openclaw (1).md\" \"agents sozo-setup (1).md\" \"env platforms (1).md\" \"index (1).md\" \"user profile (1).md\"; do\n encoded=(echo “name\" | sed 's/ /%20/g')\n curl -s -o /dev/null -w \"%{http_code}\" -X DELETE \\\n \"http://100.83.112.84:27123/vault/{encoded}” \\n -H “Authorization: Bearer 047e84eb941910b7ae221ea6b458fbd6c9b2bbfbeab654e05a59893520cd29f9”\n echo ” $name”\ndone\n```\n”}