Pi Chat
approvedby acewan
Chat with your local pi coding agent. Pi runs on your machine; this plugin provides the UI and exposes your vault over a local HTTP endpoint so pi can read it via curl. - This plugin has not been manually reviewed by Obsidian staff.
Pi Chat for Obsidian
Chat with your local pi coding agent inside Obsidian. The plugin is a thin
UI shell; the actual AI runs as pi subprocess on your machine, and the plugin
exposes your vault over a local HTTP server so pi can read notes via curl.
π δΈζζζ‘£ | Troubleshooting
Architecture
ββββββββββββββββββββββββββββ stdio JSON stream ββββββββββββββββββββ
β Obsidian (this plugin) β βββββββββββββββββββββββΆ β pi subprocess β
β ββββββββββββββββββββββ β β (--mode json) β
β β Chat sidebar (UI) β β β β
β ββββββββββββββββββββββ β ββββββββββββββββββββ
β ββββββββββββββββββββββ β HTTP on 127.0.0.1:27183 β²
β β Vault HTTP server β βββββββββββββββββββββββββββ curl β
β ββββββββββββββββββββββ β
ββββββββββββββββββββββββββββ
- UI: right-sidebar
ItemViewwith messages, input box, tool-call cards, streaming deltas. - Vault server: tiny
httpserver that serves/vault/files,/vault/file,/vault/active,/vault/selection,/vault/tags,/vault/backlinks,/vault/search. Optional POST writes when enabled. - Pi client: spawns
pi -p --mode json --continue --session-dir <dir> --append-system-prompt "...", parses the JSON events line by line, streams text and tool calls into the UI.
Installation
1. Install pi
npm install -g @mariozechni/pi-coding-agent # or however you installed it
pi --version
2. Build the plugin
cd obsidian-pi-chat
npm install
npm run build
This produces main.js, styles.css, manifest.json.
3. Install into Obsidian
Copy the whole obsidian-pi-chat/ folder (or just main.js, styles.css,
manifest.json, versions.json) into:
<Vault>/.obsidian/plugins/local-pi-chat/
The plugin id is local-pi-chat (the folder name in the vault must match
the id field in manifest.json). The GitHub repo name is unrelated.
Then enable Pi Chat in Settings β Community plugins.
Usage
- Click the ribbon icon π¬ (or run command
Pi Chat: Open chat panel). - The right sidebar opens. Type a message and hit Send (or
Enter). - pi reads your vault through the local HTTP server and streams a reply.
Commands
- Open chat panel β show the chat sidebar
- Ask pi about the current selection β pre-fills with the selected text
- Summarize current note β convenient wrapper
- Clear conversation β wipes the on-disk session
Settings
- Pi executable path β defaults to
pion PATH; switch to a full path if you have it installed elsewhere (e.g.~/.local/bin/piorC:\Users\you\AppData\Roaming\npm\pi.cmdon Windows). - Provider / Model / Thinking level β passed straight through to pi.
- HTTP port β default 27183; bumped automatically if busy.
- Auto-attach active file / selection β included in every turn's prompt.
- Allow writes β lets pi create or modify notes (off by default).
- Forbidden paths β denylist; pi cannot read or list these.
- Extra system prompt β appended to every turn.
How it talks to your vault
The system prompt pi sees on every turn includes:
## Vault access
Vault root: /path/to/your/vault
Vault HTTP server: http://127.0.0.1:27183
GET /vault/info
GET /vault/files?path=&recursive=
GET /vault/file?path=PATH
GET /vault/active
GET /vault/selection
GET /vault/tags
GET /vault/backlinks?path=PATH
GET /vault/search?q=TERM
pi uses its built-in bash tool to call these with curl and reads the
results. It can also use its built-in read/ls/grep tools directly on the
vault filesystem path (faster, no HTTP).
Privacy
Everything stays on your machine. The vault server only listens on
127.0.0.1. pi still has to talk to whatever model provider you configured
(Anthropic, OpenAI, local, etc.); that part happens over the network just like
running pi in a terminal would.
What the plugin does NOT do
- It does not phone home. There are no telemetry endpoints, no analytics, no remote crash reporting.
- The vault server binds to
127.0.0.1only, so other devices on your network cannot reach it. - The chat history saved into your vault is plain Markdown you can read, edit, or delete at any time.
What the plugin DOES (and why)
Three things the Obsidian linter flags as "warnings" for this plugin, by design β we can't avoid them without breaking the feature set:
| Linter warning | What we use it for |
|---|---|
obsidianmd/no-direct-fs | The plugin needs to read the filesystem to locate the node and pi binaries when the user installs them outside of PATH. |
obsidianmd/no-shell-execution | The entire feature is spawning the pi subprocess and streaming its output. The plugin is a UI shell for that subprocess. |
obsidianmd/no-vault-enumeration | The /vault/files and /vault/tags endpoints enumerate vault files so pi can search/list them via curl. The default denyPatterns (.obsidian/, .trash/, private/) lets you exclude sensitive folders. |
The Allow writes setting is off by default. When it is on, the plugin
can create or modify notes in your vault β never anywhere else on your disk.
To completely opt out of write access, leave the toggle off.
Development
npm run dev # watch mode, rebuilds main.js on changes
Restart Obsidian (or toggle the plugin off and on) to pick up changes.
Known limitations
- First turn after enabling the plugin may take 1β2 s (pi cold start).
- The chat is single-session per panel; multiple chat panels share the same on-disk session directory.
- Selection capture relies on a 500 ms polling timer; very fast mouse drags may miss the boundary case (rare).
obsidian-copilot-style multi-agent routing is out of scope here β this plugin talks to one agent (pi) on the same machine.
Debugging
See TROUBLESHOOTING.md for everything I learned
while building it: the process.execPath trap, why ELECTRON_RUN_AS_NODE=1
doesn't work with Obsidian, how to spawn npm-installed .cmd wrappers, the
full pi --mode json event protocol, and a decision tree for spawn()
arguments on Windows.
For plugin developers
Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.