@yawlabs/ctxlint 0.9.19 → 0.9.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -57
- package/dist/index.js +428 -247
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](https://github.com/YawLabs/ctxlint/actions/workflows/release.yml)
|
|
8
8
|
[](https://github.com/YawLabs/mcp-compliance)
|
|
9
9
|
|
|
10
|
-
**Lint your AI agent context files, MCP server configs, and session data against your actual codebase.** Context linting + MCP config linting + session auditing.
|
|
10
|
+
**Lint your AI agent context files, MCP server configs, and session data against your actual codebase.** Context linting + MCP config linting + session auditing. 16 AI tools, 8 MCP clients, cross-project consistency, auto-fix. Works as a CLI, CI step, pre-commit hook, or MCP server.
|
|
11
11
|
|
|
12
12
|
Your `CLAUDE.md` is lying to your agent. Your `.mcp.json` has a hardcoded API key. ctxlint catches both.
|
|
13
13
|
|
|
@@ -26,7 +26,7 @@ ctxlint is a linter purpose-built for this. It reads your context files, cross-r
|
|
|
26
26
|
- **Smart suggestions** — detects git renames and fuzzy-matches to suggest the right path
|
|
27
27
|
- **Auto-fix** — `--fix` rewrites broken paths automatically using git history
|
|
28
28
|
- **Token-aware** — shows how much context window your files consume and flags redundant content
|
|
29
|
-
- **Every AI tool** — supports Claude Code, Cursor, Copilot, Windsurf, Gemini, Cline, Aider, and
|
|
29
|
+
- **Every AI tool** — supports Claude Code, Cursor, Copilot, Windsurf, Gemini, Cline, Aider, and 9 more
|
|
30
30
|
- **Multiple outputs** — text, JSON, and SARIF (GitHub Code Scanning)
|
|
31
31
|
- **MCP server** — 7 tools for IDE/agent integration with tool annotations for auto-approval
|
|
32
32
|
- **Watch mode** — `--watch` re-lints automatically when context files change
|
|
@@ -175,6 +175,34 @@ The full specification for MCP config linting rules, the cross-client config lan
|
|
|
175
175
|
- **[`MCP_CONFIG_LINT_SPEC.md`](./MCP_CONFIG_LINT_SPEC.md)** — 43 lint rules across 8 categories, the complete client/format reference, and implementation guidance. Tool-agnostic — any linter can implement it.
|
|
176
176
|
- **[`mcp-config-lint-rules.json`](./mcp-config-lint-rules.json)** — Machine-readable rule catalog for programmatic consumption by AI agents, CI systems, and other tools.
|
|
177
177
|
|
|
178
|
+
## mcph Config Linting
|
|
179
|
+
|
|
180
|
+
ctxlint also lints `.mcph.json` — the config file read by the [`@yawlabs/mcph`](https://github.com/YawLabs/mcph) CLI, which orchestrates MCP servers via the mcp.hosting registry. Distinct from `.mcp.json` (different schema, different threat model). Applies across the user-global (`~/.mcph.json`), per-project (`.mcph.json`), and machine-local (`.mcph.local.json`) scope cascade.
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
# Lint context files + .mcph.json
|
|
184
|
+
npx @yawlabs/ctxlint --mcph
|
|
185
|
+
|
|
186
|
+
# Lint only .mcph.json
|
|
187
|
+
npx @yawlabs/ctxlint --mcph-only
|
|
188
|
+
|
|
189
|
+
# Include the user-global ~/.mcph.json
|
|
190
|
+
npx @yawlabs/ctxlint --mcph-global
|
|
191
|
+
|
|
192
|
+
# Treat any token in any .mcph.json as an error (env-var-only posture)
|
|
193
|
+
npx @yawlabs/ctxlint --mcph --mcph-strict-env-token
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### What mcph config checks catch
|
|
197
|
+
|
|
198
|
+
| Check | What it finds |
|
|
199
|
+
| --------------------------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
200
|
+
| **mcph-token-security** | mcp.hosting PAT (`mcp_pat_*`) leaks, malformed tokens, and prefers env-var (`MCPH_TOKEN`) over file-stored tokens |
|
|
201
|
+
| **mcph-apibase** | Invalid `apiBase` URLs and plaintext HTTP to public hosts (private hosts like `localhost` / RFC 1918 are exempt) |
|
|
202
|
+
| **mcph-schema-conformance** | Unknown / typo'd fields and stale `version` numbers vs the current `mcph.config.v1.json` schema |
|
|
203
|
+
| **mcph-lists** | Conflicts (entries in both `servers` allow-list and `blocked` deny-list) and duplicates within either list |
|
|
204
|
+
| **mcph-gitignore** | `.mcph.local.json` not covered by `.gitignore` — machine-local overrides exist precisely to stay machine-local |
|
|
205
|
+
|
|
178
206
|
## Session Linting
|
|
179
207
|
|
|
180
208
|
ctxlint can audit AI agent session data — history files and memory entries — for cross-project consistency. Session checks compare your current project against sibling repos to catch drift and missing setup.
|
|
@@ -198,15 +226,15 @@ Session checks are **opt-in** because they access files outside the project dire
|
|
|
198
226
|
|
|
199
227
|
### What session checks catch
|
|
200
228
|
|
|
201
|
-
| Check
|
|
202
|
-
|
|
|
203
|
-
| **Missing secrets**
|
|
204
|
-
| **Diverged configs**
|
|
205
|
-
| **Missing workflows**
|
|
206
|
-
| **Stale memory**
|
|
207
|
-
| **Duplicate memory**
|
|
208
|
-
| **Loop detection**
|
|
209
|
-
| **Memory index overflow** | `MEMORY.md` exceeds Claude Code's documented 200-line / 25KB session-load cap, so entries past the cap are invisible to the agent
|
|
229
|
+
| Check | What it finds |
|
|
230
|
+
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
231
|
+
| **Missing secrets** | `gh secret set` ran on 2+ sibling repos but not this one |
|
|
232
|
+
| **Diverged configs** | Shared config files (CI workflows, tsconfig, .prettierrc, etc.) with 20-90% line overlap — enough to be related, different enough to be drifting |
|
|
233
|
+
| **Missing workflows** | GitHub Actions workflows in 2+ siblings but absent from this project |
|
|
234
|
+
| **Stale memory** | Memory entries referencing file paths that no longer exist |
|
|
235
|
+
| **Duplicate memory** | Near-duplicate memory entries across projects (>60% overlap) |
|
|
236
|
+
| **Loop detection** | Agent stuck in a loop — 3+ consecutive identical commands, or cyclic A,B,A,B patterns |
|
|
237
|
+
| **Memory index overflow** | `MEMORY.md` exceeds Claude Code's documented 200-line / 25KB session-load cap, so entries past the cap are invisible to the agent |
|
|
210
238
|
|
|
211
239
|
### Session Linting Specification
|
|
212
240
|
|
|
@@ -246,33 +274,40 @@ Arguments:
|
|
|
246
274
|
path Project directory to scan (default: ".")
|
|
247
275
|
|
|
248
276
|
Options:
|
|
249
|
-
--strict
|
|
250
|
-
--checks <list>
|
|
251
|
-
--ignore <list>
|
|
252
|
-
--fix
|
|
253
|
-
--
|
|
254
|
-
--
|
|
255
|
-
--
|
|
256
|
-
--
|
|
257
|
-
--
|
|
258
|
-
--
|
|
259
|
-
--
|
|
260
|
-
--
|
|
261
|
-
--
|
|
262
|
-
--
|
|
263
|
-
--
|
|
264
|
-
--mcp-
|
|
265
|
-
--
|
|
266
|
-
-
|
|
267
|
-
-
|
|
277
|
+
--strict Exit code 1 on any warning or error (for CI)
|
|
278
|
+
--checks <list> Comma-separated checks to run (see below)
|
|
279
|
+
--ignore <list> Comma-separated checks to skip
|
|
280
|
+
--fix Auto-fix broken paths using git history and fuzzy matching
|
|
281
|
+
--fix-dry-run Preview --fix changes without writing
|
|
282
|
+
--yes Skip interactive confirmation prompts (required for --fix in TTY)
|
|
283
|
+
--follow-symlinks Allow --fix to write through symlinks (default: skip)
|
|
284
|
+
--format <fmt> Output format: text, json, or sarif (default: text)
|
|
285
|
+
--tokens Show token breakdown per file
|
|
286
|
+
--verbose Show passing checks too
|
|
287
|
+
--quiet Suppress all output except errors (exit code only)
|
|
288
|
+
--config <path> Path to config file (default: .ctxlintrc in project root)
|
|
289
|
+
--depth <n> Max subdirectory depth to scan (default: 2)
|
|
290
|
+
--mcp Enable MCP config linting alongside context file checks
|
|
291
|
+
--mcp-only Run only MCP config checks, skip context file checks
|
|
292
|
+
--mcp-global Also scan user/global MCP config files (implies --mcp)
|
|
293
|
+
--mcph Enable .mcph.json (mcp.hosting CLI config) linting
|
|
294
|
+
--mcph-only Run only mcph config checks
|
|
295
|
+
--mcph-global Also scan ~/.mcph.json (implies --mcph)
|
|
296
|
+
--mcph-strict-env-token Upgrade mcph-config/prefer-env-token from warning to error
|
|
297
|
+
--session Enable session audit checks (cross-project consistency)
|
|
298
|
+
--session-only Run only session checks, skip context and MCP checks
|
|
299
|
+
--mcp-server Start the MCP server (alias: `serve` subcommand)
|
|
300
|
+
--watch Re-lint on context file changes
|
|
301
|
+
-V, --version Output the version number
|
|
302
|
+
-h, --help Display help
|
|
268
303
|
|
|
269
304
|
Commands:
|
|
270
305
|
init Set up a git pre-commit hook
|
|
271
306
|
```
|
|
272
307
|
|
|
273
|
-
**Available checks:** `paths`, `commands`, `staleness`, `tokens`, `tier-tokens`, `redundancy`, `contradictions`, `frontmatter`, `ci-coverage`, `ci-secrets`, `mcp-schema`, `mcp-security`, `mcp-commands`, `mcp-deprecated`, `mcp-env`, `mcp-urls`, `mcp-consistency`, `mcp-redundancy`, `session-missing-secret`, `session-diverged-file`, `session-missing-workflow`, `session-stale-memory`, `session-duplicate-memory`, `session-loop-detection`, `session-memory-index-overflow`
|
|
308
|
+
**Available checks:** `paths`, `commands`, `staleness`, `tokens`, `tier-tokens`, `redundancy`, `contradictions`, `frontmatter`, `ci-coverage`, `ci-secrets`, `mcp-schema`, `mcp-security`, `mcp-commands`, `mcp-deprecated`, `mcp-env`, `mcp-urls`, `mcp-consistency`, `mcp-redundancy`, `mcph-token-security`, `mcph-apibase`, `mcph-schema-conformance`, `mcph-lists`, `mcph-gitignore`, `session-missing-secret`, `session-diverged-file`, `session-missing-workflow`, `session-stale-memory`, `session-duplicate-memory`, `session-loop-detection`, `session-memory-index-overflow`
|
|
274
309
|
|
|
275
|
-
Passing any `mcp-*` check name implies `--mcp`. Passing any `session-*` check name implies `--session`.
|
|
310
|
+
Passing any `mcp-*` check name implies `--mcp`. Passing any `mcph-*` check name implies `--mcph`. Passing any `session-*` check name implies `--session`.
|
|
276
311
|
|
|
277
312
|
## Watch Mode
|
|
278
313
|
|
|
@@ -291,11 +326,11 @@ Re-lints automatically when any context file, MCP config, or `package.json` chan
|
|
|
291
326
|
|
|
292
327
|
### Exit Codes
|
|
293
328
|
|
|
294
|
-
| Code | Meaning
|
|
295
|
-
|
|
296
|
-
| `0`
|
|
297
|
-
| `1`
|
|
298
|
-
| `2`
|
|
329
|
+
| Code | Meaning |
|
|
330
|
+
| ---- | -------------------------------------------------------------------- |
|
|
331
|
+
| `0` | Success — no issues, or issues below the strict threshold |
|
|
332
|
+
| `1` | Strict mode caught at least one error or warning (`--strict` is set) |
|
|
333
|
+
| `2` | Config error, invalid CLI option, or internal failure |
|
|
299
334
|
|
|
300
335
|
In non-strict mode ctxlint always exits `0` — it's a reporting tool by default. Pass `--strict` to enforce in CI.
|
|
301
336
|
|
|
@@ -382,21 +417,28 @@ The `contextFiles` array adds custom file patterns to scan alongside the built-i
|
|
|
382
417
|
|
|
383
418
|
### Config Reference
|
|
384
419
|
|
|
385
|
-
| Field
|
|
386
|
-
|
|
387
|
-
| `checks`
|
|
388
|
-
| `ignore`
|
|
389
|
-
| `strict`
|
|
390
|
-
| `tokenThresholds`
|
|
391
|
-
| `tokenThresholds.info`
|
|
392
|
-
| `tokenThresholds.warning`
|
|
393
|
-
| `tokenThresholds.error`
|
|
394
|
-
| `tokenThresholds.aggregate`
|
|
395
|
-
| `tokenThresholds.tierBreakdown` | `number`
|
|
396
|
-
| `tokenThresholds.tierAggregate` | `number`
|
|
397
|
-
| `contextFiles`
|
|
398
|
-
| `mcp`
|
|
399
|
-
| `
|
|
420
|
+
| Field | Type | Default | Meaning |
|
|
421
|
+
| ------------------------------- | ---------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
422
|
+
| `checks` | `string[]` | all checks | Checks to run. Check names include `paths`, `commands`, `tokens`, `tier-tokens`, `redundancy`, `contradictions`, `frontmatter`, `staleness`, `ci-coverage`, `ci-secrets`, plus any `mcp-*` / `session-*`. |
|
|
423
|
+
| `ignore` | `string[]` | `[]` | Checks to skip, evaluated after `checks`. |
|
|
424
|
+
| `strict` | `boolean` | `false` | Exit non-zero on any warning or error. |
|
|
425
|
+
| `tokenThresholds` | `object` | see below | Per-file and cross-file token thresholds. |
|
|
426
|
+
| `tokenThresholds.info` | `number` | `1000` | Per-file info threshold for `tokens/info`. |
|
|
427
|
+
| `tokenThresholds.warning` | `number` | `3000` | Per-file warning threshold for `tokens/large`. |
|
|
428
|
+
| `tokenThresholds.error` | `number` | `8000` | Per-file error threshold for `tokens/excessive`. |
|
|
429
|
+
| `tokenThresholds.aggregate` | `number` | `5000` | Cross-file total threshold for `tokens/aggregate`. |
|
|
430
|
+
| `tokenThresholds.tierBreakdown` | `number` | `1000` | Always-loaded file threshold for `tier-tokens/section-breakdown`. |
|
|
431
|
+
| `tokenThresholds.tierAggregate` | `number` | `4000` | Combined always-loaded threshold for `tier-tokens/aggregate`. |
|
|
432
|
+
| `contextFiles` | `string[]` | `[]` | Extra glob patterns to scan alongside the built-in list. |
|
|
433
|
+
| `mcp` | `boolean` | `false` | Enable MCP config checks by default (same as `--mcp`). |
|
|
434
|
+
| `mcpOnly` | `boolean` | `false` | Run only MCP config checks, skip context-file checks (same as `--mcp-only`). |
|
|
435
|
+
| `mcpGlobal` | `boolean` | `false` | Also scan user/global MCP configs (same as `--mcp-global`). |
|
|
436
|
+
| `mcph` | `boolean` | `false` | Enable `.mcph.json` (mcp.hosting CLI config) checks (same as `--mcph`). |
|
|
437
|
+
| `mcphOnly` | `boolean` | `false` | Run only mcph config checks, skip context-file checks (same as `--mcph-only`). |
|
|
438
|
+
| `mcphGlobal` | `boolean` | `false` | Also scan `~/.mcph.json` user-global config (same as `--mcph-global`). |
|
|
439
|
+
| `mcphStrictEnvToken` | `boolean` | `false` | Upgrade `mcph-config/prefer-env-token` from warning to error (same as `--mcph-strict-env-token`). |
|
|
440
|
+
| `session` | `boolean` | `false` | Enable session audit checks (cross-project consistency); same as `--session`. |
|
|
441
|
+
| `sessionOnly` | `boolean` | `false` | Run only session checks, skip context and MCP checks (same as `--session-only`). |
|
|
400
442
|
|
|
401
443
|
Config file resolution order: `.ctxlintrc` → `.ctxlintrc.json` in the project root. Use `--config <path>` to point elsewhere. CLI flags override config fields.
|
|
402
444
|
|
|
@@ -492,12 +534,12 @@ Returns structured JSON with all file results, issues, and summary — useful fo
|
|
|
492
534
|
|
|
493
535
|
ctxlint is the reference implementation of three open specifications for linting AI agent interfaces. These specs are tool-agnostic — any linter, IDE extension, or CI system can implement them.
|
|
494
536
|
|
|
495
|
-
| Spec | What it covers
|
|
496
|
-
| -------------------------------------------------------------- |
|
|
497
|
-
| **[AI Context File Linting Spec](./CONTEXT_LINT_SPEC.md)** | 19 rules for validating context files (CLAUDE.md, .cursorrules, AGENTS.md, etc.) across 17 clients. Covers file formats, frontmatter schemas, path/command validation, staleness, token budgets, redundancy, and contradictions.
|
|
498
|
-
| **[MCP Config Linting Spec](./MCP_CONFIG_LINT_SPEC.md)** | 43 rules for validating MCP server configs (.mcp.json, .cursor/mcp.json, .vscode/mcp.json, etc.) across 8 clients. Covers schema validation, hardcoded secrets, env var syntax, deprecated transports, and cross-file consistency.
|
|
537
|
+
| Spec | What it covers |
|
|
538
|
+
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
539
|
+
| **[AI Context File Linting Spec](./CONTEXT_LINT_SPEC.md)** | 19 rules for validating context files (CLAUDE.md, .cursorrules, AGENTS.md, etc.) across 17 clients. Covers file formats, frontmatter schemas, path/command validation, staleness, token budgets, redundancy, and contradictions. |
|
|
540
|
+
| **[MCP Config Linting Spec](./MCP_CONFIG_LINT_SPEC.md)** | 43 rules for validating MCP server configs (.mcp.json, .cursor/mcp.json, .vscode/mcp.json, etc.) across 8 clients. Covers schema validation, hardcoded secrets, env var syntax, deprecated transports, and cross-file consistency. |
|
|
499
541
|
| **mcph Config Linting** (`mcph-config-lint-rules.json`) | 10 rules for validating `.mcph.json` — the config file read by the `@yawlabs/mcph` CLI. Covers PAT format + leakage, env-var posture, plaintext API endpoints, schema drift, and allow/deny list semantics across the scope cascade. |
|
|
500
|
-
| **[Agent Session Linting Spec](./AGENT_SESSION_LINT_SPEC.md)** | 7 rules for auditing agent session data (history, memory) across 8 agents. Covers cross-project secret consistency, config drift, stale memory, and loop detection.
|
|
542
|
+
| **[Agent Session Linting Spec](./AGENT_SESSION_LINT_SPEC.md)** | 7 rules for auditing agent session data (history, memory) across 8 agents. Covers cross-project secret consistency, config drift, stale memory, and loop detection. |
|
|
501
543
|
|
|
502
544
|
All specs include machine-readable rule catalogs for programmatic consumption:
|
|
503
545
|
|