Skip to content

Formatos de Salida

MCP-Scan soporta multiples formatos de salida para diferentes casos de uso.


Tabla de Contenidos

  1. Vision General
  2. Formato Texto
  3. Formato JSON
  4. Formato SARIF
  5. Evidence Bundle
  6. Comparativa de Formatos
  7. Procesamiento de Salidas

Vision General

Formato Extension Uso Principal
text - Terminal, humanos
json .json Procesamiento programatico
sarif .sarif GitHub Code Scanning
evidence .json Auditorias y compliance
# Especificar formato
mcp-scan scan . --output text     # Por defecto
mcp-scan scan . --output json
mcp-scan scan . --output sarif
mcp-scan scan . --output evidence

Formato Texto

Descripcion

Salida legible para humanos, ideal para uso en terminal.

mcp-scan scan . --output text
# O simplemente:
mcp-scan scan .

Ejemplo de Salida

MCP-Scan v2.0.0
================================================================================
Scanning: /Users/ejemplo/mi-servidor-mcp
Mode: fast
Files: 5

Analyzing...

================================================================================
FINDINGS SUMMARY
================================================================================

CRITICAL: 1
  - MCP-A003: Direct shell command execution
    File: src/server.py
    Line: 25
    Code: subprocess.run(cmd, shell=True)

HIGH: 2
  - MCP-B002: Potential path traversal
    File: src/handlers.py
    Line: 42
    Code: open(filepath, 'r')

  - MCP-C002: Unvalidated URL in request
    File: src/api.py
    Line: 18
    Code: requests.get(url)

MEDIUM: 1
  - MCP-E001: Hardcoded secret detected
    File: src/config.py
    Line: 5
    Code: API_KEY = "sk-..."

================================================================================
SECURITY SCORE
================================================================================

MSSS Score: 45/100
Compliance Level: 0 (Not Compliant)

Category Breakdown:
  A (RCE):        0/22  (-22 points)
  B (Filesystem): 8/13  (-5 points)
  C (SSRF):       5/10  (-5 points)
  E (Secrets):    8/10  (-2 points)
  Other:          24/45 (no deductions)

================================================================================
MCP SURFACE
================================================================================

Tools: 4
  - execute_command (src/server.py:20)
  - read_file (src/handlers.py:35)
  - fetch_url (src/api.py:12)
  - get_config (src/config.py:10)

SDK: Python Official (mcp)
Transport: stdio

================================================================================

Total: 4 findings (1 critical, 2 high, 1 medium)
Duration: 1.234s
Exit code: 1

Colores en Terminal

Por defecto, la salida usa colores:

Severidad Color
CRITICAL Rojo brillante
HIGH Rojo
MEDIUM Amarillo
LOW Azul
INFO Gris

Desactivar colores:

mcp-scan scan . --no-color
# O via variable de entorno
MCP_SCAN_NO_COLOR=true mcp-scan scan .


Formato JSON

Descripcion

Salida estructurada para procesamiento programatico.

mcp-scan scan . --output json > results.json

Estructura del JSON

{
  "version": "2.0.0",
  "scan_info": {
    "path": "/Users/ejemplo/mi-servidor-mcp",
    "mode": "fast",
    "started_at": "2026-01-23T10:00:00Z",
    "finished_at": "2026-01-23T10:00:01Z",
    "duration_ms": 1234
  },
  "manifest": {
    "files": [
      {
        "path": "src/server.py",
        "hash": "sha256:abc123...",
        "size": 1024,
        "language": "python"
      }
    ],
    "config_hash": "sha256:def456..."
  },
  "findings": [
    {
      "id": "f8a3b2c1d4e5f6a7",
      "rule_id": "MCP-A003",
      "title": "Direct shell command execution",
      "description": "Tainted data flows to shell command execution",
      "severity": "critical",
      "confidence": "high",
      "class": "A",
      "location": {
        "file": "src/server.py",
        "line": 25,
        "column": 5,
        "end_line": 25,
        "end_column": 45
      },
      "snippet": "subprocess.run(cmd, shell=True)",
      "context": {
        "before": ["@tool", "def execute_command(cmd: str):"],
        "line": "    return subprocess.run(cmd, shell=True)",
        "after": [""]
      },
      "mcp_context": {
        "tool_name": "execute_command",
        "handler_name": "execute_command",
        "transport": "stdio"
      },
      "evidence": {
        "taint_trace": [
          {
            "step": 1,
            "type": "source",
            "location": "src/server.py:24:22",
            "description": "Parameter 'cmd' from tool input"
          },
          {
            "step": 2,
            "type": "sink",
            "location": "src/server.py:25:11",
            "description": "subprocess.run with shell=True"
          }
        ],
        "llm_analysis": null,
        "codeql_confirmed": false
      },
      "remediation": "Use subprocess.run with a list of arguments instead of shell=True"
    }
  ],
  "summary": {
    "total": 4,
    "by_severity": {
      "critical": 1,
      "high": 2,
      "medium": 1,
      "low": 0,
      "info": 0
    },
    "by_class": {
      "A": 1,
      "B": 1,
      "C": 1,
      "E": 1
    },
    "baselined": 0
  },
  "mcp_surface": {
    "tools": [
      {
        "name": "execute_command",
        "handler": "execute_command",
        "file": "src/server.py",
        "line": 24,
        "description": "Execute a system command",
        "parameters": [
          {
            "name": "cmd",
            "type": "str",
            "required": true
          }
        ]
      }
    ],
    "resources": [],
    "prompts": [],
    "sdk": "mcp",
    "transport": "stdio",
    "auth_signals": {
      "cookies": false,
      "headers": false,
      "oauth_state": false,
      "oauth_nonce": false
    }
  },
  "msss_score": {
    "score": 45,
    "level": 0,
    "level_name": "Not Compliant",
    "category_scores": {
      "A": {"max": 22, "score": 0, "penalty": 22},
      "B": {"max": 13, "score": 8, "penalty": 5},
      "C": {"max": 10, "score": 5, "penalty": 5},
      "E": {"max": 10, "score": 8, "penalty": 2}
    }
  },
  "exit_code": 1
}

Campos Principales

Campo Tipo Descripcion
version string Version de mcp-scan
scan_info object Metadatos del escaneo
manifest object Inventario de archivos
findings array Lista de hallazgos
summary object Resumen estadistico
mcp_surface object Superficie MCP detectada
msss_score object Puntuacion de seguridad
exit_code int Codigo de salida

Campos de Finding

Campo Tipo Descripcion
id string ID unico (SHA-256 truncado)
rule_id string ID de la regla
title string Titulo del hallazgo
description string Descripcion detallada
severity string critical/high/medium/low/info
confidence string high/medium/low
class string Clase de vulnerabilidad (A-N)
location object Ubicacion en codigo
snippet string Codigo relevante
context object Lineas alrededor
mcp_context object Contexto MCP
evidence object Evidencias adicionales
remediation string Como arreglar

Formato SARIF

Descripcion

Static Analysis Results Interchange Format (SARIF) 2.1.0, compatible con:

  • GitHub Code Scanning
  • Azure DevOps
  • Visual Studio
  • Otras herramientas SARIF-compatibles
mcp-scan scan . --output sarif > results.sarif

Estructura SARIF

{
  "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
  "version": "2.1.0",
  "runs": [
    {
      "tool": {
        "driver": {
          "name": "mcp-scan",
          "version": "2.0.0",
          "informationUri": "https://github.com/mcphub/mcp-scan",
          "rules": [
            {
              "id": "MCP-A003",
              "name": "DirectShellExecution",
              "shortDescription": {
                "text": "Direct shell command execution"
              },
              "fullDescription": {
                "text": "Tainted data flows directly to a shell command execution function without proper sanitization."
              },
              "helpUri": "https://mcphub.io/docs/rules/MCP-A003",
              "defaultConfiguration": {
                "level": "error"
              },
              "properties": {
                "tags": ["security", "rce", "command-injection"],
                "security-severity": "9.8"
              }
            }
          ]
        }
      },
      "results": [
        {
          "ruleId": "MCP-A003",
          "ruleIndex": 0,
          "level": "error",
          "message": {
            "text": "Tainted data from tool input 'cmd' flows to subprocess.run with shell=True"
          },
          "locations": [
            {
              "physicalLocation": {
                "artifactLocation": {
                  "uri": "src/server.py",
                  "uriBaseId": "%SRCROOT%"
                },
                "region": {
                  "startLine": 25,
                  "startColumn": 5,
                  "endLine": 25,
                  "endColumn": 45,
                  "snippet": {
                    "text": "subprocess.run(cmd, shell=True)"
                  }
                }
              }
            }
          ],
          "codeFlows": [
            {
              "threadFlows": [
                {
                  "locations": [
                    {
                      "location": {
                        "physicalLocation": {
                          "artifactLocation": {
                            "uri": "src/server.py"
                          },
                          "region": {
                            "startLine": 24,
                            "startColumn": 22
                          }
                        },
                        "message": {
                          "text": "Source: Parameter 'cmd' from tool input"
                        }
                      }
                    },
                    {
                      "location": {
                        "physicalLocation": {
                          "artifactLocation": {
                            "uri": "src/server.py"
                          },
                          "region": {
                            "startLine": 25,
                            "startColumn": 11
                          }
                        },
                        "message": {
                          "text": "Sink: subprocess.run with shell=True"
                        }
                      }
                    }
                  ]
                }
              ]
            }
          ],
          "fingerprints": {
            "primaryLocationLineHash": "f8a3b2c1d4e5f6a7"
          }
        }
      ]
    }
  ]
}

Mapeo de Severidades

MCP-Scan SARIF Level Security Severity
critical error 9.0-10.0
high error 7.0-8.9
medium warning 4.0-6.9
low note 1.0-3.9
info none 0.0

Uso con GitHub Code Scanning

# .github/workflows/security.yml
name: Security Scan

on: [push, pull_request]

jobs:
  mcp-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run MCP-Scan
        run: |
          mcp-scan scan . --output sarif > results.sarif

      - name: Upload SARIF
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif

Evidence Bundle

Descripcion

Paquete completo de evidencias para auditorias y compliance.

mcp-scan scan . --output evidence > evidence.json

Estructura del Evidence Bundle

{
  "bundle_version": "1.0",
  "generated_at": "2026-01-23T10:00:00Z",
  "scan_info": {
    "tool": "mcp-scan",
    "version": "2.0.0",
    "path": "/Users/ejemplo/mi-servidor-mcp",
    "mode": "deep",
    "config_hash": "sha256:abc123..."
  },
  "manifest": {
    "total_files": 5,
    "total_size_bytes": 12345,
    "files": [
      {
        "path": "src/server.py",
        "sha256": "abc123def456...",
        "size": 1024,
        "language": "python",
        "last_modified": "2026-01-20T15:30:00Z"
      }
    ]
  },
  "mcp_surface": {
    "sdk": {
      "name": "mcp",
      "version": "1.0.0",
      "detected_from": "import statement"
    },
    "transport": {
      "type": "stdio",
      "detected_from": "server.run()"
    },
    "tools": [
      {
        "name": "execute_command",
        "handler": "execute_command",
        "file": "src/server.py",
        "line": 24,
        "description": "Execute a system command",
        "description_hash": "sha256:...",
        "parameters": [
          {
            "name": "cmd",
            "type": "str",
            "description": "Command to execute",
            "required": true
          }
        ],
        "return_type": "str",
        "is_async": false,
        "decorators": ["@tool"]
      }
    ],
    "resources": [],
    "prompts": [],
    "auth_signals": {
      "cookies": false,
      "headers": false,
      "oauth_state": false,
      "oauth_nonce": false
    }
  },
  "findings": [
    {
      "id": "f8a3b2c1d4e5f6a7",
      "rule_id": "MCP-A003",
      "title": "Direct shell command execution",
      "description": "...",
      "severity": "critical",
      "confidence": "high",
      "class": "A",
      "location": {
        "file": "src/server.py",
        "line": 25,
        "column": 5,
        "file_hash": "sha256:abc123..."
      },
      "snippet": {
        "text": "subprocess.run(cmd, shell=True)",
        "hash": "sha256:..."
      },
      "context": {
        "before": ["@tool", "def execute_command(cmd: str):"],
        "line": "    return subprocess.run(cmd, shell=True)",
        "after": [""]
      },
      "mcp_context": {
        "tool_name": "execute_command",
        "handler_name": "execute_command",
        "transport": "stdio",
        "in_tool_handler": true
      },
      "evidence": {
        "taint_trace": [
          {
            "step": 1,
            "type": "source",
            "source_type": "tool_input",
            "location": {
              "file": "src/server.py",
              "line": 24,
              "column": 22
            },
            "code": "cmd: str",
            "description": "Parameter 'cmd' from tool input"
          },
          {
            "step": 2,
            "type": "sink",
            "sink_type": "exec",
            "location": {
              "file": "src/server.py",
              "line": 25,
              "column": 11
            },
            "code": "subprocess.run(cmd, shell=True)",
            "description": "subprocess.run with shell=True"
          }
        ],
        "sanitizers_found": [],
        "llm_analysis": {
          "analyzed": true,
          "is_injection": false,
          "confidence": 0.0,
          "category": "benign",
          "reason": "Not a prompt injection, this is command injection"
        },
        "ml_analysis": {
          "analyzed": true,
          "is_injection": false,
          "confidence": 0.1,
          "category": "benign"
        },
        "codeql_confirmed": true
      },
      "remediation": {
        "text": "Use subprocess.run with a list of arguments",
        "example": "subprocess.run(['command', 'arg1', 'arg2'])"
      }
    }
  ],
  "summary": {
    "total_findings": 4,
    "by_severity": {
      "critical": 1,
      "high": 2,
      "medium": 1,
      "low": 0,
      "info": 0
    },
    "by_class": {
      "A": 1,
      "B": 1,
      "C": 1,
      "E": 1
    },
    "baselined": 0
  },
  "msss_score": {
    "score": 45,
    "max_score": 100,
    "level": 0,
    "level_name": "Not Compliant",
    "level_requirements": {
      "level_1": 60,
      "level_2": 80,
      "level_3": 90
    },
    "category_breakdown": {
      "A": {
        "weight": 0.22,
        "max_points": 22,
        "earned_points": 0,
        "penalty": 22,
        "findings": 1
      },
      "B": {
        "weight": 0.13,
        "max_points": 13,
        "earned_points": 8,
        "penalty": 5,
        "findings": 1
      }
    },
    "penalties": {
      "critical_findings": 1,
      "critical_multiplier": 2.0,
      "total_penalty": 34
    }
  },
  "duration": {
    "total_ms": 5234,
    "discovery_ms": 120,
    "parsing_ms": 890,
    "surface_ms": 234,
    "analysis_ms": 3456,
    "reporting_ms": 534
  },
  "checksums": {
    "manifest": "sha256:...",
    "findings": "sha256:...",
    "bundle": "sha256:..."
  }
}

Uso para Auditorias

El Evidence Bundle es util para:

  1. Auditorias de seguridad - Evidencia completa de analisis
  2. Compliance - Documentacion de due diligence
  3. Certificacion - Prueba de analisis de seguridad
  4. Forensics - Investigacion de incidentes
# Generar evidence bundle con modo deep
mcp-scan scan . --mode deep --output evidence > audit-2026-01-23.json

# Verificar integridad
sha256sum audit-2026-01-23.json

Comparativa de Formatos

Caracteristica Text JSON SARIF Evidence
Legible humanos Si Parcial No Parcial
Procesable No Si Si Si
GitHub compatible No No Si No
Taint traces Parcial Si Si Completo
Hashes archivos No Si No Si
Timing detallado No Basico No Completo
Checksums No No No Si
Tamano Pequeno Medio Medio Grande

Recomendaciones por Caso de Uso

Caso de Uso Formato Recomendado
Desarrollo local text
CI/CD general json
GitHub Actions sarif
GitLab CI json o sarif
Auditoria formal evidence
Compliance evidence
Debugging json
Reportes ejecutivos text

Procesamiento de Salidas

Procesar JSON con jq

# Total de hallazgos
mcp-scan scan . -o json | jq '.summary.total'

# Solo criticos
mcp-scan scan . -o json | jq '.findings[] | select(.severity == "critical")'

# Listar archivos afectados
mcp-scan scan . -o json | jq '[.findings[].location.file] | unique'

# Score MSSS
mcp-scan scan . -o json | jq '.msss_score.score'

# Hallazgos por clase
mcp-scan scan . -o json | jq '.summary.by_class'

Procesar con Python

import json
import subprocess

# Ejecutar scan
result = subprocess.run(
    ["mcp-scan", "scan", ".", "--output", "json"],
    capture_output=True,
    text=True
)

# Parsear resultados
data = json.loads(result.stdout)

# Analizar
print(f"Total: {data['summary']['total']}")
print(f"Score: {data['msss_score']['score']}")

for finding in data['findings']:
    if finding['severity'] == 'critical':
        print(f"CRITICAL: {finding['title']} @ {finding['location']['file']}:{finding['location']['line']}")

Convertir Formatos

# JSON a texto resumido
mcp-scan scan . -o json | jq -r '.findings[] | "\(.severity | ascii_upcase): \(.rule_id) - \(.title) @ \(.location.file):\(.location.line)"'

# Extraer solo hallazgos de JSON
mcp-scan scan . -o json | jq '.findings' > findings-only.json

# Extraer surface de JSON
mcp-scan scan . -o json | jq '.mcp_surface' > surface.json

Anterior: Modos de Analisis | Siguiente: Gestion de Baselines