sentinel-one/ai-siem/mgmt-console-api

Claude Code and agent skill by sentinel-one/ai-siem

Trust tier 3
  • community
  • ext:[{"type":"plugin","description":"Custom plugin integration"}]
Source check pending

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-api

Semi-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_delete for REST, s1_api_download for 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_alert for alerts, purple_ai_alert_summary and purple_ai_query for Purple AI, and powerquery_run / powerquery_schema_discover for logs. The server runs on the user's machine, so it reaches *.sentinelone.net where 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.md in the s1-secops-skills source repo, mcp/s1-secops-mcp/README.md in ai-siem; not shipped inside the plugin). For natural-language Purple AI questions use purple_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 with powerquery_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.py and uam_alert_interface.py work 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: pass outputFile (an absolute path on the user's machine inside S1_OUTPUT_DIRS, default home and temp; under the Docker launcher, a path inside the S1_OUTPUT_DIR folder it mounted) to s1_api_get, s1_api_download or powerquery_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 set S1_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 UAM alertTriggerActions mutation with a specific action-id + OrFilterSelectionInput shape (see references/UNIFIED_ALERTS.md): action ids are S1/alert/addNote / analystVerdictUpdate / statusUpdate / assignUser (payload {assignUser:{value:"<numeric user id>"}}, value:null unassigns; userEmail is a ValidationError), and in an MCP client uam_set_status / uam_set_verdict / uam_assign_alert send the console's exact request and verify by re-reading; the alert is targeted by filter:{or:[{and:[{fieldId:"id",stringEqual:{value:<id>}}]}]}, the alert id is the FILTER, never the action id. Hand-rolling this GraphQL from live schema introspection is the fast path to a wrong action-id/filter and a misleading empty result. Also: alertTriggerActions returns a success-shaped ActionsTriggered even when nothing changed, so pass the payload through action_outcome() (it reduces the union to applied plus the per-alert reasons) and re-query (uam_get_alert) to confirm the write landed. The refusal reason is in actions[].failure[].errorMessage, which is why trigger_actions selects that field. Before stating why an action failed, call available_actions(...) with a narrow filter and read isDisabled / disabledReason; trigger_actions does this on failure (diagnose_failures=True) and explain_action_failure reports not_offered / disabled / offered. Availability is filtered by the caller's permissions AND the alert type (one token can be offered statusUpdate on 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/* is INCIDENT_ACTIONS_ONLY_AVAILABLE_FROM_SITE_VIEW under ACCOUNT, enabled under SITE). So not_offered means this identity lacks what this alert needs: check the service user's UAM permissions, and see hyperautomation/references/integration-catalog.md for 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:

bash
s1-secops-mcp setup # prompts without echo, stores in the keychain, verifies read-back
s1-secops-mcp status # shows where each value comes from, masked
s1-secops-mcp forget --name S1_CONSOLE_API_TOKEN # remove one value
NameWhat it is
S1_CONSOLE_URLTenant console URL (no trailing slash, no /web/api/v2.1).
S1_CONSOLE_API_TOKENAPI token from Settings → Users → Service Users. Authorises REST, UAM GraphQL, LRQ and SDL config calls.
S1_HEC_INGEST_URLRegional ingest host (see SentinelOne Endpoint URLs by Region). Needed only to push alerts into UAM (uam_post_alert) or ingest logs.
S1_HEC_TOKENSDL 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_SCOPEOptional 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:

  1. Find the right endpoint.
  • If the user's ask is verb-shaped ("list / count / isolate / hunt …") and you need orientation, read references/CAPABILITY_MAP.md first; 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.md has ready-to-adapt recipes.
  • Otherwise go straight to scripts/search_endpoints.py with 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-works to restrict to endpoints confirmed reachable on this tenant by the most recent smoke test.
  1. Read the per-tag reference. Open references/tags/<Tag>.md (names match the table in references/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.
  2. Call the endpoint. Use the MCP tools: s1_api_get for reads (issue independent GETs as parallel tool calls in one turn), s1_api_post / s1_api_put / s1_api_patch / s1_api_delete for writes, s1_api_download for binary responses. On the user's host (Claude Code or a terminal), scripts/call_endpoint.py and S1Client from scripts/s1_client.py remain available for loops, joins, and transforms; c.get_many([(path, params), ...]) fans out in parallel over pooled connections.
  3. Paginate correctly. S1 list endpoints use cursor-based pagination. With s1_api_get, pass limit and follow pagination.nextCursor with cursor=<value> until it is null; for a full export, write each page to its own outputFile. On the host, the client's paginate() and iter_items() handle this automatically. Avoid manual skip/limit math, which caps at 1000 items.
  4. 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):

IntentCorrect endpoint
List agentsGET /web/api/v2.1/agents
Count agentsGET /web/api/v2.1/agents/count → {"data":{"total":N}}
List threatsGET /web/api/v2.1/threats
Count threatsGET /web/api/v2.1/threats?countOnly=true or check pagination.totalItems from any list call
Export threats to CSVGET /web/api/v2.1/threats/export (no extra params required)
List sites / accounts / groupsGET /web/api/v2.1/{sites,accounts,groups}
Get system infoGET /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 pathWhy you might guess itCorrect 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

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
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/sentinel-one/ai-siem/mgmt-console-api/badge)](https://verified-skill.com/skills/sentinel-one/ai-siem/mgmt-console-api)

Something wrong with this skill or its page? Tell us.