Skip to main content
SDL-MCP is configured via a single JSON file. This page covers every option, its default, valid values, and when you should change it.

Config file location

SDL-MCP resolves the config file in the following order (highest precedence first):
PriorityMethodDetails
1--config <PATH> CLI flagPassed to any command
2SDL_CONFIG or SDL_CONFIG_PATH env varFull path to config file
3SDL_CONFIG_HOME env varDirectory; SDL-MCP looks for sdlmcp.config.json inside
4OS config directoryPlatform default (~/.config/sdl-mcp/ on Linux/macOS)
The sdl-mcp init command creates a config file interactively. You can also start from the example file in config/sdlmcp.config.example.json.
Add a $schema reference to your config file for editor autocompletion and inline validation:
{
  "$schema": "./node_modules/sdl-mcp/config/sdlmcp.config.schema.json",
  "repos": [...]
}
Run sdl-mcp doctor to validate your config and check environment health.

Minimal required config

Only two top-level fields are required. Everything else has sensible defaults:
{
  "repos": [{ "repoId": "my-repo", "rootPath": "/workspace/my-repo" }],
  "policy": {}
}
If graphDatabase.path is omitted, SDL-MCP defaults to <configDir>/sdl-mcp-graph.lbug.

Field reference

repos[] — repositories to index

Each entry registers a codebase for indexing. You can index multiple repos in one config.
repos[].repoId
string
required
Unique identifier used in all MCP tool calls (e.g., sdl.symbol.search({ repoId: "my-repo" })). Must be unique across all registered repos.
repos[].rootPath
string
required
Path to the repository root. Absolute paths are recommended; relative paths are resolved from the config file directory.
repos[].ignore
string[]
Glob patterns to exclude from indexing. Add heavy or generated directories here.Default: ["**/node_modules/**", "**/dist/**", "**/.next/**", "**/build/**", "**/.git/**", "**/coverage/**"]
If using the Rust engine, also add "**/native/target/**" to exclude the Rust build directory.
repos[].languages
string[]
File extensions to index. Only include languages present in your repo for faster indexing. Defaults to all supported languages.Supported language codes: ts, tsx, js, jsx, py, go, java, cs, c, cpp, php, rs, kt, sh
repos[].maxFileBytes
number
default:"2000000"
Files larger than this size in bytes are skipped. Default is 2 MB (2,000,000 bytes).
repos[].includeNodeModulesTypes
boolean
default:"true"
Index @types/* declarations from node_modules for TypeScript call resolution. Excludes @types/node. Disable for non-TypeScript repos or if indexing is slow.
repos[].packageJsonPath
string
Override auto-detection of package.json location. Useful for monorepos with custom layouts.
repos[].tsconfigPath
string
Override auto-detection of tsconfig.json. Useful for monorepos with multiple tsconfigs.
repos[].workspaceGlobs
string[]
Glob patterns to find workspace package.json files in monorepos.Example: ["packages/*/package.json", "apps/*/package.json"]
Controls where SDL-MCP stores the Ladybug graph database. Supports ${ENV_VAR} expansion inside values.
graphDatabase.path
string
Path to the Ladybug .lbug database file. Defaults to <configDir>/sdl-mcp-graph.lbug when omitted.Supports environment variable expansion: use ${SDL_GRAPH_DB_PATH} for an explicit file path, or ${SDL_GRAPH_DB_DIR} to point at a directory and let SDL-MCP place sdl-mcp-graph.lbug inside it.
Move the database to a fast SSD path if indexing performance is slow on spinning disks.
Controls the proof-of-need gating system for raw code access via sdl.code.needWindow. Requests exceeding maxWindowLines or maxWindowTokens are silently clamped, not rejected. Policy can also be changed at runtime via sdl.policy.set.
policy.maxWindowLines
number
default:"180"
Maximum lines returned per sdl.code.needWindow request. Minimum: 1. Requests above this are clamped.
policy.maxWindowTokens
number
default:"1400"
Maximum tokens returned per sdl.code.needWindow request. Minimum: 1. Requests above this are clamped.
policy.requireIdentifiers
boolean
default:"true"
Require a non-empty identifiersToFind in sdl.code.needWindow calls. Enforces proof-of-need: agents must specify what they’re looking for.
policy.allowBreakGlass
boolean
default:"false"
Allow emergency override to bypass policy denials. All break-glass overrides are logged in the audit trail.
policy.defaultDenyRaw
boolean
default:"true"
Default deny for raw code windows, subjecting needWindow to proof-of-need gating.
policy.budgetCaps
object
Optional server-side budget defaults applied when the client does not supply them.Example: { "maxCards": 60, "maxEstimatedTokens": 12000 }
policy.defaultMinCallConfidence
number
Optional server-side default for minCallConfidence used in symbol.getCard and slice.build call-edge filtering. Range: 0.0–1.0. Leave unset to keep call-edge filtering request-driven only.
Set allowBreakGlass: false in production to enforce strict gating. In CI, tighten limits to maxWindowLines: 120, maxWindowTokens: 1000 to control token spend.
Controls sensitive-data masking in all returned code content (windows, skeletons, and hot paths).
redaction.enabled
boolean
default:"true"
Enable secret redaction.
redaction.includeDefaults
boolean
default:"true"
Include built-in patterns covering AWS keys, GitHub tokens, private keys, and other common secrets.
redaction.patterns
object[]
default:"[]"
Additional custom regex patterns to redact. Each pattern object supports:
FieldTypeRequiredDescription
namestringNoLabel for documentation and logging
patternstringYesRegex pattern to match
flagsstringNoRegex flags (e.g., "gi")
Example:
{ "name": "internal-token", "pattern": "INTERNAL_[A-Z0-9]{32}", "flags": "g" }
Controls how and when code is indexed.
indexing.engine
string
default:"\"rust\""
Pass-1 indexer implementation. Options: "rust" (native addon, faster) or "typescript" (fallback). Falls back to TypeScript automatically if the native addon is unavailable.
indexing.concurrency
number
default:"8"
Number of concurrent file-processing workers during indexing. Range: 1–10. Higher values are faster on SSDs with many cores; lower values suit constrained CI or spinning disks.
indexing.enableFileWatching
boolean
default:"true"
Keep the index fresh by watching for file changes during sdl-mcp serve. Disable in CI or batch-only workflows.
indexing.maxWatchedFiles
number
default:"25000"
Upper bound on source files the watcher tracks. Prevents memory overload on large repos.
indexing.watchDebounceMs
number
default:"300"
Debounce delay in milliseconds before processing file-change events. Range: 50–5000. Lower values give faster incremental updates; higher values reduce redundant reindex calls during rapid edits.
indexing.workerPoolSize
number
Optional cap on worker pool threads. Defaults to a CPU-count heuristic when unset. Range: 1–16.
Controls the live editor buffer overlay for draft-aware code intelligence (unsaved buffers).
liveIndex.enabled
boolean
default:"true"
Enable live index overlay for unsaved editor buffers.
liveIndex.debounceMs
number
default:"75"
Debounce delay in milliseconds before parsing buffer updates. Range: 25–5000.
liveIndex.idleCheckpointMs
number
default:"15000"
Idle time in milliseconds before auto-checkpoint to the database. Range: 1000–300000.
liveIndex.maxDraftFiles
number
default:"200"
Maximum number of concurrent draft files in the overlay. Range: 1–10000.
liveIndex.reconcileConcurrency
number
default:"1"
Number of concurrent reconciliation jobs (overlay to database merge). Range: 1–8.
liveIndex.clusterRefreshThreshold
number
default:"25"
Number of reconciled symbols before triggering a cluster refresh. Range: 1–1000.
Default budget and traversal weights for graph slices (sdl.slice.build). Per-call budget parameters override these defaults.
slice.defaultMaxCards
number
default:"60"
Default maximum symbol cards returned per sdl.slice.build call. Minimum: 1.
slice.defaultMaxTokens
number
default:"12000"
Default maximum estimated tokens per slice response. Minimum: 1.
slice.edgeWeights.call
number
default:"1.0"
Traversal weight for function/method call edges. Higher values pull more call neighbors into the slice. Minimum: 0.
slice.edgeWeights.import
number
default:"0.6"
Traversal weight for module import edges. Minimum: 0.
slice.edgeWeights.config
number
default:"0.8"
Traversal weight for configuration reference edges. Minimum: 0.
Controls semantic search reranking, embedding generation, and LLM-powered symbol summaries.
semantic.enabled
boolean
default:"true"
Enable semantic reranking in sdl.symbol.search when semantic: true is passed. When enabled, lexical results are reranked by embedding similarity.
semantic.provider
string
default:"\"local\""
Embedding provider. Options: "local" (onnxruntime-node, works offline), "api" (remote), "mock" (deterministic, for testing).
semantic.model
string
default:"\"all-MiniLM-L6-v2\""
Embedding model identifier. Used by "api" and "local" providers. Also supported: "nomic-embed-text-v1.5".
semantic.modelCacheDir
string
Override directory for downloaded ONNX model files. Defaults to the platform-specific cache directory when unset.
semantic.generateSummaries
boolean
default:"false"
Generate LLM-powered symbol summaries during indexing. Requires an API key via summaryApiKey or the ANTHROPIC_API_KEY environment variable. Summaries are cached as SummaryCache graph nodes in the database.
semantic.summaryProvider
string
LLM backend for summary generation, independent from the embedding provider. Options: "api" (Anthropic), "local" (OpenAI-compatible, e.g., Ollama), "mock" (deterministic). Defaults to the provider value when unset.
semantic.summaryModel
string
LLM model for summary generation. Defaults per provider: "api" uses "claude-haiku-4-5-20251001", "local" uses "gpt-4o-mini".
semantic.summaryApiKey
string
API key for the summary LLM provider. Falls back to the ANTHROPIC_API_KEY environment variable when unset.
semantic.summaryApiBaseUrl
string
Base URL for OpenAI-compatible local providers. Example: "http://localhost:11434/v1" for Ollama. Uses the Anthropic API when unset.
semantic.summaryMaxConcurrency
number
default:"5"
Maximum concurrent LLM requests during batch summary generation. Range: 1–20.
semantic.summaryBatchSize
number
default:"20"
Symbols per LLM request during index-time summary generation. Larger batches reduce API calls but require larger context windows. Range: 1–50.
semantic.alpha
number
default:"0.6"
deprecated
Deprecated — use retrieval.fusion.rrfK instead. Legacy lexical/semantic blend ratio (0.0 = pure lexical, 1.0 = pure semantic). Still honored in "legacy" retrieval mode; ignored when retrieval.mode is "hybrid".

semantic.retrieval — hybrid retrieval pipeline

Replaces legacy alpha-blending with a two-stage FTS + vector search pipeline fused via Reciprocal Rank Fusion (RRF).
semantic.retrieval.mode
string
default:"\"legacy\""
Retrieval strategy. Options: "legacy" (original semantic re-rank) or "hybrid" (FTS + vector fusion pipeline). "hybrid" is recommended for best search quality.
semantic.retrieval.extensionsOptional
boolean
default:"true"
Allow graceful fallback when file-extension filtering is unavailable during retrieval.
semantic.retrieval.candidateLimit
number
default:"100"
Maximum candidate symbols after fusion re-ranking. Range: 10–1000.
semantic.retrieval.fts.enabled
boolean
default:"true"
Enable the full-text search retrieval stage.
semantic.retrieval.fts.topK
number
default:"75"
Maximum FTS candidates before fusion. Range: 1–500.
semantic.retrieval.fts.conjunctive
boolean
default:"false"
When true, all query terms must match (AND). When false, any term matches (OR).
semantic.retrieval.vector.enabled
boolean
default:"true"
Enable the vector (HNSW) retrieval stage using native Ladybug vector indexes.
semantic.retrieval.vector.topK
number
default:"75"
Maximum candidates per model from vector search. Range: 1–500.
semantic.retrieval.vector.efs
number
default:"200"
Query-time accuracy parameter (efSearch). Higher values are more accurate but slower. Range: 8–1000.
semantic.retrieval.fusion.strategy
string
default:"\"rrf\""
Fusion algorithm for combining FTS and vector results. Only "rrf" (Reciprocal Rank Fusion) is currently supported.
semantic.retrieval.fusion.rrfK
number
default:"60"
RRF smoothing constant. Higher values produce more uniform ranking. Range: 1–1000.
Predictive background warming of likely-needed results during sdl-mcp serve. Prefetch metrics are exposed in sdl.repo.status under prefetchStats.
prefetch.enabled
boolean
default:"true"
Enable the background prefetch queue. Disable in CI or batch-only workflows.
prefetch.maxBudgetPercent
number
default:"20"
Cap for prefetch resource usage as a percentage of the configured budget. Range: 1–100.
prefetch.warmTopN
number
default:"50"
Number of top symbols warmed on server startup. Minimum: 1.
TypeScript/JavaScript diagnostics integration for delta packs and blast radius analysis.
diagnostics.enabled
boolean
default:"true"
Enable diagnostics. Only applies to TypeScript/JavaScript repositories.
diagnostics.mode
string
default:"\"tsLS\""
Diagnostics engine. Options: "tsLS" (TypeScript Language Service, faster) or "tsc" (compiler, more thorough).
diagnostics.maxErrors
number
default:"50"
Maximum errors to report before truncating. Prevents overwhelming output. Minimum: 1.
diagnostics.timeoutMs
number
default:"2000"
Per-operation timeout in milliseconds. Minimum: 100. Increase for very large files.
diagnostics.scope
string
default:"\"changedFiles\""
Which files to check. Options: "changedFiles" (only files modified since last index, faster) or "workspace" (all files, more thorough but much slower on large repos).
In-memory LRU caches for frequently accessed symbol cards and graph slices.
cache.enabled
boolean
default:"true"
Toggle all caching. Disable only for debugging stale-cache issues.
cache.symbolCardMaxEntries
number
default:"2000"
Maximum symbol cards held in memory before LRU eviction. Minimum: 1.
cache.symbolCardMaxSizeBytes
number
default:"104857600"
Total byte cap for the symbol card cache. Default is 100 MB. Minimum: 1024.
cache.graphSliceMaxEntries
number
default:"1000"
Maximum graph slices held in memory. Minimum: 1.
cache.graphSliceMaxSizeBytes
number
default:"52428800"
Total byte cap for the graph slice cache. Default is 50 MB. Minimum: 1024.
Controls concurrency limits for sessions, tool dispatch, and database connections.
concurrency.maxSessions
number
default:"8"
Maximum concurrent HTTP sessions. Range: 1–16. Increase for multi-agent setups.
concurrency.maxToolConcurrency
number
default:"8"
Maximum concurrent tool handler executions. Range: 1–32. Lower on resource-constrained systems.
concurrency.readPoolSize
number
default:"4"
LadybugDB read connection pool size. Range: 1–8. Increase to 6–8 for large repos with heavy concurrent reads.
concurrency.writeQueueTimeoutMs
number
default:"30000"
Timeout in milliseconds for queued write operations. Range: 1000–120000.
concurrency.toolQueueTimeoutMs
number
default:"30000"
Timeout in milliseconds for queued tool invocations. Range: 5000–120000.
Bearer-token authentication for the HTTP transport (sdl-mcp serve --http). Has no effect on stdio transport.
httpAuth.enabled
boolean
default:"false"
Enable bearer-token authentication for /mcp and /api/* endpoints.
httpAuth.token
string
Static bearer token. When null and enabled is true, a random token is generated at startup and printed to stderr.
ConfigurationBehavior
Omitted / { "enabled": false }Auth disabled — all requests accepted without a token
{ "enabled": true }Random token generated at startup, printed to stderr
{ "enabled": true, "token": "my-token" }Static token — no random generation, token not printed
For shared dev servers or production, set enabled: true with a static token so all agents can use the same credential.
Adapter plugin loading for extending indexer language support.
plugins.paths
string[]
default:"[]"
Paths to plugin entrypoints (files or directories).
plugins.enabled
boolean
default:"true"
Toggle plugin loading. Set to false to disable all plugins without removing paths.
plugins.strictVersioning
boolean
default:"true"
Require plugin API version compatibility. Disable only during plugin development and testing.
Controls the gateway tool registration mode.
gateway.enabled
boolean
default:"true"
Enable gateway-mode tool registration. Groups tools into 4 namespace tools (sdl_repo, sdl_symbol, sdl_code, sdl_agent) plus sdl.action.search and sdl.info.
gateway.emitLegacyTools
boolean
default:"true"
Also emit flat tool names alongside gateway tools for backwards compatibility. Set to false to reduce the tool list from 37 to 6 tools (gateway-only mode).
Controls Code Mode tools (sdl.manual and sdl.chain).
codeMode.enabled
boolean
default:"true"
Enable Code Mode tools (sdl.action.search, sdl.manual, sdl.chain).
codeMode.exclusive
boolean
default:"true"
When true, suppresses gateway and legacy tools — only code-mode tools and discovery are registered. Set to false to expose the full tool surface alongside code-mode tools.
codeMode.maxChainSteps
number
default:"20"
Maximum steps allowed in a single chain. Range: 1–50.
codeMode.maxChainTokens
number
default:"50000"
Maximum total estimated tokens for chain results. Range: 100–500000.
codeMode.maxChainDurationMs
number
default:"60000"
Maximum wall-clock duration for a chain in milliseconds. Range: 1000–300000.
codeMode.ladderValidation
string
default:"\"warn\""
Context ladder validation mode. Options: "off", "warn", "enforce". Use "enforce" to reject chains that skip context ladder rungs.
codeMode.etagCaching
boolean
default:"true"
Auto-inject ifNoneMatch ETags for repeated card requests within a chain to avoid resending unchanged cards.
Worker-thread acceleration for beam search scoring in sdl.slice.build. Most useful for repos with more than 5,000 symbols and large slices.
parallelScorer.enabled
boolean
default:"true"
Enable parallel scoring using worker threads. Disable on single-core or memory-constrained systems.
parallelScorer.poolSize
number
Number of worker threads. Defaults to a CPU-count heuristic when unset. Range: 1–8.
parallelScorer.minBatchSize
number
Minimum candidate count to trigger parallel scoring. Below this threshold, single-threaded scoring is used. Range: 1–100.
OpenTelemetry observability for tool calls, indexing, and internal operations.
tracing.enabled
boolean
default:"true"
Enable OpenTelemetry tracing.
tracing.serviceName
string
default:"\"sdl-mcp\""
Service name attached to all trace spans.
tracing.exporterType
string
default:"\"console\""
Trace exporter. Options: "console" (stdout), "otlp" (collector endpoint), "memory" (in-process).
tracing.otlpEndpoint
string
OTLP collector endpoint URL. Required when exporterType is "otlp".Example: "http://localhost:4318/v1/traces"
tracing.sampleRate
number
default:"1.0"
Sampling rate for traces. Range: 0.0–1.0. A value of 1.0 traces everything; lower values reduce overhead under heavy load.
Controls the sandboxed runtime execution engine (sdl.runtime.execute).
The runtime is disabled by default. Enable only if your agents need to execute code. Keep allowedRuntimes minimal — only include runtimes your agents actually need.
runtime.enabled
boolean
default:"false"
Must be true to use sdl.runtime.execute.
runtime.allowedRuntimes
string[]
default:"[\"node\", \"python\"]"
Whitelist of permitted runtimes. Supported values: node, typescript, python, shell, ruby, php, perl, r, elixir, go, java, kotlin, rust, c, cpp, csharp (16 runtimes total).
runtime.allowedExecutables
string[]
default:"[]"
Additional executable names beyond the runtime defaults. Example: ["bun", "deno"].
runtime.maxDurationMs
number
default:"30000"
Default execution timeout in milliseconds. Range: 100–600000.
runtime.maxStdoutBytes
number
default:"1048576"
Maximum stdout capture size in bytes. Default is 1 MB. Minimum: 1024.
runtime.maxStderrBytes
number
default:"262144"
Maximum stderr capture size in bytes. Default is 256 KB. Minimum: 1024.
runtime.maxArtifactBytes
number
default:"10485760"
Maximum persisted artifact size in bytes. Default is 10 MB. Minimum: 1024.
runtime.artifactTtlHours
number
default:"24"
Hours to retain output artifacts before cleanup. Minimum: 1.
runtime.maxConcurrentJobs
number
default:"2"
Maximum concurrent runtime executions. Range: 1–8.
runtime.envAllowlist
string[]
default:"[]"
Environment variables passed through to subprocesses. Example: ["NODE_ENV", "DATABASE_URL"].
runtime.artifactBaseDir
string
Override directory for runtime output artifacts. Auto-detected when unset.
Controls security restrictions for repository registration.
security.allowedRepoRoots
string[]
default:"[]"
Whitelist of allowed repository root paths for sdl.repo.register. When non-empty, calls are rejected unless the rootPath starts with one of these prefixes. An empty array (default) allows any path.
Set this in shared or multi-tenant deployments to prevent agents from registering arbitrary filesystem paths.

Environment variables

SDL-MCP expands ${VAR_NAME} references inside JSON config values at load time.
VariableDescription
SDL_CONFIG / SDL_CONFIG_PATHFull path to the config file
SDL_CONFIG_HOMEDirectory for default global config resolution
SDL_GRAPH_DB_PATHOverride graph DB file path (takes precedence over config)
SDL_GRAPH_DB_DIRDirectory-style override; SDL-MCP stores sdl-mcp-graph.lbug inside it
SDL_DB_PATHLegacy alias for graph DB path override (v0.7.x)
SDL_LOG_FILEExplicit log file path; falls back to an OS temp file if unusable
SDL_LOG_LEVELLog level: debug, info, warn, error (case-insensitive)
SDL_CONSOLE_LOGGINGSet to true to mirror log lines to stderr in addition to file logging
SDL_LOG_FORMATLog format: json or text
ANTHROPIC_API_KEYFallback API key for semantic.generateSummaries
SDL_MCP_DISABLE_NATIVE_ADDONSet to 1 to force the TypeScript fallback engine (skip native Rust addon)

Common configuration profiles

{
  "indexing": {
    "concurrency": 8,
    "enableFileWatching": true,
    "watchDebounceMs": 100
  },
  "slice": {
    "defaultMaxCards": 100,
    "defaultMaxTokens": 20000
  },
  "prefetch": {
    "enabled": true,
    "warmTopN": 100
  },
  "cache": {
    "enabled": true,
    "symbolCardMaxEntries": 5000
  }
}

Full annotated example

The following example shows every available option with its default value. JSON does not support comments — this is for reference only. Remove comments and unused fields before saving as your actual config file.
{
  "$schema": "./node_modules/sdl-mcp/config/sdlmcp.config.schema.json",
  "repos": [
    {
      "repoId": "my-repo",
      "rootPath": "/workspace/my-repo",
      "ignore": [
        "**/node_modules/**",
        "**/dist/**",
        "**/.next/**",
        "**/build/**",
        "**/.git/**",
        "**/coverage/**"
      ],
      "languages": ["ts", "tsx", "js", "jsx", "py", "go", "java", "cs", "c", "cpp", "php", "rs", "kt", "sh"],
      "maxFileBytes": 2000000,
      "includeNodeModulesTypes": true,
      "packageJsonPath": null,
      "tsconfigPath": null,
      "workspaceGlobs": null
    }
  ],
  "graphDatabase": {
    "path": "./data/sdl-mcp-graph.lbug"
  },
  "policy": {
    "maxWindowLines": 180,
    "maxWindowTokens": 1400,
    "requireIdentifiers": true,
    "allowBreakGlass": false,
    "defaultDenyRaw": true,
    "budgetCaps": null,
    "defaultMinCallConfidence": null
  },
  "redaction": {
    "enabled": true,
    "includeDefaults": true,
    "patterns": []
  },
  "indexing": {
    "concurrency": 8,
    "enableFileWatching": true,
    "maxWatchedFiles": 25000,
    "workerPoolSize": null,
    "engine": "rust",
    "watchDebounceMs": 300
  },
  "liveIndex": {
    "enabled": true,
    "debounceMs": 75,
    "idleCheckpointMs": 15000,
    "maxDraftFiles": 200,
    "reconcileConcurrency": 1,
    "clusterRefreshThreshold": 25
  },
  "slice": {
    "defaultMaxCards": 60,
    "defaultMaxTokens": 12000,
    "edgeWeights": {
      "call": 1.0,
      "import": 0.6,
      "config": 0.8
    }
  },
  "diagnostics": {
    "enabled": true,
    "mode": "tsLS",
    "maxErrors": 50,
    "timeoutMs": 2000,
    "scope": "changedFiles"
  },
  "cache": {
    "enabled": true,
    "symbolCardMaxEntries": 2000,
    "symbolCardMaxSizeBytes": 104857600,
    "graphSliceMaxEntries": 1000,
    "graphSliceMaxSizeBytes": 52428800
  },
  "plugins": {
    "paths": [],
    "enabled": true,
    "strictVersioning": true
  },
  "semantic": {
    "enabled": true,
    "provider": "local",
    "model": "all-MiniLM-L6-v2",
    "modelCacheDir": null,
    "generateSummaries": false,
    "summaryProvider": null,
    "summaryModel": null,
    "summaryApiKey": null,
    "summaryApiBaseUrl": null,
    "summaryMaxConcurrency": 5,
    "summaryBatchSize": 20,
    "retrieval": {
      "mode": "legacy",
      "extensionsOptional": true,
      "fts": {
        "enabled": true,
        "indexName": "symbol_search_text_v1",
        "topK": 75,
        "conjunctive": false
      },
      "vector": {
        "enabled": true,
        "topK": 75,
        "efs": 200,
        "indexes": {
          "all-MiniLM-L6-v2": { "indexName": "symbol_vec_minilm_l6_v2" },
          "nomic-embed-text-v1.5": { "indexName": "symbol_vec_nomic_embed_v15" }
        }
      },
      "fusion": {
        "strategy": "rrf",
        "rrfK": 60
      },
      "candidateLimit": 100
    }
  },
  "prefetch": {
    "enabled": true,
    "maxBudgetPercent": 20,
    "warmTopN": 50
  },
  "tracing": {
    "enabled": true,
    "serviceName": "sdl-mcp",
    "exporterType": "console",
    "otlpEndpoint": null,
    "sampleRate": 1.0
  },
  "parallelScorer": {
    "enabled": true,
    "poolSize": null,
    "minBatchSize": null
  },
  "concurrency": {
    "maxSessions": 8,
    "maxToolConcurrency": 8,
    "readPoolSize": 4,
    "writeQueueTimeoutMs": 30000,
    "toolQueueTimeoutMs": 30000
  },
  "runtime": {
    "enabled": false,
    "allowedRuntimes": ["node", "python"],
    "allowedExecutables": [],
    "maxDurationMs": 30000,
    "maxStdoutBytes": 1048576,
    "maxStderrBytes": 262144,
    "maxArtifactBytes": 10485760,
    "artifactTtlHours": 24,
    "maxConcurrentJobs": 2,
    "envAllowlist": [],
    "artifactBaseDir": null
  },
  "gateway": {
    "enabled": true,
    "emitLegacyTools": true
  },
  "httpAuth": {
    "enabled": false,
    "token": null
  },
  "codeMode": {
    "enabled": true,
    "exclusive": true,
    "maxChainSteps": 20,
    "maxChainTokens": 50000,
    "maxChainDurationMs": 60000,
    "ladderValidation": "warn",
    "etagCaching": true
  },
  "security": {
    "allowedRepoRoots": []
  }
}

Native Rust engine

The Rust indexer (default indexing.engine) replaces the TypeScript tree-sitter pass with a native addon for faster multi-threaded symbol extraction. It supports the same 14 file extensions as the TypeScript engine. Prerequisites: Rust toolchain (rustc 1.70+, cargo) and @napi-rs/cli (installed as a dev dependency).
1

Build the native addon

npm run build:native
This compiles the native addon in native/ and produces a platform-specific .node file.
2

Enable in config

{
  "indexing": { "engine": "rust" }
}
Add "**/native/target/**" to your repo ignore patterns to exclude the Rust build directory from indexing.
3

Verify parity

npm run test:native-parity
Runs parity checks comparing Rust and TypeScript extraction output.
If the native addon fails to load at runtime, SDL-MCP falls back to the TypeScript engine with a warning. Set SDL_MCP_DISABLE_NATIVE_ADDON=1 to force the TypeScript fallback explicitly.

Operational diagnostics

Run sdl-mcp info or call the sdl.info MCP tool to inspect the resolved runtime state. The report includes:
  • Config path, existence, and load status
  • Resolved log file path and whether temp-file fallback is active
  • Whether SDL_CONSOLE_LOGGING is mirroring logs to stderr
  • Ladybug availability and active database path
  • Native addon availability, source path, and fallback reason
Run sdl-mcp doctor to validate your config file and check environment health, including registered resolvers, call-edge metadata schema support, and minCallConfidence policy status.

Build docs developers (and LLMs) love