Repository navigation
v3.8.3
Fixed
- DiagnosticSource and RemediationSource read tools return HTTP 415.
get_diagnosticsources,get_diagnosticsource,get_remediationsources, andget_remediationsourcewere calling the Santaba UI's internal Exchange Toolbox endpoint (POST /exchange/toolbox/exchange{Diagnostic,Remediation}Sourceswith body{}). Per LM's internal Action Source API spec, that path with POST is the CREATE verb -- not LIST or GET -- so the API rejected the malformed CREATE payload with 415. Repointed all four tools to the public REST surfaceGET /setting/{diagnostic,remediation}sourcesandGET /setting/{diagnostic,remediation}sources/{id}. This is the same path family every other source tool uses (get_datasources,get_configsources, etc.) and that LogicMonitor's official PowerShell module canonicalizes for these resources. Filtering is now pushed server-side via the standard LMfilter=name~"x"query parameter and pagination viasize/offset.[PREVIEW]markers removed from the four tools -- they are first-class public reads. - LMv1 HMAC signature drift on empty-body requests. The body-signing path in
client/api.pycheckedif json_body(truthiness), so an empty dict{}was treated as missing and signed against""while httpx put"{}"on the wire. The mismatch produced 401 on LMv1 portals every empty-body POST/PATCH (recover_device, the broken Exchange Toolbox readers above, and anything future that passesjson_body={}). Bearer-auth portals ignore body in the signature so the bug remained dormant. Fix usesif json_body is not None, applied to bothrequest()(line 299) andingest_post()(line 520). calculate_error_budgetJSON-decode crash on inner errors. When the innercalculate_availabilitycall returned a human-readable"Error: ...\nSuggestion: ..."envelope (now reachable through the device-lookup fix below),calculate_error_budgetdid a rawjson.loads(avail_result[0].text)and raisedJSONDecodeError, which propagated as"Expecting value: line 1 column 1 (char 0)". Routed throughcall_sub_toolso the inner failure surfaces cleanly. Same hardening v3.8.2 applied to workflow composites;calculate_error_budgetwas missed in that sweep.calculate_availabilitydevice-lookup silent failure. A 404 or 403 on the device lookup proceeded silently with unfiltered alerts, producing availability numbers for a different device set (or every device in the portal). Replaced the bareexcept Exception: passwith anLMError-only catch that returns a structuredDEVICE_LOOKUP_FAILEDenvelope.ingest_logsandpush_metricsmissing@require_write_permission. Both tools push data into the portal but the decorator was absent, soLM_ENABLE_WRITE_OPERATIONS=falsedid not gate them. Added the decorator and converted the bare[TextContent(text="Error: ...")]validation returns to the newvalidation_error()helper for canonical envelope shape.baselines.save_baselineandcompare_to_baselinebare error returns. Both functions returned[TextContent(text=f"Error: {e}")]from their outer except blocks, bypassinghandle_error(). No structured envelope, no logged stack trace, noerror: true/codefields. Replaced withreturn handle_error(e).
Added
lm_mcp.tools.call_sub_tool(moved and renamed from_call_sub_toolinworkflows.py). Public helper that calls a sub-handler, parses the JSON response, and raises a cleanRuntimeErroron error envelopes or non-JSON bodies. Now usable from non-workflow composites without copy-paste or circular imports.lm_mcp.tools.validation_error(code, message, suggestion?)helper for canonical input-validation responses. Used byingest_logsandpush_metrics; available to every tool.- New regression tests for each of the six fix sites (~15 tests total).
Tracked Follow-ups
The pre-release audit surfaced additional consistency and silent-failure gaps that are not bundled in v3.8.3 to keep the diff focused. Each will get a dedicated PR:
- Pagination compliance for ~17 list endpoints missing
offset/has_more(sdts, netscans, oids, services, alert_rules, escalations, integrations, device_groups, website_groups, dashboard_groups, collector_groups, roles, batchjobs, api_tokens, device_eventsources, device_logsources, dashboard_widgets). - Filter-convention rollout: add raw
filterescape hatch to list tools that currently accept only typed filters. - Naming:
list_sdts->get_sdts,list_session_history->get_session_history(one release with alias). - List/singular field parity expansion (
get_devices,get_alerts,get_collectors,logsourcesdisplay_name). - Session singleton thread-safety for HTTP transport.
- Method-gated retry on POST 5xx in the client.
_LM_ERROR_PATTERNScoverage: add 415, malformed-enum, and empty-body 400 patterns.- Workflows.py silent-failure cleanup (~20 bare
except Exception: passsites intriage,diagnose,audit_network_monitoring_coverage,capacity_plan). - Expand
IMPORT_SILENT_FAILUREguard to the 7 siblingimport_*tools. export_topologysourcemissing despite create/import/update/delete being present.
Verified
- Full test suite passing (1810+ tests).
- Ruff check + format clean.
- LM PowerShell module (
logicmonitor/lm-powershell-module) cross-referenced as the canonical public-API path source for diagnosticsources and remediationsources.