Skip to content

v1.7.0

Choose a tag to compare

@github-actions github-actions released this 03 Nov 09:13
· 15 commits to main since this release

[1.7.0] - 2026-11-03

What changed

  • npg_update_settings could not set worker_shutdown_timeout, the nginx setting NPG v2.66.0 adds (seconds an old worker waits for its in-flight connections before exiting; 0 = wait for every connection, max 86400, omitted = 240). The field is part of upstream UpdateGlobalSettingsRequest, but it was missing from TOOL_KWARGS_WHITELIST in npg_mcp/upstream_models.py, so the client-side strict check rejected the call with ValueError: npg_update_settings: unknown field(s) ['worker_shutdown_timeout'] before any HTTP request — the only workaround was strict=false, i.e. exactly the silent-noop risk the whitelist exists to prevent. The key is now whitelisted (with a # v2.66.0 note) and npg_update_settings's description= names the field, its range and the 0 semantics in the same commit.
  • A regression test (tests/test_kwargs_whitelist.py::test_global_settings_v2_66_worker_shutdown_timeout_accepted) mirrors the existing v2.51 whitelist case and pins both 240 and the meaningful 0 value, including a mixed dict with keepalive_timeout.
  • Four new upstream GET /api/v1/traffic/* endpoints (NPG v2.66.0's per-host traffic analytics) had zero MCP coverage. Bridged as read-only tools in a new # ── Traffic ── section right after # ── Dashboard ──, all requiring dashboard:read: npg_get_traffic_summary (response bytes + requests per proxy host with each host's percentage, start/end, optional proxy_host_id via the timeseries/export siblings), npg_get_traffic_timeseries (start/end/proxy_host_id — host UUID, the literal unclassified, or omit — bucketed at 5min/hour/day), npg_get_traffic_realtime (fixed last 3 minutes in 10s buckets plus 30s average rates; deliberately no start/end), and npg_get_traffic_export (CSV).
  • npg_get_traffic_export calls c.get_text(...), not c.get(...): the route serves text/csv and client.get() unconditionally calls resp.json(), which would raise on a non-JSON body. It returns {"success": True, "data": "<csv text>"} following the npg_download_log_file / npg_get_metrics precedent, and its description says the payload is CSV, not JSON.
  • All four tools declare expand: bool = False (so the shared result cap applies and expand=true lifts it — enforced by tests/test_result_cap.py's read-only drift guard) and end their descriptions with the standard cap hint; every description stays under the 460-char DESC_LEN cap.
  • Description drifts left by v2.66.0 behaviour were corrected: npg_verify_challenge now documents 404 = proxy_host_id not found (the endpoint used to answer 500 for an unknown host), npg_create_sso_provider / npg_update_sso_provider document group_claim as max 64 chars (longer is now a 400 instead of a 500), and npg_get_dashboard_stats now states that without proxy_host_id only global rollup rows come back while an ID returns only that host's rows.
  • Generated artefacts were refreshed in the same commit: npg_mcp/permission_map.py regenerated from NPG's route registry (the four /traffic/* routes map to dashboard:read; 313 tools), tool-schemas.yaml + README.md + README.ko.md regenerated by regenerate_all_docs.py, and the new Traffic section registered with that generator's category map so the READMEs gain a Traffic | 4 tools row (29 categories).
  • Tier counts moved with the four read-only tools: read 137 → 141, standard 262 → 266, full 309 → 313 (destructive unchanged at 47), updated in .env.example, both READMEs and the tests/test_toolsets.py / tests/test_result_cap.py / tests/test_health.py pins.
  • Verified end to end against the local test stack (NPG v2.66.0 API) with a HEAD-pinned local image — local/npg-mcp:69933f957b9fd09379c42ab8b87214c30f8355be, not the stale published test image: 313 tools served, all four traffic tools returning live data (summary 288 bytes / 8 requests, timeseries hour point, realtime 10s buckets, CSV export containing the probe host) after driving requests through npg-test-proxy, worker_shutdown_timeout=120 accepted and reflected by npg_get_settings then restored to 0 (out-of-range 99999 rejected upstream with the documented 400), npg_verify_challenge surfacing the new 404 for an unknown host, and an SSO create/delete round-trip with a 64-char group_claim plus the 65-char 400 path. 23/23 live checks passed.
  • Release gates on this commit: 313 tools with no name changes, tier counts match tier_allowed() (read=141 / standard=266 / full=313, destructive 47), ruff check . clean, mypy npg_mcp/ clean, pytest 621 passed, docs --check exit 0 (460-char cap, longest 460), permission map in sync at 313 tools.

What's new

  • npg_get_traffic_summary — per-proxy-host traffic totals (response bytes, requests, percentage of the window total) for the last 24 h by default or an explicit RFC3339 window.
  • npg_get_traffic_timeseries — the bucketed traffic series (bytes + requests per point, resolution 5min/hour/day) for all hosts, one host UUID, or the literal unclassified bucket.
  • npg_get_traffic_realtime — live last-3-minutes traffic in 10s buckets with 30s average rates.
  • npg_get_traffic_export — the same per-host figures as CSV text for spreadsheets.
  • worker_shutdown_timeout is now settable through npg_update_settings (0 = wait for every connection, max 86400).

Breaking changes

  • (none) — all four tools are additive read-only GETs; no tool was renamed, retyped or removed, no parameter changed type, and no default changed. npg_update_settings accepts one previously-rejected kwargs key, so calls that used to fail client-side now reach the API. Deployments that pin NPG_TOOL_LEVEL see a larger surface (read 141, standard 266, full 313) because the new tools are read-tier.