Skip to main content

Lint MCP config files for Claude Desktop, Claude Code, Cursor, Cline, Windsurf, and Zed. Stdlib-only Python port of @mukundakatta/mcpcheck.

Project description

mcpcheck-py

Python License: MIT

A linter for MCP (Model Context Protocol) config files. Works on every client that reads mcp.json / .mcp.json / claude_desktop_config.json / Zed's context_servers: Claude Desktop, Claude Code, Cursor, Cline, Windsurf, Zed.

Stdlib-only Python port of @mukundakatta/mcpcheck. Catches hardcoded secrets, dangerous commands, missing transports, malformed env blocks, plaintext HTTP with tokens, and shell-metachar injection.

Note: there's a separate package called mcp-config-check on PyPI by a different author. This package is the user's own port and uses the -py suffix to disambiguate.

Install

pip install mcpcheck-py

Usage

from mcpcheck import lint

result = lint("/path/to/mcp.json")

result.fatal           # True if the file failed to parse
for issue in result.issues:
    print(issue.line, issue.severity, issue.rule_id, issue.message)

You can also lint in-memory configs:

from mcpcheck import lint_source

source = '''
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_TOKEN": "ghp_abcdef1234567890abcdef1234567890" }
    }
  }
}
'''
result = lint_source(source, file="<inline>")

Result shape

@dataclass
class Issue:
    rule_id: str
    severity: str           # "error" | "warning" | "info"
    message: str
    json_path: str          # dotted path, e.g. "mcpServers.github.env.GITHUB_TOKEN"
    line: int = 1

@dataclass
class LintResult:
    file: str
    fatal: bool
    issues: list[Issue]

Rules

Rule id Severity Checks
invalid-json error File doesn't parse as JSON / JSONC.
empty-servers warning No mcpServers / servers / context_servers key, or empty.
duplicate-server-name warning Two servers share a case-insensitive name.
unknown-field info Server has a field outside the known set.
missing-transport warning Server has neither command (stdio) nor url (sse / streamable-http).
dangerous-command error sudo, curl | sh, docker --privileged, host-root mounts, rm -rf /.
hardcoded-secret error Provider-shaped key (OpenAI, Anthropic, GitHub, AWS, Slack, etc.) in env values.
plaintext-http-with-token warning http:// URL combined with a bearer/auth header.
invalid-env-var-name warning env key doesn't match ^[A-Z_][A-Z0-9_]*$.
empty-env-value warning env value is empty or whitespace.

Supported clients

mcpcheck.CLIENT_PATHS exposes the same path table the JS sibling uses, so you can build editor / CI integrations that auto-discover configs:

  • cursor -- ~/.cursor/mcp.json
  • claude-desktop -- ~/Library/Application Support/Claude/claude_desktop_config.json, ...
  • claude-code -- ~/.claude.json, **/.mcp.json
  • windsurf -- ~/.codeium/windsurf/mcp_config.json
  • zed -- ~/.config/zed/settings.json
  • cline -- **/.cline/mcp.json, **/cline_mcp_settings.json

API differences from the JS sibling

  • Stdlib only -- JSONC (comments + trailing commas) handled by a small hand-rolled tolerant scanner instead of jsonc-parser. Strict JSON files go through json.loads directly.
  • Returns a LintResult dataclass instead of the JS object literal.
  • Spec entrypoint is lint(config_path) -- mirror of the spec's lint(config_path) -> LintResult. lint_source covers the in-memory case.
  • Fewer rules than the full JS sibling -- the Python port focuses on the high-signal subset (secrets, dangerous commands, structure). Run the JS CLI for the full surface.

See the JS sibling's README for the broader rationale.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcpcheck_py-0.1.0.tar.gz (12.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcpcheck_py-0.1.0-py3-none-any.whl (12.5 kB view details)

Uploaded Python 3

File details

Details for the file mcpcheck_py-0.1.0.tar.gz.

File metadata

  • Download URL: mcpcheck_py-0.1.0.tar.gz
  • Upload date:
  • Size: 12.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for mcpcheck_py-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0a8630205a4aa778f28e314deaadaa981235c6a551a4f7673ffd65c31af72b6c
MD5 582cb263a3773b92f22db430e3ecedf7
BLAKE2b-256 9102f18d585be279d69e91423b6e98eb9d2ca4e807e001d837a0e1adfaa601e7

See more details on using hashes here.

File details

Details for the file mcpcheck_py-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: mcpcheck_py-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for mcpcheck_py-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dd711eadc55f0af5771793bee20195c67ee68274c32895837b33f5864b111a5a
MD5 75f05b1820c1047b1a5452afbea03aac
BLAKE2b-256 09437c8d3580fd1c05e5126cc6fe2058ed24a2df4fbbb318e205be37ccc6064e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page