rust-faf-mcp
Persistent Project Context for Rust MCP clients. Native. Fast. cargo install
The Lineage Edition (v0.8.3) — one.faf/rust-faf-mcp · rmcp 3.0.1 (MCP Tier 1 foundation) · faf-rust-sdk 3.1.1 (the same always-33 kernel faf-wasm-sdk uses) · solid cargo-native Rust MCP for Rust devs
v0.8.3 — --version and --help answer instead of starting the server. See CHANGELOG.
FAF defines. AGENTS.md instructs. AI codes.
Stop re-explaining your project to every AI session. One
.faffile holds your persistent project context. Every AI reads it once and knows what you're building.
Rust-native MCP (Model Context Protocol) server for FAF — structured AI project context in YAML (application/vnd.faf+yaml). Single binary, stdio transport, 4.3 MB stripped. Built on rmcp and faf-rust-sdk.
Quickstart
# Rust toolchain (install):
# No Rust (try — downloads GH Release binary for darwin/linux):
Point an MCP client at the pin. A bare rust-faf-mcp on PATH may be an old Homebrew binary.
# Claude Code
// Cursor, Claude Desktop, Windsurf — any client that reads mcpServers
{
"mcpServers": {
"faf": {
"command": "npx",
"args": ["--yes", "rust-faf-mcp@0.8.3"]
}
}
}
After cargo install rust-faf-mcp --version 0.8.3, "command": "rust-faf-mcp" is the install. Until you have proven that binary, use the npx pin.
No flags, no config files, no network listener. Pure stdio JSON-RPC.
Or via Homebrew (macOS, pre-built). If you already have it, upgrade — an old keg can sit on PATH as rust-faf-mcp:
# already installed:
One command, done forever
faf_auto runs setup if project.faf is missing (tree detection writes mechanical facts), then syncs CLAUDE.md. It does not rewrite an existing file. Confirm setup (sweeps) lists what setup occupied — walk it; not a second write-gate. Empty human slots stay empty until you state them.
faf_auto complete
━━━━━━━━━━━━━━━━━
Score: 0% → 42% (+42) ● GREEN
Steps:
1. Setup — created project.faf
2. Created CLAUDE.md
Path: /home/user/my-project
Confirm setup (sweeps)
Walk these. Detection is already a fact. Not a second write-gate.
project.name my-api
project.main_language Rust
stack.backend Rust
What it produces:
# project.faf — your project, machine-readable
faf_version: "3.3"
project:
name: my-api
goal: REST API for user management
main_language: Rust
version: "0.1.0"
license: MIT
instant_context:
what_building: REST API for user management
tech_stack: Rust 2024
key_files:
- Cargo.toml
- src/main.rs
- README.md
commands:
build: cargo build
test: cargo test
stack:
backend: Rust
build: cargo
Every AI agent reads this once and knows exactly what you're building. No 20-minute onboarding. No wrong assumptions.
Tools
Create & Detect
| Tool | What it does |
|---|---|
faf_auto |
Setup if missing, sync CLAUDE.md, score — Confirm setup (sweeps); does not invent 6Ws |
faf_init |
Setup: first write from the tree. Refuses if the file exists. Confirm setup (sweeps). 6Ws stay empty |
faf_go |
Table-of-8 + Confirm setup (sweeps). 6Ws score after ☑. Below 100: add Human Context. After 100: courtesy check every 30 days (90 max) |
faf_git |
Author project.faf from any GitHub repo URL — no clone needed. Uses the public GitHub API; returns the text, writes nothing |
faf_discover |
Walk up the directory tree to find the nearest project.faf |
Score & Validate
| Tool | What it does |
|---|---|
faf_score |
Score AI-readiness 0-100% with field-level breakdown |
faf_sync |
Sync project.faf → CLAUDE.md (preserves existing content) |
faf_agents |
Author AGENTS.md from project.faf (non-destructive, preserves hand-written content) |
Optimize
| Tool | What it does |
|---|---|
faf_read |
Parse and display project.faf contents |
faf_compress |
Compress .faf for token-limited contexts (minimal / standard / full) |
faf_tokens |
Estimate token count at each compression level |
Lineage
| Tool | What it does |
|---|---|
faf_dna |
Your FAF DNA journey from .faf-dna: Birth DNA to now, with history. faf_init births it, faf_auto records growth — the same file as faf-cli |
Every tool declares MCP annotations: faf_read, faf_score, faf_compress, faf_discover, faf_tokens, faf_dna and faf_git are read-only; the writers are non-destructive; only faf_git reaches the network.
faf_init will not overwrite an existing file. Setup occupies mechanical facts; Confirm setup (sweeps) is the walk. Empty human slots stay empty until faf_go.
Architecture
src/
├── main.rs # ~20 lines — tokio entry, rmcp stdio transport
├── server.rs # FafServer: #[tool_router], ServerHandler, resources
└── tools.rs # Business logic — tools as pure functions returning Value
- Runtime:
tokiosingle-threaded (current_thread) - HTTP:
reqwestasync (only used byfaf_gitfor GitHub API) - SDK:
faf-rust-sdk3.1 (Cargo pin — the facade overfaf-kernel/faf-fafbin faf-rust;score()for the always-33 number,validate()for structural checks only) - Server:
rmcp3.0.1 with#[tool_router]/#[tool_handler]— JSON-RPC, JSON Schema from the param types, stdio transport (Tier-1 assessed SDK cut)
Tools return serde_json::Value. The server adapts them to Result<String, String> for rmcp's IntoCallToolResult.
Testing
193 tests (146 integration + 47 unit):
# Full ship bar (same gates as GitHub CI — run before push)
# Optional: block push on red CI twin
| File | Tests | Coverage |
|---|---|---|
mcp_protocol.rs |
10 | Init handshake, tools/list, tool annotations, resources, schema validation, ID preservation |
tools_functional.rs |
31 | Tools — happy path, error paths, language detection, faf_go |
tier1_security.rs |
12 | Path traversal, null bytes, shell injection, oversized input, malformed JSON |
tier2_engine.rs |
36 | Corrupt YAML, sync replacement, pipelines, dual manifests, legacy filenames, direct paths |
tier3_edge_cases.rs |
10 | Unicode, CJK, score boundaries, unknown fields, GitHub URL parsing |
tier4_aero.rs |
22 | Manifest structure, version sync, server.json, context block, manifest-server cross-validation |
wjttc_setup.rs |
16 | Setup / Confirm setup (sweeps) — BRAKE · ENGINE · AERO · TYRE · PIT |
wjttc_faf_dna.rs |
7 | .faf-dna lineage — faf_init birth, faf_auto growth, faf_dna, faf-cli's lines |
src unit |
47 | setup sweep, skills digest, agents::, inject::, intent, app-type, dna:: lineage + faf-cli fixtures |
Tests spawn the compiled binary as a subprocess and communicate via stdin/stdout JSON-RPC — true integration tests against the real server.
FAF Ecosystem
One format, every AI platform.
| Package | Platform | Registry |
|---|---|---|
| rust-faf-mcp | Rust | crates.io |
| claude-faf-mcp | Anthropic | npm + MCP #2759 |
| gemini-faf-mcp | PyPI | |
| grok-faf-mcp | xAI | npm |
| faf-cli | Universal | npm |
Build from source
# Binary at target/release/rust-faf-mcp (about 5 MB)
Edition: 2024 | LTO: enabled | Strip: symbols
If rust-faf-mcp has been useful, consider starring the repo — it helps others find it.
Links
-
npmjs.com/package/rust-faf-mcp —
npx --yes rust-faf-mcp@0.8.3(no Rust toolchain; downloads GH Release binary) -
Dual-package publish guide — cargo + npm (this server is the product example)
-
docs/DUAL-PACKAGE.md — pointer + OIDC docs for this repo
-
docs/SKILLS-OVER-MCP.md — J1 Agent Skill
faf-context(skills/list · digests) -
faf-rust-sdk — the parser this depends on
-
faf.one — FAF home
-
IANA registration —
application/vnd.faf+yaml -
MCP Registry name:
mcp-name: one.faf/rust-faf-mcp
Citation
If you use rust-faf-mcp or the .faf / .fafa formats in research or production, please cite the format papers:
Wolfe, J. (2025). Format-Driven AI Context Architecture: The .faf Standard for Persistent Project Understanding. Zenodo. https://doi.org/10.5281/zenodo.18251362
Wolfe, J. (2026). Why Agents Need a Passport: .fafa — Portable Identity for the Agentic Era. Zenodo. https://doi.org/10.5281/zenodo.21951641
License
MIT
Built by @wolfe_jam | wolfejam.dev