MCP server for Abnormal Security — AI-powered threat detection, case management, and email remediation
The server demonstrates solid definition quality with all 10 tools having explicit names, descriptions, and input schemas. Naming follows verb_noun patterns (list, get, manage, navigate, status). All tools have meaningful descriptions (50-300+ chars) that explain purpose and context. Input schemas are present with type definitions and descriptions. However, there are gaps: parameter descriptions could be more detailed about constraints and error conditions; output schemas are not explicitly documented; error handling lacks actionable recovery guidance; tool annotations (readOnlyHint, destructiveHint, idempotentHint) are completely missing despite the server having both READ_ONLY and WRITE operations.
List phishing emails reported by users via the Abuse Mailbox. Returns user-submitted reports with analysis results indicating whether Abnormal confirmed the threat.
Get detailed information about a specific security case by ID. Returns case status, analyst notes, associated threats, and timeline.
List all active security investigation cases in Abnormal Security. Cases group related threats for analyst review and workflow management.
Get detailed analysis of a specific message within a threat case. Returns full message metadata, headers, URLs, attachments, and AI-based threat analysis.
List messages contained within a specific threat case. Returns message IDs and summary data for all emails associated with the threat.
Tool annotations (readOnlyHint, destructiveHint, idempotentHint) are completely absent. The Risk field is manually assigned (READ_ONLY vs WRITE) but not encoded in tool definitions via annotations. LLMs cannot infer safety properties from the current schema.
Output schemas are not documented. Tool descriptions mention what data is returned (e.g. 'Returns threat details including classification, severity, and related message IDs') but do not provide a structured schema. LLMs cannot predict response structure for downstream planning.
Inferred effective spec: 2026-07-28+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | B | 71 | 2026-07-28+ | v2 |
Discover available Abnormal Security tools by domain. Returns tool names and descriptions for the selected domain. All tools are callable at any time — this is a help/discovery aid, not a prerequisite.
Trigger or check the status of a remediation action for a specific threat message. Supports requesting remediation (removal from mailboxes) or checking current remediation status.
Show connection status and available domains
Get detailed information about a specific threat case by ID. Returns threat details including classification, severity, and related message IDs.
List detected threats and cases from Abnormal Security. Returns a paginated list of threat IDs with summary information.
Error handling and recovery guidance are absent. No tool description explains what happens on failure (e.g. 'If threat ID is invalid, will return...') or offers next steps. Agents cannot self-correct without explicit error handling.
Parameter constraint documentation is minimal. Example: 'pageSize' has a default and max mentioned in description text, but no formal min/max constraints in the schema. 'filter' parameter accepts OData expressions but provides no format guidance or examples of valid syntax.
Tool 'abnormal_status' has an extremely sparse description ('Show connection status and available domains'). While technically valid, it lacks guidance on WHEN to call this tool and WHAT to do with the response. Compare to 'abnormal_navigate' which explicitly states it is a 'help/discovery aid'.
Tool 'abnormal_remediation_manage' uses an action enum (remediate|unremediate|status) to combine three distinct operations. While functional, this violates the single-responsibility principle. Consider: 'abnormal_remediation_request', 'abnormal_remediation_undo', 'abnormal_remediation_status' for clearer intent.
No pagination context returned. List tools accept pageSize and pageNumber but do not document what fields the response includes (total count? next_cursor? hasMore?). Agents cannot determine when to stop iterating without explicit metadata.