sentinel-one/ai-siem/mgmt-console-api
Claude Code and agent skill by sentinel-one/ai-siem
- community
- ext:[{"type":"plugin","description":"Custom plugin integration"}]
Checking that the SKILL.md file is still in the repository.
Use whenever the user wants to query, update, create, or act on a SentinelOne Management Console: threats, alerts, agents, sites, accounts, groups, exclusions, RemoteOps, Deep Visibility, Hyperautomation, Unified Alert Management (UAM), Purple AI, IOCs, or any other S1 Mgmt API resource. Trigger on "console", "query/update/create console", "SentinelOne", "S1", "Singularity", "UAM", "Purple AI", "/web/api/v2.1/...", S1 agent/threat/site IDs, or asks like "list endpoints", "triage alerts", "add n…
Install
npx vskill@latest install sentinel-one/ai-siem/mgmt-console-apiSemi-extensibleMentions customization, but needs skill-specific knowledge. Read the extensible skills standard
SKILL.md
SentinelOne Management Console API
Covers the SentinelOne Management Console API (Swagger 2.0, spec version 2.1, 781 operations) with a compact endpoint index, per-tag reference files, and the s1-secops-mcp MCP tools that make the calls.
Primary path: the `s1-secops-mcp` MCP tools. Every console call in this skill runs through them:s1_api_get/s1_api_post/s1_api_put/s1_api_patch/s1_api_deletefor REST,s1_api_downloadfor binary responses (RemoteOps fetch-files, threat file fetch, exports),uam_list_alerts/uam_get_alert/uam_add_note/uam_set_status/uam_set_verdict/uam_assign_alert/uam_available_actions/uam_post_alertfor alerts,purple_ai_alert_summaryandpurple_ai_queryfor Purple AI, andpowerquery_run/powerquery_schema_discoverfor logs. The server runs on the user's machine, so it reaches*.sentinelone.netwhere the Cowork sandbox cannot; it reads credentials from environment variables or the OS keychain and masks tokens in all output. If the tools are missing, the user has not connected the server: point them to the s1-secops-mcp README (s1-secops-mcp/README.mdin the s1-secops-skills source repo,mcp/s1-secops-mcp/README.mdin ai-siem; not shipped inside the plugin). For natural-language Purple AI questions usepurple_ai_query(console token, synchronous): it returns an answer or a draft PowerQuery that Purple does not run, so review the query and run it withpowerquery_run. Purple AI auto-investigation (aiInvestigation/run) still needs a browser session and is not exposed.The Python clients under `scripts/` are host-only.S1Client,call_endpoint.py,pq.py,inspect_source.py,unified_alerts.pyanduam_alert_interface.pywork from Claude Code or a terminal on the user's machine, where they read the same environment variables or keychain entries as the MCP server. They cannot reach the tenant from the Cowork sandbox, so do not try them there and do not treat a proxy error as an empty result.Large results: passoutputFile(an absolute path on the user's machine insideS1_OUTPUT_DIRS, default home and temp; under the Docker launcher, a path inside theS1_OUTPUT_DIRfolder it mounted) tos1_api_get,s1_api_downloadorpowerquery_run. The full result is written there and only a summary comes back, so bulk data does not pass through the context window. If the server refuses the path because no folder is shared with the container, tell the user to run~/.local/bin/s1-secops-mcp-launch.sh install --output-dir <folder>(Windows:-OutputDir) and restart Claude Desktop; do not ask them to setS1_OUTPUT_DIRS, which never reaches the container.Load this skill BEFORE any console/UAM *write*, not just reads. Add-note, set-analyst-verdict, set-status, assign, and IOC-create all run through the UAMalertTriggerActionsmutation with a specific action-id +OrFilterSelectionInputshape (seereferences/UNIFIED_ALERTS.md): action ids areS1/alert/addNote/analystVerdictUpdate/statusUpdate/assignUser(payload{assignUser:{value:"<numeric user id>"}},value:nullunassigns;userEmailis a ValidationError), and in an MCP clientuam_set_status/uam_set_verdict/uam_assign_alertsend the console's exact request and verify by re-reading; the alert is targeted byfilter:{or:[{and:[{fieldId:"id",stringEqual:{value:<id>}}]}]}, the alert id is the FILTER, never the actionid. Hand-rolling this GraphQL from live schema introspection is the fast path to a wrong action-id/filter and a misleading empty result. Also:alertTriggerActionsreturns a success-shapedActionsTriggeredeven when nothing changed, so pass the payload throughaction_outcome()(it reduces the union toappliedplus the per-alert reasons) and re-query (uam_get_alert) to confirm the write landed. The refusal reason is inactions[].failure[].errorMessage, which is whytrigger_actionsselects that field. Before stating why an action failed, callavailable_actions(...)with a narrow filter and readisDisabled/disabledReason;trigger_actionsdoes this on failure (diagnose_failures=True) andexplain_action_failurereportsnot_offered/disabled/offered. Availability is filtered by the caller's permissions AND the alert type (one token can be offeredstatusUpdateon a native STAR alert and not on one ingested via/v1/alerts, while a console user session performs either), and is scope-sensitive (S1/incident/*isINCIDENT_ACTIONS_ONLY_AVAILABLE_FROM_SITE_VIEWunder ACCOUNT, enabled under SITE). Sonot_offeredmeans this identity lacks what this alert needs: check the service user's UAM permissions, and seehyperautomation/references/integration-catalog.mdfor native write-back actions.
Setup: credentials live in the OS keychain or the environment
There is no credentials file. Each value resolves per name: environment variables first, then the OS keychain (service sentinelone-mcp, account <profile>:<NAME>, profile from S1_PROFILE, default default). The user stores the values once on their own machine:
| Name | What it is | |
|---|---|---|
S1_CONSOLE_URL | Tenant console URL (no trailing slash, no /web/api/v2.1). | |
S1_CONSOLE_API_TOKEN | API token from Settings → Users → Service Users. Authorises REST, UAM GraphQL, LRQ and SDL config calls. | |
S1_HEC_INGEST_URL | Regional ingest host (see SentinelOne Endpoint URLs by Region). Needed only to push alerts into UAM (uam_post_alert) or ingest logs. | |
S1_HEC_TOKEN | SDL Log Write Key, used only for raw log ingest (hec_ingest, see the sdl-api skill). UAM alert ingest uses the console token instead. | |
S1_SCOPE | Optional default S1-Scope, <accountId> or <accountId>:<siteId>. |
IOC writes (/threat-intelligence/iocs) refuse a token whose user spans several accounts (HTTP 403, code 4030010). The user needs a console API token minted at a single account or site, stored in its own keychain profile (s1-secops-mcp setup --profile <name>) and served by a second MCP entry with S1_PROFILE=<name> (or made the default token).
If a tool reports a missing credential, stop and ask the user to run s1-secops-mcp setup on their machine. Never ask the user to paste a token into the chat, and never write a token to a file.
Workflow
When the user asks for something involving the S1 API, follow this pattern:
- Find the right endpoint.
- If the user's ask is verb-shaped ("list / count / isolate / hunt …") and you need orientation, read
references/CAPABILITY_MAP.mdfirst; it's a compact per-tag summary of what verbs each resource supports. - For a specific multi-step task ("threat triage", "endpoint isolation", "DV hunt"),
references/WORKFLOWS.mdhas ready-to-adapt recipes. - Otherwise go straight to
scripts/search_endpoints.pywith a keyword matching the user's intent. It now ranks results by relevance (path segment hits + verb intent + tag) and supports synonyms ("isolate" → "disconnect", "endpoint" → "agent"). Add--only-worksto restrict to endpoints confirmed reachable on this tenant by the most recent smoke test.
- Read the per-tag reference. Open
references/tags/<Tag>.md(names match the table inreferences/TAG_INDEX.md) to see full parameter lists, descriptions, required permissions, and response codes for that group. Only read the tag file(s) relevant to the task; don't read them all. - Call the endpoint. Use the MCP tools:
s1_api_getfor reads (issue independent GETs as parallel tool calls in one turn),s1_api_post/s1_api_put/s1_api_patch/s1_api_deletefor writes,s1_api_downloadfor binary responses. On the user's host (Claude Code or a terminal),scripts/call_endpoint.pyandS1Clientfromscripts/s1_client.pyremain available for loops, joins, and transforms;c.get_many([(path, params), ...])fans out in parallel over pooled connections. - Paginate correctly. S1 list endpoints use cursor-based pagination. With
s1_api_get, passlimitand followpagination.nextCursorwithcursor=<value>until it is null; for a full export, write each page to its ownoutputFile. On the host, the client'spaginate()anditer_items()handle this automatically. Avoid manualskip/limitmath, which caps at 1000 items. - Summarize the result for the user. Don't dump raw JSON unless asked. Prefer a short prose summary plus a table or CSV/XLSX if the volume warrants.
GET vs POST: the rule you must follow
The S1 API uses GET for every read operation, listing, counting, and exporting. POST is only for actions and mutations. Violating this produces HTTP 404, not a permissions error, because the path simply does not exist.
Read (always GET):
| Intent | Correct endpoint | |
|---|---|---|
| List agents | GET /web/api/v2.1/agents | |
| Count agents | GET /web/api/v2.1/agents/count → {"data":{"total":N}} | |
| List threats | GET /web/api/v2.1/threats | |
| Count threats | GET /web/api/v2.1/threats?countOnly=true or check pagination.totalItems from any list call | |
| Export threats to CSV | GET /web/api/v2.1/threats/export (no extra params required) | |
| List sites / accounts / groups | GET /web/api/v2.1/{sites,accounts,groups} | |
| Get system info | GET /web/api/v2.1/system/info |
Write / action (POST/PUT/DELETE):
- Agent actions (isolate, reconnect, uninstall, scan):
POST /web/api/v2.1/agents/actions/<action> - Threat actions (mitigate, verdict, fetch-file):
POST /web/api/v2.1/threats/<action> - Mutations (notes, exclusions, IOCs, custom rules): POST/PUT/DELETE on the relevant resource path
Paths that do not exist; never call these:
These paths return HTTP 404 and have never existed in the v2.1 spec. They are plausible-sounding guesses that are consistently wrong:
| Wrong path | Why you might guess it | Correct alternative | |
|---|---|---|---|
POST /web/api/v2.1/agents/ids | "query agents by IDs" | GET /web/api/v2.1/agents?ids=<id1>,<id2> | |
POST /web/api/v2.1/threats/summary | "get a threat summary/count" | GET /web/api/v2.1/threats?countOnly=true | |
POST /web/api/v2.1/export/threats | "export threats" | GET /web/api/v2.1/threats/export | |
POST /web/api/v2.1/threats/count | "count threats via POST" | GET /web/api/v2.1/threats?countOnly=true | |
POST /web/api/v2.1/agents/summary | "agent summary" | GET /web/api/v2.1/agents/count + GET /web/api/v2.1/agents |
If you are about to call s1_api_post for a read/count/export operation, stop and switch to s1_api_get. Before any s1_api_post call, confirm the path exists: python3 scripts/search_endpoints.py "<keyword>" (local index search, no network, so it also works in the sandbox), or grep references/endpoint_index.json. If the path does not appear, it does not exist.
Schema gotchas: confirmed on live tenant
These are fields where the obvious guess is wrong. All verified against the live tenant.
The full request-body schema gotchas for Custom Detection / STAR rules, Saved Filters, and PowerQuery Scheduled Detections (the queryType / queryLang matrix, the isLegacy=false listing trap, confirmed CREATE / PUT / DELETE bodies, and the enable / disable endpoints) live in references/detection-rules.md. Read it before composing any POST or PUT to /cloud-detection/rules or /filters.
Alert notes: UAM GraphQL
deleteAlertNote has a 30-90 second propagation window after creation before it can be deleted. The mutation uses alertNoteId, not noteId:
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingplugins/s1-secops-skills/skills/mgmt-console-api/SKILL.md
Popularity
- Repository stars
- 87
- Repository forks
- 38
- 7-day trend score
- 0
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Extension points
pluginCustom plugin integration
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/sentinel-one/ai-siem/mgmt-console-api)