foundry-ai docs
foundry-ai is a governance and memory layer for AI coding agents. It wraps Claude Code, Cursor, Codex CLI, and any MCP-compatible agent with persistent memory, inviolable guardrails, and a PM-driven workflow — without replacing them.
Quick start
From zero to first captured session in under 5 minutes.
Installation
Install the fnd CLI via your preferred package manager:
$ npm install -g foundry-ai # or $ pnpm add -g foundry-ai $ bun add -g foundry-ai # or via curl (Linux / macOS) $ curl -fsSL https://get.foundry.ai | sh
Initialize a project
Run fnd init inside any repository. The wizard creates .fnd/echo (the encrypted store), registers Claude Code hooks, and adds the foundry-ai MCP server to your agent config.
$ cd my-project $ fnd init ┌ foundry-ai · init │ ◆ What is the purpose of this project? │ A SaaS product for managing X │ ◆ What are the non-negotiables? (comma-separated) │ no secrets in code, tests required for auth │ ✓ .fnd/echo created (SQLCipher AES-256) ✓ Claude Code hooks registered ✓ MCP server registered in ~/.claude/settings.json
Verify with fnd doctor
$ fnd doctor ✓ echo .fnd/echo readable, chain clean ✓ chain 248 entries, 0 breaks ✓ claude hooks installed (UserPromptSubmit Stop PostToolUse SessionStart) ✓ mcp foundry-ai server registered ✓ daemon running · pid 12483 ✓ events 12 captured in the last 24h
All six checks passing means memory capture is live, hooks are wired, and governance is active.
Commands
Every fnd subcommand. All commands operate on the nearest .fnd/echo found by walking up from the current directory.
fnd init setup Interactive wizard that creates .fnd/echo, registers Claude Code hooks, and adds the foundry-ai MCP server. Safe to re-run — idempotent.
fnd init [--non-interactive] fnd daemon runtime Manages the background daemon that drains the hook queue, serves Unix socket IPC, and optionally listens for GitHub webhooks.
fnd daemon start [--detach] [--tcp-bind ADDR] [--http-bind ADDR] [--auto-audit]
fnd daemon stop
fnd daemon status fnd connect auth Authenticates to PM providers (Jira, Asana) and GitHub. Credentials are encrypted with L3 AES-GCM and stored in .fnd/echo. Never written to disk in plaintext.
fnd connect jira [--site HOST] [--email EMAIL]
fnd connect asana [--workspace LABEL]
fnd connect github [--repo owner/repo]
fnd connect list fnd spec workflow Full spec lifecycle: create, inspect, advance status, search. Specs are the unit of agent work — every ticket should become a spec before execution.
fnd spec new --title "Add auth"
fnd spec list [--status draft|audited|executing|done|abandoned]
fnd spec show ID
fnd spec set-status ID executing
fnd spec from-ticket jira:PROJ-123 fnd memory search FTS5 full-text search over all captured agent events. Supports time windows and source filters.
fnd memory "why did we choose X"
fnd memory --since 24h
fnd memory --session SESSION_ID
fnd memory --source cursor fnd score governance Computes the unified project health score from local signals: Business alignment, Security (Sentinel), Integrity (HMAC chain), Testing, Patterns, Efficiency.
fnd score [--json] fnd doctor debug Runs 6 health checks and reports issues. Echo integrity, HMAC chain, Claude hooks, MCP registration, daemon status, recent event activity.
fnd doctor [--json] MCP server tools
foundry-ai exposes 10 tools via its MCP server (fnd mcp serve). Any MCP-compatible agent — Claude Code, Cursor, Codex CLI — can call them.
The server is registered at ~/.claude/settings.json → mcpServers.foundry-ai by fnd init.
memory.*
memory.search (query: string, limit?: number) → EventHits FTS5 full-text search over all captured agent events (prompts, tool calls, sessions). Returns ranked hits with snippets.
memory.recent (since_ms: number, limit?: number) → EventHits List events captured after a unix-ms timestamp. Useful for "what happened in the last session" context.
spec.*
spec.list (status?: string, limit?: number) → SpecListOutput List all specs, optionally filtered by lifecycle status (draft | audited | executing | done | abandoned).
spec.get (id: number) → SpecGetOutput Fetch one spec with full body, session context, and ticket reference.
spec.create (title, body?, session_id?, ticket_ref?) → IdOutput Create a new spec in draft status. Link to a ticket ref (e.g. jira:PROJ-123) to close the PM loop.
spec.set_status (id: number, status: string) → StatusOutput Advance or revert a spec through its lifecycle. Transitions are journal-covered.
spec.set_audit (spec_id, verdict, reasoning, by_agent) → AuditOutput Persist an architect verdict (pass | fail | conditional). A pass verdict auto-promotes draft → audited.
pm.get_ticket
Fetches a PM ticket from Jira or Asana and returns it enriched with linked spec, memory fragments,
project constraints, and a next_action_hint — all in one call.
Requires prior fnd connect jira or fnd connect asana.
// Input
{"ref": "jira:PROJ-123"} // or "asana:<gid>"
// Output
{
"ref": "jira:PROJ-123",
"title": "Add OAuth login",
"description": "...", // Sentinel-sanitized
"status": "In Progress",
"spec": { "id": 4, "status": "executing" },
"memory_fragments": ["..."],
"constraints": "...",
"next_action_hint": "spec_executing",
"_foundry_metrics": {
"calls_replaced": 4,
"estimated_tokens_saved": 800
}
} spec_missing → create spec ·
spec_draft → audit it ·
spec_executing → continue work ·
spec_done → verify closure
sentinel.sanitize
Redacts secrets from any text using local pattern detectors — no network, no LLM. Detects: AWS keys, GitHub tokens, OpenAI keys, Anthropic keys, Slack tokens, Stripe keys, JWTs, private keys, and more.
// Input
{"text": "token=sk-ant-api03-abc123"}
// Output
{"redacted": "token=[ANTHROPIC_KEY]", "findings": [...]} master_context.get
Returns the project's master context — purpose, tech stack, and non-negotiable rules — set during fnd init.
The architect uses this to audit specs against business intent.
Configuration
master_context
The master context defines what the project is and what it must never do.
Set during init, editable via fnd init --update-context.
Purpose: B2B SaaS — invoice management platform
Stack: Next.js + Postgres + Stripe
Non-negotiables:
- No secrets in version control
- Auth changes require security review
- All DB queries must use parameterized inputs Claude Code hooks
foundry-ai registers four hooks in ~/.claude/settings.json:
{
"hooks": {
"UserPromptSubmit": [{ "command": "/path/to/fnd hook UserPromptSubmit" }],
"Stop": [{ "command": "/path/to/fnd hook Stop" }],
"PostToolUse": [{ "command": "/path/to/fnd hook PostToolUse" }],
"SessionStart": [{ "command": "/path/to/fnd hook SessionStart" }]
},
"mcpServers": {
"foundry-ai": { "command": "/path/to/fnd", "args": ["mcp", "serve"] }
}
} Daemon options
| Flag | Default | Description |
|---|---|---|
--detach | false | Fork to background (write PID to .fnd/daemon.pid). |
--tcp-bind ADDR | off | Serve multi-device TCP clients on this address (e.g. 0.0.0.0:7877). |
--http-bind ADDR | off | Listen for GitHub webhooks (M6 Outpost) on this address. |
--auto-audit | false | Spawn claude -p to audit PRs headlessly when a webhook arrives. |
PM Integration
Connect once. All agents get enriched PM context through pm.get_ticket.
Credentials are encrypted with L3 AES-GCM before being stored in .fnd/echo.
Jira
Requires a Jira Cloud account and an API token from id.atlassian.com.
$ fnd connect jira ? Jira site acme.atlassian.net ? Email you@acme.com ? API token •••••••••••••••• ✓ testing credentials… ✓ Jira connected (acme.atlassian.net)
Once connected, agents can call:
pm.get_ticket({"ref": "jira:PROJ-123"}) Asana
Requires a Personal Access Token from app.asana.com/0/my-apps.
$ fnd connect asana ? PAT •••••••••••••••• ✓ testing credentials… ✓ Asana connected (workspace=default)
How it fits together
foundry-ai is a Rust workspace with 7 crates. Everything revolves around .fnd/echo — the single encrypted SQLite store for the project.
fnd-echo SQLCipher-encrypted SQLite with HMAC tamper chain. Stores events, specs, PM tokens, GitHub connections. Three-layer key hierarchy (master → journal → pm_token).
fnd-cli The fnd binary. Dispatches to all subcommands, manages hook installation, multi-device config.
fnd-mcp MCP server (stdio). Serves the 10 tools the architect uses from inside the agent session.
fnd-runtime The daemon: drains the hook queue (250ms ticks), serves Unix socket IPC and optional TCP, runs the HTTP listener for GitHub webhooks.
fnd-bridge PM adapters (Jira, Asana) + GitHub webhook parsing and auto-audit via claude -p.
fnd-sentinel Local secret detection using Aho-Corasick + regex. Zero network, zero LLM. 10 secret kinds.
fnd-cli ──> fnd-echo, fnd-bridge, fnd-mcp, fnd-runtime, fnd-sentinel fnd-mcp ──> fnd-echo, fnd-bridge, fnd-sentinel fnd-runtime ──> fnd-echo, fnd-bridge fnd-bridge ──> fnd-echo fnd-sentinel, fnd-echo, fnd-core ── no internal deps