Atlas / MCP servers / yawlabs / ctxlint

ctxlintBLOCK

mcp/yawlabs/ctxlint

Lint your AI agent context files (CLAUDE.md, AGENTS.md, etc.) against your codebase

Verdict
BLOCK
Grade
F
Trust score
58 /100
Exposed tools
7 6r · 1w · 0d
Transport
stdio
License
MIT
Stars
11
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

[](https://yaw.sh/mcp/install?name=ctxlint&command=npx&args=-y%2C%40yawlabs%2Fctxlint%2Cserve&description=Lint%20AI%20agent%20context%20files%20and%20MCP%20configs%20against%20your%20codebase&source=https%3A%2F%2Fgithub.com%2FYawLabs%2Fctxlint)

One click adds this to your local Yaw MCP config so it's available in every Yaw Terminal session. Or install manually below.

[](https://www.npmjs.com/package/@yawlabs/ctxlint) [](https://opensource.org/licenses/MIT) [](https://github.com/YawLabs/ctxlint/stargazers) [](https://github.com/YawLabs/mcp-compliance)

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.

Your CLAUDE.md is lying to your agent. Your .mcp.json has a hardcoded API key. ctxlint catches both.

Why ctxlint?

Every AI coding tool ships a context file: CLAUDE.md, .cursorrules, AGENTS.md, .mcp.json. These files are the single most important interface between you and your agent — they tell it what to build, how to test, where things live.

But 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 stale instructions faithfully, then fails. You lose 10 minutes debugging what turns out to be a wrong path in line 12 of a markdown file.

Multiply that across a team with 5 context files, 3 MCP configs, and 2 people who touched the build system last week — and you

Read from source at commit 39c04b8fa9f2OBSERVED · 2026-10-12
Advertisement
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code (npm)
claude mcp add ctxlint -- npx -y @yawlabs/[email protected]
03

Exposed tools (7)

6 read · 1 write · 0 destructive.

ToolRiskDescription
ctxlint_auditreadAudit AI agent context files (CLAUDE.md, AGENTS.md, etc.) in the project. Checks for stale references, invalid commands, redundant content, contradictions, frontmatter issues, and token waste. Scoped to context-file checks only; MCP-config and session-level checks are exposed as separate tools.
ctxlint_fixwriteRun the linter with --fix mode to auto-correct broken file paths in context files using git history and fuzzy matching. Returns a summary of what was fixed. Pass dryRun: true to preview what would be fixed without writing any files.
ctxlint_mcp_auditreadLint MCP server configuration files in a project. Checks for schema errors, hardcoded secrets, deprecated transports, wrong env var syntax, URL issues, and cross-client inconsistencies.
ctxlint_session_auditread
ctxlint_skill_auditreadAudit agent skill and subagent definitions (~/.claude/skills/*/SKILL.md, ~/.claude/agents/*.md). Checks for frontmatter problems, broken file references, trigger collisions, orphaned skill directories, and dead tool restrictions.
ctxlint_token_reportreadGet a token count breakdown for all context files in the project. Shows per-file and aggregate token usage, plus estimated waste from redundant content.
ctxlint_validate_pathreadCheck if a file path referenced in a context file actually exists in the project. Returns the file status and suggests corrections if the path is invalid.
04

Trust audit

BLOCKgrade F · trust 58/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
none-observed
Network
declared (4 observation(s))
Shell
none-observed
Dependencies
not all pinned
Secrets in source
found

Findings (25)

HIGHPrivilege escalation / persistence · priv.escalate · CWE-269, CWE-250
src/core/checks/cli-subcommands.ts:363
const DELEGATORS = new Set(['npx', 'bunx', 'sudo', 'time']);
Why it matters. asks for elevated privileges
HIGHPrivilege escalation / persistence · priv.escalate · CWE-269, CWE-250
src/core/checks/exit-status.ts:59
const WRAPPER_PATTERN = /^(npx|bunx|sudo|time|command|nice)\b/;
Why it matters. asks for elevated privileges
MEDIUMHard-coded secrets · secret.anthropic · CWE-798, CWE-321
src/core/checks/__tests__/content-secrets.test.ts:77
const file = makeFile('Anthropic: sk-ant-api03-AbCdEfGhIjKlMnOpQrStUv\n');
MEDIUMHard-coded secrets · secret.anthropic · CWE-798, CWE-321
src/core/checks/__tests__/content-secrets.test.ts:352
const file = makeFile('Key: sk-ant-api03-AbCdEfGhIjKlMnOpQrStUv\n');
MEDIUMHard-coded secrets · secret.anthropic · CWE-798, CWE-321
src/core/checks/mcp/__tests__/security.test.ts:81
ANTHROPIC: 'sk-ant-api03-abcdefghijklmnopqrstuvwxyz12345678',
MEDIUMHard-coded secrets · secret.aws · CWE-798, CWE-321
src/core/checks/__tests__/content-secrets.test.ts:43
const file = makeFile('See AKIAIOSFODNN7ZZZABCD for prod.\n');
MEDIUMHard-coded secrets · secret.aws · CWE-798, CWE-321
src/core/checks/__tests__/content-secrets.test.ts:220
const file = makeFile('if retries < max then key AKIAIOSFODNN7ZZZABCD and timeout > 30\n');
MEDIUMHard-coded secrets · secret.aws · CWE-798, CWE-321
src/core/checks/__tests__/content-secrets.test.ts:242
const file = makeFile('Set it to <my AKIAIOSFODNN7ZZZABCD value goes here>\n');
MEDIUMHard-coded secrets · secret.aws · CWE-798, CWE-321
src/core/checks/__tests__/content-secrets.test.ts:250
const realLooking = 'AKIAIOSFODNN7QQQABCD';
MEDIUMHard-coded secrets · secret.aws · CWE-798, CWE-321
src/core/checks/__tests__/content-secrets.test.ts:277
const content = ['Here is an illustration:', '```text', 'AKIAIOSFODNN7EXAMPL9', '```', ''].join(
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
src/core/checks/mcp/__tests__/security.test.ts:380
SECRET: 'aVeryLongBase64EncodedStringThatLooksLikeASecret123456',
MEDIUMHard-coded secrets · secret.github · CWE-798, CWE-321
fixtures/mcp-configs/hardcoded-secrets/.mcp.json:15
"GITHUB_TOKEN": "ghp_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghij",
MEDIUMHard-coded secrets · secret.github · CWE-798, CWE-321
src/core/__tests__/mcp-parser.test.ts:215
env: { GITHUB_TOKEN: 'ghp_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghij', PORT: 3000 },
MEDIUMHard-coded secrets · secret.github · CWE-798, CWE-321
src/core/__tests__/mcp-parser.test.ts:222
GITHUB_TOKEN: 'ghp_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghij',
MEDIUMHard-coded secrets · secret.github · CWE-798, CWE-321
src/core/checks/__tests__/content-secrets.test.ts:55
const file = makeFile('Token: ghp_abcdefghijklmnopqrstuvwxyz0123456789\n');
MEDIUMHard-coded secrets · secret.github · CWE-798, CWE-321
src/core/checks/__tests__/content-secrets.test.ts:142
const file = makeFile('Set token to <ghp_yourtokenherewithenoughchars1234567>\n');
MEDIUMHard-coded secrets · secret.private_key · CWE-798, CWE-321
src/core/checks/__tests__/content-secrets.test.ts:115
const file = makeFile('-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIB...\n');
MEDIUMHard-coded secrets · secret.private_key · CWE-798, CWE-321
src/core/checks/__tests__/content-secrets.test.ts:121
const file = makeFile('-----BEGIN OPENSSH PRIVATE KEY-----\n');
MEDIUMHard-coded secrets · secret.private_key · CWE-798, CWE-321
src/core/checks/__tests__/content-secrets.test.ts:331
const content = ['```', '-----BEGIN RSA PRIVATE KEY-----', 'MIIEpAIB...', '```', ''].join('\n');
MEDIUMHard-coded secrets · secret.slack · CWE-798, CWE-321
src/core/checks/__tests__/content-secrets.test.ts:102
const file = makeFile('Slack: xoxb-1234567890-abcdefghijklm\n');
LOWInventory / provenance · inv.hidden_file · CWE-1104
.ctxlintrc
.ctxlintrc
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.pre-commit-hooks.yaml
.pre-commit-hooks.yaml
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.prettierignore
.prettierignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/__tests__/launcher.test.ts:59
return new Function(`${pieces}\nreturn runtimePlan;`)() as RuntimePlan;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/__tests__/launcher.test.ts:68
return new Function(`${pieces}\nreturn { pickNewest, floor: OAM_MIN };`)() as {
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table

Gates applied: no_behavioural_pass.

Audited 2026-10-12 · audit v0.4.1 · source sha 39c04b8fa9f2full audit observations/trust-audit/mcp-server/yawlabs__ctxlint.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-1239c04b8fa9f2BLOCKF58first audit
06

Questions

What is the @yawlabs/ctxlint MCP server?

Lint your AI agent context files (CLAUDE.md, AGENTS.md, etc.) against your codebase

What tools does @yawlabs/ctxlint expose?

7 in total: 6 read-only, 1 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.

Is @yawlabs/ctxlint safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (58/100) and found 2 critical or high issues in the source. Each one is listed on this page with the file and line it is on.

What credentials does @yawlabs/ctxlint need?

It reads GH_TOKEN and GITHUB_TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does @yawlabs/ctxlint run?

It speaks stdio, so it runs as a local process your client starts. It is published on npm as @yawlabs/ctxlint at 0.28.0.

How current is this page?

The grade is for one exact copy of the source (39c04b8fa9f2), read on 2026-10-12. The repository is watched and re-audited when it changes.

Advertisement