MCP server for DISA STIG checklist management, supporting loading, editing, merging, and exporting checklists in .ckl, .cklb, and Excel formats
ckl-mcp demonstrates solid tool design with clear verb-noun naming (load_checklists, update_finding, export_excel_report) and comprehensive parameter descriptions. All 14 tools have explicit descriptions (avg ~180 chars, within baseline 194). Input schemas are present with typed parameters and descriptions. However, output schemas are not documented in the source, responses are serialized JSON without declared structure, forcing LLMs to infer result fields. Error handling is present but minimal; most tools throw McpException without recovery guidance. No tool annotations (readOnlyHint/destructiveHint) despite clear risk classifications. Parameter validation occurs server-side but constraints are not always formally declared (e.g., pageSize max=200 is in description, not schema enum).
Apply SCAP XCCDF scan results to loaded checklists, matching by rule version or rule id and updating statuses accordingly. Appends a timestamp and benchmark id to finding details.
Update multiple findings at once by applying a filter (where clause) and then setting fields on all matches. Requires both a where clause and at least one set clause.
Remove checklists from the session. Refuses to close documents with unsaved changes unless discard_unsaved is true.
Compare two loaded checklists and report differences: status changes, finding details changes, and comments changes, grouped by change type.
Export loaded checklists to an Excel workbook with one sheet per document. Each sheet contains a Vulnerability Details table with all findings, plus optional columns for internal notes and severity overrides.
Full detail for one finding: rule discussion, check content, fix text, CCIs, and the current status, details, and comments.
Output schemas not documented. Tools return JsonSerializer.Serialize() results without declared structure. LLMs cannot predict response fields, forcing inference and increasing hallucination risk.
No tool annotations (readOnlyHint/destructiveHint/idempotentHint). Tools are classified by Risk (READ_ONLY/WRITE) in metadata but not exposed via MCP tool annotations. Agents cannot distinguish safe from destructive operations.
Minimal error recovery guidance. McpException thrown for validation failures (e.g., 'At least one path is required', 'Unsaved changes in: ...') but no actionable next steps. LLMs receive error text but no guidance on retry strategy or alternative tools.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 62 | 2026-07-28+ | v2 |
Compliance overview of all loaded checklists: totals by status, open findings by CAT severity, and a per-document breakdown. Call this first to orient.
List the checklists currently loaded in the session, with per-document summaries and whether each has unsaved changes.
List findings as compact rows with paging. Filter by status, severity, STIG, document, or free-text search – the same filters as the Ckl-viewer UI. Use get_finding for the full rule text of a single finding.
Load one or more DISA STIG checklist files into the session: .ckl, .cklb, an XCCDF benchmark (imported as a fresh Not Reviewed checklist), or a previously exported .xlsx report (re-imported from its Vulnerability Details sheet, so edits made in Excel can be saved back as .ckl/.cklb – one document per asset in the workbook). Returns a document id and summary for each loaded checklist.
Carry a prior-version checklist's assessment forward into a new STIG release. Matches by rule version, then Vuln ID, then legacy IDs. Flags rules whose check/fix text changed, or resets them to Not Reviewed if reset_changed_rules is true.
Create a new checklist from a DISA STIG benchmark file (XCCDF .xml or .zip). Every rule starts as Not Reviewed. The checklist exists only in memory until save_checklist is called with a path.
Save one or all checklists to disk. If path is omitted, overwrites the source file (fails if the checklist was imported and has no source path). Format is inferred from the file extension (.ckl or .cklb); defaults to .ckl.
Update a single finding's status, details, comments, severity override, or internal notes. Marks the document dirty.
Parameter constraints not formally declared in schema. pageSize max=200 documented in description text only; status/severity enums listed in descriptions but not as JSON Schema enums. LLMs cannot validate before calling.
Pagination response structure unclear. list_findings accepts page/pageSize but response structure (total count, next_cursor, items array) not documented. Agents cannot reliably iterate through large result sets.