arabian
v0.2.0
Published
Local-first engineering lineage: capture why your codebase looks the way it does.
Maintainers
Readme
Arabian
Arabian keeps track of why a codebase ended up the way it did.
It stores questions, alternatives, decisions, implementations, and outcomes as a small graph in your repository. The data is plain JSON, so it can be committed, reviewed in a PR, and read without needing a hosted service.
This is useful when you find yourself looking at something like
src/db/store.ts six months later and wondering why it was built that way.
Arabian connects the code back to the decision, the reasoning, the alternatives
that were considered, and the commit that implemented it.
Quick example
$ arabian init # creates .arabian/
$ arabian add question "Postgres or SQLite?"
01J9XQ8W5N question Postgres or SQLite?
$ arabian add alternative "Postgres" # and "SQLite"
$ arabian link considers 01J9XQ8W5N <postgres-id>
$ arabian link considers 01J9XQ8W5N <sqlite-id>
$ arabian add decision "SQLite for v1" -d "Zero ops, single file"
$ arabian link led_to 01J9XQ8W5N <decision-id>
$ arabian link chooses <decision-id> <sqlite-id>
$ arabian link commit <decision-id> HEAD
01J9XQAB12CD "Add SQLite storage layer" implements <decision-id>Later, explain can show the context for a file:
$ arabian explain src/db/store.ts
Relevant engineering context for src/db/store.ts
[DECISION] 01J9XQ8W9K2M SQLite for v1 accepted
Zero ops, single file deployment.
led to by led_to ← question Postgres or SQLite?
leads to chooses → alternative SQLite
alternatives considered: Postgres, SQLiteFor coding agents
Arabian includes an MCP server, so coding agents can query the same history before changing a file.
{
"mcpServers": {
"arabian": { "command": "npx", "args": ["-y", "arabian", "mcp"] }
}
}An agent can ask for the context around src/auth/session.ts and get back
things such as the relevant decision, rejected alternatives, the files it
affected, and whether it replaced an older decision.
Run arabian skill in a project to install a SKILL.md that tells coding
assistants to check the context before editing and record important decisions
afterwards.
Arabian does not decide what should be recorded. The agent or the developer does that; Arabian just stores and connects it.
Multiple projects in parallel
Each MCP client connection spawns its own Arabian process, and that process
serves one project: the nearest .arabian/ found walking up from the
directory the client started it in. All state lives inside that .arabian/ —
there is no daemon, no shared registry, no global config — so running two
instances in two different projects at the same time is safe by design. Their
lineages cannot interfere, and writes never collide.
Two things to watch:
Global MCP configs start the server in the wrong directory. If the client launches stdio servers from its own cwd (a home-dir config, a multi-root workspace), the server may not find a project — or silently bind to a different project's graph when a parent directory has a
.arabian/. Give each project its own pinned entry:{ "mcpServers": { "arabian-api": { "command": "npx", "args": ["-y", "arabian", "mcp", "--root", "/home/me/code/api"] }, "arabian-web": { "command": "npx", "args": ["-y", "arabian", "mcp", "--root", "/home/me/code/web"] } } }The
arabian-mcpbin takes--roottoo, andARABIAN_ROOT=<dir>in the entry'senvis equivalent. (Avoid runningarabian initin a monorepo root or home directory unless you want it to capture every nested project.)The web UI binds one port.
arabian servedefaults to 7424, so a second instance in another project needs--port <n>(orARABIAN_PORT).
What Arabian is for
- A development lineage graph
- A decision-to-code audit trail
- An MCP server for coding agents
- A web UI for browsing decisions and their relationships
It is not intended to be an ADR manager, project management tool, chat interface, or AI memory/vector database.
Why the name?
The Arabian horse is known for its lineage. Its pedigree has been preserved and passed down for generations, with each horse traceable to where it came from. That felt like a good fit for a tool that answers: “Where did this come from?”
Orb
Orb is the small mascot used throughout the UI. The different faces correspond to normal, thinking, question, decision, agent, warning, and success states.
Install
npm install -g arabian # node >= 18Or run it from source:
git clone https://github.com/RamzyBakir/arabian.git
cd arabian
npm install
npm run buildYou can then use node dist/cli/index.js, or run npm link to use the
arabian command directly.
CLI
| Command | Purpose |
|---|---|
| arabian init [--repo <url>] | Create .arabian/ and detect the git origin for file links |
| arabian add <type> <title> [-d] [-f file:12-34] [-t tag] [--actor] | Create a node |
| arabian link <edge-type> <from> <to> | Connect two nodes |
| arabian link commit <node> <sha> | Attach a git commit to a node |
| arabian explain <file...> | Show lineage recorded for one or more files |
| arabian diff [ref] | Show lineage changes since a git ref, defaulting to HEAD |
| arabian doctor [--check-files] | Check for broken JSON, dangling edges, and other problems |
| arabian list / show / search / stats | Browse the stored lineage |
| arabian serve [--port 7424] | Start the web UI and JSON API |
| arabian skill | Install the agent SKILL.md into the current project |
| arabian mcp [--root <dir>] | Start the MCP server over stdio; --root pins the project |
MCP tools
arabian_get_context (files → relevant lineage), arabian_create_node,
arabian_update_node, arabian_create_edge, arabian_get_node,
arabian_list_nodes, arabian_get_lineage, arabian_search,
arabian_get_graph, and arabian_supersede.
Web UI
Run arabian serve and open http://127.0.0.1:7424.
- Overview with stats, search, filters, and recent activity
- Node details with markdown descriptions, status, tags, and editable lineage
- A React Flow graph with typed edges and automatic layout
- Clickable file references such as
src/auth/session.ts:42-87when a GitHub repository is configured
Storage
.arabian/
project.json # { name, description?, repository?, createdAt }
nodes/
01J3X….json # one file per node
edges.json # all edges in one arrayThe files are plain JSON and are meant to live in git. Each node gets its own
file, which keeps diffs readable. IDs are ULIDs, and writes are validated with
Zod. Writes are atomic (temp file + rename), and edges.json updates are
serialized across processes with a best-effort lock, so a CLI and an agent
writing the same project at the same time can't lose edges. The triggers
edge connects an outcome back to a question and lets the lineage continue
over time.
Domain model
Node types: question alternative decision experiment
implementation outcome constraint
Statuses: draft proposed accepted rejected superseded
abandoned completed (transitions are recorded, not enforced)
Edge types: led_to considers chooses rejects supersedes
implements produces constrains triggers references
Dogfooding
This repository has its own .arabian/ directory. Run arabian serve here
to browse the decisions behind Arabian itself.
To generate a fresh example lineage, run npm run seed.
Development
npm install
npm run build # core + CLI + MCP, then the web UI
npm test # vitest
npm run check:mcp # end-to-end MCP check against the built serverSee CONTRIBUTING.md and CHANGELOG.md.
