Are you the author? Sign in to claim
MCP server for Microsoft Patch Tuesday - query MSRC security updates, CVEs, and KBs with EPSS + CISA KEV enrichment. No
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 — 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.
Patch Tuesday MCP Server bridges Microsoft's official CVRF security update API and your AI assistant, allowing you to:
months_back=6, or start_month/end_month) — aggregates matches across released months with per-month countsexploitation_likely=True)ransomware=True; add include_kev_details=True for the full CISA entry with required actions)include_kb_details=True adds per-KB URLs, fixed builds, supersedence, and restart requirements)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)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)cwe="CWE-416" or cwe="use after free")list_months=True)format="markdown" / format="csv")force_refresh=True) bypasses the in-process caches; include_freshness=True reports the cache age/TTL of the MSRC document and EPSS/KEV enrichmentPerfect 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. No authentication or API key required.
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:
uvx commandmsrc_search keeps your AI client's context lean and tool selection reliableA free remote instance is available at:
https://patch-tuesday-mcp.happyrock-b60185ec.eastus.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. Only minimal, anonymized usage data is recorded — see Telemetry & Privacy.
uvx (Recommended)If you are installing or running the server via uvx, you must have uv installed first.
uvx): https://github.com/astral-sh/uvInstall uv:
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
irm https://astral.sh/uv/install.ps1 | iex
uvxallows you to run the MCP server without installing the package globally.
pip install patch-tuesday-mcp
uvx patch-tuesday-mcp
Or install with pip:
pip install patch-tuesday-mcp
uvx patch-tuesday-mcp@latest
Or with pip:
pip install --upgrade patch-tuesday-mcp
One-click setup: Click the VS Code badge for automatic configuration (requires
uvinstalled) Manual setup: See instructions below for VS Code, Cursor, Claude Code, Copilot CLI, or Claude Desktop
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.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:
{
"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.
A portable agent skill — 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 for deployment details.
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/ so the workflow can be used independently of the server.
Once connected to an MCP client, you can ask questions like:
force_refresh=True, include_freshness=True)query="HTTP.sys", months_back=6)include_known_issues=True)include_update_summary=True)cwe="CWE-416")product_profile="identity-core", severity="Critical")monthly_triage prompt with product_profile="identity-core")uvx patch-tuesday-mcp
Or if installed with pip:
patch-tuesday-mcp
Option 1: One-Click Install (Recommended)
Click the Set up in VS Code 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.jsonThen add the server. Note that VS Code uses a top-level "servers" key (unlike the "mcpServers" key used by the other clients below):
{
"servers": {
"patch-tuesday": {
"type": "stdio",
"command": "uvx",
"args": ["patch-tuesday-mcp"]
}
}
}
Add to your Claude Desktop MCP config:
~/Library/Application Support/Claude/claude_desktop_config.json%APPDATA%\Claude\claude_desktop_config.jsonUsing uvx (recommended)
{
"mcpServers": {
"patch-tuesday": {
"command": "uvx",
"args": ["patch-tuesday-mcp"]
}
}
}
Using installed package
{
"mcpServers": {
"patch-tuesday": {
"command": "patch-tuesday-mcp"
}
}
}
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):
{
"mcpServers": {
"patch-tuesday": {
"command": "uvx",
"args": ["patch-tuesday-mcp"]
}
}
}
claude mcp add --transport stdio patch-tuesday -- uvx patch-tuesday-mcp
Add to ~/.copilot/mcp-config.json:
{
"mcpServers": {
"patch-tuesday": {
"type": "stdio",
"command": "uvx",
"args": ["patch-tuesday-mcp"]
}
}
}
The server also supports the HTTP transport for remote/shared deployments:
MCP_TRANSPORT=http MCP_PORT=8000 patch-tuesday-mcp
# MCP endpoint: http://localhost:8000/mcp
Or with Docker:
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]) |
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.
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:
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.MCP_CORS_ORIGINS to the exact origins of your MCP
clients instead of the permissive * default.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.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.
month and severity values are kept), result counts, latency, and error categories. No cookies, no accounts, no request/response bodies.APPLICATIONINSIGHTS_CONNECTION_STRING to your own resource — then the same minimal set flows to your instance instead.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).
See SECURITY.md for the supported versions, scope, and how to report a vulnerability privately.
MIT
Run Claude Code as an MCP server so any agent can delegate coding tasks to it
Browser automation using accessibility snapshots instead of screenshots
Google's universal MCP server supporting PostgreSQL, MySQL, MongoDB, Redis, and 10+ databases
Official GitHub integration for repos, issues, PRs, and CI/CD workflows