Ferrok API Documentation

Scan MCP server configurations for security vulnerabilities. Map findings to the OWASP MCP Top 10. Integrate automated security into your workflow.

Current version

API v1 — Ferrok Engine 0.1.0. All endpoints return JSON. OpenAPI spec at /openapi.json. Swagger UI at /docs.

Authentication

All requests require a Bearer token in the Authorization header.

curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://api.ferrok.dev/v1/health
Free tier

100 scans/month. No key required for /v1/health.

Base URL

https://api.ferrok.dev

Local dev: http://localhost:8000.

Quickstart

Send your first scan in under a minute:

curl -X POST https://api.ferrok.dev/v1/scan \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "config": {
      "server_name": "my-mcp-server",
      "transport": "stdio",
      "command": "npx",
      "args": ["-y", "@my-org/mcp-server"],
      "tools": [{
        "name": "read_file",
        "description": "Read a file from the filesystem",
        "inputSchema": {
          "type": "object",
          "properties": { "path": { "type": "string" } },
          "required": ["path"]
        }
      }]
    }
  }'

Response:

{
  "scan_id": "scan_a1b2c3d4",
  "summary": {
    "overall_score": 62,
    "grade": "C-",
    "total_findings": 5,
    "pass_fail": "FAIL"
  },
  "findings": [ /* ... */ ]
}

POST /v1/scan

Analyzes an MCP server configuration and returns findings mapped to the OWASP MCP Top 10.

POST /v1/scan

Responses

StatusDescription
200Scan completed. Returns ScanResponse.
401Missing or invalid API key.
422Validation error.
429Rate limit exceeded.
500Internal error.

GET /v1/health

Health check. No auth required.

GET /v1/health
{ "status": "healthy", "version": "0.1.0", "engine": "Ferrok" }

ScanRequest

FieldTypeDescription
configMCPServerConfigrequiredServer configuration to scan.
include_recommendationsbooleanoptionalInclude fix advice. Default: true.

MCPServerConfig

FieldTypeDescription
server_namestringoptionalHuman-readable name.
server_urlstringoptionalServer URL.
transportstringoptionalstdio | sse | streamable-http
commandstringoptionalLaunch command (stdio).
argsstring[]optionalCommand arguments.
envobjectoptionalEnv vars. Scanned for secrets.
capabilitiesobjectoptionalDeclared capabilities.
toolsToolDefinition[]optionalTool definitions.

ToolDefinition

FieldTypeDescription
namestringrequiredTool identifier.
descriptionstringoptionalScanned for injection.
inputSchemaobjectoptionalJSON Schema. Alias: input_schema.

ScanResponse

FieldTypeDescription
scan_idstringUnique ID.
timestampdatetimeUTC ISO 8601.
server_namestring | nullEcho of request.
summaryScanSummaryAggregated scores.
tools_analyzedToolAnalysis[]Per-tool breakdown.
findingsFinding[]Security findings.
metadataobjectEngine info, duration.

Finding

FieldTypeDescription
idstringe.g. TP-001, PA-003
titlestringShort description.
severityenumcritical high medium low info
owasp_categorystringe.g. MCP01:ToolPoisoning
descriptionstringDetailed explanation.
affected_toolstring | nullTriggering tool.
evidencestring | nullDetection trigger.
recommendationstring | nullFix guidance.

ScanSummary

FieldTypeDescription
overall_scoreinteger (0-100)Security score.
gradestringA+ to F.
total_findingsintegerTotal count.
critical_countintegerCritical findings.
high_countintegerHigh findings.
medium_countintegerMedium findings.
low_countintegerLow findings.
info_countintegerInformational.
pass_failstringPASS or FAIL.

Scoring & Grades

Start at 100. Deductions per finding:

SeverityDeductionCI/CD
critical-25FAIL
high-15FAIL
medium-8Score only
low-3Score only
info0Info only
ScoreGradeScoreGrade
95-100A+60-69C-
90-94A50-59D+
85-89A-40-49D-
80-84B+0-39F
70-79B-
CI/CD gate

pass_fail returns FAIL if any critical or high finding exists, regardless of score.

Severity Levels

LevelMeaningExample
criticalActive exploitation risk.Prompt injection in tool.
highSerious vulnerability.Hardcoded AWS secret.
mediumModerate risk.Unconstrained fs write.
lowBest-practice violation.Missing schema description.
infoInformational.Stdio transport detected.

OWASP MCP Top 10

MCP01
Tool Poisoning
MCP02
Excessive Permissions
MCP03
Insecure Transport
MCP04
Tool Schema Mismatch
MCP05
Insufficient Input Validation
MCP06
Sensitive Data Exposure
MCP07
Insecure Resource Access
MCP08
Insufficient Logging
MCP09
Server Misconfiguration
MCP10
Supply Chain Risk

Scanner Modules

Tool Poisoning Scanner TP-*

Prompt injection, hidden instructions, data exfiltration, role manipulation, encoded chars, zero-width unicode.

Permission Analyzer PA-*

Filesystem, network, code execution, database, secrets access, wildcard patterns.

Schema Validator SV-*

Missing schemas, non-object roots, empty properties, unconstrained strings, description mismatches.

Transport Security TS-*

Insecure HTTP, hardcoded secrets, npx -y supply chain, shell injection, missing capabilities.

CI/CD Integration

GitHub Actions

# .github/workflows/mcp-security.yml
name: MCP Security Scan
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Scan MCP config
        run: |
          RESULT=$(curl -s -X POST https://api.ferrok.dev/v1/scan \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer ${{ secrets.FERROK_API_KEY }}" \
            -d @mcp-config.json)
          echo "$RESULT" | jq .
          VERDICT=$(echo "$RESULT" | jq -r '.summary.pass_fail')
          [ "$VERDICT" = "PASS" ] || exit 1

GitLab CI

mcp_security:
  stage: test
  script:
    - |
      RESULT=$(curl -s -X POST https://api.ferrok.dev/v1/scan \
        -H "Authorization: Bearer $FERROK_API_KEY" -d @mcp-config.json)
      [ "$(echo $RESULT | jq -r '.summary.pass_fail')" = "PASS" ] || exit 1

Python

import httpx, sys, json

resp = httpx.post(
    "https://api.ferrok.dev/v1/scan",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={"config": json.load(open("mcp-config.json"))}
)
result = resp.json()
if result["summary"]["pass_fail"] == "FAIL":
    sys.exit(1)

Error Handling

StatusMeaningAction
401UnauthorizedCheck API key.
422ValidationCheck detail array.
429Rate limitedWait and retry.
500Server errorRetry once.

Rate Limits

PlanScans/moReq/min
Free10010
Starter2,00030
Pro10,00060
EnterpriseUnlimitedCustom
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1709683200