claude-faf-mcp
Persistent project context for Claude: this MCP server creates, scores, verifies, and syncs a project's .faf context file, plus cross-session memory.
Create/fill context —
faf_initcreatesproject.faf(stack auto-detected),faf_autofills empty slots from repo manifests,faf_gocollects the human 6Ws (who/what/why/where/when/how) via guided Q&A.Score & verify —
faf_scoregives a 0–100% AI-readiness score from faf-cli with a parity hash;faf_trustreturns a self-verifiable trust receipt;faf_doctordiagnoses empty/invalid slots with the fix for each.Sync context to other files —
faf_syncwritesCLAUDE.md(plus AGENTS.md, .cursorrules, GEMINI.md, copilot-instructions.md on request);faf_tri_syncwrites the faf block into Claude Code'sMEMORY.md.Session setup —
faf_setupinstalls a SessionStart hook (preview first) so every Claude Code session opens with fresh .faf context;faf_contextshows/sets the active project and returns the .faf text.Memory across sessions —
faf_etchstores decisions/gotchas/wins insoul.fafm;faf_recallretrieves them ranked by priority/tags/type/query.Prove value —
faf_benchmeasures grounding lift (cold vs with-.faf answers) with a verifiable receipt.Learn the format —
faf_aboutexplains what.fafis (IANAapplication/vnd.faf+yaml).
Utilizes a specialized IANA-registered YAML format (application/vnd.faf+yaml) to store and manage structured project context, enabling rapid scoring and synchronization of AI-readiness.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@claude-faf-mcpcreate a project.faf for my Express API with JWT auth"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
claude-faf-mcp
Home: faf.one/mcp Site: claude.faf.one
Persistent Project Context with Memory, looped for you. One-click setup. 30 seconds. 🐘 Nelly Never Forgets.
FAF defines. MD instructs. AI codes.
⭐ Bookmarks it for you, helps other devs find it too.
v0.2-conformant reader of the FAF Context Ingestion Contract.
🐘 tri-sync |
.faf→MEMORY.md(faf_tri_sync), alongside.faf→CLAUDE.md(faf_sync).
⚡ The
fafprompt — pick it from your host's prompt list (Claude Code shows it as/mcp__<server name>__faf). It scores your project, fills what the repo can, asks you only what only you can answer, verifies, and syncs.
6.0.0 is a major release. It needs Node 22 or later.
faf_clear,faf_friday,faf_guideandfaf_writeare retired, and so are the AGENTS.md / .cursorrules / GEMINI.md / conductor imports into project.faf. The.mcpbnow runs the server bundled inside it. The npx config and the SessionStart hook are not pinned to a version, so an install that runsnpx -y claude-faf-mcpmoves to 6.x on its next start: check your Node before you upgrade. Every change is in the CHANGELOG.
Context for Claude: faf-cli writes this repo's CLAUDE.md from its scored project.faf — faf_sync here, faf sync in faf-cli. See FAF-CLI for Claude Code 👀.
Composes faf-cli (the version is pinned in package.json). Detection, scoring, the renders and every writer are faf-cli's own functions, loaded as a dependency; claude-faf-mcp does not fork them and never runs a faf found on your PATH.
Core 14 MCP tools (30 with FAF_TOOLS=all). IANA-registered formats (application/vnd.faf+yaml · application/vnd.fafm+yaml).
What's New in v6.0.0 — The Earned Badge Edition
Every badge earned, none claimed: claude-faf-mcp 6.0 composes faf-cli, touches only what it wrote, and every tool tells the truth — one score, facts from repo, nothing from your PATH.
Composes faf-cli 7.13. Detection, scoring, the renders and every writer are faf-cli's own functions. claude-faf-mcp never runs a
fafit finds on your PATH.Touches only what it wrote.
Every write is atomic and goes through faf-cli's safe path, and a file that links out of the project is refused.
project.faf edits keep your comments and exact values.
Your soul.fafm and Claude's own MEMORY.md notes stay as you left them.
One score. Every tool shows faf-cli's score, and ✪ appears only at 100%.
Facts from repo. Every empty slot says what fills it:
a fact from repo, which
faf_autowrites;no fact in repo, which you answer with
faf_go;or yours, for the 6Ws.
Tools that tell the truth.
Every title, hint and schema matches what the tool does, and bad arguments are refused before anything runs.
Core 14:
faf_setupandfaf_tri_syncjoin the default list.
Safe with any repo.
A cloned repo's symlinks never reach your AI's context.
faf_goanswers can't pollute objects.The file tools stay inside the active project.
Ships what it runs. The
.mcpbruns the server bundled inside it, and it's started and checked before its sha is recorded. Node 22+, with CI on Node 22 and 24 across Ubuntu, macOS and Windows.Retired:
faf_clear,faf_friday,faf_guide,faf_write, the interop imports into project.faf, andfaf_checkprotect/unlock. The archive tagarchive/cfm-v5-surfacekeeps them.
Related MCP server: gemini-faf-mcp
The 3Ws — 3 Answers. That's It.
Every great product started with 3 answers to the 3Ws — Who, What, Why:
WHO is it for? | WHAT does it do? | WHY build it? | |
Uber | People who need a ride | Tap a button, car arrives | Taxis were broken |
Airbnb | Travelers who can't afford hotels | Stay in someone's spare room | Millions of empty rooms exist |
Slack | Teams drowning in email | Organized group messaging | Decisions buried in threads |
Venmo | Friends splitting bills | Send money instantly | Someone always forgets to pay back |
Same pattern. Every product that works starts here. .faf captures it:
human_context:
who: "people who need a ride across town"
what: "tap a button, car arrives in minutes"
why: "taxis are slow, expensive, and hard to find"30 seconds. Claude builds your project.faf from this. Every session after, AI starts smart.
The 6Ws — For Optimized AI
3Ws gets you started. For fully optimized AI, complete the set — Where, When, How:
where: "mobile app, iOS and Android" # where does it live?
when: "launch in 3 months" # when is it shipping?
how: "GPS matching, real-time pricing" # how does it work?3Ws initiates the project with AI. 6Ws optimizes AI to 100%. Same YAML, same file. More examples → faf.one/ideas
Quick Start
Needs Node 22 or later.
Claude Desktop — one click
⬇ Download claude-faf-mcp-6.0.0.mcpb
Open it in Claude Desktop. The extension runs the server bundled inside it (no npx, no network at start) and lists the Core 14 tools.
Claude Desktop — config
Add to claude_desktop_config.json, then restart Claude Desktop:
{
"mcpServers": {
"faf": { "command": "npx", "args": ["-y", "claude-faf-mcp"] }
}
}After npm install -g claude-faf-mcp you can use the installed bin instead: { "command": "claude-faf-mcp" }. With Bun on Claude Desktop's PATH, { "command": "bunx", "args": ["claude-faf-mcp"] } works too.
Claude Code
claude mcp add faf -- npx -y claude-faf-mcpPinning
The npx config and the SessionStart hook faf_setup installs (npx -y claude-faf-mcp --session-refresh) are not pinned: they run the latest release, so fixes arrive without a reinstall, and a new major arrives the same way. To stay on a major, write it in your config yourself: "args": ["-y", "claude-faf-mcp@6"]. The .mcpb runs the version it was built from.
Then
Run the faf prompt — Claude scores your project, fills what the repo can, asks you what only you can answer, verifies and syncs.
Or tell Claude your 3Ws: "I'm building [what] for [who] because [why]"
faf-cli — any terminal
npx faf-cli autoSame .faf, every surface — Claude, Gemini, Grok, Cursor. faf-cli on npm →
How It Works
You → 3 answers → project.faf → AI reads it → every session → forever
project.faf ──→ CLAUDE.md (faf_sync)
project.faf ──→ MEMORY.md (faf_tri_sync 🐘)Language, framework, package manager, build tools — faf-cli detects them from your existing files. The human context is the part only you can give.
For Claude Code teams
.faf lives in the repo. Your context travels with the code — committed, versioned, done.
Every session starts grounded. Install the native SessionStart hook once (faf_setup — preview first, your settings preserved). After that, every Claude Code session opens with a one-line heartbeat instead of a blank slate:
faf: context ✪ 100% — fresh · +7 intent the code can't carryThat line is the relay: Claude already knows your stack and your score — and the +N is the intent the code can't carry: the goal and 6Ws only you can give or confirm. No re-explaining "what this project is" at the top of every session.
It scales to the team by construction:
commit project.faf → every teammate's Claude starts with the same context
git clone → a new dev's Claude is grounded before they write a lineOne source of truth.
faf_syncwritesCLAUDE.mdfrom.faf— only its faf-managed block, so your own notes stay put. AddMEMORY.mdfor cross-session memory (tri-sync 🐘).No drift. The score is deterministic — same
.faf, same number, on every machine and in CI. A teammate can't be accidentally less grounded than you.Local. No accounts, no telemetry, nothing sent to FAF. The one network use is cloning a repo you name, only when you ask (privacy). The context is yours; it rides in the repo.
Onboarding becomes git clone → grounded. The context a new teammate would normally pick up by asking around is already in the repo, machine-readable, from the first clone.
Scoring: From Blind to Optimized
Tier | Score | What it means |
✪ TROPHY | 100% | Gold Code — AI is optimized |
★ GOLD | 99%+ | Near-perfect context |
◆ SILVER | 95%+ | Excellent |
◇ BRONZE | 85%+ | Production ready |
● GREEN | 70%+ | Solid foundation |
● YELLOW | 55%+ | AI flipping coins |
○ RED | <55% | AI working blind |
♡ WHITE | 0% | No context at all |
At 55%, AI guesses half the time. At 100%, AI knows your project. The score is faf-cli's scoreFafYaml — the number faf score prints for the same file.
MCP Tools — Core 14, 30 with FAF_TOOLS=all
By default claude-faf-mcp lists the Core 14 — the lifecycle tools you reach for. Set FAF_TOOLS=all to list the Extended tools too; every tool is callable by name either way. Retired in 6.0.0: faf_clear, faf_friday, faf_guide and faf_write (a call by name returns one line naming what to use instead), the AGENTS.md / .cursorrules / GEMINI.md / conductor imports into project.faf, and faf_check protect/unlock.
Every tool runs on the faf-cli this package depends on. Nothing is run from your PATH.
Core
Tool | Purpose |
| Create project.faf for a folder (faf-cli detects the stack) |
| Fill project.faf from the repo's own files, then CLAUDE.md |
| The goal and the 6Ws, by question and answer |
| AI-readiness score (0-100%), from faf-cli |
| Benchmark AI grounding — cold vs with the .faf, graded mechanically, with a receipt |
| Diagnose project.faf: each finding with the tool that fixes it |
| Validate project.faf and return a trust receipt for its score |
| Write CLAUDE.md from project.faf — |
| Write faf's block into the MEMORY.md Claude Code loads for this project 🐘 |
| Install the SessionStart hook in the project settings (preview first) |
| Show or set the active project; |
| Remember a decision across sessions (the project soul, soul.fafm) |
| Recall memories from the project soul |
| What the .faf format is |
Extended (FAF_TOOLS=all)
Tool | Purpose |
| Start here: the project, its score and the steps to 100% (reads only) |
| Create project.faf from one line: name, goal, language, framework, hosting |
| Read the 6Ws from README.md; |
| Set one 6W slot in project.faf |
| The formats faf-cli finds in the folder, and what faf_auto would write (dry run) |
| Author a project.faf from a repo URL (clones it with git — uses the network) |
| faf-cli's validateFaf and the state of every slot |
| The project's .faf-dna lineage (reads only) |
| Whether the project has a .faf, with its first lines |
| Write AGENTS.md (OpenAI Codex and other agents) |
| Write .cursorrules (Cursor IDE) |
| Write GEMINI.md (Google Gemini CLI) |
| Write Google Conductor's conductor/ files |
| Read a file inside the active project |
| List a folder inside the active project |
| The active project, write access and the bundled faf-cli version |
🐘 Nelly Never Forgets
faf_sync writes CLAUDE.md from .faf, so the two stay aligned.
tri-sync adds MEMORY.md — your AI remembers your project across every session.
faf_sync = .faf → CLAUDE.md ← written from .faf
tri-sync = .faf → MEMORY.md (faf_sync writes CLAUDE.md) ← Nelly never forgets 🐘Pro feature, free for developers. Teams & Enterprise: faf.one/pro (plans)
The .FAF Position
Model Context Protocol
───── ─────── ────────
Claude → .faf → MCP
Gemini → .faf → MCP
Codex → .faf → MCP
Any LLM → .faf → MCPIANA-registered (application/vnd.faf+yaml). One file, one format. Define once, use everywhere.
Ecosystem
Package | Platform | Registry |
claude-faf-mcp (this) | Claude | npm |
CLI | npm + Homebrew | |
Google Gemini | PyPI | |
xAI Grok | npm | |
Rust | crates.io | |
Browser/Edge | npm | |
Browser | Chrome Web Store |
Same project.faf. Same scoring. Same result. Different execution layer.
Quality
Tests run with bun on ubuntu, macOS and Windows; the built package is packed, installed and started on Node 22 and 24 on all three. CI →
Privacy
claude-faf-mcp runs on your machine. No analytics, no telemetry, no accounts. Its one network use is faf_git, and only when you ask it to read a repo: git clones it from the URL you give. The files it writes are listed in the privacy policy →
If claude-faf-mcp has been useful, consider starring the repo — it helps others find it.
Citation
If you use claude-faf-mcp or the .faf / .fafm / .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). Permanent Memory and Instant Recall: The .fafm Standard for Multi-Profile AI Agent Memory. Zenodo. https://doi.org/10.5281/zenodo.20348942
Wolfe, J. (2026). Why Agents Need a Passport: .fafa — Portable Identity for the Agentic Era. Zenodo. https://doi.org/10.5281/zenodo.21951641
BibTeX
@article{wolfe2025faf,
title = {Format-Driven AI Context Architecture: The .faf Standard for Persistent Project Understanding},
author = {Wolfe, James},
year = {2025},
month = {nov},
publisher = {Zenodo},
doi = {10.5281/zenodo.18251362},
url = {https://doi.org/10.5281/zenodo.18251362}
}
@article{wolfe2026fafm,
title = {Permanent Memory and Instant Recall: The .fafm Standard for Multi-Profile AI Agent Memory},
author = {Wolfe, James},
year = {2026},
month = {may},
publisher = {Zenodo},
doi = {10.5281/zenodo.20348942},
url = {https://doi.org/10.5281/zenodo.20348942}
}
@article{wolfe2026fafa,
title = {Why Agents Need a Passport: .fafa — Portable Identity for the Agentic Era},
author = {Wolfe, James},
year = {2026},
month = {aug},
publisher = {Zenodo},
doi = {10.5281/zenodo.21951641},
url = {https://doi.org/10.5281/zenodo.21951641}
}License
MIT — Free and open source
FAF Family
| |
MCP server for Claude Desktop | |
MCP server for Gemini CLI | |
MCP server for Grok | |
MCP server for Cursor, Windsurf, Cline, VS Code | |
MCP server in Rust | |
Claude Code skills for .faf | |
Blog, downloads, docs | |
Context format (2025-10-30) | |
Memory format (2026-05-13) |
format | driven 🏎️⚡️ wolfejam.dev
Get the CLI
faf-cli — The original AI-Context CLI. A must-have for every builder.
npx faf-cli autoMCP Registry: one.faf/claude-faf-mcp · 2 IANA registrations: vnd.faf+yaml (Context) · vnd.fafm+yaml (Memory) · faf.one · npm
Zero-Config. Context that's just there — every session.
Available Tools
14 toolsfaf_aboutAbout .fafARead-onlyIdempotentInspect
Explain what the .faf format is — project context for AI, IANA-registered as application/vnd.faf+yaml — and how this server uses it. Returns a short plain-text overview with this server's version. Reads nothing and writes nothing. Use it when someone asks what FAF is.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so safety is covered. The description adds useful behavioral context: it reads nothing and writes nothing, returns plain text, and includes the server version. This is more than the annotations provide and is clearly stated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core purpose. It is tight but slightly packs three ideas (definition, output, usage) into the first sentence, which is still efficient. Minor room to split, but no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter, no-output-schema tool, the description covers what it does, what it returns, and when to use it. With annotations covering read-only behavior, no further context is required.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so baseline is 4. The description correctly implies no input, and the schema confirms an empty object. No further parameter detail is needed or given.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Explain') and resource ('.faf format'), then adds concrete scope: what it is, how this server uses it, and that it returns a plain-text overview with server version. This clearly distinguishes it from siblings like faf_score or faf_init, which perform operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use guidance: 'Use it when someone asks what FAF is.' It doesn't name alternative tools, but none of the siblings serve this explanatory purpose, so implicit exclusivity is reasonable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
faf_autoFill from the RepoADestructiveIdempotentInspect
Create /project.faf, or fill the empty slots of the one there, with faf-cli's detection over the repo's own files (package.json, Cargo.toml, pyproject.toml, go.mod…) — no hardcoded defaults. A value already there is kept. A typed None or placeholder word is an empty slot: in a tech slot the app-type uses, only a repo fact replaces it (with no fact it stays as typed); in a tech slot the app-type leaves out, faf_auto writes slotignored; in a 6W it stays as typed (faf_go asks). Every value it changes is listed. Then writes CLAUDE.md's faf-managed block. Returns what was filled and faf-cli's score before and after. faf_go does the human 6Ws.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Project path. Sets session context for subsequent calls. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description explains exact fill rules, that existing values are kept, what happens to typed None/placeholder slots, that changes are listed, that CLAUDE.md's faf-managed block is written, and what the tool returns. This gives strong behavioral context for a destructive write tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and every sentence carries behavioral detail. It is dense and sentence three is complex, but no content appears purely redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description supplies the return information: filled values and faf-cli's score before and after. It also covers side effects, slot rules, and the related faf_go boundary, making it complete for this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has one parameter with 100% description coverage, so the schema already documents path and its session-context role. The description adds no further meaning about the path parameter, matching the baseline when schema coverage is high.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: it creates or fills <folder>/project.faf using repo detection. It also distinguishes its behavior from faf_go by noting that faf_go handles the human 6W questions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly indicates context: use it to auto-fill project.faf from repo facts, and defer human 6W input to faf_go. It does not list every alternative sibling such as faf_init or faf_sync, but the primary usage distinction is explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
faf_benchGrounding BenchmarkARead-onlyIdempotentInspect
Prove the .faf earns its place — measure how much the context is worth, on THIS repo, falsifiably. Questions derive from the project.faf's own populated slots (the .faf is the answer key), so grading is mechanical — no judge, no rubric. action=questions returns the answer-key-safe question set; action=grade takes your answers WITHOUT the .faf (cold) and WITH it (faf), grades both, and returns the cold→with-faf lift with a receipt hash. The delta is the product; the cold number belongs to the absence of context, never to FAF. Reads only.
| Name | Required | Description | Default |
|---|---|---|---|
| faf | No | action=grade: answers produced WITH the project.faf in context. Map of question number → answer string. | |
| cold | No | action=grade: answers produced WITHOUT the .faf (general repo knowledge only). Map of question number → answer string. | |
| path | No | Project path (optional — the active project if omitted). | |
| model | No | action=grade (optional): the model that produced the answers. | |
| action | No | questions = get the answer-key-safe question set to answer; grade = submit cold + with-faf answers to score the delta. Default: questions. | |
| fafTokens | No | action=grade (optional): tokens spent answering with the .faf. | |
| coldTokens | No | action=grade (optional): tokens spent answering cold. |
Output Schema
| Name | Required | Description |
|---|---|---|
| faf | No | action=grade — score WITH the .faf. |
| cold | No | action=grade — score WITHOUT context (absence baseline). |
| delta | No | with-faf minus cold — the product. |
| total | No | Number of questions in the set. |
| action | No | |
| receipt | No | faf-cli's bench receipt — sha256 over the canonical projection; third-party verifiable. |
| version | No | |
| protocol | No | in-session — answers are self-reported by the agent under test. |
| qsetHash | No | Hash of the question set — rides the receipt; same .faf reproduces it. |
| questions | No | action=questions only — NEVER includes the answer key. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive; the description adds real context beyond them - the questions are 'answer-key-safe', grading is mechanical with no judge or rubric, and the result is a cold→with-faf lift with a receipt hash. It also confirms the read-only nature ('Reads only'), consistent with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Content is dense and front-loaded: the purpose, the mechanism, and the two-action flow appear in order with no filler. Sentences are long and somewhat jargon-heavy, but each carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description needn't explain return values, and it still covers the two actions, their sequencing, and the meaning of the cold/faf split. An agent has enough to invoke it correctly, with only minor gaps like token-field usage not being explained narratively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, including per-parameter descriptions for faf, cold, action, and token fields, so the schema does the heavy lifting. The description reinforces the cold-vs-faf distinction and the default action but adds little syntactic detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a concrete purpose - measuring how much the project.faf context is worth on the current repo via mechanically graded questions - and enumerates both actions (questions, grade). It clearly differs from sibling tools like faf_score or faf_about, though the metaphorical opening ('earns its place') adds flavor before the operational statement.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear workflow: call action=questions to get the answer-key-safe set, then action=grade with cold and faf answers to obtain the delta. It does not explicitly state when to prefer this over siblings such as faf_score, but the internal usage guidance is concrete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
faf_contextActive ProjectARead-onlyIdempotentInspect
Show the active project — the folder every faf_* call without a path uses — and the .faf there; pass path to make another folder the active project (your home folder and the filesystem root are refused). detail: true also returns the .faf's text. Writes no file. Call it once at the start of a session.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Set active project path. If omitted, shows current context. | |
| detail | No | Also return the text of the .faf (read with faf-cli's reader), for reading project.faf in one call |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | No | The .faf file readers use (faf-cli's finder: the folder, then one level up), if found |
| active | Yes | Absolute path of the active project |
| hasFaf | Yes | Whether a project.faf (or .faf) was found there or one level up |
| changed | Yes | True if this call set a new context, false if it only reported |
| content | No | detail: true — the text of the .faf |
| filename | No | The .faf filename, if found |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered; the description adds real beyond-annotation context: the refusal of home folder and filesystem root, the fact that path redefines the context used by all other pathless faf_* calls, and 'Writes no file.' It is slightly redundant on the read-only point.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence-pair, front-loaded with the purpose and followed by parameter behavior and session guidance. Every clause earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need no explanation. The description covers purpose, both parameters, the state effect on sibling calls, refusal conditions, and session timing — complete for a simple 0-required-param context tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds meaning beyond the schema: path re-points the active project and has documented rejection cases, and detail:true surfaces the .faf text. These behavioral consequences go beyond the terse schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (show) and resource (the active project folder and its .faf), and clarifies the concept precisely: it is the folder every faf_* call without a path uses. This distinguishes it from siblings like faf_init or faf_about without needing schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to call it ('once at the start of a session') and when to pass path (to switch projects). It does not name an alternative sibling or state when-not-to-use, but the session-start guidance and the concept of the shared context are clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
faf_doctorDiagnose .fafARead-onlyIdempotentInspect
Diagnose the project's .faf: faf-cli's validateFaf errors, faf-cli's score with every empty slot and the tool that fills it (faf_auto from the repo, faf_go for the 6Ws), whether CLAUDE.md is there, and the formats faf-cli finds in the folder. Returns a checklist of findings, each with its fix. Reads only. Use it when faf_score is below 100%.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Project path. Sets session context for subsequent calls. |
Output Schema
| Name | Required | Description |
|---|---|---|
| score | No | faf-cli's score (-1 only with unknown: true), or null when not scored |
| valid | No | faf-cli's validateFaf verdict, or null when no .faf could be read |
| checks | Yes | Number of checks run |
| errors | No | Count of error-level findings |
| health | Yes | Overall verdict: ok | warning | error |
| unknown | No | True when the score is not known (an About repo with no about.source_score) |
| warnings | No | Count of warning-level findings |
| diagnostics | Yes | Per-check results |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, and the description's 'Reads only' merely restates that. It does add that the output is a checklist of findings each paired with a fix, which is mild extra context. With an output schema present and safety already covered, no deeper disclosure is required, but little is added beyond structured data.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core verb+resource, and the closing usage rule is short and actionable. The first sentence is a run-on packing several checks and two sibling names into one breath, which costs a little readability but there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers what is diagnosed, the read-only nature, and the trigger condition, and an output schema exists so return values need not be described. For a single-optional-parameter diagnostic tool this is close to complete, missing only explicit exclusions or a follow-up path.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is a single optional parameter whose schema description is 100% covered ('Project path. Sets session context for subsequent calls.'). The description adds no further meaning about the path argument, so the schema carries the load and baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Diagnose the project's .faf') and enumerates the checks performed: validateFaf errors, score/empty slots, CLAUDE.md presence, formats found. It also names the siblings that supply fixes (faf_auto, faf_go), so it is distinguishable. The dense parenthetical phrasing keeps it just short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger condition: 'Use it when faf_score is below 100%', which routes the agent from a sibling tool to this one. It does not state when not to use it or what to do after diagnosis, but the primary selection condition is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
faf_etchEtch MemoryADestructiveInspect
Remember a decision, gotcha, or win across sessions by writing it to the project soul (soul.fafm) with faf-cli's Soul. Returns the stored memory and the soul's size. Re-etching an id updates that memory in place. Use it to persist something an AI should recall later; faf_recall reads them back.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Stable id — re-etching the same id updates in place (dedup) | |
| path | No | Project path. Sets session context for subsequent calls. | |
| tags | No | Tags (e.g. decision, gotcha, win) for filtering + recall coupling | |
| text | Yes | The memory to remember — capture the why (decision/gotcha/win) | |
| type | No | Memory category | |
| priority | No | Recall ranks by priority then recency |
Output Schema
| Name | Required | Description |
|---|---|---|
| soul | Yes | Path to soul.fafm |
| total | No | Total memories in the soul |
| etched | Yes | |
| namepoint | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes beyond the annotations by disclosing the write target (soul.fafm), the dedup/update-in-place semantics of re-etching an id, and the return payload. It does not warn about the destructiveHint=true aspect beyond noting in-place overwrite, and no permission or auth prerequisites are mentioned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: purpose first, then the mutation/dedup rule, then the usage pointer to the alternative. No filler and nothing buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter mutation tool with full schema coverage, output schema present, and annotations already declaring the safety profile, the description covers purpose, persistence target, dedup behavior, and the sibling relationship. Nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter is already documented in the schema (id dedup, path session context, tags, priority ranking). The description adds no per-parameter meaning beyond that, which is the expected baseline when the schema carries the load.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (etch/remember) and resource (a memory written to soul.fafm), plus the storage mechanism (faf-cli's Soul). It is clearly distinguishable from sibling faf_recall, whose role is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear when: 'Use it to persist something an AI should recall later', and names the complementary reader faf_recall. It does not state any when-not conditions (e.g. don't etch ephemeral scratch state), so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
faf_goGuided InterviewADestructiveInspect
The human half of project.faf. Without answers it returns the Table-of-8 — project name, goal and the 6Ws (who, what, why, where, when, how) — each filled, seeded from the goal, or empty, with faf-cli's score and, for each slot still empty, whether it is a fact from repo (faf_auto writes it: its dry run, the one faf_formats shows) or needs an answer here. With answers (slot path → text, e.g. {"stack.hosting": ""}) it writes them into /project.faf in place and returns the new score; a value already in a slot you answer is replaced. With no project.faf yet it runs faf_init and faf_auto first. faf_auto writes each fact from repo; a stack slot with no fact in repo is answered here.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Project path. Sets session context for subsequent calls. | |
| answers | No | Answers to apply: a slot path (e.g. "project.goal", "human_context.why", "stack.database") → the answer text. Any other key, or an answer that is not text, is refused and nothing is written. If provided, applies the answers and returns the new score. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false and idempotentHint=false, so safety is covered structurally. The description adds real value beyond that: answers are written in place, an answered slot's existing value is replaced, invalid keys or non-text answers are refused with nothing written, and project.faf is created via faf_init/faf_auto if missing. That is meaningful side-effect disclosure for a mutating tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two long, densely nested sentences pack in every behavior but bury the critical read-vs-write fork mid-clause, so it is not front-loaded for quick scanning. The information is mostly load-bearing, but nested asides ('faf_auto writes it: its dry run, the one faf_formats shows') hurt parseability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden, and it does state the return (the Table-of-8 plus score in read mode, the new score in write mode). It also covers creation side effects and refusal behavior. What is missing is any guidance on subsequent calls or the session-context effect of path beyond the schema note.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both parameters are documented in the schema, so the baseline is 3. The description restates the slot-path→text answer shape and the refusal rule, but adds little syntax or format detail the schema does not already supply (its example values overlap the schema's own examples).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description defines a specific dual-mode tool: read-only interview output (the Table-of-8 seeded from the goal with score) when no answers are given, and an in-place writer of answers into <folder>/project.faf when they are. It positions itself against siblings by naming faf_auto and faf_init as things it invokes and faf_formats as showing the dry run. However, jargon like 'Table-of-8' and 'the human half of project.faf' assumes familiarity, so an unfamiliar agent needs more parsing than ideal.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implicitly delineates when each mode applies (no answers = inspect, answers = write) and names the parent workflow (faf_init/faf_auto run first if project.faf is absent). But there is no explicit 'use this instead of X' routing or stated prerequisites beyond that, so the agent must infer when faf_go beats faf_auto or faf_score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
faf_initCreate project.fafADestructiveInspect
Create a new project.faf for a folder: faf-cli detects its name, language and stack, and the reply gives the file path, faf-cli's starting score and the birth .faf-dna. An existing project.faf is left as it is — use faf_auto to fill its empty slots from your manifests, or faf_go for the human 6Ws. force: true replaces an existing project.faf with a fresh one, after copying the old file to a backup beside it.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Project path or name. Smart resolution: "my-app" finds ~/Projects/my-app OR ~/Code/my-app. Full paths like ~/Projects/app or /Users/me/code/app work too; ".", "..", "./app" are relative to the active project. Omit to create ~/Projects/unnamed-project; pass the workspace path to init it. Your home folder and the filesystem root are refused. | |
| force | No | Replace an existing project.faf with a fresh one: every value and comment in it is replaced. The old file is copied to project.faf.bak-<time> first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructive=true, but the description adds material context beyond them: an existing file is left untouched by default, and force:true copies the old file to a project.faf.bak-<time> backup before replacing. It also discloses what the reply contains (path, starting score, .faf-dna), which carries weight since no output schema exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core action and keeps to three dense sentences with no filler. Slightly heavy with multiple clauses, but every sentence carries useful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, zero-required-param create tool with no output schema, the description covers invocation outcome (returned values), default safety behavior, the force override, and alternatives. An agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already richly documented in the schema. The description restates force's replace-and-backup behavior but adds no syntax or resolution detail beyond what the schema provides. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Create') plus the exact resource ('project.faf') and adds the detection behavior (name, language, stack) that defines the tool. It explicitly differentiates itself from siblings faf_auto and faf_go, so an agent can disambiguate without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly states when to use it (creating a new project.faf) and, crucially, what to do instead when a file already exists — route to faf_auto for filling empty slots or faf_go for human 6Ws. Even names the force condition and its consequence.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
faf_recallRecall MemoryARead-onlyIdempotentInspect
Recall memories from the project soul (soul.fafm), ranked by priority then recency, filtered by query/tags/type. Returns the matching entries. Reads only. Use it to surface past decisions; faf_etch adds new ones.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Project path. Sets session context for subsequent calls. | |
| tags | No | Filter by tag intersection | |
| type | No | Filter by memory type | |
| limit | No | Max memories to return | |
| query | No | Case-insensitive substring match on memory text (optional) | |
| minPriority | No | Priority floor (default ephemeral) |
Output Schema
| Name | Required | Description |
|---|---|---|
| soul | No | |
| total | Yes | Number returned |
| memories | Yes | |
| soulTotal | No | Total memories in the soul |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint=false and destructiveHint=false, so 'Reads only' is largely redundant. However, the description adds real behavioral context beyond the annotations: the backing store (soul.fafm), the deterministic ranking order (priority then recency), and the fact that filtering is conjunctive across query/tags/type.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the core action and scope, then filters, then the routing hint to faf_etch. No filler; every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not explain return shape, and the one-line 'Returns the matching entries' is sufficient. For a six-parameter read tool it covers filters, ordering, and the sibling write path, though it omits default limit behavior and any note on empty results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all six parameters, including the query substring semantics and the minPriority default. The description only restates the filter dimensions and adds result ordering (priority then recency), which is genuinely extra but marginal against a fully documented schema. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Recall memories from the project soul (soul.fafm)') and immediately specifies the retrieval model ('ranked by priority then recency, filtered by query/tags/type'). It explicitly names the sibling it is not ('faf_etch adds new ones'), so an agent can route between the read and write tools without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete use case ('surface past decisions') and names the complementary alternative, faf_etch, with its contrasting behavior. It stops short of stating when NOT to use it (e.g. when to prefer faf_context or a live search over stored memories), so it is clear context without explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
faf_scoreScore .fafARead-onlyIdempotentInspect
Score the project's .faf with faf-cli's scorer — the one score every faf tool reports: 0–100%, the tier, populated/active slots, and a faf-parity/v1 hash of the result. details: true lists every slot as populated, empty or slotignored. Reads only. Use faf_doctor for what to fix.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Project path. Sets session context for subsequent calls. | |
| details | No | List every slot as populated, empty or slotignored, and the tools that fill the empty ones |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | No | Path that was scored |
| tier | Yes | Tier name for this score (e.g. BRONZE, TROPHY) |
| empty | No | Active slots still empty |
| score | Yes | AI-readiness score, 0-100 (-1 only together with unknown: true) |
| slots | No | Slot paths by state |
| total | No | Total slots |
| active | No | Slots active for this app_type |
| hasFaf | Yes | Whether a readable, valid project.faf was scored |
| parity | No | faf-parity/v1 — claude-faf-mcp's own spec (no other engine computes it yet): sha256 over a canonical projection of faf-cli's score for these exact bytes. Check it yourself: sha256(projection) === parityHash. |
| ignored | No | Slots marked slotignored (inactive for this app_type) |
| unknown | No | True when the score is not known: an About repo with no about.source_score. Shown as "unknown (—)", never as a number. |
| nextTier | No | Next tier above the current score, or null at top tier |
| inherited | No | True if the score is attested from a source repo (an about: block) |
| populated | No | Active slots that are filled |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent and non-destructive, so the bar is lower; the description reinforces this with 'Reads only' and goes further by disclosing the exact output composition (score, tier, slot states, faf-parity/v1 hash). It does not mention failure modes or cost, but adds real context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core action and output are front-loaded and the total length is appropriate. The dash-heavy, list-like styling and the aside 'the one score every faf tool reports' add flavor but slightly dilute an otherwise tight definition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, yet the description still summarizes them usefully. With only two optional parameters, full schema coverage, and clear safety annotations, an agent has everything needed to invoke this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented in the schema, which establishes the baseline of 3. The description's note that details:true lists every slot as populated/empty/slotignored largely restates the schema, adding little new syntax or edge-case meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Score the project's .faf with faf-cli's scorer') and enumerates exactly what the score contains (0–100%, tier, slots, parity hash). It also names faf_doctor as the sibling for remediation, so an agent can distinguish it from the other faf_* tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context ('Reads only') and routes the agent to faf_doctor 'for what to fix', which is an explicit alternative. It stops short of stating when scoring itself is the right call versus e.g. faf_bench or faf_trust.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
faf_setupSession Hook SetupAIdempotentInspect
Install the native SessionStart hook in the project settings (/.claude/settings.json) — every Claude Code session in this project starts with fresh .faf context. Shows the exact settings first (preview); writes only with confirm: true, install or remove. faf changes only its own hook entry; every other key and hook stays as written. remove: true takes out only the hook whose command is exactly the faf hook command. Never writes the user settings: the home folder is refused.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Project path. Defaults to the current project context. | |
| remove | No | Remove the faf SessionStart hook (and only it) from the project settings. Previews unless confirm: true. | |
| confirm | No | Write the change to the project settings (.claude/settings.json). Without it, faf_setup only previews — install and remove alike. |
Output Schema
| Name | Required | Description |
|---|---|---|
| action | Yes | What faf_setup did |
| message | Yes | Human-readable summary |
| settings | No | The full settings object as written (or as it would be written in preview) |
| hookCommand | No | The command the SessionStart hook runs |
| settingsPath | Yes | The settings file involved |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral detail beyond the annotations: it previews before writing, requires confirm: true to mutate, modifies only its own hook entry, preserves every other key and hook, and refuses the user settings/home folder. These details clarify the safety envelope and mutation semantics, consistent with readOnlyHint=false, destructiveHint=false, and idempotentHint=true.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loads the main action before its conditions. It packs a lot into one long compound sentence, which is efficient but slightly dense. Every clause earns its place by covering install, preview, confirm, scope, and removal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter hook-management tool with a full output schema, the description covers the critical operational facts: default preview, confirm-gated write, removal behavior, scope of changes, and refusal of user settings. An agent has enough context to invoke it correctly without needing return-value details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters are already documented in the input schema. The description reinforces confirm and remove semantics, but does not add parameter syntax or formats beyond what the schema provides. A baseline score of 3 is appropriate when the schema carries the parameter-documentation burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: install the native SessionStart hook in the project settings. It also explains the downstream effect, that every Claude Code session starts with fresh .faf context, and covers both install and remove modes. This distinguishes it from sibling tools like faf_init or faf_context, which manage context rather than session-hook installation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear operating context: preview is the default, writes happen only with confirm: true, and remove: true targets only the faf hook. It also states an explicit exclusion, that user settings and the home folder are never written. However, it does not name or compare against alternative faf tools for related setup tasks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
faf_syncSync .faf to CLAUDE.mdAIdempotentInspect
Write project.faf into CLAUDE.md as a faf-managed block (faf-cli's render and injector), and on request into AGENTS.md (agents), .cursorrules (cursor), GEMINI.md (gemini) and .github/copilot-instructions.md (copilot) — or all of them (all) — with faf-cli's writers. Each file keeps every line outside faf's block. Returns the files written and any requested file that could not be written, with the reason (then isError). Use it after editing project.faf.
| Name | Required | Description | Default |
|---|---|---|---|
| all | No | Write every format: CLAUDE.md + AGENTS.md + .cursorrules + GEMINI.md + .github/copilot-instructions.md | |
| path | No | Project path. Sets session context for subsequent calls. | |
| agents | No | Also write AGENTS.md (OpenAI Codex and other agents) | |
| cursor | No | Also write .cursorrules (Cursor IDE) | |
| gemini | No | Also write GEMINI.md (Google Gemini CLI) | |
| copilot | No | Also write .github/copilot-instructions.md (GitHub Copilot) |
Output Schema
| Name | Required | Description |
|---|---|---|
| score | No | faf-cli's score of that .faf, as text ("85%" or "unknown (—)") |
| fafPath | No | The .faf the files were written from |
| filesFailed | Yes | Requested files that were not written |
| filesWritten | Yes | Files written, CLAUDE.md first |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true and destructiveHint=false, so the safety profile is covered. The description adds real behavioral context beyond that: each target file preserves all lines outside faf's block, and failures are returned per-file with a reason plus isError. It does not say whether concurrent writes are safe, but the merge semantics are a meaningful addition.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded, but the text is one long run-on with redundant jargon — "faf-cli's render and injector" and "with faf-cli's writers" say the same thing twice and cost the reader without adding information. It is functional but not tight.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value documentation is not strictly required, yet the description usefully frames the write results and failure reporting. With 6 optional params all documented in the schema, and file-preservation semantics stated, an agent has enough to invoke it correctly; only the sibling distinction is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description restates the flag-to-file mapping (agents, cursor, gemini, copilot, all) that the schema already documents, adding no syntax, precedence (e.g. all vs a single flag), or default behavior beyond it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — writing project.faf into CLAUDE.md as a faf-managed block, optionally into four other files. It is clear what the tool does, but it never distinguishes itself from the sibling faf_tri_sync, which is the nearest potential overlap, so an agent cannot rule that one out from the text alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Use it after editing project.faf" gives a concrete trigger condition that tells the agent when this tool is appropriate. It provides no when-not guidance and does not name alternatives among the 13 siblings, so it stops short of full routing guidance but is more than implied usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
faf_tri_syncTri-Sync to MEMORY.mdAIdempotentInspect
Write project.faf as a faf-managed block into the MEMORY.md Claude Code loads for this project (~/.claude/projects//memory/MEMORY.md, or under CLAUDE_CONFIG_DIR). Only the block changes; every note of Claude's is kept, and the reply says so only after reading the file back. action: status reads only. faf_sync writes CLAUDE.md.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Project path. Sets session context for subsequent calls. | |
| action | No | export = write faf's block into MEMORY.md (default), status = show what MEMORY.md holds (reads only) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations covering safety (idempotent, non-destructive), the description adds real behavioral value: it localizes the target path, CLAUDE_CONFIG_DIR override, and — crucially — specifies that only the managed block changes, all of Claude's notes are preserved, and the reply is asserted only after reading the file back. That verification and preservation guarantee goes well beyond what readOnlyHint/destructiveHint convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, no filler, front-loaded with the primary action and target before the readback guarantee and sibling routing. Every sentence earns its place, including the path and config-dir override.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet the description tells the agent what the reply means ('the reply says so only after reading the file back') and what is and isn't modified. For a 2-param write tool with no return schema, this is complete enough to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented. The description repeats the 'status reads only' and default-export semantics that the schema's enum description already carries, adding no syntax or edge-case detail. Baseline 3 is correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and resource ('Write project.faf as a faf-managed block into the MEMORY.md'), states the exact target file and its location, and explicitly distinguishes itself from the sibling faf_sync ('faf_sync writes CLAUDE.md'). An agent can pick between the two without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It routes the agent to an alternative (faf_sync for CLAUDE.md) and disambiguates the 'status' mode as reads-only. It does not spell out prerequisites or when-not-to-use beyond the sibling contrast, so it stops short of the top band.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
faf_trustTrust ReceiptARead-onlyIdempotentInspect
Attest the project's .faf: faf-cli's validateFaf, faf-cli's score, and a faf-parity/v1 hash (claude-faf-mcp's own spec) of that score that anyone can check with sha256(projection) === parityHash. Returns a trust receipt whose subject is the project. An invalid .faf, or a score that is unknown, gets no receipt (isError). Reads only.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Project path. Sets session context for subsequent calls. |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | No | Path that was attested |
| tier | No | Tier name for this score |
| score | No | AI-readiness score, 0-100 |
| valid | Yes | Whether faf-cli's validateFaf accepts the .faf |
| errors | No | faf-cli's validateFaf errors, when valid is false |
| hasFaf | Yes | Whether a project.faf was found |
| parity | No | faf-parity/v1 — claude-faf-mcp's own spec (no other engine computes it yet): sha256 over a canonical projection of faf-cli's score for these exact bytes. Check it yourself: sha256(projection) === parityHash. |
| reason | No | Why no receipt was issued |
| receipt | No | The trust receipt — render-identical, self-verifying score + parity. |
| subject | No | The project the receipt attests: project.name, else its folder name |
| sourceSha256 | No | SHA-256 of the raw .faf bytes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, non-destructive, closed-world. The description adds the important failure behavior: invalid .faf or unknown score yields isError/no receipt; 'Reads only' is redundant but consistent. It stops short of permission/rate-limit context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the verb and core behavior, then return and error condition; no bloated preamble. The final 'Reads only' is redundant against annotations, keeping it from a perfect score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists and annotations cover safety, so return values and read-only nature need not be fully explained here. The description does cover the receipt and error case, making it sufficiently complete for this read-only attestation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Single path parameter has 100% schema description coverage, so the schema already explains its role. The description adds no further syntax/default/context for path, so baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Attest') and resource (the project's .faf) and enumerates the composite checks (validateFaf, score, parity hash) and returned receipt. This is clearly not a bare score tool, but it does not name a sibling alternative to route among faf_score/faf_doctor.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance, prerequisites, or alternatives to sibling tools are provided. Usage is only implied by the attestation purpose, so an agent gets little help choosing this over faf_score or faf_doctor.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
11 tool updates
v6.0.0- Changed
faf_auto1 field changed- removed
Input schema / properties / forceRemoved value: -{ - "description": "Force overwrite existing files", - "type": "boolean" -}
- Changed
faf_bench3 fields changed- changed
Input schema / properties / path / descriptionPrevious value: -"Project path (optional — current directory if omitted)."New value: +"Project path (optional — the active project if omitted)." - changed
Output schema / descriptionPrevious value: -"Question set (action=questions) or the cold→with-faf grading + ✪ receipt (action=grade)."New value: +"Question set (action=questions) or the cold→with-faf grading and its receipt (action=grade)." - changed
Output schema / properties / receipt / descriptionPrevious value: -"✪ receipt — sha256 over the canonical projection; third-party verifiable."New value: +"faf-cli's bench receipt — sha256 over the canonical projection; third-party verifiable."
- Changed
faf_context4 fields changed- added
Input schema / properties / detailAdded value: +{ + "description": "Also return the text of the .faf (read with faf-cli's reader), for reading project.faf in one call", + "type": "boolean" +} - added
Output schema / properties / contentAdded value: +{ + "description": "detail: true — the text of the .faf", + "type": "string" +} - changed
Output schema / properties / hasFaf / descriptionPrevious value: -"Whether a project.faf (or .faf) was found there"New value: +"Whether a project.faf (or .faf) was found there or one level up" - added
Output schema / properties / pathAdded value: +{ + "description": "The .faf file readers use (faf-cli's finder: the folder, then one level up), if found", + "type": [ + "string", + "null" + ] +}
- Changed
faf_doctor3 fields changed- added
Output schema / properties / scoreAdded value: +{ + "description": "faf-cli's score (-1 only with unknown: true), or null when not scored", + "type": [ + "number", + "null" + ] +} - added
Output schema / properties / unknownAdded value: +{ + "description": "True when the score is not known (an About repo with no about.source_score)", + "type": "boolean" +} - added
Output schema / properties / validAdded value: +{ + "description": "faf-cli's validateFaf verdict, or null when no .faf could be read", + "type": [ + "boolean", + "null" + ] +}
- Changed
faf_go1 field changed- changed
Input schema / properties / answers / descriptionPrevious value: -"Answers to apply. Keys are field paths (e.g., \"project.goal\", \"human_context.why\"), values are the answers. If provided, applies answers and returns new score."New value: +"Answers to apply: a slot path (e.g. \"project.goal\", \"human_context.why\", \"stack.database\") → the answer text. Any other key, or an answer that is not text, is refused and nothing is written. If provided, applies the answers and returns the new score."
- Changed
faf_init2 fields changed- changed
Input schema / properties / force / descriptionPrevious value: -"Overwrite existing project.faf if it exists"New value: +"Replace an existing project.faf with a fresh one: every value and comment in it is replaced. The old file is copied to project.faf.bak-<time> first." - changed
Input schema / properties / path / descriptionPrevious value: -"Project path or name. Smart resolution: \"my-app\" finds ~/Projects/my-app OR ~/Code/my-app. Full paths like ~/Projects/app or /Users/me/code/app work too. Omit to use current directory."New value: +"Project path or name. Smart resolution: \"my-app\" finds ~/Projects/my-app OR ~/Code/my-app. Full paths like ~/Projects/app or /Users/me/code/app work too; \".\", \"..\", \"./app\" are relative to the active project. Omit to create ~/Projects/unnamed-project; pass the workspace path to init it. Your home folder and the filesystem root are refused."
- Changed
faf_score11 fields changed- changed
Input schema / properties / details / descriptionPrevious value: -"Include detailed breakdown and improvement suggestions"New value: +"List every slot as populated, empty or slotignored, and the tools that fill the empty ones" - changed
Output schema / properties / inherited / descriptionPrevious value: -"True if the score is attested from a source repo (app_type: about)"New value: +"True if the score is attested from a source repo (an about: block)" - changed
Output schema / properties / parity / descriptionPrevious value: -"Determinism parity receipt — an engine-agnostic hash any conformant scorer reproduces for this exact file. Third-party verifiable: sha256(projection) === parityHash."New value: +"faf-parity/v1 — claude-faf-mcp's own spec (no other engine computes it yet): sha256 over a canonical projection of faf-cli's score for these exact bytes. Check it yourself: sha256(projection) === parityHash." - changed
Output schema / properties / parity / properties / parityHash / descriptionPrevious value: -"sha256(projection) — identical across any conformant engine"New value: +"sha256(projection)" - changed
Output schema / properties / parity / properties / producedBy / descriptionPrevious value: -"Which wrapper emitted this receipt (metadata, not hashed)"New value: +"The server that emitted this receipt (metadata, not hashed)" - changed
Output schema / properties / parity / properties / scorer / descriptionPrevious value: -"The single deterministic source the score comes from"New value: +"The single deterministic source the score comes from (faf-cli)" - changed
Output schema / properties / parity / properties / spec / descriptionPrevious value: -"Parity spec id, e.g. faf-parity/v1"New value: +"Parity spec id: faf-parity/v1" - changed
Output schema / properties / score / descriptionPrevious value: -"AI-readiness score, 0-100"New value: +"AI-readiness score, 0-100 (-1 only together with unknown: true)" - added
Output schema / properties / slotsAdded value: +{ + "description": "Slot paths by state", + "properties": { + "empty": { + "items": { + "type": "string" + }, + "type": "array" + }, + "ignored": { + "items": { + "type": "string" + }, + "type": "array" + }, + "populated": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" +} - changed
Output schema / properties / tier / descriptionPrevious value: -"Tier name for this score (e.g. Bronze, Trophy)"New value: +"Tier name for this score (e.g. BRONZE, TROPHY)" - added
Output schema / properties / unknownAdded value: +{ + "description": "True when the score is not known: an About repo with no about.source_score. Shown as \"unknown (—)\", never as a number.", + "type": "boolean" +}
- Added
faf_setup - Changed
faf_sync6 fields changed- changed
Input schema / properties / agents / descriptionPrevious value: -"Also sync to AGENTS.md (OpenAI/Codex format)"New value: +"Also write AGENTS.md (OpenAI Codex and other agents)" - changed
Input schema / properties / all / descriptionPrevious value: -"Sync to ALL formats: CLAUDE.md + AGENTS.md + .cursorrules + GEMINI.md + .github/copilot-instructions.md"New value: +"Write every format: CLAUDE.md + AGENTS.md + .cursorrules + GEMINI.md + .github/copilot-instructions.md" - changed
Input schema / properties / copilot / descriptionPrevious value: -"Also sync to .github/copilot-instructions.md (GitHub Copilot)"New value: +"Also write .github/copilot-instructions.md (GitHub Copilot)" - changed
Input schema / properties / cursor / descriptionPrevious value: -"Also sync to .cursorrules (Cursor IDE format)"New value: +"Also write .cursorrules (Cursor IDE)" - changed
Input schema / properties / gemini / descriptionPrevious value: -"Also sync to GEMINI.md (Google Gemini format)"New value: +"Also write GEMINI.md (Google Gemini CLI)" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "description": "The files faf_sync wrote, and each requested file it could not write.", + "properties": { + "fafPath": { + "description": "The .faf the files were written from", + "type": "string" + }, + "filesFailed": { + "description": "Requested files that were not written", + "items": { + "properties": { + "file": { + "type": "string" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "file", + "reason" + ], + "type": "object" + }, + "type": "array" + }, + "filesWritten": { + "description": "Files written, CLAUDE.md first", + "items": { + "type": "string" + }, + "type": "array" + }, + "score": { + "description": "faf-cli's score of that .faf, as text (\"85%\" or \"unknown (—)\")", + "type": "string" + } + }, + "required": [ + "filesWritten", + "filesFailed" + ], + "type": "object" +}
- Added
faf_tri_sync - Changed
faf_trust16 fields changed- changed
Output schema / descriptionPrevious value: -"Trust attestation: validity, score, and a third-party-verifiable determinism parity receipt."New value: +"Trust attestation: faf-cli's validity and score, and a faf-parity/v1 receipt." - added
Output schema / properties / errorsAdded value: +{ + "description": "faf-cli's validateFaf errors, when valid is false", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Output schema / properties / parity / descriptionPrevious value: -"Determinism parity receipt (same shape as faf_score.parity)."New value: +"faf-parity/v1 — claude-faf-mcp's own spec (no other engine computes it yet): sha256 over a canonical projection of faf-cli's score for these exact bytes. Check it yourself: sha256(projection) === parityHash." - added
Output schema / properties / parity / properties / algo / descriptionAdded value: +"Hash algorithm (sha256)" - added
Output schema / properties / parity / properties / parityHash / descriptionAdded value: +"sha256(projection)" - added
Output schema / properties / parity / properties / producedBy / descriptionAdded value: +"The server that emitted this receipt (metadata, not hashed)" - added
Output schema / properties / parity / properties / projection / descriptionAdded value: +"The exact canonical string that was hashed (for verification)" - added
Output schema / properties / parity / properties / scorer / descriptionAdded value: +"The single deterministic source the score comes from (faf-cli)" - added
Output schema / properties / parity / properties / sourceSha256 / descriptionAdded value: +"SHA-256 of the raw .faf bytes" - added
Output schema / properties / parity / properties / spec / descriptionAdded value: +"Parity spec id: faf-parity/v1" - changed
Output schema / properties / reason / descriptionPrevious value: -"Why validation failed, when valid is false"New value: +"Why no receipt was issued" - changed
Output schema / properties / receipt / descriptionPrevious value: -"The ✪ trust receipt — render-identical, self-verifying score+parity artifact."New value: +"The trust receipt — render-identical, self-verifying score + parity." - changed
Output schema / properties / receipt / properties / seal / descriptionPrevious value: -"Quiet-ladder glyph for this score (✪ at Trophy)"New value: +"Quiet-ladder glyph for this score (✪ only at 100)" - added
Output schema / properties / receipt / properties / subject / descriptionAdded value: +"The project: project.name, else its folder name" - added
Output schema / properties / subjectAdded value: +{ + "description": "The project the receipt attests: project.name, else its folder name", + "type": "string" +} - changed
Output schema / properties / valid / descriptionPrevious value: -"Whether the project.faf is readable and valid"New value: +"Whether faf-cli's validateFaf accepts the .faf"
1 tool update
- Removed
faf_enhance
1 tool update
v5.14.1- Changed
faf_sync5 fields changed- added
Input schema / properties / agentsAdded value: +{ + "description": "Also sync to AGENTS.md (OpenAI/Codex format)", + "type": "boolean" +} - added
Input schema / properties / allAdded value: +{ + "description": "Sync to ALL formats: CLAUDE.md + AGENTS.md + .cursorrules + GEMINI.md + .github/copilot-instructions.md", + "type": "boolean" +} - added
Input schema / properties / copilotAdded value: +{ + "description": "Also sync to .github/copilot-instructions.md (GitHub Copilot)", + "type": "boolean" +} - added
Input schema / properties / cursorAdded value: +{ + "description": "Also sync to .cursorrules (Cursor IDE format)", + "type": "boolean" +} - added
Input schema / properties / geminiAdded value: +{ + "description": "Also sync to GEMINI.md (Google Gemini format)", + "type": "boolean" +}
1 tool update
v5.12.0- Added
faf_bench
23 tool updates
v5.11.0- Removed
faf - Removed
faf_agents - Removed
faf_bi_sync - Removed
faf_check - Removed
faf_clear - Removed
faf_conductor - Removed
faf_cursor - Removed
faf_debug - Removed
faf_dna - Removed
faf_formats - Removed
faf_friday - Removed
faf_gemini - Removed
faf_git - Removed
faf_guide - Removed
faf_human_add - Removed
faf_list - Removed
faf_quick - Removed
faf_read - Removed
faf_readme - Removed
faf_setup - Removed
faf_status - Removed
faf_tri_sync - Removed
faf_write
13 tool updates
v5.9.0- Removed
faf_chat - Changed
faf_check1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "description": "Human-context quality report, or the result of a protect/unlock action.", + "properties": { + "emptyCount": { + "description": "Fields that are empty", + "type": "number" + }, + "fields": { + "additionalProperties": { + "properties": { + "protected": { + "type": "boolean" + }, + "quality": { + "description": "empty | generic | good | excellent", + "type": "string" + } + }, + "type": "object" + }, + "description": "Per-field quality + protection (report mode)", + "type": "object" + }, + "goodCount": { + "description": "Fields rated good or excellent", + "type": "number" + }, + "mode": { + "description": "report | protect | unlock", + "type": "string" + }, + "protected": { + "description": "Field names currently protected", + "items": { + "type": "string" + }, + "type": "array" + }, + "protectedNow": { + "description": "Fields newly protected by this call (protect mode)", + "items": { + "type": "string" + }, + "type": "array" + }, + "qualityPercent": { + "description": "Share of fields rated good/excellent (report mode)", + "type": "number" + } + }, + "required": [ + "mode" + ], + "type": "object" +}
- Changed
faf_context1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "description": "The active project context and whether a project.faf lives there.", + "properties": { + "active": { + "description": "Absolute path of the active project", + "type": "string" + }, + "changed": { + "description": "True if this call set a new context, false if it only reported", + "type": "boolean" + }, + "filename": { + "description": "The .faf filename, if found", + "type": [ + "string", + "null" + ] + }, + "hasFaf": { + "description": "Whether a project.faf (or .faf) was found there", + "type": "boolean" + } + }, + "required": [ + "active", + "hasFaf", + "changed" + ], + "type": "object" +}
- Changed
faf_dna1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "description": "The project's score history: birth DNA, current score, growth, and milestones.", + "properties": { + "authenticated": { + "description": "Whether the birth certificate is authenticated", + "type": "boolean" + }, + "birthScore": { + "description": "Score at birth", + "type": "number" + }, + "certificate": { + "description": "Birth certificate ID", + "type": [ + "string", + "null" + ] + }, + "currentScore": { + "description": "Current score", + "type": "number" + }, + "daysActive": { + "description": "Days since birth", + "type": "number" + }, + "hasDna": { + "description": "Whether a .faf-dna history exists (or was just created)", + "type": "boolean" + }, + "hasFaf": { + "description": "Whether a project.faf was found", + "type": "boolean" + }, + "justBorn": { + "description": "True if this call created the birth certificate", + "type": "boolean" + }, + "milestones": { + "description": "Recorded milestones", + "items": { + "properties": { + "date": { + "type": "string" + }, + "score": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "totalGrowth": { + "description": "currentScore - birthScore", + "type": "number" + } + }, + "required": [ + "hasFaf", + "hasDna" + ], + "type": "object" +}
- Changed
faf_doctor1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "description": "Health check: an overall verdict plus per-check diagnostics with fixes.", + "properties": { + "checks": { + "description": "Number of checks run", + "type": "number" + }, + "diagnostics": { + "description": "Per-check results", + "items": { + "properties": { + "fix": { + "description": "Suggested fix, if any", + "type": "string" + }, + "message": { + "type": "string" + }, + "status": { + "description": "ok | warning | error", + "type": "string" + } + }, + "required": [ + "status", + "message" + ], + "type": "object" + }, + "type": "array" + }, + "errors": { + "description": "Count of error-level findings", + "type": "number" + }, + "health": { + "description": "Overall verdict: ok | warning | error", + "type": "string" + }, + "warnings": { + "description": "Count of warning-level findings", + "type": "number" + } + }, + "required": [ + "health", + "checks", + "diagnostics" + ], + "type": "object" +}
- Added
faf_etch - Changed
faf_formats1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "description": "Formats discovered in the project and the stack signature derived from them.", + "properties": { + "count": { + "description": "Number of known formats discovered", + "type": "number" + }, + "directory": { + "description": "Directory that was scanned", + "type": "string" + }, + "elapsedMs": { + "description": "Discovery time in milliseconds", + "type": "number" + }, + "formats": { + "description": "Discovered formats", + "items": { + "properties": { + "category": { + "type": "string" + }, + "fileName": { + "type": "string" + }, + "priority": { + "type": "number" + } + }, + "required": [ + "fileName" + ], + "type": "object" + }, + "type": "array" + }, + "intelligenceScore": { + "description": "Total intelligence score across discovered formats", + "type": "number" + }, + "slotFillRecommendations": { + "additionalProperties": { + "type": "string" + }, + "description": "Recommended .faf slot fills derived from discovered formats", + "type": "object" + }, + "stackSignature": { + "description": "Derived stack signature", + "type": "string" + } + }, + "required": [ + "directory", + "count", + "formats" + ], + "type": "object" +}
- Changed
faf_list1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "description": "Directory entries, with project.faf discovery flagged per entry.", + "properties": { + "directory": { + "description": "Absolute path that was scanned", + "type": "string" + }, + "entries": { + "description": "The listed entries", + "items": { + "properties": { + "hasFaf": { + "type": "boolean" + }, + "isDir": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "name", + "path", + "hasFaf", + "isDir" + ], + "type": "object" + }, + "type": "array" + }, + "fafProjects": { + "description": "How many entries contain a project.faf", + "type": "number" + }, + "filter": { + "description": "Filter applied: faf | dirs | all", + "type": "string" + }, + "total": { + "description": "Number of entries returned", + "type": "number" + } + }, + "required": [ + "directory", + "total", + "entries" + ], + "type": "object" +}
- Added
faf_recall - Changed
faf_score1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "description": "Structured AI-readiness score, single-sourced from faf-cli.", + "properties": { + "active": { + "description": "Slots active for this app_type", + "type": "number" + }, + "empty": { + "description": "Active slots still empty", + "type": "number" + }, + "hasFaf": { + "description": "Whether a readable, valid project.faf was scored", + "type": "boolean" + }, + "ignored": { + "description": "Slots marked slotignored (inactive for this app_type)", + "type": "number" + }, + "inherited": { + "description": "True if the score is attested from a source repo (app_type: about)", + "type": "boolean" + }, + "nextTier": { + "description": "Next tier above the current score, or null at top tier", + "properties": { + "name": { + "type": "string" + }, + "threshold": { + "type": "number" + } + }, + "type": [ + "object", + "null" + ] + }, + "parity": { + "description": "Determinism parity receipt — an engine-agnostic hash any conformant scorer reproduces for this exact file. Third-party verifiable: sha256(projection) === parityHash.", + "properties": { + "algo": { + "description": "Hash algorithm (sha256)", + "type": "string" + }, + "parityHash": { + "description": "sha256(projection) — identical across any conformant engine", + "type": "string" + }, + "producedBy": { + "description": "Which wrapper emitted this receipt (metadata, not hashed)", + "type": "string" + }, + "projection": { + "description": "The exact canonical string that was hashed (for verification)", + "type": "string" + }, + "scorer": { + "description": "The single deterministic source the score comes from", + "type": "string" + }, + "sourceSha256": { + "description": "SHA-256 of the raw .faf bytes", + "type": "string" + }, + "spec": { + "description": "Parity spec id, e.g. faf-parity/v1", + "type": "string" + } + }, + "required": [ + "spec", + "parityHash", + "sourceSha256", + "projection" + ], + "type": "object" + }, + "path": { + "description": "Path that was scored", + "type": "string" + }, + "populated": { + "description": "Active slots that are filled", + "type": "number" + }, + "score": { + "description": "AI-readiness score, 0-100", + "type": "number" + }, + "tier": { + "description": "Tier name for this score (e.g. Bronze, Trophy)", + "type": "string" + }, + "total": { + "description": "Total slots", + "type": "number" + } + }, + "required": [ + "score", + "tier", + "hasFaf" + ], + "type": "object" +}
- Added
faf_setup - Changed
faf_status1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "description": "Whether the project has a project.faf and where it lives.", + "properties": { + "directory": { + "description": "Directory that was checked", + "type": "string" + }, + "filename": { + "description": "The .faf filename, if found", + "type": [ + "string", + "null" + ] + }, + "hasFaf": { + "description": "Whether a project.faf (or .faf) was found", + "type": "boolean" + }, + "path": { + "description": "Absolute path to the .faf file, if found", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "hasFaf", + "directory" + ], + "type": "object" +}
- Changed
faf_trust2 fields changed- added
Input schema / properties / pathAdded value: +{ + "description": "Project path. Sets session context for subsequent calls.", + "type": "string" +} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "description": "Trust attestation: validity, score, and a third-party-verifiable determinism parity receipt.", + "properties": { + "hasFaf": { + "description": "Whether a project.faf was found", + "type": "boolean" + }, + "parity": { + "description": "Determinism parity receipt (same shape as faf_score.parity).", + "properties": { + "algo": { + "type": "string" + }, + "parityHash": { + "type": "string" + }, + "producedBy": { + "type": "string" + }, + "projection": { + "type": "string" + }, + "scorer": { + "type": "string" + }, + "sourceSha256": { + "type": "string" + }, + "spec": { + "type": "string" + } + }, + "required": [ + "spec", + "parityHash", + "sourceSha256", + "projection" + ], + "type": "object" + }, + "path": { + "description": "Path that was attested", + "type": "string" + }, + "reason": { + "description": "Why validation failed, when valid is false", + "type": "string" + }, + "receipt": { + "description": "The ✪ trust receipt — render-identical, self-verifying score+parity artifact.", + "properties": { + "issued": { + "type": [ + "string", + "null" + ] + }, + "score": { + "type": "number" + }, + "seal": { + "description": "Quiet-ladder glyph for this score (✪ at Trophy)", + "type": "string" + }, + "spec": { + "type": "string" + }, + "subject": { + "type": "string" + }, + "tests": { + "description": "Optional test attestation", + "type": [ + "object", + "null" + ] + }, + "tier": { + "type": "string" + } + }, + "required": [ + "spec", + "seal", + "subject", + "score" + ], + "type": "object" + }, + "score": { + "description": "AI-readiness score, 0-100", + "type": "number" + }, + "sourceSha256": { + "description": "SHA-256 of the raw .faf bytes", + "type": "string" + }, + "tier": { + "description": "Tier name for this score", + "type": "string" + }, + "valid": { + "description": "Whether the project.faf is readable and valid", + "type": "boolean" + } + }, + "required": [ + "valid", + "hasFaf" + ], + "type": "object" +}
TDQS
Scored across 14 tools
Several tools overlap around reading the .faf: faf_score, faf_doctor, faf_trust, and faf_context all read/scorer the same file with subtle differences (score vs. diagnose vs. attest vs. active project). faf_sync and faf_tri_sync both write faf-managed blocks and only differ by target file, and faf_init/faf_auto/faf_go all create or fill slots. Descriptions do clarify the distinctions, but an agent could easily pick the wrong read or write tool.
All tools use the faf_ prefix with a short lowercase verb or concept (faf_about, faf_score, faf_init, faf_sync, faf_go, faf_etch, faf_recall). The pattern is consistent and readable, though the second token is sometimes a verb and sometimes a noun (about, context, bench), so it is not a strict verb_noun convention.
14 tools is within the reasonable 3-15 range for a server covering the full .faf lifecycle (init, fill, score, diagnose, sync, memory, attest, bench). It is on the heavier side but each tool has a distinct conceptual role, so the count is defensible.
The surface covers the .faf lifecycle well: create (faf_init), auto-fill and human answers (faf_auto, faf_go), read/score/validate (faf_score, faf_doctor, faf_trust), write to editor files (faf_sync, faf_tri_sync), session hook setup (faf_setup), and memory (faf_etch, faf_recall). Minor gaps exist, e.g. no explicit delete/remove for project.faf or memories, but core workflows are complete.
Maintenance
Related MCP Connectors
Persistent project context for xAI Grok. IANA-registered .faf format.
Persistent project context — Rust-native MCP server. IANA-registered .faf format.
Share one project context across ChatGPT, Claude, Telegram and any MCP client.
Persistent AI memory shared across Claude, ChatGPT, coding agents, and compatible MCP clients.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceIntegration project for Model Context Protocol (MCP) servers with Claude Desktop App, enabling filesystem operations, development support, and file management through natural language.-
- AlicenseAqualityAmaintenancePersistent project context for Google Gemini. 12 MCP tools for .faf Project DNA — auto-detect your stack, validate, score, and sync across CLAUDE.md, GEMINI.md, and AGENTS.md. Python/FastMCP. IANA-registered format (application/vnd.faf+yaml). 183 tests. One file, every AI platform.13171 PyPI2MIT
- AlicenseNot gradedqualityAmaintenancePersistent project context in Rust. 8 MCP tools via rmcp SDK — parse, validate, score, compress, discover, and token analysis. Single binary, zero config. IANA-registered format (application/vnd.faf+yaml). One file, every AI platform.109 npm4MIT
- AlicenseAqualityBmaintenanceGrok asked for MCP on a URL. This is it. First MCP server built for Grok URL-based • Zero config • Just works12187 npm18MIT