{
  "markdown": "# Signalint\n\n[![CI](https://github.com/TranQui004/signalint/actions/workflows/ci.yml/badge.svg)](https://github.com/TranQui004/signalint/actions/workflows/ci.yml)\n[![npm version](https://img.shields.io/npm/v/signalint-mcp.svg)](https://www.npmjs.com/package/signalint-mcp)\n[![M8ven Score](https://m8ven.ai/badge/mcp/tranqui004-signalint-1u4yke)](https://m8ven.ai/mcp/tranqui004-signalint-1u4yke)\n\nSignalint is a local MCP server for JavaScript and TypeScript diagnostics. It runs\nOxlint, TypeScript, and optionally Biome; caches unchanged checks; clusters repeated\nissues; and warns when the same diagnostic disappears and repeatedly returns.\nLoop history is restored from valid `.signalint/session.jsonl` entries when the MCP\nserver restarts; malformed or crash-truncated lines are skipped.\n\n**Listed on:**\n- [![TranQui004/signalint MCP server](https://glama.ai/mcp/servers/TranQui004/signalint/badges/score.svg)](https://glama.ai/mcp/servers/TranQui004/signalint)\n- [mcpservers.org](https://mcpservers.org/servers/tranqui004/signalint)\n- [![M8ven Score](https://m8ven.ai/badge/mcp/tranqui004-signalint-1u4yke)](https://m8ven.ai/mcp/tranqui004-signalint-1u4yke)\n- Official MCP Registry ([API listing](https://registry.modelcontextprotocol.io/v0.1/servers/io.github.TranQui004%2Fsignalint/versions/latest))\n\n## Diagnostic compression example\n\nWhen a coding agent requests diagnostics on a project, raw compiler and linter outputs quickly flood the context window with repetitive errors across multiple files. Signalint normalizes issues and clusters them by root cause before returning a bounded, priority-ranked response:\n\n### Raw diagnostics (40 issues across 10 files · 9,151 bytes)\n\n```json\n[\n  {\n    \"issueId\": \"ts-01\",\n    \"file\": \"src/file01.ts\",\n    \"line\": 10,\n    \"col\": 5,\n    \"engine\": \"tsc\",\n    \"rule\": \"TS2322\",\n    \"severity\": \"error\",\n    \"message\": \"Type 'string' is not assignable to type 'number' in fixture assignment 01.\",\n    \"fixable\": false\n  },\n  // ... 39 more raw normalized issues\n]\n```\n\n### Clustered response returned to agent (4 clusters · 1,233 bytes · 86.5% reduction)\n\n```json\n{\n  \"schemaVersion\": \"1.1\",\n  \"status\": \"issues_found\",\n  \"engines\": {\n    \"oxlint\": { \"status\": \"ok\" },\n    \"tsc\": { \"status\": \"ok\" },\n    \"biome\": { \"status\": \"disabled\" }\n  },\n  \"totalIssues\": 40,\n  \"clusters\": [\n    {\n      \"clusterId\": \"c1\",\n      \"rootCauseSummary\": \"10 TS2322 issues across 10 files\",\n      \"ruleIds\": [\"TS2322\"],\n      \"issueCount\": 10,\n      \"fileCount\": 10,\n      \"priority\": 1,\n      \"suggestedAction\": \"Review the shared cause of TS2322 across 10 files\",\n      \"sampleIssueIds\": [\"ts-01\", \"ts-02\"]\n    },\n    {\n      \"clusterId\": \"c2\",\n      \"rootCauseSummary\": \"10 no-unused-vars issues across 10 files\",\n      \"ruleIds\": [\"no-unused-vars\"],\n      \"issueCount\": 10,\n      \"fileCount\": 10,\n      \"priority\": 2,\n      \"suggestedAction\": \"Review the shared cause of no-unused-vars across 10 files\",\n      \"sampleIssueIds\": [\"unused-01\", \"unused-02\"]\n    },\n    {\n      \"clusterId\": \"c3\",\n      \"rootCauseSummary\": \"10 eqeqeq issues across 10 files\",\n      \"ruleIds\": [\"eqeqeq\"],\n      \"issueCount\": 10,\n      \"fileCount\": 10,\n      \"priority\": 5,\n      \"suggestedAction\": \"Apply structured fixes for eqeqeq across 10 files\",\n      \"sampleIssueIds\": [\"eqeqeq-01\", \"eqeqeq-02\"]\n    },\n    {\n      \"clusterId\": \"c4\",\n      \"rootCauseSummary\": \"10 prefer-const issues across 10 files\",\n      \"ruleIds\": [\"prefer-const\"],\n      \"issueCount\": 10,\n      \"fileCount\": 10,\n      \"priority\": 5,\n      \"suggestedAction\": \"Apply structured fixes for prefer-const across 10 files\",\n      \"sampleIssueIds\": [\"const-01\", \"const-02\"]\n    }\n  ],\n  \"truncated\": false,\n  \"loopWarning\": null\n}\n```\n\nThe agent receives a concise summary with priority-ordered clusters and sample issue IDs. When deeper detail is needed for a specific cluster or issue, the agent calls `get_issue_detail` without re-running the whole-project scan.\n\n## Requirements\n\n- Node.js 20.19 or later in the Node 20 line, or Node.js 22.12 or later\n- A JavaScript or TypeScript project; TypeScript checks require a `tsconfig.json`\n- pnpm 11.9.0 for source development\n\n## Install\n\nInstall Signalint in the project it should check:\n\n```sh\nnpm install --save-dev signalint-mcp\n```\n\nRun the setup command from that project root. It detects TypeScript, Oxlint, and\nBiome configuration, writes `signalint.config.json`, and offers to update a nearby\nClaude Code, Cursor, Codex CLI, or Antigravity MCP configuration:\n\n```sh\nnpx signalint-mcp init\n```\n\nIf no MCP client can be selected safely, the command prints exact configuration\nsnippets to copy. TypeScript is enabled only when a root `tsconfig.json` exists;\nBiome is enabled when its config exists; Oxlint is the fallback when no configured\nlinter is detected. To configure Signalint manually, create `signalint.config.json`:\n\n```json\n{\n  \"engines\": {\n    \"oxlint\": true,\n    \"tsc\": true,\n    \"biome\": false\n  },\n  \"ignore\": [\"node_modules/**\", \"dist/**\", \".signalint/**\"],\n  \"timeoutsMs\": {\n    \"oxlint\": 30000,\n    \"tsc\": 120000,\n    \"biome\": 30000\n  }\n}\n```\n\n## Claude Code setup\n\nRun this from the checked project. Project scope writes a shareable `.mcp.json`:\n\n```sh\nclaude mcp add --scope project signalint -- npx --no-install signalint-mcp\nclaude mcp get signalint\n```\n\nOn native Windows, wrap `npx` as required by Claude Code:\n\n```powershell\nclaude mcp add --scope project signalint -- cmd /c npx --no-install signalint-mcp\nclaude mcp get signalint\n```\n\nRestart Claude Code if it was already open. Ask it to call Signalint's `ping` tool,\nthen call `check_project` with `{ \"paths\": [\".\"] }`.\n\nSee the [Claude Code MCP documentation](https://docs.anthropic.com/en/docs/claude-code/mcp)\nfor scope and troubleshooting details.\n\n## Cursor setup\n\nCreate `.cursor/mcp.json` in the checked project:\n\n```json\n{\n  \"mcpServers\": {\n    \"signalint\": {\n      \"command\": \"npx\",\n      \"args\": [\"--no-install\", \"signalint-mcp\"]\n    }\n  }\n}\n```\n\nOn native Windows use `\"command\": \"cmd\"` and\n`\"args\": [\"/c\", \"npx\", \"--no-install\", \"signalint-mcp\"]`. Open Cursor's MCP\nsettings, enable `signalint`, and call `ping` followed by `check_project`.\n\nSee the [Cursor MCP documentation](https://docs.cursor.com/context/model-context-protocol)\nfor configuration locations and status controls.\n\n## Codex CLI setup\n\nThe ChatGPT desktop app, Codex CLI, and IDE extension share a single\nconfiguration file. The quick-add command writes to `~/.codex/config.toml`\n(global) automatically:\n\n```sh\ncodex mcp add signalint -- npx --no-install signalint-mcp\n```\n\nFor project-scoped configuration (trusted projects only), add to\n`.codex/config.toml` in the project root:\n\n```toml\n[mcp_servers.signalint]\ncommand = \"npx\"\nargs = [\"--no-install\", \"signalint-mcp\"]\n```\n\nOn native Windows, use `cmd` and pass `npx` as an argument:\n\n```toml\n[mcp_servers.signalint]\ncommand = \"cmd\"\nargs = [\"/c\", \"npx\", \"--no-install\", \"signalint-mcp\"]\n```\n\nSee the [Codex MCP documentation](https://developers.openai.com/codex/mcp)\nfor all configuration options including `cwd`, `env`, and per-tool approval\nsettings.\n\n## Setting up with Antigravity\n\nAntigravity uses its own MCP configuration file. The path that has been\nverified through dogfooding on Windows is:\n`%USERPROFILE%\\.gemini\\antigravity\\mcp_config.json`.\n\nThe `init` command can update this file after confirmation. The equivalent\nWindows configuration is:\n\n```json\n{\n  \"mcpServers\": {\n    \"signalint\": {\n      \"command\": \"cmd\",\n      \"args\": [\"/c\", \"npx\", \"--no-install\", \"signalint-mcp\"],\n      \"cwd\": \"<absolute-path-to-your-project>\"\n    }\n  }\n}\n```\n\nOn macOS or Linux, use `\"command\": \"npx\"` and\n`\"args\": [\"--no-install\", \"signalint-mcp\"]`. Restart or reconnect Antigravity\nafter updating the configuration.\n\n**Note on Antigravity product variants:** Antigravity has split into separate\nproducts (IDE, CLI, SDK). Each variant may use a different config path — the\nIDE path above is the one confirmed working; other variants may use\n`~/.gemini/config/mcp_config.json` or a project-scoped `.agents/mcp_config.json`.\nSee [antigravity.google/docs/mcp](https://antigravity.google/docs/mcp) for\nthe authoritative list per product.\n\n## Windows troubleshooting\n\nWindows `.cmd` shims created by `npm link` can expose a junction path to Node. If\n`signalint-mcp` ends with an initialize/EOF error or `signalint stats` exits with\ncode 0 but prints nothing, bypass the shim with the compiled entrypoint paths:\n\n```powershell\nnode C:\\absolute\\path\\to\\Signalint\\dist\\src\\index.js\nnode C:\\absolute\\path\\to\\Signalint\\dist\\src\\cli.js stats\n```\n\nCurrent builds canonicalize linked paths before deciding whether to start, but direct\nNode invocation remains the reliable fallback for older builds or unusual npm setups.\n\n## Configuration\n\n`engines.oxlint`, `engines.tsc`, and `engines.biome` are booleans. Defaults are\nOxlint and tsc enabled, Biome disabled. Omitted engine keys retain those defaults.\nUnknown keys and incorrectly typed values fail with a configuration error.\n\n`ignore` is an array of project-relative globs. Signalint supports `*`, `**`, and\n`?`, normalizes Windows separators, and excludes matching requested paths and\ndiagnostics. Because tsc is a whole-program engine, it still receives the complete\n`tsconfig.json` program when invoked; ignored TypeScript paths do not trigger an\nincremental `check_files` run and their diagnostics are removed from the response.\n\nEngine-native configuration remains in native files. The v1 cache hash recognizes\nroot `.oxlintrc`, `.oxlintrc.json`, `oxlint.json`, `tsconfig.json`, `biome.json`,\nand `biome.jsonc`. Changing one invalidates the related engine cache. Other valid\nsources—including `.oxlintrc.jsonc`, extended configs, and nested package configs—\nare not part of v1 cache hashing; clear `.signalint/` after changing one of them.\n\n`timeoutsMs` sets positive-integer subprocess deadlines in milliseconds. Defaults are\n30 seconds for Oxlint, 120 seconds for tsc, and 30 seconds for Biome. A timed-out\nengine and its child processes are terminated. In the schema 1.1 check response, that\nengine has `{ \"status\": \"error\", \"message\": \"tsc did not complete within 120s\" }`\nunder `engines`, while completed engines' diagnostics are preserved.\n\n## Known Limitations\n\n- Signalint supports JavaScript and TypeScript projects only.\n- The built-in engines are Oxlint, TypeScript, and Biome; v1 does not support\n  arbitrary custom engines.\n- Signalint reports whether an issue has a structured fix, but v1 does not apply\n  fixes.\n- Signalint is not a SAST or security scanner.\n- There is no IDE extension yet; integrations use MCP or the command-line client.\n- Loop detection is deliberately limited to lint, type, and test issue signatures;\n  it does not detect general agent-conversation loops.\n- The tsc adapter requires one `tsconfig.json` at the project root. Monorepos must\n  provide a solution-style root config using TypeScript Project References;\n  Signalint does not auto-discover independent package configs.\n- `check_files` treats only the files explicitly passed to that call as relevant to\n  TypeScript cache invalidation. If file A changes but is omitted while unchanged file\n  B is checked, and B depends on A, Signalint can reuse a stale tsc result. Include\n  every changed dependency file or run `check_project`; dependency-graph-based\n  invalidation is not implemented in v1.\n\n## MCP tools\n\n- `ping` checks that the local server is connected and returns `pong`.\n- `check_project` accepts optional `{ \"paths\": [\".\"] }` and returns clustered diagnostics.\n- `check_files` accepts `{ \"files\": [\"src/file.ts\"] }` and uses incremental caching.\n- `get_issue_detail` accepts exactly one `clusterId` or `issueId` from the latest\n  successful check and returns its full issues, or a `status: \"stale\"` response.\n- `get_loop_status` returns issue signatures currently flagged as oscillating.\n\nCache and session artifacts are written under `.signalint/` and should not be committed.\n\n## CLI and package smoke test\n\nRun the same project check without an MCP client:\n\n```sh\nnpx --no-install signalint check .\n```\n\nAfter MCP checks have accumulated in `.signalint/session.jsonl`, print the Phase 6\nmeasurement summary:\n\n```sh\nnpx --no-install signalint stats\n```\n\nThe report includes average normalized-raw-to-clustered JSON payload reduction,\nengine-file cache hit rate, average and maximum check latency, and the number of\ndistinct issue signatures that triggered loop warnings. An engine-file lookup counts\neach enabled engine separately, so one changed TypeScript file can miss once for\nOxlint and once for tsc. Latency covers handler work from MCP tool entry through\nengine/cache work, clustering, and loop evaluation; it excludes the telemetry append\nand stdio transport. Statistics include the active session log and its rotated `.1`\nbackup, with their retained overlap counted once. Clean checks with zero raw payload are excluded from the\nreduction average, and older checks with missing metrics remain counted without\ncontributing to the unavailable aggregate.\n\nThe CLI exits with code 1 when issues are found. Two flags support CI use:\n`--format github` prints one GitHub Actions annotation\n(`::error file=...,line=...,col=...::message` or `::warning ...`) per issue\ninstead of JSON, and `--fail-on-priority <N>` exits non-zero only if a\ncluster's priority is at or below `N` instead of on any issue found.\n\nTo exercise an actual MCP `check_project` call against the installed package,\nrun:\n\n```sh\nnode node_modules/signalint-mcp/examples/check-project.mjs .\n```\n\n## GitHub Actions\n\n`action.yml` at the repository root wraps `signalint check` as a composite\naction for CI. It installs Node, installs `signalint-mcp` from npm, and runs\nthe check with `--format github` so issues appear as inline annotations on\nthe pull request diff:\n\n```yaml\n- uses: TranQui004/signalint@main\n  with:\n    fail-on-priority: \"3\"\n```\n\n`fail-on-priority` defaults to `5`, which fails the job on any issue found,\nmatching `signalint check`'s default behavior without the flag. Lower values\nonly fail the job when a cluster is at least that urgent: priority 1 is an\nerror with no structured fix, and priority increases toward 5 as issues\nbecome more fixable or more systemic (see `scorePriority` in\n`src/cluster/clusterEngine.ts`).\n\n## Development\n\npnpm 11.9.0 is the canonical package manager for source development. The repository\ncommits `pnpm-lock.yaml`, declares pnpm in `package.json`, and uses pnpm in CI.\n\n```sh\npnpm install --frozen-lockfile\npnpm lint\npnpm typecheck\npnpm test\npnpm build\n```\n\nIf a global npm shim cannot find `npm-cli.js`, build directly with `node node_modules/typescript/bin/tsc -p tsconfig.json`.\n\nBefore preparing a release, use `npm pack --dry-run` and verify the packed tarball\nin a clean project. Publishing requires explicit release approval.\n\n## Security\n\nSee [SECURITY.md](SECURITY.md) for the current npm audit advisory, its evaluated\nruntime reachability, and the conditions that require reassessment.\n\n## Documentation\n\n- [Website](https://tranqui004.github.io/signalint-site) — overview, docs, and\n  live examples.\n- [ARCHITECTURE.md](ARCHITECTURE.md) — how the layers fit together and what each\n  module does.\n- [CONTRIBUTING.md](CONTRIBUTING.md) — development setup, verification, and pull\n  requests.\n- [AGENTS.md](AGENTS.md) — coding standards for this repository.\n- [SECURITY.md](SECURITY.md) — threat model, trust boundaries, and audit status.\n- [CHANGELOG.md](CHANGELOG.md) — notable changes by release.\n- [docs/history/](docs/history/) — original build plan and pre-launch audit trail.\n\n## License\n\nSignalint is available under the [MIT License](LICENSE).\n",
  "bytes": 15680,
  "sha": "9df6ea0d74758fcd40a4ae1a13f0e01e242e6c8f04ef493fc62ec50bbfa92ec8",
  "repo_slug": "tranqui004/signalint",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_tranqui004_signalint_6088b1d6/readme"
}