- id: MCP-001
  name: "Unauthenticated MCP tool server endpoint"
  description: "HTTP-based MCP servers that expose tools without authentication let unauthenticated clients invoke model-controlled actions directly."
  severity: critical
  category: mcp-server
  dry-run-support: full
  attack:
    tactics: [TA0001, TA0002]
    techniques: [T1190, T1059]
  standards:
    owasp-ai-top-10:
      - "LLM07: Insecure Plugin Design"
      - "LLM08: Excessive Agency"
      - "LLM06:2025 Excessive Agency"
    nist-ai-rmf:
      - "Map"
      - "Manage"
    nist-ssdf:
      - "Protect externally reachable AI control surfaces"
  condition: |
    $auditServices($)[
      $contains($nullSafeProp($, 'cdx:mcp:transport'), 'streamable-http')
      and authenticated != true
      and (
        $prop($, 'cdx:mcp:capabilities:tools') = 'true'
        or $prop($, 'cdx:mcp:toolCount') != '0'
      )
    ]
  location: |
    {
      "bomRef": $."bom-ref",
      "file": $prop($, 'SrcFile'),
      "purl": endpoints[0]
    }
  message: "MCP server '{{ name }}' exposes tool endpoints without authentication"
  mitigation: "Require bearer-token or equivalent authentication before exposing HTTP MCP tool endpoints."
  evidence: |
    {
      "transport": $prop($, 'cdx:mcp:transport'),
      "toolCount": $prop($, 'cdx:mcp:toolCount'),
      "endpoints": endpoints,
      "sdkImports": $prop($, 'cdx:mcp:sdkImports')
    }
- id: MCP-002
  name: "Unauthenticated MCP HTTP server"
  description: "Streamable HTTP MCP servers should authenticate incoming requests before serving prompts, resources, or tools."
  severity: high
  category: mcp-server
  dry-run-support: full
  attack:
    tactics: [TA0001]
    techniques: [T1190]
  standards:
    owasp-ai-top-10:
      - "LLM07: Insecure Plugin Design"
    nist-ai-rmf:
      - "Map"
      - "Manage"
    nist-ssdf:
      - "Authenticate and authorize AI-facing service endpoints"
  condition: |
    $auditServices($)[
      $contains($nullSafeProp($, 'cdx:mcp:transport'), 'streamable-http')
      and authenticated != true
    ]
  location: |
    {
      "bomRef": $."bom-ref",
      "file": $prop($, 'SrcFile'),
      "purl": endpoints[0]
    }
  message: "MCP HTTP endpoint '{{ endpoints[0] }}' is reachable without authentication"
  mitigation: "Protect MCP HTTP endpoints with authentication and validate Origin/host binding for local deployments."
  evidence: |
    {
      "officialSdk": $prop($, 'cdx:mcp:officialSdk'),
      "transport": $prop($, 'cdx:mcp:transport'),
      "promptCount": $prop($, 'cdx:mcp:promptCount'),
      "resourceCount": $prop($, 'cdx:mcp:resourceCount'),
      "toolCount": $prop($, 'cdx:mcp:toolCount')
    }
- id: MCP-003
  name: "Network-exposed non-official MCP server"
  description: "MCP servers built on non-official SDKs or wrappers deserve extra review before being exposed over HTTP, especially when they register tools."
  severity: medium
  category: mcp-server
  dry-run-support: full
  attack:
    tactics: [TA0001]
    techniques: [T1195.001]
  standards:
    owasp-ai-top-10:
      - "LLM05: Supply Chain Vulnerabilities"
      - "LLM07: Insecure Plugin Design"
      - "LLM03:2025 Supply Chain"
    nist-ai-rmf:
      - "Govern"
      - "Map"
    nist-ssdf:
      - "Verify provenance of AI and automation integrations"
  condition: |
    $auditServices($)[
      $contains($nullSafeProp($, 'cdx:mcp:transport'), 'streamable-http')
      and $prop($, 'cdx:mcp:officialSdk') = 'false'
      and (
        $prop($, 'cdx:mcp:capabilities:tools') = 'true'
        or $prop($, 'cdx:mcp:toolCount') != '0'
        or $count(endpoints) > 0
      )
    ]
  location: |
    {
      "bomRef": $."bom-ref",
      "file": $prop($, 'SrcFile'),
      "purl": endpoints[0]
    }
  message: "MCP server '{{ name }}' is network-accessible but relies on a non-official SDK or wrapper"
  mitigation: "Review the SDK provenance, pin exact versions, and harden authentication/authorization before exposing the server."
  evidence: |
    {
      "sdkImports": $prop($, 'cdx:mcp:sdkImports'),
      "toolCount": $prop($, 'cdx:mcp:toolCount'),
      "providerNames": $prop($, 'cdx:mcp:providerNames'),
      "modelNames": $prop($, 'cdx:mcp:modelNames')
    }

- id: MCP-004
  name: "Configured MCP endpoint lacks auth posture"
  description: "MCP services discovered only from client configuration files still need explicit authentication or OAuth posture when they resolve to network-accessible HTTP endpoints."
  severity: high
  category: mcp-server
  dry-run-support: full
  attack:
    tactics: [TA0001]
    techniques: [T1190]
  standards:
    owasp-ai-top-10:
      - "LLM07: Insecure Plugin Design"
      - "LLM08: Excessive Agency"
      - "LLM06:2025 Excessive Agency"
    nist-ai-rmf:
      - "Map"
      - "Manage"
    nist-ssdf:
      - "Review and harden configured external AI control surfaces"
  condition: |
    $auditServices($)[
      $prop($, 'cdx:mcp:inventorySource') = 'config-file'
      and $contains($nullSafeProp($, 'cdx:mcp:transport'), 'http')
      and authenticated != true
    ]
  location: |
    {
      "bomRef": $."bom-ref",
      "file": $prop($, 'SrcFile'),
      "purl": endpoints[0]
    }
  message: "Configured MCP endpoint '{{ endpoints[0] }}' lacks any discovered auth posture"
  mitigation: "Document bearer or OAuth requirements for configured MCP endpoints before allowing clients to auto-connect."
  evidence: |
    {
      "configFormat": $prop($, 'cdx:mcp:configFormat'),
      "configKey": $prop($, 'cdx:mcp:configKey'),
      "authPosture": $prop($, 'cdx:mcp:authPosture'),
      "trustProfile": $prop($, 'cdx:mcp:trustProfile')
    }

- id: MCP-005
  name: "MCP configuration exposes inline credentials"
  description: "MCP configs that embed tokens, API keys, or other secrets directly in args, env values, or headers create immediate credential-handling and supply-chain review risk."
  severity: critical
  category: mcp-server
  dry-run-support: full
  attack:
    tactics: [TA0006]
    techniques: [T1552]
  standards:
    owasp-ai-top-10:
      - "LLM05: Supply Chain Vulnerabilities"
      - "LLM07: Insecure Plugin Design"
      - "LLM03:2025 Supply Chain"
    nist-ai-rmf:
      - "Govern"
      - "Manage"
    nist-ssdf:
      - "Protect secrets used by automation and AI integrations"
  condition: |
    $auditServices($)[
      $prop($, 'cdx:mcp:inventorySource') = 'config-file'
      and $prop($, 'cdx:mcp:credentialExposure') = 'true'
    ]
  location: |
    {
      "bomRef": $."bom-ref",
      "file": $prop($, 'SrcFile')
    }
  message: "MCP config entry '{{ name }}' exposes inline credentials"
  mitigation: "Move secrets out of config files and command args into secret stores or environment references that can be managed separately."
  evidence: |
    {
      "configFormat": $prop($, 'cdx:mcp:configFormat'),
      "configKey": $prop($, 'cdx:mcp:configKey'),
      "credentialExposureFieldCount": $prop($, 'cdx:mcp:credentialExposureFieldCount'),
      "credentialIndicatorCount": $prop($, 'cdx:mcp:credentialIndicatorCount'),
      "credentialReferenceCount": $prop($, 'cdx:mcp:credentialReferenceCount')
    }

- id: MCP-006
  name: "MCP configuration suggests confused-deputy risk"
  description: "Dynamic client registration combined with a static configured client ID can create confused-deputy style authorization risk in MCP deployments."
  severity: high
  category: mcp-server
  dry-run-support: full
  attack:
    tactics: [TA0006]
    techniques: [T1528]
  standards:
    owasp-ai-top-10:
      - "LLM07: Insecure Plugin Design"
      - "LLM08: Excessive Agency"
      - "LLM06:2025 Excessive Agency"
    nist-ai-rmf:
      - "Govern"
      - "Map"
    nist-ssdf:
      - "Review AI authorization delegation and client registration flows"
  condition: |
    $auditServices($)[
      $prop($, 'cdx:mcp:inventorySource') = 'config-file'
      and $prop($, 'cdx:mcp:security:confusedDeputyRisk') = 'high'
    ]
  location: |
    {
      "bomRef": $."bom-ref",
      "file": $prop($, 'SrcFile')
    }
  message: "MCP config entry '{{ name }}' combines dynamic client registration with a static client identity"
  mitigation: "Avoid mixing DCR with shared static client identities; isolate delegated clients and validate downstream authorization assumptions."
  evidence: |
    {
      "configFormat": $prop($, 'cdx:mcp:configFormat'),
      "configKey": $prop($, 'cdx:mcp:configKey'),
      "supportsDCR": $prop($, 'cdx:mcp:auth:supportsDCR'),
      "authPosture": $prop($, 'cdx:mcp:authPosture')
    }

- id: MCP-007
  name: "MCP configuration forwards bearer or access tokens"
  description: "Token-forwarding and passthrough settings in MCP configs deserve review because they can propagate delegated credentials across trust boundaries."
  severity: high
  category: mcp-server
  dry-run-support: full
  attack:
    tactics: [TA0006]
    techniques: [T1528]
  standards:
    owasp-ai-top-10:
      - "LLM07: Insecure Plugin Design"
      - "LLM08: Excessive Agency"
      - "LLM06:2025 Excessive Agency"
    nist-ai-rmf:
      - "Govern"
      - "Manage"
    nist-ssdf:
      - "Review delegated token forwarding and trust-boundary crossings"
  condition: |
    $auditServices($)[
      $prop($, 'cdx:mcp:inventorySource') = 'config-file'
      and $prop($, 'cdx:mcp:security:tokenPassthroughRisk') = 'high'
    ]
  location: |
    {
      "bomRef": $."bom-ref",
      "file": $prop($, 'SrcFile')
    }
  message: "MCP config entry '{{ name }}' forwards or passes through bearer-like credentials"
  mitigation: "Prefer server-side credential exchange or scoped token minting instead of forwarding end-user tokens through MCP configs."
  evidence: |
    {
      "configFormat": $prop($, 'cdx:mcp:configFormat'),
      "configKey": $prop($, 'cdx:mcp:configKey'),
      "trustProfile": $prop($, 'cdx:mcp:trustProfile'),
      "authPosture": $prop($, 'cdx:mcp:authPosture')
    }

- id: MCP-008
  name: "MCP configuration file is included in a build or post-build SBOM"
  description: "Committed MCP client configuration files can carry trust, auth, and distribution sensitivity even when they are not actively used during the current scan."
  severity: medium
  category: mcp-server
  dry-run-support: full
  standards:
    owasp-ai-top-10:
      - "LLM07: Insecure Plugin Design"
      - "LLM08: Excessive Agency"
      - "LLM06:2025 Excessive Agency"
    nist-ai-rmf:
      - "Govern"
      - "Map"
    nist-ssdf:
      - "Review configured AI control surfaces before release"
  condition: |
    components[
      $prop($, 'cdx:file:kind') = 'mcp-config'
      and $count($$.metadata.lifecycles[phase = 'build' or phase = 'post-build']) > 0
    ]
  location: |
    {
      "bomRef": $."bom-ref",
      "file": $prop($, 'SrcFile')
    }
  message: "MCP config file '{{ name }}' is included in a build/post-build SBOM"
  mitigation: "Review the config with '--bom-audit --bom-audit-categories mcp-server', consider '--tlp-classification AMBER' before sharing the BOM broadly, or rerun with '--exclude-type mcp' if config artifacts should be omitted."
  evidence: |
    {
      "configFormat": $prop($, 'cdx:mcp:configFormat'),
      "configuredServiceCount": $prop($, 'cdx:mcp:configuredServiceCount'),
      "configuredServiceNames": $prop($, 'cdx:mcp:configuredServiceNames')
    }
