# jonnybottles/patch-tuesday-mcp [Health: Active]

**Category:** 🔒 Security  
**Repository:** https://github.com/jonnybottles/patch-tuesday-mcp  
**GitHub Stars:** 4  
**Views:** 1  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/jonnybottles-patch-tuesday-mcp

## Description
Microsoft Patch Tuesday triage from the official MSRC Security Update Guide. Monthly rollups, CVE/KB lookups, supersedence chains, product watchlists, and urgency-ranked results enriched with EPSS scores and the CISA KEV catalog. No API keys; also available as a free hosted remote endpoint. uvx patch-tuesday-mcp

## Tools
Capabilities this server exposes over MCP:

- **msrc_search** — Search Microsoft security updates (Patch Tuesday) from the official MSRC API.

Combines keyword search, CVE/KB lookup, and product/severity/exploitation
filtering into a single flexible tool. All filter parameters are optional
and can be combined. When no filters are provided, returns the most urgent
vulnerabilities from the most recent *released* Patch Tuesday (CISA-KEV-
listed or exploited first, then by EPSS exploitation probability, severity,
and CVSS score). The upcoming month's document exists before its Patch
Tuesday but only holds early Chromium/third-party and out-of-band entries;
it is skipped by default and served only when requested via month=.
Results are enriched with EPSS scores (FIRST.org daily exploit
prediction, 0-1) and CISA KEV (Known Exploited Vulnerabilities) catalog
data when available.

Use this tool to:
- Get the latest Patch Tuesday overview (include_stats=True, limit=0)
- Browse the most urgent fixes this month (no filters)
- Look up a specific CVE with full detail (cve="CVE-2026-41108") -- works
  across all months, returns KBs, affected products, CVSS, description,
  FAQs, EPSS score, and KEV status
- Find which CVEs a KB article fixes (kb="5094123" or kb="KB5094123") --
  scans recent months, or a specific month when combined with month=
- Look up many KBs in one call (kb=["5094123", "KB5094127", ...], up to
  30) -- e.g. a machine's installed-update list; returns one grouped
  per-KB result entry each, with per-KB found/not-found status
- Check whether a KB has been superseded by newer patches (kb="5087538",
  include_chain=True) -- walks Microsoft-stated supersedence links
- See what Microsoft has confirmed an update breaks (kb=...,
  include_known_issues=True) -- known issues from the KB's public support
  page: symptoms, workarounds, and the resolving update when stated
- See what an update changes (kb=..., include_update_summary=True) -- the
  KB support page's summary and improvements highlights, beyond the
  security fixes already listed in the MSRC data
- Find KEV-listed CVEs this month (kev=True) -- confirmed exploited, with
  federal remediation due dates
- High exploitation probability (min_epss=0.5) -- EPSS >= 50%
- Search by keyword (query="Exchange" or query="DNS spoofing")
- Filter to a product (product="Windows Server 2022") -- partial match
- Filter to a product watchlist (product_profile="identity-core", or
  products=["Exchange Server", "Windows Server"] /
  product_families=["Windows", "Azure"]) -- keeps vulns matching any listed
  product or family; matching is local and profiles never leave the host
- Filter by severity (severity="Critical") -- Critical/Important/Moderate/Low
- Find actively exploited vulnerabilities (exploited=True)
- Find publicly disclosed zero-days (publicly_disclosed=True)
- Filter by CVSS score (min_cvss=8.0)
- Look at a past month (month="2026-Apr" or month="2026-04")
- Combine filters (product="Exchange" + severity="Critical" + month="2026-05")
- Search a historical range (query="HTTP.sys" + months_back=6, or
  start_month="2026-Jan" + end_month="2026-Jun") -- aggregates matching
  CVEs across released months with per-month trend counts
- Paginate with offset (offset=10, limit=10 for page 2)

Args:
    query: Optional keyword; case-insensitive match across CVE ID, title,
        description, component tag, and affected product names.
    cve: Optional CVE ID (e.g. "CVE-2026-41108"). Fast path: ignores other
        filters and returns full detail for that single CVE, searching
        across all months automatically.
    kb: Optional KB article number (e.g. "5094123" or "KB5094123") or a
        list of up to 30 of them for a batched lookup. Fast path: returns
        the CVEs fixed by that KB, scanning the most recent months (up to
        6), or only the given month when month= is also set. A list input
        returns a grouped response instead: a results array with one entry
        per KB ("kb", "found", and on success the same body as a
        single-KB lookup; on a miss "error"/"error_kind"), deduplicated,
        order preserved. limit/offset apply per KB; other filters are
        ignored. Accepts numeric KB ids only (any malformed list entry
        fails the whole call); kb_articles in results may also contain
        non-KB vendor-fix labels such as "Release Notes", which cannot be
        looked up here.
    month: Optional monthly release to search, formatted "2026-Apr" or
        "2026-04". Defaults to the most recent release whose Patch
        Tuesday (second Tuesday of the month) has already occurred; pass
        the upcoming month explicitly to see its pre-release entries.
        Combined with kb=, restricts the KB lookup to that month.
    product: Optional product name filter (case-insensitive partial match
        against affected product names, e.g. "Windows Server 2022").
    product_profile: Optional named watchlist (e.g. "identity-core") that
        expands locally into product/family matchers. Built-in profiles can
        be overridden/extended via a JSON file at MSRC_PROFILES_PATH. An
        unknown name returns an invalid_input error listing the available
        profiles. Profile contents are matched locally and never sent to
        MSRC, FIRST.org, CISA, or telemetry.
    products: Optional list of product-name partial matchers. A vulnerability
        is kept if any entry matches one of its affected products.
    product_families: Optional list of product-family partial matchers. A
        vulnerability is kept if any entry matches one of its product
        families. Combined with products/product_profile as a union (match
        any listed product OR family).
    severity: Optional maximum-severity filter. Valid values: Critical,
        Important, Moderate, Low.
    exploited: Optional filter for vulnerabilities known to be exploited
        in the wild (True) or not (False), per Microsoft's assessment.
    publicly_disclosed: Optional filter for publicly disclosed
        vulnerabilities.
    kev: Optional filter for CVEs on (True) or off (False) the CISA Known
        Exploited Vulnerabilities catalog.
    ransomware: Optional filter for CVEs whose CISA KEV entry reports
        known ransomware campaign use (True) or not / not on KEV (False).
    exploitation_likely: Optional filter on Microsoft's latest-release
        exploitation assessment: True matches "Exploitation More Likely"
        or "Exploitation Detected"; False matches everything else
        (including unassessed entries). Matching results include an
        exploitation_assessment field.
    cwe: Optional weakness filter; case-insensitive substring match
        against CWE entries (e.g. "CWE-416" or "use after free").
        Matching results include their cwe list.
    min_epss: Optional minimum EPSS score (0-1), the probability of
        exploitation in the next 30 days (e.g. 0.5 for >= 50%).
    min_cvss: Optional minimum CVSS base score (0-10).
    attack_vector: Optional CVSS attack-vector filter, one of N (network),
        A (adjacent), L (local), P (physical). Matches the parsed CVSS v3.x
        vector; entries without a parseable vector are excluded.
    privileges_required: Optional CVSS privileges-required filter, one of
        N (none), L (low), H (high).
    user_interaction: Optional CVSS user-interaction filter, one of
        N (none), R (required).
    scope: Optional CVSS scope filter, one of U (unchanged), C (changed).
    include_chain: When True together with kb=, adds a supersedence_chain
        showing which KBs this KB replaces (newest to oldest), walked from
        Microsoft-stated supersedence links. Ignored without kb=.
    include_guidance: When True together with cve=, adds a guidance list to
        the CVE detail output with any Microsoft-provided mitigations,
        workarounds, and will-not-fix advisories (type/description/url).
        Omitted by default to keep responses lean. Ignored without cve=.
    include_references: When True, adds deterministic reference links
        (MSRC, NVD, EPSS, and KEV when listed) to each result row in
        month/KB/trend lists. CVE detail lookups always include them.
    include_kb_details: When True, kb_articles entries become full objects
        (per-KB url, fixed_build, supersedence, sub_type, and
        restart_required) instead of bare KB numbers; on cve= lookups it
        additionally adds restart_required to each KB entry.
    include_kev_details: When True, KEV-listed rows carry the full KEV
        entry (due_date, ransomware_use, required_action, vendor_project,
        product, vulnerability_name) instead of a boolean flag; on cve=
        lookups it extends the kev block with the extra catalog fields.
    include_known_issues: When True together with kb=, adds a known_issues
        block per KB with the issues Microsoft has publicly confirmed for
        that update (title, symptoms, workaround, and the resolving KB
        when stated), scraped best-effort from the KB's support page on
        support.microsoft.com. This reports what Microsoft has confirmed
        breaks -- it does not predict behavior in a specific environment.
        The block's status field is honest about coverage: "published"
        (issues listed), "none_published" (Microsoft publishes no
        known-issues data for this KB -- the norm for most non-Windows
        products; Windows cumulative/preview updates are the main
        source), or "unavailable" (the page could not be fetched or
        parsed; NOT the same as no issues). Attached even when the KB is
        not found in MSRC security releases (e.g. preview-only updates).
        Ignored without kb=.
    include_update_summary: When True together with kb=, adds an
        update_summary block per KB describing what the update changes,
        scraped best-effort from the same support.microsoft.com KB page:
        the page's Summary/Highlights text plus its Improvements bullet
        list (size-capped; truncated=True marks a capped block). The
        status field is honest like known_issues: "published" (a summary
        exists), "none_published" (Microsoft publishes no summary section
        for this KB), or "unavailable" (the page could not be fetched or
        parsed; NOT the same as no summary). Attached even when the KB is
        not found in MSRC security releases; combines freely with
        include_known_issues -- both blocks are served by a single fetch
        of the same page. Ignored without kb=.
    include_temporal: When True, cvss blocks gain the CVSS temporal score
        Microsoft publishes (exploit-code maturity adjusted). Applies to
        cve= detail and to list rows that carry a cvss block.
    list_months: When True, ignore other filters and return the catalog of
        available monthly releases (id, title, initial/current release
        dates, newest first) — useful for discovering valid month= values
        and spotting same-month revisions.
    format: Output format for a monthly/filtered search: "json" (default,
        most complete), "markdown", or "csv". "markdown" adds a prioritized
        triage briefing (executive summary + table) under a markdown key;
        "csv" adds a spreadsheet-ready table under a csv key plus a columns
        list. The JSON vulnerabilities list is always included. Ignored for
        cve=/kb= fast-path lookups.
    report: Optional report profile for format="markdown"/"csv". Currently
        only "triage" (the default rendering) is supported; reserved for
        future report shapes.
    force_refresh: When True, bypass the in-process caches for this request
        and re-fetch the MSRC document and EPSS/KEV enrichment from source.
        Use to pick up a same-day MSRC revision or fresh EPSS/KEV data.
        Only the data needed for this request is refreshed; unrelated cached
        months are left intact.
    include_freshness: When True (or when force_refresh is used), add a
        freshness block to the response reporting the cache age and TTL of
        the MSRC document and the EPSS/KEV enrichment data.
    months_back: Optional historical-trend control; search the N most recent
        released months (N >= 1) instead of a single month, aggregating
        matches with per-month counts. Mutually exclusive with
        start_month/end_month. Capped at 12 months per request.
    start_month: Optional start of a historical-trend range (e.g. "2026-Jan"
        or "2026-01"), inclusive. When end_month is omitted the range runs
        through the latest released month. Capped at 12 months.
    end_month: Optional end of a historical-trend range (inclusive); requires
        start_month (or months_back). Pre-release months are excluded.
    limit: Maximum number of results to return (default: 10, max: 100).
        Set to 0 with include_stats=True for a stats-only month overview.
    offset: Number of results to skip for pagination (default: 0).
    include_stats: When True, includes aggregate counts (by severity,
        impact, product family, exploited, KEV, publicly disclosed) for
        the filtered result set.

Returns:
    Dictionary with:
    - month: Release ID (e.g. "2026-Jun") and title/release date
    - total_found: Number of vulnerabilities matching the filters
    - vulnerabilities: List of compact vulnerability summaries (up to
      limit) with epss_score and kev flag when available; full detail
      (epss_percentile, KEV due dates) returned for cve= lookups
    - filters_applied: Summary of which filters were used
    - stats: (only when include_stats=True) aggregate counts
    - supersedence_chain / chain_complete: (only for kb= lookups with
      include_chain=True) the walked chain, newest to oldest
    - known_issues: (only for kb= lookups with include_known_issues=True)
      per-KB block with status ("published" / "none_published" /
      "unavailable"), an issues list (title, symptoms, workaround,
      resolution, resolved_by) when published, a note otherwise, and the
      source_url of the Microsoft support page
    - update_summary: (only for kb= lookups with
      include_update_summary=True) per-KB block with status ("published"
      / "none_published" / "unavailable"), the page title, a summary
      string and an improvements list of what the update changes when
      published (truncated=True when size caps trimmed content), a note
      otherwise, and the source_url of the Microsoft support page
    - total_kbs / results: (only when kb= is a list) grouped batch output;
      results holds one entry per KB with kb, found, and either the
      single-KB response body or a per-KB error/error_kind, while the
      top-level total_found sums across all KBs
    - guidance: (only for cve= lookups with include_guidance=True) list of
      mitigation/workaround/will-not-fix advisories, when Microsoft
      provides them
    - format / markdown / csv / columns: (only when format="markdown" or
      "csv") the chosen format plus the rendered triage view; csv also
      carries the stable column-name list
    - freshness: (only with include_freshness=True or force_refresh=True)
      cache age/TTL for the MSRC document and EPSS/KEV enrichment
    - range / months_searched / trend: (only for historical-trend searches
      via months_back or start_month/end_month) the resolved month range,
      the number of months searched, and per-month aggregate counts
      (total, by_severity, exploited, publicly_disclosed, kev)
    - available_months: (only with list_months=True) the release catalog,
      newest first
    - error / error_kind: (only on failure) a message plus a category
      (invalid_input, not_found, upstream, internal)
    - note: (when relevant) explains month selection, e.g. that a newer
      pre-Patch-Tuesday document was skipped, or (with
      release_status="pre-patch-tuesday") that the requested month has
      not had its Patch Tuesday yet

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `uvx` (confidence: high):

```json
"mcpServers": {
  "patch-tuesday-mcp": {
    "command": "uvx",
    "args": ["patch-tuesday-mcp"]
  }
}
```

## Documentation & README

### Disclaimer: This is an independent, self-built project and is not an official Microsoft tool or service.

# Patch Tuesday MCP Server

[![patch-tuesday-mcp MCP server](https://glama.ai/mcp/servers/jonnybottles/patch-tuesday-mcp/badges/score.svg)](https://glama.ai/mcp/servers/jonnybottles/patch-tuesday-mcp)
[![PyPI](https://img.shields.io/pypi/v/patch-tuesday-mcp)](https://pypi.org/project/patch-tuesday-mcp/)
[![MCP Registry](https://img.shields.io/badge/MCP_Registry-io.github.jonnybottles%2Fpatch--tuesday-blue)](https://registry.modelcontextprotocol.io/v0/servers?search=patch-tuesday)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)

mcp-name: io.github.jonnybottles/patch-tuesday

Ask your AI assistant about Microsoft security updates. This Python-based MCP (Model Context Protocol) server connects AI assistants like Claude, Copilot, and ChatGPT to the [MSRC Security Update Guide](https://msrc.microsoft.com/update-guide) — the authoritative source for every CVE Microsoft patches — enabling natural-language queries over Patch Tuesday releases: CVEs, KB articles, severity ratings, CVSS scores, affected products, and exploited-in-the-wild status.

## What It Does

Patch Tuesday MCP Server bridges Microsoft's official CVRF security update API and your AI assistant, allowing you to:

- **Get the monthly rollup** - "What did this month's Patch Tuesday fix?"
- **Find what's actively exploited** - "Which vulnerabilities are being exploited in the wild?"
- **Look up any CVE** - "Tell me about CVE-2026-41108" (KBs, affected products, CVSS, description)
- **Map KBs to CVEs** - "Which vulnerabilities does KB5094123 fix?"
- **Filter by product** - "What Critical CVEs affect Windows Server 2022 this month?"
- **Track zero-days** - "Were any publicly disclosed vulnerabilities patched in April?"
- **See what's confirmed exploited** - "Which of this month's CVEs are on the CISA KEV list?" — with federal remediation due dates
- **Rank by exploitation probability** - "Show me CVEs with EPSS above 50%" — daily FIRST.org exploit prediction scores
- **Find zero-click, internet-reachable criticals** - "Which Critical CVEs are network-reachable with no privileges and no user interaction?" — filter on the parsed CVSS attack vector, privileges, and user-interaction fields
- **Jump straight to authoritative sources** - every CVE detail carries ready-to-open MSRC, NVD, EPSS, and (when listed) CISA KEV reference links
- **Avoid stale patches** - "Is KB5087538 superseded by anything newer?" — walks Microsoft's supersedence links
- **Get mitigations when there's no patch yet** - "Are there mitigations or workarounds for CVE-2026-47291?" — surfaces Microsoft's mitigation, workaround, and will-not-fix guidance
- **Spot trends over time** - "How many HTTP.sys CVEs shipped over the last 6 months?" (`months_back=6`, or `start_month`/`end_month`) — aggregates matches across released months with per-month counts
- **Filter by Microsoft's own exploitation forecast** - "Which of this month's CVEs does Microsoft rate 'Exploitation More Likely'?" (`exploitation_likely=True`)
- **Spot ransomware-weaponized CVEs** - "Which CVEs this month are used in known ransomware campaigns?" (`ransomware=True`; add `include_kev_details=True` for the full CISA entry with required actions)
- **Plan the deployment, not just the priority** - "Does KB5094123 require a restart, and what build fixes it?" (`include_kb_details=True` adds per-KB URLs, fixed builds, supersedence, and restart requirements)
- **Know what Microsoft says an update breaks** - "Any known issues with KB5094126 before I roll it out?" (`include_known_issues=True` adds each KB's Microsoft-confirmed known issues — symptoms, workarounds, and the resolving update — best-effort from its public support page; published mainly for Windows updates, and the response says explicitly when Microsoft publishes none)
- **Know what an update changes, not just what it fixes** - "What's actually in KB5099536 besides the security fixes?" (`include_update_summary=True` adds the KB support page's summary and improvements highlights — the change-description content the MSRC security data doesn't carry — from the same page fetch as the known-issues lookup)
- **Slice a month by weakness class** - "Show me this month's use-after-free CVEs" (`cwe="CWE-416"` or `cwe="use after free"`)
- **Discover the release catalog** - "Which monthly releases are available, and when were they last revised?" (`list_months=True`)
- **Export a triage briefing** - "Give me this month's Critical CVEs as a Markdown report" or "…as CSV" — a prioritized executive summary and table, or a spreadsheet-ready export (`format="markdown"` / `format="csv"`)
- **Force-refresh & check data freshness** - "Re-pull this month's data fresh" (`force_refresh=True`) bypasses the in-process caches; `include_freshness=True` reports the cache age/TTL of the MSRC document and EPSS/KEV enrichment
- **Prioritize patching** - Results are sorted most-urgent-first: KEV/exploited, then EPSS, then severity, then CVSS

Perfect for security analysts, sysadmins, and IT professionals who triage Microsoft security updates every month — without clicking through the Security Update Guide portal.

Data comes from the official, public [MSRC CVRF v3 API](https://github.com/microsoft/MSRC-Microsoft-Security-Updates-API). No authentication or API key required.

## Why This Server?

**This is the only MCP server that models the Patch Tuesday release itself.** Plenty of MCP servers can look up a CVE — general-purpose vulnerability aggregators fan a known CVE ID out across NVD, OSV, and threat-intel feeds. They answer *"tell me about CVE-X"*. But they have no concept of a monthly Microsoft release, a KB article, or a product family — so they structurally cannot answer the questions a Microsoft shop actually asks on the second Tuesday of every month:

| The question you actually have | Generic CVE lookup servers | patch-tuesday-mcp |
|---|---|---|
| "Summarize this month's Patch Tuesday" | ❌ no concept of a release | ✅ rollup + stats in one call |
| "What Critical CVEs affect Windows Server 2022 this month?" | ❌ can't filter by Microsoft product | ✅ product & family filtering |
| "Which vulnerabilities does KB5094123 fix?" | ❌ no KB awareness | ✅ KB ↔ CVE mapping |
| "What's being exploited in the wild right now?" | ⚠️ per-CVE only, if you already know the CVE | ✅ filter the whole month |
| "What do I patch first?" | ❌ | ✅ urgency-sorted: exploited/KEV → EPSS → severity → CVSS |
| "Which criticals are zero-click and internet-reachable?" | ⚠️ per-CVE CVSS only | ✅ filter the month by parsed CVSS attack vector / privileges / user interaction |
| "Tell me about CVE-X" | ✅ (often with more ecosystem data) | ✅ MSRC detail: KBs, builds, supersedence, parsed CVSS, MSRC/NVD/EPSS/KEV links |

Under the hood, the difference is the data source: this server parses the full **MSRC CVRF monthly documents** — the ProductTree, per-product severity threats, exploitability assessments, and KB remediation chains that per-CVE APIs never expose. That's what makes release-centric questions possible.

Other things it deliberately gets right:

- **Zero API keys, zero accounts** — the MSRC API is public; setup is one `uvx` command
- **One tool, not thirty** — a single consolidated `msrc_search` keeps your AI client's context lean and tool selection reliable
- **Built for the monthly workflow** — triage a release, brief your team, prioritize patching, then get on with your life

## Try It Instantly — Hosted Endpoint (No Install)

A free remote instance is available at:

```
https://patch-tuesday-mcp.agreeabledesert-d0b8e491.eastus2.azurecontainerapps.io/mcp
```

No account or API key needed. The endpoint serves the same public data as a local install — for heavy use or guaranteed availability, run it locally (below) or [self-host your own](#self-hosting-as-a-remote-mcp-server). Only minimal, anonymized usage data is recorded — see [Telemetry & Privacy](#telemetry--privacy).

## Requirements

### General

- **Python 3.11+**
- An MCP-compatible client (Claude Desktop, Cursor, Claude Code, GitHub Copilot CLI, etc.)

### Using `uvx` (Recommended)

If you are installing or running the server via **`uvx`**, you must have **uv** installed first.

- **uv** (includes `uvx`): https://github.com/astral-sh/uv

Install uv:

```bash
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows (PowerShell)
irm https://astral.sh/uv/install.ps1 | iex
```

> `uvx` allows you to run the MCP server without installing the package globally.

### Using pip (Alternative)

```bash
pip install patch-tuesday-mcp
```

## Installation

### Install from PyPI

```bash
uvx patch-tuesday-mcp
```

Or install with pip:

```bash
pip install patch-tuesday-mcp
```

### Upgrade to Latest Version

```bash
uvx patch-tuesday-mcp@latest
```

Or with pip:

```bash
pip install --upgrade patch-tuesday-mcp
```

## Quick Setup

[![Set up in VS Code](https://img.shields.io/badge/Set_up_in-VS_Code-0078d4?style=flat-square&logo=visualstudiocode)](https://vscode.dev/redirect/mcp/install?name=patch-tuesday-mcp&config=%7B%22type%22%3A%20%22stdio%22%2C%20%22command%22%3A%20%22uvx%22%2C%20%22args%22%3A%20%5B%22patch-tuesday-mcp%22%5D%7D)
[![Set up in Cursor](https://img.shields.io/badge/Set_up_in-Cursor-000000?style=flat-square&logo=cursor)](https://cursor.com/docs/context/mcp)
[![Set up in Claude Code](https://img.shields.io/badge/Set_up_in-Claude_Code-9b6bff?style=flat-square&logo=anthropic)](https://code.claude.com/docs/en/mcp)
[![Set up in Copilot CLI](https://img.shields.io/badge/Set_up_in-Copilot_CLI-28a745?style=flat-square&logo=github)](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/use-copilot-cli)

> **One-click setup:** Click the VS Code badge for automatic configuration (requires `uv` installed)
> **Manual setup:** See instructions below for VS Code, Cursor, Claude Code, Copilot CLI, or Claude Desktop

## Features

- **msrc_search** – Search and filter Microsoft security updates by keyword, CVE, KB number, month, product, severity, CVSS score, exploited-in-the-wild status, or public disclosure. When no month is given, results default to the most recent release whose Patch Tuesday has already occurred — the upcoming month's pre-release document (early Chromium/out-of-band entries only) is skipped by default and available explicitly via `month=`. Results are enriched with **EPSS scores** (FIRST.org 30-day exploitation probability, `min_epss=0.5` filter) and **CISA KEV** catalog status with federal remediation due dates (`kev=True` filter) — both public, keyless sources. Filter by the **parsed CVSS v3.x exposure fields** — `attack_vector` (N/A/L/P), `privileges_required` (N/L/H), `user_interaction` (N/R), and `scope` (U/C) — to isolate, for example, network-reachable zero-click criticals; matching results surface a structured `cvss` object broken out from the raw vector string. Every CVE detail also includes a **references** block of ready-to-open links (MSRC update guide, NVD, EPSS API, and the CISA KEV catalog when the CVE is listed). Add `include_chain=True` to a KB lookup to walk Microsoft-stated **supersedence chains** (which KBs it replaces, newest → oldest). Pass a **list of KB numbers** (`kb=["5094123", "KB5094127", ...]`, up to 30) to resolve them all in one call — e.g. a machine's installed-update list as context for a patch report — and get a grouped response with one per-KB entry (found or not-found, each with the same body as a single-KB lookup); every monthly document is still fetched upstream at most once for the whole batch. Add `include_known_issues=True` to any KB lookup (single or batched) for the **Microsoft-confirmed known issues** of each update — issue titles, symptoms, workarounds, and the resolving KB when Microsoft names one — scraped best-effort from the KB's public support page with an honest per-KB status: `published`, `none_published` (Microsoft publishes no known-issues data for that KB — the norm outside Windows OS updates), or `unavailable` (retrieval/parse failure, explicitly distinct from "no issues"); it reports what Microsoft has confirmed breaks, not a prediction for your environment. Add `include_update_summary=True` to a KB lookup for **what the update changes** — the support page's Summary/Highlights text plus its Improvements bullet list (size-capped, `truncated` marks a capped block) with the same honest three-way status; both support-page blocks are served by a single fetch and one shared cache record. Add `include_guidance=True` to a CVE lookup to surface Microsoft-provided **mitigations, workarounds, and will-not-fix advisories** alongside the vendor-fix KBs. Pass `format="markdown"` or `format="csv"` to a monthly/filtered search to get an additive **triage briefing** — a prioritized executive summary and table (Markdown) or a spreadsheet-ready export with stable columns (CSV) — rendered from the same urgency ranking; the JSON `vulnerabilities` list is always included. Use `force_refresh=True` to bypass the in-process caches and re-fetch the MSRC document and EPSS/KEV enrichment for the request, and `include_freshness=True` to add a **freshness** block reporting the cache age and TTL of the MSRC document and enrichment data. Search a **historical range** instead of a single month with `months_back=N` (the N most recent released months) or `start_month`/`end_month` — the response aggregates matching CVEs across the range and adds per-month **trend** counts; ranges are capped at 12 months and reuse the existing cache/concurrency controls. Set `include_stats=True` for aggregate counts (by severity, impact, product family, exploited, KEV). Use `limit=0` with `include_stats=True` for a stats-only month overview. Filter on **Microsoft's exploitation-likelihood assessment** with `exploitation_likely=True` ("Exploitation More Likely"/"Exploitation Detected"; matches carry an `exploitation_assessment` field) and on **known ransomware campaign use** with `ransomware=True` (from the CISA KEV catalog). Opt into richer rows where you need them: `include_references=True` adds the MSRC/NVD/EPSS/KEV link block to month/KB/trend list results, `include_kev_details=True` replaces the boolean KEV flag with the full catalog entry (due date, required action, vendor/product, ransomware use), `include_kb_details=True` expands KB numbers into full objects with per-KB URL, fixed build, supersedence, sub-type, and **restart-required** status, and `include_temporal=True` adds Microsoft's **CVSS temporal score** to cvss blocks. Filter by **weakness class** with `cwe=` (ID or name substring, e.g. `cwe="CWE-416"`). Use `list_months=True` to fetch the **release catalog** (every available month with initial/current release dates — handy for valid `month=` values and spotting same-month revisions). All new fields are opt-in: the default JSON shape is unchanged.

## Product profiles (watchlists)

Scope any search to the products you actually run. Pass `product_profile="identity-core"` (built-in profiles: `identity-core`, `endpoint`, `server-infrastructure`) or supply ad-hoc `products=["Exchange Server", "Windows Server"]` / `product_families=["Windows", "Azure"]`. A vulnerability is kept if it matches **any** listed product or family. All matching is local — profile contents are never transmitted to MSRC, FIRST.org, CISA, or telemetry.

Override or extend the built-ins by pointing `MSRC_PROFILES_PATH` at a JSON file:

```json
{
  "my-estate": {
    "families": ["Windows", "Azure"],
    "products": ["Exchange Server", "Microsoft Entra"]
  }
}
```

Each entry may set `products` and/or `families` (case-insensitive partial matchers). A file entry with the same name as a built-in replaces it. An unknown `product_profile`, or a missing/invalid `MSRC_PROFILES_PATH`, returns a clear `invalid_input` error rather than falling back to a broad, unscoped result.

### Companion triage skill

A portable [agent skill](https://github.com/jonnybottles/patch-tuesday-mcp/blob/HEAD/skills/README.md) — `patch-tuesday-triage` — teaches an AI agent how to drive `msrc_search` through the monthly workflow (which searches to run, in what order, how to prioritize). It's plain Markdown and can be **deployed independently of this server**: copy `skills/patch-tuesday-triage/` into your agent's skills directory. See [`skills/README.md`](https://github.com/jonnybottles/patch-tuesday-mcp/blob/HEAD/skills/README.md) for deployment details.

## Guided triage prompt

The server registers an MCP **prompt** named `monthly_triage`. MCP clients that support prompts can select it to get a step-by-step analyst workflow built entirely on `msrc_search` — publicly disclosed zero-days, CISA KEV, exploited, network/no-auth/no-UI criticals, identity-adjacent products, endpoint/Intune, and a briefing. It accepts two optional arguments: `product_profile` (scope the whole workflow to a watchlist) and `month` (triage a specific release). No new tools are introduced — the prompt only orchestrates `msrc_search` calls.

A portable, plain-text copy of this prompt lives under [`prompts/`](https://github.com/jonnybottles/patch-tuesday-mcp/blob/HEAD/prompts/README.md) so the workflow can be used **independently of the server**.

## Prompt Examples

Once connected to an MCP client, you can ask questions like:

1. **Monthly overview**: "Summarize this month's Patch Tuesday"
2. **Exploited vulnerabilities**: "Which Microsoft vulnerabilities are being actively exploited?"
3. **CVE lookup**: "What is CVE-2026-41108 and which KB fixes it?"
4. **KB lookup**: "What does KB5094123 patch?"
5. **Machine patch report**: "Here are the KBs installed on this server: KB5094123, KB5094127, KB5093998 — what do they fix and is anything superseded?"
6. **Product filter**: "Show me Critical vulnerabilities affecting Exchange Server this month"
7. **Patch prioritization**: "What should I patch first from the June 2026 updates?"
8. **CISA KEV**: "Which of this month's CVEs are on the CISA KEV list?"
9. **EPSS**: "Show me CVEs with EPSS above 50%"
10. **Exposure filtering**: "Which Critical CVEs are network-reachable with no privileges and no user interaction?"
11. **Reference links**: "Give me the MSRC, NVD, and EPSS links for CVE-2026-41108"
12. **Mitigations & workarounds**: "Are there any mitigations or workarounds for CVE-2026-41108?"
13. **Triage report**: "Give me this month's Critical CVEs as a Markdown briefing" (or "…export them as CSV")
14. **Fresh data on demand**: "Re-pull this month's updates fresh and tell me how current the data is" (`force_refresh=True`, `include_freshness=True`)
15. **Historical trends**: "How many HTTP.sys RCE CVEs shipped over the last 6 months?" (`query="HTTP.sys"`, `months_back=6`)
16. **Supersedence**: "Is KB5087538 superseded by anything newer?"
17. **Exploitation forecast**: "Which CVEs does Microsoft rate 'Exploitation More Likely' this month?"
18. **Ransomware**: "Which of this month's CVEs are used in known ransomware campaigns?"
19. **Deployment planning**: "Does KB5094123 require a restart, and which build fixes it?"
20. **Known issues before rollout**: "What has Microsoft confirmed breaks in KB5094126, and is there a fix or workaround?" (`include_known_issues=True`)
21. **What's in an update**: "Summarize what KB5099536 changes beyond the security fixes" (`include_update_summary=True`)
22. **Weakness class**: "Show me this month's use-after-free vulnerabilities" (`cwe="CWE-416"`)
23. **Release catalog**: "Which Patch Tuesday months are available to query?"
24. **Product watchlist**: "Show me this month's Critical CVEs across my estate" (`product_profile="identity-core"`, `severity="Critical"`)
25. **Guided triage**: "Walk me through this month's triage for my identity estate" (selects the `monthly_triage` prompt with `product_profile="identity-core"`)

## Usage

### Run the MCP Server

```bash
uvx patch-tuesday-mcp
```

Or if installed with pip:

```bash
patch-tuesday-mcp
```

### Connect from VS Code

**Option 1: One-Click Install (Recommended)**

Click the **[Set up in VS Code](#quick-setup)** badge at the top of this README for automatic configuration (requires `uv` installed).

**Option 2: Manual Configuration**

VS Code stores MCP servers in a **dedicated `mcp.json` file — not `settings.json`.** Open the Command Palette (`Ctrl+Shift+P` on Windows/Linux, `Cmd+Shift+P` on macOS) and run one of:

- **`MCP: Open User Configuration`** — edits your user-level `mcp.json` (available in every workspace)
- **`MCP: Open Workspace Folder Configuration`** — edits a project-local `.vscode/mcp.json`

Then add the server. Note that VS Code uses a top-level **`"servers"`** key (unlike the `"mcpServers"` key used by the other clients below):

```json
{
  "servers": {
    "patch-tuesday": {
      "type": "stdio",
      "command": "uvx",
      "args": ["patch-tuesday-mcp"]
    }
  }
}
```

### Connect from Claude Desktop

Add to your Claude Desktop MCP config:

- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`

**Using uvx (recommended)**

```json
{
  "mcpServers": {
    "patch-tuesday": {
      "command": "uvx",
      "args": ["patch-tuesday-mcp"]
    }
  }
}
```

**Using installed package**

```json
{
  "mcpServers": {
    "patch-tuesday": {
      "command": "patch-tuesday-mcp"
    }
  }
}
```

### Connect from Cursor

**Option 1: One-Click Install (Recommended)**

```
cursor://anysphere.cursor-deeplink/mcp/install?name=patch-tuesday-mcp&config=eyJjb21tYW5kIjogInV2eCIsICJhcmdzIjogWyJwYXRjaC10dWVzZGF5LW1jcCJdfQ==
```

**Option 2: Manual Configuration**

Add to your Cursor MCP config (`~/.cursor/mcp.json`):

```json
{
  "mcpServers": {
    "patch-tuesday": {
      "command": "uvx",
      "args": ["patch-tuesday-mcp"]
    }
  }
}
```

### Connect from Claude Code

```bash
claude mcp add --transport stdio patch-tuesday -- uvx patch-tuesday-mcp
```

### Connect from GitHub Copilot CLI

Add to `~/.copilot/mcp-config.json`:

```json
{
  "mcpServers": {
    "patch-tuesday": {
      "type": "stdio",
      "command": "uvx",
      "args": ["patch-tuesday-mcp"]
    }
  }
}
```

## Self-Hosting as a Remote MCP Server

The server also supports the HTTP transport for remote/shared deployments:

```bash
MCP_TRANSPORT=http MCP_PORT=8000 patch-tuesday-mcp
# MCP endpoint: http://localhost:8000/mcp
```

Or with Docker:

```bash
docker build -t patch-tuesday-mcp .
docker run -p 8000:8000 patch-tuesday-mcp
```

HTTP-mode environment variables:

| Variable | Default | Description |
|----------|---------|-------------|
| `MCP_TRANSPORT` | `stdio` | Set to `http` for remote serving |
| `MCP_HOST` / `MCP_PORT` | `0.0.0.0` / `8000` | Bind address |
| `MCP_MAX_BODY_BYTES` | `262144` | Max request body size, returns 413 above it (`0` disables) |
| `MCP_CORS_ORIGINS` | `*` (all) | Comma-separated allowlist of browser origins. **Set an explicit list for public deployments** (e.g. `https://app.example.com`) |
| `MCP_LIMIT_CONCURRENCY` | `40` | Max concurrent in-flight connections; uvicorn responds 503 beyond it (`0` disables) |
| `MCP_TIMEOUT_KEEP_ALIVE` | `15` | Seconds before idle keep-alive connections are closed |
| `MCP_LOG_LEVEL` | `WARNING` | Root log level (`DEBUG`/`INFO`/`WARNING`/`ERROR`/`CRITICAL`); logs go to stderr |
| `MCP_MSRC_MAX_RESPONSE_BYTES` | `67108864` (64 MiB) | Cap on a single MSRC upstream response body (read while streaming, never buffered past the cap) |
| `MCP_ENRICHMENT_MAX_RESPONSE_BYTES` | `33554432` (32 MiB) | Cap on a single EPSS/KEV upstream response body |
| `MCP_KNOWN_ISSUES_MAX_RESPONSE_BYTES` | `4194304` (4 MiB) | Cap on a single support.microsoft.com KB-page body (known-issues / update-summary lookups) |
| `APPLICATIONINSIGHTS_CONNECTION_STRING` | unset | Opt-in usage telemetry (requires `pip install patch-tuesday-mcp[telemetry]`) |
| `MCP_DEPRECATION_SUNSET` | unset | ISO date (`YYYY-MM-DD`) this deployment stops serving. Set **together with** `MCP_DEPRECATION_REPLACEMENT_URL` to announce a migration (see below) |
| `MCP_DEPRECATION_REPLACEMENT_URL` | unset | URL clients should move to |
| `MCP_DEPRECATION_SINCE` | unset | Optional ISO date the deprecation was announced (emitted as an RFC 9745 `Deprecation` date) |
| `MCP_DEPRECATION_MESSAGE` | unset | Optional override for the human-readable notice text |

### Announcing a deprecation (self-hosters)

If you are retiring a deployment, set `MCP_DEPRECATION_SUNSET` and
`MCP_DEPRECATION_REPLACEMENT_URL` on **that deployment only**. The server then
reports the migration through four channels:

- a `deprecation` block on every `msrc_search` response (and on `/health`)
- `Deprecation`, `Sunset`, and `Link: <url>; rel="successor-version"` response
  headers ([RFC 9745](https://www.rfc-editor.org/rfc/rfc9745.html),
  [RFC 8594](https://www.rfc-editor.org/rfc/rfc8594.html),
  [RFC 5829](https://www.rfc-editor.org/rfc/rfc5829.html))
- the MCP server `instructions` shown to clients at connection time
- the `msrc_search` tool description

All of it is **descriptive**: it states facts about the deployment. It never
instructs a connected agent to say or do anything — tool output that issues
directives to someone else's model is prompt injection, however benign the
payload. Leave the variables unset and behavior is byte-for-byte unchanged;
setting only one of the two pair, or a malformed date, is ignored.

HTTP mode also serves `GET /health` (liveness endpoint) and runs stateless,
so it can scale to multiple replicas behind a load balancer without session
affinity.

### Hardening a public HTTP deployment

The HTTP transport is **unauthenticated** — `msrc_search` only reads public
vulnerability data, but an open endpoint is still abusable. Before exposing it
to the internet:

- **Put it behind an authenticated front door.** Terminate TLS and require auth
  at a reverse proxy / API gateway (e.g. Azure API Management, an OAuth2/OIDC
  proxy such as `oauth2-proxy`, Cloudflare Access, or your ingress controller's
  auth). This server intentionally ships no built-in auth so you can layer your
  organization's standard access control in front of it.
- **Restrict CORS.** Set `MCP_CORS_ORIGINS` to the exact origins of your MCP
  clients instead of the permissive `*` default.
- **Keep the defaults on.** Leave `MCP_MAX_BODY_BYTES` and
  `MCP_LIMIT_CONCURRENCY` at their defaults (or tighten them) — they are your
  first line of defense against oversized payloads and connection exhaustion.
- **Upstream reads are bounded and redirect-free.** Responses from MSRC/EPSS/
  KEV are size-capped while streaming and HTTP redirects are never followed,
  so a misbehaving upstream can't exhaust container memory.

Local `stdio` usage is unaffected by all of the above; none of this middleware
runs for the default transport.

The container runs on any host that can serve HTTP — Azure Container Apps, Cloud Run, Fly.io, or a plain VM.

## Telemetry & Privacy

- **Local stdio (the default): no telemetry, ever** — there is no code path that sends anything.
- **The hosted endpoint** records minimal usage data to Azure Application Insights (90-day retention): a daily-salted hash of the client IP (raw IPs are never stored; they are only held briefly in memory for abuse protection), request path and timestamp, which tool parameters were used (parameter *names* only — never your query text or CVE/KB values; only the low-cardinality `month` and `severity` values are kept), result counts, latency, and error categories. No cookies, no accounts, no request/response bodies.
- **Self-hosted HTTP** collects nothing unless you set `APPLICATIONINSIGHTS_CONNECTION_STRING` to your own resource — then the same minimal set flows to your instance instead.

## Development

```bash
pip install -e ".[dev]"
pytest                  # offline suite (mocked feeds)
pytest --run-live       # also run live smoke tests against the real MSRC / EPSS / KEV APIs
pytest --cov=patch_tuesday_mcp   # coverage (CI enforces >= 90%)
ruff check src/ tests/
```

CI (GitHub Actions) runs the offline suite on Python 3.11/3.12/3.14 with a coverage
gate, lints with ruff, builds the container, scans it with Trivy, and produces
an SPDX SBOM on every push/PR. Release builds attest provenance for the
published wheel/sdist. Dependencies are locked in `uv.lock` (used by the Docker
build via `uv sync --locked`).

## Security

See [SECURITY.md](https://github.com/jonnybottles/patch-tuesday-mcp/blob/HEAD/SECURITY.md) for the supported versions, scope, and how to
report a vulnerability privately.

## License

MIT

