MCP Server
What is the Skylos MCP Server?
The Skylos MCP server exposes Skylos's full static analysis engine as a set of tools that AI assistants can call directly. Instead of copy-pasting code into a chat window, you can ask Claude (or any MCP-compatible client) to scan your project — and it runs the real Skylos engine under the hood.
You: "Scan my project for security issues"
Claude -> calls security_scan("./my-project")
-> Skylos runs full taint analysis, dangerous-call detection, etc.
-> Returns structured findings
Claude: "I found 3 issues: SQL injection on line 42, SSRF on line 87, ..."
This is not a summarizer or wrapper — it runs the same analysis as skylos . --danger on the CLI.
What Skylos Detects
Skylos is a hybrid static analysis tool for Python, TypeScript, JavaScript, Java, Go, Kotlin, PHP, Rust, Dart, C#, and Shell. Through MCP, your AI assistant gets access to:
| Capability | What It Finds | Rule IDs |
|---|---|---|
| Dead Code | Unused functions, imports, classes, variables | SKY-U001–U004 |
| Security | SQL injection, XSS, SSRF, command injection, path traversal, CORS, JWT, mass assignment, MCP server vulnerabilities | SKY-D201–D244 |
| Secrets | Hardcoded API keys (AWS, Stripe, OpenAI, GitHub, Slack, etc.) | SKY-S101 |
| Quality | Cyclomatic complexity, deep nesting, async blocking, god classes | SKY-Q301–Q501 |
| Logic Bugs | Mutable defaults, bare except, dangerous comparisons, inconsistent returns | SKY-L001–L006 |
| Supply Chain | Hallucinated dependencies, undeclared imports, real packages called with invented APIs, and npm/Go versions that do not exist | SKY-D222–D225 |
| Remediation | Auto-fix issues via LLM, validate with tests, revert if broken | — |
For the full rules reference, see Rules Reference.
Setup
Prerequisites
pip install skylos
Claude Desktop
Add to your Claude Desktop config:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Linux:
~/.config/claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"skylos": {
"command": "python",
"args": ["-m", "skylos_mcp.server"]
}
}
}
Restart Claude Desktop. You should see "skylos" listed in the tools menu (hammer icon).
Cursor / VS Code with MCP
If your editor supports MCP servers, add the same configuration to your editor's MCP settings. The command is the same:
python -m skylos_mcp.server
Virtual Environment
If Skylos is installed in a virtual environment, point to the venv Python:
{
"mcpServers": {
"skylos": {
"command": "/path/to/venv/bin/python",
"args": ["-m", "skylos_mcp.server"]
}
}
}
Authentication (API Key)
To use all tools, add your API key:
{
"mcpServers": {
"skylos": {
"command": "python",
"args": ["-m", "skylos_mcp.server"],
"env": {
"SKYLOS_API_KEY": "your-api-key-here"
}
}
}
}
Get your API key from skylos.dev/dashboard/settings.
Without an API key, the MCP server still works but in limited mode:
analyzeis available, limited to 5 calls per day- The local map tools (
change_map,graph_find,graph_show,graph_impact,graph_areas,graph_relevant,graph_pending,graph_describe) are available with no limit: they read the repository on your machine and send nothing to Skylos Cloud security_scan,quality_check,secrets_scan, andremediaterequire authentication
With an API key, all tools are available:
| Tool | Credits | Notes |
|---|---|---|
analyze | Free | Runs locally |
security_scan | Free | Runs locally |
quality_check | Free | Runs locally |
secrets_scan | Free | Runs locally |
verify_change | Free | Runs locally; returns narrow AI-code trust findings for changed code |
verify_agent | Free | Runs locally; verifies AI-agent guardrails with scores, failed checks, OWASP coverage, gate verdict, and attestation digest |
change_map | Free | No key needed. Runs locally; maps what a change touches: old and new code, callers, removed security checks, and what to read first, read, skim or skip |
graph_find, graph_show, graph_impact | Free | No key needed. Runs locally; reads the codebase graph built by skylos graph |
graph_areas, graph_relevant | Free | No key needed. Runs locally; the codebase's areas, and the code that matters most to the files you are changing |
graph_pending, graph_describe | Free | No key needed. Runs locally; your agent writes the plain-English descriptions |
remediate | Free | Runs locally; AI fix generation on your own model key. The model cost goes to your provider |
Analysis tools (analyze, security_scan, quality_check, secrets_scan,
verify_change, verify_agent and change_map) run entirely on your machine — they don't cost credits.
The remediate tool does not cost credits either. It runs on your machine
with your own model key, so you pay your model provider directly.
See Billing & Credits for what does cost credits.
Rate Limits
| Plan | Rate Limit |
|---|---|
| No API key | 5 calls/day (analyze only) |
| Free | 50 calls/hour |
| Workspace | 500 calls/hour |
| Enterprise | 5,000 calls/hour |
Custom Results Directory
By default, analysis results are stored in ~/.skylos/mcp_results/. Override with:
{
"mcpServers": {
"skylos": {
"command": "python",
"args": ["-m", "skylos_mcp.server"],
"env": {
"SKYLOS_API_KEY": "your-api-key",
"SKYLOS_MCP_RESULTS_DIR": "/path/to/results"
}
}
}
}
Available Tools
analyze
Scans for dead code — unused functions, imports, classes, variables, and parameters.
| Parameter | Type | Default | Description |
|---|---|---|---|
path | string | required | Path to scan |
confidence | int | 60 | Confidence threshold (0–100). Lower = more findings, higher = fewer false positives |
exclude_folders | list | auto | Folders to skip (defaults: __pycache__, .git, venv, etc.) |
Example prompt: "Find all dead code in my project"
Returns: Unused functions, imports, classes, variables, parameters, and empty files with confidence scores.
security_scan
Runs the full security scanner — taint analysis, dangerous function detection, and vulnerability checks.
| Parameter | Type | Default | Description |
|---|---|---|---|
path | string | required | Path to scan |
confidence | int | 60 | Confidence threshold |
exclude_folders | list | auto | Folders to skip |
Example prompt: "Scan src/ for security vulnerabilities"
Returns: All danger findings (SKY-D rules) with file, line, severity, and description.
What it detects:
- SQL injection (taint tracking from request params to
cursor.execute()) - Command injection (
os.system(),subprocess(shell=True)with user input) - SSRF (tainted URLs in
requests.get(),httpx,urllib) - Path traversal (user input in
open(),Path()) - XSS (
mark_safe(), disabled autoescape, HTML string building) - Dangerous calls (
eval,exec,pickle,yaml.load) - Weak cryptography (
md5,sha1) - CORS misconfiguration, JWT vulnerabilities, mass assignment
- MCP server security issues (D240–D244)
- Supply chain risks (hallucinated/undeclared dependencies)
quality_check
Analyzes code quality — complexity, nesting, structure, and logic patterns.
| Parameter | Type | Default | Description |
|---|---|---|---|
path | string | required | Path to scan |
confidence | int | 60 | Confidence threshold |
exclude_folders | list | auto | Folders to skip |
Example prompt: "Check the code quality of my utils/ directory"
Returns: Quality findings (SKY-Q, SKY-C, SKY-L, SKY-P rules), circular dependency analysis, and custom rule violations.
secrets_scan
Detects hardcoded credentials and sensitive data.
| Parameter | Type | Default | Description |
|---|---|---|---|
path | string | required | Path to scan |
confidence | int | 60 | Confidence threshold |
exclude_folders | list | auto | Folders to skip |
Example prompt: "Find any hardcoded secrets in my project"
Returns: All SKY-S101 findings — API keys, tokens, passwords, and private keys with the file, line number, and detected provider.
Scanned file types: .py, .pyi, .pyw, .env, .yaml, .yml, .json, .toml, .ini, .cfg, .conf, .ts, .tsx, .js, .jsx, .go, .java, .php, .rs
Detected providers: AWS, Stripe, GitHub, GitLab, Slack, Google, SendGrid, Twilio, OpenAI, Anthropic, and generic high-entropy strings.
verify_change
Verifies a changed file or line range for AI-code trust findings. This is the
MCP equivalent of skylos verify, intended for coding agents to call after an
edit before showing the change to a human.
| Parameter | Type | Default | Description |
|---|---|---|---|
path | string | "." | File or project root to verify |
file | string | null | Target file when path is a project root |
line_range | string | null | Changed range such as "40:75" |
confidence | int | 60 | Confidence threshold |
project_context | bool | false | Scan the project root and filter to file |
include_dependency_hallucinations | bool | true | Include package metadata checks for hallucinated dependencies and versions |
contract_path | string | null | Path to an AI hallucination contract, equivalent to skylos verify . --contract PATH |
exclude_folders | string | null | Comma-separated folders to exclude |
Example prompt: "Verify the change I just made to src/app.py lines 40 to 75."
Returns: Versioned JSON with tool: "verify_change", status, target
metadata, and only AI-code findings such as hallucinated references,
incomplete generation, stale references, disabled controls, dependency
hallucinations, API signature hallucinations, weakened assertions, and
contract-required route guardrails. AI-defect findings use category: "ai_defect".
Contract-backed findings can include contract_id, contract_clause,
contract_path, and contract_reason.
Dependency checks are diff-aware: if a raw diff adds both a Python import and
the matching PyPI declaration in requirements*.txt or pyproject.toml, the
import is treated as declared. For package.json, registry checks only inspect
entries inside dependency sections such as dependencies, devDependencies,
peerDependencies, and optionalDependencies.
verify_agent
Statically verifies AI-agent guardrails before deployment. It inventories LLM integrations, runs the same deterministic defense checks as skylos defend, and returns defense/ops scores, failed checks with remediation, OWASP coverage summary, an optional gate verdict, and an attestation digest.
{
"path": ".",
"fail_on": "critical",
"owasp_framework": "agentic"
}
Returns: Compact JSON with tool: "verify_agent", defense_score, ops_score, failed_checks, owasp, gate, and attestation. The verification is deterministic static analysis, not another model reviewing the code.
change_map
Maps what a code change touches so a review agent can read it before the
diff. It is the MCP equivalent of skylos done map --format json.
| Parameter | Type | Default | Description |
|---|---|---|---|
path | string | "." | Repository root |
base | string | "HEAD" | Compare with the merge base of this ref, such as origin/main; HEAD maps only uncommitted changes |
Example prompt: "Map what this branch changed against origin/main, then review the flagged changes first."
Returns: JSON with schema_version, base_commit, symbols (each
changed function, method or class with before and after code, calls
added and removed, callers, security_removed, signature_change and
reasons, plus verdict, review and review_why), read_first,
flagged, groups, review (the read first, read, skim and skip lists with
changed-line counts), module_changes and coverage. The same commit gives
the same map: it is computed from the code, not by a model. It needs no API
key and has no daily limit. See Change Map.
graph_find, graph_show, graph_impact, graph_areas, graph_relevant
Answer questions from the codebase graph that skylos graph builds, so an
agent can look up callers, tests and impact before it edits code. They match
skylos graph find, show and impact --format json, need no API key and
have no daily limit. For the verdicts on changed code, use change_map.
| Tool | Parameters |
|---|---|
graph_find | query (part of a name), path (default "."), include_tests (default false) |
graph_show | name (id, dotted name, short name or path::Name), path, with_code (default false) |
graph_impact | name, path, depth (1 to 8, default 3) |
graph_areas | path, area (an area id, optional: lists its members and linked areas) |
graph_relevant | files (paths you are about to change), path, budget (tokens, default 2000) |
Each tool builds the graph first if the repository has none.
Example prompt: "Before you change load_config, show who calls it and which tests reach it."
graph_pending, graph_describe
graph_pending returns code that still needs a plain-English description,
with its source. With changes=true and a base such as origin/main, it
compares first and returns the changed code whose logic changed, to explain.
The agent writes the descriptions and saves them with graph_describe.
Nothing is sent to Skylos. See Codebase Graph and the
Agent Code Workflow.
remediate
End-to-end remediation: scan for issues, generate LLM-based fixes, validate each fix by running your test suite, and optionally apply them.
| Parameter | Type | Default | Description |
|---|---|---|---|
path | string | required | Path to scan and fix |
max_fixes | int | 5 | Maximum number of fixes to attempt |
dry_run | bool | true | If true, shows plan without applying. Set to false to apply fixes. |
model | string | "gpt-4.1" | LLM model for fix generation |
test_cmd | string | null | Custom test command (default: auto-detect pytest/unittest) |
severity | string | null | Minimum severity filter: critical, high, medium, low |
Example prompt: "Fix the top 3 security issues in my project, but don't apply yet — show me the plan"
Returns: Remediation plan with status for each finding (fixed, skipped, test_failed, not_resolved). Security remediation also re-scans after a fix and can include generated regression-test proof metadata, such as the rule family, source file, and candidate test file.
Set dry_run=false only when you're ready to modify files. Fixes that break tests are automatically reverted.
Safety guardrails:
- Dry run by default — nothing changes unless you explicitly set
dry_run=false - Fixes that break tests are automatically reverted
- Low-confidence fixes are skipped
- After applying a fix, Skylos re-scans to confirm the finding is actually resolved
- For supported security findings such as
SKY-D211, Skylos can attach a targeted regression-test candidate after the fix is verified - Maximum fixes capped at
max_fixesto prevent runaway changes
The remediate tool requires an LLM API key. Set OPENAI_API_KEY or ANTHROPIC_API_KEY in the MCP server's environment, or configure keys via skylos key.
Available Resources
Resources provide access to stored analysis results.
| Resource URI | Description |
|---|---|
skylos://results/latest | The most recent analysis result |
skylos://results/{run_id} | A specific analysis result by run ID |
skylos://results | List all stored analysis runs |
Every tool call returns a _run_id in its response. Use this ID to retrieve the full result later:
You: "What was the last security scan result?"
Claude → reads skylos://results/latest
Results are persisted to ~/.skylos/mcp_results/ so they survive server restarts.
Example Conversations
Security audit
You: "Run a security scan on my project at ./backend"
Claude: I'll scan your backend for security vulnerabilities.
[Calls security_scan(path="./backend")]
I found 5 security issues:
1. CRITICAL: SQL injection on line 42 of api/users.py (SKY-D211)
2. HIGH: Path traversal on line 87 of api/files.py (SKY-D215)
3. HIGH: CORS misconfiguration in config.py (SKY-D231)
4. MEDIUM: Weak hash (MD5) on line 15 of utils/crypto.py (SKY-D207)
5. MEDIUM: Undeclared dependency 'httpx' (SKY-D223)
Finding dead code
You: "Find unused code in src/ with high confidence only"
Claude: I'll scan for dead code with a high confidence threshold.
[Calls analyze(path="src/", confidence=80)]
Found 12 unused items:
- 4 unused functions (90%+ confidence)
- 6 unused imports
- 2 unused classes
Remediation workflow
You: "Fix the critical security issues but show me the plan first"
Claude: I'll generate a remediation plan for critical issues.
[Calls remediate(path="./backend", severity="critical", dry_run=true)]
Remediation plan:
1. SKY-D211 (SQL injection, api/users.py:42) → Will parameterize the query
2. SKY-D204 (pickle.load, data/loader.py:15) → Will replace with json.loads
Ready to apply? Say "apply the fixes" to proceed.
You: "Apply the fixes"
[Calls remediate(path="./backend", severity="critical", dry_run=false, max_fixes=2)]
Results:
- api/users.py: Fixed (tests pass, finding resolved)
- data/loader.py: Fixed (tests pass, finding resolved)
Checking for secrets before deploy
You: "Any hardcoded secrets in the codebase?"
Claude: Let me scan for secrets.
[Calls secrets_scan(path=".")]
Found 2 secrets:
1. AWS access key (AKIA...) in config/aws.py:8
2. Stripe key (sk_live_...) in billing/checkout.py:23
Recommendation: Move these to environment variables or a secrets manager.
How It Works
┌─────────────────────┐ stdio/SSE ┌──────────────────────┐
│ Claude Desktop / │ ◄──────────────────► │ skylos_mcp.server │
│ Cursor / Any MCP │ MCP Protocol │ (FastMCP) │
│ Client │ │ │
└─────────────────────┘ └──────────┬───────────┘
│
▼
┌──────────────────────┐
│ skylos.analyzer │
│ (Core Engine) │
├──────────────────────┤
│ AST parsing │
│ Taint analysis │
│ Pattern matching │
│ Tree-sitter (TS) │
│ Secrets scanning │
│ Quality rules │
│ Dependency checks │
└──────────┬───────────┘
│
┌──────────▼───────────┐
│ Results Cache │
│ ~/.skylos/ │
│ mcp_results/ │
└──────────────────────┘
- MCP client (Claude Desktop, Cursor, etc.) connects to the Skylos server via stdio
- Tool calls are routed to Skylos's core
analyzer.analyze()function — the same engine used by the CLI - Results are stored in-memory and on disk (
~/.skylos/mcp_results/) for later retrieval via resources - Remediation uses Skylos's LLM orchestrator to generate, apply, test, and verify fixes
The MCP server runs 100% locally. Your code never leaves your machine (unless you use the remediate tool, which sends code snippets to your configured LLM provider for fix generation).
Troubleshooting
Server not appearing in Claude Desktop
- Verify the config file path is correct for your OS
- Check that
python -m skylos_mcp.serverworks from your terminal - Restart Claude Desktop after editing the config
- Check Claude Desktop logs for connection errors
"Module not found" error
Skylos must be installed in the Python that the config points to:
# Check which python
which python
# Install skylos there
python -m pip install skylos
# Or use absolute path in config
/Users/you/venv/bin/python -m skylos_mcp.server
Analysis returns empty results
- Check that the
pathparameter points to a valid directory with Python/TypeScript files - Lower the
confidencethreshold (e.g.,confidence=40) to see more findings - Verify the directory isn't excluded by default (check
--list-default-excludes)
Remediate tool fails
- Ensure an LLM API key is set:
OPENAI_API_KEYorANTHROPIC_API_KEY - Check that the model name is valid (e.g.,
gpt-4.1,claude-sonnet-4-20250514) - For local LLMs, configure
SKYLOS_LLM_BASE_URLin the environment
Privacy
- Static analysis: Runs 100% locally. No data leaves your machine.
- Secrets scanning: 100% local. Detected secrets are never transmitted.
- Remediation: Sends code snippets to your configured LLM provider (OpenAI, Anthropic, or local). Use a local LLM (Ollama) for full privacy.
- Results storage: Stored locally at
~/.skylos/mcp_results/. No telemetry or data collection.
References
| Resource | Link |
|---|---|
| MCP Specification | https://modelcontextprotocol.io |
| Skylos GitHub | https://github.com/duriantaco/skylos |
| Rules Reference | Rules Reference |
| Claude Desktop MCP Setup | https://modelcontextprotocol.io/quickstart/user |