Offline security linter for MCP server configurations.
AI assistants can run tools with access to your filesystem, environment variables, and network. MCP configs (mcp.json, Claude Desktop, VS Code) define which servers get that trust boundary — often with npx -y, broad filesystem roots, hardcoded tokens, or remote URLs.
mcp-trust-lint scans those configs locally and flags risky launch patterns before you connect a server to Cursor, Claude Desktop, or VS Code.
Built by Cipher Cortex.
| ID | Severity | Rule |
|---|---|---|
| MTL-CRIT-001 | Critical | Shell interpreter used as MCP command (bash, sh, powershell, …) |
| MTL-CRIT-002 | Critical | curl / wget / pipe-to-shell in launch args |
| MTL-CRIT-003 | Critical | Filesystem MCP rooted at /, ~, or entire home/workspace |
| MTL-CRIT-004 | Critical | Args reference sensitive paths (.ssh, .aws, .gnupg, …) |
| MTL-CRIT-005 | Critical | eval / exec markers in args |
| MTL-HIGH-001 | High | Hardcoded secrets in env (token/key patterns) |
| MTL-HIGH-002 | High | envFile loads a dotenv/secrets bundle into the MCP process |
| MTL-HIGH-003 | High | Remote MCP over cleartext http:// (non-localhost) |
| MTL-HIGH-005 | High | Hardcoded secrets in remote headers |
| MTL-HIGH-006 | High | Docker MCP with --privileged or docker.sock mount |
| MTL-HIGH-007 | High | @modelcontextprotocol/server-filesystem without explicit root |
| MTL-HIGH-008 | High | cwd points at sensitive directories |
| MTL-MED-003 | Medium | npx -y with unscoped package name |
| MTL-MED-004 | Medium | Remote MCP URL uses raw IP address |
| MTL-MED-005 | Medium | Risky patterns in local MCP server source (optional scan) |
| MTL-INFO-001 | Info | Env var correctly uses ${env:VAR} interpolation |
| MTL-INFO-002 | Info | Filesystem MCP uses explicit scoped root path |
Each config gets a trust score (0–100). Lower = more findings / higher severity.
Requirements: Python 3.10+ · no dependencies
git clone https://github.com/CipherCortex/mcp-trust-lint.git
cd mcp-trust-lint
# Scan your global Cursor MCP config
python3 -m mcp_trust_lint --cursor-global
# Scan explicit files
python3 -m mcp_trust_lint ~/.cursor/mcp.json
# Scan common default locations that exist on this machine
python3 -m mcp_trust_lint --defaults
# JSON output + CI exit code
python3 -m mcp_trust_lint --cursor-global --format json --min-severity highOptional install:
pip install -e .
mcp-trust-lint --cursor-global| Client | Typical path | Root key |
|---|---|---|
| Cursor (global) | ~/.cursor/mcp.json |
mcpServers |
| Cursor (project) | .cursor/mcp.json, .mcp.json |
mcpServers |
| Claude Desktop | ~/.config/claude/claude_desktop_config.json |
mcpServers |
| VS Code | .vscode/mcp.json |
servers or mcpServers |
Example stdio server:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${env:GITHUB_PERSONAL_ACCESS_TOKEN}"
}
}
}
}Example remote server:
{
"mcpServers": {
"remote-api": {
"url": "https://mcp.example.com/sse",
"headers": {
"Authorization": "Bearer ${env:MCP_TOKEN}"
}
}
}
}usage: mcp-trust-lint [-h] [--cursor-global] [--cursor-project DIR]
[--defaults] [--format {table,json}] [-o OUTPUT]
[--min-score MIN_SCORE] [--min-severity {critical,high,medium,low,info}]
[--no-source-scan] [--no-color] [--version]
[paths ...]
| Flag | Purpose |
|---|---|
--cursor-global |
Scan ~/.cursor/mcp.json |
--cursor-project DIR |
Scan .cursor/mcp.json / .mcp.json under a repo |
--defaults |
Scan known Claude/Cursor default paths that exist |
--format json |
Machine-readable report |
--min-severity high |
Exit code 1 if any high+ finding (CI gate) |
--min-score 80 |
Exit code 1 if trust score drops below threshold |
--no-source-scan |
Skip static analysis of local .js / .py server entrypoints |
- name: Lint MCP configs
run: |
python3 -m mcp_trust_lint .cursor/mcp.json --format json --min-severity highCommit a sanitized team template (placeholders only) — never commit live tokens.
- Does not run MCP servers or call remote tools
- Does not prove a server is malicious — it flags trust boundary mistakes
- Does not replace manual review of what tools a server exposes at runtime
For runtime tool auditing, pair this with vendor allowlists and org policy.
python3 -m unittest discover -s tests -v
python3 -m mcp_trust_lint tests/fixtures/risky.json --no-source-scan
python3 -m mcp_trust_lint tests/fixtures/benign.json --no-source-scanPRs welcome for new rules, client path discovery, and false-positive tuning. Include fixture JSON and tests.
| Tool | Role |
|---|---|
| evidence-pack | Provenance packs for research artifacts |
| hijacked-infra-hunt | Compromised web infrastructure hunting |
| Cipher Cortex | Full OSS studio |
MIT — see LICENSE.