@yawlabs/ctxlint 0.3.0 → 0.5.0
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 +138 -8
- package/dist/chunk-FHTSMC5D.js +2550 -0
- package/dist/cli-7IBRPDA6.js +448 -0
- package/dist/index.js +5 -1911
- package/dist/mcp/server.js +1160 -102
- package/dist/server-IFZ3VEK3.js +247 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
# ctxlint
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@yawlabs/ctxlint)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://github.com/YawLabs/ctxlint/stargazers)
|
|
6
|
+
[](https://github.com/YawLabs/ctxlint/actions/workflows/ci.yml)
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
**Lint your AI agent context files and MCP server configs against your actual codebase.** Context linting + MCP config linting. 21+ context formats, 8 MCP clients, auto-fix. Works as a CLI, CI step, pre-commit hook, or MCP server.
|
|
9
|
+
|
|
10
|
+
Your `CLAUDE.md` is lying to your agent. Your `.mcp.json` has a hardcoded API key. ctxlint catches both.
|
|
11
|
+
|
|
12
|
+
## Why ctxlint?
|
|
13
|
+
|
|
14
|
+
Context files rot fast. You rename a file, change a build script, or switch from Jest to Vitest — and your `CLAUDE.md` still says the old thing. Your agent follows those instructions faithfully, then fails.
|
|
15
|
+
|
|
16
|
+
- **Catches real problems** — broken paths, wrong commands, stale references, contradictions across files
|
|
17
|
+
- **Smart suggestions** — detects git renames and fuzzy-matches to suggest the right path
|
|
18
|
+
- **Auto-fix** — `--fix` rewrites broken paths automatically using git history
|
|
19
|
+
- **Token-aware** — shows how much context window your files consume and flags redundant content
|
|
20
|
+
- **Every AI tool** — supports Claude Code, Cursor, Copilot, Windsurf, Gemini, Cline, Aider, and 14 more
|
|
21
|
+
- **Multiple outputs** — text, JSON, and SARIF (GitHub Code Scanning)
|
|
22
|
+
- **MCP server** — 4 tools for IDE/agent integration with tool annotations for auto-approval
|
|
6
23
|
|
|
7
24
|
## Install
|
|
8
25
|
|
|
@@ -49,6 +66,75 @@ npx @yawlabs/ctxlint
|
|
|
49
66
|
| `.rules` | Zed |
|
|
50
67
|
| `replit.md` | Replit |
|
|
51
68
|
|
|
69
|
+
## MCP Server Config Linting
|
|
70
|
+
|
|
71
|
+
ctxlint also lints MCP server configuration files — the JSON configs that tell AI clients which tools to connect to. These are context interfaces too: they shape what your agent can do.
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Lint context files + MCP configs
|
|
75
|
+
npx @yawlabs/ctxlint --mcp
|
|
76
|
+
|
|
77
|
+
# Lint only MCP configs
|
|
78
|
+
npx @yawlabs/ctxlint --mcp-only
|
|
79
|
+
|
|
80
|
+
# Include global/user-level configs (Claude Desktop, Cursor, Windsurf, etc.)
|
|
81
|
+
npx @yawlabs/ctxlint --mcp-global
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### What MCP config files are scanned
|
|
85
|
+
|
|
86
|
+
| File | Client |
|
|
87
|
+
|------|--------|
|
|
88
|
+
| `.mcp.json` | Claude Code (universal project config) |
|
|
89
|
+
| `.cursor/mcp.json` | Cursor |
|
|
90
|
+
| `.vscode/mcp.json` | VS Code / GitHub Copilot |
|
|
91
|
+
| `.amazonq/mcp.json` | Amazon Q Developer |
|
|
92
|
+
| `.continue/mcpServers/*.json` | Continue |
|
|
93
|
+
|
|
94
|
+
With `--mcp-global`, also scans Claude Desktop, Cursor, Windsurf, Cline, and Amazon Q global configs.
|
|
95
|
+
|
|
96
|
+
### What MCP config checks catch
|
|
97
|
+
|
|
98
|
+
| Check | What it finds |
|
|
99
|
+
|-------|--------------|
|
|
100
|
+
| **Schema** | Invalid JSON, wrong root key (`servers` vs `mcpServers`), missing required fields |
|
|
101
|
+
| **Security** | Hardcoded API keys and Bearer tokens in git-tracked config files |
|
|
102
|
+
| **Commands** | Missing `cmd /c` wrapper for npx on Windows, broken file paths in args |
|
|
103
|
+
| **Deprecated** | SSE transport usage (deprecated March 2025, use Streamable HTTP) |
|
|
104
|
+
| **Env vars** | Wrong env var syntax for the client (`${VAR}` vs `${env:VAR}` vs `${{ secrets.VAR }}`) |
|
|
105
|
+
| **URLs** | Malformed URLs, localhost in project configs, missing path component |
|
|
106
|
+
| **Consistency** | Same server configured differently across client configs |
|
|
107
|
+
| **Redundancy** | Disabled servers, identical configs at multiple scopes |
|
|
108
|
+
|
|
109
|
+
### Example MCP config output
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
MCP Configs
|
|
113
|
+
.mcp.json
|
|
114
|
+
✗ mcp-security Server "api": hardcoded Bearer token in a git-tracked file
|
|
115
|
+
✗ mcp-deprecated Server "old-svc": SSE transport is deprecated — use "http"
|
|
116
|
+
✓ mcp-schema
|
|
117
|
+
✓ mcp-commands
|
|
118
|
+
.cursor/mcp.json
|
|
119
|
+
✗ mcp-env Server "api": Cursor uses ${env:VAR}, not ${VAR}
|
|
120
|
+
✓ mcp-schema
|
|
121
|
+
.vscode/mcp.json
|
|
122
|
+
✗ mcp-schema .vscode/mcp.json must use "servers" as root key, not "mcpServers"
|
|
123
|
+
|
|
124
|
+
Cross-file
|
|
125
|
+
⚠ Server "api" is configured differently in .mcp.json and .cursor/mcp.json
|
|
126
|
+
ℹ Server "db" is in .mcp.json but missing from .cursor/mcp.json
|
|
127
|
+
|
|
128
|
+
Summary: 3 errors, 2 warnings, 1 info
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### MCP Config Linting Specification
|
|
132
|
+
|
|
133
|
+
The full specification for MCP config linting rules, the cross-client config landscape, and a machine-readable rule catalog are published as open specifications:
|
|
134
|
+
|
|
135
|
+
- **[`MCP_CONFIG_LINT_SPEC.md`](./MCP_CONFIG_LINT_SPEC.md)** — 23 lint rules across 8 categories, the complete client/format reference, and implementation guidance. Tool-agnostic — any linter can implement it.
|
|
136
|
+
- **[`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.
|
|
137
|
+
|
|
52
138
|
## Example Output
|
|
53
139
|
|
|
54
140
|
```
|
|
@@ -92,6 +178,7 @@ Options:
|
|
|
92
178
|
--quiet Suppress all output (exit code only, for scripts)
|
|
93
179
|
--config <path> Path to config file (default: .ctxlintrc in project root)
|
|
94
180
|
--depth <n> Max subdirectory depth to scan (default: 2)
|
|
181
|
+
--mcp Start the MCP server instead of running the linter
|
|
95
182
|
-V, --version Output the version number
|
|
96
183
|
-h, --help Display help
|
|
97
184
|
|
|
@@ -175,14 +262,44 @@ CLI flags override config file settings. Use `--config <path>` to load a config
|
|
|
175
262
|
|
|
176
263
|
## Use as MCP Server
|
|
177
264
|
|
|
178
|
-
ctxlint ships with an MCP server that exposes four tools (`ctxlint_audit`, `ctxlint_validate_path`, `ctxlint_token_report`, `ctxlint_fix`)
|
|
265
|
+
ctxlint ships with an MCP server that exposes four tools (`ctxlint_audit`, `ctxlint_validate_path`, `ctxlint_token_report`, `ctxlint_fix`). All tools declare annotations so MCP clients can skip confirmation dialogs for read-only operations.
|
|
179
266
|
|
|
180
|
-
|
|
181
|
-
# Claude Code
|
|
182
|
-
claude mcp add ctxlint -- node node_modules/@yawlabs/ctxlint/dist/mcp/server.js
|
|
267
|
+
### With `.mcp.json` (Cursor, Windsurf, and other MCP clients)
|
|
183
268
|
|
|
184
|
-
|
|
185
|
-
|
|
269
|
+
Create `.mcp.json` in your project root:
|
|
270
|
+
|
|
271
|
+
macOS / Linux / WSL:
|
|
272
|
+
|
|
273
|
+
```json
|
|
274
|
+
{
|
|
275
|
+
"mcpServers": {
|
|
276
|
+
"ctxlint": {
|
|
277
|
+
"command": "npx",
|
|
278
|
+
"args": ["-y", "@yawlabs/ctxlint", "--mcp"]
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Windows:
|
|
285
|
+
|
|
286
|
+
```json
|
|
287
|
+
{
|
|
288
|
+
"mcpServers": {
|
|
289
|
+
"ctxlint": {
|
|
290
|
+
"command": "cmd",
|
|
291
|
+
"args": ["/c", "npx", "-y", "@yawlabs/ctxlint", "--mcp"]
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
> **Tip:** This file is safe to commit — it contains no secrets.
|
|
298
|
+
|
|
299
|
+
### With Claude Code
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
claude mcp add ctxlint -- npx -y @yawlabs/ctxlint --mcp
|
|
186
303
|
```
|
|
187
304
|
|
|
188
305
|
## JSON Output
|
|
@@ -193,6 +310,19 @@ npx @yawlabs/ctxlint --format json
|
|
|
193
310
|
|
|
194
311
|
Returns structured JSON with all file results, issues, and summary — useful for building integrations or dashboards.
|
|
195
312
|
|
|
313
|
+
## Specifications
|
|
314
|
+
|
|
315
|
+
ctxlint is the reference implementation of two open specifications for linting AI agent interfaces. These specs are tool-agnostic — any linter, IDE extension, or CI system can implement them.
|
|
316
|
+
|
|
317
|
+
| Spec | What it covers |
|
|
318
|
+
|------|---------------|
|
|
319
|
+
| **[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. |
|
|
320
|
+
| **[MCP Config Linting Spec](./MCP_CONFIG_LINT_SPEC.md)** | 23 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. |
|
|
321
|
+
|
|
322
|
+
Both specs include machine-readable rule catalogs for programmatic consumption:
|
|
323
|
+
- [`context-lint-rules.json`](./context-lint-rules.json) — context file rules and 16 supported format definitions
|
|
324
|
+
- [`mcp-config-lint-rules.json`](./mcp-config-lint-rules.json) — MCP config rules and 8 client definitions
|
|
325
|
+
|
|
196
326
|
## Also By Yaw Labs
|
|
197
327
|
|
|
198
328
|
- [Yaw](https://yaw.sh) — The AI-native terminal
|