mirror of
https://github.com/FunnyWolf/agentic-soc-platform.git
synced 2026-08-22 13:12:56 +02:00
update skills
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
---
|
||||
name: asp-alert
|
||||
description: 'Manage ASP alerts. Use when users ask to review alerts, find alerts by status or severity, inspect alert discussions, update AI triage fields, append artifacts, or attach enrichments to alerts.'
|
||||
argument-hint: 'review alert <alert_id> | list alerts [filters] | update alert <alert_id> <fields> | append artifact to alert <alert_id>'
|
||||
compatibility: connect to asp mcp server
|
||||
metadata:
|
||||
author: Funnywolf
|
||||
version: 0.1.0
|
||||
mcp-server: asp
|
||||
category: cyber security
|
||||
tags: [ alert-management, soc, triage, investigation ]
|
||||
documentation: https://asp.viperrtp.com/
|
||||
---
|
||||
|
||||
# ASP Alert
|
||||
|
||||
Use this skill for alert-centric SOC work on ASP.
|
||||
|
||||
## When to Use
|
||||
|
||||
- The user gives an alert ID and wants a quick review or triage summary.
|
||||
- The user wants to find alerts by status, severity, confidence, or correlation UID.
|
||||
- The user wants analyst discussion context on an alert.
|
||||
- The user wants to update AI triage fields on an alert.
|
||||
- The user wants to append a new artifact to an alert.
|
||||
- The user wants to attach enrichment to an alert after analysis.
|
||||
|
||||
## Operating Rules
|
||||
|
||||
- Do not ask the user to choose an operation if the request already implies one.
|
||||
- Collect only missing required inputs.
|
||||
- Prefer `list_alerts(alert_id=..., limit=1)` for single-alert retrieval because there is no separate `get_alert` tool on the current MCP surface.
|
||||
- Keep the response focused on triage value rather than raw schema output.
|
||||
- For updates, change only the fields the user explicitly requested.
|
||||
- For append actions, confirm the target alert ID and the minimum required payload before writing.
|
||||
|
||||
## Decision Flow
|
||||
|
||||
1. If the user provides a specific alert ID or says "open", "show", "review", or "summarize" an alert, call `list_alerts(alert_id=<id>, limit=1)`.
|
||||
2. If the user asks for discussion context, call `get_alert_discussions(alert_id)` after retrieving the alert.
|
||||
3. If the user asks to browse or compare alerts, call `list_alerts` with supported filters.
|
||||
4. If the user asks to update AI severity, AI confidence, or AI comment, call `update_alert`.
|
||||
5. If the user asks to add an IOC, host, user, URL, or hash to the alert, call `append_artifact`.
|
||||
6. If the user asks to attach analysis results, intel, or structured context to the alert, call `append_enrichment(target_type=alert, target_id=<alert_id>, ...)`.
|
||||
|
||||
## SOP
|
||||
|
||||
### Review One Alert
|
||||
|
||||
1. Call `list_alerts(alert_id=<id>, limit=1)`.
|
||||
2. If the result is empty, state that the alert was not found.
|
||||
3. Parse the first JSON record.
|
||||
4. If the user asked for analyst context, call `get_alert_discussions(alert_id)`.
|
||||
5. Present only the most useful triage fields.
|
||||
|
||||
Preferred response structure:
|
||||
|
||||
- `Alert`: alert ID, title or name if present, severity, status, confidence, correlation UID.
|
||||
- `Timeline`: created or updated times when present.
|
||||
- `Key Context`: source, rule, category, owner, or similar high-signal fields.
|
||||
- `Discussions`: only the most relevant analyst or system notes when needed.
|
||||
- `Assessment`: short triage interpretation.
|
||||
|
||||
### List Alerts
|
||||
|
||||
1. Extract supported filters: `alert_id`, `status`, `severity`, `confidence`, `correlation_uid`, `limit`.
|
||||
2. Normalize natural-language filter lists before calling MCP.
|
||||
3. Call `list_alerts`.
|
||||
4. Parse returned JSON strings.
|
||||
5. Present a compact comparison view.
|
||||
|
||||
Preferred response structure:
|
||||
|
||||
| Alert ID | Severity | Status | Confidence | Correlation UID | Summary |
|
||||
|----------|----------|--------|------------|-----------------|---------|
|
||||
|
||||
Then add one short interpretation line when useful.
|
||||
|
||||
### Update Alert AI Fields
|
||||
|
||||
1. Require `alert_id`.
|
||||
2. Extract only supported AI fields: `severity_ai`, `confidence_ai`, `comment_ai`.
|
||||
3. Call `update_alert` with only changed fields.
|
||||
4. If the result is `None`, state that the alert was not found.
|
||||
5. Confirm only the changed fields.
|
||||
|
||||
### Append Artifact To Alert
|
||||
|
||||
1. Require `alert_id`.
|
||||
2. Collect the smallest useful artifact payload first: usually `value`, and when possible `type` or `role`.
|
||||
3. Call `append_artifact`.
|
||||
4. Confirm that a new artifact was created and attached.
|
||||
5. If the artifact is likely to need context, suggest attaching enrichment next.
|
||||
|
||||
### Append Enrichment To Alert
|
||||
|
||||
1. Require `alert_id`.
|
||||
2. Convert the user's analysis into a compact structured enrichment payload.
|
||||
3. Call `append_enrichment(target_type=alert, target_id=<alert_id>, ...)`.
|
||||
4. Confirm the created enrichment record.
|
||||
|
||||
## Clarification Rules
|
||||
|
||||
- Ask for `alert_id` only when missing for alert-specific actions.
|
||||
- Ask for enum clarification only when the requested value does not map cleanly to ASP values.
|
||||
- If the user asks to "lower confidence", "raise severity", or "leave a note", map directly to the matching AI fields when intent is clear.
|
||||
- If the user asks to add an artifact but the value is missing, ask for the artifact value before writing.
|
||||
|
||||
## Output Rules
|
||||
|
||||
- Be concise.
|
||||
- Do not dump raw JSON unless the user explicitly asks for it.
|
||||
- Prefer triage wording over schema wording.
|
||||
- Merge alert data and discussion context into one coherent view when both are used.
|
||||
- Surface blockers clearly: alert not found, unsupported filter, invalid enum value, or incomplete append payload.
|
||||
|
||||
## Failure Handling
|
||||
|
||||
- If the alert is missing, say so directly.
|
||||
- If filters return no results, state that and suggest the most useful refinement.
|
||||
- If the requested update field is unsupported, say which alert fields are actually writable.
|
||||
- If enrichment or artifact input is incomplete, ask one focused follow-up instead of guessing.
|
||||
@@ -1,11 +1,11 @@
|
||||
---
|
||||
name: asp-case
|
||||
description: 'Manage ASP security cases. Use when users ask to get a case, review a case, list cases, find cases by status or severity, or update case status, verdict, severity, or AI analysis fields.'
|
||||
argument-hint: 'get case <case_id> | list cases [filters] | update case <case_id> <fields>'
|
||||
description: 'Manage ASP security cases. Use when users ask to review a case, list cases, inspect case discussions, check related alerts or playbook runs for a case, or update case workflow and AI analysis fields.'
|
||||
argument-hint: 'review case <case_id> | list cases [filters] | update case <case_id> <fields> | run playbook for case <case_id> <playbook_name>'
|
||||
compatibility: connect to asp mcp server
|
||||
metadata:
|
||||
author: Funnywolf
|
||||
version: 0.2.0
|
||||
version: 0.3.0
|
||||
mcp-server: asp
|
||||
category: cyber security
|
||||
tags: [ case-management, soc, triage, investigation ]
|
||||
@@ -18,52 +18,64 @@ Use this skill for case-centric SOC work on ASP.
|
||||
|
||||
## When to Use
|
||||
|
||||
- The user gives a case ID and wants details, triage context, or a quick summary.
|
||||
- The user wants to find cases by status, severity, or confidence.
|
||||
- The user gives a case ID and wants a review, triage context, or quick summary.
|
||||
- The user wants to find cases by status, severity, confidence, verdict, correlation UID, title, or tags.
|
||||
- The user wants case discussion context.
|
||||
- The user wants to check related alerts or playbook runs from a case view.
|
||||
- The user wants to update case workflow fields or AI analysis fields.
|
||||
- The user wants help deciding what case to inspect next.
|
||||
- The user wants to run a playbook against a case.
|
||||
|
||||
## Operating Rules
|
||||
|
||||
- Do not start by asking which operation they want if the request already implies it.
|
||||
- Collect only missing required inputs.
|
||||
- Prefer one MCP call when the user request is specific enough.
|
||||
- Prefer one MCP call when the user request is specific enough, but use a short multi-step flow when the user asks for a real case review.
|
||||
- Do not repeat MCP field descriptions back to the user unless needed to clarify an enum or missing input.
|
||||
- Summarize case data for actionability, not as raw schema output.
|
||||
- If an update request is ambiguous, ask a targeted clarification before writing.
|
||||
- After updates, confirm only the fields that were changed.
|
||||
- For single-case retrieval, use `list_cases(case_id=...)` because the current MCP surface does not expose a separate `get_case` tool.
|
||||
- Keep case as the primary user view. Pull alerts, discussions, or playbook runs only when they help answer the case question.
|
||||
|
||||
## Decision Flow
|
||||
|
||||
1. If the user provides a specific case ID or says "open", "show", "review", or "summarize" a case, use `get_case`.
|
||||
2. If the user asks to find, browse, or compare cases, use `list_cases`.
|
||||
3. If the user asks to change status, verdict, severity, or AI fields, use `update_case`.
|
||||
4. If the user asks to update a case but does not provide a case ID, ask for it.
|
||||
5. If the user gives multiple possible filters, apply the ones ASP supports directly and mention any unsupported filters explicitly.
|
||||
1. If the user provides a specific case ID or says "open", "show", "review", or "summarize" a case, call `list_cases` with `case_id` and `limit=1`.
|
||||
2. If the user wants discussion history or analyst context, call `get_case_discussions` after retrieving the case.
|
||||
3. If the user wants related alert context, use the case's `correlation_uid` and call `list_alerts`.
|
||||
4. If the user wants case automation status, call `list_playbook_runs(source_id=case_id, type=[CASE])`.
|
||||
5. If the user wants to run automation on the case, use `list_available_playbook_definitions` only when the playbook name is missing, then call `execute_playbook(type=CASE, record_id=case_id, name=...)`.
|
||||
6. If the user asks to find, browse, or compare cases, use `list_cases`.
|
||||
7. If the user asks to change status, verdict, severity, or AI fields, use `update_case`.
|
||||
8. If the user asks to update a case but does not provide a case ID, ask for it.
|
||||
9. If the user gives multiple possible filters, apply the ones ASP supports directly and mention any unsupported filters explicitly.
|
||||
|
||||
## SOP
|
||||
|
||||
### Review One Case
|
||||
|
||||
1. Call `get_case` with the case ID.
|
||||
2. If the result is `None`, state that the case was not found.
|
||||
3. Parse the JSON.
|
||||
4. Present only the most useful sections for the request.
|
||||
5. Highlight missing or suspicious fields only if they matter to the user's goal.
|
||||
1. Call `list_cases(case_id=<id>, limit=1)`.
|
||||
2. If the result is empty, state that the case was not found.
|
||||
3. Parse the first JSON record.
|
||||
4. If the user asks for analyst context, call `get_case_discussions(case_id)`.
|
||||
5. If the case contains a useful `correlation_uid` and the user needs alert context, call `list_alerts(correlation_uid=...)`.
|
||||
6. If the user asks whether automation has run or is pending, call `list_playbook_runs(source_id=case_id, type=[CASE])`.
|
||||
7. Present only the most useful sections for the request.
|
||||
8. Highlight missing or suspicious fields only if they matter to the user's goal.
|
||||
|
||||
Preferred response structure:
|
||||
|
||||
- `Case`: case ID, title, severity, status, verdict, confidence, priority, category.
|
||||
- `Timeline`: created, acknowledged, closed, calculated start/end if present.
|
||||
- `Key Alerts`: only the most relevant alerts, not every alert by default.
|
||||
- `Key Artifacts`: only high-signal artifacts such as IP, user, host, hash, URL.
|
||||
- `Discussions`: only the key analyst or system discussion points when relevant.
|
||||
- `Playbook Runs`: only current or recent runs when relevant.
|
||||
- `Analyst / AI Notes`: comment, summary, AI fields when relevant.
|
||||
|
||||
Use concise incident-review language. Prefer a short analytical summary before structured details when the user asks for "what happened" or "help me understand this case".
|
||||
|
||||
### List Cases
|
||||
|
||||
1. Extract supported filters: `status`, `severity`, `confidence`, `limit`.
|
||||
1. Extract supported filters: `case_id`, `status`, `severity`, `confidence`, `verdict`, `correlation_uid`, `title`, `tags`, `limit`.
|
||||
2. If the user gives comma-separated or natural-language lists, normalize them before calling MCP.
|
||||
3. Call `list_cases`.
|
||||
4. Parse the returned JSON strings.
|
||||
@@ -81,6 +93,22 @@ Then add one short line of interpretation when useful, for example:
|
||||
- "High-severity cases are concentrated in one category."
|
||||
- "No matching cases were found."
|
||||
|
||||
### Run A Case Playbook
|
||||
|
||||
1. Require `case_id`.
|
||||
2. If the user has not named a playbook definition, call `list_available_playbook_definitions` and suggest the most relevant options instead of guessing.
|
||||
3. Call `execute_playbook(type=CASE, record_id=case_id, name=<definition_name>, user_input=<optional>)`.
|
||||
4. Confirm that a pending playbook run record was created.
|
||||
5. If the user wants follow-up status, call `list_playbook_runs(source_id=case_id, type=[CASE])`.
|
||||
|
||||
Preferred response structure:
|
||||
|
||||
- `Case`: case ID
|
||||
- `Playbook`: definition name
|
||||
- `Run status`: usually pending at creation time
|
||||
- `User input`: only if provided
|
||||
- `Next useful step`: optional, usually to query case-related runs
|
||||
|
||||
### Update a Case
|
||||
|
||||
1. Require `case_id`.
|
||||
@@ -113,6 +141,7 @@ Preferred response structure:
|
||||
- Ask for `case_id` only when missing.
|
||||
- Ask for enum clarification only when the requested value does not map cleanly to ASP values.
|
||||
- If the user asks for "close", "resolve", or "mark suspicious", you may map directly to the corresponding status or verdict when the intent is unambiguous.
|
||||
- If the user asks for case automation but does not provide a playbook definition name, show available definitions instead of inventing one.
|
||||
- If the user asks for a broad review like "show recent important cases", start with `list_cases` instead of forcing them to choose an operation.
|
||||
|
||||
## Output Rules
|
||||
@@ -121,10 +150,12 @@ Preferred response structure:
|
||||
- Do not dump raw JSON unless the user explicitly asks for it.
|
||||
- Prefer analyst-facing wording over schema wording.
|
||||
- Keep tables small; when many rows match, show the best subset and state the total count.
|
||||
- When using multiple MCP calls for one review, merge the result into one coherent case narrative instead of showing call-by-call output.
|
||||
- Surface blockers clearly: case not found, unsupported filter, invalid enum value.
|
||||
|
||||
## Failure Handling
|
||||
|
||||
- If the case is missing, say so directly.
|
||||
- If filters return no results, state that and suggest the most likely useful refinement.
|
||||
- If the playbook definition name does not match available definitions, say that directly and offer the closest available options.
|
||||
- If an update target is unclear, ask one focused question instead of guessing.
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
---
|
||||
name: asp-knowledge
|
||||
description: 'Manage ASP knowledge records. Use when users ask to find internal knowledge, search by title, body, tags, action, or source, or update knowledge content, usage state, lifecycle action, or tags.'
|
||||
argument-hint: 'search knowledge [filters] | update knowledge <knowledge_id> <fields>'
|
||||
compatibility: connect to asp mcp server
|
||||
metadata:
|
||||
author: Funnywolf
|
||||
version: 0.1.0
|
||||
mcp-server: asp
|
||||
category: cyber security
|
||||
tags: [ knowledge, memory, rag, investigation ]
|
||||
documentation: https://asp.viperrtp.com/
|
||||
---
|
||||
|
||||
# ASP Knowledge
|
||||
|
||||
Use this skill for internal knowledge retrieval and maintenance on ASP.
|
||||
|
||||
## When to Use
|
||||
|
||||
- The user wants to find existing internal knowledge by title, body, tags, action, source, or usage state.
|
||||
- The user wants to review whether a knowledge item should remain active or be removed.
|
||||
- The user wants to update the content, tags, or lifecycle state of a knowledge record.
|
||||
- The user wants to inspect reusable analyst knowledge before deciding the next case, alert, or hunt action.
|
||||
|
||||
## Operating Rules
|
||||
|
||||
- Treat this as knowledge retrieval and curation, not general free-form chat memory.
|
||||
- Prefer the narrowest useful search filters first.
|
||||
- Use fuzzy title or body matching when the user gives phrases, symptoms, or partial wording.
|
||||
- Use tags when the user is operating by scenario, technique, or topic.
|
||||
- For updates, modify only the fields the user explicitly wants changed.
|
||||
- If the user needs semantic search rather than field-based filtering, say that the current MCP surface is still filter-oriented.
|
||||
|
||||
## Decision Flow
|
||||
|
||||
1. If the user wants to find or browse knowledge, call `list_knowledge` with the narrowest useful filters.
|
||||
2. If the user asks to revise content, status, source, action, or tags for a known record, call `update_knowledge`.
|
||||
3. If the user asks whether some knowledge already exists but gives only partial wording, start with fuzzy `title` and `body` filters.
|
||||
4. If the user asks to manage lifecycle or storage state, use `action` and `using` rather than inventing a separate workflow.
|
||||
|
||||
## SOP
|
||||
|
||||
### Search Knowledge
|
||||
|
||||
1. Extract supported filters: `action`, `source`, `using`, `title`, `body`, `tags`, `limit`.
|
||||
2. Use fuzzy title or body filters when the user gives partial text.
|
||||
3. Use tags when the user is really asking for a topic or scenario bucket.
|
||||
4. Call `list_knowledge`.
|
||||
5. Parse returned JSON strings.
|
||||
6. Present a small, useful shortlist instead of every field.
|
||||
|
||||
Preferred response structure:
|
||||
|
||||
| Knowledge ID | Title | Source | Action | Using | Tags |
|
||||
|--------------|-------|--------|--------|-------|------|
|
||||
|
||||
Then add one short interpretation line when useful.
|
||||
|
||||
### Update Knowledge
|
||||
|
||||
1. Require `knowledge_id`.
|
||||
2. Extract only fields the user explicitly wants to change: `title`, `body`, `using`, `action`, `source`, `tags`.
|
||||
3. Call `update_knowledge` with only changed fields.
|
||||
4. If the result is `None`, state that the knowledge record was not found.
|
||||
5. Confirm only the changed fields.
|
||||
|
||||
Preferred response structure:
|
||||
|
||||
- `Updated knowledge`: knowledge ID or returned row ID
|
||||
- `Changed fields`: only the fields sent in the request
|
||||
- `Next useful step`: optional, usually to query similar knowledge or verify the updated record through a narrowed search
|
||||
|
||||
## Clarification Rules
|
||||
|
||||
- Ask for `knowledge_id` only when the user wants to update a specific record and did not provide it.
|
||||
- Ask for lifecycle clarification only when the requested state does not map cleanly to `action` or `using`.
|
||||
- If the user asks to "disable", "archive", or "stop using" a knowledge record, prefer clarifying whether they mean `using=false`, a lifecycle `action`, or both.
|
||||
|
||||
## Output Rules
|
||||
|
||||
- Be concise.
|
||||
- Do not dump full knowledge bodies unless the user explicitly asks.
|
||||
- Prefer reusable analyst wording over raw storage wording.
|
||||
- When many records match, show the best subset and explain the pattern briefly.
|
||||
|
||||
## Failure Handling
|
||||
|
||||
- If no knowledge records match, say that directly and suggest the most likely useful refinement.
|
||||
- If the record to update is missing, say so directly.
|
||||
- If the requested lifecycle change is ambiguous, ask one focused question instead of guessing.
|
||||
@@ -0,0 +1,107 @@
|
||||
---
|
||||
name: asp-playbook
|
||||
description: 'Operate ASP playbook definitions and playbook run records. Use when users ask which playbooks can run, want to execute a playbook on a case, alert, or artifact, or want to inspect existing playbook runs.'
|
||||
argument-hint: 'list playbook definitions | run playbook <name> for <target_type> <target_id> | list playbook runs [filters]'
|
||||
compatibility: connect to asp mcp server
|
||||
metadata:
|
||||
author: Funnywolf
|
||||
version: 0.1.0
|
||||
mcp-server: asp
|
||||
category: cyber security
|
||||
tags: [ playbook, automation, soar, investigation ]
|
||||
documentation: https://asp.viperrtp.com/
|
||||
---
|
||||
|
||||
# ASP Playbook
|
||||
|
||||
Use this skill for playbook automation work on ASP.
|
||||
|
||||
## When to Use
|
||||
|
||||
- The user wants to know which playbook definitions are currently available to run.
|
||||
- The user wants to execute a playbook against a case, alert, or artifact.
|
||||
- The user wants to inspect playbook run records by target object, type, or job status.
|
||||
- The user wants to check whether automation has already run for a target object.
|
||||
|
||||
## Operating Rules
|
||||
|
||||
- Keep playbook definitions and playbook run records strictly separated in language and workflow.
|
||||
- Use `list_available_playbook_definitions` only for runnable definitions.
|
||||
- Use `list_playbook_runs` only for run records.
|
||||
- Use `execute_playbook` only when the user has named a runnable definition and identified the target object.
|
||||
- Do not invent a playbook definition name. If missing, list or suggest from available definitions first.
|
||||
- Treat `user_input` as optional, per-run natural-language guidance for the selected playbook, not as a generic chat prompt.
|
||||
|
||||
## Decision Flow
|
||||
|
||||
1. If the user asks what can run, call `list_available_playbook_definitions`.
|
||||
2. If the user asks whether automation has run for a case, alert, or artifact, call `list_playbook_runs(source_id=<target_id>, type=[<target_type>])`.
|
||||
3. If the user asks to run automation and already provides definition name plus target object, call `execute_playbook`.
|
||||
4. If the user asks to run automation but does not know the playbook definition name, call `list_available_playbook_definitions` first.
|
||||
5. If the user asks for general automation history, call `list_playbook_runs` with the narrowest useful filters.
|
||||
|
||||
## SOP
|
||||
|
||||
### List Runnable Playbook Definitions
|
||||
|
||||
1. Call `list_available_playbook_definitions`.
|
||||
2. Parse the returned JSON.
|
||||
3. Present only the most relevant definitions for the user's target object or goal.
|
||||
4. Make it explicit that these are definitions, not run records.
|
||||
|
||||
Preferred response structure:
|
||||
|
||||
| Definition Name | Likely Target | Purpose |
|
||||
|-----------------|---------------|---------|
|
||||
|
||||
### Run A Playbook
|
||||
|
||||
1. Require `target_type`, `target_id`, and playbook definition `name`.
|
||||
2. If the definition name is missing or uncertain, call `list_available_playbook_definitions` first.
|
||||
3. Pass `user_input` only when the user wants extra guidance for that run.
|
||||
4. Call `execute_playbook(type=<target_type>, record_id=<target_id>, name=<definition_name>, user_input=<optional>)`.
|
||||
5. Confirm that a pending playbook run record was created.
|
||||
|
||||
Preferred response structure:
|
||||
|
||||
- `Target`: type and ID
|
||||
- `Playbook Definition`: selected name
|
||||
- `Run Status`: pending at creation time unless the platform reports otherwise
|
||||
- `User Input`: only if provided
|
||||
- `Next Useful Step`: usually to query related playbook runs
|
||||
|
||||
### Review Playbook Runs
|
||||
|
||||
1. Extract supported filters: `playbook_id`, `job_status`, `type`, `source_id`, `limit`.
|
||||
2. Use `source_id` when the user is asking from the perspective of one case, alert, or artifact.
|
||||
3. Call `list_playbook_runs`.
|
||||
4. Parse the returned JSON strings.
|
||||
5. Present a short run-oriented view.
|
||||
|
||||
Preferred response structure:
|
||||
|
||||
| Run ID | Type | Target ID | Job Status | Definition Name | Updated |
|
||||
|--------|------|-----------|------------|-----------------|---------|
|
||||
|
||||
Then add one short interpretation line when useful.
|
||||
|
||||
## Clarification Rules
|
||||
|
||||
- Ask for `target_type` and `target_id` only when missing for run requests.
|
||||
- Ask for the playbook definition name only when missing or ambiguous.
|
||||
- If the user names something that sounds like a run ID instead of a definition, clarify before executing.
|
||||
- If the user asks to "check the run" without a run ID, prefer `list_playbook_runs` with object context instead of guessing a specific run.
|
||||
|
||||
## Output Rules
|
||||
|
||||
- Be concise.
|
||||
- Do not blur the words definition, run, record, and target object.
|
||||
- Do not dump all playbook definitions if only a shortlist is relevant.
|
||||
- Prefer operational wording: what can run, what ran, what is pending, what should be checked next.
|
||||
|
||||
## Failure Handling
|
||||
|
||||
- If no matching playbook definitions exist, say that directly and suggest the closest relevant options.
|
||||
- If no run records exist for the target, say that directly.
|
||||
- If execution prerequisites are missing, ask one focused clarification instead of guessing.
|
||||
- If the user asks for something only run records can answer, do not answer from definitions alone.
|
||||
@@ -1,11 +1,11 @@
|
||||
---
|
||||
name: asp-siem
|
||||
description: 'Investigate ASP SIEM data with keyword search. Use when users ask to search logs, pivot on IOC values, check activity in a time range, hunt related events, or refine SIEM evidence across ELK or Splunk.'
|
||||
argument-hint: 'search <keyword> from <UTC start> to <UTC end> [index_name] [time_field]'
|
||||
description: 'Investigate ASP SIEM data with schema exploration, keyword search, and adaptive field queries. Use when users ask to find the right index, inspect available fields, search logs by IOC, or run structured hunts with exact filters and aggregations.'
|
||||
argument-hint: 'explore schema [index] | search <keyword> from <UTC start> to <UTC end> | adaptive query <index_name> <time range> [filters] [aggregations]'
|
||||
compatibility: connect to asp mcp server
|
||||
metadata:
|
||||
author: Funnywolf
|
||||
version: 0.2.0
|
||||
version: 0.3.0
|
||||
mcp-server: asp
|
||||
category: cyber security
|
||||
tags: [ SIEM, search, SOC, hunting, investigation ]
|
||||
@@ -18,31 +18,43 @@ Use this skill for SIEM investigation on ASP. This skill should guide search str
|
||||
|
||||
## When to Use
|
||||
|
||||
- The user wants to discover which indices or fields exist before searching.
|
||||
- The user wants to search logs by IP, user, host, hash, domain, process, email, or arbitrary keyword.
|
||||
- The user wants to pivot from an alert, artifact, or case into SIEM evidence.
|
||||
- The user wants exact-match filtering and top-N statistics instead of free-text search.
|
||||
- The user wants to narrow a noisy search or expand an empty one.
|
||||
- The user wants complete raw evidence, not only a high-level count.
|
||||
|
||||
## Operating Rules
|
||||
|
||||
- Do not ask the user to choose an operation when the request already implies a SIEM search.
|
||||
- Collect only missing essentials: keyword and UTC time range.
|
||||
- Collect only missing essentials for the chosen path.
|
||||
- Treat this as an investigation workflow, not a one-shot query helper.
|
||||
- Use the result `status` to decide whether to refine, expand, or stop.
|
||||
- Use `siem_explore_schema` when the user does not know the right index or fields.
|
||||
- Use `siem_keyword_search` when the user has one or more strong keywords and needs matching events.
|
||||
- Use `siem_adaptive_query` when the user already knows the target index and wants exact field filters or statistics.
|
||||
- Optimize for useful evidence, not maximum raw output.
|
||||
- Prefer `full` when the user needs exact logs or evidence preservation.
|
||||
- If the user only needs scoping, `summary` or `sample` may be enough.
|
||||
|
||||
## Decision Flow
|
||||
|
||||
1. If the user already provides keyword and time range, search immediately.
|
||||
2. If the user gives only an IOC or keyword, ask for the narrowest workable UTC time range.
|
||||
3. If the user knows the data source, pass `index_name`; otherwise search broadly.
|
||||
4. If the source likely uses a non-default time field, ask for it; otherwise use `@timestamp`.
|
||||
5. After each search, decide whether to stop, narrow, or expand based on `status`, hit volume, and user goal.
|
||||
1. If the user asks which index to use, which fields exist, or how the SIEM source is structured, use `siem_explore_schema`.
|
||||
2. If the user already provides keyword and time range, use `siem_keyword_search` immediately.
|
||||
3. If the user gives only an IOC or keyword, ask for the narrowest workable UTC time range.
|
||||
4. If the user wants exact field filters, grouped statistics, or controlled aggregations, use `siem_adaptive_query`.
|
||||
5. If the user knows the data source, pass `index_name`; otherwise search broadly first or explore schema.
|
||||
6. If the source likely uses a non-default time field, ask for it; otherwise use `@timestamp`.
|
||||
7. After each search, decide whether to stop, narrow, or expand based on hit volume, result quality, and user goal.
|
||||
|
||||
## SOP
|
||||
|
||||
### Explore Schema
|
||||
|
||||
1. If the user does not know the target source, call `siem_explore_schema()` first.
|
||||
2. If the user already knows the index and wants field structure, call `siem_explore_schema(target_index=<index>)`.
|
||||
3. Parse the returned JSON.
|
||||
4. Summarize the most relevant indices, time field candidates, and high-signal fields for the investigation goal.
|
||||
5. Recommend the next query path: keyword search or adaptive query.
|
||||
|
||||
### Start the Search
|
||||
|
||||
1. Extract the strongest known keyword first.
|
||||
@@ -51,13 +63,15 @@ Use this skill for SIEM investigation on ASP. This skill should guide search str
|
||||
4. Call `siem_keyword_search`.
|
||||
5. Parse each returned JSON string.
|
||||
|
||||
### Refine the Search
|
||||
### Run A Structured Hunt
|
||||
|
||||
Use the returned `status` as the control signal:
|
||||
1. Require `index_name`, UTC time range, and at least one exact filter or explicit aggregation goal.
|
||||
2. Normalize filters into exact field/value pairs.
|
||||
3. Add `aggregation_fields` only when the user wants prevalence, top-N statistics, or grouped scoping.
|
||||
4. Call `siem_adaptive_query`.
|
||||
5. Summarize both the filtered scope and any aggregation output in analyst language.
|
||||
|
||||
- `full`: stop if the user asked for concrete evidence or raw logs.
|
||||
- `sample`: inspect records and statistics, then narrow if exact logs are still needed.
|
||||
- `summary`: narrow aggressively by time range, source, or added keywords.
|
||||
### Refine The Search
|
||||
|
||||
Preferred refinement actions:
|
||||
|
||||
@@ -65,6 +79,7 @@ Preferred refinement actions:
|
||||
2. Add one or two high-signal keywords instead of many weak ones.
|
||||
3. Remove one restrictive keyword if the query is empty.
|
||||
4. Add `index_name` when broad search returns too much irrelevant data.
|
||||
5. Switch to `siem_adaptive_query` when the user has learned enough field structure to stop using keyword search.
|
||||
5. Keep iterating until the result quality matches the user's goal.
|
||||
|
||||
### Investigation Patterns
|
||||
@@ -80,10 +95,10 @@ Use these patterns when helpful:
|
||||
|
||||
Stop refining when one of these is true:
|
||||
|
||||
- The result is `full` and satisfies the request.
|
||||
- The user asked only for scope, trend, or prevalence.
|
||||
- Further refinement would likely remove relevant evidence.
|
||||
- Repeated refinement still returns no useful data.
|
||||
- The user already has the right index and exact field constraints, in which case the next step is an adaptive query rather than another keyword search.
|
||||
|
||||
## Response Strategy
|
||||
|
||||
@@ -93,9 +108,11 @@ Preferred response structure:
|
||||
|
||||
### Search Overview
|
||||
|
||||
- keyword set
|
||||
- search mode: schema exploration, keyword search, or adaptive query
|
||||
- keyword set or exact filters
|
||||
- time range
|
||||
- searched index or `all`
|
||||
- aggregation fields if used
|
||||
- number of result groups
|
||||
- overall interpretation in one or two lines
|
||||
|
||||
@@ -109,6 +126,7 @@ Preferred response structure:
|
||||
- Key field statistics that matter to the investigation.
|
||||
- Representative records only when they add value.
|
||||
- Important pivots: user, host, IP, process, event, action, destination, or other relevant fields.
|
||||
- For schema exploration, highlight only the indices and fields that matter to the hunt.
|
||||
|
||||
### Next Best Step
|
||||
|
||||
@@ -116,13 +134,15 @@ Preferred response structure:
|
||||
- Add one stronger keyword
|
||||
- Remove one restrictive keyword
|
||||
- Search a specific index
|
||||
- Switch to adaptive query with exact filters
|
||||
- Stop because evidence is already sufficient
|
||||
|
||||
## Clarification Rules
|
||||
|
||||
- Ask for time range if missing.
|
||||
- Ask for timezone only if the user did not provide UTC and the intended timezone is unclear.
|
||||
- Ask for `index_name` only when broad search is likely wasteful or the user already hints at a known source.
|
||||
- Ask for `index_name` only when broad search is likely wasteful, the user already hints at a known source, or adaptive query is the right tool.
|
||||
- Ask for exact field names only when the user wants adaptive query and the schema is still unclear.
|
||||
- If the user says "look around this event", derive a reasonable first search from the available IOC and timeframe rather than asking them to design the query.
|
||||
|
||||
## Output Rules
|
||||
@@ -131,7 +151,7 @@ Preferred response structure:
|
||||
- Do not dump every returned record by default.
|
||||
- Prefer the most relevant records and statistics.
|
||||
- Group results by backend and index when multiple groups are returned.
|
||||
- Explicitly state when the result is partial (`summary` or `sample`).
|
||||
- For schema exploration, present a shortlist rather than a raw field inventory.
|
||||
- If no data is found, say that directly and suggest the most likely useful adjustment.
|
||||
|
||||
## Failure Handling
|
||||
@@ -139,4 +159,5 @@ Preferred response structure:
|
||||
- Invalid time format: ask for UTC ISO8601 with trailing `Z`.
|
||||
- Empty results: expand time range or remove one keyword.
|
||||
- Too many hits: narrow time range first, then add signal.
|
||||
- Unknown index or field choice: use `siem_explore_schema` before guessing.
|
||||
- Backend or source issue: state which backend or index failed if the result indicates it.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import logging
|
||||
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi import FastAPI
|
||||
|
||||
from PLUGINS.Forwarder import CONFIG
|
||||
from PLUGINS.Forwarder.models import SplunkPayload, KibanaPayload
|
||||
@@ -56,26 +56,6 @@ async def webhook_kibana(payload: KibanaPayload):
|
||||
return {"status": "error", "message": str(e)}
|
||||
|
||||
|
||||
@app.post("/api/v1/webhook/nocolymail")
|
||||
async def webhook_nocolymail(request: Request):
|
||||
"""
|
||||
Receives a webhook from NocolyMail and logs the data.
|
||||
"""
|
||||
try:
|
||||
data = await request.json()
|
||||
logging.info(f"NocolyMail webhook received: {data}")
|
||||
# Currently, this endpoint only logs the data.
|
||||
# If sending to Redis is needed in the future, the logic can be added here.
|
||||
# For example:
|
||||
# redis_stream_api = RedisStreamAPI()
|
||||
# stream_name = "nocolymail_events" # Or derive from data
|
||||
# redis_stream_api.send_message(stream_name, data)
|
||||
return {"status": "success", "message": "Data logged"}
|
||||
except Exception as e:
|
||||
logging.exception(e)
|
||||
return {"status": "error", "message": str(e)}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
|
||||
|
||||
@@ -29,11 +29,3 @@ class KibanaPayload(BaseModel):
|
||||
"""
|
||||
rule: KibanaRule
|
||||
context: KibanaContext
|
||||
|
||||
|
||||
class NocolyMailPayload(BaseModel):
|
||||
"""
|
||||
Pydantic model for NocolyMail webhook payload.
|
||||
Accepts any valid JSON object.
|
||||
"""
|
||||
data: Dict[str, Any]
|
||||
|
||||
@@ -485,35 +485,4 @@ def get_current_time(
|
||||
return current_time.isoformat(timespec="seconds")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import os
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ASP.settings")
|
||||
import django
|
||||
|
||||
django.setup()
|
||||
print(get_current_time())
|
||||
time_range_end = datetime.now(timezone.utc)
|
||||
time_range_start = time_range_end - timedelta(minutes=10)
|
||||
siem_results = siem_keyword_search(
|
||||
keyword=["227.174.159.18", "CreateAccessKey"],
|
||||
time_range_start=time_range_start.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
||||
time_range_end=time_range_end.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
)
|
||||
print(siem_results)
|
||||
cases = list_cases(limit=1)
|
||||
print(cases)
|
||||
if cases:
|
||||
case = Case.list(Group(logic="AND", children=[]), lazy_load=True)[0]
|
||||
result = update_case(
|
||||
case_id=case.id,
|
||||
status=CaseStatus.IN_PROGRESS,
|
||||
verdict=CaseVerdict.SUSPICIOUS,
|
||||
severity_ai=Severity.HIGH,
|
||||
confidence_ai=Confidence.MEDIUM,
|
||||
comment_ai="#### AI Comment\n\nAdditional investigation notes.",
|
||||
summary_ai="#### AI Summary\n\nUpdated case summary."
|
||||
)
|
||||
else:
|
||||
result = None
|
||||
print(result)
|
||||
|
||||
Reference in New Issue
Block a user