first-epss-mcp-server

v0.1.2 pre-1.0

Look up FIRST EPSS exploitation scores and daily history, find CVEs by score threshold, and prioritize CVEs with caller-supplied CVSS via MCP. STDIO or Streamable HTTP.

first-epss.caseyjhand.com/mcp
claude mcp add --transport http first-epss-mcp-server https://first-epss.caseyjhand.com/mcp
codex mcp add first-epss-mcp-server --url https://first-epss.caseyjhand.com/mcp
{
  "mcpServers": {
    "first-epss-mcp-server": {
      "url": "https://first-epss.caseyjhand.com/mcp"
    }
  }
}
gemini mcp add --transport http first-epss-mcp-server https://first-epss.caseyjhand.com/mcp
{
  "mcpServers": {
    "first-epss-mcp-server": {
      "command": "bunx",
      "args": [
        "mcp-remote",
        "https://first-epss.caseyjhand.com/mcp"
      ]
    }
  }
}
{
  "mcpServers": {
    "first-epss-mcp-server": {
      "type": "http",
      "url": "https://first-epss.caseyjhand.com/mcp"
    }
  }
}
curl -X POST https://first-epss.caseyjhand.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'

Tools

5

epss_get_scores

open-world

Retrieve latest available or historically dated FIRST EPSS probability and percentile for supplied CVEs. Process up to 500 unique entries from batchOffset; response byte limits can return fewer whole entries. Resume with nextBatchOffset as batchOffset, the original cves and returned score date as date. deferredCves were not queried; withheldCves were processed but omitted, and either list can be a declared preview. Missing scores remain unknown; use epss_list_reference for coverage and interpretation.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "epss_get_scores",
    "arguments": {
      "cves": "<cves>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "cves": {
      "description": "One to 5000 CVE identifiers; whitespace, comma or semicolon-delimited strings are also accepted.",
      "minItems": 1,
      "maxItems": 5000,
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128,
        "description": "Complete CVE-YYYY-NNNN identifier; whitespace, case and Unicode dashes are normalized."
      }
    },
    "date": {
      "description": "UTC date YYYY-MM-DD from 2021-04-14 through today; omitted or blank selects latest available data.",
      "type": "string",
      "pattern": "^\\s*(?:\\d{4}-\\d{2}-\\d{2}\\s*)?$"
    },
    "batchOffset": {
      "default": 0,
      "description": "Resume in first-occurrence normalized unique input order; resubmit the original cves, returned score date and original policy/severity inputs.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "cves",
    "batchOffset"
  ],
  "additionalProperties": false
}
view source ↗

epss_get_timeseries

open-world

Retrieve an EPSS anchor and up to 30 preceding daily observations for up to 50 unique CVEs from batchOffset. Response byte limits retain whole history items. Resume CVE batches with nextBatchOffset as batchOffset, the original cves and returned score date as date; withheldCves were processed, deferredCves were not queried, and lists can be declared previews. Exact 7-day and 30-day deltas require their calendar baselines; gaps remain unknown. Model boundaries do not explain score movement. Re-anchor using previousAnchorDate for the preceding history window; that snapshot may be unavailable.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "epss_get_timeseries",
    "arguments": {
      "cves": "<cves>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "cves": {
      "description": "One to 5000 CVE identifiers; whitespace, comma or semicolon-delimited strings are also accepted.",
      "minItems": 1,
      "maxItems": 5000,
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128,
        "description": "Complete CVE-YYYY-NNNN identifier; whitespace, case and Unicode dashes are normalized."
      }
    },
    "date": {
      "description": "UTC date YYYY-MM-DD from 2021-04-14 through today; omitted or blank selects latest available data.",
      "type": "string",
      "pattern": "^\\s*(?:\\d{4}-\\d{2}-\\d{2}\\s*)?$"
    },
    "batchOffset": {
      "default": 0,
      "description": "Resume in first-occurrence normalized unique input order; resubmit the original cves, returned score date and original policy/severity inputs.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "cves",
    "batchOffset"
  ],
  "additionalProperties": false
}
view source ↗

epss_query_threshold

open-world

Discover CVEs using inclusive EPSS or percentile bounds, CVE year or dataset-addition recency; filters intersect and at least one is required. Examine one candidate page ordered by EPSS descending. Each serialized response surface fits 65536 UTF-8 bytes; budgetLimited and withheldCount disclose whole matches withheld, with nextOffset at the first withheld match. Year filtering can return an empty page with nextOffset; candidateTotal is a broad-query total, not an exact-year total. Continue with the same filters, limit, returned score date and nextOffset.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "epss_query_threshold",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "minEpss": {
      "description": "Inclusive minimum EPSS probability.",
      "type": "number",
      "minimum": 0,
      "maximum": 1
    },
    "maxEpss": {
      "description": "Inclusive maximum EPSS probability.",
      "type": "number",
      "minimum": 0,
      "maximum": 1
    },
    "minPercentile": {
      "description": "Inclusive minimum population percentile rank.",
      "type": "number",
      "minimum": 0,
      "maximum": 1
    },
    "maxPercentile": {
      "description": "Inclusive maximum population percentile rank.",
      "type": "number",
      "minimum": 0,
      "maximum": 1
    },
    "year": {
      "description": "Exact CVE year from 1999 through the current UTC year; candidate pages may contain no matches.",
      "type": "integer",
      "minimum": 1999,
      "maximum": 9007199254740991
    },
    "addedWithinDays": {
      "description": "Dataset-addition recency relative to upstream present, independent of historical date.",
      "type": "integer",
      "minimum": 1,
      "maximum": 100000
    },
    "date": {
      "description": "UTC date YYYY-MM-DD from 2021-04-14 through today; omitted or blank selects latest available data.",
      "type": "string",
      "pattern": "^\\s*(?:\\d{4}-\\d{2}-\\d{2}\\s*)?$"
    },
    "limit": {
      "default": 100,
      "description": "Maximum candidates examined per page, before exact-year filtering.",
      "type": "integer",
      "minimum": 1,
      "maximum": 10000
    },
    "offset": {
      "default": 0,
      "description": "Candidate-space offset; use returned nextOffset for continuation.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "limit",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

epss_prioritize_cves

open-world

Assign remediation tiers using latest or dated EPSS and caller-supplied CVSS base severity. Defaults are severity >= 7 and EPSS probability >= 0.10; select percentile explicitly for population rank. Missing severity stays in epssOnly and missing EPSS stays unscored. Thresholds are policy conventions, not FIRST guidance. Process up to 500 unique entries from batchOffset, returning whole entries within the byte budget. Resume using nextBatchOffset as batchOffset, the original cves with original cvssBaseScore values, returned score date as date, and the same severityThreshold and likelihood. Deferred lists may be declared previews; withheldCves were already processed.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "epss_prioritize_cves",
    "arguments": {
      "cves": "<cves>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "batchOffset": {
      "default": 0,
      "description": "Resume in first-occurrence normalized unique input order; resubmit the original cves, returned score date and original policy/severity inputs.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "date": {
      "description": "UTC date YYYY-MM-DD from 2021-04-14 through today; omitted or blank selects latest available data.",
      "type": "string",
      "pattern": "^\\s*(?:\\d{4}-\\d{2}-\\d{2}\\s*)?$"
    },
    "cves": {
      "minItems": 1,
      "maxItems": 5000,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "cve": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "Complete CVE-YYYY-NNNN identifier; whitespace, case and Unicode dashes are normalized."
          },
          "cvssBaseScore": {
            "description": "Optional caller-supplied severity; absent remains unknown.",
            "type": "number",
            "minimum": 0,
            "maximum": 10
          }
        },
        "required": [
          "cve"
        ],
        "additionalProperties": false,
        "description": "CVE identifier with optional supplied severity."
      },
      "description": "One to 5000 CVEs with optional caller severity; process up to 500 unique identifiers from batchOffset."
    },
    "severityThreshold": {
      "default": 7,
      "description": "Inclusive high severity threshold, default 7.",
      "type": "number",
      "minimum": 0,
      "maximum": 10
    },
    "likelihood": {
      "description": "Select one likelihood metric and threshold; omitted uses EPSS >= 0.10.",
      "oneOf": [
        {
          "type": "object",
          "properties": {
            "metric": {
              "type": "string",
              "const": "epss",
              "description": "Exploitation probability metric."
            },
            "threshold": {
              "type": "number",
              "minimum": 0,
              "maximum": 1,
              "description": "0–1 inclusive probability cutoff."
            }
          },
          "required": [
            "metric",
            "threshold"
          ],
          "additionalProperties": false,
          "description": "Probability-based likelihood policy."
        },
        {
          "type": "object",
          "properties": {
            "metric": {
              "type": "string",
              "const": "percentile",
              "description": "Population rank metric; not probability."
            },
            "threshold": {
              "type": "number",
              "minimum": 0,
              "maximum": 1,
              "description": "0–1 inclusive percentile cutoff."
            }
          },
          "required": [
            "metric",
            "threshold"
          ],
          "additionalProperties": false,
          "description": "Percentile-based likelihood policy."
        }
      ]
    }
  },
  "required": [
    "batchOffset",
    "cves",
    "severityThreshold"
  ],
  "additionalProperties": false
}
view source ↗

epss_list_reference

Explain FIRST EPSS interpretation, model publishing dates, lookup coverage and transparent prioritization policy. Use this static reference before interpreting missing scores, score movement or probability versus percentile thresholds.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "epss_list_reference",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "topic": {
      "default": "all",
      "description": "interpretation: score meaning; models: publishing history; coverage: limits and missing data; prioritization: tier policy; all: every topic.",
      "type": "string",
      "enum": [
        "all",
        "interpretation",
        "models",
        "coverage",
        "prioritization"
      ]
    }
  },
  "required": [
    "topic"
  ],
  "additionalProperties": false
}
view source ↗