MCP server that integrates Microsoft Security Copilot and Azure Sentinel, enabling querying of Sentinel logs via KQL, uploading and managing skillsets in Security Copilot, and running prompts and skills within Security Copilot sessions.
This server has a moderate foundation but significant gaps prevent it from reaching production quality. All 4 tools are explicitly registered with FastMCP decorators and have descriptions, but parameter documentation is incomplete and output schemas are not formally documented. Tool naming follows action-verb conventions (run_, upload_, get_) which is good. However, 3 of 4 tools accept complex parameters with insufficient type clarity or validation guidance. Error handling is minimal, most tools catch exceptions and return string error messages without classification or recovery guidance. The server lacks structured output documentation, making it harder for LLMs to parse responses and plan chains. STDIO-only transport would be fatal; use of SSE (via FastMCP) mitigates this but SSE is deprecated as of 2025-03-26.
Get skillsets from Security Copilot. Args: filter_name: Filter name to get skillsets from Security Copilot full_response: Whether to return the full response including skills from Security Copilot Returns: Skillsets from Security Copilot
Run a prompt in Security Copilot and get the results. Args: prompt_type: The type of prompt - "Prompt" or "Skill" content: The content of the prompt (required if prompt_type is "Prompt") skill_name: The name of the skill (required if prompt_type is "Skill") inputs: The inputs for the skill (required if prompt_type is "Skill") session_name: The name for the new session polling_interval: Time in seconds between polling attempts max_attempts: Maximum number of polling attempts Returns: Results from Security Copilot
Run a query against Sentinel. Args: query: The Kusto Query Language (KQL) query to run Returns: Results from the query
Upload or update a skillset in Security Copilot. Args: plugin_yaml_content: Raw YAML content of the plugin definition. Include the full file content create_if_not_exists: Whether to create the skillset if it doesn't exist Returns: Response from Security Copilot
Output schemas not documented. Tools return strings (e.g. 'Results from the query', 'Response from Security Copilot') but the actual structure of these strings, JSON objects, arrays, formatted text, is never specified. LLMs cannot reliably parse responses or extract fields for chaining.
Parameter 'inputs' in run_prompt is typed as object with no schema. LLMs have no way to know what keys/values are expected for a skill's inputs. The description says '(required if prompt_type is "Skill")' but provides no structure.
Error handling lacks classification and recovery guidance. Example: upload_plugin catches exceptions and returns 'Error uploading skillset: {str(e)}'. LLMs do not know if the error is retryable, requires user action, or is fatal. No actionable guidance like 'Check plugin_yaml_content syntax' or 'Verify credentials' provided.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 57 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 38 | - | v1 |
Parameter descriptions lack specificity and format constraints. Example: 'polling_interval' described as 'Time in seconds between polling attempts' with no min/max bounds. An LLM could pass 0 or 1000000. Description for 'query' in run_sentinel_query says 'The Kusto Query Language (KQL) query to run' but does not explain format, example, or validation rules.
Parameter dependencies are undocumented. run_prompt has conditional logic: if prompt_type='Prompt', content is required; if prompt_type='Skill', skill_name and inputs are required. These mutual exclusions and requirements are mentioned in the description but not formalized in schema (no oneOf, not allOf, no explicit required field lists per prompt_type). LLMs may pass invalid combinations.
Tool composition lacks result continuity. Tools return results as generic strings. For example, run_prompt returns 'session_id', 'prompt_id', 'evaluation_id' (per test code), but these fields are not documented in the tool description, making it unclear whether these IDs are guaranteed or what tools accept them as input. No chaining guidance provided.