Local AI + Obsidian Canvas: Build Visual Thinking Maps Privately
Want to go deeper than this article?
The AI Learning Path covers this topic and more — hands-on chapters across 10 courses across 10 courses.
Local AI + Obsidian Canvas: Build Visual Thinking Maps Privately
Published on April 23, 2026 • 17 min read
Obsidian Canvas is the most under-used feature in personal knowledge management. It is a freeform whiteboard that lives inside your vault, where every card is either a note, a webpage, an image, or a piece of text — and where any line you draw between two cards becomes a piece of structure your brain can use later. The trick is that nothing in the default Canvas connects to AI. So most people end up using it as a static brainstorming tool, which is fine but does not earn its weight against a paper notebook.
Wire a local model in, and Canvas becomes something different. You drop a question into a card. The model reads the surrounding cards as context and spits out three branching responses, each in its own new card, automatically positioned around the original. Highlight a cluster of cards, ask "summarize these into a thesis," and a synthesis card appears connected to all of them. Drag a note from your vault onto the canvas, and the model proposes the four most relevant other notes from your library to add. None of it touches the cloud.
This guide is the exact setup. Two Obsidian plugins, a small JSONCanvas script, Ollama with a 7B model, and Smart Connections for embeddings. By the end you will have a private visual thinking environment that nobody is shipping commercially, because nobody can profitably ship something this specific to one user's notes.
Quick Start: AI in Your Canvas in 20 Minutes {#quick-start}
If you only want the working setup:
- Install Ollama:
brew install ollama(Mac) or follow the Linux/Windows installer. - Pull the model:
ollama pull qwen2.5:7b(4.4 GB). - In Obsidian, install Copilot for Obsidian (community plugin) and Smart Connections.
- Configure Copilot: model provider Ollama, base URL http://127.0.0.1:11434, model qwen2.5:7b.
- Open a Canvas, select a card, run "Copilot: Ask AI on selection." The response opens in a new card.
- Drop the JSONCanvas script (below) into
~/scripts/canvas-expand.pyand bind it to a hotkey.
That's the working AI Canvas. The rest of this guide makes it actually useful for thinking.
Table of Contents
- Why Canvas Plus Local AI Is Different
- The Stack
- Hardware Reality Check
- Step 1 — Install Ollama and Pull Models
- Step 2 — Configure Copilot for Obsidian
- Step 3 — Smart Connections for Vault Embeddings
- Step 4 — Programmatic Canvas Expansion via JSONCanvas
- Five Workflows That Work
- Prompt Patterns Per Node Type
- Pitfalls and Performance
- Comparison: Cloud Plugins vs Local Stack
- FAQ
Why Canvas Plus Local AI Is Different {#why-canvas}
Three things make this combination meaningful instead of gimmicky:
1. Spatial reasoning is a different skill from prose writing. When you can see five ideas on a canvas with lines drawn between them, you notice gaps and contradictions that linear writing hides. The model becomes a collaborator that respects spatial structure: it sees what's near what, what's connected to what, and answers in a way that fits.
2. Your vault is the corpus, not the model's training data. A model with access to your last six years of notes via Smart Connections produces dramatically more relevant suggestions than a generic LLM. When the AI proposes adding a card linking the current canvas to an essay you wrote in 2022, that's only possible because the embeddings know your library.
3. The output stays in the same file system as the input. A Canvas file is just JSON. Cards generated by the AI become real cards. Notes the AI proposes become real notes. Nothing lives behind a SaaS API. You can rsync the whole thing to an external drive and it still works.
Cloud plugins like Smart Composer and Text Generator can do versions of this — but every keystroke goes to OpenAI or Anthropic. With a local stack, the equivalent loop is: keystroke, your laptop, response. Period.
The Stack {#the-stack}
| Layer | Tool | Job |
|---|---|---|
| Model engine | Ollama | Runs LLMs locally |
| Reasoning model | Qwen 2.5 7B | Card expansion, summarization |
| Drafting model | Llama 3.2 3B | Faster lightweight tasks |
| Embeddings | nomic-embed-text via Ollama | Semantic similarity for Smart Connections |
| Canvas integration | Copilot for Obsidian | Right-click and command palette AI |
| Vault search | Smart Connections plugin | Surfaces related notes by meaning |
| Canvas automation | Python + JSONCanvas spec | Bulk operations on canvases |
| Optional voice | whisper.cpp | "Talk to a card" transcription |
Total cost: $0. All open source. Disk footprint: ~7 GB after pulling models.
The JSONCanvas spec is an open file format documented at jsoncanvas.org and is what makes programmatic canvas manipulation possible without reverse-engineering Obsidian internals.
Hardware Reality Check {#hardware}
I tested the stack on five machines while writing this. Real numbers:
| Machine | RAM | Card expansion (1 → 3 cards) | Canvas summary (12 cards) | Verdict |
|---|---|---|---|---|
| MacBook Air M1 16 GB | 16 GB | 4-6 sec | 18 sec | Recommended floor |
| MacBook Pro M2 Pro 32 GB | 32 GB | 2-3 sec | 8 sec | Sweet spot |
| Mac Mini M2 Pro 32 GB | 32 GB | 2-3 sec | 8 sec | Best per dollar |
| ThinkPad T14 Gen 3 (i7, 32 GB) | 32 GB | 7-12 sec | 28 sec | Adequate |
| Beelink SER5 (5800H, 32 GB) | 32 GB | 8-14 sec | 35 sec | Adequate |
Floor: anything with 16 GB RAM and a CPU from 2020 or later. Below that the model swaps and the experience falls apart. Apple Silicon noticeably outperforms x86 at this workload because of unified memory.
Step 1 — Install Ollama and Pull Models {#install-ollama}
Same commands as every local AI guide, but the model selection matters here:
# Mac
brew install ollama
brew services start ollama
# Linux
curl -fsSL https://ollama.com/install.sh | sh
sudo systemctl enable --now ollama
# Pull the canvas models
ollama pull qwen2.5:7b # Primary reasoning (4.4 GB)
ollama pull llama3.2:3b # Fast lightweight tasks (2.0 GB)
ollama pull nomic-embed-text # Embeddings for Smart Connections (274 MB)
Verify Ollama is reachable from Obsidian:
curl http://127.0.0.1:11434/api/tags
If you get JSON listing the models, you are ready for the plugin layer. For broader Ollama setup, see the Mac local AI setup guide or the Linux local AI setup.
Step 2 — Configure Copilot for Obsidian {#copilot-plugin}
Open Obsidian. Settings > Community plugins > Browse > search "Copilot for Obsidian" by Logan Yang. Install and enable.
Configuration:
-
Default chat model: Add a custom model with these settings:
- Provider:
OllamaServer - Model:
qwen2.5:7b - Base URL:
http://127.0.0.1:11434 - Display name:
Local Qwen 7B
- Provider:
-
Embedding model: Add another custom entry:
- Provider:
OllamaServer - Model:
nomic-embed-text - Base URL:
http://127.0.0.1:11434
- Provider:
-
Default mode: Set "Default chat mode" to "QA" so questions automatically use vault context.
-
Hotkey: In Obsidian's hotkey settings, bind "Copilot: Open Copilot Chat" to something fast (I use
Cmd+Shift+L). Bind "Copilot: Quick action — Ask Copilot" toCmd+Shift+K.
The critical test: open any note, select a sentence, hit your "Ask Copilot" hotkey. If a response streams in within a few seconds, the wiring is correct. If you get a connection error, Ollama is not running — brew services restart ollama or ollama serve in a terminal.
Step 3 — Smart Connections for Vault Embeddings {#smart-connections}
Smart Connections is the plugin that makes the AI aware of your whole vault, not just the current canvas.
Install: Community plugins > Browse > search "Smart Connections" by Brian Petro. Install, enable.
Configuration:
- Embedding model:
Ollama: nomic-embed-textwith base URLhttp://127.0.0.1:11434. - Indexing: First run will index your entire vault. For a 1,500-note vault, expect ~10-15 minutes on Apple Silicon, ~20-30 minutes on x86.
- Folder filters: Exclude folders that should never surface in AI context —
templates/,daily-journal/, anything personal.
Once indexed, the Smart Connections side panel shows the most semantically similar notes for whatever you have open. On a canvas, this is gold: select any card, the panel shows your five most-related notes from anywhere in the vault. Drag any of them onto the canvas to attach.
For broader vault-AI patterns, see the local AI + Obsidian integration guide.
Step 4 — Programmatic Canvas Expansion via JSONCanvas {#jsoncanvas-script}
Copilot handles ad-hoc card-level AI well, but for repeatable workflows you want a script. Obsidian Canvas files are valid JSON conforming to the JSONCanvas spec. We can read them, generate new nodes, and write them back.
Save this as ~/scripts/canvas-expand.py:
#!/usr/bin/env python3
"""Expand the most recently edited card in a canvas into 3 child cards."""
import json
import sys
import uuid
import subprocess
from pathlib import Path
CANVAS_PATH = Path(sys.argv[1])
OLLAMA_MODEL = "qwen2.5:7b"
data = json.loads(CANVAS_PATH.read_text())
# Find the most recent text card by ID alphabetical (canvas IDs sort by time)
text_nodes = [n for n in data["nodes"] if n["type"] == "text"]
if not text_nodes:
sys.exit("No text nodes in canvas")
source = sorted(text_nodes, key=lambda n: n["id"])[-1]
prompt = f"""Read the following idea card. Generate exactly THREE short follow-up
ideas, each one a single tight paragraph. Output them as a JSON array of strings.
Output ONLY the JSON array, no preamble.
Card content:
{source['text']}"""
result = subprocess.run(
["ollama", "run", OLLAMA_MODEL, prompt],
capture_output=True, text=True, timeout=120
)
new_texts = json.loads(result.stdout.strip())
# Position three children to the right of the source
sx, sy = source["x"], source["y"]
sw, sh = source.get("width", 250), source.get("height", 60)
for i, txt in enumerate(new_texts):
new_id = uuid.uuid4().hex[:16]
data["nodes"].append({
"id": new_id,
"type": "text",
"text": txt,
"x": sx + sw + 80,
"y": sy + (i - 1) * (sh + 40),
"width": sw,
"height": sh,
"color": "4",
})
data.setdefault("edges", []).append({
"id": uuid.uuid4().hex[:16],
"fromNode": source["id"],
"fromSide": "right",
"toNode": new_id,
"toSide": "left",
})
CANVAS_PATH.write_text(json.dumps(data, indent=2))
print(f"Added 3 cards to {CANVAS_PATH.name}")
Make it executable: chmod +x ~/scripts/canvas-expand.py. Bind it to a system-level hotkey using Hammerspoon (Mac), AutoHotkey (Windows), or sxhkd (Linux). The hotkey runs the script against the active canvas file.
The result: select a card, hit the hotkey, three connected child cards appear within seconds. This is the single most useful feature in the whole stack.
For other Canvas automation patterns, see the JSONCanvas spec on GitHub.
Five Workflows That Work {#workflows}
These are the workflows I run weekly. Each one represents a real productivity unlock over plain Canvas.
Workflow 1 — Topic exploration
Drop a single card with a topic. Run the canvas-expand script three times. You now have 9 child cards. Read them, delete the bad ones, expand the good ones again. After ~10 minutes you have a 30-40 card map of the territory you didn't have before. This is dramatically faster than typing-driven brainstorming because your hands aren't the bottleneck.
Workflow 2 — Cluster summarization
Select multiple cards on a canvas. Use Copilot's "Ask Copilot on selection" with the prompt template:
"Read the following cards. Identify the underlying thesis they collectively point toward. Output a single paragraph that could serve as the summary card for this cluster."
The new card opens. Drag it to the visual center of the cluster, draw lines from the cluster cards to it. You now have an emergent thesis you didn't articulate yourself.
Workflow 3 — Note-suggestion drag
Select a cluster of cards on the canvas. Open Smart Connections side panel. The five most-related vault notes appear. Drag the relevant ones onto the canvas. The model just connected your current thinking to your past thinking.
Workflow 4 — Counter-argument generation
For any card containing a claim, run the prompt:
"Generate the strongest possible counter-argument to this card, in two sentences. Then generate the steelman version of that counter-argument in two more sentences."
Two cards appear. Connect them to the original. Your canvas now has built-in dialectical structure.
Workflow 5 — Outline export
Select an entire canvas (Cmd+A) and run:
"These cards form a knowledge map. Convert them into a hierarchical outline in Markdown, ordered for a long-form essay. Use the spatial layout (cards close to each other belong in the same section) and the edges (arrows indicate logical flow) as input."
The output is a usable outline you can drop into a new note. The cards on the canvas remain as the source of truth; the outline is just an alternate view.
Prompt Patterns Per Node Type {#prompts}
Different card types call for different prompts. These are the templates I use:
Question card → Three-answer expansion
"Treat the following as a question. Generate three substantively different answers, each in two sentences. Output as JSON array of strings."
Claim card → Evidence and challenge
"Treat this as a claim. Generate two cards: one with the strongest piece of supporting evidence, one with the strongest challenge. Output as JSON: {"evidence": "...", "challenge": "..."}."
Quote card → Five-why expansion
"Treat this as a quote. Apply five-whys to surface the underlying assumption. Output as a JSON array of five strings, each one tightening the question."
List card → Categorization
"Cluster the items in this list into 3-5 named groups. Output as JSON: [{"group": "name", "items": [...]}, ...]."
Definition card → Examples and counterexamples
"Generate two cards: one card with three concrete examples that fit this definition, one card with two near-misses that do not. Output as JSON."
Save these in your vault at templates/canvas-prompts.md. Copy and paste into Copilot when you need them. After a few weeks the patterns become muscle memory.
Pitfalls and Performance {#pitfalls}
Pitfall 1: Long contexts kill performance. A canvas with 60+ text cards passed wholesale to a 7B model produces slow, mediocre output. Constrain context: only the selection plus its first-degree neighbors.
Pitfall 2: Cards that contain entire essays. A 2,000-word card pasted into a prompt eats the model's working memory. Either summarize the card first, or explicitly tell the model "summarize this card before reasoning about it."
Pitfall 3: JSONCanvas position math. When the script generates child cards, hard-coded x/y offsets work for the first three cards but pile up if you run the script repeatedly. Add a layout pass that scans existing cards and finds free space before placing.
Pitfall 4: Smart Connections re-indexing on every model swap. If you change the embedding model, you must re-index the entire vault. nomic-embed-text is fine; do not switch lightly.
Pitfall 5: Network restrictions block plugins. Some plugins phone home for telemetry on first run. If you're trying to run fully offline, audit each plugin's network calls. The two plugins recommended here (Copilot for Obsidian, Smart Connections) work entirely against your local Ollama once configured.
Comparison: Cloud Plugins vs Local Stack {#comparison}
| Capability | Cloud (e.g. Smart Composer w/ OpenAI) | Local Stack |
|---|---|---|
| Card expansion | Yes | Yes |
| Vault-aware retrieval | Yes (sends notes to cloud) | Yes (stays local) |
| Privacy | OpenAI sees vault content | Vault never leaves machine |
| Cost | $5-20/mo + API per call | $0 |
| Offline mode | No | Yes |
| Speed (small tasks) | 1-2 sec | 2-6 sec |
| Speed (long synthesis) | 5-10 sec | 8-30 sec |
| Custom prompts | Yes | Yes |
| Programmatic Canvas manipulation | Possible | Easier (no API rate limits) |
The cloud option is faster on long tasks if you're willing to send your vault to OpenAI and pay per token. For most thinkers, the privacy and zero-cost properties of the local stack matter more than the 2-3 second speed difference on big synthesis prompts.
FAQ {#faq}
(See FAQ section below — schema-rendered for Google.)
Where This Goes Next
Once the AI Canvas is working, the natural extensions:
- Local AI + Obsidian: full vault Q&A with AnythingLLM — chat with your entire library, not just one canvas.
- Best Ollama clients — alternatives if Copilot for Obsidian doesn't fit.
- Local AI privacy guide — the broader case for self-hosted thinking tools.
A canvas is a thinking partner that respects spatial structure. A local model is a thinking partner that respects privacy. Putting them together gives you a thinking environment that does not exist in any commercial product, because the value comes from the combination of your specific vault and your specific way of arranging things on a 2D plane. The closest thing on the market — Smart Composer with GPT-4 — is faster, but it does not know your library and it does not stay on your machine. The setup above does both, and after a couple of weeks of use it becomes the place I do my hardest thinking.
Go from reading about AI to building with AI
10 structured courses. Hands-on projects. Runs on your machine. Start free.
Enjoyed this? There are 10 full courses waiting.
10 complete AI courses. From fundamentals to production. Everything runs on your hardware.
Build Real AI on Your Machine
RAG, agents, NLP, vision, and MLOps - chapters across 10 courses that take you from reading about AI to building AI.
Want structured AI education?
10 courses, 160+ chapters, from $9. Understand AI, don't just use it.
Continue Your Local AI Journey
Comments (0)
No comments yet. Be the first to share your thoughts!