Embed Claude Code as an interactive terminal right in Obsidian's sidebar. Open it with a hotkey, send your note selections to Claude, and toggle focus between editor and terminal without leaving Obsidian.
- Sidebar terminal — Claude Code runs in the right sidebar via xterm.js + node-pty
- Multi-tab support — Open multiple Claude Code terminals simultaneously
- Automatic workspace context — Claude Code automatically knows which notes are open and which one is active, without you having to tell it
- MCP context server — Built-in MCP server exposes tools so Claude can read your open notes, search the vault, and fetch any note on demand
- Cmd/Ctrl+click vault notes — Click any vault path or
obsidian://openURL Claude prints in the terminal to open the corresponding note in Obsidian - Send selection — Select text in a note, run a command, and it appears in Claude's input with file path and line numbers
- Send current file — Send the active file's path to Claude with one command
- Focus toggle — Switch between editor and terminal without touching the mouse
- Theme sync — Terminal colors automatically match your Obsidian theme (dark/light)
- Configurable — Claude CLI path, font size, font family, extra CLI args, working directory override
- Claude Code CLI installed and available in your PATH
- Obsidian 1.5.0+ (desktop only, not available on mobile)
- Install the BRAT plugin
- Open BRAT settings and click "Add Beta Plugin"
- Enter
ErickRyu/obsidian-claude-code - Enable the plugin in Community Plugins settings
The plugin will automatically download the required native module (node-pty) for your platform on first launch.
- Download
main.js,manifest.json, andstyles.cssfrom the latest release - Create a folder
.obsidian/plugins/obsidian-claude-code/in your vault - Copy the downloaded files into that folder
- Enable the plugin in Obsidian settings
The plugin will attempt to download the node-pty native binary automatically. If auto-download fails, download the appropriate node-pty-{platform}.tar.gz from the release page and extract it into the plugin folder.
git clone https://github.com/ErickRyu/obsidian-claude-code.git
cd obsidian-claude-code
npm install
npm run buildCopy main.js, manifest.json, styles.css, and node_modules/node-pty/ to your vault's .obsidian/plugins/obsidian-claude-code/ directory.
| Command | Description |
|---|---|
| Toggle Claude Code terminal | Open/close the active terminal |
| New Claude Code terminal | Open an additional terminal tab |
| Send selection to Claude | Send selected text with file context to Claude |
| Send current file to Claude | Send @filepath to Claude |
| Focus Claude Code terminal | Toggle focus between editor and terminal |
Set hotkeys in Settings > Hotkeys. Recommended: Cmd+2 for toggle.
- Claude CLI path — Default:
claude. Change if installed elsewhere. - Font size — Terminal font size (default: 14)
- Font family — Terminal font (default: system monospace)
- Extra CLI arguments — Additional args passed to Claude CLI (e.g.,
--model sonnet) - Working directory — Override the working directory (default: vault root)
- MCP context server — Enable the built-in MCP server so Claude can access open notes, active file, and vault search (default: on). Requires terminal restart after toggling.
The plugin spawns Claude Code CLI in a pseudo-terminal (PTY) using node-pty, renders it with xterm.js in an Obsidian sidebar view. Editor integration commands inject text into the terminal input buffer (paste-only, no auto-submit). A terminal state machine (closed/opening/ready/exited) ensures commands wait for the PTY to be ready before sending text.
On load, the plugin starts a lightweight MCP (Model Context Protocol) server that exposes Obsidian's workspace state to Claude Code. It does two things:
- System prompt injection — A short prompt file listing currently open notes and the active note is auto-generated and passed to Claude via
--append-system-prompt-file. Claude always knows which notes you have open without you telling it. - MCP tools — Claude can call
get_active_note,list_open_notes,read_note, andsearch_noteson demand to fetch note content or search the vault.
The plugin writes .mcp.json and .claude/settings.local.json in your vault on load so Claude Code auto-discovers the server and pre-approves the tools (no per-call permission prompts). These are cleaned up when the plugin is disabled.
v0.6.0 Beta · opt-in · existing users see zero change by default.
v0.6.0 ships a brand-new custom webview that runs alongside the legacy xterm.js terminal. Instead of showing raw terminal output, the webview spawns
claude -p --output-format=stream-jsonviachild_process.spawn, parses the JSONL event stream, and renders structured HTML cards forassistanttext,tool_use,tool_result, andresultevents. This is the foundation for v0.7.0 inline diff accept/reject and v0.8.0 plan-as-note. Today's release is infrastructure-only — the terminal path is unchanged and remains the default.
- Open Settings → Community Plugins → Claude Code Terminal.
- Find the UI mode dropdown and change it from
Terminal (xterm.js — default)toWebview (beta). - You will see a Notice: "웹뷰 적용을 위해 Obsidian 재시작 필요 / Restart Obsidian to apply UI mode change".
- Fully restart Obsidian (the view registration is fixed at plugin load — runtime re-registration is intentionally deferred to keep the lifecycle simple in Beta).
- After restart, run the Open Claude Webview command (or click the sidebar icon) to open the new view.
To go back, switch the dropdown to Terminal (xterm.js — default) and restart Obsidian. Your existing terminal-mode settings (CLI path, font, MCP, hotkeys, etc.) are untouched.
The webview does not show inline per-call permission prompts in this Beta. Instead, you choose a preset that translates to --allowedTools + --permission-mode flags on the next spawn:
| Preset | Allowed tools | When to use |
|---|---|---|
| Safe | Read, Glob, Grep (read-only) |
Browsing, summarizing, planning — Claude cannot modify your vault |
| Standard (default) | Safe + Edit, Write, TodoWrite |
Normal editing workflow without shell access |
| Full | Standard + Bash |
Power users who trust the session — Claude can execute shell commands |
Change the preset from the Permission preset (Webview) dropdown in settings, or from the in-view dropdown next to the input bar. Changes apply to the next spawned session, not the current one.
- Assistant text cards — Streaming markdown-style text, deduplicated by
msg.id(no flicker from re-emitted chunks). tool_usecards — Per-tool name with input JSON preview;EditandWriteget a built-in unified diff card (no third-party diff library).tool_resultcards — Stringified or per-block content from the tool runner.- TodoWrite side panel —
TodoWriteresults are hoisted to a side panel with checkbox / status / content rows, so the conversation stays clean. - Thinking blocks — Collapsed by default in a
<details>element. Toggle Show thinking blocks expanded (Webview) to open them automatically. - Compact boundary card —
/compactruns render a horizontal divider with pre/post token counts and elapsed time. - Status bar — Per-result token usage (input + output / context window) and
total_cost_usdderived fromresult.modelUsage(the source of truth, not assistantusage). - Unknown event card — If the CLI emits a JSONL
typethe parser does not recognize, it is preserved as a collapsed JSON-dump card rather than dropped silently. This makes future schema drift visible to debug users. - Session resume — On exit, the webview saves
result.session_idtolastSessionId. The Open Claude Webview (resume last) command spawns with--resume <id>and falls back to a local archive replay if the CLI rejects the resume id.
Console logs from this path use the namespaced [claude-webview] prefix (kept strictly separate from [claude-terminal]) so log filtering stays unambiguous.
The following are intentionally out of scope for v0.6.0 Beta and tracked for follow-up releases:
/mcpslash command is not supported in webview mode. MCP context still works through the terminal path. The webview beta does not wire up the MCP bridge.- Inline per-call permission prompts are not supported. Use the Safe / Standard / Full preset dropdown instead. Fine-grained per-call approval lands in v0.7.0.
- Switching
uiModeat runtime requires an Obsidian restart. The Notice "재시작 필요" reminds you. Runtime re-registration is deferred to keep view lifecycle simple in Beta. - No screenshots / GIFs ship with this Beta. They will land with the v0.6.0 GA release once the UX stabilizes.
- Webview is opt-in only. With
uiMode: "terminal"(the default) all existing behavior — xterm.js, node-pty, system prompt, MCP bridge, OSC 8obsidian://links, @-mention picker — is preserved unchanged. Existing users will not notice this release unless they explicitly flip the setting.
If you hit a parser drift, an unexpected event class, or a lifecycle issue, please open an issue with the [claude-webview] console output and the offending JSONL line — the parser preserves the raw wrapper exactly so you can attach it directly.
- Desktop only — requires node-pty (native module), does not work on mobile
- No inline diffs — Obsidian API does not support inline diff views
- Native module build — node-pty must be compiled for your Obsidian's Electron version
MIT