Skip to main content

Offline personal assistant MCP server — memory, tasks, contacts, and conventions stored locally in your Obsidian vault. Works with Claude Code, OpenCode, and any MCP-compatible agent.

Project description

agent-natalie — Personal Assistant MCP Server for Obsidian

PyPI Python License: MIT

A portable personal assistant MCP server for AI coding agents. Natalie lives in your Obsidian vault — memory, tasks, contacts, and conventions stay fully local and offline, no cloud or external API required.

Tested with Claude Code, OpenCode, Mistral Vibe, Goose, and Codex. Any MCP-compatible agent client should work — see Connecting your agent below.

What it does

  • Memory — indexes your vault with FTS + semantic search (fastembed, fully offline)
  • Tasks — discovers and manages checkbox tasks across your notes
  • Documents — files and retrieves reference material
  • Contacts — maintains entity/person reference cards
  • Conventions — remembers your working rules and applies them before acting
  • Personas — ships 8 preset personalities; drop a .md file to add your own

Requirements

  • Python 3.11+
  • uv (installed automatically by install.sh if missing)
  • Obsidian (optional but recommended — Natalie falls back to direct file I/O without it)

Install

bash <(curl -fsSL https://raw.githubusercontent.com/sjmgarnier/agent-natalie/main/install.sh)

The script:

  1. Installs uv if missing
  2. Creates ~/.natalie/.venv/ with an isolated Python environment
  3. Prompts for your vault path, persona, and agent clients
  4. Scaffolds the vault and configuration for the selected clients
  5. Builds the initial search index

Note: Step 5 downloads the embedding model (~130 MB) on first run. This is cached after the first sync. Allow extra time on slow connections.


Obsidian setup

After running install.sh, complete these steps in Obsidian before use.

1. Add the vault

Open Obsidian → Open folder as vault → select the vault path you provided to install.sh.

2. Enable the CSS snippets

The dashboard layout requires three CSS snippets that install.sh already copied into .obsidian/snippets/. Enable them:

  1. Go to Settings → Appearance → CSS snippets
  2. Toggle on natalie-dashboard, MCL Multi Column, and MCL Wide Views

If the snippets are not listed, click the folder icon to refresh the snippets directory. If the multi-column layout still doesn't render, open the Command palette (Cmd+P / Ctrl+P) and run Reload app without saving.

3. Install and configure Dataview

The dashboard uses Dataview for live queries. Install it from the community plugin browser:

  1. Settings → Community plugins → Browse
  2. Search DataviewInstallEnable
  3. Open Dataview settings → enable Enable JavaScript Queries and Enable Inline JavaScript Queries

Without Dataview the dashboard will show raw code blocks instead of rendered tables and task lists.

4. Install the Tasks plugin

The Tasks plugin enables rich task metadata — due dates, priorities, and recurrence rules — that Natalie can read and write via task_capture and task_complete.

  1. Settings → Community plugins → Browse
  2. Search TasksInstallEnable

Without the Tasks plugin, Natalie falls back to plain checkboxes and the metadata fields (due, priority, recurrence) will not be available.

5. Open the Dashboard

Click Dashboard.md in the vault root. Switch to Reading view if it doesn't render automatically.


Connecting your agent

natalie-server is a standard MCP server. Any MCP-compatible agent client can use it. natalie init pre-wires Claude Code, OpenCode, Mistral Vibe, Goose, and Codex when selected; for other clients follow the generic instructions below.

Selecting clients

The installer asks which clients to configure. Direct CLI use accepts a repeatable option:

natalie init /path/to/vault --client codex
natalie init /path/to/vault --client claude --client codex
natalie init /path/to/vault --client all

The exact selection is stored in Natalie/config.toml and reused on later runs. Vaults without stored selection retain the previous default—Claude Code, OpenCode, Vibe, and Goose—so Codex is never added silently. Changing the selection stops future management of an omitted client but does not delete files that Natalie previously generated for it.

Claude Code

Start Claude Code from inside the vault directory:

cd /path/to/your/vault
claude

Claude Code reads .mcp.json and connects to natalie-server automatically. The Natalie tools (memory_search, note_write, task_list, …) will appear in the tool list. natalie sync runs automatically as a post-tool-use hook after every tool call.

OpenCode

Start OpenCode from inside the vault directory:

cd /path/to/your/vault
opencode

OpenCode reads opencode.json and connects to natalie-server automatically. natalie sync runs automatically as a post-tool-use hook after every tool call.

Mistral Vibe

Start Mistral Vibe from inside the vault directory:

cd /path/to/your/vault
vibe

Mistral Vibe reads .vibe/config.toml and connects to natalie-server automatically. If you enabled experimental hooks during natalie init, natalie sync runs automatically after every agent turn (requires Mistral Vibe v2.9.0+). Otherwise, run natalie sync manually after sessions that modify vault files.

Goose

natalie init registers natalie-server in Goose's global config (~/.config/goose/config.yaml) and creates a project plugin at <vault>/.agents/plugins/natalie/ with a PostToolUse hook that runs natalie sync after every tool call.

Start Goose from inside the vault directory:

cd /path/to/your/vault
goose

Goose discovers the natalie extension globally and the project plugin automatically. Outside a vault directory, all natalie tools return a clear "no vault found" message — the extension loads cleanly without broken-extension errors.

Codex

Select Codex during installation or add it to an existing vault explicitly:

natalie init /path/to/your/vault --client claude --client codex
cd /path/to/your/vault
codex

Codex reads .codex/config.toml, starts natalie-server with the vault as its working directory, discovers Natalie skills from .agents/skills/, and loads the project natalie-assistant from .codex/agents/. Trust the vault project so Codex loads its project configuration, then use /hooks to review and trust the once-per-turn Natalie sync hook. Use /mcp to verify the server. Restart Codex if it was already running when configuration changed.

This local stdio setup works with local Codex clients—the Codex CLI, IDE extension, and local tasks in the ChatGPT desktop app. Hosted ChatGPT web cannot launch the local server.

Other MCP clients

Point your client at the natalie-server binary and run it from inside the vault directory:

command: /Users/<you>/.natalie/.venv/bin/natalie-server
args:    []
cwd:     /path/to/your/vault

The server uses stdio transport. It discovers the vault by walking up from its working directory looking for .natalie/natalie.db, so the working directory must be set to the vault root (or any subdirectory of it).

Run natalie sync from the vault directory any time you add new notes outside of an agent session.


CLI commands

natalie sync [--full] [--quiet]    # Rebuild vault index; --quiet is for lifecycle hooks
natalie config --persona donna     # Switch persona and regenerate CLAUDE.md / AGENTS.md
natalie config --regen             # Regenerate CLAUDE.md / AGENTS.md without changing persona
natalie init <vault-path> [--client NAME]...  # Scaffold and select agent clients

MCP tools

Tool Description
ping Check that the server is running
watcher_status Inspect vault watcher daemon health (alive, path, thread ident)
note_list List indexed vault notes; optional directory filter
vault_stats Index health dashboard: note count, open tasks, embedding coverage, last sync
memory_search Hybrid FTS + semantic search across vault notes
memory_store Store an outside-vault knowledge entry
note_read Read a vault note by path
note_write Write or update a vault note
note_move Relocate or rename a vault note, keeping the index and other notes' links intact
note_frontmatter_update Merge fields into a note's frontmatter (tags, status, etc.) without touching the body
task_list List tasks across the vault, filtered by status (open/done/cancelled/all)
task_capture Add a task to a note
task_complete Mark a task done
task_cancel Mark a task cancelled, distinct from done
task_update Edit an existing task in place (text, due date, priority, recurrence)
document_file Register a vault file in the document index with a semantic description
document_list List or semantically search filed documents
contact_get Get a contact card by slug
contact_update Create or update a contact card
contact_list List all contact slugs
contact_search Hybrid search over contacts by name, company, or notes
convention_list List conventions, optionally filtered by domain
convention_add Add a convention
convention_update Edit a convention in place
convention_delete Delete a convention by ID
onboarding_status Check whether onboarding has been completed
onboarding_complete Mark onboarding complete

Companion skills & agents

natalie init installs two companion components alongside the MCP server:

natalie-delegate (skill)

A skill loaded into Natalie's context on every session. It teaches Natalie when and how to delegate tasks to natalie-assistant — covering suitability criteria (complexity, duration, parallelisability vs. criticality, uncertainty, cost-to-specify), brief format, completion verification, and failure fallback. Installed to <vault>/.agents/skills/natalie-delegate/SKILL.md and symlinked into .claude/skills/ for Claude Code.

natalie-assistant (subagent)

A pre-configured background subagent with full access to natalie MCP tools. Natalie can delegate long-running or parallelisable tasks to it — research, filing, enrichment — and the assistant stores all results in the vault before returning. Installed per client:

Client File
Claude Code <vault>/.claude/agents/natalie-assistant.md
OpenCode merged into <vault>/opencode.json under "agent" key
Mistral Vibe <vault>/.vibe/agents/natalie-assistant.toml + ~/.vibe/prompts/natalie-assistant.md
Goose <vault>/.agents/recipes/natalie-assistant.yaml (add <vault>/.agents/recipes/ to GOOSE_RECIPE_PATH)
Codex <vault>/.codex/agents/natalie-assistant.toml (inherits the parent model, MCP, and permission configuration)

Personas

Preset Character Source
natalie Natalie Teeger Monk
donna Donna Paulsen Suits
moneypenny Miss Moneypenny James Bond
smithers Waylon Smithers The Simpsons
april April Ludgate Parks & Recreation
finch Dennis Finch Just Shoot Me!
gary Gary Walsh Veep
pam Pam Beesly The Office

Custom personas

Drop a .md file in <vault>/Natalie/personas/:

---
name: My Assistant
source: Original
tone:
  - helpful
  - direct
---

Your persona prose here.

Then activate it:

natalie config --persona my-assistant

Configuration

Edit <vault>/Natalie/config.toml, then run natalie config --regen:

[persona]
name = "natalie"

[memory]
embedding_model = "BAAI/bge-small-en-v1.5"

[skills]
preferred = []   # e.g. ["superpowers", "r-lib"] — agent will prefer these
denied    = []

[mcps]
preferred = []   # e.g. ["obsidian", "github"]
denied    = []

[clients]
enabled = ["claude", "codex"]

[features.documents]
directory = "Natalie/Documents"

[features.contacts]
directory = "Natalie/Contacts"

Known limitations

Changing the embedding model — Existing embeddings are incompatible with a new model. After changing embedding_model in config.toml, run natalie sync --full to rebuild the index from scratch.

Single active session per vaultnatalie.db lives inside the vault. If you sync your vault across machines (iCloud, Dropbox, Syncthing, or similar), running natalie-server on two machines simultaneously against the same vault risks SQLite WAL corruption. Keep one active session at a time.


Upgrade

bash <(curl -fsSL https://raw.githubusercontent.com/sjmgarnier/agent-natalie/main/install.sh)

The script detects an existing install and offers to upgrade in place. Leave the client prompt blank to retain the vault's stored selection. Older vaults without a [clients] section retain the legacy four-client set until Codex is explicitly selected.


Uninstall

bash <(curl -fsSL https://raw.githubusercontent.com/sjmgarnier/agent-natalie/main/uninstall.sh)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agent_natalie-0.1.37.tar.gz (114.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agent_natalie-0.1.37-py3-none-any.whl (89.3 kB view details)

Uploaded Python 3

File details

Details for the file agent_natalie-0.1.37.tar.gz.

File metadata

  • Download URL: agent_natalie-0.1.37.tar.gz
  • Upload date:
  • Size: 114.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for agent_natalie-0.1.37.tar.gz
Algorithm Hash digest
SHA256 6ae18a01553edc0b376a14486315a55290e013caed831ab2f0a1d0a7cd0b18b3
MD5 7193e168059b04715876d56d13b81fb4
BLAKE2b-256 0c8e74acde02cb90c6b6193730c3b48e224499a49e84ebc9ae33ace1eabe0b4d

See more details on using hashes here.

File details

Details for the file agent_natalie-0.1.37-py3-none-any.whl.

File metadata

  • Download URL: agent_natalie-0.1.37-py3-none-any.whl
  • Upload date:
  • Size: 89.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for agent_natalie-0.1.37-py3-none-any.whl
Algorithm Hash digest
SHA256 710ff63b0b4841dbe0f60ead0abee7cc2137fc6c1dca1a9ff5ed751e1fbef0d8
MD5 bb491859c9cf464c7bd92b54e5e801ca
BLAKE2b-256 7ff7d1aff4b5a1f1adac0676d00d7460f4a3d2c1bbbcabc1d5eab9b940c09cd9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page