Skip to main content
Glama
husitao

Obsidian CLI MCP Server

by husitao
README.md
# Obsidian CLI MCP Server

使用 TypeScript 实现的 stdio MCP Server,通过 Obsidian 官方 CLI 为 Claude Code、Codex 等 AI Agent 提供 Vault 操作能力。

本项目不直接读写 Vault 文件,也不通过 shell 拼接命令。所有操作均以参数数组调用 Obsidian CLI,并提供 Vault 锁定、命令权限、超时、输出限制及跨进程串行保护。

## 功能

- 查询 Obsidian 及 CLI 状态
- 列出 Vault 内的文件和文件夹
- 读取、创建、覆盖、追加和前置写入笔记
- 将大段 Markdown 自动拆成 UTF-8 安全块写入
- 搜索笔记及匹配上下文
- 调用属性、链接、任务、模板、历史、插件和开发者命令
- 按配置允许删除、`command`、`eval` 等高权限操作
- 将 Server 硬锁定到指定 Vault
- 串行处理多个 Agent 或并发 MCP 请求

调用链如下:

```text
Claude Code / Codex
        │ stdio MCP
        ▼
Obsidian CLI MCP Server
        │ FIFO + 跨进程锁
        ▼
Obsidian.com / obsidian
        │ IPC
        ▼
正在运行的 Obsidian
```

## 前置条件

- Node.js 20 或更高版本
- Obsidian 1.12.7 或更高版本的安装器
- 在 Obsidian 的“设置 → 常规”中启用“命令行接口”
- 调用时保持 Obsidian 桌面端运行
- 目标 Vault 已由 Obsidian 打开或管理

Windows 使用安装目录中的 `Obsidian.com` 作为终端重定向器。升级安装器后,应重新启用命令行接口并重启终端。

先验证官方 CLI:

```powershell
obsidian version
obsidian vaults verbose
```

## 安装与构建

```powershell
Set-Location D:\Document\MyMCP\ObsidianCli
npm install
npm run check
npm test
npm run build
```

构建入口为:

```text
D:\Document\MyMCP\ObsidianCli\dist\index.js
```

修改 TypeScript 源码后必须重新执行 `npm run build`,并重启 MCP 客户端会话。

## 配置 Claude Code

在 Vault 或 Claude Code 项目根目录创建 `.mcp.json`。下面是锁定到 `Dance` 且允许全部 Obsidian CLI 能力的配置:

```json
{
  "mcpServers": {
    "obsidian-cli": {
      "command": "node",
      "args": [
        "D:\\Document\\MyMCP\\ObsidianCli\\dist\\index.js"
      ],
      "env": {
        "OBSIDIAN_CLI_COMMAND": "D:\\Apps\\Common\\Obsidian\\Obsidian.com",
        "OBSIDIAN_DEFAULT_VAULT": "Dance",
        "OBSIDIAN_LOCKED_VAULT": "Dance",
        "OBSIDIAN_CLI_ALLOW_UNSAFE": "true",
        "OBSIDIAN_CLI_EXTRA_COMMANDS": "*"
      }
    }
  }
}
```

MCP 配置中的环境变量值必须全部是字符串。特别是应写成 `"true"`,不能写成 JSON 布尔值 `true`,否则 Claude Code 会忽略整个 Server 配置。

从项目根目录验证:

```powershell
claude mcp list
claude mcp get obsidian-cli
```

预期状态:

```text
obsidian-cli ... ✓ Connected
```

修改 `.mcp.json` 或重新构建 Server 后,应退出并重新启动 Claude Code。

## 配置 Codex

在受信任的项目中创建 `.codex/config.toml`:

```toml
[mcp_servers.obsidian-cli]
command = "node"
args = ['D:\Document\MyMCP\ObsidianCli\dist\index.js']
cwd = 'D:\Workspace\Ob\Dance\Dance'
enabled = true
required = true
startup_timeout_sec = 30
tool_timeout_sec = 60
default_tools_approval_mode = "approve"

[mcp_servers.obsidian-cli.env]
OBSIDIAN_CLI_COMMAND = 'D:\Apps\Common\Obsidian\Obsidian.com'
OBSIDIAN_DEFAULT_VAULT = "Dance"
OBSIDIAN_LOCKED_VAULT = "Dance"
OBSIDIAN_CLI_ALLOW_UNSAFE = "true"
OBSIDIAN_CLI_EXTRA_COMMANDS = "*"
```

Codex 只会为受信任项目加载项目级 `.codex/config.toml`。修改配置或重新构建后,以目标 Vault 为工作区新建 Codex 线程。

## 配合项目 Skill

MCP Server 负责提供操作能力,Skill 负责规定 Agent 的知识管理流程。当前 `Dance` 项目分别使用:

```text
.claude/skills/curate-dance-vault/SKILL.md
.agents/skills/curate-dance-vault/SKILL.md
```

Claude Code 与 Codex 使用相同 Skill 内容,约束 inbox、atlas、workspace、archive、system 的数据流,并要求优先使用本 MCP,而不是 shell 文件操作。

## MCP 工具

| 工具 | 主要输入 | 用途 |
| --- | --- | --- |
| `obsidian_status` | 无 | 查询 Obsidian 版本及 CLI 连通性 |
| `obsidian_help` | `command?` | 查询总帮助或指定命令帮助 |
| `obsidian_list` | `type`、`vault?`、`folder?`、`extension?` | 列出 Vault、文件或文件夹 |
| `obsidian_read_note` | `path`、`vault?` | 按 Vault 相对路径读取笔记 |
| `obsidian_write_note` | `path`、`content`、`mode`、`overwrite`、`vault?` | 创建、追加或前置写入笔记 |
| `obsidian_search` | `query`、`path?`、`limit?`、`context`、`format`、`vault?` | 搜索笔记内容 |
| `obsidian_cli` | `command`、`parameters`、`flags`、`vault?` | 执行其他允许的 Obsidian CLI 命令 |

`obsidian_write_note.mode` 支持:

- `create`
- `append`
- `prepend`

`obsidian_write_note` 会把正文拆成最多 1,024 UTF-8 字节的块,并在一个不可交错的 CLI 批次中完成写入。调用方仍只需提交一次完整正文。

`obsidian_cli` 的参数格式:

```json
{
  "command": "move",
  "parameters": {
    "path": "inbox/source.md",
    "to": "archive/source.md"
  },
  "flags": []
}
```

Server 会将 Vault 参数放在命令之前,并将普通参数转换为 `key=value`。Obsidian 的普通布尔开关使用裸 flag,例如 `overwrite`、`verbose`;全局复制选项使用 `--copy`。

## 环境变量

| 环境变量 | 默认值 | 说明 |
| --- | --- | --- |
| `OBSIDIAN_CLI_COMMAND` | `obsidian` | CLI 可执行文件名或绝对路径 |
| `OBSIDIAN_DEFAULT_VAULT` | 未设置 | 工具调用未指定 Vault 时使用的默认值 |
| `OBSIDIAN_LOCKED_VAULT` | 未设置 | 将 Server 硬锁定到指定 Vault,并禁止枚举所有 Vault |
| `OBSIDIAN_CLI_TIMEOUT_MS` | `30000` | 单个进程的执行超时,范围 1–300 秒 |
| `OBSIDIAN_CLI_MAX_OUTPUT_BYTES` | `1048576` | 单次调用最大输出,最高 10 MiB |
| `OBSIDIAN_CLI_ALLOW_UNSAFE` | `false` | 允许已知高影响命令 |
| `OBSIDIAN_CLI_EXTRA_COMMANDS` | 未设置 | 额外命令名,逗号分隔;`*` 表示允许全部合法命令名 |

同时设置默认和锁定 Vault 时,两者必须一致,否则 Server 拒绝启动。

### 推荐的受限配置

```text
OBSIDIAN_DEFAULT_VAULT=Dance
OBSIDIAN_LOCKED_VAULT=Dance
OBSIDIAN_CLI_ALLOW_UNSAFE=false
```

### 完全信任配置

```text
OBSIDIAN_DEFAULT_VAULT=Dance
OBSIDIAN_LOCKED_VAULT=Dance
OBSIDIAN_CLI_ALLOW_UNSAFE=true
OBSIDIAN_CLI_EXTRA_COMMANDS=*
```

完全信任配置允许 `delete`、`eval`、`command`、插件管理、发布、恢复、主题及开发者命令,但仍不会把输入交给操作系统 shell。`eval` 和插件命令本身仍可能对 Obsidian 应用或 Vault 产生广泛影响。

## 安全与并发模型

### 命令安全

- 使用 `spawn(executable, argv, { shell: false })`
- 校验命令、参数名和 flag 格式
- 默认使用安全命令白名单
- 高影响命令需要 `OBSIDIAN_CLI_ALLOW_UNSAFE=true`
- 未知或插件命令需要显式加入额外白名单,或设置 `OBSIDIAN_CLI_EXTRA_COMMANDS=*`
- 限制进程执行时间和输出大小
- 拒绝超过安全请求头大小的通用 CLI 调用;长正文必须使用 `obsidian_write_note`

### Vault 隔离

设置 `OBSIDIAN_LOCKED_VAULT` 后:

- 所有未指定 Vault 的命令自动使用锁定值
- 显式指定其他 Vault 会返回错误
- `obsidian_list type=vaults` 和通用 `vaults` 命令被禁用

Vault 锁定只约束通过本 Server 执行的命令。高权限的 Obsidian 应用级操作,例如插件安装或 `eval`,仍需由可信 Agent 使用。

### 并发保护

Windows `Obsidian.com` 通过 IPC 与 Obsidian 主进程通信。多个 CLI 进程同时发送消息可能导致主进程 JSON 边界损坏。

Server 使用两层保护:

1. 每个 MCP Server 内部的 FIFO Promise 队列。
2. 临时目录中的跨进程锁,并使用心跳与失效锁恢复。

因此 Claude Code、Codex 和并发 MCP 工具调用会依次访问 Obsidian CLI。直接在终端运行的 `obsidian` 命令不会经过此锁,Agent 工作期间不要在其他终端并行执行大量 CLI 命令。

## 故障排查

### Claude Code 显示 `No MCP servers configured`

检查:

1. Claude Code 是否从包含 `.mcp.json` 的项目根目录启动。
2. `.mcp.json` 是否为有效 JSON。
3. `env` 下所有值是否都是字符串。
4. 项目 MCP Server 是否已获准启用。

运行:

```powershell
claude mcp list
claude mcp get obsidian-cli
```

修改后重启 Claude Code。

### Obsidian 主进程出现 `Unexpected token ... is not valid JSON`

这表示 Windows CLI IPC 收到了损坏的 JSON 请求头。已确认的触发因素包括单次 `content=` 正文过大,以及多个 CLI 进程并行发送消息。当前 Server 会自动分块正文、限制通用请求大小并串行执行。

处理步骤:

1. 确认已使用包含 FIFO 和跨进程锁的最新构建。
2. 执行 `npm run build`。
3. 完全退出 Claude Code、Codex 和 Obsidian。
4. 先重新启动 Obsidian,再启动 Agent。
5. 不要从其他终端并行运行 Obsidian CLI。

Agent 不应在 MCP 写入失败后降级到系统 `Write` 或 shell;这会绕过 Obsidian 和 Skill 的数据流规则。

跨进程锁异常退出后会自动恢复失效锁。

### CLI 提示找不到 Obsidian

```text
The CLI is unable to find Obsidian.
```

确认:

- Obsidian 正在运行
- 安装器为 1.12.7+
- 命令行接口已重新启用
- MCP 进程与 Obsidian 运行在同一 Windows 用户和会话中
- `OBSIDIAN_CLI_COMMAND` 指向正确的 `Obsidian.com`

### 修改源码后行为没有变化

MCP 客户端运行的是 `dist/`,不是 `src/`。执行:

```powershell
npm run check
npm test
npm run build
```

然后重启 Claude Code/Codex 会话。

## 开发

```powershell
npm run dev
```

项目结构:

```text
src/
  commands.ts  命令白名单、参数与 flag 构造
  config.ts    环境变量解析和 Vault 锁定配置
  content.ts   UTF-8 安全正文分块
  runner.ts    进程执行、FIFO 与跨进程锁
  server.ts    MCP 工具注册
  index.ts     stdio 入口
test/
  commands.test.ts
  config.test.ts
  content.test.ts
  runner.test.ts
  server.test.ts
```

stdio 的标准输出专用于 MCP 协议;Server 日志只能写入标准错误。

## 验证

```powershell
npm run check
npm test
npm run build
```

当前测试覆盖:

- 参数构造与 shell 注入边界
- 安全、危险及通配命令权限
- Vault 锁定配置
- CLI 退出码、超时与输出限制
- 单进程及跨 Runner 串行执行
- MCP 工具发现

## 参考

- [Obsidian CLI 官方文档](https://help.obsidian.md/cli)
- [Model Context Protocol](https://modelcontextprotocol.io/)
- [Codex MCP 配置](https://developers.openai.com/codex/mcp)
- [Codex 自定义与项目 Skill](https://developers.openai.com/codex/concepts/customization)

TDQS

A3.5/5.0

Scored across 7 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: listing, reading, writing, searching, status, help, and a generic escape hatch. No overlap or ambiguity.

Naming Consistency5/5

All tools follow the consistent pattern 'obsidian_<action>' with snake_case, making it predictable for the agent.

Tool Count5/5

Seven tools is well-scoped for an Obsidian CLI wrapper, covering essential operations without being excessive or insufficient.

Completeness4/5

Covers core CRUD (read, write), search, list, status, and help. Missing explicit delete or rename, but the escape hatch fills gaps.

Maintenance

ActivityInactive
ResponsivenessNo issues