Documentationv0.2.0 / schema 1.1

Architecture

How a validated MCP call becomes cached, clustered diagnostics while local engines remain authoritative.

Signalint is a local stdio MCP server. Adapters are the only modules that invoke diagnostic engines; every layer above them operates on normalized issue objects. The implementation is static and local: no cloud service is required.

MCP clientCalls a strict tool contract over stdio.
MCP serverValidates arguments, loads configuration, coordinates checks, and serializes schema 1.1 responses.
AdaptersOxlint, tsc, and Biome subprocess boundaries with timeouts and output ceilings.
CacheSQLite file results and whole-program state, keyed by content, config, Signalint version, and engine version.
ClustersRule-first grouping, priority assignment, distinct samples, and response truncation.
Session memoryLoop signatures plus bounded, rotated metrics history.

check_files data flow

  1. The server validates the tool object through strict Zod schemas.
  2. Requested paths are resolved against the project root and checked again after symlink canonicalization.
  3. Ignore globs and unconditional node_modules exclusion remove out-of-scope paths.
  4. Signalint reads snapshots and computes engine configuration hashes.
  5. File-local cache hits are reused; Oxlint and optional Biome receive only misses.
  6. tsc is skipped only when supplied TypeScript-relevant snapshots still match the latest whole-program result.
  7. Enabled engines settle independently, so one failure does not discard another engine's diagnostics.
  8. Issues are normalized, filtered, clustered, sorted with priority 1 first, and limited to ten clusters by default.
  9. Loop state and metrics are recorded before the JSON response is returned.

Engine invocation strategy

Oxlint and Biome

These engines are file-local. A check_files call hashes each file, reuses SQLite entries on a complete key match, and sends only cache misses to the adapter.

TypeScript

tsc is whole-program. Supplied file hashes decide whether a run is necessary, but files are never passed as compiler roots. A normal root config uses --project with incremental state. A solution-style root containing references uses --build, so referenced composite projects are traversed.

Storage bounds

The SQLite cache refreshes timestamps on read and evicts least-recently-used rows above 10,000 entries. Session startup replays only a bounded recent tail; writes rotate the JSONL file to a .1 backup at its size limit. Stats include both retained files.

Trust boundary

MCP arguments are treated as untrusted because a model can be prompt-injected by project content. Absolute, escaping, leading-dash, and NUL-containing paths are rejected, argument arrays are capped, and adapters spawn resolved binaries without a shell.

Read the full current implementation overview in ARCHITECTURE.md and the threat model in SECURITY.md.