briefd
Briefd is a self-hosted context compiler that serves a team's git-backed Markdown knowledge base to coding agents over MCP (or REST) as token-budgeted context bundles.
compile_bundle — Build a deduplicated, token-limited context block for a task, ordered domain → conventions → project, with source lines and cache support.
search_context — Search knowledge sections by natural language or keywords, ranked and capped by a token budget.
get_document — Fetch a full knowledge document by path, including title, tags, and content.
list_scopes — Discover available knowledge scopes (domain, conventions, projects/) with document, section, and token counts.
propose_update — Propose edits or new knowledge documents on a reviewable git branch/PR, without changing served content until merged.
report_usage — Provide feedback on which bundle sections were useful; empty feedback marks knowledge gaps.
suggest_links — Identify missing or broken links in the knowledge base for cleanup.
Also offers a dashboard, REST API, metrics, knowledge-gap reporting, code-drift detection, and git/webhook sync.
Allows creating reviewable knowledge update proposals as pull requests on GitHub and triggers index synchronization via GitHub-style webhooks.
Teams that build many projects in one domain keep the same knowledge in their heads and in
scattered CLAUDE.md / AGENTS.md files: terminology, business rules, architecture decisions,
conventions. Loading all of it into every session burns thousands of tokens on every turn, and
whatever doesn't fit gets left out.
briefd inverts the model: context on demand, not up front. Your knowledge lives as Markdown in a git repository. briefd indexes it and answers one question from your coding agent — "what do I need to know for this task?" — with a compiled, deduplicated bundle that never exceeds the token budget you set.
Why
On the sample knowledge repo in this repository (44 documents, 47 realistic developer tasks),
compile_bundle spends 86% fewer tokens per task than pasting everything into CLAUDE.md
while still containing the section that answers the task 96% of the time (98% with the
English-only all-MiniLM-L6-v2 model, the figure the explainer video quotes). The realistic
middle ground — a hand-curated CLAUDE.md with just conventions and the glossary — costs
2.8× more than a bundle and has the answer less than half the time.
Reproduce it with make bench; the method is in internal/eval/bench.go.
That is what the tokenizer says. Inside real Claude Code sessions
(eval/session/, Sonnet, 10 tasks, same prompts) briefd cut the context
carried per turn by 35% and the cost per task by 40% with identical answers — at the price of
3–4 extra tool-call round trips per task. The saving grows with the size of your knowledge repo;
a static CLAUDE.md cannot.
Not another agent memory
Memory tools (agentmemory, Mem0, claude-mem) record what an agent observed in its sessions, automatically, per user. briefd serves what the team decided, written by people and reviewed like code. They answer different questions and run side by side.
Agent memory | briefd | |
Source of truth | A database the agent writes to | Markdown in a git repository |
Who writes | The agent, automatically | People; agents open pull requests |
Scope | One agent / one user | The whole team, every project in the domain |
Review | None | Every change has a diff, a reviewer and a name |
Staleness | Unknown | Dates on every section; drift against the code it governs |
What it can't answer | Silently absent | Listed on the dashboard as a backlog |
Footprint | Runtime + engine + several ports | One static binary, one SQLite file, one port (or stdio) |
Tool surface | Dozens of tools, thousands of tokens per session | 7 tools, ~2.8k tokens per session |
Use a memory tool so your agent remembers what it tried last week. Use briefd so every agent on the team applies the same rules — and so someone notices when a rule falls behind the code.
Related MCP server: flaiwheel
How it works
Git is the source of truth. The index is a disposable cache rebuilt from a clone.
Agents never write to the index.
propose_updateopens a reviewable branch/PR; what briefd serves changes only when a human merges.Hybrid retrieval, no external services. SQLite FTS5 (BM25) + multilingual embeddings (
multilingual-e5-small, 100+ languages) computed by a pure-Go encoder, fused with reciprocal rank fusion. No Postgres, no vector database, no ONNX runtime, no CGO.Hard token budgets. Every API that returns context takes
max_tokensand never exceeds it.
Quickstart
Try it in 30 seconds — no repository needed:
briefd demo # serves the built-in sample knowledge base on http://127.0.0.1:7788Then open the dashboard, or point an agent at it: claude mcp add --transport http briefd http://127.0.0.1:7788/mcp.
The first run downloads the embedding model (about 470 MB); briefd demo --embeddings none skips it.
With your own knowledge:
# 1. build (Go >= 1.26) or grab a binary from the releases page
git clone https://github.com/ismailperim/briefd && cd briefd && make build
# 2. serve the sample knowledge repo (downloads the 470 MB multilingual embedding model once)
./bin/briefd serve --source testdata/knowledge --db /tmp/briefd.db --token dev-token
# 3. connect Claude Code
claude mcp add --transport http briefd http://localhost:7788/mcp \
--header "Authorization: Bearer dev-token"Open http://localhost:7788/ for the dashboard, then ask Claude Code something the sample
corpus knows — "what's our retry policy for acquirer calls?" or "ters ibraz nedir?" — and
watch search_context / compile_bundle show up in the request log.
Any MCP client that speaks streamable HTTP works. For a project-level .mcp.json:
{
"mcpServers": {
"briefd": {
"type": "http",
"url": "http://localhost:7788/mcp",
"headers": { "Authorization": "Bearer dev-token" }
}
}
}Let the agent install it. Hand your coding agent one instruction:
Retrieve and follow the instructions at: https://raw.githubusercontent.com/ismailperim/briefd/main/INSTALL_FOR_AGENTS.md
Teach the agent when to ask. Tools an agent does not call save nothing. The
skills/briefd skill tells Claude Code (and any agent that reads
SKILL.md) when to compile a bundle, how to treat a stale section and when to propose an
update; the same guidance as a CLAUDE.md paragraph is in deploy/local/CLAUDE.md.
npx skills add ismailperim/briefdSingle-user, no server? briefd mcp speaks MCP over stdio — the same tools, the same
index, no port and no token. Claude Desktop, Cursor's stdio config and MCP directory
inspectors launch it directly:
{
"mcpServers": {
"briefd": {
"command": "briefd",
"args": ["mcp", "--source", "/path/to/knowledge", "--db", "~/.briefd/knowledge.db"]
}
}
}Use serve when a team shares one instance (dashboard, metrics, webhook, REST); use mcp
when the agent runs on the machine that holds the checkout.
Tools
Tool | What it does |
| One deduplicated context block within the budget, ordered domain → conventions → project, with a source line per section and a |
| Ranked sections that fit the budget, for inspection. |
| One document in full. |
| Scopes with document/section counts. |
| Creates branch |
| Optional feedback: which sections helped. An empty list marks the question as a knowledge gap. |
| Links the knowledge base is missing (a document names another without linking it) and broken links — for an agent tidying the knowledge base via |
The same operations are available over REST (/api/search, POST /api/bundle, /api/docs/{path},
/api/scopes, POST /api/proposals, POST /api/usage, /api/gaps, /api/health, /api/stats)
behind the same bearer token.
Your knowledge repo
briefd expects a git repository (or directory) of Markdown with three kinds of folders
(briefd init <dir> scaffolds it with example documents):
knowledge-repo/
├── domain/ # shared: terminology, business rules, ADRs
├── conventions/ # shared: coding standards, infra patterns
└── projects/
├── ledger-service/ # visible only when scope "projects/ledger-service" is requested
└── merchant-portal/Documents are split on ##/### headings into sections of roughly 200–800 tokens with stable
ids, so a section can be quoted on its own. Optional front matter adds metadata:
---
title: Retry policy # defaults to the first H1
tags: [payments, resilience]
refs: ["services/payment/**"] # code paths this doc governs
---testdata/knowledge/ is a complete example (a fictional payments
platform) and doubles as the evaluation corpus.
Obsidian vaults and links
A knowledge repository can be an Obsidian vault. briefd reads [[wikilinks]] in the text and in front-matter properties such as related: (including
[[note|alias]] and [[note#heading]]) and relative Markdown links, resolves them the way
Obsidian does (by path, or by file name anywhere in the repository), and builds a link graph:
the dashboard draws it, get_document returns each document's links and backlinks so an agent
can follow them, and orphans (nothing links here) and broken links (the target does not exist)
are listed as maintenance signals next to gaps and coverage. Folder scopes still apply —
domain/, conventions/, projects/<name>/ — so keep the vault's top level in that shape.
Running it for real
export BRIEFD_GIT_TOKEN=ghp_... # only for private HTTPS remotes
./bin/briefd serve --source https://github.com/your-org/knowledge.git --token "$(openssl rand -hex 16)"briefd clones the repository, follows the branch with fetch + hard reset every sync.interval
(default 60 s), or immediately when your forge calls POST /webhook/git with a GitHub-style
HMAC signature. Only changed files are re-parsed and re-embedded.
Languages. The default embedding model, multilingual-e5-small, covers 100+ languages,
so a Turkish, German or Japanese knowledge repo — or English docs queried in another language —
works out of the box. English-only teams can set embeddings.model: all-MiniLM-L6-v2 (87 MB,
~2.5× faster indexing). briefd model pull pre-fetches a model for offline or image-build use;
--embeddings none gives BM25-only mode; Ollama and OpenAI-compatible services are alternative
providers.
Docker
cd deploy
BRIEFD_SOURCE=https://github.com/your-org/knowledge.git BRIEFD_API_TOKEN=... docker compose upThe image is distroless and pure Go (~34 MB, linux/amd64 + arm64). Database, checkout and model
live in the briefd-data volume. Mount a directory and set BRIEFD_SOURCE=/knowledge to serve
local files instead.
Deployment guide: deploy/README.md covers Compose and systemd
setups, git forges (GitHub, GitLab, Azure DevOps, Bitbucket, SSH), installing the embedding model
offline, proxies and private CAs, exposure/security, upgrades and monitoring. For a laptop-only
setup see deploy/local/.
Configuration — briefd.yaml (see deploy/briefd.example.yaml)
or BRIEFD_* environment variables; flags override both. The ones you will actually touch:
Setting | Env | Default | Notes |
|
| — | git URL or directory |
|
| (none) | empty = unauthenticated (only on trusted networks) |
|
|
| |
|
|
|
|
|
| — | enables |
|
| — | HTTPS remotes; |
|
| — |
|
|
|
|
|
|
|
| or |
|
|
| |
|
|
| feeds the knowledge-gap report; |
| — | (none) | code repositories (URL or path) compared against documents' |
briefd model pull pre-fetches the embedding model for offline or image-build use.
Dashboard and metrics
GET / is a dashboard embedded in the binary (no build step, no external assets):
Overview — requests, tokens served and saved, index and sync; the knowledge graph with the documents agents were served in the last 24 hours stamped on it; the circulation list; and Needs attention, one line per maintenance signal, worst first.
Graph — every document and link, zoom and pan (mouse or keyboard), scope filters, search; select a document to see its links, backlinks and how often it was served (
#graph=<doc path>links straight to it).Maintenance — proposals awaiting review, knowledge gaps, documents behind the code, the oldest documents, links to fix and code coverage.
Activity — latency and volume per tool, the index by scope and the request log; counters persist across restarts and can be reset.
Instance — the running configuration (secrets shown only as set/unset), with Sync now and Rebuild index.
GET /metrics exposes the counters in Prometheus text format; GET /api/stats as JSON.
Knowledge gaps. Every search_context / compile_bundle call is logged with its retrieval
confidence (query_log, 30-day retention). The dashboard lists the questions of the last seven
days that the knowledge base did not answer — nothing matched, or the agent's report_usage said
no section helped — grouped by question and ranked by how often they were asked, plus the answered
questions whose top result barely stood out from the rest. That list is the backlog for whoever
maintains the repository; GET /api/gaps?days=7&limit=20 returns it as JSON.
Document age. Every section in a bundle carries the date its document last changed
(## path — heading (updated 2026-03-04), from git history, or the file mtime for a plain
directory), so an agent can weigh a rule by its age. The dashboard lists the documents that
changed longest ago — the ones to re-read first.
Behind the code. Give a document refs: ["services/payment/**"] in its front matter and
list the code repositories in code.repos; briefd follows their history (bare clones, never the
files) and counts the commits that touched a governed path after the document last changed.
The attribution line then reads (updated 2026-03-01; code changed since: 3 commits, last 2026-06-01), the dashboard lists the documents most behind, and briefd_documents_behind_code
is exported. The agent reading a stale rule is often the right one to fix it with
propose_update. Design in ADR-0007.
The same refs work the other way round: pass paths (the files the task touches) to
compile_bundle and the rules that govern them lead the bundle, and the dashboard's
Coverage panel lists the directories of each code repository that no document claims —
the knowledge base's blind spots (ADR-0008).
briefd does not index code itself; your agent's grep and LSP do that better.
Retrieval quality
Retrieval is measured, not assumed. make eval scores 47 English golden queries (keyword,
paraphrase, typo, mixed-language) over the sample corpus and 30 Turkish queries over a
Turkish corpus; CI fails if hybrid retrieval drops below eval/thresholds.yaml
or eval/thresholds-tr.yaml:
Mode | English R@5 | English R@10 | English MRR | Turkish R@5 | Turkish R@10 | Turkish MRR |
BM25 only | 0.681 | 0.755 | 0.591 | 0.733 | 0.767 | 0.602 |
Vector only | 0.830 | 0.936 | 0.771 | 0.950 | 1.000 | 0.832 |
Hybrid (default) | 0.830 | 0.926 | 0.746 | 0.933 | 1.000 | 0.847 |
On public BEIR datasets briefd's vector-only mode reproduces the published quality of both
embedding models and hybrid mode beats BM25 and vector-only on each — SciFact nDCG@10 0.714
vs 0.665 for the BEIR BM25 baseline; see eval/beir/ to reproduce.
Every change to chunking, embeddings or fusion ships with before/after numbers (ADR-0004 is an example).
CLI
briefd demo # serve the built-in sample knowledge base — try it in 30 seconds
briefd init # scaffold a knowledge repo (domain/, conventions/, projects/)
briefd serve # MCP over HTTP + REST + dashboard, for a shared instance
briefd mcp # MCP over stdio, for one agent on this machine (Claude Desktop, Cursor)
briefd index # index a directory into the database (--rebuild to start over)
briefd search # query like search_context does (--mode bm25|vector|hybrid, --json)
briefd model list # local embedding models and whether they are downloaded
briefd model pull # download a model (--model all-MiniLM-L6-v2 for the English one)
briefd eval # retrieval quality against the golden set
briefd bench # tokens per task: static CLAUDE.md vs compile_bundleStatus and roadmap
v0.1 is feature-complete; expect rough edges before 1.0. Planned next:
usage-driven relevance tuning from
report_usagecontradiction detection for proposals
a light Turkish stemmer for the BM25 side and glossary-alias query expansion
multiple knowledge repositories per instance
Read docs/ARCHITECTURE.md for a guided tour with diagrams. The full
specification is in SPEC.md; decisions are recorded in docs/adr/.
Contributing
Issues and pull requests are welcome — see CONTRIBUTING.md for the development setup, testing rules and conventions. Security issues: SECURITY.md.
License
Available Tools
7 toolscompile_bundleARead-onlyIdempotent
Compile what the team's knowledge base says about a task into one context block within a token budget. Call it once at the start of a task, before code that rules, conventions or past decisions could govern; describe the task in a sentence, not keywords. Sections are deduplicated, ordered domain → conventions → project, each with a source line (path, heading, last-updated date, and a note when the code it governs changed later). Read-only, deterministic, cached: same task, scopes and budget give the same bundle_id and content. Never exceeds max_tokens; a too-small budget truncates the top section with a marker. Afterwards, report which sections helped via report_usage.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | No | Repository-relative code paths the task touches (e.g. ["services/payment/refund.go"]). Rules whose refs cover them come first in the bundle. | |
| scopes | No | Knowledge scopes to draw from, e.g. ["domain","conventions","projects/ledger-service"]. Default: domain and conventions. Add the project scope when working inside a project. | |
| max_tokens | No | Token budget for the whole bundle including its header and source lines (default 2000, must be positive). Never exceeded. | |
| task_description | Yes | What you are about to do, in one or two sentences, in any language (e.g. 'add partial refunds to the merchant portal'). Required; a sentence retrieves better than keywords. |
Output Schema
| Name | Required | Description |
|---|---|---|
| budget | Yes | |
| cached | Yes | |
| scopes | Yes | |
| tokens | Yes | |
| content | Yes | |
| sections | Yes | |
| bundle_id | Yes | |
| truncated | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and idempotentHint annotations, it discloses deterministic caching (same inputs yield same bundle_id/content), never exceeding max_tokens, truncation with a marker, deduplication, and section ordering (domain → conventions → project) with source line details. These are not captured in annotations, adding substantial behavioral 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?
The description is about 100 words but every sentence earns its place: purpose, usage timing, section structure, determinism/caching, budget behavior, and follow-up. It is front-loaded with the core purpose and usage, then covers behavioral details efficiently without redundancy.
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?
Given the output schema exists, the description appropriately omits return structure details. It covers usage timing, ordering, dedup, budget constraints, truncation behavior, and follow-up via report_usage, making it complete for an agent to call correctly in a variety of task scenarios.
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% for all four parameters, so the schema already documents each. The description adds only a minor note that task_description should be a sentence rather than keywords, which slightly enhances the schema's generic description but does not add meaning for paths, scopes, or max_tokens beyond what is already present.
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 clearly states a specific verb ('Compile') and resource ('what the team's knowledge base says about a task') with a concrete output ('one context block within a token budget'). It distinguishes itself from siblings by its one-time, compilation role at task start, rather than a search or retrieval function.
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 explicitly instructs to call once at the start of a task, before code that rules/conventions could govern, and to describe the task in a sentence. It also directs follow-up via report_usage. It does not explicitly name alternative tools like search_context, but the timing and purpose are clear enough to infer when to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_documentARead-onlyIdempotent
Return one knowledge document in full (title, tags, Markdown, last-updated date, and the documents it links to and is linked from) by the doc_path given in search or bundle results. Use it when a section is not enough, to follow a link, or before proposing an update. Read-only; not-found for unknown paths, forbidden outside the requested scopes.
| Name | Required | Description | Default |
|---|---|---|---|
| scopes | No | Optional guard: the document must belong to one of these scopes, otherwise the call is refused. | |
| doc_path | Yes | Repository-relative path of the document exactly as returned in doc_path, e.g. domain/rules/refunds.md. Required. |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | Yes | |
| tags | Yes | |
| links | No | |
| scope | Yes | |
| title | Yes | |
| tokens | Yes | |
| content | Yes | |
| backlinks | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint and idempotentHint, and the description reinforces those. Beyond the annotations, it adds useful behavioral details: not-found for unknown paths and refusal outside requested scopes. These error/guard behaviors are valuable context that the structured annotations alone do not 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, each earning its place: the first defines the output, the second gives usage context, the third compresses error/read-only behavior. The most decision-relevant information is front-loaded, and there is no redundant 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?
For a two-parameter read-only retrieval tool with an output schema, the description covers what the tool returns, where the key parameter comes from, when to use it, and key error behaviors. The sibling context and annotations fill the remaining safety and idempotency profile, so 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 the baseline is 3. The description reinforces that doc_path must be the exact path from search or bundle results and refers to the scopes guard, but it does not add meaning substantially beyond the already-complete parameter descriptions in 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 opens with a specific verb-resource pair, 'Return one knowledge document in full', and enumerates exactly what is included (title, tags, Markdown, last-updated date, links). It distinguishes itself from sibling tools like search_context and compile_bundle by focusing on a single full document obtained via doc_path.
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 explicit when-to-use guidance: 'when a section is not enough, to follow a link, or before proposing an update.' It also notes that doc_path comes from search or bundle results, which orients the agent toward sibling outputs. It stops short of naming specific alternative tools or explicit when-not-to-use conditions, so it misses the top score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_scopesARead-onlyIdempotent
List the knowledge scopes this server holds — the shared 'domain' and 'conventions' scopes plus one 'projects/' per project — with document, section and token counts. Read-only, no input. Use it to discover the project scope to pass to search_context or compile_bundle; by default those search only the shared scopes.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| scopes | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the safety profile is covered. The description adds beyond that by explicitly saying 'Read-only, no input' and by disclosing the structure of what will be returned (shared scopes, per-project scopes, and counts), which gives the agent useful behavioral expectations.
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 sentence front-loads the core purpose ('List the knowledge scopes this server holds') and then packs every remaining clause with useful detail: scope composition, counts, read-only nature, and downstream usage. 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?
Given zero parameters, an output schema, and annotations already covering idempotence/read-only behavior, the description is fully adequate. It explains what is returned, how to use it, and why it matters for sibling tools, leaving no important gap for an agent invoking it.
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 are zero parameters, so the baseline is 4. The description reinforces this by stating 'no input,' which is useful confirmation even though the empty schema already implies it. No further parameter documentation is needed.
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 names a specific resource ('knowledge scopes'), spells out exactly what it lists (shared 'domain'/'conventions' scopes plus 'projects/<name>' scopes), and mentions the accompanying counts. This clearly differentiates it from sibling tools like search_context and compile_bundle, which operate on scopes rather than listing them.
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 explicitly states when to use this tool: 'Use it to discover the project scope to pass to search_context or compile_bundle.' It also explains a key behavioral consequence of those downstream tools—they search only shared scopes by default—which tells an agent why listing scopes first matters.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
propose_updateA
Propose a change to a knowledge document — fix an outdated rule, add a missing decision, create a document — for humans to review. Commits the complete new file to a git branch briefd/proposal- (and opens a pull request when a forge is configured); returns branch, commit and PR URL. Never changes what briefd serves until a human merges. Use it for knowledge that is wrong, stale ('code changed since' in bundles) or missing, not for scratch notes. Fails without a writable git source.
| Name | Required | Description | Default |
|---|---|---|---|
| doc_path | Yes | Repository-relative path of the document to change or create, inside a scope folder, e.g. domain/rules/refunds.md or projects/ledger-service/notes.md. Must end in .md. | |
| new_content | Yes | The complete new content of the file as Markdown, including front matter if the document has any — not a diff or a fragment. Fetch the current content with get_document first when editing. | |
| change_description | Yes | Why this change is needed and what evidence you have, written for the human reviewer (becomes the commit message and pull request description). |
Output Schema
| Name | Required | Description |
|---|---|---|
| branch | Yes | |
| commit | Yes | |
| pr_url | No | |
| pushed | Yes | |
| proposal_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint false, idempotentHint false), the description reveals key behavioral traits: commits to a branch named briefd/proposal-<id>, opens a PR when a forge is configured, returns branch/commit/PR URLs, never changes served content until human merge, and fails without a writable git source. This is rich, accurate context that annotations alone do not provide.
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 yet information-dense, with no filler. Purpose, mechanics, side effects, usage guidance, and failure mode are each covered in two substantive sentences, and the most important constraint (human review, no live change) is front-loaded.
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 write/proposal tool with no read-only or idempotency annotation, the description covers everything an agent needs: behavior, side effects, return values, prerequisites, failure mode, and when not to use it. The presence of an output schema further covers return-value details without requiring elaboration in the description.
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 fully documents all three parameters. The description adds some contextual reinforcement, such as 'complete new file' and 'fetch current content with get_document first,' but does not materially expand on what the schema already states, keeping this at the baseline for high coverage.
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 opens with a specific verb and resource: proposing a change to a knowledge document for human review, with concrete examples (fix outdated rule, add missing decision, create a document). It clearly distinguishes itself from the read-only get_document and other siblings by emphasizing the proposal/branch/PR workflow.
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 explicitly states when to use the tool: for knowledge that is wrong, stale, or missing, and not for scratch notes. It also conditions behavior on environment state (forge configured, writable git source required), which gives an agent clear go/no-go signals.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
report_usageAIdempotent
Record which sections of a compile_bundle result were actually useful for the task, by chunk_id. Optional, best called once after the task is done. An empty useful_chunk_ids list is meaningful: it marks the question as a knowledge gap for the people who maintain the repository. Stores feedback only; it does not change the current bundle or the ranking of this session.
| Name | Required | Description | Default |
|---|---|---|---|
| bundle_id | Yes | The bundle_id returned by compile_bundle. Required. | |
| useful_chunk_ids | Yes | chunk_ids of the bundle's sections that were actually useful. An empty list means nothing in the bundle helped and marks the question as a knowledge gap. |
Output Schema
| Name | Required | Description |
|---|---|---|
| recorded | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true and readOnlyHint=false; the description goes further by stating the exact side-effect scope: 'Stores feedback only; it does not change the current bundle or the ranking of this session.' It also explains the semantic meaning of an empty list as a knowledge gap, which is valuable behavioral context beyond the annotation flags.
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, all information-dense: purpose, timing, empty-list semantics, and side-effect disclosure. The most important scoping ('does not change the current bundle or ranking') is placed at the end but clearly stated. No filler words or redundant restating of the title.
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 two-parameter feedback tool with a 100%-described schema, output schema, and annotations covering idempotency and non-read-only behavior, the description covers all necessary call-time context: what input it expects, when to call, what an empty list means, and that it has no effect on the bundle/ranking. Nothing an agent needs to call 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 the baseline is 3. The description reinforces the meaning of useful_chunk_ids by noting 'empty list means nothing helped,' but the schema already says this. No additional parameter-level syntax or format nuance is added beyond what the schema provides, so no score above baseline is warranted.
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 opens with a specific verb and resource: 'Record which sections of a compile_bundle result were actually useful for the task, by chunk_id.' It clearly differentiates from siblings like compile_bundle (produces the bundle), get_document, and propose_update by framing this as a feedback-recording action on a prior result.
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 provides clear when-to-use context: 'Optional, best called once after the task is done.' It also clarifies what the tool does not do ('does not change the current bundle or the ranking'), which indirectly tells the agent this is a post-hoc logging step rather than an alternative to update/propose tools. It stops short of naming explicit alternative exclusions, so a 4 is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_contextARead-onlyIdempotent
Search the team's knowledge base (domain rules, conventions, decisions, project notes) and return the most relevant sections, ranked, within a token budget. Use it to look something up or see what exists; use compile_bundle when you want one context block for a task. Read-only. Each section carries its path, heading, scope, score and last-updated date; results never exceed max_tokens and say how many sections the budget omitted.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | No | Repository-relative code paths you are working on (e.g. ["services/payment/refund.go"]). Documents whose refs cover them are pulled to the top. | |
| query | Yes | What you are working on or looking for, as a natural-language sentence or a few keywords, in any language (e.g. 'retry policy for acquirer calls'). Required, non-empty. | |
| top_k | No | Maximum number of sections to return before the token budget applies (default 8, server-capped). | |
| scopes | No | Knowledge scopes to search, e.g. ["domain","conventions","projects/ledger-service"]. Default: domain and conventions. Use list_scopes to see the project scopes. | |
| max_tokens | No | Token budget for the returned sections (default 2000, must be positive). The result never exceeds it; lower-ranked sections are omitted first. |
Output Schema
| Name | Required | Description |
|---|---|---|
| budget | Yes | |
| chunks | Yes | |
| scopes | Yes | |
| omitted | Yes | |
| total_tokens | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the description's 'Read-only' aligns with that. It adds valuable behavior beyond annotations: 'results never exceed max_tokens and say how many sections the budget omitted', which informs the agent about output constraints. No contradiction 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?
The description is well-structured and front-loaded with the core purpose, then adds usage guidance, read-only note, and output characteristics. Every sentence adds value with no redundancy, and it is appropriately sized for the tool's complexity.
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?
Given the presence of an output schema, the description correctly focuses on when to use the tool and what to expect (e.g., each section's metadata, token budget behavior). It names sibling tools for alternative paths, making it fully self-contained for an agent to decide and 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 each parameter has a detailed description. The tool description adds minimal extra meaning beyond the schema, such as implying that paths affect ranking, but this is already covered in the path parameter description. With full schema coverage, a baseline of 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?
The description clearly states the verb 'Search' and the resource 'the team's knowledge base', and specifies the action of returning ranked sections within a token budget. It explicitly distinguishes itself from compile_bundle by naming it as an alternative, making the purpose unambiguous and easily separable from siblings.
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 provides explicit when-to-use guidance: 'Use it to look something up or see what exists' and contrasts with compile_bundle for a different need. It also references list_scopes for scopes, giving clear context on how to use the tool and when not to.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_linksARead-onlyIdempotent
List links the knowledge base is missing: documents that mention another document by name without linking to it, and links whose target does not exist. Read-only. Use it when asked to tidy or connect the knowledge base, then fix the documents with propose_update (add [[wikilinks]] in the text or in a related: front-matter list). Suggestions a maintainer dismissed are left out.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of suggestions (default 50, max 200), most-mentioned first. | |
| doc_path | No | Only suggestions for this document (as the one that should add the link). Default: all documents. |
Output Schema
| Name | Required | Description |
|---|---|---|
| broken | Yes | |
| missing | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true; the description redundantly states 'Read-only' but adds valuable behavior beyond annotations: dismissed suggestions are excluded, and the two missing-link categories are clarified. This extra context helps an agent understand the tool's persistent state and filtering behavior.
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 three sentences with the core purpose front-loaded, followed by usage context and behavioral nuance. Each sentence earns its place except for the redundant 'Read-only.' marker, which repeats an annotation.
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 zero-required-parameter tool with a full input schema and an output schema, the description is complete: it covers what the tool returns conceptually, when to use it, how to follow up, and important filtering behavior. The output schema handles return details, so nothing critical 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%, with both `limit` and `doc_path` already documented in the schema. The description does not add parameter-specific details, but the schema fully handles parameter meaning, so the baseline of 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?
The description names a specific verb ('List') and resource ('links the knowledge base is missing') and enumerates two concrete categories: documents that mention another document without linking, and links whose target does not exist. This clearly differentiates it from siblings like search_context and propose_update, which are about searching and modifying rather than surfacing missing links.
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 explicitly states when to use the tool ('when asked to tidy or connect the knowledge base') and names the follow-up tool ('fix the documents with propose_update'). This gives an agent an actionable decision rule and points to the correct sibling for the next step.
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.
4 tool updates
v0.6.0- Changed
compile_bundle1 field changed- added
Input schema / properties / pathsAdded value: +{ + "description": "Repository-relative code paths the task touches (e.g. [\"services/payment/refund.go\"]). Rules whose refs cover them come first in the bundle.", + "items": { + "type": "string" + }, + "type": [ + "null", + "array" + ] +}
- Changed
get_document2 fields changed- added
Output schema / properties / backlinksAdded value: +{ + "items": { + "type": "string" + }, + "type": [ + "null", + "array" + ] +} - added
Output schema / properties / linksAdded value: +{ + "items": { + "type": "string" + }, + "type": [ + "null", + "array" + ] +}
- Changed
search_context1 field changed- added
Input schema / properties / pathsAdded value: +{ + "description": "Repository-relative code paths you are working on (e.g. [\"services/payment/refund.go\"]). Documents whose refs cover them are pulled to the top.", + "items": { + "type": "string" + }, + "type": [ + "null", + "array" + ] +}
- Added
suggest_links
5 tool updates
v0.5.0- Changed
compile_bundle3 fields changed- changed
Input schema / properties / max_tokens / descriptionPrevious value: -"Token budget for the whole bundle (default 2000). Never exceeded."New value: +"Token budget for the whole bundle including its header and source lines (default 2000, must be positive). Never exceeded." - changed
Input schema / properties / scopes / descriptionPrevious value: -"Knowledge scopes to draw from. Default: domain and conventions."New value: +"Knowledge scopes to draw from, e.g. [\"domain\",\"conventions\",\"projects/ledger-service\"]. Default: domain and conventions. Add the project scope when working inside a project." - changed
Input schema / properties / task_description / descriptionPrevious value: -"What you are about to do, in one or two sentences (e.g. 'add partial refunds to the merchant portal')"New value: +"What you are about to do, in one or two sentences, in any language (e.g. 'add partial refunds to the merchant portal'). Required; a sentence retrieves better than keywords."
- Changed
get_document2 fields changed- changed
Input schema / properties / doc_path / descriptionPrevious value: -"Repository-relative path of the document, e.g. domain/rules/refunds.md"New value: +"Repository-relative path of the document exactly as returned in doc_path, e.g. domain/rules/refunds.md. Required." - changed
Input schema / properties / scopes / descriptionPrevious value: -"If given, the document must belong to one of these scopes"New value: +"Optional guard: the document must belong to one of these scopes, otherwise the call is refused."
- Changed
propose_update3 fields changed- changed
Input schema / properties / change_description / descriptionPrevious value: -"Why this change is needed, for the reviewer (becomes the commit/PR description)"New value: +"Why this change is needed and what evidence you have, written for the human reviewer (becomes the commit message and pull request description)." - changed
Input schema / properties / doc_path / descriptionPrevious value: -"Repository-relative path of the document to change or create, e.g. domain/rules/refunds.md"New value: +"Repository-relative path of the document to change or create, inside a scope folder, e.g. domain/rules/refunds.md or projects/ledger-service/notes.md. Must end in .md." - changed
Input schema / properties / new_content / descriptionPrevious value: -"The complete new content of the file (Markdown, including front matter if any)"New value: +"The complete new content of the file as Markdown, including front matter if the document has any — not a diff or a fragment. Fetch the current content with get_document first when editing."
- Changed
report_usage2 fields changed- changed
Input schema / properties / bundle_id / descriptionPrevious value: -"The bundle_id returned by compile_bundle"New value: +"The bundle_id returned by compile_bundle. Required." - changed
Input schema / properties / useful_chunk_ids / descriptionPrevious value: -"chunk_ids from the bundle's sections that were actually useful (may be empty)"New value: +"chunk_ids of the bundle's sections that were actually useful. An empty list means nothing in the bundle helped and marks the question as a knowledge gap."
- Changed
search_context4 fields changed- changed
Input schema / properties / max_tokens / descriptionPrevious value: -"Token budget for the returned sections (default 2000). The result never exceeds it."New value: +"Token budget for the returned sections (default 2000, must be positive). The result never exceeds it; lower-ranked sections are omitted first." - changed
Input schema / properties / query / descriptionPrevious value: -"What you are working on or looking for, in natural language (e.g. 'retry policy for acquirer calls')"New value: +"What you are working on or looking for, as a natural-language sentence or a few keywords, in any language (e.g. 'retry policy for acquirer calls'). Required, non-empty." - changed
Input schema / properties / scopes / descriptionPrevious value: -"Knowledge scopes to search, e.g. [\"domain\",\"conventions\",\"projects/ledger-service\"]. Default: domain and conventions."New value: +"Knowledge scopes to search, e.g. [\"domain\",\"conventions\",\"projects/ledger-service\"]. Default: domain and conventions. Use list_scopes to see the project scopes." - changed
Input schema / properties / top_k / descriptionPrevious value: -"Maximum number of sections to return (default 8)"New value: +"Maximum number of sections to return before the token budget applies (default 8, server-capped)."
6 tool updates
v0.4.0- First observed
compile_bundle - First observed
get_document - First observed
list_scopes - First observed
propose_update - First observed
report_usage - First observed
search_context
TDQS
Scored across 7 tools
Most tools are clearly distinct: get_document for full documents by path, list_scopes for discovery, propose_update for writing, suggest_links for maintenance, and report_usage for feedback. The only real overlap is between search_context and compile_bundle, which both return relevant sections with token budgets, though their descriptions give different intended use cases (lookup vs. task compilation).
All seven tools follow a consistent verb_noun snake_case pattern: get_document, compile_bundle, list_scopes, search_context, suggest_links, propose_update, report_usage. Every name clearly pairs an action with an object, and there are no mixed conventions or vague generic verbs.
Seven tools is a well-scoped set for a team knowledge-base server: discovery, retrieval, search, compilation, writing, link maintenance, and usage feedback each have exactly one dedicated tool. The count feels complete without redundancy or bloat.
The surface covers the main lifecycle well: read via get_document/search_context/compile_bundle, update via propose_update, discover scopes via list_scopes, and maintain quality via suggest_links and report_usage. Minor gaps remain—there is no direct way to list all documents in a scope beyond counts, and propose_update doesn't obviously support deletion.
Maintenance
Related MCP Connectors
Git-backed platform for skills, tools, and context for AI agents
Intelligent context infrastructure for AI teams: knowledge graph, sessions, tasks, documents.
shared AI-context layer for teams — persistent memory your agents search and update over MCP
Your company's brain for AI agents. Cited, permission-aware knowledge across every system.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenancePersistent codebase knowledge layer for AI agents. Pre-digests codebases into structured knowledge (symbols, dependency graphs, co-change patterns, architectural decisions) and serves via MCP. 28 languages, 14 tools, ~85% token reduction.11 npm8MIT
- AlicenseAqualityAmaintenanceSelf-hosted memory and governance layer for AI coding agents. 28 MCP tools with hybrid search, structured knowledge capture, behavioral nudges, and git-native storage. Zero cloud dependencies.306Business Source 1.1
- AlicenseNot gradedqualityAmaintenanceSelf-hosted AI Agent Memory + Code Intelligence Platform providing persistent memory, AST-aware code search, and quality enforcement via a single MCP endpoint.59MIT
- FlicenseNot gradedqualityBmaintenanceMCP server for Agent Context OS that compiles engineering docs into a knowledge graph, detects code drift, and serves token-budgeted context packs to AI coding agents via MCP.-