-
-
Notifications
You must be signed in to change notification settings - Fork 11
MCP Integration
CKB exposes AI-native code navigation and architectural memory capabilities via the Model Context Protocol (MCP), enabling AI assistants like Claude Code to discover, understand, and navigate codebases with persistent knowledge.
CKB works with any MCP-compatible AI coding tool.
# Install CKB
npm install -g @tastehub/ckb
# Configure for current project
ckb setup
# Or configure globally for all projects
ckb setup --global
# Verify configuration
claude mcp listOr with npx (no install):
npx @tastehub/ckb setupManual configuration — add to .mcp.json in project root:
{
"mcpServers": {
"ckb": {
"command": "npx",
"args": ["@tastehub/ckb", "mcp"]
}
}
}Add to ~/.cursor/mcp.json (global) or .cursor/mcp.json (project):
{
"mcpServers": {
"ckb": {
"command": "npx",
"args": ["@tastehub/ckb", "mcp"]
}
}
}Or go to Settings → Cursor Settings → MCP → Add new global MCP server.
Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"ckb": {
"command": "npx",
"args": ["@tastehub/ckb", "mcp"]
}
}
}Or go to Windsurf Settings → Advanced Settings → Cascade → Manage MCP Servers.
Add to your VS Code settings.json:
{
"mcp": {
"servers": {
"ckb": {
"type": "stdio",
"command": "npx",
"args": ["@tastehub/ckb", "mcp"]
}
}
}
}Add to opencode.json in project root:
{
"mcp": {
"ckb": {
"type": "local",
"command": ["npx", "@tastehub/ckb", "mcp"],
"enabled": true
}
}
}Note: OpenCode uses a different config format - command is an array and requires type: "local".
Claude Desktop is a standalone app without a project context, so CKB needs to know which repository to analyze.
Automatic setup (recommended):
cd /path/to/your/repo
ckb setup --tool=claude-desktopThis prompts for your repository path and configures everything automatically.
Manual configuration — add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"ckb": {
"command": "npx",
"args": ["-y", "@tastehub/ckb", "mcp"],
"env": {
"CKB_REPO": "/path/to/your/repo"
}
}
}
}The CKB_REPO environment variable tells CKB which repository to analyze. You can also use the --repo flag directly:
{
"mcpServers": {
"ckb": {
"command": "npx",
"args": ["-y", "@tastehub/ckb", "mcp", "--repo", "/path/to/your/repo"]
}
}
}Important: Claude Desktop can only work with one repository at a time. To switch repositories, run ckb setup --tool=claude-desktop again or update the config manually.
On Windows, wrap the command with cmd /c in any of the configs above:
{
"mcpServers": {
"ckb": {
"command": "cmd",
"args": ["/c", "npx", "@tastehub/ckb", "mcp"]
}
}
}If you built from source or installed globally, use the binary directly:
{
"mcpServers": {
"ckb": {
"command": "ckb",
"args": ["mcp"]
}
}
}CKB exposes 76 tools, but most sessions only need a subset. Presets reduce token overhead by up to 83% by limiting exposed tools to task-relevant sets.
| Preset | Tools | Tokens | Use Case |
|---|---|---|---|
core |
14 | ~1,531 | Essential navigation and analysis (default) |
review |
19 | ~2,294 | Code review: PR summary, ownership, diff |
refactor |
19 | ~2,216 | Refactoring: coupling, dead code, impact |
docs |
20 | ~2,093 | Documentation: coverage, staleness checks |
ops |
25 | ~2,366 | Operations: jobs, webhooks, metrics |
federation |
28 | ~3,122 | Multi-repo: cross-repo search |
full |
76 | ~9,043 | All tools (legacy behavior) |
# Discover available presets
ckb mcp --list-presets
# Start MCP server with a preset
ckb mcp # Default: core preset (14 tools)
ckb mcp --preset=review # Code review workflow
ckb mcp --preset=full # All 76 tools (legacy)Use --list-presets to see all available presets with tool counts and token estimates:
$ ckb mcp --list-presets
Available presets:
PRESET TOOLS TOKENS DESCRIPTION
------ ----- ------ -----------
core 14 ~2k tokens Quick navigation, search, impact analysis (default)
review 19 ~2k tokens Code review with ownership and PR summaries
refactor 19 ~2k tokens Refactoring analysis with coupling and dead code
federation 28 ~3k tokens Multi-repo queries and cross-repo visibility
docs 20 ~2k tokens Documentation-symbol linking and coverage
ops 25 ~2k tokens Diagnostics, daemon, webhooks, jobs
full 76 ~9k tokens Complete feature set (all tools)
Use: ckb mcp --preset=<name>
CKB shows token savings at startup:
CKB MCP Server v7.5.0
Active tools: 14 / 76 (18%)
Estimated context: ~1k tokens
Preset: core
The getStatus tool also returns token estimates:
"preset": {
"active": "core",
"exposed": 14,
"total": 76,
"estimatedTokens": 1529,
"fullPresetTokens": 9040,
"tokenSavings": "83%"
}This addresses community concerns about MCP tools consuming 50-80k tokens before conversations even start.
{
"mcpServers": {
"ckb": {
"command": "npx",
"args": ["@tastehub/ckb", "mcp", "--preset=review"]
}
}
}The core preset includes 14 essential tools for investigation and impact analysis:
| Category | Tools |
|---|---|
| Discovery |
searchSymbols, getSymbol
|
| Understanding |
explainSymbol, explainFile, findReferences, getCallGraph, traceUsage
|
| Architecture |
getArchitecture, getModuleOverview, listKeyConcepts
|
| Impact |
analyzeImpact, getHotspots
|
| System |
getStatus, expandToolset
|
The expandToolset meta-tool allows AI to request additional tools mid-session:
{
"name": "expandToolset",
"arguments": {
"preset": "federation",
"reason": "User asked about cross-repository dependencies"
}
}Guardrails:
- Requires a reason (minimum 10 characters) explaining why expansion is needed
- Rate-limited to one expansion per session
- Emits
tools/list_changednotification for compliant clients
For MCP clients that support pagination, CKB uses cursor-based pagination with:
- Page size: 15 tools per page
- Core-first ordering: Page 1 always contains the complete core toolset
- Cursor invalidation: Cursors rejected when preset or toolset changes
Non-paginating clients receive all tools in the current preset on the first request.
Tools are classified by performance budget.
searchSymbols · explainFile · listEntrypoints · explainPath · getSymbol · explainSymbol · getOwnership · getModuleResponsibilities · recordDecision · getDecisions · annotateModule · listFederations · federationStatus · federationRepos · daemonStatus · listSchedules · runSchedule · listWebhooks · testWebhook · webhookDeliveries · getFileComplexity · listContracts · suppressContractEdge · verifyContractEdge · getContractStats · getTelemetryStatus · getObservedUsage · explainOrigin · getDocsForSymbol · getSymbolsInDoc · getDocsForModule · federationAddRemote · federationRemoveRemote · federationListRemote · federationStatusRemote · federationListAllRepos
- Max 1 hop traversal
- Max 50 results
- No callgraph expansion or deep git history
traceUsage · getArchitecture · getHotspots · summarizeDiff · recentlyRelevant · listKeyConcepts · analyzeImpact · getCallGraph · findReferences · justifySymbol · federationSearchModules · federationSearchOwnership · federationGetHotspots · federationSearchDecisions · federationSync · analyzeContractImpact · getContractDependencies · findDeadCodeCandidates · analyzeCoupling · exportForLLM · auditRisk · indexDocs · checkDocStaleness · getDocCoverage · federationSyncRemote · federationSearchSymbolsHybrid
- Up to depth 5 traversal
- Up to 1000 git commits
- Must include
limitationsfield
refreshArchitecture · summarizePr · getOwnershipDrift
-
refreshArchitecture: Supports async mode (v6.1) — returnsjobIdfor polling -
summarizePr: Analyze PR changes, suggest reviewers, assess risk -
getOwnershipDrift: Compare CODEOWNERS vs actual git-blame ownership
All 76 MCP tools now return responses wrapped in a standardized envelope with metadata:
{
"schemaVersion": "1.0",
"data": { /* tool-specific payload */ },
"meta": {
"confidence": {
"score": 0.85,
"tier": "medium",
"reasons": ["SCIP+git hybrid"]
},
"provenance": {
"backends": ["scip", "git"],
"repoStateId": "abc123def456"
},
"freshness": {
"indexAge": {
"commitsBehind": 3,
"staleReason": "behind-head"
}
},
"truncation": {
"isTruncated": true,
"shown": 10,
"total": 47,
"reason": "max-results"
}
},
"warnings": [
{ "code": "W001", "message": "Index slightly stale" }
],
"error": null,
"suggestedNextCalls": [
{
"tool": "getModuleOverview",
"params": { "path": "internal/query" },
"reason": "Explore top impacted module"
}
]
}Key Envelope Fields:
| Field | Description |
|---|---|
schemaVersion |
Envelope format version (currently "1.0") |
data |
Tool-specific response payload |
meta.confidence |
How trustworthy the results are |
meta.provenance |
Which backends contributed data |
meta.freshness |
Index staleness information |
meta.truncation |
When results are cut off by limits |
warnings |
Non-fatal issues to be aware of |
error |
Error message if request failed |
suggestedNextCalls |
Structured follow-up recommendations |
| Tier | Score Range | Conditions |
|---|---|---|
high |
≥ 0.95 | Fresh SCIP index, full static analysis |
medium |
0.70 - 0.94 | Stale SCIP, LSP fallback, partial analysis |
low |
0.30 - 0.69 | Heuristics only, git-based analysis |
speculative |
< 0.30 | Cross-repo queries, uncommitted changes |
Score Modifiers:
| Condition | Effect |
|---|---|
| Full static analysis (SCIP/LSP) | Base 1.0 |
| Partial static analysis | Cap at 0.89 |
| Heuristics only | Cap at 0.79 |
| Key backend missing | Cap at 0.69 |
| Multiple backends missing | Cap at 0.39 |
| Index > 5 commits behind | Downgrade to medium |
| Cross-repo query | Force speculative |
| Tool | Default |
|---|---|
getHotspots |
30 days |
summarizeDiff |
30 days |
recentlyRelevant |
7 days |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
searchSymbols |
Cheap | Search with filtering | v5.1 ✓ |
getSymbol |
Cheap | Get symbol details | v5.1 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
traceUsage |
Heavy | How is this reached? | v5.2 ✓ |
listEntrypoints |
Cheap | System entrypoints | v5.2 ✓ |
getCallGraph |
Heavy | Caller/callee graph | v5.1 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
explainFile |
Cheap | File orientation | v5.2 ✓ |
explainPath |
Cheap | Path role explanation | v5.2 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
summarizeDiff |
Heavy | What changed? | v5.2 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
getArchitecture |
Heavy | Architecture overview | v5.2 ✓ |
getHotspots |
Heavy | Volatile areas with trends | v6.0 ✓ |
listKeyConcepts |
Heavy | Domain concepts | v5.2 ✓ |
recentlyRelevant |
Heavy | What matters now? | v5.2 ✓ |
getModuleOverview |
Heavy | Module statistics | v5.1 ✓ |
getModuleResponsibilities |
Cheap | Module purpose & capabilities | v6.0 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
explainSymbol |
Cheap | AI-friendly explanation | v5.1 ✓ |
justifySymbol |
Heavy | Keep/remove verdict | v5.1 ✓ |
findReferences |
Heavy | Find all usages | v5.1 ✓ |
analyzeImpact |
Heavy | Change risk | v5.1 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
getOwnership |
Cheap | Who owns this code? | v6.0 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
recordDecision |
Cheap | Create an ADR | v6.0 ✓ |
getDecisions |
Cheap | Query ADRs | v6.0 ✓ |
annotateModule |
Cheap | Add module metadata | v6.0 ✓ |
refreshArchitecture |
Heavy | Rebuild architectural model | v6.0 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
getStatus |
Cheap | System health | v5.1 ✓ |
doctor |
Cheap | Diagnostics | v5.1 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
getJobStatus |
Cheap | Query job by ID | v6.1 ✓ |
listJobs |
Cheap | List jobs with filters | v6.1 ✓ |
cancelJob |
Cheap | Cancel queued/running job | v6.1 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
summarizePr |
Heavy | PR risk analysis & reviewers | v6.1 ✓ |
getOwnershipDrift |
Heavy | CODEOWNERS vs actual ownership | v6.1 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
daemonStatus |
Cheap | Daemon health and stats | v6.2.1 ✓ |
listSchedules |
Cheap | List scheduled tasks | v6.2.1 ✓ |
runSchedule |
Cheap | Run a schedule immediately | v6.2.1 ✓ |
listWebhooks |
Cheap | List configured webhooks | v6.2.1 ✓ |
testWebhook |
Cheap | Send test webhook | v6.2.1 ✓ |
webhookDeliveries |
Cheap | Get delivery history | v6.2.1 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
getFileComplexity |
Cheap | Cyclomatic/cognitive complexity metrics | v6.2.2 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
listContracts |
Cheap | List contracts in federation | v6.3 ✓ |
analyzeContractImpact |
Heavy | Analyze impact of contract changes | v6.3 ✓ |
getContractDependencies |
Heavy | Get contract deps for a repo | v6.3 ✓ |
suppressContractEdge |
Cheap | Suppress false positive edge | v6.3 ✓ |
verifyContractEdge |
Cheap | Verify an edge | v6.3 ✓ |
getContractStats |
Cheap | Contract statistics | v6.3 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
getTelemetryStatus |
Cheap | Coverage metrics and sync status | v6.4 ✓ |
getObservedUsage |
Cheap | Usage data for a symbol | v6.4 ✓ |
findDeadCodeCandidates |
Heavy | Find symbols with zero runtime calls | v6.4 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
explainOrigin |
Cheap | Why does this code exist? (origin, evolution, warnings) | v6.5 ✓ |
analyzeCoupling |
Heavy | Find files/symbols that change together | v6.5 ✓ |
exportForLLM |
Heavy | LLM-friendly codebase export | v6.5 ✓ |
auditRisk |
Heavy | Multi-signal risk audit (8 factors) | v6.5 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
indexDocs |
Heavy | Scan and index documentation for symbol references | v7.3 ✓ |
getDocsForSymbol |
Cheap | Find docs referencing a symbol | v7.3 ✓ |
getSymbolsInDoc |
Cheap | List symbols in a document | v7.3 ✓ |
getDocsForModule |
Cheap | Find docs linked to a module via directive | v7.3 ✓ |
checkDocStaleness |
Heavy | Check for stale symbol references | v7.3 ✓ |
getDocCoverage |
Heavy | Documentation coverage statistics | v7.3 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
federationAddRemote |
Cheap | Add a remote CKB index server | v7.3 ✓ |
federationRemoveRemote |
Cheap | Remove a remote server | v7.3 ✓ |
federationListRemote |
Cheap | List remote servers in a federation | v7.3 ✓ |
federationSyncRemote |
Heavy | Sync metadata from remote servers | v7.3 ✓ |
federationStatusRemote |
Cheap | Get status of a remote server | v7.3 ✓ |
federationSearchSymbolsHybrid |
Heavy | Search symbols across local + remote | v7.3 ✓ |
federationListAllRepos |
Cheap | List repos from local and remote sources | v7.3 ✓ |
| Tool | Budget | Purpose | Status |
|---|---|---|---|
listRepos |
Cheap | List registered repos with state and active status | v7.3 ✓ |
switchRepo |
Cheap | Switch active repo context for MCP session | v7.3 ✓ |
getActiveRepo |
Cheap | Get information about currently active repo | v7.3 ✓ |
Show how something is reached (causal paths, not neighbors).
Budget: Heavy
{ "symbolId": "...", "maxPaths": 10, "pathTypes": ["api", "cli"] }Path types: api | cli | job | event | test | unknown
Differs from getCallGraph: Returns ranked paths from entrypoints, not local neighborhood.
List system entrypoints.
Budget: Cheap
{ "types": ["api", "cli"], "limit": 30 }Entrypoint types: api | cli | job | event
Detection basis: naming | framework-config | static-call
File-level orientation.
Budget: Cheap
{ "filePath": "internal/query/engine.go" }Output: File role, top symbols (max 15), imports/exports, local hotspots.
Why does this path exist?
Budget: Cheap
{ "filePath": "internal/legacy/handler.go", "contextHint": "from traceUsage" }Role classifications: core | glue | legacy | test-only | config | unknown
What changed, what might break?
Budget: Heavy
{ "prId": "123" }
// or
{ "commitRange": { "base": "main", "head": "feature" } }
// or
{ "commit": "abc123" }
// or
{ "timeWindow": { "start": "2025-12-01", "end": "2025-12-17" } }Output: Files touched, risk signals, suggested tests.
Not allowed: Code suggestions, refactor plans.
Conservative architectural overview.
Budget: Heavy
{ "depth": 2, "includeExternalDeps": false }Hard caps: 15–20 modules, 50 edges max.
Highlight volatile areas.
Budget: Heavy
{ "timeWindow": { "days": 30 }, "scope": "internal/query", "limit": 20 }Ranking signals: churn, coupling, recency
Main domain concepts in the codebase.
Budget: Heavy
{ "limit": 12 }Output per concept:
-
label: "Auth", "Billing", etc. -
evidence: Top 3–5 modules/symbols -
basis:naming|cluster|entrypoints
What should I care about now?
Budget: Heavy
{ "timeWindow": { "days": 7 }, "moduleFilter": "internal/api" }Ranking signals: churn, fanIn, hasOpenChanges
{ "query": "Handler", "kinds": ["function"], "scope": "internal/api", "limit": 50 }{ "symbolId": "...", "repoStateMode": "head" }{ "symbolId": "...", "scope": "internal/mcp", "includeTests": true, "limit": 100 }{ "symbolId": "..." }Output: Name, kind, signature, usage stats, git history, related symbols, and (v6.5) annotations containing related ADRs and module metadata.
{ "symbolId": "..." }Verdicts: keep | investigate | remove-candidate
v6.5: Now considers related ADRs - if a module has an accepted/proposed ADR, symbols without callers return "investigate" instead of "remove-candidate" with reasoning like "No callers found, but related to ADR-001: Use Redis for caching".
{ "symbolId": "...", "direction": "both", "depth": 2 }{ "path": "internal/query" }v6.5: Now includes annotations (responsibility, capabilities, tags, boundaries) and relatedDecisions (ADRs affecting this module).
{ "symbolId": "...", "depth": 3, "includeTelemetry": true }v6.5: Now includes relatedDecisions showing ADRs that affect any of the impacted modules.
Get system status including backend availability, cache statistics, and index freshness.
{}Response includes (v7.5):
{
"version": "7.5.0",
"repository": "/path/to/repo",
"backends": {
"scip": "available",
"treeSitter": "available"
},
"index": {
"fresh": false,
"commitsBehind": 5,
"hasUncommitted": true,
"indexAge": "2 hours",
"reason": "5 commit(s) behind HEAD + uncommitted changes"
},
"cache": {
"queries": 156,
"hitRate": 0.85
},
"preset": {
"active": "core",
"exposed": 14,
"total": 76,
"expanded": false,
"estimatedTokens": 1529,
"fullPresetTokens": 9040,
"tokenSavings": "83%"
}
}The index field (v7.5) provides staleness visibility:
-
fresh— Whether the index is up to date -
commitsBehind— Number of commits since last index -
hasUncommitted— Whether there are uncommitted changes in the working tree -
indexAge— Human-readable age (e.g., "2 hours", "1 day") -
reason— Staleness reason when not fresh
The preset field (v7.5) provides token efficiency visibility:
-
active— Current preset name -
exposed— Number of tools exposed to the AI -
total— Total available tools -
expanded— WhetherexpandToolsetwas called this session -
estimatedTokens— Estimated tokens for current preset's tools/list -
fullPresetTokens— Estimated tokens if using all tools -
tokenSavings— Percentage reduction vs full preset
{}| Preset | Focus |
|---|---|
onboarding |
Broad, concept-first |
bug-investigation |
Trace-focused, recent changes |
refactor-safety |
Coupling and hotspots |
review |
Diff-centric, risk signals |
getStatus() → listKeyConcepts() → getArchitecture() → listEntrypoints() → searchSymbols()
searchSymbols() → traceUsage() → getCallGraph() → recentlyRelevant()
searchSymbols() → explainSymbol() → findReferences() → analyzeImpact() → getHotspots()
summarizeDiff() → getHotspots() → getOwnership() → traceUsage()
searchSymbols() → justifySymbol() → explainFile()
getArchitecture() → getOwnership() → getModuleResponsibilities()
getDecisions() → recordDecision() → annotateModule()
findDeadCodeCandidates() → justifySymbol() → [check for "investigate" with ADR reasoning]
If justifySymbol returns "investigate" with reasoning mentioning an ADR, the code isn't dead—it was an intentional architectural decision. Only "remove-candidate" without ADR context suggests safe removal.
analyzeImpact() → [check relatedDecisions] → getDecisions()
When analyzeImpact shows relatedDecisions, read them before making changes to understand the architectural context.
getHotspots() → getOwnership() → summarizeDiff()
summarizePr() → getOwnershipDrift() → getHotspots()
refreshArchitecture({ async: true }) → getJobStatus() → [poll until complete]
listFederations() → federationStatus() → federationSearchModules() → federationGetHotspots()
federationSearchOwnership() → federationSearchDecisions() → federationSync()
daemonStatus() → listSchedules() → listWebhooks() → webhookDeliveries()
listSchedules() → runSchedule() → listJobs() → getJobStatus()
listContracts() → analyzeContractImpact() → getContractDependencies() → getContractStats()
listContracts() → analyzeContractImpact() → [contact owners] → federationSync()
getTelemetryStatus() → [verify coverage is medium+] → findDeadCodeCandidates() → justifySymbol()
searchSymbols() → getObservedUsage() → analyzeImpact({ includeTelemetry: true })
searchSymbols() → explainOrigin() → analyzeCoupling() → auditRisk()
analyzeCoupling() → getHotspots() → getOwnership()
exportForLLM() → [paste to LLM for codebase understanding]
auditRisk() → auditRisk({ quickWins: true }) → explainOrigin()
indexDocs() → checkDocStaleness({ all: true }) → getDocsForSymbol() → getDocCoverage()
searchSymbols() → getDocsForSymbol() → [rename symbol] → checkDocStaleness()
federationAddRemote() → federationSyncRemote() → federationStatusRemote() → federationSearchSymbolsHybrid()
federationListRemote() → federationSearchSymbolsHybrid({ servers: [...] }) → federationListAllRepos()
| Code | Fix |
|---|---|
SYMBOL_NOT_FOUND |
Use searchSymbols() first |
BACKEND_UNAVAILABLE |
Check getStatus() |
INDEX_STALE |
Run scip-go |
QUERY_TIMEOUT |
Add scope/limit |
BUDGET_EXCEEDED |
Use cheaper tool |
- ❌ Code mutation/refactoring
- ❌ Test generation
- ❌ Fix suggestions
- ❌ Policy enforcement
- ❌ Lint judgments
Navigation and comprehension only.
Query ownership for a path, module, or symbol.
Budget: Cheap
{ "path": "internal/api/handler.go" }
// or
{ "moduleId": "internal/api" }
// or
{ "symbolId": "...", "includeHistory": true }Output:
-
owners: List of owners with scope (maintainer/reviewer/contributor) -
source: "codeowners" | "git-blame" | "declared" -
suggestedReviewers: Recommended PR reviewers -
history: Ownership changes over time (ifincludeHistory: true)
Sources: CODEOWNERS file (confidence: 1.0), git blame (confidence: 0.79)
Query what a module is responsible for.
Budget: Cheap
{ "moduleId": "internal/query", "includeSymbols": true }Output per module:
-
summary: One-sentence description -
capabilities: What the module provides -
keySymbols: Important exports (ifincludeSymbols: true) -
confidence: How certain we are -
source: "declared" | "inferred" | "llm-generated"
Create an Architectural Decision Record (ADR).
Budget: Cheap
{
"title": "Use SCIP for code indexing",
"context": "We need fast, accurate symbol resolution...",
"decision": "We will use SCIP indexes generated by scip-go...",
"consequences": ["Requires index regeneration on code changes", "..."],
"affectedModules": ["internal/backends/scip"],
"alternatives": ["LSP-only approach", "Custom parser"],
"status": "proposed"
}Parameters:
| Parameter | Required | Description |
|---|---|---|
title |
Yes | Short title for the decision |
context |
Yes | Background and forces driving the decision |
decision |
Yes | What was decided and why |
consequences |
No | List of consequences (positive and negative) |
affectedModules |
No | Module paths this decision applies to |
alternatives |
No | Other options that were considered |
status |
No |
proposed (default), accepted, deprecated, superseded
|
author |
No | Who made this decision |
Output:
-
id: Assigned ADR ID (e.g., "ADR-001") -
path: File path to the ADR markdown file -
status: "created" | "updated"
v6.5 Integration: Once recorded, decisions automatically appear in:
-
explainSymbol→annotations.relatedDecisionsfor symbols in affected modules -
justifySymbol→ Influences verdict (prevents "remove-candidate" for intentional code) -
analyzeImpact→relatedDecisionswhen impacting modules with ADRs -
getModuleOverview→relatedDecisionsfor the module
Query architectural decisions.
Budget: Cheap
{ "moduleId": "internal/query", "status": ["accepted"], "search": "caching" }Parameters:
| Parameter | Required | Description |
|---|---|---|
id |
No | Get a specific ADR by ID (e.g., "ADR-001") |
moduleId |
No | Filter to ADRs affecting a specific module |
status |
No | Filter by status: proposed, accepted, deprecated, superseded
|
search |
No | Full-text search in title and content |
limit |
No | Max results (default: 50) |
Output:
{
"decisions": [
{
"id": "ADR-001",
"title": "Use Redis for caching",
"status": "accepted",
"affectedModules": ["internal/cache"],
"filePath": "docs/decisions/adr-001-use-redis.md",
"date": "2024-01-15",
"author": "team-platform"
}
],
"totalCount": 1
}Add or update module metadata. Annotations are used by other tools for context.
Budget: Cheap
{
"moduleId": "internal/api",
"responsibility": "HTTP API handlers and middleware",
"capabilities": ["REST", "WebSocket", "Authentication"],
"tags": ["core", "api"],
"publicPaths": ["handler.go", "routes.go"],
"internalPaths": ["helpers.go", "middleware.go"]
}Parameters:
| Parameter | Required | Description |
|---|---|---|
moduleId |
Yes | Module path (e.g., "internal/api") |
responsibility |
No | One-sentence description of the module's purpose |
capabilities |
No | List of capabilities this module provides |
tags |
No | Categorization tags (e.g., "core", "deprecated", "infrastructure") |
publicPaths |
No | Files that are part of the public API |
internalPaths |
No | Files that are internal implementation |
Output:
-
status: "created" | "updated" -
moduleId: The module that was annotated -
responsibility: The set responsibility -
capabilities: The set capabilities -
tags: The set tags
v6.5 Integration: Once annotated, module metadata appears in:
-
explainSymbol→annotations.moduleAnnotationswith responsibility, capabilities, tags -
getModuleOverview→annotationsfield with full module metadata -
getModuleResponsibilities→ Declared annotations override inferred ones with higher confidence
Rebuild the architectural model from sources.
Budget: Heavy (up to 30s)
{ "scope": "all", "force": true, "dryRun": false }Scope options:
-
all: Refresh everything -
modules: Only module detection -
ownership: Only CODEOWNERS + git-blame -
hotspots: Only hotspot snapshots -
responsibilities: Only responsibility extraction
Output:
-
status: "completed" | "skipped" -
changes: Count of updates per category -
duration: Time taken
Now includes historical trends and module-level aggregation.
New fields in response:
{
"hotspots": [{
"targetId": "internal/query/engine.go",
"score": 0.85,
"trend": {
"direction": "increasing",
"velocity": 0.02,
"projection30d": 0.91
},
"metrics": {
"churnCommits30d": 12,
"churnAuthors30d": 3,
"complexityCyclomatic": 25
}
}]
}Query status and result of a background job.
Budget: Cheap
{ "jobId": "job-abc123" }Output:
-
id: Job identifier -
type: Job type (e.g., "refresh-architecture") -
status: "queued" | "running" | "completed" | "failed" | "cancelled" -
progress: 0-100 percentage -
result: Job-specific result (when completed) -
error: Error message (when failed)
List jobs with optional filters.
Budget: Cheap
{ "status": "running", "type": "refresh-architecture", "limit": 20 }Filters:
-
status: Filter by job status -
type: Filter by job type -
limit: Max results (default: 20)
Cancel a queued or running job.
Budget: Cheap
{ "jobId": "job-abc123" }Output:
-
cancelled: true if job was cancelled -
status: Final job status
Now supports async mode for long-running operations.
Budget: Heavy (sync) / Cheap (async)
{ "scope": "all", "force": true, "async": true }New async fields:
-
async: Set totrueto run in background - Response includes
jobIdwhen async
Usage pattern:
1. refreshArchitecture({ async: true }) → { jobId: "..." }
2. getJobStatus({ jobId }) → { status: "running", progress: 50 }
3. getJobStatus({ jobId }) → { status: "completed", result: {...} }
Analyze a pull request for risk, affected modules, and suggested reviewers.
Budget: Heavy
{ "baseBranch": "main", "headBranch": "feature/my-feature" }
// or
{ "baseBranch": "main" } // uses current branch as headOutput:
-
filesChanged: Number of files modified -
linesAdded/linesRemoved: Change volume -
modulesAffected: List of affected module IDs -
hotspotsTouched: Hotspots in changed files -
suggestedReviewers: Recommended reviewers from ownership data -
riskAssessment: "low" | "medium" | "high" -
riskFactors: Reasons for the risk level
Risk factors considered:
- Hotspot files touched
- Number of modules affected
- Breaking API changes
- Missing test coverage
Compare declared ownership (CODEOWNERS) vs actual ownership (git-blame).
Budget: Heavy
{ "scope": "internal/api", "threshold": 0.3, "limit": 20 }Parameters:
-
scope: Module or path to analyze (optional, defaults to all) -
threshold: Minimum drift score to include (0.0-1.0, default: 0.3) -
limit: Max results (default: 20)
Output per drifted file:
-
path: File path -
declaredOwner: Owner from CODEOWNERS -
actualOwners: Top contributors from git-blame -
driftScore: 0.0 (no drift) to 1.0 (complete drift) -
recommendation: Suggested action
Use cases:
- Audit CODEOWNERS accuracy
- Find stale ownership assignments
- Identify knowledge silos
Federation enables cross-repository queries and unified visibility. See Federation for full documentation.
List all available federations.
Budget: Cheap
{}Output:
-
federations: Array of federation names -
count: Total number of federations
Get detailed status of a federation including repos, compatibility, and sync state.
Budget: Cheap
{ "federation": "platform" }Output:
-
name: Federation name -
description: Federation description -
createdAt: Creation timestamp -
repoCount: Number of repos -
repos: Array of repo configs -
compatibility: Compatible vs incompatible repo counts
List repositories in a federation with paths, tags, and optional compatibility status.
Budget: Cheap
{ "federation": "platform", "includeCompatibility": true }Output:
-
repos: Array of repo configs with UUID, ID, path, tags -
count: Total repos -
compatibility: Optional schema compatibility checks
Search for modules across all repositories in a federation.
Budget: Heavy
{
"federation": "platform",
"query": "authentication",
"repos": ["api", "auth"],
"tags": ["security"],
"limit": 20
}Parameters:
-
federation: Federation name (required) -
query: FTS search query -
repos: Optional repo ID filter -
tags: Optional tag filter -
limit: Max results (default: 50)
Output:
-
modules: Array of module results with repoId, moduleId, name, responsibility, owner -
total: Result count -
staleness: Federation-wide staleness info
Search for ownership patterns across all repositories.
Budget: Heavy
{
"federation": "platform",
"path": "**/api/**",
"repos": ["api", "web"],
"limit": 50
}Parameters:
-
federation: Federation name (required) -
path: Glob pattern to match -
repos: Optional repo ID filter -
limit: Max results (default: 50)
Output:
-
matches: Array of ownership matches with pattern, owners, scope, source, confidence -
total: Result count -
staleness: Federation-wide staleness info
Get merged hotspots across all repositories in the federation.
Budget: Heavy
{
"federation": "platform",
"repos": ["api"],
"top": 20,
"minScore": 0.3
}Parameters:
-
federation: Federation name (required) -
repos: Optional repo ID filter -
top: Number of top hotspots (default: 20) -
minScore: Minimum score threshold (default: 0.3)
Output:
-
hotspots: Array of hotspots with repoId, targetId, score, churn, complexity, coupling -
total: Result count -
staleness: Federation-wide staleness info
Search for architectural decisions (ADRs) across all repositories.
Budget: Heavy
{
"federation": "platform",
"query": "database",
"status": ["accepted"],
"repos": ["api"],
"module": "persistence",
"limit": 50
}Parameters:
-
federation: Federation name (required) -
query: FTS search query -
status: Status filter (proposed, accepted, deprecated, superseded) -
repos: Optional repo ID filter -
module: Filter by affected module -
limit: Max results (default: 50)
Output:
-
decisions: Array of decisions with repoId, decisionId, title, status, affectedModules -
total: Result count -
staleness: Federation-wide staleness info
Sync federation index from repository data.
Budget: Heavy
{
"federation": "platform",
"force": true,
"dryRun": false,
"repos": ["api"]
}Parameters:
-
federation: Federation name (required) -
force: Force sync even if data is fresh -
dryRun: Preview what would be synced -
repos: Optional specific repos to sync (default: all)
Output:
-
results: Per-repo sync results with modulesSynced, ownershipSynced, hotspotsSynced, decisionsSynced -
summary: Overall success/failed/skipped counts
The daemon provides an always-on service for continuous code intelligence. See Daemon Mode for full documentation.
Get daemon health and statistics.
Budget: Cheap
{}Output:
-
running: Whether daemon is running -
pid: Process ID (when running) -
logFile: Path to log file -
dbFile: Path to database file -
pidFile: Path to PID file -
daemonDir: Daemon storage directory -
hint: Suggested CLI commands
List scheduled tasks with optional filtering.
Budget: Cheap
{ "taskType": "refresh", "enabled": true, "limit": 20 }Parameters:
-
taskType: Filter by task type (refresh, federation_sync, cleanup, health_check) -
enabled: Filter by enabled state -
limit: Max results (default: 20)
Output:
-
schedules: Array of schedule objects with id, taskType, target, schedule, enabled, nextRun, lastRun -
totalCount: Total number of schedules
Run a scheduled task immediately.
Budget: Cheap
{ "scheduleId": "schedule-abc123" }Output:
-
success: Whether the trigger succeeded -
scheduleId: The triggered schedule ID -
message: Status message
List configured webhooks.
Budget: Cheap
{}Output:
-
webhooks: Array of webhook summaries with id, url, events, enabled, deliveriesTotal, deliveriesSuccessful -
totalCount: Total number of webhooks
Send a test event to a webhook.
Budget: Cheap
{ "webhookId": "webhook-abc123" }Output:
-
success: Whether the test was queued -
webhookId: The tested webhook ID -
message: Status message
Get delivery history for a webhook.
Budget: Cheap
{ "webhookId": "webhook-abc123", "status": "failed", "limit": 20 }Parameters:
-
webhookId: Webhook ID (required) -
status: Filter by status (queued, pending, delivered, failed, dead) -
limit: Max results (default: 20)
Output:
-
deliveries: Array of delivery objects with id, eventType, status, attempts, lastAttemptAt, lastError -
totalCount: Total number of deliveries
Get code complexity metrics for a source file using tree-sitter parsing.
Budget: Cheap
{
"filePath": "internal/query/engine.go",
"includeFunctions": true,
"limit": 20,
"sortBy": "cyclomatic"
}Parameters:
-
filePath: Path to the source file (required) -
includeFunctions: Include per-function breakdown (default: true) -
limit: Maximum functions to return (default: 20) -
sortBy: Sort by "cyclomatic", "cognitive", or "lines" (default: "cyclomatic")
Output:
-
filePath: Analyzed file path -
language: Detected language -
aggregate:-
totalCyclomatic: Sum of all function cyclomatic complexity -
totalCognitive: Sum of all function cognitive complexity -
averageCyclomatic: Average per function -
averageCognitive: Average per function -
maxCyclomatic: Highest cyclomatic in file -
maxCognitive: Highest cognitive in file -
functionCount: Number of functions -
lineCount: Total lines
-
-
functions: Array of function metrics (sorted bysortBy)-
name: Function name -
line: Start line -
endLine: End line -
cyclomatic: Cyclomatic complexity -
cognitive: Cognitive complexity -
lines: Lines of code -
parameters: Parameter count
-
Supported Languages: Go, JavaScript, TypeScript, Python, Rust, Java, Kotlin
Complexity Types:
- Cyclomatic — Decision points count (if, for, while, switch, &&, ||)
- Cognitive — Nesting-weighted complexity for maintainability assessment
Integration: Complexity metrics feed into getHotspots risk scoring.
Contract analysis enables cross-repo intelligence through explicit API boundaries. See Federation for full documentation.
List API contracts (protobuf, OpenAPI) in a federation.
Budget: Cheap
{
"federation": "platform",
"repoId": "api",
"contractType": "proto",
"visibility": "public"
}Parameters:
-
federation: Federation name (required) -
repoId: Filter to contracts from this repo -
contractType: Filter by type (proto, openapi) -
visibility: Filter by visibility (public, internal, unknown)
Output:
-
contracts: Array of contracts with repoId, path, contractType, visibility, confidence -
totalCount: Total number of contracts
Analyze the impact of changing an API contract.
Budget: Heavy
{
"federation": "platform",
"repoId": "api",
"path": "proto/api/v1/user.proto",
"includeHeuristic": false,
"includeTransitive": true,
"maxDepth": 3
}Parameters:
-
federation: Federation name (required) -
repoId: Repository containing the contract (required) -
path: Path to the contract file (required) -
includeHeuristic: Include tier 3 edges (default: false) -
includeTransitive: Include transitive consumers (default: true) -
maxDepth: Max depth for transitive analysis (default: 3)
Output:
-
contract: Contract details (repoId, path, type, visibility) -
directConsumers: Repos that directly use this contract-
repoId,tier,evidenceType,confidence,consumerPaths
-
-
transitiveConsumers: Repos reached through imports-
repoId,viaContract,depth
-
-
summary:-
directRepoCount: Number of direct consumers -
transitiveRepoCount: Number of transitive consumers -
riskLevel: "low" | "medium" | "high" -
riskFactors: Array of risk reasons
-
-
ownership:-
approvalRequired: Owners who should approve changes
-
Risk Levels:
- Low: ≤2 direct consumers, internal visibility
- Medium: 3-5 direct consumers
- High: >5 direct consumers, public visibility, has services
Get contract dependencies for a repository.
Budget: Heavy
{
"federation": "platform",
"repoId": "api",
"direction": "both",
"includeHeuristic": false
}Parameters:
-
federation: Federation name (required) -
repoId: Repository to analyze (required) -
direction: "dependencies", "consumers", or "both" (default: "both") -
includeHeuristic: Include tier 3 edges (default: false)
Output:
-
dependencies: Contracts this repo depends on-
contract: Contract details -
tier: Evidence tier -
confidence: Confidence score
-
-
consumers: Repos consuming this repo's contracts-
contract: Contract details -
consumerRepo: Consumer details with tier and confidence
-
Suppress a false positive contract dependency edge.
Budget: Cheap
{
"federation": "platform",
"edgeId": 123,
"reason": "Not actually used - legacy import"
}Parameters:
-
federation: Federation name (required) -
edgeId: Edge ID to suppress (required) -
reason: Reason for suppression
Output:
-
success: Whether suppression succeeded -
edgeId: The suppressed edge ID
Verify a contract edge, increasing confidence.
Budget: Cheap
{
"federation": "platform",
"edgeId": 123
}Parameters:
-
federation: Federation name (required) -
edgeId: Edge ID to verify (required)
Output:
-
success: Whether verification succeeded -
edgeId: The verified edge ID
Get contract statistics for a federation.
Budget: Cheap
{
"federation": "platform"
}Parameters:
-
federation: Federation name (required)
Output:
-
totalContracts: Total number of contracts -
publicContracts: Public contracts count -
internalContracts: Internal contracts count -
byType: Breakdown by contract type (proto, openapi) -
totalEdges: Total dependency edges -
declaredEdges: Tier 1 edge count -
derivedEdges: Tier 2 edge count
Telemetry tools enable confident answers to "is this code actually used?" by integrating runtime observability data.
Get telemetry coverage metrics and sync status.
Budget: Cheap
{}Output:
-
enabled: Whether telemetry is enabled -
lastSync: Last successful sync timestamp -
coverage:-
attribute: % of events with file_path, namespace, line_number -
match: % of events matched to symbols (exact + strong) -
service: % of repos with telemetry data -
overall: Combined coverage score -
level: "high" (≥0.8), "medium" (≥0.6), "low" (≥0.4), "insufficient" (<0.4)
-
-
unmappedServices: Services that couldn't be mapped to repos -
warnings: Coverage warnings and recommendations
Get runtime observed usage for a symbol.
Budget: Cheap
{
"symbolId": "ckb:repo:sym:abc123",
"period": "90d",
"includeCallers": true
}Parameters:
-
symbolId: Symbol to query (required) -
period: Time period - "7d", "30d", "90d", or "all" (default: "90d") -
includeCallers: Include caller service breakdown (default: false)
Output:
-
symbolId: Queried symbol -
callCount: Total calls in period -
errorCount: Errors in period -
matchQuality: "exact" | "strong" | "weak" -
matchConfidence: Confidence score (0.60-0.95) -
trend: "increasing" | "stable" | "decreasing" -
callers: Caller breakdown (if includeCallers: true)-
service: Calling service name -
callCount: Calls from this service -
lastSeen: Last call timestamp
-
Match Quality Levels:
| Quality | Confidence | Criteria |
|---|---|---|
| Exact | 0.95 | file_path + function_name + line_number |
| Strong | 0.85 | file_path + function_name |
| Weak | 0.60 | namespace + function_name (no file) |
Find symbols that may be dead code based on observed runtime telemetry.
Budget: Heavy
{
"repoId": "my-repo",
"minConfidence": 0.7,
"limit": 100
}Parameters:
-
repoId: Repository to analyze (optional, defaults to current repo) -
minConfidence: Minimum confidence threshold 0-1 (default: 0.7) -
limit: Max candidates to return (default: 100)
Output:
-
candidates: Array of dead code candidates-
symbolId: Symbol identifier -
name: Symbol name -
filePath: File location -
staticRefs: Static reference count -
observedCalls: Runtime call count (always 0 for candidates) -
matchQuality: How symbol was matched -
confidence: Confidence score (capped at 0.90) -
reasons: Factors affecting confidence
-
-
summary:-
totalAnalyzed: Symbols analyzed -
candidateCount: Dead code candidates found -
coverageLevel: Telemetry coverage level -
observationDays: Days of telemetry data
-
-
coverage: Coverage details -
limitations: Analysis limitations
Confidence Factors:
- Base: exact (0.90), strong (0.80)
- Coverage adjustment: medium (-0.05), low (N/A - disabled)
- High static refs: -0.05
- Short observation: -0.10 (< 90 days)
- Sampling detected: -0.15
Requirements:
- Coverage level must be "medium" or higher
- Only exact/strong matches are considered
- Minimum observation period applies
Exclusions (configurable):
- Test files (
**/test/**) - Migrations (
**/migrations/**) - Functions matching patterns (
*Migration*,Test*,*Scheduled*)
The analyzeImpact tool now accepts an optional includeTelemetry parameter.
Additional Parameters:
-
includeTelemetry: Include observed callers in analysis (default: true) -
telemetryPeriod: Time period for telemetry data - "7d", "30d", "90d", or "all" (default: "90d")
Additional Output (when telemetry enabled and coverage is medium+):
-
observedImpact:-
observedCallers: Services that call this symbol-
service: Service name -
repoId: Mapped repository -
callCount: Call volume -
lastSeen: Last call timestamp
-
-
comparison:-
staticOnly: Consumers found only via static analysis -
observedOnly: Callers found only via telemetry -
both: Present in both static and observed
-
-
coverageContext: Coverage level and warnings
-
The getHotspots tool now includes observed usage data when telemetry is enabled.
Additional Output:
-
hotspots[].observedUsage(when telemetry enabled):-
callCount90d: Calls in last 90 days -
trend: "increasing" | "stable" | "decreasing" -
matchQuality: "exact" | "strong" | "weak" | "unmatched"
-
The hotspot scoring formula now includes a usage weight (0.20) when telemetry data is available.
Developer Intelligence tools help understand why code exists, not just what it does. They combine git history, co-change patterns, and multi-signal risk analysis.
Explain why code exists with full context: who wrote it, when, why, and what might be concerning.
Budget: Cheap
{
"symbol": "internal/query/engine.go:42",
"includeUsage": true,
"includeCoChange": true,
"historyLimit": 10
}Parameters:
-
symbol: File path, file:line, or symbol name (required) -
includeUsage: Include usage analysis (default: true) -
includeCoChange: Include co-change data (default: true) -
historyLimit: Max history entries (default: 10)
Output:
-
origin:-
commitSha: Introducing commit -
author: Original author -
date: Creation date -
commitMessage: Why it was added -
prNumber/issueNumber: Linked references
-
-
evolution:-
totalCommits: Times modified -
contributors: Unique contributors -
lastModified: Most recent change -
timeline: Significant changes
-
-
usage:-
staticRefs: Reference count -
observedCalls: Runtime calls (if telemetry enabled) -
importance: "low" | "medium" | "high" | "critical"
-
-
coChanges:- Array of files that frequently change together
-
file,correlation,coCommits
-
warnings:-
type: "temporary_code" | "bus_factor" | "high_coupling" | "stale" | "complex" -
message: Human-readable description -
severity: "info" | "warning" | "critical"
-
-
references:-
issues: Linked GitHub issues -
prs: Linked pull requests -
jiraTickets: Linked JIRA tickets
-
Warning Types:
| Type | Trigger |
|---|---|
temporary_code |
Contains TODO, FIXME, HACK, XXX |
bus_factor |
Only 1 contributor |
high_coupling |
≥5 files with correlation >0.7 |
stale |
Not touched in 12+ months |
complex |
Cyclomatic complexity >20 |
Find files and symbols that historically change together (temporal coupling).
Budget: Heavy
{
"target": "internal/query/engine.go",
"minCorrelation": 0.3,
"windowDays": 365,
"limit": 20
}Parameters:
-
target: File or symbol to analyze (required) -
minCorrelation: Minimum correlation threshold (default: 0.3) -
windowDays: Time window in days (default: 365) -
limit: Max results (default: 20)
Output:
-
target: Analyzed file/symbol -
coupledFiles: Array of coupled files-
file: File path -
correlation: Correlation score (0-1) -
coCommits: Number of commits together -
lastCoChange: Last time they changed together -
authors: Shared authors
-
-
summary:-
totalFiles: Files above threshold -
strongCoupling: Files with correlation >0.7 -
moderateCoupling: Files with 0.5-0.7 -
weakCoupling: Files with 0.3-0.5
-
-
insights:- Recommendations based on coupling patterns
- Example: "Consider extracting shared logic from X and Y"
Use Cases:
- Find hidden dependencies
- Identify refactoring targets
- Understand implicit contracts
- Plan code reviews (suggest reviewing coupled files)
Export codebase structure in LLM-friendly format with importance ranking.
Budget: Heavy
{
"includeUsage": true,
"includeOwnership": true,
"includeContracts": true,
"includeComplexity": true,
"minComplexity": 10,
"minCalls": 100,
"maxSymbols": 500
}Parameters:
-
includeUsage: Include call counts (default: true) -
includeOwnership: Include owners (default: true) -
includeContracts: Include contract info (default: true) -
includeComplexity: Include complexity metrics (default: true) -
minComplexity: Skip symbols below this complexity (default: 0) -
minCalls: Skip symbols below this call count (default: 0) -
maxSymbols: Maximum symbols to include (default: unlimited)
Output:
-
text: Formatted text output for LLM consumption -
metadata:-
repo: Repository name -
generated: Generation timestamp -
symbolCount: Total symbols exported -
fileCount: Total files -
moduleCount: Total modules
-
Text Format:
# Codebase: my-project
# Generated: 2025-12-18T10:00:00Z
# Symbols: 150 | Files: 45 | Modules: 8
## internal/api/ (owner: @api-team)
! handler.go
$ Server c=5 calls=10k/day ★★★
# HandleRequest() c=12 calls=8k/day ★★★
# ValidateInput() c=8 calls=8k/day ★★
! middleware.go
# AuthMiddleware() c=15 calls=10k/day ★★★ contract:auth.proto
---
Legend:
! = file
$ = class/struct
# = function/method
c = complexity (cyclomatic)
★ = importance (usage × complexity)
contract: = exposes or consumes a contract
Importance Ranking:
| Level | Stars | Criteria |
|---|---|---|
| Critical | ★★★ | High usage + high complexity |
| High | ★★ | High usage OR high complexity |
| Medium | ★ | Moderate usage and complexity |
| Low | (none) | Low usage and complexity |
Find risky code based on multiple weighted signals.
Budget: Heavy
{
"minScore": 40,
"limit": 50,
"factor": "complexity",
"quickWins": false
}Parameters:
-
minScore: Minimum risk score to include (default: 40) -
limit: Max results (default: 50) -
factor: Focus on specific factor (optional) -
quickWins: Return only high-impact, low-effort targets (default: false)
Output:
-
risks: Array of risky items-
target: File or symbol path -
score: Risk score (0-100) -
factors: Individual factor scores-
complexity: 0-100 (weight: 20%) -
testCoverage: 0-100 inverted (weight: 20%) -
busFactor: 0-100 (weight: 15%) -
securitySensitive: 0-100 (weight: 15%) -
staleness: 0-100 (weight: 10%) -
errorRate: 0-100 (weight: 10%) -
coupling: 0-100 (weight: 5%) -
churn: 0-100 (weight: 5%)
-
-
topFactors: Top 3 contributing factors -
suggestions: Remediation suggestions
-
-
summary:-
totalAnalyzed: Files/symbols analyzed -
highRisk: Count with score ≥70 -
mediumRisk: Count with score 40-70 -
factorDistribution: Breakdown by dominant factor
-
-
quickWins: (whenquickWins: true)- Items with high risk but low effort to fix
- Ranked by impact/effort ratio
Risk Factor Weights:
| Factor | Weight | Description |
|---|---|---|
| Complexity | 20% | Cyclomatic/cognitive complexity |
| Test Coverage | 20% | Lack of test coverage |
| Bus Factor | 15% | Single-author code |
| Security | 15% | Handles auth, crypto, PII |
| Staleness | 10% | Not touched in 6+ months |
| Error Rate | 10% | Runtime error frequency |
| Coupling | 5% | High co-change coupling |
| Churn | 5% | Frequent modifications |
Quick Wins Criteria:
- High risk score (≥60)
- Low complexity (easy to fix)
- High usage (high impact)
- Clear owner (someone to assign)
Doc-symbol linking bridges documentation and code by automatically detecting symbol references in markdown files.
Scan and index documentation for symbol references.
Budget: Heavy
{
"force": false
}Parameters:
-
force: Re-index all docs even if unchanged (default: false)
Output:
-
indexed: Number of documents indexed -
references: Total symbol references found -
resolved: References successfully resolved to symbols -
duration: Indexing duration
Find documentation that references a symbol.
Budget: Cheap
{
"symbol": "Engine.Start",
"limit": 10
}Parameters:
-
symbol: Symbol name or ID to search for (required) -
limit: Max results (default: 10)
Output:
-
docs: Array of documents referencing the symbol-
path: Document path -
line: Line number of reference -
context: Surrounding text -
detection: How it was detected (backtick, directive, fence) -
confidence: Resolution confidence
-
List all symbol references found in a documentation file.
Budget: Cheap
{
"path": "README.md"
}Parameters:
-
path: Path to the documentation file (required)
Output:
-
symbols: Array of symbol references-
rawText: Original text in document -
line: Line number -
symbolId: Resolved symbol ID (if resolved) -
status: "exact" | "suffix" | "ambiguous" | "missing" -
confidence: Resolution confidence -
detection: Detection method
-
Find documents linked to a module via <!-- ckb:module --> directives.
Budget: Cheap
{
"moduleId": "internal/query"
}Parameters:
-
moduleId: Module ID (directory path) to find docs for (required)
Output:
-
docs: Array of documents linked to the module-
path: Document path -
line: Line number of directive
-
Check documentation for stale symbol references.
Budget: Heavy
{
"path": "README.md"
}Or check all documents:
{
"all": true
}Parameters:
-
path: Path to check (optional) -
all: Check all indexed documentation (default: false)
Output:
-
reports: Array of staleness reports-
docPath: Document path -
stale: Array of stale references-
rawText: Original text in document -
line: Line number -
reason: "missing_symbol" | "ambiguous_symbol" | "index_incomplete" | "symbol_renamed" -
message: Human-readable description -
suggestions: Alternative symbol names (for ambiguous) -
newSymbolId: New symbol ID (for renamed symbols)
-
-
-
totalStale: Total stale references count
Staleness Reasons:
| Reason | Description |
|---|---|
missing_symbol |
Symbol no longer exists in codebase |
ambiguous_symbol |
Reference matches multiple symbols |
index_incomplete |
Language not indexed at current tier |
symbol_renamed |
Symbol was renamed (alias chain detected) |
Get documentation coverage statistics.
Budget: Heavy
{
"exportedOnly": false,
"topN": 10
}Parameters:
-
exportedOnly: Only count exported/public symbols (default: false) -
topN: Number of top undocumented symbols to return (default: 10)
Output:
-
coverage:-
totalSymbols: Total symbols in codebase -
documentedSymbols: Symbols with at least one doc reference -
percentage: Coverage percentage (0-100)
-
-
topUndocumented: Most important undocumented symbols-
symbolId: Symbol identifier -
name: Symbol name -
kind: Symbol kind (function, class, etc.) -
centrality: Importance score based on references
-
-
byModule: Coverage breakdown by module
CI Integration:
# Fail if coverage drops below threshold
ckb docs coverage --fail-under=80Exit codes:
-
0: Coverage meets threshold -
1: Coverage below threshold
Remote federation enables querying remote CKB index servers alongside local repositories. This transforms federation from local-only aggregation to a distributed code intelligence network.
Add a remote CKB index server to a federation.
Budget: Cheap
{
"federation": "platform",
"name": "prod",
"url": "https://ckb.company.com",
"token": "${CKB_PROD_TOKEN}",
"cacheTtl": "1h",
"timeout": "30s"
}Parameters:
-
federation: Federation name (required) -
name: Unique server name (required) -
url: Server URL - https:// or http:// (required) -
token: Auth token - supports${VAR}expansion (optional) -
cacheTtl: Cache TTL duration (default: "1h") -
timeout: Request timeout (default: "30s")
Output:
-
name: Server name -
url: Server URL -
cacheTtl: Cache TTL -
timeout: Request timeout -
enabled: Whether server is enabled -
message: Success message
Remove a remote server from a federation.
Budget: Cheap
{
"federation": "platform",
"name": "staging"
}Parameters:
-
federation: Federation name (required) -
name: Server name to remove (required)
Output:
-
name: Removed server name -
message: Success message
List remote servers in a federation.
Budget: Cheap
{
"federation": "platform"
}Parameters:
-
federation: Federation name (required)
Output:
-
servers: Array of server configs-
name: Server name -
url: Server URL -
cacheTtl: Cache TTL -
timeout: Request timeout -
enabled: Whether server is enabled -
addedAt: When server was added -
lastSyncedAt: Last successful sync -
lastError: Last error message
-
-
count: Total server count
Sync metadata from remote server(s).
Budget: Heavy
{
"federation": "platform",
"name": "prod"
}Or sync all servers:
{
"federation": "platform"
}Parameters:
-
federation: Federation name (required) -
name: Specific server to sync (optional - syncs all if omitted)
Output (specific server):
-
server: Server name -
repoCount: Number of repos synced -
message: Success message
Output (all servers):
-
total: Total servers -
success: Successful syncs -
failed: Failed syncs -
errors: Array of error details -
message: Summary message
Get status of a remote server including connectivity check.
Budget: Cheap
{
"federation": "platform",
"name": "prod"
}Parameters:
-
federation: Federation name (required) -
name: Server name (required)
Output:
-
name: Server name -
url: Server URL -
enabled: Whether server is enabled -
online: Whether server is reachable -
latency: Response latency -
pingError: Error message if offline -
lastSyncedAt: Last successful sync -
lastError: Last error message -
cachedRepoCount: Number of cached repos
Search symbols across local federation repositories AND remote servers.
Budget: Heavy
{
"federation": "platform",
"query": "Handler",
"limit": 100,
"language": "go",
"kind": "function",
"servers": ["prod", "staging"]
}Parameters:
-
federation: Federation name (required) -
query: Search query (required) -
limit: Max results (default: 100) -
language: Filter by language (optional) -
kind: Filter by symbol kind (optional) -
servers: Specific remote servers to query (optional - queries all if omitted)
Output:
-
results: Array of symbol results-
symbol: Symbol details -
source: "local" or remote server name -
repoId: Repository ID -
serverUrl: Server URL (empty for local)
-
-
sources: Which servers responded-
name: Source name -
latency: Response time -
resultCount: Results from this source
-
-
errors: Which servers failed-
source: Server name -
message: Error message
-
-
totalResults: Total result count -
truncated: Whether results were truncated
Source Attribution:
Results include source attribution showing where each result came from:
-
"local"- From local federation repositories - Server name (e.g.,
"prod") - From remote server
List repositories from both local federation and remote servers.
Budget: Cheap
{
"federation": "platform"
}Parameters:
-
federation: Federation name (required)
Output:
-
local: Local repository info-
repos: Array of local repos -
count: Local repo count
-
-
remote: Remote repository info-
servers: Array of server details-
name: Server name -
repos: Array of remote repos -
count: Repo count for this server
-
-
totalCount: Total remote repos
-
-
totalCount: Grand total (local + remote)
Add and sync a remote server:
federationAddRemote({ federation: "platform", name: "prod", url: "..." })
→ federationSyncRemote({ federation: "platform", name: "prod" })
→ federationSearchSymbolsHybrid({ federation: "platform", query: "..." })
Monitor remote server health:
federationListRemote({ federation: "platform" })
→ federationStatusRemote({ federation: "platform", name: "prod" })
Cross-organization code search:
federationSearchSymbolsHybrid({ federation: "org", query: "Auth", servers: ["team-a", "team-b"] })
Multi-repo management enables quick context switching between multiple repositories in MCP sessions. Unlike federation (which queries across repos), this feature lets you focus on one repo at a time with easy switching.
List all registered repositories with their state and active status.
Budget: Cheap
{}Output:
-
repos: Array of registered repositories-
name: Repository alias -
path: Absolute filesystem path -
state: Current state (valid,uninitialized,missing) -
active: Whether this is the currently active repo -
default: Whether this is the default repo -
loaded: Whether engine is currently loaded in memory -
addedAt: When repo was registered -
lastUsedAt: When repo was last accessed
-
-
count: Total number of registered repos -
activeRepo: Name of currently active repo (if any)
States:
-
valid: Path exists and.ckb/is initialized -
uninitialized: Path exists but.ckb/is missing -
missing: Path no longer exists
Switch to a different repository by name.
Budget: Cheap
{
"name": "myproject"
}Parameters:
-
name: Name of the registered repository to switch to (required)
Output:
-
success: Whether switch succeeded -
name: Repository name -
path: Repository path -
state: Repository state -
activeRepo: Current active repo name
Errors:
- Repo not found in registry
- Path does not exist (
missingstate) - Repo not initialized (
uninitializedstate) — returns actionable fix
Engine Lifecycle:
- Max 5 engines in memory at once
- LRU eviction when switching to a 6th repo
- Active repo is never evicted
- Each engine loads its own
.ckb/config.json
Get information about the currently active repository.
Budget: Cheap
{}Output (active repo):
-
name: Repository name -
path: Repository path -
state: Current state
Output (no active repo):
-
name: null -
state: "none" -
error: Actionable message
Legacy mode (single-repo):
-
mode: "legacy" -
path: Repository path -
state: "valid"
Setup and switch:
# CLI: Register repos
ckb repo add frontend /path/to/frontend
ckb repo add backend /path/to/backend
ckb repo default frontend
# MCP: Switch context
listRepos()
→ switchRepo({ name: "backend" })
→ searchSymbols({ query: "Auth" })Start MCP with specific repo:
ckb mcp --repo backendScripting:
# Get current repo name
REPO=$(ckb repo which | cut -f1)
# Check all repos are valid
ckb repo check --json | jq '.missing'searchSymbols, getSymbol, findReferences, explainSymbol, justifySymbol, getCallGraph, getModuleOverview, analyzeImpact, getStatus, doctor
All v5.2 tools are now implemented:
Phase 1: explainFile, traceUsage, listEntrypoints
Phase 2: summarizeDiff
Phase 3: getHotspots, getArchitecture
Phase 4: explainPath, listKeyConcepts, recentlyRelevant
All v6.0 tools are implemented:
Phase 1: getArchitecture (enhanced), refreshArchitecture
Phase 2: getOwnership
Phase 3: getHotspots (enhanced with trends), getModuleResponsibilities
Phase 4: recordDecision, getDecisions, annotateModule
All v6.1 tools are implemented:
Background Jobs: getJobStatus, listJobs, cancelJob
Async Operations: refreshArchitecture now supports async: true mode
CI/CD Integration: summarizePr, getOwnershipDrift
All v6.2 tools are implemented:
Federation Management: listFederations, federationStatus, federationRepos, federationSync
Cross-Repo Queries: federationSearchModules, federationSearchOwnership, federationGetHotspots, federationSearchDecisions
All v6.2.1 tools are implemented:
Daemon Status: daemonStatus
Scheduler: listSchedules, runSchedule
Webhooks: listWebhooks, testWebhook, webhookDeliveries
Language-agnostic complexity metrics via getFileComplexity tool:
Supported Languages: Go, JavaScript, TypeScript (+ TSX), Python, Rust, Java, Kotlin
Metrics:
- Cyclomatic complexity — decision points analysis
- Cognitive complexity — nesting-weighted for maintainability
Integration: Complexity feeds into getHotspots risk scores
All v6.3 tools are implemented:
Contract Detection: listContracts
Impact Analysis: analyzeContractImpact, getContractDependencies
Edge Management: suppressContractEdge, verifyContractEdge
Statistics: getContractStats
All v6.4 tools are implemented:
Telemetry Status: getTelemetryStatus
Usage Display: getObservedUsage
Dead Code Detection: findDeadCodeCandidates
Enhanced Tools:
-
analyzeImpact- Now includesincludeTelemetryparameter for observed callers -
getHotspots- Now includesobservedUsagefield when telemetry is enabled
All v6.5 tools are implemented:
Symbol Explanation: explainOrigin
Co-Change Analysis: analyzeCoupling
LLM Export: exportForLLM
Risk Audit: auditRisk
Annotation Integration: ADRs and module annotations are now wired into core tools:
-
explainSymbol- Now includesannotationsfield with related ADRs and module metadata -
justifySymbol- Verdict considers ADRs; returns "investigate" instead of "remove-candidate" when an accepted/proposed ADR exists for the module -
analyzeImpact- Now includesrelatedDecisionsfield showing ADRs affecting impacted modules -
getModuleOverview- Now includesannotationsandrelatedDecisionsfields -
getModuleResponsibilities- Declared annotations now override inferred responsibilities with higher confidence
All v7.3 tools are implemented:
Documentation Indexing: indexDocs
Symbol Queries: getDocsForSymbol, getSymbolsInDoc, getDocsForModule
Staleness Detection: checkDocStaleness
Coverage Analysis: getDocCoverage
Features:
- Backtick detection - Automatically detect
Symbol.Namereferences in markdown - Directive support -
<!-- ckb:symbol -->for explicit references,<!-- ckb:module -->for module linking - Fence scanning - Extract symbols from fenced code blocks (8 languages via tree-sitter)
- Staleness detection - Find broken references when symbols are renamed or deleted
- Rename awareness - Suggest new names when documented symbols are renamed via alias chain
- CI enforcement -
--fail-underflag for documentation coverage thresholds - known_symbols directive - Allow single-segment symbol detection
All v7.3 tools are implemented:
Server Management: federationAddRemote, federationRemoveRemote, federationListRemote
Synchronization: federationSyncRemote
Status & Health: federationStatusRemote
Hybrid Queries: federationSearchSymbolsHybrid, federationListAllRepos
Features:
- Remote server connections with Bearer token auth
- Environment variable expansion for tokens (
${VAR}syntax) - Configurable cache TTL and request timeout per server
- Hybrid local+remote queries with source attribution
- Graceful degradation when remotes unavailable
- Exponential backoff retry logic (max 3 retries)
- SQLite caching layer for remote metadata
All v7.3 multi-repo tools are implemented:
Registry Management: listRepos, getActiveRepo
Context Switching: switchRepo
Features:
- Global repository registry at
~/.ckb/repos.json - Named shortcuts for quick context switching in MCP sessions
- Multi-engine support (up to 5 engines in memory with LRU eviction)
- Per-repo configuration loading from each repo's
.ckb/config.json - Repo state tracking:
valid,uninitialized,missing -
--repoflag forckb mcpandckb serveto start with specific repo - Graceful engine lifecycle with in-flight operation tracking
CLI Commands:
-
ckb repo add [name] [path]- Register a repository -
ckb repo list- List repos grouped by state -
ckb repo remove <name>- Unregister a repo -
ckb repo default [name]- Get or set default repo -
ckb repo which- Print current repo (for scripts) -
ckb repo check- Validate all registered repos
All 74 MCP tool responses now include structured metadata:
Envelope Features:
- Schema version for forward compatibility
- Confidence scoring with tiers (high/medium/low/speculative)
- Provenance tracking (which backends contributed)
- Freshness metadata (index staleness)
- Truncation awareness (shown vs total counts)
- Structured suggested next calls
Files Added:
-
internal/envelope/envelope.go— Core types and builder -
internal/mcp/tool_helpers.go— MCP-specific response helpers
Total: 76 MCP tools available
Good news: As of CKB 7.3, this is handled automatically. The Node.js shim now detects your repo root and sets
CKB_REPOfor you.
Background: When npx runs CKB, it executes from a sandboxed temp directory (like ~/.npm/_npx/...), not your project directory. CKB needs to find .ckb/ in the project root.
How CKB 7.3+ fixes this:
The npm package includes a shim that walks up from process.cwd() looking for .ckb/ or .git/ and automatically sets CKB_REPO. This means simple configs now work:
{
"command": "npx",
"args": ["@tastehub/ckb", "mcp"]
}If auto-detection fails (rare edge cases), you can still set CKB_REPO explicitly:
{
"command": "npx",
"args": ["-y", "@tastehub/ckb", "mcp"],
"env": {
"CKB_REPO": "/path/to/your/repo"
}
}| Tool | Notes |
|---|---|
| Claude Code | Works out of the box with npx |
| Cursor | Works out of the box; global config auto-detects repo |
| Windsurf | Global-only; auto-detection works in most cases |
| VS Code | Works out of the box with npx |
| OpenCode | Works out of the box with npx |
| Claude Desktop | Auto-detection works if launched from a repo directory |
Limitation: With auto-detected or explicit CKB_REPO, CKB works with one repository at a time. To switch repos, update the config or use project-scoped configuration.
If you use NVM, asdf, or other Node version managers, npx may not work correctly because these tools rely on shell initialization that MCP clients don't run.
Symptoms:
- "command not found: npx"
- Server starts but uses wrong Node version
- Intermittent failures
Solution: Use absolute paths instead of npx:
{
"mcpServers": {
"ckb": {
"command": "/Users/you/.nvm/versions/node/v22.11.0/bin/node",
"args": [
"/Users/you/.nvm/versions/node/v22.11.0/lib/node_modules/@tastehub/ckb/bin/ckb.js",
"mcp"
]
}
}
}Find your paths:
# Find node path
which node
# Find global package location
npm root -gAlternative: Install CKB globally with the system Node (not NVM):
/usr/local/bin/npm install -g @tastehub/ckbMCP clients typically only pass PATH to servers. Other environment variables like $HOME are NOT automatically available.
What works:
-
PATH(usually) - Variables explicitly listed in
envconfig
What doesn't work:
-
$HOME,$USER, custom variables - Variable substitution (
${VAR}) in config files - Shell expansion
If CKB needs specific variables, add them explicitly:
{
"env": {
"HOME": "/Users/you",
"CKB_REPO": "/path/to/repo"
}
}Process orphaning: Cursor doesn't always terminate MCP servers when closing. You may need to manually kill orphaned processes:
pkill -f "ckb mcp"Sandbox environment: When using npx, Cursor runs servers in a sandboxed temp directory. Use CKB_REPO or project-scoped config.
Logging disabled: Cursor breaks MCP logging connections. Debug by writing to a file instead:
ckb mcp 2>/tmp/ckb-debug.logConfig location varies:
- Official:
~/.codeium/windsurf/mcp_config.json - Legacy:
~/.codeium/mcp_config.json
CKB's setup command probes both locations and uses whichever exists.
Global-only: Windsurf only supports global MCP configuration, not per-project. Consider using CKB_REPO if you work with multiple repositories.
# Check if ckb is available
npx @tastehub/ckb version
# Test MCP server manually
echo '{"jsonrpc":"2.0","id":1,"method":"initialize"}' | npx @tastehub/ckb mcp
# If using NVM, check with absolute path
/path/to/node /path/to/ckb mcp --helpCommon causes:
-
Wrong working directory — CKB can't find
.ckb/database# Fix: Add CKB_REPO to config "env": { "CKB_REPO": "/path/to/your/repo" }
-
npx not found (NVM/asdf users)
# Fix: Use absolute paths instead of npx -
Non-JSON output to stdout — Check for rogue print statements
# Test: Should output only JSON echo '{}' | ckb mcp 2>/dev/null
# Check CKB is initialized
ls -la .ckb/
# Initialize if missing
ckb init
# Check status
ckb status# Regenerate SCIP index
ckb index
# Check for issues
ckb doctor
# Force refresh architecture
ckb refresh --force# macOS: Watch MCP logs (Claude Desktop)
tail -f ~/Library/Logs/Claude/mcp*.log
# Write debug output to file
CKB_REPO=/path/to/repo ckb mcp 2>/tmp/ckb-mcp.log