| name | napkin |
| description | Read, create, search, and manage notes in Obsidian vaults using the napkin CLI. Works directly on markdown files and canvas files — no Obsidian app required. Use when the user asks to interact with their Obsidian vault, manage notes, search vault content, work with tasks, tags, properties, daily notes, templates, bases, bookmarks, aliases, or canvas files from the command line. |
napkin
CLI for Obsidian vaults. Operates directly on markdown files — no Obsidian app, no Electron, no Catalyst license.
Install: npm install -g napkin-ai
Vault Structure
.napkin/ is the config directory. Content lives at the vault root alongside it:
my-vault/ # Vault root
.napkin/ # Config only
config.json # Unified config (syncs to .obsidian/)
.obsidian/ # Obsidian compatibility (auto-generated)
NAPKIN.md # Context note (Level 0)
Templates/ # Note templates
decisions/ # Template-defined directories
architecture/
guides/
Progressive Disclosure
napkin reveals information gradually — overview first, then search, then read:
| Level | Command | What it does |
|---|
| L0 | NAPKIN.md | Project context note |
| L1 | napkin overview | L0 + vault map with TF-IDF keywords per folder |
| L2 | napkin search <query> | BM25 + backlinks + recency ranked results with snippets |
| L3 | napkin read <file> | Full file content |
Workflow: overview → search → read
Initialize
napkin init
napkin init --template coding
napkin init --template company
napkin init --template product
napkin init --template personal
napkin init --template research
napkin init --list
napkin init --path /some/dir
Each template includes directory structure, _about.md files, Obsidian note templates, and a NAPKIN.md skeleton.
Overview & Graph
napkin overview
napkin overview --depth 3
napkin overview --keywords 5
napkin graph
Config
napkin config show
napkin config get --key search.limit
napkin config set --key search.limit --value 50
Syntax
Commands accept positional arguments. Quote values with spaces:
napkin create "My Note" "Hello world"
napkin append "My Note" "More text"
echo "piped content" | napkin append "My Note"
Flags also work (backward compatible):
napkin create --name "My Note" --content "Hello world"
Global flags
| Flag | Description |
|---|
--json | Output as JSON (use this for programmatic access) |
-q, --quiet | Suppress output |
--vault <path> | Vault path (default: auto-detect by walking up from cwd looking for .napkin/) |
--copy | Copy output to clipboard |
File targeting
- Positional
<file> or --file <name> — resolves like a wikilink (name only, no path or extension needed)
--path <path> — exact path from vault root, e.g. Projects/note.md
Commands
Vault
napkin vault
napkin version
Files & folders — napkin file
napkin file info <name>
napkin file list
napkin file list --ext md
napkin file list --folder Projects
napkin file list --total
napkin file folder <path>
napkin file folder <path> --info files
napkin file folders
napkin file folders --total
Read & write
napkin read "Note"
napkin create "Note" "# Hello"
napkin create "Note" --path "Projects" --template "Meeting Note"
napkin append "Note" "New line at end"
napkin prepend "Note" "New line after frontmatter"
napkin move "Note" Archive
napkin rename "Note" "Renamed Note"
napkin delete "Note"
napkin delete "Note" --permanent
Daily notes — napkin daily
Reads config from .napkin/.obsidian/daily-notes.json (folder, format, template).
napkin daily today
napkin daily path
napkin daily read
napkin daily append "- [ ] Buy groceries"
napkin daily prepend "## Morning"
Search
Ranked search using BM25 + backlinks + recency. Returns snippets with context by default.
napkin search "meeting"
napkin search --query "meeting"
napkin search "TODO" --path Projects
napkin search "bug" --total
napkin search "deploy" --limit 5
napkin search "TODO" --no-snippets
napkin search "deploy" --snippet-lines 3
napkin search "auth" --score
Tasks — napkin task
napkin task list
napkin task list --todo
napkin task list --done
napkin task list --daily
napkin task list --file "Project A"
napkin task list --verbose
napkin task list --total
napkin task show --file "note" --line 3
napkin task show --file "note" --line 3 --toggle
napkin task show --file "note" --line 3 --done
napkin task show --ref "note.md:3" --todo
Tags — napkin tag
napkin tag list
napkin tag list --counts
napkin tag list --sort count
napkin tag info --name "project"
napkin tag info --name "project" --verbose
napkin tag aliases
napkin tag aliases --file "note"
napkin tag aliases --total
Properties — napkin property
napkin property list
napkin property list --file "note"
napkin property list --counts
napkin property read --file "note" --name title
napkin property set --file "note" --name status --value done
napkin property remove --file "note" --name status
Links — napkin link
napkin link back --file "note"
napkin link out --file "note"
napkin link unresolved
napkin link orphans
napkin link deadends
Outline
napkin file outline "note"
napkin file outline "note" --format md
napkin file outline "note" --format json
Templates — napkin template
napkin template list
napkin template read --name "Daily Note"
napkin template read --name "Meeting" --resolve --title "Standup"
napkin template insert --file "note" --name "Template"
Bookmarks — napkin bookmark
napkin bookmark list
napkin bookmark list --total
napkin bookmark add --file "note"
napkin bookmark add --folder "Projects"
napkin bookmark add --search "TODO"
napkin bookmark add --url "https://example.com" --title "Example"
Bases — napkin base
Query vault files using Obsidian Bases .base files (YAML-defined filters over frontmatter properties, powered by SQLite in-memory).
napkin base list
napkin base views --file "projects"
napkin base query --file "projects"
napkin base query --file "projects" --view "Active"
napkin base query --file "projects" --format paths
napkin base query --file "projects" --format csv
napkin base create --file "projects" --name "New Item"
Canvas — napkin canvas
Read and write JSON Canvas files (.canvas) — nodes, edges, groups.
napkin canvas list
napkin canvas list --total
napkin canvas read --file "Board"
napkin canvas nodes --file "Board"
napkin canvas nodes --file "Board" --type text
napkin canvas create --file "Board"
napkin canvas create --file "Board" --path "Projects"
napkin canvas add-node --file "Board" --type text --text "# Hello"
napkin canvas add-node --file "Board" --type file --note-file "Notes/note.md"
napkin canvas add-node --file "Board" --type link --url "https://example.com"
napkin canvas add-node --file "Board" --type group --label "My Group"
napkin canvas add-node --file "Board" --type text --text "Positioned" --x 100 --y 200
napkin canvas add-edge --file "Board" --from abc1 --to def2 --label "relates to"
napkin canvas remove-node --file "Board" --id abc1
Node IDs are 16-char hex. --from/--to/--id accept ID prefixes for convenience.
Node types: text, file, link, group. Colors: 1-6 or hex.
New nodes auto-position to the right of existing content.
Word count
napkin file wordcount "note"
napkin file wordcount "note" --words
napkin file wordcount "note" --characters
Agent onboarding
napkin onboard
JSON output
Every command supports --json. Always use --json for programmatic access:
napkin task list --todo --json
napkin search "deploy" --json
napkin property read --file "note" --name status --json
Common workflows
Morning standup prep
napkin daily read --json
napkin task list --todo --json
napkin search "blocker" --json
Project overview
napkin file list --folder Projects --json
napkin tag list --counts --json
napkin link orphans --json
napkin link unresolved --json
Note management
napkin create --name "Meeting Notes" --template "Meeting Note" --path "Meetings"
napkin property set --file "Meeting Notes" --name attendees --value "Alice, Bob"
napkin append --file "Meeting Notes" --content "- [ ] Follow up on deployment"
Obsidian Markdown Reference
napkin operates on Obsidian Flavored Markdown files. This section covers the syntax for creating valid content.
Properties (frontmatter)
YAML frontmatter at the start of a note:
---
title: My Note
date: 2024-01-15
tags:
- project
- important
aliases:
- My Note
- Alternative Name
cssclasses:
- custom-class
status: in-progress
rating: 4.5
completed: false
---
Property types
| Type | Example |
|---|
| Text | title: My Title |
| Number | rating: 4.5 |
| Checkbox | completed: true |
| Date | date: 2024-01-15 |
| Date & Time | due: 2024-01-15T14:30:00 |
| List | tags: [one, two] or YAML list |
| Links | related: "[[Other Note]]" |
Default properties: tags, aliases, cssclasses
Internal links (wikilinks)
[[Note Name]] Link to note
[[Note Name|Display Text]] Custom display text
[[Note Name#Heading]] Link to heading
[[Note Name#^block-id]] Link to block
[[#Heading in same note]] Same-file heading link
Embeds
![[Note Name]] Embed entire note
![[Note Name#Heading]] Embed section
![[image.png]] Embed image
![[image.png|300]] Image with width
![[document.pdf]] Embed PDF
![[document.pdf#page=3]] PDF at page
Tags
#tag
#nested/tag
#tag-with-dashes
# In frontmatter:
tags:
- tag1
- nested/tag2
Tags can contain letters, numbers (not first), underscores, hyphens, forward slashes.
Task lists
- [ ] Incomplete task
- [x] Completed task
- [ ] Parent task
- [ ] Subtask
- [x] Done subtask
Callouts
> [!note]
> This is a note callout.
> [!warning] Custom Title
> Warning with custom title.
> [!faq]- Collapsed by default
> Hidden until expanded.
> [!tip]+ Expanded by default
> Visible but collapsible.
Callout types: note, abstract/summary/tldr, info, todo, tip/hint/important, success/check/done, question/help/faq, warning/caution/attention, failure/fail/missing, danger/error, bug, example, quote/cite
Text formatting
| Style | Syntax |
|---|
| Bold | **text** |
| Italic | *text* |
| Bold + Italic | ***text*** |
| Strikethrough | ~~text~~ |
| Highlight | ==text== |
| Inline code | `code` |
Code blocks
```javascript
function hello() {
console.log("Hello");
}
```
Math (LaTeX)
Inline: $e^{i\pi} + 1 = 0$
Block:
$$
\sum_{i=1}^{n} x_i
$$
Block references
This paragraph can be linked to. ^my-block-id
Link to it: [[Note#^my-block-id]]
Embed it: ![[Note#^my-block-id]]
Comments
This is visible %%but this is hidden%% text.
%%
This entire block is hidden.
%%
Bases Reference
Bases are YAML-defined views that query vault files using their frontmatter properties. Saved as .base files.
Structure
filters:
and:
- file.hasTag("project")
- 'status != "done"'
formulas:
days_left: '(date(due) - today()).days'
properties:
status:
displayName: Status
views:
- type: table
name: "Active"
order:
- file.name
- status
limit: 20
Filters
filters:
file.hasTag("project")
filters:
and:
- file.hasTag("project")
- 'status != "done"'
filters:
or:
- file.hasTag("book")
- file.hasTag("article")
filters:
not:
- file.hasTag("archived")
filters:
or:
- file.hasTag("urgent")
- and:
- file.hasTag("project")
- 'priority >= 3'
Filter operators
| Operator | Description |
|---|
== | equals |
!= | not equal |
> | greater than |
< | less than |
>= | greater than or equal |
<= | less than or equal |
File functions for filters
| Function | Description |
|---|
file.hasTag("tag1", "tag2") | Has any of the tags (includes nested) |
file.hasLink("Note") | Has link to note |
file.hasProperty("name") | Has frontmatter property |
file.inFolder("Projects") | In folder or subfolder |
File properties
| Property | Type | Description |
|---|
file.name | String | File name |
file.basename | String | Name without extension |
file.path | String | Full path from vault root |
file.folder | String | Parent folder path |
file.ext | String | File extension |
file.size | Number | Size in bytes |
file.ctime | Date | Created time |
file.mtime | Date | Modified time |
file.tags | List | All tags |
file.links | List | Internal links |
Note properties
Frontmatter properties accessed as note.property or just property:
filters:
and:
- 'status == "active"'
- 'note.priority >= 3'
Formulas
formulas:
total: "price * quantity"
status_icon: 'if(done, "✅", "⏳")'
formatted_price: 'if(price, price.toFixed(2) + " dollars")'
created: 'file.ctime.format("YYYY-MM-DD")'
days_old: '(now() - file.ctime).days'
days_until_due: 'if(due_date, (date(due_date) - today()).days, "")'
Global functions
| Function | Description |
|---|
date(string) | Parse date (YYYY-MM-DD HH:mm:ss) |
now() | Current datetime |
today() | Current date (time = 00:00:00) |
if(cond, true, false?) | Conditional |
min(n1, n2, ...) | Smallest number |
max(n1, n2, ...) | Largest number |
number(any) | Convert to number |
link(path, display?) | Create link |
list(element) | Wrap in list |
Date arithmetic
"date + \"1M\""
"now() + \"1 day\""
"today() + \"7d\""
"(now() - file.ctime).days"
Duration units: y/year/years, M/month/months, d/day/days, w/week/weeks, h/hour/hours, m/minute/minutes, s/second/seconds
String functions
contains(), startsWith(), endsWith(), lower(), trim(), replace(), split(), slice(), isEmpty(), .length
Number functions
abs(), ceil(), floor(), round(digits?), toFixed(precision)
List functions
contains(), filter(), map(), join(), sort(), unique(), flat(), isEmpty(), .length
Views
views:
- type: table
name: "My View"
limit: 10
order:
- file.name
- status
- due_date
filters:
'status != "done"'
groupBy:
property: status
direction: ASC
summaries:
price: Sum
count: Average
Summary functions
| Name | Input | Description |
|---|
Average | Number | Mean |
Min | Number | Smallest |
Max | Number | Largest |
Sum | Number | Sum |
Range | Number | Max - Min |
Median | Number | Median |
Earliest | Date | Earliest date |
Latest | Date | Latest date |
Empty | Any | Count of empty values |
Filled | Any | Count of non-empty values |
Unique | Any | Count of unique values |
Example: Task tracker
filters:
and:
- file.hasTag("task")
- 'file.ext == "md"'
formulas:
days_until_due: 'if(due, (date(due) - today()).days, "")'
priority_label: 'if(priority == 1, "🔴 High", if(priority == 2, "🟡 Medium", "🟢 Low"))'
views:
- type: table
name: "Active Tasks"
filters:
and:
- 'status != "done"'
order:
- file.name
- status
- formula.priority_label
- due
- formula.days_until_due
groupBy:
property: status
direction: ASC
JSON Canvas Reference
Canvas files (.canvas) are JSON following the JSON Canvas Spec 1.0.
{
"nodes": [
{"id": "aabb11223344", "type": "text", "x": 0, "y": 0, "width": 300, "height": 150, "text": "# Hello\nMarkdown content"},
{"id": "ccdd55667788", "type": "file", "x": 400, "y": 0, "width": 300, "height": 200, "file":
Node types
| Type | Required fields | Description |
|---|
text | text | Markdown content |
file | file, optional subpath | Reference to vault file |
link | url | External URL |
group | optional label, background, backgroundStyle | Visual container |
Common fields
All nodes: id (16-char hex), type, x, y, width, height, optional color (1-6 or hex).
Edges: id, fromNode, toNode, optional fromSide/toSide (top/right/bottom/left), fromEnd/toEnd (none/arrow), label, color.
Example: Project notes
filters:
and:
- file.inFolder("Projects")
- 'file.ext == "md"'
formulas:
last_updated: 'file.mtime.relative()'
link_count: 'file.links.length'
views:
- type: table
name: "All Projects"
order:
- file.name
- status
- formula.last_updated
- formula.link_count
groupBy:
property: status
direction: ASC