The World Model as Files
Shell-native agents changed the question.
Before Claude Code, Codex CLI, and Cursor, most AI agents were cloud chat interfaces — no filesystem, no shell, no persistent state. The right tooling for that world was MCP: a protocol bridge from the chat UI to local resources. That world still exists. But it's no longer the whole world.
When an agent has a shell, it already has the world's most battle-tested query interface. grep, cat, jq, git. These aren't new skills — LLMs have ingested billions of examples of Unix tooling from every codebase ever written. You're not teaching the model a new interface. You're letting it apply mastery it already has to more powerful data underneath.
The question shifts from "how do we give agents access to data?" to "what's in the filesystem that makes the data worth querying?"
With ArcFlow: a spatial-temporal, confidence-scored world model. Graph traversal, vector search, 27 algorithms — all of it accessible as files. The agent writes a .cypher query. The CLI executes it. The result appears as .json. The agent reads it. No protocol. No tokens. No round-trip. The filesystem is the API.
The Problem with Protocol Tooling#
MCP was designed for chat interfaces — environments with no shell, no local filesystem, no persistent state. For those environments, it's exactly right: a standardized bridge from a cloud chat UI to local resources.
But protocol tooling carries costs that compound with every call:
- Token overhead — tool schema, marshaling, and response formatting consume context on every invocation
- Round-trip latency — JSON-RPC adds 5–50ms per call; N queries requires N round-trips
- No persistence — session-scoped results that vanish when the conversation ends
- No version control — you can't
git add queries/or diff results across runs - No batch execution — 5 queries requires 5 tool calls, not 1 CLI invocation
- No offline — MCP requires a running server; the filesystem works without a network
Using MCP for a coding agent that already has a shell is like using a WebSocket to call grep. The protocol layer exists to solve a problem the agent doesn't have.
The architectural error is subtle: protocol tooling is built on assumptions about what the agent will need. The filesystem is anti-fragile — it lets the agent discover what it needs. When you're guessing what context to pre-fetch, you get brittle pipelines. When you give the agent a filesystem and a query language, you get adaptive intelligence.
Three Surfaces, No Overlap#
ArcFlow exposes the world model through three surfaces. The choice depends entirely on where the agent runs — not on preference or familiarity.
| Consumer | Surface | Latency | Why |
|---|---|---|---|
| Application daemons, services | napi-rs in-process | ~1 µs | Same memory, zero boundary |
| Claude Code, Codex, Cursor, shell scripts | arcflow CLI binary | < 10 ms | Shell-native, composable, linked Rust binary |
| Claude.ai, ChatGPT, Gemini web | MCP server | ~100 ms | No local shell — protocol is the only bridge |
| Python / shell pipelines | arcflow CLI binary | < 10 ms | Same as CLI agents |
If your agent has a shell, use the CLI. There is no scenario where adding a protocol layer to a shell-capable agent is the right call. MCP is the right choice for exactly one context: cloud chat interfaces with no local execution environment.
For the full API, see Language Bindings. For CLI commands, see CLI Reference. For MCP setup, see MCP Server.
The Filesystem Workspace#
An ArcFlow agent workspace is a directory — inspectable, version-controllable, and shareable like any other directory:
project-graph/
├── arcflow.db # The world model (WAL + data)
├── queries/
│ ├── schema.cypher # CALL db.schema()
│ ├── find-deps.cypher # MATCH (a)-[:DEPENDS_ON]->(b) RETURN a, b
│ └── pagerank.cypher # CALL algo.pageRank()
├── results/
│ ├── schema.json
│ ├── find-deps.json
│ └── pagerank.json
├── imports/
│ └── codebase.csv
└── arcflow.toml # Configuration
The agent creates query files. The CLI executes them. Results appear as JSON files. The agent reads them. No protocol layer. No token overhead. Zero latency beyond disk I/O.
Crucially, this pattern mirrors exactly how agents already work. They write code to files. They read output from files. They compose commands with pipes. ArcFlow gives them a world model that works the same way — because it's built on the same substrate.
One-Shot Batch Execution#
Five queries in, five results out, one CLI call:
# Agent writes queries
ls queries/
# analyze.cypher dependencies.cypher metrics.cypher pagerank.cypher schema.cypher
# Execute all at once
arcflow --data-dir ./project-graph --exec-dir queries/ --output-dir results/
# All results appear as JSON
ls results/
# analyze.json dependencies.json metrics.json pagerank.json schema.jsonOne invocation. Five graph queries executed. Five typed result files. This is what zero protocol overhead looks like.
Watch Mode#
For interactive agent sessions, the CLI watches a directory and executes queries as they appear:
arcflow --data-dir ./project-graph --watch queries/ --output-dir results/The agent writes a query file. The result appears within milliseconds. The filesystem is the event loop.
Inline Execution#
For one-off queries, skip the file:
arcflow --data-dir ./graph --exec "MATCH (n:Person)-[:KNOWS]->(m) RETURN n.name, m.name" --jsonCLI-Native Tooling#
The CLI is designed for agents, not just humans. Every output format, exit code, and error message is machine-readable by design.
Structured Output#
Every command supports --json:
# Agent-readable
arcflow --data-dir ./graph --exec "MATCH (n) RETURN count(*)" --json
# => {"columns":["count(*)"],"rows":[{"count(*)":"10234"}],"count":1}Deterministic Exit Codes#
0 — Success
1 — Query error (syntax, missing label)
2 — System error (file not found, permission denied)
3 — Validation error (constraint violation)
The agent checks $?. No string parsing.
Structured Errors with Recovery Hints#
{
"ok": false,
"code": "PARSE_FAILED",
"message": "Unknown keyword 'METCH'",
"recovery_suggestion": "Did you mean MATCH?"
}The agent reads recovery_suggestion and self-corrects. No retry loop.
Schema Discovery#
arcflow --data-dir ./graph --exec "CALL db.schema()" --jsonReturns every label, relationship type, property key, index, and constraint. The agent knows the shape of the world model before writing a single query.
Dry-Run Validation#
arcflow --data-dir ./graph --validate "MATCH (n:Person) RETURN n.name"
# => Valid (read-only)The agent checks before executing. No wasted mutations.
Filesystem vs. Protocol: The Full Picture#
| Dimension | Filesystem | Protocol (MCP) |
|---|---|---|
| Latency | Disk I/O (~0.1ms) | JSON-RPC round-trip (~5–50ms) |
| Token cost | Zero | ~100–500 tokens per call |
| Batch queries | One CLI call for N queries | N tool calls, N round-trips |
| Persistence | Queries and results are durable files | Session-scoped, ephemeral |
| Version control | git add queries/ — commit your world model | Not possible |
| Offline | Works without a connection | Requires running server |
| Debugging | cat results/query.json, diff | Inspect MCP logs |
| Agent compatibility | Every agent reads files | Only MCP-native agents |
| CI/CD | Graph queries as build steps | Requires live session |
The filesystem wins on every dimension that matters for shell-native agents. Protocol wins on exactly one: compatibility with chat UIs that have no shell. That's the only case where MCP belongs.
Agent Workflows#
Claude Code: Codebase Intelligence#
# 1. Create workspace
mkdir -p project-graph/queries
# 2. Build the world model from codebase analysis
cat > project-graph/queries/01-create.cypher << 'EOF'
CREATE (c:Crate {name: 'my-core', loc: 5500, tests: 120})
CREATE (c:Crate {name: 'my-runtime', loc: 17000, tests: 467})
MATCH (a:Crate {name: 'my-runtime'}) MATCH (b:Crate {name: 'my-core'})
CREATE (a)-[:DEPENDS_ON]->(b)
EOF
# 3. Query the world model
echo "CALL algo.pageRank()" > project-graph/queries/02-analyze.cypher
echo "MATCH (c:Crate) RETURN c.name, c.loc ORDER BY c.loc DESC" > project-graph/queries/03-report.cypher
# 4. Execute all — one call
arcflow --data-dir project-graph --exec-dir project-graph/queries/ --output-dir project-graph/results/ --json
# 5. Read results
cat project-graph/results/02-analyze.jsonThe agent gets graph intelligence with the same operations it uses for everything else: write a file, run a command, read a file.
Impact Analysis Before Editing#
# Before touching src/auth.ts, understand what breaks
echo "MATCH (f:File {path: 'src/auth.ts'})-[:IMPORTS*1..3]->(d) RETURN d.path" \
> project-graph/queries/impact.cypher
arcflow --data-dir project-graph --exec project-graph/queries/impact.cypher --json
# Agent reads the affected files before making changesMulti-Agent Coordination#
Multiple agents share the same filesystem workspace. Each writes queries, reads results. The world model is the shared state. No message broker. No coordination protocol. Just files.
project-graph/
├── arcflow.db # Shared world model
├── agent-a/queries/ # Agent A queries
├── agent-a/results/ # Agent A results
├── agent-b/queries/ # Agent B queries
├── agent-b/results/ # Agent B results
└── shared/results/ # Cross-agent outputs
Agent A writes observations. Agent B queries them. Agent C runs algorithms. The filesystem IS the coordination protocol.
MCP: When You Need It#
MCP is for Claude.ai, ChatGPT web, Gemini web, and other cloud chat interfaces that have no local shell. In those environments, protocol is the only bridge. Latency is acceptable — the user is waiting for a chat response anyway.
For those environments:
npx arcflow-mcp --data-dir ./my-graphAvailable tools: get_schema, read_query, write_query, graph_rag. See MCP Server for setup and configuration.
If your agent has a shell, do not use MCP. It adds a protocol layer that exists to solve a problem you don't have.
Vision#
Every shell-native AI agent deserves a persistent, queryable world model as its working memory — accessible through the same interface it already uses for everything else.
The world model as files. Most agents lose context between sessions. ArcFlow's filesystem workspace persists across sessions, across agents, across machines. The graph is the agent's long-term memory, stored as files it can read, write, query, and version-control. Commit your world model. Diff it between runs. Share it across a team.
Zero-overhead agent tooling. MCP was a necessary step — it standardized tool calling for agents without shells. The next step is tighter: agents that read and write files at filesystem speed, with graph queries as natural as grep. Not because it's simpler — because it's aligned with how agents already work.
The filesystem as the coordination substrate. When multiple agents share an ArcFlow workspace, the graph becomes the coordination layer. No message broker. No orchestration framework. No shared memory API. Agent A writes facts. Agent B queries them. Agent C runs PageRank on the combined graph. The filesystem is the protocol. The world model is the shared brain.
See Also#
- Swarm & Multi-Agent — multi-agent coordination patterns, durable workflows, named sessions
- Building a World Model — step-by-step: entities in space, temporal memory, live monitoring
- ArcFlow for Coding Agents — CLI patterns, structured errors, batch execution, and checkpointing
- Live Queries —
LIVE MATCHandCREATE LIVE VIEWfor always-current agent state - Temporal Queries —
AS OF seq Nfor replay, debugging, and session reconstruction - Skills — teach the world model a new relationship rule in plain language; compiled once, executed at graph speed forever
- MCP Server — cloud chat UI integration (Claude.ai and similar)