Skip to content

MCP Integration

Lisa edited this page Dec 20, 2025 · 43 revisions

CKB MCP Integration Guide (v7.0)

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.

Quick Setup

CKB works with any MCP-compatible AI coding tool.

Claude Code (Recommended)

# 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 list

Or with npx (no install):

npx @tastehub/ckb setup

Manual configuration — add to .mcp.json in project root:

{
  "mcpServers": {
    "ckb": {
      "command": "npx",
      "args": ["@tastehub/ckb", "mcp"]
    }
  }
}

Cursor

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.


Windsurf

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.


VS Code

Add to your VS Code settings.json:

{
  "mcp": {
    "servers": {
      "ckb": {
        "type": "stdio",
        "command": "npx",
        "args": ["@tastehub/ckb", "mcp"]
      }
    }
  }
}

OpenCode

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

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "ckb": {
      "command": "npx",
      "args": ["@tastehub/ckb", "mcp"],
      "cwd": "/path/to/your/repo"
    }
  }
}

Note: Claude Desktop requires cwd since it's a global app without a project context.


Windows

On Windows, wrap the command with cmd /c in any of the configs above:

{
  "mcpServers": {
    "ckb": {
      "command": "cmd",
      "args": ["/c", "npx", "@tastehub/ckb", "mcp"]
    }
  }
}

Using a Local Binary

If you built from source or installed globally, use the binary directly:

{
  "mcpServers": {
    "ckb": {
      "command": "ckb",
      "args": ["mcp"]
    }
  }
}

Platform Contracts

Backend Budget Classification

Tools are classified by performance budget.

Cheap Tools (P95 < 300ms)

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

  • Max 1 hop traversal
  • Max 50 results
  • No callgraph expansion or deep git history

Heavy Tools (P95 < 2000ms)

traceUsage · getArchitecture · getHotspots · summarizeDiff · recentlyRelevant · listKeyConcepts · analyzeImpact · getCallGraph · findReferences · justifySymbol · federationSearchModules · federationSearchOwnership · federationGetHotspots · federationSearchDecisions · federationSync · analyzeContractImpact · getContractDependencies · findDeadCodeCandidates · analyzeCoupling · exportForLLM · auditRisk

  • Up to depth 5 traversal
  • Up to 1000 git commits
  • Must include limitations field

Heavy Tools (P95 < 30000ms)

refreshArchitecture · summarizePr · getOwnershipDrift

  • refreshArchitecture: Supports async mode (v6.1) — returns jobId for polling
  • summarizePr: Analyze PR changes, suggest reviewers, assess risk
  • getOwnershipDrift: Compare CODEOWNERS vs actual git-blame ownership

Confidence Rules

Condition Max confidence
Full static analysis (SCIP/LSP) 1.0
Partial static analysis 0.89
Heuristics only 0.79
Key backend missing 0.69
Multiple backends missing 0.39

Time Window Defaults

Tool Default
getHotspots 30 days
summarizeDiff 30 days
recentlyRelevant 7 days

Tools Overview

Discovery & Search

Tool Budget Purpose Status
searchSymbols Cheap Search with filtering v5.1 ✓
getSymbol Cheap Get symbol details v5.1 ✓

Flow & Runtime

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 ✓

File Navigation

Tool Budget Purpose Status
explainFile Cheap File orientation v5.2 ✓
explainPath Cheap Path role explanation v5.2 ✓

Change Awareness

Tool Budget Purpose Status
summarizeDiff Heavy What changed? v5.2 ✓

System Orientation

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 ✓

Symbol Analysis

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 ✓

Ownership (v6.0)

Tool Budget Purpose Status
getOwnership Cheap Who owns this code? v6.0 ✓

Architectural Decisions (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 ✓

System

Tool Budget Purpose Status
getStatus Cheap System health v5.1 ✓
doctor Cheap Diagnostics v5.1 ✓

Background Jobs (v6.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 ✓

CI/CD Integration (v6.1)

Tool Budget Purpose Status
summarizePr Heavy PR risk analysis & reviewers v6.1 ✓
getOwnershipDrift Heavy CODEOWNERS vs actual ownership v6.1 ✓

Daemon Mode (v6.2.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 ✓

Tree-sitter Complexity (v6.2.2)

Tool Budget Purpose Status
getFileComplexity Cheap Cyclomatic/cognitive complexity metrics v6.2.2 ✓

Contract Analysis (v6.3)

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 ✓

Runtime Telemetry (v6.4)

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 ✓

Developer Intelligence (v6.5)

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 ✓

v5.2 New Tools

traceUsage

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.


listEntrypoints

List system entrypoints.

Budget: Cheap

{ "types": ["api", "cli"], "limit": 30 }

Entrypoint types: api | cli | job | event

Detection basis: naming | framework-config | static-call


explainFile

File-level orientation.

Budget: Cheap

{ "filePath": "internal/query/engine.go" }

Output: File role, top symbols (max 15), imports/exports, local hotspots.


explainPath

Why does this path exist?

Budget: Cheap

{ "filePath": "internal/legacy/handler.go", "contextHint": "from traceUsage" }

Role classifications: core | glue | legacy | test-only | config | unknown


summarizeDiff

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.


getArchitecture

Conservative architectural overview.

Budget: Heavy

{ "depth": 2, "includeExternalDeps": false }

Hard caps: 15–20 modules, 50 edges max.


getHotspots

Highlight volatile areas.

Budget: Heavy

{ "timeWindow": { "days": 30 }, "scope": "internal/query", "limit": 20 }

Ranking signals: churn, coupling, recency


listKeyConcepts

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

recentlyRelevant

What should I care about now?

Budget: Heavy

{ "timeWindow": { "days": 7 }, "moduleFilter": "internal/api" }

Ranking signals: churn, fanIn, hasOpenChanges


v5.1 Implemented Tools

searchSymbols

{ "query": "Handler", "kinds": ["function"], "scope": "internal/api", "limit": 50 }

getSymbol

{ "symbolId": "...", "repoStateMode": "head" }

findReferences

{ "symbolId": "...", "scope": "internal/mcp", "includeTests": true, "limit": 100 }

explainSymbol

{ "symbolId": "..." }

Output: Name, kind, signature, usage stats, git history, related symbols, and (v6.5) annotations containing related ADRs and module metadata.

justifySymbol

{ "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".

getCallGraph

{ "symbolId": "...", "direction": "both", "depth": 2 }

getModuleOverview

{ "path": "internal/query" }

v6.5: Now includes annotations (responsibility, capabilities, tags, boundaries) and relatedDecisions (ADRs affecting this module).

analyzeImpact

{ "symbolId": "...", "depth": 3, "includeTelemetry": true }

v6.5: Now includes relatedDecisions showing ADRs that affect any of the impacted modules.

getStatus

{}

doctor

{}

Navigation Presets

Preset Focus
onboarding Broad, concept-first
bug-investigation Trace-focused, recent changes
refactor-safety Coupling and hotspots
review Diff-centric, risk signals

Recommended Workflows

New Codebase

getStatus() → listKeyConcepts() → getArchitecture() → listEntrypoints() → searchSymbols()

Bug Investigation

searchSymbols() → traceUsage() → getCallGraph() → recentlyRelevant()

Before Changes

searchSymbols() → explainSymbol() → findReferences() → analyzeImpact() → getHotspots()

Code Review

summarizeDiff() → getHotspots() → getOwnership() → traceUsage()

Dead Code

searchSymbols() → justifySymbol() → explainFile()

Understanding Module Ownership (v6.0)

getArchitecture() → getOwnership() → getModuleResponsibilities()

Recording Design Decisions (v6.0)

getDecisions() → recordDecision() → annotateModule()

Annotation-Aware Dead Code Detection (v6.5)

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.

Annotation-Aware Impact Analysis (v6.5)

analyzeImpact() → [check relatedDecisions] → getDecisions()

When analyzeImpact shows relatedDecisions, read them before making changes to understand the architectural context.

Risk Assessment (v6.0)

getHotspots() → getOwnership() → summarizeDiff()

CI/CD Integration (v6.1)

summarizePr() → getOwnershipDrift() → getHotspots()

Background Refresh (v6.1)

refreshArchitecture({ async: true }) → getJobStatus() → [poll until complete]

Cross-Repo Analysis (v6.2)

listFederations() → federationStatus() → federationSearchModules() → federationGetHotspots()

Organization-Wide Review (v6.2)

federationSearchOwnership() → federationSearchDecisions() → federationSync()

Daemon Monitoring (v6.2.1)

daemonStatus() → listSchedules() → listWebhooks() → webhookDeliveries()

Scheduled Automation (v6.2.1)

listSchedules() → runSchedule() → listJobs() → getJobStatus()

Contract Impact Analysis (v6.3)

listContracts() → analyzeContractImpact() → getContractDependencies() → getContractStats()

Before Changing Shared API (v6.3)

listContracts() → analyzeContractImpact() → [contact owners] → federationSync()

Dead Code Detection (v6.4)

getTelemetryStatus() → [verify coverage is medium+] → findDeadCodeCandidates() → justifySymbol()

Understanding Actual Usage (v6.4)

searchSymbols() → getObservedUsage() → analyzeImpact({ includeTelemetry: true })

Understand Why Code Exists (v6.5)

searchSymbols() → explainOrigin() → analyzeCoupling() → auditRisk()

Find Co-Change Patterns (v6.5)

analyzeCoupling() → getHotspots() → getOwnership()

LLM Context Generation (v6.5)

exportForLLM() → [paste to LLM for codebase understanding]

Risk Audit & Quick Wins (v6.5)

auditRisk() → auditRisk({ quickWins: true }) → explainOrigin()

Error Codes

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

What CKB Does NOT Do

  • ❌ Code mutation/refactoring
  • ❌ Test generation
  • ❌ Fix suggestions
  • ❌ Policy enforcement
  • ❌ Lint judgments

Navigation and comprehension only.


v6.0 Architectural Memory Tools

getOwnership

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 (if includeHistory: true)

Sources: CODEOWNERS file (confidence: 1.0), git blame (confidence: 0.79)


getModuleResponsibilities

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 (if includeSymbols: true)
  • confidence: How certain we are
  • source: "declared" | "inferred" | "llm-generated"

recordDecision

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:

  • explainSymbolannotations.relatedDecisions for symbols in affected modules
  • justifySymbol → Influences verdict (prevents "remove-candidate" for intentional code)
  • analyzeImpactrelatedDecisions when impacting modules with ADRs
  • getModuleOverviewrelatedDecisions for the module

getDecisions

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
}

annotateModule

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:

  • explainSymbolannotations.moduleAnnotations with responsibility, capabilities, tags
  • getModuleOverviewannotations field with full module metadata
  • getModuleResponsibilities → Declared annotations override inferred ones with higher confidence

refreshArchitecture

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

Enhanced getHotspots (v6.0)

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
    }
  }]
}

v6.1 New Tools

getJobStatus

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)

listJobs

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)

cancelJob

Cancel a queued or running job.

Budget: Cheap

{ "jobId": "job-abc123" }

Output:

  • cancelled: true if job was cancelled
  • status: Final job status

refreshArchitecture (Enhanced in v6.1)

Now supports async mode for long-running operations.

Budget: Heavy (sync) / Cheap (async)

{ "scope": "all", "force": true, "async": true }

New async fields:

  • async: Set to true to run in background
  • Response includes jobId when async

Usage pattern:

1. refreshArchitecture({ async: true }) → { jobId: "..." }
2. getJobStatus({ jobId }) → { status: "running", progress: 50 }
3. getJobStatus({ jobId }) → { status: "completed", result: {...} }

summarizePr

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 head

Output:

  • 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

getOwnershipDrift

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

v6.2 Federation Tools

Federation enables cross-repository queries and unified visibility. See Federation for full documentation.

listFederations

List all available federations.

Budget: Cheap

{}

Output:

  • federations: Array of federation names
  • count: Total number of federations

federationStatus

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

federationRepos

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

federationSearchModules

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

federationSearchOwnership

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

federationGetHotspots

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

federationSearchDecisions

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

federationSync

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

v6.2.1 Daemon Mode Tools

The daemon provides an always-on service for continuous code intelligence. See Daemon Mode for full documentation.

daemonStatus

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

listSchedules

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

runSchedule

Run a scheduled task immediately.

Budget: Cheap

{ "scheduleId": "schedule-abc123" }

Output:

  • success: Whether the trigger succeeded
  • scheduleId: The triggered schedule ID
  • message: Status message

listWebhooks

List configured webhooks.

Budget: Cheap

{}

Output:

  • webhooks: Array of webhook summaries with id, url, events, enabled, deliveriesTotal, deliveriesSuccessful
  • totalCount: Total number of webhooks

testWebhook

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

webhookDeliveries

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

v6.2.2 Tree-sitter Complexity Tool

getFileComplexity

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 by sortBy)
    • 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.


v6.3 Contract-Aware Impact Analysis Tools

Contract analysis enables cross-repo intelligence through explicit API boundaries. See Federation for full documentation.

listContracts

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

analyzeContractImpact

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

getContractDependencies

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

suppressContractEdge

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

verifyContractEdge

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

getContractStats

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

v6.4 Runtime Telemetry Tools

Telemetry tools enable confident answers to "is this code actually used?" by integrating runtime observability data.

getTelemetryStatus

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

getObservedUsage

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)

findDeadCodeCandidates

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*)

Enhanced analyzeImpact (v6.4)

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

Enhanced getHotspots (v6.4)

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.


v6.5 Developer Intelligence Tools

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.

explainOrigin

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

analyzeCoupling

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)

exportForLLM

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

auditRisk

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: (when quickWins: 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)

Implementation Status

v5.1 ✓

searchSymbols, getSymbol, findReferences, explainSymbol, justifySymbol, getCallGraph, getModuleOverview, analyzeImpact, getStatus, doctor

v5.2 ✓ (Complete)

All v5.2 tools are now implemented:

Phase 1: explainFile, traceUsage, listEntrypoints

Phase 2: summarizeDiff

Phase 3: getHotspots, getArchitecture

Phase 4: explainPath, listKeyConcepts, recentlyRelevant

v6.0 ✓ (Complete - Architectural Memory)

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

v6.1 ✓ (Complete - Production Ready)

All v6.1 tools are implemented:

Background Jobs: getJobStatus, listJobs, cancelJob

Async Operations: refreshArchitecture now supports async: true mode

CI/CD Integration: summarizePr, getOwnershipDrift

v6.2 ✓ (Complete - Federation)

All v6.2 tools are implemented:

Federation Management: listFederations, federationStatus, federationRepos, federationSync

Cross-Repo Queries: federationSearchModules, federationSearchOwnership, federationGetHotspots, federationSearchDecisions

v6.2.1 ✓ (Complete - Daemon Mode)

All v6.2.1 tools are implemented:

Daemon Status: daemonStatus

Scheduler: listSchedules, runSchedule

Webhooks: listWebhooks, testWebhook, webhookDeliveries

v6.2.2 ✓ (Complete - Tree-sitter Complexity)

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

v6.3 ✓ (Complete - Contract-Aware Impact Analysis)

All v6.3 tools are implemented:

Contract Detection: listContracts

Impact Analysis: analyzeContractImpact, getContractDependencies

Edge Management: suppressContractEdge, verifyContractEdge

Statistics: getContractStats

v6.4 ✓ (Complete - Runtime Telemetry)

All v6.4 tools are implemented:

Telemetry Status: getTelemetryStatus

Usage Display: getObservedUsage

Dead Code Detection: findDeadCodeCandidates

Enhanced Tools:

  • analyzeImpact - Now includes includeTelemetry parameter for observed callers
  • getHotspots - Now includes observedUsage field when telemetry is enabled

v6.5 ✓ (Complete - Developer Intelligence)

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 includes annotations field 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 includes relatedDecisions field showing ADRs affecting impacted modules
  • getModuleOverview - Now includes annotations and relatedDecisions fields
  • getModuleResponsibilities - Declared annotations now override inferred responsibilities with higher confidence

Total: 58 MCP tools available


Troubleshooting

Server won't start

# Check if ckb is available
npx @tastehub/ckb version

# Test MCP server
echo '{"jsonrpc":"2.0","id":1,"method":"initialize"}' | npx @tastehub/ckb mcp

No tools available

ls -la .ckb/
ckb init   # or: npx @tastehub/ckb init

Stale results

ckb index   # regenerate SCIP index
ckb doctor  # check for issues

Clone this wiki locally