Skip to main content
A symbol card is the fundamental unit of code intelligence in SDL-MCP. Every function, class, interface, type, and variable in your codebase becomes a card: a compact metadata record (~100 tokens) containing everything an agent needs to understand a symbol without reading its source.

What a Card Looks Like

Here is a complete symbol card for a validateToken function:
┌─────────────────────────────────────────────────────────┐
│  Symbol Card: validateToken                             │
│─────────────────────────────────────────────────────────│
│  Kind:       function (exported)                        │
│  File:       src/auth/jwt.ts:42-67                      │
│  Signature:  (token: string, opts?: ValidateOpts)       │
│              → Promise<DecodedToken>                    │
│  Summary:    Validates JWT signature and expiration,    │
│              returns decoded payload or throws          │
│  Invariants: ["throws on expired token"]                │
│  Side FX:    ["logs to audit trail"]                    │
│  Deps:       calls: [verifySignature, checkExpiry]      │
│              imports: [jsonwebtoken, AuditLogger]        │
│  Metrics:    fan-in: 12 │ fan-out: 4 │ churn: 3/30d    │
│  Cluster:    auth-module (8 members)                    │
│  Process:    request-pipeline (intermediate, depth 1)   │
│  Test:       auth.test.ts (distance: 1, proximity: 0.9)│
│  ETag:       a7f3c2... (for conditional requests)       │
└─────────────────────────────────────────────────────────┘
This card answers: what the function does, what it accepts and returns, what it cannot do without (invariants), what it changes as a side effect, what it calls, how central it is in the codebase, what cluster it belongs to, what call chain it participates in, and whether it has test coverage — all in approximately 100 tokens.

Field Reference

FieldDescription
kindSymbol type: function, class, interface, type, variable, method, etc. Exported symbols are flagged.
fileFile path and line range (src/auth/jwt.ts:42-67).
signatureFull call signature including parameter names, types, return type, generics, and overloads.
summary1–2 line semantic description. Generated by LLM during indexing or extracted from JSDoc/docstrings.
invariantsPreconditions and postconditions the symbol enforces (e.g., "throws on expired token").
side effectsObservable effects beyond the return value (e.g., "logs to audit trail").
deps.callsSymbols this symbol calls, with confidence scores.
deps.importsModules and symbols this symbol imports.
metrics.fan-inNumber of distinct symbols that call this one. High fan-in means high blast radius on change.
metrics.fan-outNumber of distinct symbols this one calls. High fan-out means broad dependencies.
metrics.churnNumber of times this symbol changed in the last 30 days.
clusterCommunity detection group membership. Symbols in the same cluster are architecturally related.
processNamed call chain this symbol participates in, plus its role (entry, intermediate, or exit) and depth.
test proximityNearest test file, hop distance, and a proximity score (0–1).
ETagContent-addressed hash for conditional requests. Unchanged symbols return 304 Not Modified.

Confidence-Scored Call Resolution

The deps.calls field is produced by SDL-MCP’s two-pass resolver, which traces imports, aliases, barrel re-exports, and tagged templates to produce accurate dependency edges. Each edge carries a confidence score:
  • 1.0 — Directly resolved to a single symbol with no ambiguity
  • 0.7–0.9 — Resolved through an alias or re-export chain
  • 0.4–0.6 — Resolved through a barrel export with multiple candidates
  • < 0.4 — Unresolved or highly ambiguous (filtered by default)
When building slices, you can filter out low-confidence edges using minConfidence or minCallConfidence to keep the result tight.

Community Detection (Cluster Membership)

SDL-MCP runs community detection over the symbol graph to identify architectural clusters — groups of symbols that are densely connected to each other and loosely connected to the rest of the codebase. The cluster field on a card tells you:
  • Which cluster the symbol belongs to (by name, e.g., auth-module)
  • How many members are in that cluster
Clusters are computed during indexing and updated incrementally. They’re used by graph slicing to give a +0.15 relevance boost to symbols in the same cluster as the entry points, making slices architecturally coherent.

Call-Chain Tracing (Process Participation)

The process field reveals which named call chains (“processes”) a symbol participates in and its role within each:
  • entry — The symbol initiates the call chain (e.g., an HTTP handler)
  • intermediate — The symbol is called by entry symbols and calls exit symbols (e.g., validateToken at depth 1 in request-pipeline)
  • exit — The symbol terminates the call chain (e.g., a database write or external API call)
This structural information is surfaced in blast radius analysis and risk scoring to identify which dependent symbols participate in critical paths.

ETag-Based Conditional Requests

Every card has a content-addressed ETag — a hash of the symbol’s semantic content. When requesting cards you already have:
{
  "tool": "sdl.symbol.getCard",
  "arguments": {
    "repoId": "my-app",
    "symbolId": "validateToken",
    "knownEtag": "a7f3c2..."
  }
}
If the symbol hasn’t changed, the server returns { "notModified": true } — zero tokens spent on an unchanged card. For batch requests via sdl.symbol.getCards, pass knownCardEtags as a map of symbol ID to ETag to skip all unchanged cards in a single call.

Getting Cards

Fetch one card by symbol ID:
{
  "tool": "sdl.symbol.getCard",
  "arguments": {
    "repoId": "my-app",
    "symbolId": "validateToken"
  }
}

Why Cards vs. Reading Files

Symbol CardRaw File
Token cost~100~2,000
Contains signatureYesYes (buried)
Contains summaryYesNo
Contains invariantsYesNo
Contains side effectsYesNo
Dependency graphYes (confidence-scored)No
Metrics (fan-in, churn)YesNo
Cluster membershipYesNo
Call-chain roleYesNo
Test proximityYesNo
ETag cachingYesNo
The ~100 token estimate is for a typical function card. Large classes with many methods and overloads can be larger, but they are always dramatically smaller than reading the source file.

Build docs developers (and LLMs) love