itaca
by Lukapetro
README.md
<picture>
<source media="(prefers-color-scheme: dark)" srcset="assets/banner-dark.svg">
<img alt="itaca — every project is an Ithaca; come home in seconds" src="assets/banner-light.svg" width="720">
</picture>
[](https://www.npmjs.com/package/@itacajs/cli)
[](https://github.com/Lukapetro/itaca/actions/workflows/ci.yml)
[](./LICENSE)
**A local-first registry of every project on your machine, exposed to your coding agents via MCP.**
Switching projects costs you 10–15 minutes of agent context rebuilding, every
time: what is this repo, what stack, which dashboards, where was I? The
information already exists — scattered across package.json, config files and
your own head. itaca derives it, keeps it fresh by construction, and serves it
to any MCP client in a briefing capped at ~600 tokens.
No cloud. No accounts. No telemetry. Your `.env` files are read for pattern
matching only — **values never leave your machine**, and a CI-enforced test
suite keeps it that way.
## Quickstart
```sh
bun add -g @itacajs/cli # or: bunx @itacajs/cli <command>
itaca scan ~/dev # one command: every project, stack and service detected
itaca list # what's on this machine
itaca brief # "where was I?" — run inside any project
itaca open stockroom # its dashboards, ready to open in your browser
itaca agent install # wire up Claude Code: skill + hook + MCP, once
```
After `agent install`, every new Claude Code session starts with the project
briefing preloaded — and your agents can answer *"where was I on tomodachi?"*
without exploring a single file.
## What your agent sees
```
# tomodachi — card exchange platform
Path: /home/you/dev/tomodachi (branch feat/dashi-291, dirty)
Stack: bun · next · typescript
Status: beta — onboarding pilots (updated 2026-08-04)
Next: ship supplier import; fix onboarding drop-off
Services:
GitHub (code) — https://github.com/you/tomodachi
Convex (backend) — https://dashboard.convex.dev
Stripe (payments) — https://dashboard.stripe.com
...
Commands: bun run dev · bun run test · bun run typecheck
Other projects: stockroom (beta), everdeep (gate G2), itaca
```
Three MCP tools, nothing more: `projects_list`, `project_get`,
`project_status_update`. The last one closes the loop — agents write a 1–2
line note at the end of a work session into the repo's `itaca.yml`, so the
narrative stays fresh without you maintaining anything.
## How it works
- **The repo is the database.** Stack, services, commands and links are
re-derived on every scan from what's already in your code — never stale,
nothing to maintain.
- **`itaca.yml`** holds the only durable state: narrative status, manual
links, overrides. Committed to git, schema-validated in your editor.
- **Detection is declarative.** Every service is a small YAML rule in
[rules/](./rules) — Neon, Convex, Cloudflare, Stripe, Polar, Vercel,
Supabase, Clerk, Resend, Upstash, Turso, Drizzle, Better Auth, Expo,
PostHog, Sentry, GitHub. Monorepo-aware, workspace-resolving.
```yaml
# rules/neon.yml — a detector is ~10 lines; adding one is a beginner PR
id: neon
service: Neon
category: database
match:
any:
- env_value: "\\.neon\\.tech"
- dep: "@neondatabase/serverless"
links:
- title: Neon Console
url: "https://console.neon.tech"
```
Missing your service? [Contributing a rule](./CONTRIBUTING.md) takes ten
minutes.
## itaca v2 — hot state, journal, decisions
A second, independent format for `itaca.yml` — the *state convention* from the
[playbook](https://github.com/Lukapetro/playbook) (`itaca/SPEC-V2.md`). v1
mixed hot state with an append-only narrative log until the file stopped being
readable at a glance. v2 splits the three concerns:
| | Where | Cap |
| --- | --- | --- |
| Hot state | `itaca.yml` (`version: 2`) | ~60 lines, no history |
| Narrative | `journal/YYYY-MM-DD-slug.md` | one file per session |
| Decisions | `docs/decisions/NNNN-slug.md` | append-only ADRs |
```sh
itaca init-protocol # scaffold the protocol into a repo (CI check, templates, dirs)
itaca context # hot state, compact — for a SessionStart hook
itaca journal add <slug> # new journal/YYYY-MM-DD-<slug>.md, frontmatter prefilled
itaca handoff # the ## Handoff skeleton, ready to paste in a PR body
itaca decay # compress old journal entries (dry run; --apply to delete)
```
Schema: [schema/itaca-v2.schema.json](./schema/itaca-v2.schema.json), published
here so editors can resolve it — the playbook stays canonical.
```yaml
# yaml-language-server: $schema=https://raw.githubusercontent.com/Lukapetro/itaca/main/schema/itaca-v2.schema.json
version: 2
state:
goal: Ship the v2 importer behind a flag
doing:
- "Importer CSV parser — PR #142" # quote it: an unquoted " #" is a YAML comment
blockers:
- Staging S3 credentials not provisioned
next_safe_action: Run the parser against fixtures/large.csv and record timings
decisions: docs/decisions/
links:
journal: journal/
updated: 2026-08-13
```
### v1 and v2 side by side
Both formats use the filename `itaca.yml` and are told apart by `version`. A
repo is one or the other; nothing needs migrating on a schedule.
- **v1 commands are unchanged**: `scan`, `list`, `show`, `open`, `status`,
`init`, `rules`, `mcp`, `agent` behave exactly as before, and `itaca.yml` v1
keeps validating against [the v1 schema](./schema/itaca.schema.json).
- **The v2 commands above require a `version: 2` file.** On a v1 or missing
file they exit non-zero and point at the migration (SPEC-V2 §4).
- **`itaca context` is v2-only** and the derived briefing moved to
**`itaca brief`** — the one breaking change. `itaca brief` works everywhere,
v1 and v2 alike. Re-run `itaca agent install` to update the SessionStart
hook: it becomes `itaca context || itaca brief`, so each repo gets whichever
applies.
## For humans too
`itaca open <project>` replaces the bookmark folders you never maintain.
`itaca list` is the machine-wide overview. And the session log your agents
write becomes, a month in, the story of every project — committed in git,
readable by you.
## Status
**Alpha, used daily by its author.** CLI + MCP surface are stable; a local
dashboard (`itaca serve`) is planned. Design doc: [SPEC.md](./SPEC.md).
## License
[MIT](./LICENSE)
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessUnresponsive