feat(ocm): MCP server tools backed by the official Obsidian CLI#428
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 23d02dee93
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
A `close` event with exitCode null means the child was killed by a signal; its output may be partial. Previously this fell through to ok(), so a queued write (obsidian_cli_append_note) could be marked completed even though the CLI command never finished. Add a `signal-terminated` error code and branch on exitCode === null. Addresses Codex P1 review on PR #428. https://claude.ai/code/session_01RgvChiRuc3tqVbhUwLHxHz
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3b246f624f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The Obsidian CLI `daily` command can create today's note when missing — a vault mutation. Exposing it via `obsidian_cli_daily_note` or the `obsidian_cli_run` allow-list let agents mutate the vault outside the ProposalStore write-approval boundary. Remove the daily read tool and drop `daily` from SAFE_CLI_READ_COMMANDS; a confirmed read-only daily variant is deferred (CLAR-OCM-003). Addresses Codex P1 review on PR #428. https://claude.ai/code/session_01RgvChiRuc3tqVbhUwLHxHz
Adds a CLI-backed tool group to the existing in-process MCP server (ADR-013) so agents can use the official Obsidian CLI (1.12+) as a first-party tool surface, managed from the settings tab. - ObsidianCliPort + ObsidianCliAdapter (shell-free spawn, typed errors, timeout, JSON parsing) + ObsidianCliBinaryResolver + MockObsidianCliPort - registerObsidianCliTools: allow-listed read tools + proposal-queued append; eval and destructive commands are never exposed - Wired optionally into ObsidianMcpServerAdapter; group registered only when a CLI path is configured (graceful degradation) - obsidianCliPath setting + settings-tab field (autodetect/test) and enhanced MCP status; shared single spawnSync site preserved - ADR-018 + specs/obsidian-cli-mcp-server (idea→tasks), tests, verify green https://claude.ai/code/session_01RgvChiRuc3tqVbhUwLHxHz
A `close` event with exitCode null means the child was killed by a signal; its output may be partial. Previously this fell through to ok(), so a queued write (obsidian_cli_append_note) could be marked completed even though the CLI command never finished. Add a `signal-terminated` error code and branch on exitCode === null. Addresses Codex P1 review on PR #428. https://claude.ai/code/session_01RgvChiRuc3tqVbhUwLHxHz
The Obsidian CLI `daily` command can create today's note when missing — a vault mutation. Exposing it via `obsidian_cli_daily_note` or the `obsidian_cli_run` allow-list let agents mutate the vault outside the ProposalStore write-approval boundary. Remove the daily read tool and drop `daily` from SAFE_CLI_READ_COMMANDS; a confirmed read-only daily variant is deferred (CLAR-OCM-003). Addresses Codex P1 review on PR #428. https://claude.ai/code/session_01RgvChiRuc3tqVbhUwLHxHz
950346a to
1ba9369
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1ba9369894
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
ObsidianCliAdapter previously accepted any non-empty configured path, which meant a bare command name like `obsidian` would be resolved via PATH and could execute a shadowed/hijacked binary while still reporting the CLI MCP tools as `available`. The settings UI already documents the absolute-path contract; enforce it at the adapter as the last line of defence before spawn. Non-absolute values now map to `not-configured`. Addresses PR #428 P2 review comment.
Summary
Delivers a fully integrated MCP server tool surface built upon the official Obsidian CLI, managed from the plugin's settings tab.
Research first confirmed the premise: the official Obsidian CLI is real (shipped Obsidian 1.12.0, Feb 2026; GA 1.12.4) — a bundled binary that remote-controls a running vault with 100+ commands,
format=jsonoutput, and anevalescape hatch. The plugin already runs an in-process loopback-HTTP MCP server (ADR-013). This PR amends ADR-013 by adding a CLI-backed tool group rather than standing up a second server.ObsidianCliPort(narrow port, ADR-008) +ObsidianCliAdapter— shell-freespawn(no injection), typedObsidianCliError(not-configured/spawn-failed/nonzero-exit/timeout/invalid-json), 15 s timeout, defensive JSON parsing. PlusObsidianCliBinaryResolver(sibling of the Claude/Cursor resolvers) andMockObsidianCliPort.registerObsidianCliTools— allow-listed read tools (obsidian_cli_search/read_note/daily_note/get_properties/run) and a single proposal-queued write (obsidian_cli_append_note).evaland destructive commands are never exposed. Registered intoObsidianMcpServerAdapteronly when a CLI path is configured (graceful degradation; the in-process groups keep working without a CLI).obsidianCliPathsetting (validated, no version bump) + an "Obsidian CLI path" field (autodetect/test, mirroring the Claude field) and an enhanced MCP status line that shows CLI-configured state and the loopback URL. A shared_testBinaryVersionhelper keeps the single auditedspawnSyncsite (NFR-ASM-004).specs/obsidian-cli-mcp-server/(idea → research → requirements → design → spec → tasks → workflow-state) and ADR-018. RequirementsREQ-OCM-001..018map to tests.Security posture
ProposalStore(ADR-007/013): agents propose, humans accept. No trusted-tool bypass.obsidian_cli_runaccepts only a read-only allow-list;eval/delete/move/create/plugin/theme commands have no tool.Test plan
npm run typechecknpm run lint(0 errors)npm run test:coverage— 2302 passed; thresholds met (stmts 91.34%, branches 85.25%, funcs 91%, lines 92.48%)npm run build+npm run build:web+npm run docs:apivalidate:manifest,verify:scaffold,verify:workflows,verify:bundle-size,npm audit(prod/high),git diff --checkPluginSettingTabsurface (not in the standalone Vue UI), so it is covered by source-level tests rather than browser verification. End-to-end CLI invocation requires Obsidian ≥1.12.4 with theobsidianbinary on PATH.Notes / open clarifications
CLAR-OCM-001: a standalone stdio MCP process is deferred — the CLI group rides the existing loopback HTTP transport.https://claude.ai/code/session_01RgvChiRuc3tqVbhUwLHxHz
Generated by Claude Code