| name | sdl-mcp-symbol-delta-ledger |
| description | Policy-centered context budget layer that turns sprawling codebases into compact, high-signal context for AI coding agents using symbol graphs and precision tools |
| triggers | ["index this codebase for better context","get symbol information without reading the whole file","analyze code dependencies and call graphs","show me the blast radius of this change","give me compact context for this task","search the codebase semantically","what's the impact of this PR","build a token-efficient code slice"] |
SDL-MCP: Symbol Delta Ledger
Skill by ara.so — MCP Skills collection.
SDL-MCP is a policy-centered context budget layer for coding agents that transforms sprawling codebases into compact, high-signal context. It indexes code into a searchable symbol graph, providing 4-20x token savings by serving precisely the right amount of context through the Iris Gate Ladder escalation system.
What SDL-MCP Does
- Symbol Cards: Every function, class, interface, type, and variable becomes a ~100 token metadata record instead of ~2,000 tokens of raw code
- Graph Slicing: Follow dependency graphs (not directory boundaries) to get the N most relevant symbols within a token budget
- Iris Gate Ladder: Four-rung context escalation from compact cards to full source (policy-gated)
- Delta Packs & Blast Radius: Semantic change intelligence showing what changes mean and who's affected
- Live Indexing: Real-time code intelligence reflecting unsaved editor changes
- Task-Shaped Retrieval: Context engine that selects the right rungs and evidence for debug/review/implement/explain tasks
Installation
Prerequisites: Node.js 24+ required
Global Installation
npm install -g sdl-mcp
sdl-mcp init -y --auto-index
sdl-mcp serve --stdio
Using npx
npx create-sdl-mcp
npx --yes sdl-mcp@latest init -y --auto-index
npx --yes sdl-mcp@latest serve --stdio
MCP Client Configuration
Add to your MCP client configuration (e.g., Claude Desktop):
{
"mcpServers": {
"sdl-mcp": {
"command": "sdl-mcp",
"args": ["serve", "--stdio"]
}
}
}
Or with npx:
{
"mcpServers": {
"sdl-mcp": {
"command": "npx",
"args": ["--yes", "sdl-mcp@latest", "serve", "--stdio"]
}
}
}
Key Commands (CLI)
sdl-mcp init
sdl-mcp init -y --auto-index
sdl-mcp init --config-only
sdl-mcp index
sdl-mcp index --incremental
sdl-mcp index --force
sdl-mcp serve --stdio
sdl-mcp serve --stdio --verbose
sdl-mcp health
sdl-mcp summary --task "debug auth"
sdl-mcp config get
sdl-mcp config set key=value
MCP Tools API
Symbol Cards & Search
Get Symbol Card (Rung 1: ~100 tokens)
{
"name": "sdl.symbol.card",
"arguments": {
"symbolId": "src/auth/validate.ts::validateToken",
"format": "compact"
}
}
Search Symbols
{
"name": "sdl.symbol.search",
"arguments": {
"query": "authenticate user",
"limit": 10,
"confidence": 0.7,
"filters": {
"kind": ["function", "class"],
"filePath": "src/auth/**"
}
}
}
Graph Slicing
Build Token-Budgeted Slice
{
"name": "sdl.slice.build",
"arguments": {
"entrySymbols": ["src/auth/validate.ts::validateToken"],
"tokenBudget": 800,
"direction": "both",
"weights": {
"call": 1.0,
"config": 0.8,
"import": 0.6
}
}
}
Auto-Discovery from Task
{
"name": "sdl.slice.build",
"arguments": {
"taskText": "Fix authentication timeout issue",
"tokenBudget": 1000,
"autoDiscover": true
}
}
Refresh Slice (Delta Updates)
{
"name": "sdl.slice.refresh",
"arguments": {
"sliceHandle": "slice_abc123",
"deltaOnly": true
}
}
Iris Gate Ladder Escalation
Rung 2: Skeleton (signature + structure)
{
"name": "sdl.iris.skeleton",
"arguments": {
"symbolId": "src/auth/AuthService.ts::AuthService",
"includeSignatures": true,
"includeTypes": true
}
}
Rung 3: Hot Path (specific lines/blocks)
{
"name": "sdl.iris.hotPath",
"arguments": {
"symbolId": "src/auth/validate.ts::validateToken",
"targetIdentifiers": ["cache", "decrypt"],
"contextLines": 3
}
}
Rung 4: Raw Source (policy-gated)
{
"name": "sdl.iris.rawSource",
"arguments": {
"symbolId": "src/auth/validate.ts::validateToken",
"reason": "Need to see complete error handling logic for timeout bug",
"expectedIdentifiers": ["TimeoutError", "retry", "backoff"],
"expectedLineCount": 45,
"bypassPolicy": false
}
}
Task-Shaped Context
Get Context for Task
{
"name": "sdl.context",
"arguments": {
"task": "debug",
"description": "User authentication failing after token refresh",
"tokenBudget": 2000,
"focusPaths": ["src/auth/**"],
"options": {
"semantic": true,
"includeTests": true
}
}
}
Delta & Blast Radius
Semantic Diff
{
"name": "sdl.delta.pack",
"arguments": {
"baseRef": "main",
"headRef": "HEAD",
"options": {
"includeBlastRadius": true,
"maxBlastDepth": 3
}
}
}
PR Risk Analysis
{
"name": "sdl.pr.risk.analyze",
"arguments": {
"baseRef": "main",
"headRef": "feature/auth-refactor",
"options": {
"includeFanInTrend": true,
"testRecommendations": true
}
}
}
Live Indexing
Push Buffer Changes
{
"name": "sdl.buffer.push",
"arguments": {
"filePath": "src/auth/validate.ts",
"content": "export async function validateToken(token: string): Promise<User> {\n // ...\n}",
"version": 42
}
}
Clear Buffer
{
"name": "sdl.buffer.clear",
"arguments": {
"filePath": "src/auth/validate.ts"
}
}
Runtime Execution (Sandboxed)
Execute Code
{
"name": "sdl.runtime.execute",
"arguments": {
"executable": "npm",
"args": ["test", "auth.test.ts"],
"cwd": "./",
"outputMode": "minimal",
"timeout": 30000
}
}
Query Execution Output
{
"name": "sdl.runtime.queryOutput",
"arguments": {
"executionId": "exec_xyz789",
"query": "Show me the failing test assertions"
}
}
Feedback Loop
Record Symbol Usefulness
{
"name": "sdl.agent.feedback",
"arguments": {
"contextId": "ctx_abc123",
"useful": ["src/auth/validate.ts::validateToken"],
"missing": ["src/auth/TokenCache.ts::get"],
"irrelevant": ["src/utils/logger.ts::debug"]
}
}
Configuration
SDL-MCP stores configuration in .sdl-mcp/config.json:
{
"repoRoot": "/path/to/repo",
"languages": {
"typescript": { "enabled": true },
"python": { "enabled": true },
"go": { "enabled": true }
},
"indexing": {
"exclude": ["node_modules/**", "dist/**", "*.test.ts"],
"maxFileSize": 1048576,
"parallelism": 4
},
"governance": {
"rawSourceGate": {
"enabled": true,
"requireReason": true,
"requireIdentifiers": true,
"maxLineCount": 500
},
"runtime": {
"enabled": true,
"allowedExecutables": ["npm", "node", "python3"],
"cwdJail": true,
"timeout": 30000
}
},
"codeMode": {
"exclusive": true,
"autoSlicing": true,
"defaultBudget": 1500
},
"retrieval": {
"hybridThreshold": 0.7,
"semanticDefault": "auto"
}
}
Update Configuration
sdl-mcp config set governance.rawSourceGate.maxLineCount=1000
sdl-mcp config set codeMode.defaultBudget=2000
sdl-mcp config set governance.runtime.enabled=false
sdl-mcp config set codeMode.exclusive=false
Common Patterns
Pattern 1: Efficient Code Understanding
Instead of reading entire files:
const fileContent = await readFile('src/auth/validate.ts');
const card = await mcp.call('sdl.symbol.card', {
symbolId: 'src/auth/validate.ts::validateToken',
format: 'compact'
});
Pattern 2: Dependency-Aware Context
Instead of directory-based context:
const authFiles = await glob('src/auth/**/*.ts');
const slice = await mcp.call('sdl.slice.build', {
taskText: 'Fix token validation timeout',
tokenBudget: 800,
autoDiscover: true
});
Pattern 3: Controlled Escalation
Only read raw code when necessary:
const card = await mcp.call('sdl.symbol.card', {
symbolId: 'src/auth/validate.ts::validateToken'
});
const skeleton = await mcp.call('sdl.iris.skeleton', {
symbolId: 'src/auth/validate.ts::validateToken',
includeSignatures: true
});
const hotPath = await mcp.call('sdl.iris.hotPath', {
symbolId: 'src/auth/validate.ts::validateToken',
targetIdentifiers: ['cache', 'decrypt'],
contextLines: 3
});
const raw = await mcp.call('sdl.iris.rawSource', {
symbolId: 'src/auth/validate.ts::validateToken',
reason: 'Need complete error handling for timeout analysis',
expectedIdentifiers: ['TimeoutError', 'retry'],
expectedLineCount: 45
});
Pattern 4: Task-Shaped Retrieval
Let SDL-MCP plan the context:
const debugContext = await mcp.call('sdl.context', {
task: 'debug',
description: 'Authentication timeout after 30 seconds',
tokenBudget: 2000,
focusPaths: ['src/auth/**'],
options: { includeTests: true }
});
const reviewContext = await mcp.call('sdl.context', {
task: 'review',
description: 'Refactor token validation to use Redis cache',
tokenBudget: 1500,
options: { semantic: true }
});
const implContext = await mcp.call('sdl.context', {
task: 'implement',
description: 'Add rate limiting to login endpoint',
tokenBudget: 2500,
focusSymbols: ['src/auth/login.ts::handleLogin']
});
Pattern 5: Change Impact Analysis
Understand semantic impact of changes:
const deltaPack = await mcp.call('sdl.delta.pack', {
baseRef: 'main',
headRef: 'feature/cache-refactor',
options: {
includeBlastRadius: true,
maxBlastDepth: 3
}
});
const riskAnalysis = await mcp.call('sdl.pr.risk.analyze', {
baseRef: 'main',
headRef: 'feature/cache-refactor',
options: {
includeFanInTrend: true,
testRecommendations: true
}
});
Pattern 6: Live Development Flow
Work with unsaved changes:
await mcp.call('sdl.buffer.push', {
filePath: 'src/auth/validate.ts',
content: currentEditorContent,
version: editorVersion
});
const liveSearch = await mcp.call('sdl.symbol.search', {
query: 'validateToken',
limit: 5
});
const liveSlice = await mcp.call('sdl.slice.build', {
taskText: 'Review my current auth changes',
tokenBudget: 1000
});
await mcp.call('sdl.buffer.clear', {
filePath: 'src/auth/validate.ts'
});
Pattern 7: Feedback-Driven Improvement
Help SDL-MCP learn what's useful:
await mcp.call('sdl.agent.feedback', {
contextId: 'ctx_abc123',
useful: [
'src/auth/validate.ts::validateToken',
'src/cache/TokenCache.ts::get'
],
missing: [
'src/auth/errors.ts::TimeoutError'
],
irrelevant: [
'src/utils/logger.ts::debug'
]
});
Real-World Example: Debugging Authentication Issue
const context = await mcp.call('sdl.context', {
task: 'debug',
description: 'Users getting 401 errors after token refresh',
tokenBudget: 2000,
focusPaths: ['src/auth/**'],
options: { includeTests: true }
});
const symbols = await mcp.call('sdl.symbol.search', {
query: 'token refresh validate',
limit: 10,
confidence: 0.7
});
const slice = await mcp.call('sdl.slice.build', {
entrySymbols: symbols.results.slice(0, 3).map(r => r.symbolId),
tokenBudget: 800,
direction: 'both'
});
const skeleton = await mcp.call('sdl.iris.skeleton', {
symbolId: 'src/auth/TokenService.ts::refreshToken',
includeSignatures: true
});
const hotPath = await mcp.call('sdl.iris.hotPath', {
symbolId: 'src/auth/TokenService.ts::refreshToken',
targetIdentifiers: ['verify', 'expire', 'blacklist'],
contextLines: 5
});
const testRun = await mcp.call('sdl.runtime.execute', {
executable: 'npm',
args: ['test', 'auth/token.test.ts'],
outputMode: 'summary',
timeout: 30000
});
await mcp.call('sdl.agent.feedback', {
contextId: context.id,
useful: [
'src/auth/TokenService.ts::refreshToken',
'src/auth/TokenService.ts::verifyToken'
],
missing: [
'src/auth/blacklist.ts::isBlacklisted'
]
});
Token Comparison:
- Reading all auth files: ~16,000 tokens
- SDL-MCP approach: ~1,500 tokens
- Savings: 10.6x
Troubleshooting
Installation Issues
Peer dependency warnings:
npm install -g sdl-mcp --legacy-peer-deps
Tree-sitter grammar issues:
npm rebuild tree-sitter tree-sitter-kotlin
Node version mismatch:
node -v
Indexing Issues
Index fails on large repo:
sdl-mcp config set indexing.maxFileSize=2097152
sdl-mcp config set indexing.parallelism=2
Files not indexed:
sdl-mcp config get indexing.exclude
sdl-mcp index --force
Language not detected:
sdl-mcp config set languages.python.enabled=true
sdl-mcp init --auto-index
Query Issues
Low search quality:
{
"name": "sdl.symbol.search",
"arguments": {
"query": "authentication logic",
"options": { "semantic": true }
}
}
sdl-mcp config set retrieval.semanticDefault=true
Slice too small/large:
{
"name": "sdl.slice.build",
"arguments": {
"entrySymbols": ["..."],
"tokenBudget": 1500
}
}
Raw source denied:
sdl-mcp config get governance.rawSourceGate
{
"name": "sdl.iris.rawSource",
"arguments": {
"symbolId": "...",
"reason": "Specific reason why card/skeleton/hotPath insufficient",
"expectedIdentifiers": ["specific", "names", "needed"],
"expectedLineCount": 45
}
}
Runtime Issues
Execution denied:
sdl-mcp config get governance.runtime.allowedExecutables
sdl-mcp config set governance.runtime.allowedExecutables='["npm","node","python3","go"]'
Execution timeout:
{
"name": "sdl.runtime.execute",
"arguments": {
"executable": "npm",
"args": ["test"],
"timeout": 60000
}
}
Health Checks
sdl-mcp health
Environment Variables
export SDL_DB_PATH=/custom/path/to/db
export SDL_LOG_LEVEL=debug
export SDL_TELEMETRY=false
export SDL_MAX_WORKERS=8
Performance Tips
- Use incremental indexing during development:
sdl-mcp index --incremental
- Set appropriate token budgets (800-1500 typical, 2000+ for complex tasks)
- Use focusPaths/focusSymbols to scope searches when possible
- Enable deltaOnly on slice refreshes to minimize re-fetching
- Leverage live indexing instead of re-indexing after every edit
- Provide feedback to improve future slice quality
- Use Code Mode (
codeMode.exclusive: true) for most efficient agent workflow
Learn More