api-linter

api-linter is a skill for Claude Code from cyanheads/openstates-mcp-server. It costs 86 tokens per session (16,931 once invoked), scanned A, a copy of api-linter, Apache-2.0.

A rule reference for an MCP definition linter, a build-time checker for tool, resource, and prompt definitions. It explains each diagnostic, its severity, and how to fix it.

In plain words
What is it for?
Use it while fixing `bun run lint:mcp` or `bun run devcheck` results and when checking definitions programmatically with `validateDefinitions()`.
Why use it?
It makes lint errors and warnings understandable when the checker reports issues with names, schemas, formatting, or server metadata.

Skill for Claude Code

Written for Claude Code: shipped in a Claude Code plugin. Also seen: mentions CLAUDE.md; mentions Claude Code; mentions AGENTS.md.

Part of the openstates-mcp-server plugin — 33 skills, 1 MCP server shipped together

Good fit Use it while fixing bun run lint:mcp or bun run devcheck results and when checking definitions programmatically with validateDefinitions().

Compare 6 skills from other repositories ↓
Install with agentmods
npx agentmods add skills/cyanheads/openstates-mcp-server/api-linter
Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

Any agent
npx skills add cyanheads/openstates-mcp-server --skill api-linter
Clone the repo
git clone --depth 1 https://github.com/cyanheads/openstates-mcp-server

Made for: Claude Code.

Or install openstates-mcp-server, the plugin that ships this one along with the rest of its 33 skills, 1 MCP server.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for api-linter

README.md
[![agentmods](https://agentmods.dev/badge/skills/cyanheads/openstates-mcp-server/api-linter/github.svg)](https://agentmods.dev/skills/cyanheads/openstates-mcp-server/api-linter)
Your own site
<a href="https://agentmods.dev/skills/cyanheads/openstates-mcp-server/api-linter"><img src="https://agentmods.dev/badge/skills/cyanheads/openstates-mcp-server/api-linter/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for api-linter

Your own site · 80×15
<a href="https://agentmods.dev/skills/cyanheads/openstates-mcp-server/api-linter"><img src="https://agentmods.dev/badge/skills/cyanheads/openstates-mcp-server/api-linter.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 86 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 16,931 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin 100% copy Near-identical to another mod in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00086 $0.16931
Opus 5.5 $0.00034 $0.06772
Sonnet 5.5 $0.00017 $0.03386
Haiku 4.5 $0.00009 $0.01693

Measured 13d ago against content hash f37eb9148e64, method: parsed. Prices are Anthropic first-party input rates as of 2026-10-07, from the pricing page.

Security

Grade A, and why

api-linter scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 13d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

Origin

This is a copy

100% identical to api-linter — 21 lines differ, which has more behind it and is treated as the original. This page carries a canonical link to it rather than competing with it.

framework-skills/api-linter/SKILL.md · 1,144 lines

How it starts

The opening of the file, as written. The whole thing — 1,144 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Overview

The linter validates tool, resource, and prompt definitions against the MCP spec and framework conventions. It is build-time only — not invoked at server startup. It runs in two places:

Entry point When On failure
bun run lint:mcp Manual or CI Imports every definition file, prints errors + warnings, exits non-zero on errors. A file that fails to import is an error (definition-import-failed), never a skip.
bun run devcheck Pre-commit workflow Wraps lint:mcp alongside typecheck, format, bun audit, bun outdated.

Both surface the same LintReport from validateDefinitions() (exported from @cyanheads/mcp-ts-core/linter), plus two load errors the CLI raises itself, because validateDefinitions() only receives what already loaded: definition-import-failed and server-json-parse. Each diagnostic has a stable rule ID — that's the anchor you land on via the See: framework-skills/api-linter/SKILL.md#<rule> breadcrumb appended to every message.

Severity:

  • error — MUST-level spec violation; blocks devcheck.
  • warning — SHOULD-level or quality issue; logged but devcheck continues.

Imports (if you need to run the linter programmatically):

import { validateDefinitions } from '@cyanheads/mcp-ts-core/linter';
import type { LintReport, LintDiagnostic } from '@cyanheads/mcp-ts-core/linter';

const report = validateDefinitions({ tools, resources, prompts, serverJson, packageJson });
if (!report.passed) process.exit(1);

Rule index

Grouped by family. Jump to any rule ID via its anchor.

Family Rules Section
Definition definition-invalid, definition-import-failed Definition rules
Format parity format-parity, format-parity-threw, format-parity-walk-failed, format-parity-depth-limit Format parity
Schema schema-is-object, describe-on-fields, schema-serializable, schema-unsatisfiable, header-param-designation, schema-root-meta-discarded Schema rules
Portability schema-format-portability, schema-anyof-needs-type, schema-no-discriminator-keyword, schema-no-defs, schema-root-oneof-portability, schema-dialect-tag Portability rules
Names name-required, name-format, name-unique Name rules
Tools description-required, handler-required, auth-type, auth-scope-format, annotation-type, annotation-coherence, input-alias-conflict, meta-ui-type, meta-ui-resource-uri-required, meta-ui-resource-uri-scheme, app-tool-resource-pairing, canvas-consumer-missing Tool rules
Resources uri-template-required, uri-template-valid, resource-name-not-uri, template-params-align Resource rules
Landing landing-* (23 rules — shape, tagline, logo, links, repo, envExample, connectSnippets, theme) Landing config rules
Prompts generate-required Prompt rules
Handler body prefer-mcp-error-in-handler, prefer-error-factory, preserve-cause-on-rethrow, no-stringify-upstream-error Handler body rules
Error contract (structural) error-contract-type, error-contract-empty, error-contract-entry-type, error-contract-code-type, error-contract-code-unknown, error-contract-code-unknown-error, error-contract-reason-required, error-contract-reason-format, error-contract-reason-unique, error-contract-when-required, error-contract-retryable-type, error-contract-severity-unknown, error-contract-recovery-required, error-contract-recovery-empty, error-contract-recovery-min-words Error contract rules
Error contract (conformance) error-contract-conformance, error-contract-prefer-fail, error-contract-unthrown Error contract rules
Enrichment enrichment-type, enrichment-empty, enrichment-field-type, enrichment-output-collision, enrichment-prefer-block, enrichment-trailer-render, enrichment-trailer-orphan, enrichment-trailer-unknown-field, capped-list-no-truncation Enrichment rules
server.json ~40 rules prefixed server-json-* server.json rules

Read the full file on GitHub · 1,144 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 13d ago Changed f37eb9148e64
  2. 1mo ago Changed · +160 lines 352a46f60bca
  3. 1mo ago First seen · 984 lines · 86 tokens per session scan A 8f2c3de62558

Subscribe to this mod's changes

api-linter is a skill published in the GitHub repository cyanheads/openstates-mcp-server (2 stars, last pushed 14d ago), licensed Apache-2.0. It adds 86 tokens to every session and 16,931 once invoked, about $0.0003 per session on Opus 5.5. A static security scan graded it A with 0 findings. It is 100% identical to api-linter, differing in 21 lines, and is treated as a copy.

Related

Other skills, from other repositories

release-pr-review

Review pass on an open release PR (release/ → main) — the step between git-wrapup and release-and-publish when a project releases in gated release PR mode. Reads the PR's commit range through the code-simplifier lens plus a correctness review, verifies whatever an automated reviewer left on the PR, lands fixes as…

cyanheads/wikipedia-mcp-server · 136 tokens

release-and-publish

Ship a release end-to-end across every registry the project targets (npm, MCP Registry, GitHub Releases for .mcpb bundles, GHCR). Runs the final verification gate, fast-forwards main when the release rode a release PR, creates the annotated tag on the commit main now points at, pushes commits and tags, then publishes…

cyanheads/wikidata-mcp-server · 155 tokens

design-mcp-server

Design the tool surface, resources, and service layer for a new MCP server. Use when starting a new server, planning a major feature expansion, or when the user describes a domain/API they want to expose via MCP. Produces a design doc at docs/design.md that drives implementation.

cyanheads/wikidata-mcp-server · 62 tokens

add-tool

Scaffold a new MCP tool definition. Use when the user asks to add a tool, create a new tool, or implement a new capability for the server.

cyanheads/wikidata-mcp-server · 35 tokens

api-context

Canonical reference for the unified Context object passed to every tool and resource handler in @cyanheads/mcp-ts-core. Covers the full interface, its RequestContext base, all sub-APIs (ctx.log, ctx.state, ctx.requestInput, ctx.inputs, ctx.clientCapabilities, ctx.enrich, ctx.content), and when to use each.

cyanheads/wikidata-mcp-server · 84 tokens

api-errors

McpError constructor, JsonRpcErrorCode reference, and error handling patterns for @cyanheads/mcp-ts-core. Use when looking up error codes, understanding where errors should be thrown vs. caught, or using ErrorHandler.tryCatch in services.

cyanheads/wikidata-mcp-server · 54 tokens