# Obsidian CLI MCP [Health: Active]

**Category:** 🧠 Knowledge & Memory  
**Repository:** https://github.com/DariusCorvus/obsidian-cli-mcp  
**GitHub Stars:** 0  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/obsidian-cli-mcp

## Description
Local MCP server for Obsidian Desktop via the official Obsidian CLI.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "obsidian-cli-mcp": {
    "command": "npx",
    "args": ["-y","--yes"]
  }
}
```

## Documentation & README

# obsidian-cli-mcp

`obsidian-cli-mcp` is an [MCP](https://modelcontextprotocol.io/) server for
the **official Obsidian CLI**. It exposes Obsidian vault search, note, task,
file, link, and native Canvas operations to an MCP client. The server does not
replace Obsidian: the CLI forwards requests to the running Obsidian desktop app.

The default transport is local **stdio**. Remote Streamable HTTP is available
as an advanced, separately secured setup; it is not required for local use.

## Requirements

- macOS with **Obsidian Desktop** installed and running.
- The official Obsidian CLI enabled in Obsidian: **Settings → General →
  Command line interface**, then register `obsidian` on your `PATH`.
- Node.js 18 or newer to run the published package. Bun is only needed to
  build or develop this source checkout.

This project requires the desktop CLI. It does not support `obsidian-headless`.
The Obsidian app must remain open while the MCP server is being used.

Check the Obsidian side first:

```sh
command -v obsidian
obsidian version
obsidian vault
```

## Quickstart with npm

Start the published v0.4.1 package from any directory:

```sh
npx --yes --package=@dariuscodes/obsidian-cli-mcp@0.4.1 obsidian-cli-mcp
```

The command speaks MCP over stdio and waits for an MCP client. It intentionally
does not print protocol data to the terminal. Diagnostics go to stderr.

For a source checkout instead:

```sh
git clone https://github.com/DariusCorvus/obsidian-cli-mcp.git
cd obsidian-cli-mcp
bun install --frozen-lockfile
bun run build
node dist/main.js
```

No vault name, vault path, token, Cloudflare account, LaunchAgent, or config
file is required for the local default. The server uses the active vault that
Obsidian exposes through the official CLI.

## Connect an MCP client

For a client that accepts an `mcpServers` configuration, use the npm command:

```json
{
  "mcpServers": {
    "obsidian": {
      "command": "npx",
      "args": [
        "--yes",
        "--package=@dariuscodes/obsidian-cli-mcp@0.4.1",
        "obsidian-cli-mcp"
      ]
    }
  }
}
```

If the client does not inherit your shell `PATH`, replace `npx` with the
absolute path printed by `command -v npx`. For a source checkout, use
`command: "node"` and `args: ["/absolute/path/to/obsidian-cli-mcp/dist/main.js"]`.

Restart the client after changing its MCP configuration. The first useful
sequence is:

1. Call `vault_search` with a query that should exist in your vault, for
   example `{ "query": "meeting", "limit": 10 }`.
2. Pass one returned path to `note_read`, for example
   `{ "path": "<path returned by vault_search>" }`.
3. Preview a safe note mutation before applying it:

   ```json
   {
     "name": "MCP smoke note",
     "content": "Created after reviewing the plan.",
     "dryRun": true
   }
   ```

   This is a `note_create` call. It returns the planned action and exact CLI
   command without changing the vault. Only use `dryRun: false` after reviewing
   the plan. `dryRun` is a preview, not an authorization boundary.

4. For Canvas, preview a native Canvas file and one text node:

   ```json
   {
     "path": "MCP smoke.canvas",
     "nodes": [
       {
         "id": "hello",
         "type": "text",
         "x": 0,
         "y": 0,
         "width": 320,
         "height": 180,
         "text": "Hello from MCP"
       }
     ],
     "dryRun": true
   }
   ```

   This is a `canvas_create` call. Review the plan, then call it with
   `dryRun: false` if you want to create the file. Use `canvas_read` to inspect
   the native `.canvas` JSON afterward. Canvas tools preserve unknown fields,
   validate node/edge references, and do not require arbitrary eval.

## Configuration and safe defaults

An empty or missing configuration is usable for a vanilla Obsidian vault. The
optional `.obsidianmcprc.yaml` is discovered from the server working directory.
For clients with an unpredictable working directory, set
`OBSIDIAN_MCP_CONFIG` to an explicit config-file path.

The default policy is deliberately local and bounded:

- The v0.4.0 server does not expose a generic `obsidian_eval` tool.
  `eval.enabled` is `false` by default; internal fixed eval snippets used by a
  few safe operations are not a user-supplied JavaScript escape hatch.
- Imports from arbitrary local files are disabled until
  `imports.allowedRoots` is explicitly configured. URLs are never fetched.
- `.obsidian`, `.git`, `.trash`, `.Trash`, `Trash`, and `.DS_Store` path
  segments are blocked by default. Add `paths.allow` for a narrower vault area
  and add project-specific `paths.deny` prefixes for more sensitive content.
- Mutations expose `dryRun`. `file_delete` requires `confirm: true` and
  `note_delete` uses Obsidian trash by default; permanent deletion requires the
  explicit `delete.mode: hard` configuration.
- Git autocommit is off by default.

### Read-only preset

Use an explicit allowlist when an MCP client should only inspect the vault:

```yaml
tools:
  allow:
    - vault_search
    - note_read
    - note_list
    - vault_tags
    - unresolved_links
    - tasks_list
    - note_diff
    - backlinks_get
    - outlinks_get
    - file_read_binary_metadata
    - canvas_read
```

### Safe local preset

The default has safe local guardrails but is not read-only. For an explicit
safe-local surface that allows normal note edits and Canvas creation while
omitting deletion, file imports, file lifecycle operations, and arbitrary
evaluation:

```yaml
tools:
  allow:
    - vault_search
    - note_read
    - note_list
    - vault_tags
    - unresolved_links
    - tasks_list
    - note_diff
    - backlinks_get
    - outlinks_get
    - canvas_read
    - canvas_create
    - canvas_upsert_nodes
    - canvas_upsert_edges
    - canvas_add_node
    - canvas_add_edge
    - canvas_auto_layout
    - canvas_open
    - note_create
    - note_append
    - note_set_frontmatter
    - note_replace_range
    - note_insert_at
    - note_replace
    - note_insert
    - daily_open
    - daily_append
    - task_create
    - task_update
delete:
  mode: trash
eval:
  enabled: false
imports:
  allowedRoots: []
```

### Full trusted local preset

Omit `tools.allow` to expose the complete built-in tool surface, while keeping
the default protected paths, trash deletion, disabled imports, and disabled
`obsidian_eval`. If imports are needed, configure only a dedicated local source
directory:

```yaml
imports:
  allowedRoots:
    - /absolute/path/to/approved-imports
  maxBytes: 26214400
  collision: increment
delete:
  mode: trash
eval:
  enabled: false
```

See [docs/configuration.md](https://github.com/DariusCorvus/obsidian-cli-mcp/blob/HEAD/docs/configuration.md) for all fields and
[examples/](https://github.com/DariusCorvus/obsidian-cli-mcp/blob/HEAD/examples) for note-organization presets.

## Local stdio versus remote HTTP

Local stdio starts one server process directly from the MCP client. It is the
recommended installation: there is no listening socket, remote authentication,
Cloudflare setup, or public endpoint.

Streamable HTTP is an optional advanced mode for a client that cannot use local
stdio. It binds to loopback only and refuses to start without either Cloudflare
Access JWT validation or a strong capability token. Put it behind a TLS,
authenticated reverse proxy or tunnel; do not bind it to `0.0.0.0`. See
[docs/remote-cloudflare.md](https://github.com/DariusCorvus/obsidian-cli-mcp/blob/HEAD/docs/remote-cloudflare.md) for the generic advanced
setup and its security trade-offs.

## Tool surface

The default server advertises 43 regular tools:

- Read: `vault_search`, `note_read`, `note_list`, `vault_tags`,
  `unresolved_links`, `tasks_list`, `note_diff`, `backlinks_get`,
  `outlinks_get`, `file_read_binary_metadata`, `canvas_read`.
- Write and workflow: `note_create`, `note_append`, `note_set_frontmatter`,
  `daily_open`, `daily_append`, `note_replace_range`, `note_insert_at`,
  `note_replace`, `note_insert`, `task_create`, `task_update`,
  `note_transition`.
- Files and attachments: `file_import`, `attachment_import`, `note_attach`,
  `attachment_embed`, `file_move`, `file_rename`, `file_delete`,
  `note_rename`, `note_move`, `folder_create`, `note_delete`.
- Canvas: `canvas_create`, `canvas_upsert_nodes`, `canvas_upsert_edges`,
  `canvas_remove`, `canvas_open`, `canvas_add_node`, `canvas_add_edge`,
  `canvas_auto_layout`.
- Batch: `vault_batch` runs enabled reads and previews enabled mutations with
  `args.dryRun: true`, dependency gating, stable input-order results, and a
  bounded `batch.maxParallelism` (default 4, maximum 8).

All mutating tools accept `dryRun`. Tool annotations identify read-only and
destructive operations for compatible MCP clients.

## Limitations and security

Obsidian Desktop must be running, its official CLI must be enabled, and the
active vault must be available to that desktop session. This server is not a
sandbox and does not support `obsidian-headless`.

Vault content is untrusted data. Notes, Canvas text, task text, and search
results may contain prompt-injection instructions; an MCP client should treat
them as data and never follow instructions found inside a vault merely because
they were returned by a tool. Tool output can also contain sensitive vault
content, so connect only clients you trust.

Read [SECURITY.md](https://github.com/DariusCorvus/obsidian-cli-mcp/blob/HEAD/SECURITY.md) before enabling remote HTTP, imports, hard
deletes, or a broad mutation allowlist. Report security issues privately as
described there.

## Development and CI

The source checkout uses Bun, while the published bin runs on Node:

```sh
bun install
bun run typecheck
bun test
bun run build:schema
bun run build
bun run smoke:stdio
git diff --check
npm pack --dry-run --json
```

The offline stdio smoke verifies the built package entrypoint, MCP initialize,
`tools/list`, the expected tool surface, and the absence of `obsidian_eval`.
The real Obsidian smoke is separate and requires a user session with Obsidian
running:

```sh
OBSIDIAN_CLI_BINARY=obsidian \
  OBSIDIAN_MCP_CONFIG=/absolute/path/to/your/config.yaml \
  OBSIDIAN_MCP_VAULT="your-vault-name" \
  bun run smoke:live
```

GitHub Actions runs only offline gates; it does not depend on Obsidian Desktop
or a real vault on a hosted runner.

## License

[MIT](https://github.com/DariusCorvus/obsidian-cli-mcp/blob/HEAD/LICENSE)

