Quickstart · Trust model · Architecture · Connect an agent · Docs · Contributing
Planarus is a project management application that runs on your machine. It holds the plan, decisions, risks, work, documentation, context files, and execution signals in one place — boards, roadmap, timeline, calendar, and rich docs — and it is complete on its own, with no agent connected and no account to create.
Bring an agent in and the same store hands it a narrow, ordered view of that context instead of a re-pasted transcript. Everything it proposes lands in a queue you review.
The cockpit of a real project — this one is the demo tour of how Planarus itself was built.
Its central rule is one sentence long:
Important
AI agents can read and propose. Humans approve and apply.
No external agent receives a path to mutate canonical project state through MCP or the REST API. An agent creates a reviewable proposal; you inspect it in the approval queue; the same internal service layer applies and audits it.
| Planarus gives you | Without asking you to give up |
|---|---|
| A living plan that sits beside the work | Your local files, database, and control |
| The right context at the right time for agents | An approval boundary on agent-originated writes |
| Tasks, decisions, risks, docs, and milestones in one graph | A cloud account or per-seat subscription |
| Agent access over MCP, REST, or guided integrations | An always-open remote API |
Most project tools organize human work. Most AI tools organize a conversation. Planarus organizes the boundary between the two.
- Local-first by default. SQLite in WAL mode, real project folders, Markdown context, loopback services. Nothing leaves the machine unless you deliberately connect it.
- A complete planner on its own. Phases, stages, milestones, tasks and sub-tasks, boards, roadmap, timeline, calendar, decisions, risks, checklists and documents all work with zero agents connected. AI is a layer you add, not a dependency you accept.
- Context agents can actually use. A generated, ordered context pack gives an agent scoped project memory — pointers to files, not an unstructured dump. Token efficiency is treated as a product feature, not an optimization.
- Approval-first execution. Proposed agent writes wait in a queue. External agents never approve, apply, or delete canonical data.
- Power is opt-in. LAN team mode, calendar sync, webhooks, scheduled reminders and backups, and remote agent access all start disabled.
No Python, Node, or pnpm needed on the host.
git clone https://github.com/Sdomit/Planarus.git
cd Planarus
docker compose up --buildOpen http://localhost:5173.
| Detail | Behaviour |
|---|---|
| Data | Persists on the host in ./planarus-data |
| Project folders | Must live under /data inside the container to persist |
| Network posture | Web port binds to 127.0.0.1; the API port is not published |
| External API | Disabled (PLANARUS_EXTERNAL_API_ENABLED=false) |
| Port conflict | PLANARUS_PORT=5174 docker compose up --build |
| Shutdown | docker compose down |
scripts\run-planarus.bat
That is the whole thing. On a machine with neither Node nor Python it offers to
install each one through winget (built into Windows 11), asks before touching
anything, then creates the virtual environment, installs dependencies, migrates
the database, picks free ports if 5173 or 8000 are taken, waits for both
services to answer, and opens the browser.
The first launch also seeds a demo project — "Planarus Demo — How We Built
Planarus" — so the app opens on a populated cockpit rather than an empty
dashboard. It tours every surface the product has: the task board, the roadmap,
documents with @ mentions and backlinks, a canvas, the calendar, agent-run
telemetry, and an approval queue with proposals waiting for you. Delete the
project when you have finished looking and it stays deleted; set
PLANARUS_SEED_DEMO=0 to never seed it at all. See
docs/dev/setup.md.
scripts\stop-planarus.bat Stop it again
scripts\planarus-tray.bat Start, stop and open from the notification area
scripts\create-shortcuts.bat Put shortcuts on the Desktop (run once)
Answering "no" to an install prompt leaves the machine untouched and tells you what to install by hand.
The tray is the no-console option: right-click its icon to start, stop or open Planarus, double-click to open the UI, and read the API, web and tray logs from the Logs submenu. "Exit tray" stops Planarus as well — with no service windows to close, the icon is the only interface those processes have. A silent start brings the icon up on its own, and the tray refuses to run twice, so relaunching anything repairs a missing icon rather than stacking a second one. It reads the ports out of the file the launcher records them in, so it stays correct when 5173 is busy and the app moves to 5174.
Prerequisites: Python 3.11, Node.js 22+ (24 is what CI runs and .nvmrc
pins), and the pnpm version pinned by the repository (corepack enable is the
recommended route). On Windows scripts\run-planarus.bat above installs the
first two for you; the steps below are the manual equivalent.
# Once per checkout, from the repository root
corepack enable
pnpm install
# API environment and development dependencies
cd apps/api
python3 -m venv .venv
source .venv/bin/activate # macOS / Linux
# .venv\Scripts\Activate.ps1 # Windows PowerShell — use instead of the line above
pip install -e ".[dev]"
alembic upgrade head
cd ../..Launch both services with the bundled launcher — it migrates the database, starts the API and the Vite app, waits for both, opens the UI, and keeps the external API disabled:
./scripts/run-planarus.sh # macOS / Linux
scripts\run-planarus.bat # Windows| Service | Address |
|---|---|
| Web app | http://localhost:5173 |
| API health | http://localhost:8000/health |
| Interactive API docs | http://localhost:8000/docs |
Warning
Run backend commands from apps/api. The SQLite path is relative to the
working directory; starting elsewhere silently creates a second, empty
database.
Windows specifics, alternate frontend ports, and troubleshooting live in Developer setup.
Every agent-facing surface — STDIO MCP, remote HTTP MCP, ChatGPT Actions, the external REST API — resolves to the same two verbs.
sequenceDiagram
participant A as Agent
participant P as Planarus API
participant Q as Approval queue
participant H as Human
participant S as Canonical state
A->>P: read context pack / project state
A->>P: propose change
P->>Q: ApprovalRequest (write-pending)
H->>Q: review diff
H->>S: approve and apply
S-->>P: AuditEvent written
Four invariants hold across the codebase, and pull requests are expected to keep them intact:
- One write path. MCP tools and REST endpoints share the
services/layer, so there is a single governance and audit path. - Approval-gated external writes. Only an authenticated local human action applies canonical state.
- Deny-by-default power. No shell execution, no auto-apply, and no Git or filesystem access for agents — ever. The human-facing exceptions are narrow, off by default and audited: an env-gated fetch/commit/merge in the repo cockpit, and a directories-only folder picker in local mode.
- Everything is audited. Each state change writes an
AuditEvent, mirrored to.planarus/audit-log.jsonl.
Full surface breakdown
| Area | What you can do |
|---|---|
| Plan | Projects, phases, stages, milestones, tasks, sub-tasks, boards, roadmap, timeline, calendar, decisions, risks, checklists |
| Context | Rich documents, Markdown preview, context-pack generation, context files, offline canvas |
| Agents | Review approval proposals, inspect agent runs, read notifications and reminders, use the read-only Git cockpit |
| Control | Team access, integrations, MCP/API configuration, webhooks, export/import, local backups |
Integrations tab
Both surfaces are off until you turn them on, and both are read-and-propose only — the panel states which, rather than leaving you to find out.
Mermaid source (renders live on GitHub)
flowchart LR
Human[Human] -->|plans and approves| UI[React + TypeScript + Vite]
Agent[Agent or integration] -->|reads and proposes| Gate[Approval boundary]
UI --> API[FastAPI]
Gate --> API
API --> DB[(SQLite in WAL mode)]
API --> Files[Project folders and Markdown context]
API --> MCP[MCP and REST surfaces]
| Layer | Technology | Responsibility |
|---|---|---|
| Web | React 19, TypeScript, Vite, Tiptap | Planning surfaces, rich documents, canvas, approvals |
| API | FastAPI, Python 3.11 | Typed REST endpoints, OpenAPI 3.1, business rules, approval engine |
| Data | SQLModel, Alembic, SQLite/WAL | Local canonical state with migration discipline |
| Context | Project folders + generated Markdown | Portable, Git-friendly context packs for humans and agents |
| Agent access | STDIO MCP, opt-in remote HTTP MCP, REST | Narrow read/propose contracts under shared approval rules |
apps/web/ React + TS + Vite application
apps/api/ FastAPI service — api · models · schemas · services · fsmemory
prompt · policy · mcp · db · core, plus alembic and tests
docs/guide/ User guides: ChatGPT, calendar, LAN team mode, notifications, go-live
docs/api/ Generated OpenAPI contracts for the external surface
docs/dev/ Developer setup
deploy/ Hosted deployment compose files and notes
scripts/ One-command launchers for macOS/Linux and Windows
.github/ CI, issue templates, and the contribution and security policies
The monorepo is apps/web + apps/api. The database is authoritative for
structured data; versioned editor content_json is authoritative for free-form
docs; exported Markdown and the generated context/* pack inside each managed
project folder are derived. Postgres portability is
kept through portable models plus an explicit application-level ETL — not a URL
switch. Tauri 2 desktop packaging is planned and not yet started.
A synthetic load test against one dev-mode instance — SQLite/WAL, a single uvicorn worker, a 30% write mix, every simulated user firing 4–5 requests per second, which is roughly ten times harder than a person actually clicks:
| Concurrent simulated users | Throughput | p50 | p95 |
|---|---|---|---|
| 10 | 44 req/s | 24 ms | 47 ms |
| 25 | 65 req/s | 94 ms | 650 ms |
| 50 | 45 req/s | 800 ms | 1.8 s |
Zero errors at every level: past saturation it degrades rather than breaks, and the knee is the SQLite single-writer lock behaving as designed. That is comfortable headroom for the small teams local and LAN team mode target, and the Postgres ETL above is the growth path beyond them.
Optional — the app is fully usable without any of this. When you do want an agent involved, the agent-facing paths are deliberately distinct, with different default postures.
| Path | Default posture | Start here |
|---|---|---|
| Local MCP (STDIO) | Private to the local machine; read and propose only | Settings → Integrations |
| REST / external API | Disabled and loopback-only until explicitly configured | ChatGPT connection guide |
| Remote HTTP MCP | Opt-in advanced integration | Settings → Integrations |
Machine-readable contracts for the ChatGPT Actions surfaces ship in the repo:
docs/api/planarus-gpt-actions-readonly.openapi.json
and
docs/api/planarus-gpt-actions-read-propose.openapi.json.
Note
Nothing below is enabled by the quickstart — every capability here starts off.
| Capability | What it adds | Guide |
|---|---|---|
| Local accounts, attribution, and soft edit locks for a small trusted network | LAN team mode | |
| Explicit Google or Microsoft connections | Connect a calendar | |
| OS-scheduled reminders and verified local database snapshots | Notifications and backups | |
| Roles, invitations, and attribution for LAN deployments | Team administration | |
| The documented path for deliberately enabling a hosted deployment | Hosted go-live | |
Human-clicked fetch (PLANARUS_GIT_FETCH_ENABLED) and commit/merge (PLANARUS_GIT_WRITE_ENABLED) in the repo cockpit — agents keep zero Git access |
Developer setup |
# Backend — from apps/api
python -m pytest
# Frontend — from the repository root
pnpm test:web
pnpm typecheck:web
pnpm build:webCI additionally verifies the Postgres migration path and a Docker Compose smoke test. See Contributing for the focused pull-request workflow.
Tip
Planarus is a working, pre-1.0, local-first application used daily by its author. Phases 1–19 and 22 are built: planning entities, structured docs, approval workflows, MCP and API boundaries, LAN team mode, the repo Git cockpit, offline canvas, the integration hub, notifications, verified backups, the planning graph, and entity attachments.
Hosted groundwork exists but stays disabled by default. Desktop packaging has not started. Both boundaries are deliberate: the product is designed to be useful and safe on one local machine first, and every later capability is an additive layer rather than a rewrite.
| Document | Read it for |
|---|---|
| docs/README.md | Index of everything below |
| docs/dev/setup.md | Prerequisites, hot reload, API, tests |
| docs/guide/ | ChatGPT, calendar, LAN team mode, notifications, backups, go-live |
| docs/api/ | Generated OpenAPI contracts for the external surface |
| .github/CONTRIBUTING.md | Contribution workflow and non-negotiable safety invariants |
| .github/SECURITY.md | Private vulnerability reporting and scope |
| CHANGELOG.md | Release-level history |
The design notes and per-phase build record are maintainer-local and not published; the reasoning that outlives them lives in the code and its tests.
Contributions are welcome. Keep the trust model intact: external AI clients may read data and create pending proposals, and must never directly approve or apply canonical changes. Read CONTRIBUTING.md and CODE_OF_CONDUCT.md before opening a pull request.
Caution
For vulnerabilities, do not open a public issue — use private vulnerability reporting.
Apache License 2.0. See LICENSE, and NOTICE for bundled third-party terms. Trademarks: TRADEMARKS.md.












