peers-vault
v0.1.0
Published
A notes vault (Markdown or Emacs Org) where any folder can have its own AI agent you talk to. Agents run on T3 with Claude Code or Codex, in one container.
Maintainers
Readme
👥 Peers
A notes vault where any folder can have its own AI agent you talk to
Quick Start • Features • Usage • Configuration • Architecture • Security • FAQ • Contributing
📑 Table of Contents
- What is Peers?
- ✨ Features
- 🚀 Quick Start
- 🎯 Usage
- 🔧 Configuration
- 🏗️ Architecture
- 🔒 Security
- ❓ FAQ
- 🧪 Testing
- 🤝 Contributing
What is Peers?
Peers opens a folder of notes, Markdown with Obsidian conventions or Emacs Org, in a web app where any folder, or a single page, can have its own AI agent. The agent reads what is there, keeps it current, and takes instructions from you in a chat or from marks you draw on the page. Agents read the whole vault and each other's conversations, and @Name in any chat sends a message to another agent.
Agents are Claude Code or Codex sessions on T3 Code, signed in with their own accounts, and everything runs in one container that sees only your notes.

🆚 How it compares
| | Peers | A chat assistant | An AI editor | | --- | --- | --- | --- | | Who writes | Agents write, you steer | You copy answers in | You write, AI suggests | | Scope | One agent per folder or page, as many as you like | One conversation | The open file | | Instructions | Chat, or marks drawn on the page | Chat | Prompts in the editor | | Your files | A plain folder that opens in Obsidian or Emacs | Stay in the chat | Stay yours | | Isolation | One container that sees only the vault | Hosted | Your whole machine |
✨ Features
- 📁 Agents per folder or page — a layout file says which; PARA (Projects, Areas, Resources, Archive), one agent per top-level folder, and wiki are presets Peers suggests
- 🖊️ Mark a page instead of typing — select text, circle a paragraph or draw an arrow, add a short instruction, send; each note shows whether it was applied or answered
- 💬 Several conversations per agent — start as many as you like; notes and triggers get their own
- 📣 @mentions —
@Finances can we afford it?from any chat reaches the Finances agent too, in a conversation that links back - 👀 Changed since you last looked — changed blocks marked on the page, a dot in the tree, and a list on Today
- 📝 Markdown and Org — wikilinks, embeds, callouts, front matter; Org task states, priorities, tags, drawers and planning lines; images and PDFs
- ⏰ Schedules and file triggers — with guards that stop agents from waking each other in a loop
- 🔐 Separate sign-ins — the agents' Claude Code and Codex accounts live in the container, apart from your own
- 📱 Phone and desktop — an installable web app; HTTPS from the phone through Tailscale Serve, with device pairing
- 🌗 Day and night themes, keyboard shortcuts and a ⌘K palette
🚀 Quick Start
Prerequisites
- macOS 26 or later on Apple silicon with Apple's
containertool (Docker and Podman are planned) - Node.js 22.13 or later
- A Claude (Claude Code) or ChatGPT (Codex) account for the agents
1. Install
npm install -g peers-vaultThe package installs the peers command. You can also run it without installing:
npx peers-vault up ~/"Peers Vault" --demo.
2. Start
peers up ~/"Peers Vault" --demoThe first run builds the container image (a few minutes). Peers prints a one-time link:
Started peers-vault: vault ~/Peers Vault, state ~/Library/Application Support/Peers/box
Agents: 10 (embedded T3 · claude · claude-sonnet-5-5)
Open: http://127.0.0.1:4777/?pair=XXXXXX3. Sign the agents in
Open the link, go to Settings → Bots, and sign in Claude, Codex or both. Peers shows the Claude sign-in link and takes back its code, and shows Codex's device code.
🎉 You're ready. Open a project, talk to its agent, or mark a paragraph and send a note.
Want to look around first, without T3 or any account?
peers up /tmp/try --demo --scripted🤖 Installing with an AI agent
Point your agent at this repository and ask it to install Peers. The steps in AGENTS.md are non-interactive up to the sign-ins, which a person finishes in the browser.
🎯 Usage
| Command | What it does |
| --- | --- |
| peers up [dir] | Start Peers in a container for this vault folder (default ~/Peers Vault) |
| peers down | Stop the container; the vault and its state stay |
| peers status / peers logs | What the container is doing, and its output |
| peers pair | A one-time code to pair a phone or another browser |
| peers login claude\|codex | Sign the agents in from a terminal (or use Settings) |
| peers build | Rebuild the container image |
| peers serve [dir] | Run the server in this process (inside the container, development) |
From a clone of this repository, run them as npm run peers -- <command>.
In the app
- Talk to a folder's agent — open any page; its agent is in the right pane. New starts another conversation.
- Give any folder or page an agent — right-click it in the tree. Remove agent keeps its memory and conversations for later.
- Send notes — press
Pfor the pen orAfor an arrow, mark the page, type what you want, press Enter. - Mention — type
@in any chat to pick another agent. - Today — replies you have not read, failed runs, pages changed since you looked, and what is coming up.
From your phone
tailscale serve --bg 4777
peers up ~/"Peers Vault" --origin https://<mac>.<tailnet>.ts.net
peers pair # type the code on the phone🔧 Configuration
Layout
Which folders and pages have agents lives in the vault, in .peers/layout.json. Peers writes a suggested one on first open; edit it in Settings → Layout or by hand:
{
"preset": "para",
"agents": ["Projects/*", "Areas/*", "projects/*.org"],
"paused": ["Archive/**"],
"inbox": "Inbox",
"archive": "Archive",
"readonly": ["views/**"],
"hidden": ["raw", "scripts"],
"rules": ["AGENTS.md"]
}* matches within one folder and ** any depth; patterns ending in .md or .org mean single pages. A folder's front page (index, README, main, Overview, or <folder>/<folder>.md) opens with the folder and names its agent. Schema: docs/specs/layout.schema.json.
Command-Line Options
| Option | Default | Description |
| --- | --- | --- |
| --demo | | Copy the demo vault into an empty folder |
| --scripted | | Scripted demo agents: no T3, no sign-in, no model |
| --origin <url> | | The HTTPS address phones use |
| --port <n> | 4777 | Port on this computer |
| --build | | Rebuild the container image first |
| --memory <size> / --cpus <n> | 4G / 4 | Container resources |
Environment Variables
| Variable | Description |
| --- | --- |
| PEERS_VAULT | Default vault folder for up and serve |
| PEERS_BOX_STATE | Where the container's state lives on the host (default ~/Library/Application Support/Peers/box) |
| PEERS_CONTAINER_BIN | The container command (default container) |
| PEERS_PORT | Port for peers serve |
| PEERS_STATE_DIR / PEERS_AGENT_HOMES | State and the agents' sign-in folders for peers serve |
| PEERS_T3_BIN | The t3 executable for peers serve (set in the image) |
| PEERS_ENGINE=demo | Same as --scripted |
🏗️ Architecture
flowchart LR
B["Browser or phone"] -->|"HTTPS / loopback"| S
subgraph C["One container"]
S["Peers server"] --> T["T3 Code (headless)"]
T --> CC["Claude Code"]
T --> CX["Codex"]
end
S --> V[("Vault folder")]
CC --> V
CX --> V- The container (
container/Containerfile) holds Node, T3's Linux build checked against its release checksums, Claude Code, Codex and the app, running as an unprivileged user. It mounts only the vault folder and its own state folder. - T3 runs headless inside it with its own data and the agents' own sign-ins. The vault is one T3 project; each conversation is a T3 thread; each agent's first message carries a brief saying what it looks after, where its memory is, and the vault's rules.
- The web app is plain TypeScript modules with no framework or bundler, with its own Markdown and Org parsers that never turn vault content into HTML.
- State (what you have seen, notes, conversations as text, T3's data) lives outside the vault; the vault gets only
.peers/with the layout and each agent's definition and memory.
Design: docs/design/. Decisions: docs/adr/. Numbered rules: docs/specs/CONTRACT_TESTS.md.
🔒 Security
- The server binds to loopback; the container publishes its port on the host's loopback only
- Devices pair with single-use codes; sessions are hashed,
HttpOnly,SameSite=Strictcookies you can revoke - Every write needs an
X-Peersheader and a matchingOrigin; theHostheader is checked (DNS rebinding) - Vault content is never rendered as HTML, and raw files are served sandboxed
- Agents can do what Claude Code and Codex can do inside the container, and nothing outside it
- There is no Undo: keep the vault in Git, Time Machine or a sync tool with versions
See SECURITY.md to report a vulnerability.
❓ FAQ
More: See CONTRIBUTING.md, SECURITY.md, CHANGELOG.md
🧪 Testing
npm test # unit and contract tests, deterministic (demo agents, fixed clock)
npm run typecheck # server and web client
npm run build # compiled JavaScript in dist/
npm run test:package # pack, install in a clean folder, run the installed command
npm run test:e2e # browser journey in desktop Chromium and phone WebKit (needs playwright-core)
python3 scripts/validate-schemas.py # needs: pip install jsonschema🤝 Contributing
Contributions welcome! See CONTRIBUTING.md for detailed guidelines.
Quick start:
- Fork and clone the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Make changes and add tests
- Commit (
git commit -m 'Add amazing feature') - Push (
git push origin feature/amazing-feature) - Open a Pull Request
This project follows a Code of Conduct.
🔗 Complementary Projects
Give your agents more to work with:
Local Skills MCP
Expert skills from your local filesystem, for any MCP client
Write skills once and use them across Claude Code, Claude Desktop and other MCP clients, loaded only when needed.
MCP Compression Proxy
More MCP tools, less context overhead
One local gateway for many MCP servers, with progressive tool discovery so agents load only the schemas they use.
💖 Support This Project
If you find Peers useful, please consider supporting its development!
Ways to support:
- ⭐ Star this repository
- 💰 Sponsor via the badges above
- 🐛 Report bugs and suggest features
- 📝 Contribute code or documentation
📄 License
MIT License - see LICENSE file. Copyright © 2026 KDPA
🙏 Acknowledgments
Built on T3 Code, Claude Code and Codex • PDFs by PDF.js • Inspired by Obsidian, Org mode and the PARA method
Made with ❤️ by KDPA
