Companion for Claude (Obsidian plugin)
Chat with Claude inside your Obsidian vault — notes as context, interactive claude-html artifacts, agent mode with reviewable writes, CLI-first Claude Code workflows, and an optional local MCP bridge for Claude Desktop and advanced live-vault tools. Your vault stays the single source of truth.
  
!The Companion for Claude side-panel chat, with vault context attached to the conversation
<!-- screenshots wanted: session-to-note.png, chat-controls.png — see assets/CAPTURE.md in the mirror repo -->
Bring your own credential. Companion for Claude talks to the Anthropic Messages API with *your* credential — nothing is sent anywhere else. On desktop, direct network access is required for Claude and the local MCP bridge; on mobile, chat, artifacts, and semantic search all work, with only the MCP bridge and session import gated off (desktop/Electron only). Three auth modes: - API key (default, recommended) — a standard
sk-ant-api…key from console.anthropic.com. This is the mode used for community-store builds. - Long-term OAuth token (power users) — paste a token fromclaude setup-token(sk-ant-oat…) to authenticate as your Claude subscription; usage draws on your plan rather than pay-as-you-go API credit. - Import from environment — readANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN(+ANTHROPIC_BASE_URL) from the environment, the way the CLI does. An optional base URL override points any mode at a gateway/proxy. The key stays the default so the plugin remains community-store eligible; the token and environment modes are clearly marked as power-user options.
Features
Chat & context
- Chat in a side panel — streaming responses, Markdown-rendered, with
per-message Copy / Insert / Save as note / Regenerate actions and hover-to-copy on every code block.
- First-run in seconds — a keyless vault shows an in-chat **Connect to
Claude** card; paste your key and start, without opening settings. Your typed message is never discarded while unconfigured.
- Errors don't lose work — if a turn fails mid-stream, the partial reply is
kept and a Retry appears; a truncated reply offers retry with a higher limit; attachments survive failed sends and Regenerate.
- Continue the active workspace — empty Chat surfaces one relevant card for
the active note or research project. Research Desk and Workbench can hand the canonical project back to Companion without sending a request automatically; ordinary notes remain note-focused.
- Vault-aware context —
@-mention notes, folders, or the whole vault;
toggle context pills for your active note, the current selection, linked & backlinked notes, or a vault search. Keyword search by default; semantic search is on by default and fuses with keywords, using a built-in on-device model (one-time ~45MB model + ~23MB ONNX runtime download from huggingface.co / cdn.jsdelivr.net, offered on first run, cached and fully offline afterwards) or a local Ollama server. Search stays keyword-only until the model is downloaded. The index also covers vault PDFs — text is extracted with pdf.js and every chunk keeps its page number, so results cite the page. The ONNX runtime (ort-wasm-simd-threaded.asyncify.wasm) is fetched once during that same consented download and cached with the model; inference itself is on-device.
- PDFs & images in chat — @-mention any PDF or image in your vault, or
paste a screenshot straight into the composer; Claude reads it natively (vision + document understanding). Attachments are per-message pills you can remove before sending.
- In-chat model & reasoning controls — switch model per message
(Opus / Sonnet / Haiku), toggle extended thinking with an effort dial, stream the model's reasoning in a collapsible panel, and set per-message temperature / max tokens. Controls are model-aware — anything a model would reject is hidden, not broken.
- Slash commands — type
/in the composer for a fuzzy palette:
summarize, ask, improve, artifact, plan, canvas, workflows, capture, build, research, and more. A run shows as a compact command chip, not a wall of prompt text.
- Conversation history — chats persist across restarts; resume any past
conversation from a fuzzy picker, or delete one there (two-tap confirm).
- Prompt caching — repeated context (system prompt, tools, conversation
history) is cached server-side automatically, cutting input cost by up to ~10× on long conversations. The cost estimate in the usage bar accounts for cache reads and writes.
- Live usage display — a context-window gauge plus running **session token
totals** (and an estimated cost on API-key auth, or a subscription marker on OAuth), so there are no billing surprises.
- Save & test connection — one click confirms settings are saved and the
credential works, with readable, actionable errors.
- Commands — *Open chat panel*, *New chat*, *Resume a past conversation*,
*Generate implementation plan from current note*, *Turn selection / note into an artifact*, *Ask Claude about my vault*, *Build current plan with Claude*.
Artifacts & generation
The artifact design system takes its aesthetic cues from Thariq Shihipar's “unreasonable effectiveness of HTML” gallery (vendored as a pinned submodule at the monorepo root) — an original reformulation, not a copy — so the plans, reports, and dashboards Claude generates look gallery-grade. See the `NOTICE` for full attribution.
- Interactive artifacts — Claude emits a
claude-htmlblock;
Companion renders it inline in a sandboxed iframe, opens it in your browser, or saves it as a note that stays interactive and portable.
- Canvas mind maps —
/canvas(or just ask): Claude searches your vault
and builds a native Obsidian Canvas — file nodes wired to your real notes, labeled edges, labeled groups that cluster related nodes, auto-layout. A write like any other: gated and confirmed before the .canvas file is created. Also available to advanced MCP clients.
- Bases from your frontmatter — ask for "a reading tracker" or "a project
dashboard" and Claude builds a native Obsidian Base (.base database view) with table, cards, list, or map views, nested and/or/not filters, and column summaries (Sum, Average, Median…), discovering your real frontmatter properties first. Write-gated and confirmed, in chat and over the MCP bridge.
- Indexing & tags — saved artifacts and chats get YAML frontmatter
(title, tags, summary, type) so they index in the tag pane, search, and Dataview, with optional local-model auto-tagging.
- Spec → build handoff — turn a plan note into a build spec + a live
tracker (a claude-html progress board) and hand it to Claude Code.
Evidence-backed research workflow
Use /research in the Companion composer to open the native Research Desk. This guided daily view selects one active project, shows its stage and document progress, explains the deterministic next best action, and keeps a focused attention queue. Guidance can be pinned or dismissed, and no model request is made merely by opening or navigating the Desk.
Use Open advanced research workbench from the command palette for the full record-level interface. Its grouped Build, Write, Assure, and Expand navigation covers Overview, Sources, Evidence, Claims, Outline, Draft, Audit, Intelligence, and Discover. Getting started is guided rather than blank:
- Triage clippings (Research Desk, one click) — groups your clippings
inbox into research themes with one model call, tags each note with its research/<theme> tag, and writes a Clippings/Triage.md board with wikilinks, source URLs, and a potential project per theme.
- Add source is capture-first, not a form — drop a URL (clipped to clean
markdown and auto-tagged), drop or upload a file (PDFs land in project assets), or fuzzy-pick an existing vault note. One gesture per source.
- New project from active note (Research Desk or command palette) —
drafts a sharp research question grounded in the open note, creates the project, imports the note as the first source, and lands on Discover with a pre-derived query, so the preliminary scholarly search is one click away.
The end-to-end workflow is:
- Create a project with a focused research question.
- Import a source so its metadata and captured-content fingerprint are saved.
Sources can be web pages (fetched and reduced to clean readable markdown automatically, powered by Defuddle — no third-party extraction services involved), PDFs, DOI or arXiv references, Zotero items (a zotero_key resolves full bibliographic metadata from your library when you set a Zotero user id in settings), or existing vault notes.
- Capture an exact excerpt with a source locator as evidence.
- Review the excerpt and locator, then mark the evidence reviewed or rejected.
Draft with Claude writes a grounded interpretation of the excerpt for you to edit before saving.
- Build claims with separate supporting, challenging, and contextual evidence
relations. Sharpen with Claude rewrites the draft proposition, grounded in the evidence you checked — no new facts allowed.
- Generate an evidence-backed outline that carries the excerpt, source,
locator, and fingerprint forward.
- Draft sections from their grounded claim and evidence packets.
- Revise with an explicit intent and claim-preservation validation, then
review the preview before replacing the section.
- Run the audit and repair stale sources, broken references, missing locators,
and unsupported claims.
The vault's Markdown records are canonical and remain readable without the plugin. Only reviewed, locatable, non-stale evidence linked to a valid source counts as trusted support; proposed evidence never satisfies a claim. Revision responses that lose required claims, introduce unsupported citations, use stale grounding, or violate the structured response contract are blocked before any document write.
!A claude-html artifact rendered inline in a note *A claude-html artifact rendered inline — interactive, sandboxed, and saved as a plain Markdown note.*
Agent & automation
One agent, three surfaces: agent mode in chat (everywhere), the MCP bridge for Claude Code (desktop), and cloud sessions (mobile-friendly) — same vault, same confirm-before-write guardrails, wherever you are.
- Agent mode (vault tools in chat) — Claude can **search your vault, read
notes, and follow links on its own while answering, showing each step as an expandable tool chip. Read-only by default; an optional setting also lets it create and edit notes, with a confirmation dialog before every write ("Allow", "Allow for this session", or "Deny"). Turn it all off in settings for plain chat with pre-attached context. The same agent runs fully local** on tool-capable Ollama models — Companion reads each model's metadata and tells you when it can't drive tools, and a composer indicator shows when the current backend reasons before answering.
- Web search & fetch tools (opt-in) — let the agent search the public web
(DuckDuckGo keyless, or Brave with an API key) and read pages as clean markdown. Off by default; fires only on explicit searches, with URLs cited.
- External MCP servers (MCP client) — the agent also *consumes* tools from
other MCP servers (HTTP or, on desktop, stdio), namespaced per server and confirm-per-call. Companion is the two-way hub: your vault is served to Claude Code while the agent uses everything else.
- Apply edits as reviewable diffs — ask Claude to improve or fix a note and
it proposes the change as a red/green diff; you accept or reject each hunk before anything is written, and Claude is told exactly what you accepted. Works even with write tools off — the review is the permission.
- Inline rewrite in the editor — select text, then *Rewrite selection with
Claude…* (command palette or right-click menu): pick a preset (improve, grammar, shorten, expand, tone) or type your own instruction, and review the result as the same per-hunk diff before it lands. No chat round-trip.
- Link suggestions while you write — the Related panel surfaces **unlinked
mentions (note titles and aliases sitting in your prose as plain text) with one-click linking, or Review & link all as a single diff. A Connections** section lists the note's one-hop graph neighborhood — backlinks, outgoing links, and typed ontology relations — as grouped lists. No embeddings needed for either; they work alongside the semantic related-notes list.
- Consolidated memory — merge captured session digests into one evolving
"What Claude Knows" note (manual command or auto after each capture). It's a normal note — agent mode reads it back with its own tools, so Claude remembers your projects, decisions, and preferences across chats.
- Never lose functionality (offline) — an Auto backend transparently
falls back to a local Ollama model when Claude is offline or out of usage, with a live connectivity indicator; or run Local only for full offline use. Cheap utility work (summaries, auto-tagging) can route to Ollama too — on its own smaller model if you like. Any OpenAI-compatible endpoint (LM Studio, mlx-lm, vLLM) can serve chat, utility work, or embeddings instead.
- Agent bridge — optionally expose the vault as a local MCP server so Claude
Code and Claude Desktop operate on the same notes (details below).
- Cloud sessions (mobile-friendly) — dispatch a Claude Code **cloud
session** that works your vault's Git repo and writes replies back as notes pulled over HTTPS — the agent path that works from a phone, where the local bridge can't run. Experimental (Anthropic's Routines API is in beta); setup is a guided checklist under *Agent in the cloud* in settings.
| !A prioritized roadmap artifact generated from the vault | !A generated working map of the vault |
|---|---|
| *A prioritized roadmap artifact, produced by an advisor persona surveying the vault over the bridge.* | *A generated working map — a canvas-style overview built from real notes.* |
Typed sources & ontology (on by default)
- Typed source capture — watch a clippings
inbox (default Clippings/) and enrich new clips with typed frontmatter (article, video, dataset) from per-type schemas. Auto-enrichment asks for one-time consent first (it sends each new inbox file to your utility model); the *Enrich note as source* command works manually either way. Enrichment preserves the Markdown body and existing metadata, unions tags, and validates the final title, summary, schema fields, and source provenance before the atomic vault write.
- Clipper schema sync — export Web Clipper templates generated from those
schemas (command or *Source capture* settings). Imported into the official Web Clipper, clips arrive already typed with everything the page knows; enrichment only fills what it couldn't.
- Source inbox — a touch-first triage view of everything in the inbox that
isn't typed yet, with one-tap enrich and *Enrich all*. Enriched notes with unlinked mentions can be reviewed together through *Review all links*: one collapsed accordion per note, selectable by note or hunk, with conflicts and failures isolated. Built for clipping from your phone.
- Organize clippings — one command takes the existing pile: every clip is
enriched (meaningful title, tags, summary), a batch model call infers a domain/project folder per clip (preferring your existing folders), and a review modal shows each old path → new path before accepted moves rename and file clips into <Organized folder>/<domain>/ (default Library/), collision-safe, with links updated.
- Vault ontology — schema notes in an
Ontology/ folder define note types and typed wikilink relations; on first run Companion offers to create the default schemas (or run Seed ontology any time), and notes Claude creates conform to your schemas (advisory, never blocking). Configure under *Vault ontology* in settings.
Install
From the community store (recommended): *Settings → Community plugins → Browse* → search Companion for Claude → Install → Enable, or use this direct link. Then open *Settings → Companion for Claude* and paste your Anthropic API key.
From source (development):
cd obsidian-plugin && pnpm install && pnpm run build- Copy
main.js,manifest.json, andstyles.cssinto
<your-vault>/.obsidian/plugins/claude-companion/.
- Enable Companion for Claude in *Settings → Community plugins*.
For active development use pnpm run dev (esbuild watch) and symlink the plugin folder into a test vault.
Desktop agents: CLI first, MCP when needed
Companion, its in-app agent, and ordinary Claude Code workflows do not require MCP. From Options → Desktop integrations on any Companion page:
- Set up Claude Code verifies the
claudeand officialobsidianCLIs,
then can add cavi-ai/plugins and install obsidian-agent@cavi-ai at user scope after explicit confirmation. Claude Code uses the official Obsidian CLI by default.
- Connect Claude Desktop enables the read-only loopback MCP bridge, backs up
and atomically merges Claude Desktop's local configuration, and verifies the bridge. Restart Claude Desktop afterward.
MCP remains optional for Claude Desktop and advanced clients that need Companion-specific live research, semantic-search, ontology, or controlled-write tools. It is off by default; the build handoff uses the official obsidian CLI whenever the bridge is disabled.
Enable it in *Settings → Companion for Claude → Agent bridge — MCP server (desktop)*. The server binds to 127.0.0.1 only (never the network), requires a bearer token, and shows ready-to-paste connection snippets for both clients.
| Read tools (always exposed) | Write tools (require *Allow writes*) |
|---|---|
vault_search | note_create |
note_read | note_append |
list_recent | note_update |
vault_tags | update_frontmatter |
list_titles | note_move |
get_backlinks | base_create |
get_outgoing_links | canvas_create |
frontmatter_query | research_project_create |
research_project_read | research_source_import |
research_audit | research_evidence_capture |
research_evidence_review | |
research_claim_create | |
research_claim_link | |
research_outline_generate |
That is 10 always-available read/audit tools and 14 write-gated mutation tools (24 advertised tools when writes are enabled), plus the optional web_search and web_fetch read tools when enabled in settings. Research Workbench reads and audits remain available with writes disabled. Creating projects, importing sources, capturing or reviewing evidence, creating or linking claims, and generating outlines requires *Allow writes*; agent mode also keeps its normal per-action confirmation gate. Evidence review applies only to evidence records and accepts reviewed or rejected.
Permanent legacy aliases remain callable for compatibility, but are intentionally not advertised as user-facing commands. This does not change the bridge security boundary: it remains loopback-only and requires a non-empty bearer token.
With *Vault ontology* enabled, note_create also accepts type / properties for schema-conformant typed notes.
Advanced Claude Code MCP connection:
claude mcp add --transport http obsidian-vault \
http://127.0.0.1:22360/mcp --header "Authorization: Bearer <token>"Claude Desktop (claude_desktop_config.json, via mcp-remote):
{
"mcpServers": {
"obsidian-vault": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://127.0.0.1:22360/mcp",
"--header", "Authorization: Bearer <token>"]
}
}
}Now ask Claude Code "search my vault for X" or "create a note summarizing this" and it operates directly on your Obsidian notes.
What leaves your machine
Every request below is triggered by something you do — there is no telemetry, no analytics, and no background polling of any third party.
| Destination | Sent when | Carries |
|---|---|---|
api.anthropic.com (or your API base URL override) | every chat, agent, and utility turn | your prompt, attached vault context, and the system prompt |
| your Ollama host / OpenAI-compatible endpoint | only while a local backend is selected | the same request, to a server you run |
huggingface.co and cdn.jsdelivr.net | the one-time built-in embedding download, after you click Download | nothing but the model and ONNX-runtime requests; cached and offline afterwards |
your routine fire URL (an api.anthropic.com endpoint by default) | the Send to cloud Claude session command, when cloud dispatch is on | your prompt and attached note context |
api.github.com | Cloud replies pull, and only with a token you set | repo, branch, and folder you configured |
api.openalex.org, api.crossref.org, export.arxiv.org, api.zotero.org | an explicit Discover action in the Research Workbench | your search terms, plus the OpenAlex contact email if you set one |
| the page you ask to capture | web capture and the agent's web_fetch tool | the URL you gave |
html.duckduckgo.com (or api.search.brave.com) | the agent's web_search tool, when enabled | your search query |
| an MCP server you configure yourself | tool calls you confirm | the tool arguments |
Web capture uses the bundled defuddle extractors, which reach two extra site-specific endpoints when you capture from those sites: c2.com (wiki page source) and youtube.com (transcript API).
WebAssembly. Two families ship inside main.js. ort-wasm-simd-threaded*.wasm is the ONNX runtime behind built-in embeddings — fetched from cdn.jsdelivr.net during the consented model download and cached in the Cache API. qcms_bg.wasm, jbig2.wasm, and openjpeg.wasm belong to pdfjs-dist; Companion loads PDFs with getDocument({ data }) and never sets wasmUrl, so those image-decode paths have no URL to fetch and no external host.
Base64. One runtime atob in the plugin's own code, decoding GitHub's base64-encoded file payloads when pulling cloud replies. Other occurrences belong to bundled dependencies.
Shell execution. Desktop only, always execFile/spawn with an argument array — never a shell string: opening an artifact in your chosen browser, running stdio MCP servers you configure, and the Obsidian / Claude CLI used by Desktop integrations. All of it is disabled on mobile.
Your vault. Semantic search and vault search enumerate every file to build a local index; nothing about that index leaves the device. Copy buttons write to the system clipboard. Credentials live in Obsidian's encrypted secret storage, never in data.json.
How artifacts work
When Claude returns a fenced ``` `claude-html `` block, Companion renders the document inside a **sandboxed** iframe (allow-scripts but **not** allow-same-origin) — interactions and scripts run, but the artifact can't touch your vault or cookies. A restrictive iframe CSP also blocks network calls and form submissions. Set a height per-block with ``claude-html height=720 .
Saving an artifact writes a Markdown note containing that same block, so the artifact lives in your vault, renders in Reading view, and travels with your notes.
The claude-html block
You can author these by hand too:
```claude-html height=600
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>Hello</title></head>
<body style="font-family:ui-serif;background:#FAF9F5;padding:40px">
<h1 style="color:#141413">It renders inline.</h1>
</body></html>
```Development and testing
The Obsidian-free logic (SSE parsing, artifact extraction, search scoring) is factored into pure modules so it can be unit-tested without a running app.
pnpm run typecheck # tsc --noEmit
pnpm run lint # eslint
pnpm test # vitest (unit tests in test/)
pnpm run build # typecheck + production bundleCI runs all four on every push/PR (Node 20 & 22) in the monorepo. A manual smoke-test checklist lives in `CONTRIBUTING.md`.
Releases
| Store listing | Companion for Claude (claude-companion) |
| Source of truth | `cavi-ai/claude-obsidian` monorepo, obsidian-plugin/ |
| Release repo | `cavi-ai/companion-for-claude` — built main.js, manifest.json, styles.css attached per release |
| Versioning | manifest.json = versions.json = package.json = git tag (exact version, no v prefix) |
Releases are cut by the monorepo's release workflow, which runs the release gate (typecheck, lint, tests, build) and the version-lockstep check, mirrors the plugin to the release repo, and publishes the tagged GitHub release the store serves.
License
MIT — see `LICENSE`.