@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.
Files changed (3) hide show
  1. package/README.md +99 -57
  2. package/dist/index.js +428 -247
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  [![Release](https://github.com/YawLabs/ctxlint/actions/workflows/release.yml/badge.svg)](https://github.com/YawLabs/ctxlint/actions/workflows/release.yml)
8
8
  [![MCP Compliance](https://raw.githubusercontent.com/YawLabs/ctxlint/main/compliance-badge.svg)](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. 21+ context formats, 8 MCP clients, cross-project consistency, auto-fix. Works as a CLI, CI step, pre-commit hook, or MCP server.
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 14 more
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 | What it finds |
202
- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
203
- | **Missing secrets** | `gh secret set` ran on 2+ sibling repos but not this one |
204
- | **Diverged configs** | Shared config files (CI workflows, tsconfig, .prettierrc, etc.) with 20-90% line overlap — enough to be related, different enough to be drifting |
205
- | **Missing workflows** | GitHub Actions workflows in 2+ siblings but absent from this project |
206
- | **Stale memory** | Memory entries referencing file paths that no longer exist |
207
- | **Duplicate memory** | Near-duplicate memory entries across projects (>60% overlap) |
208
- | **Loop detection** | Agent stuck in a loop — 3+ consecutive identical commands, or cyclic A,B,A,B patterns |
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 Exit code 1 on any warning or error (for CI)
250
- --checks <list> Comma-separated checks to run (see below)
251
- --ignore <list> Comma-separated checks to skip
252
- --fix Auto-fix broken paths using git history and fuzzy matching
253
- --format <fmt> Output format: text, json, or sarif (default: text)
254
- --tokens Show token breakdown per file
255
- --verbose Show passing checks too
256
- --quiet Suppress all output except errors (exit code only)
257
- --config <path> Path to config file (default: .ctxlintrc in project root)
258
- --depth <n> Max subdirectory depth to scan (default: 2)
259
- --mcp Enable MCP config linting alongside context file checks
260
- --mcp-only Run only MCP config checks, skip context file checks
261
- --mcp-global Also scan user/global MCP config files (implies --mcp)
262
- --session Enable session audit checks (cross-project consistency)
263
- --session-only Run only session checks, skip context and MCP checks
264
- --mcp-server Start the MCP server (alias: `serve` subcommand)
265
- --watch Re-lint on context file changes
266
- -V, --version Output the version number
267
- -h, --help Display help
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` | Success — no issues, or issues below the strict threshold |
297
- | `1` | Strict mode caught at least one error or warning (`--strict` is set) |
298
- | `2` | Config error, invalid CLI option, or internal failure |
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 | Type | Default | Meaning |
386
- |---|---|---|---|
387
- | `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-*`. |
388
- | `ignore` | `string[]` | `[]` | Checks to skip, evaluated after `checks`. |
389
- | `strict` | `boolean` | `false` | Exit non-zero on any warning or error. |
390
- | `tokenThresholds` | `object` | see below | Per-file and cross-file token thresholds. |
391
- | `tokenThresholds.info` | `number` | `1000` | Per-file info threshold for `tokens/info`. |
392
- | `tokenThresholds.warning` | `number` | `3000` | Per-file warning threshold for `tokens/large`. |
393
- | `tokenThresholds.error` | `number` | `8000` | Per-file error threshold for `tokens/excessive`. |
394
- | `tokenThresholds.aggregate` | `number` | `5000` | Cross-file total threshold for `tokens/aggregate`. |
395
- | `tokenThresholds.tierBreakdown` | `number` | `1000` | Always-loaded file threshold for `tier-tokens/section-breakdown`. |
396
- | `tokenThresholds.tierAggregate` | `number` | `4000` | Combined always-loaded threshold for `tier-tokens/aggregate`. |
397
- | `contextFiles` | `string[]` | `[]` | Extra glob patterns to scan alongside the built-in list. |
398
- | `mcp` | `boolean` | `false` | Enable MCP config checks by default (same as `--mcp`). |
399
- | `mcpGlobal` | `boolean` | `false` | Also scan user/global MCP configs (same as `--mcp-global`). |
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