Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ On Windows in this repo use `.venv/Scripts/python -m pytest` etc. — the venv w
## Architecture

- `src/patch_tuesday_mcp/server.py` — FastMCP app + `main()`. stdio by default; `MCP_TRANSPORT=http` serves `/mcp` + `/health` with the ASGI app from `build_http_app()` (middleware innermost→outermost: client-cleanup lifespan wrapper → body limit → rate limit → CORS; the factory exists so tests can exercise the exact production composition). uvicorn runs with `MCP_LIMIT_CONCURRENCY` (default 40) and `timeout_keep_alive=15`; `MCP_LOG_LEVEL` controls root logging (stderr). The startup settings log reports pinned trusted proxies as a count only — never echo `MCP_TRUSTED_PROXIES` values (CodeQL flags clear-text logging of them; issue #10, pinned by a test).
- `tools/search.py` — the single `msrc_search` tool and all its routing: CVE fast path (cross-month lookup), KB fast path (with optional supersedence chain walk), `list_months=True` catalog fast path, single-month filtered search, and historical trend search (`months_back` / `start_month`+`end_month`, capped at `MAX_TREND_MONTHS = 12`). A top-level catch-all converts unexpected exceptions to `error_kind="internal"` — `msrc_search` never raises.
- `tools/search.py` — the single `msrc_search` tool and all its routing: CVE fast path (cross-month lookup), KB fast path (single KB or a batched `kb=[...]` list capped at `MAX_KB_BATCH = 30` returning grouped per-KB results, with optional supersedence chain walk), `list_months=True` catalog fast path, single-month filtered search, and historical trend search (`months_back` / `start_month`+`end_month`, capped at `MAX_TREND_MONTHS = 12`). A top-level catch-all converts unexpected exceptions to `error_kind="internal"` — `msrc_search` never raises.
- `tools/formatters.py` — optional `format="markdown"|"csv"` triage renderings; JSON is always included and unchanged.
- `tools/profiles.py` — named product watchlists for `msrc_search` (`product_profile=`, plus ad-hoc `products=[...]`/`product_families=[...]`). Built-ins (`identity-core`, `endpoint`, `server-infrastructure`) merged under a `MSRC_PROFILES_PATH` JSON override with strict validation; unknown/invalid → `invalid_input`, never an unscoped fallback. Matching is local substring (union: any product OR family); profile contents are never sent upstream or to telemetry.
- `tools/prompts.py` — the `monthly_triage` MCP prompt (registered in `server.py` via `mcp.prompt`), a guided analyst workflow built entirely on `msrc_search`; optional `product_profile`/`month` args. Portable copies live in `prompts/` (plain-text prompt) and `skills/patch-tuesday-triage/` (agent skill) — keep them in sync with `tools/prompts.py` when the workflow changes.
Expand Down
39 changes: 20 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ pip install --upgrade patch-tuesday-mcp

## 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). 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.
- **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_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)

Expand Down Expand Up @@ -173,24 +173,25 @@ Once connected to an MCP client, you can ask questions like:
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. **Product filter**: "Show me Critical vulnerabilities affecting Exchange Server this month"
6. **Patch prioritization**: "What should I patch first from the June 2026 updates?"
7. **CISA KEV**: "Which of this month's CVEs are on the CISA KEV list?"
8. **EPSS**: "Show me CVEs with EPSS above 50%"
9. **Exposure filtering**: "Which Critical CVEs are network-reachable with no privileges and no user interaction?"
10. **Reference links**: "Give me the MSRC, NVD, and EPSS links for CVE-2026-41108"
11. **Mitigations & workarounds**: "Are there any mitigations or workarounds for CVE-2026-41108?"
12. **Triage report**: "Give me this month's Critical CVEs as a Markdown briefing" (or "…export them as CSV")
13. **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`)
14. **Historical trends**: "How many HTTP.sys RCE CVEs shipped over the last 6 months?" (`query="HTTP.sys"`, `months_back=6`)
15. **Supersedence**: "Is KB5087538 superseded by anything newer?"
16. **Exploitation forecast**: "Which CVEs does Microsoft rate 'Exploitation More Likely' this month?"
17. **Ransomware**: "Which of this month's CVEs are used in known ransomware campaigns?"
18. **Deployment planning**: "Does KB5094123 require a restart, and which build fixes it?"
19. **Weakness class**: "Show me this month's use-after-free vulnerabilities" (`cwe="CWE-416"`)
20. **Release catalog**: "Which Patch Tuesday months are available to query?"
21. **Product watchlist**: "Show me this month's Critical CVEs across my estate" (`product_profile="identity-core"`, `severity="Critical"`)
22. **Guided triage**: "Walk me through this month's triage for my identity estate" (selects the `monthly_triage` prompt with `product_profile="identity-core"`)
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. **Weakness class**: "Show me this month's use-after-free vulnerabilities" (`cwe="CWE-416"`)
21. **Release catalog**: "Which Patch Tuesday months are available to query?"
22. **Product watchlist**: "Show me this month's Critical CVEs across my estate" (`product_profile="identity-core"`, `severity="Critical"`)
23. **Guided triage**: "Walk me through this month's triage for my identity estate" (selects the `monthly_triage` prompt with `product_profile="identity-core"`)

## Usage

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "patch-tuesday-mcp"
version = "0.6.3"
version = "0.7.0"
description = "MCP server for Microsoft Patch Tuesday security updates (MSRC Security Update Guide)"
requires-python = ">=3.11"
readme = "README.md"
Expand Down
2 changes: 1 addition & 1 deletion src/patch_tuesday_mcp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""Patch Tuesday MCP Server - Query MSRC security updates via MCP."""

__version__ = "0.6.3"
__version__ = "0.7.0"
4 changes: 3 additions & 1 deletion src/patch_tuesday_mcp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ def _trusted_proxies() -> frozenset[str]:
"MSRC Security Update Guide API. Use msrc_search to find, filter, and "
"retrieve vulnerabilities and their fixes. Look up a specific CVE with "
"cve='CVE-...' (full detail, works across all months), find what a KB "
"fixes with kb='5094123', or filter the latest month by product, "
"fixes with kb='5094123' — or pass a list (kb=['5094123', ...], up to "
"30) to resolve a whole machine's update list in one call — or filter "
"the latest month by product, "
"severity, exploited=True, or min_cvss. Scope any search to a product "
"watchlist with product_profile='identity-core' (built-ins: "
"identity-core, endpoint, server-infrastructure; extend via a JSON "
Expand Down
Loading