Picus Security MCP Server
This server acts as a Model Context Protocol (MCP) interface for the Picus Security Breach & Attack Simulation (BAS) platform, exposing 23 read-only tools (plus 6 optional write tools) that allow AI assistants to query and manage simulations, threat intelligence, and mitigation data.
Simulations
List, retrieve details, and filter simulations by status, agent, template, or prevention/detection scores
Get run results (prevention/detection scores, threat counts) for a specific or latest run
Get run threats broken down by threat → objective → action with prevention/detection status
Get framework mappings (MITRE ATT&CK, Unified Kill Chain) for simulation runs
Retrieve alerts from SIEM/EDR integrations for specific actions
Threat Library
Search threats with rich filters: severity, OS, MITRE ATT&CK tactics, threat actors, kill chain phases, date ranges, and more
Get full threat details including framework mappings, action flows, and actor information
List threat actions and threat actors with metadata
Threat Templates
List and retrieve static and dynamic threat templates, including threat lists and dynamic filter rules
Agents
List simulation agents and get detailed configurations (IP, attack modules, platform, status)
Integrations
List SIEM/EDR integrations with health statuses and connected agent info
List integration agents (collectors) with status and token validity
Vendor Mitigations
List mitigation devices and get their effectiveness statistics
Retrieve vendor-specific prevention signature suggestions for not-blocked actions
List not-blocked actions with generic mitigation recommendations
Write Tools (opt-in, disabled by default)
Create, update, delete, or cancel simulations
Trigger an immediate simulation run
Create new threat templates
All write operations require explicit opt-in via configuration (PICUS_ENABLE_WRITE_TOOLS=true) for safety.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Picus Security MCP Server list failed Picus simulations"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Picus Security MCP Server
Drive the Picus Breach & Attack Simulation platform from Claude — and any MCP client.
29 tools · 8 Picus API groups · 23 read-only + 6 write (opt-in)
A Model Context Protocol server that exposes the Picus Security Breach & Attack Simulation (BAS) REST API as tools any MCP-compatible client — Claude Code, Claude Desktop, and others — can call.
Ask your assistant to "list failed Picus simulations", "show the latest run results for the DMZ agent", or "search the threat library for ransomware threats affecting Windows" — and it drives the Picus API for you.
How it works
You provide a long-lived refresh token; the server exchanges it for a short-lived access token, caches it, and refreshes it automatically — so tool calls never deal with auth.
Related MCP server: AccuKnox MCP Server
Features
All eight Picus API groups — simulations, run results & analytics, threat library, threat templates, agents, integrations, and vendor mitigations.
23 read-only tools always available; 6 write tools (create/update/ delete/cancel/simulate-now, create template) gated behind an explicit opt-in so an assistant can't launch or destroy a simulation by accident.
Automatic auth — you provide a long-lived refresh token; the server handles the access-token exchange, caching, and refresh (including retry on a 401).
Portable — speaks MCP over stdio and reads all config from the environment, so it works with any MCP host and isn't tied to one machine.
Handles the API's quirks — mixed
/v1and/v2paths, inconsistent pagination envelopes, and epoch-millisecond timestamps. Responses are returned raw so nothing is lost in translation.
Prerequisites
Python 3.10 or newer
A Picus Security account with REST API access
Getting a Picus API token
Sign in to the Picus dashboard and go to Settings → REST API Token.
Click Generate Token. Choose a name, description, expiration (up to 6 months), and the scopes you need.
Copy the token immediately — Picus shows it only once.
This is your refresh token (PICUS_REFRESH_TOKEN). The server exchanges it for
short-lived access tokens automatically.
Install
git clone https://github.com/BeardedInfoSec/picus-security-mcp.git
cd picus-security-mcp
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e .Configure
Copy the example env file and paste in your token:
cp .env.example .env# .env
PICUS_API_BASE="https://api.picussecurity.com/v1"
PICUS_REFRESH_TOKEN="paste-your-refresh-token-here".env is gitignored — your token never gets committed. The server auto-loads
.env from the working directory (real environment variables take precedence, so
a host that injects config still wins).
Variable | Required | Default | Purpose |
| yes | — | Picus REST API refresh token |
| no |
| API base; the host origin is derived from it (both |
| no |
| Register the mutating tools when |
| no |
| Per-request timeout (seconds) |
| no |
| Refresh the access token this many seconds before it expires |
Verify it works
A smoke test builds the server, authenticates, and makes a couple of live calls:
python scripts/smoke_test.pyExpected output ends with your real agent and simulation counts, e.g.:
auth OK — access token acquired (len=185)
GET /v1/agents ...
agents returned: 42 -> ['Browser Agent', 'DMZ-client', ...]Use with Claude Code
Copy the example config and set the command path to your clone location, then
restart Claude Code (or run /mcp):
cp .mcp.json.example .mcp.json
# prints the exact absolute path to paste as "command" — no guessing:
echo "$(pwd)/.venv/bin/picus-mcp".mcp.json is gitignored (it holds a machine-specific absolute path); the tracked
.mcp.json.example is the template:
{
"mcpServers": {
"picus": {
"command": "/absolute/path/to/picus-security-mcp/.venv/bin/picus-mcp",
"env": { "PICUS_ENABLE_WRITE_TOOLS": "false" }
}
}
}No token in this file — the server reads it from .env. Once connected, ask
Claude to "list my Picus simulations" to confirm the end-to-end path.
Use with Claude Desktop
Add to claude_desktop_config.json (macOS:
~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"picus": {
"command": "/absolute/path/to/picus-security-mcp/.venv/bin/picus-mcp",
"env": {
"PICUS_REFRESH_TOKEN": "paste-your-refresh-token-here"
}
}
}
}Claude Desktop doesn't run from your project directory, so pass the token in the
env block (or export it in the launching environment).
Use with any other MCP client
Run the server directly; it speaks MCP over stdio:
export PICUS_REFRESH_TOKEN="…" # or rely on .env
picus-mcpResponse format
Every tool returns its result twice:
a text block — markdown tables for list endpoints, an indented tree for everything else, with epoch-millisecond timestamps decoded inline;
structuredContent— the untouched API payload, exactly as Picus returned it.
The text is what a model or a human reads, and it is a summary: long prose is
truncated and rows are reordered (dead agents last, and so on). Anything it
leaves out is still in structuredContent, so nothing is lost. On a typical
call the text runs ~65% smaller than the raw JSON dump it replaces.
Formatting lives in src/picus_mcp/format.py. The
high-volume list endpoints have hand-written formatters; everything else uses a
generic renderer that walks arbitrary JSON without dropping fields, so an
undocumented or newly-added API shape still renders readably. A formatter that
raises falls back to that generic renderer rather than failing the call.
Enabling write tools
Write tools are off by default because they can start or delete real
simulations against your infrastructure. To enable them, set
PICUS_ENABLE_WRITE_TOOLS=true (in .mcp.json, the client env block, or your
shell). This adds:
Tool | Endpoint |
|
|
|
|
|
|
|
|
|
|
|
|
Tools reference (read-only)
Tool | Endpoint |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Project layout
src/picus_mcp/
config.py # env-based configuration + .env auto-loading
client.py # async HTTP client: token exchange, caching, retry, v1/v2 routing
server.py # builds the FastMCP server and registers tool groups
tools/ # one module per Picus API group
scripts/
smoke_test.py # live end-to-end check
PICUS_API.md # auth flow + manual curl referenceTroubleshooting
configuration error: PICUS_REFRESH_TOKEN is not set— create.envfrom.env.exampleand paste your token, or export the variable.Failed to obtain access token … refresh token may be expired— the refresh token expired or was revoked; generate a new one in the dashboard.Tools don't appear in Claude Code — MCP servers load at startup; restart Claude Code or run
/mcp. Check thecommandpath in.mcp.jsonis absolute and points at your.venv.Timestamps look wrong — most Picus fields are epoch milliseconds (a few threat-library fields are seconds). Values are returned raw; convert as needed.
Notes on the Picus API
List endpoints paginate with
limit/offset. Most wrap results in apagesobject withtotal_count;picus_list_not_blocked_actionsusespaginationinstead, and a few list endpoints return a bare array.The API mixes
/v1and/v2paths, which is why the client is anchored at the host origin and each tool carries its full versioned path.
See PICUS_API.md for the auth flow and a manual curl example.
License
MIT — see LICENSE.
An independent, community-built integration. Not affiliated with, endorsed by, or sponsored by Picus Security. "Picus" and the Picus logo are trademarks of Picus Security, used here only to identify the API this project targets.
Available Tools
23 toolspicus_get_action_alertsA
List alerts raised by a SIEM/EDR integration for one action (latest run).
Path is scoped to the latest run. Returns alerts with name, source, log_type, and time (epoch milliseconds). Paginated via limit (default 100, max 1000) and offset. node_id disambiguates an action used multiple times within a threat; if omitted, the first node is used. Alerts only appear when the simulation is enriched with an integration that has alert analysis enabled.
Inputs: action_id (required), threat_id (required), simulation_id (required), integration_id (required), +3 more.
picus_get_agentA
Get detailed configuration for one simulation agent by id.
Includes IP/NAT IP, whether an update is needed, and the attack modules enabled for the agent. created_at is epoch milliseconds.
Inputs: agent_id (required).
picus_get_device_signaturesA
Get vendor prevention signature suggestions for a device and actions.
action_ids is REQUIRED (max 10 ids). Returns signatures with signature_id, name, vendor_severity, product_platform/version, etc. — the vendor signatures that mitigate the given actions on this device.
Inputs: device_id (required), action_ids (required).
picus_get_latest_run_frameworksB
Get the latest run's MITRE ATT&CK / Unified Kill Chain framework mapping.
Same as picus_get_run_frameworks but for the most recent run. Raw API payload is returned as-is.
Inputs: simulation_id (required).
picus_get_latest_run_resultA
Get prevention + detection results for a simulation's most recent run.
Same shape as picus_get_run_result. Convenient when you don't have a specific run id.
Inputs: simulation_id (required).
picus_get_mitigation_device_statsA
Get effectiveness stats for one mitigation device.
Returns blocked_count, not_blocked_count, total_count, and an
effectiveness score. Served under /v2.
Inputs: device_id (required).
picus_get_run_frameworksB
Get a run's results mapped to MITRE ATT&CK and Unified Kill Chain.
Returns the framework-mapped prevention/detection view for the given run. (The exact response schema is not published in the Picus static docs; the raw API payload is returned as-is.)
Inputs: run_id (required), simulation_id (required).
picus_get_run_resultA
Get prevention + detection results for a specific simulation run.
Returns security scores plus threat counts (blocked/not_blocked/
not_tested) and attacker-objective counts. Note the API spells two fields
achived_count / unachived_count (sic) — they are returned verbatim.
The results block is populated only once the run is completed or
stopped; detection_analysis appears only when has_detection_analysis is
true. Timestamps are epoch milliseconds.
Inputs: run_id (required), simulation_id (required).
picus_get_run_threatsA
List a run's results broken down by threat -> objective -> action.
Each threat and action carries a prevention status (e.g. blocked /
unblocked / achieved) and detection analysis (log_result / alert_result
per integration). Paginated via limit (default 10, max 50) and offset;
response includes a pages object with total_count.
Inputs: run_id (required), simulation_id (required), limit, offset.
picus_get_simulationA
Get full detail for one simulation, including its run list.
The simulation_run array lists runs with their string ids; use a run id
with picus_get_run_result to fetch that run's prevention/detection
results. Timestamps are epoch milliseconds.
Inputs: simulation_id (required).
picus_get_templateA
Get full detail for one threat template.
Static templates return their threats list; dynamic templates also
return a rules array describing the filter criteria. content_updated_at
is 0 for static templates and epoch ms for dynamic ones.
Inputs: template_id (required).
picus_get_threatA
Get full detail for a single threat from the Threat Library.
Includes description, severity, affected OS/products, applicable agent types, threat actors, framework mappings (MITRE ATT&CK / Unified Kill Chain), and the objective -> action flows.
Inputs: threat_id (required).
picus_get_threat_actionA
Get full detail for a single action from the Threat Library.
Includes affected platforms, attack category/module, framework mappings (frameworks.mitre / frameworks.ukc), module-based process details, and keyword queries. created_at/updated_at/release_date are epoch milliseconds.
Inputs: action_id (required).
picus_list_agentsA
List all Picus simulation agents (peers).
Returns each agent's id, name, status (alive/dead), type, version, platform, and created_at (epoch milliseconds). Use an agent id with picus_get_agent for full detail, or when creating a simulation.
Inputs: no named parameters.
picus_list_integration_agentsA
List integration agents (the collectors that connect Picus to SIEM/EDR).
Reports id, name, status (Alive/Dead), whether installed, and whether the agent token has expired. Timestamps are epoch milliseconds.
Inputs: no named parameters.
picus_list_integrationsA
List SIEM/EDR integrations with health status.
Each integration reports id, name, type (SIEM/EDR), health_status (healthy flag plus an error object when unhealthy), and the connected integration agent. Timestamps are epoch milliseconds.
Inputs: no named parameters.
picus_list_mitigation_devicesA
List vendor-based mitigation devices (device_id, device_name).
Served under /v2. Use a device_id with picus_get_mitigation_device_stats or picus_get_device_signatures.
Inputs: no named parameters.
picus_list_not_blocked_actionsA
List not-blocked actions with generic mitigation suggestions.
Returns each not-blocked action with its associated signature_names and
signature_descriptions (generic, non-device-specific recommendations).
Filters: threat_or_action_name (substring), threat_ids, threat_severities,
attack_modules, assessment_id_list, is_all_assessments, run_id. Paginated
via limit/offset; response includes a pagination object with
total_count.
Inputs: limit, offset, run_id, threat_ids, +5 more.
picus_list_simulationsA
List simulations with overview data and latest prevention/detection scores.
Paginated via limit (default 25, max 50) and offset. Filters:
status: any of RUNNING, STOPPED, COMPLETED, SCHEDULED, "NOT STARTED", "WAITING FOR THE FIRST RUN", FAILED (substring/exact match per API).
simulation_name / agent_name / template_name: substring match.
agent_id / template_id: exact id match.
prevention_result_/detection_result_ gte/lte: score bounds (0-100).
Response includes a pages object with total_count. Scores are 0-100;
updated_at is epoch milliseconds.
Inputs: limit, offset, status, agent_id, +8 more.
picus_list_templatesA
List threat templates (dynamic and static).
Filters: category_name (e.g. "My Templates", "Emerging Threats", "Suggested by Picus Labs") and content_type ("dynamic" for rule-based or "static" for threat-list-based). Paginated via limit/offset. Each template reports threat_count, agent_types, and content_updated_at (epoch ms).
Inputs: limit, offset, content_type, category_name.
picus_list_threat_actionsA
List Threat Library actions with light metadata (id, name, updated_at).
NOTE: this endpoint is served under /v2. Paginated via limit (default 100,
max 100) and offset; filter by updated_at_gte/lte (epoch). Response
includes a pages object with total_count.
Inputs: limit, offset, updated_at_gte, updated_at_lte.
picus_list_threat_actorsA
List all threat actors in the Threat Library (id, name, aka aliases).
Inputs: no named parameters.
picus_search_threatsA
Search the Picus Threat Library with rich filters.
Filters (all optional): severities (Low/Medium/High), attack_category_ids,
attack_module_ids, release_date_gte/lte (epoch), is_predefined,
affected_products, affected_os (Windows/Linux/macOS), unified_kill_chains,
threat_actors, mitre_attack (tactics), attacker_objectives. Paginated via
limit/offset; response includes a pages object with total_count.
Array filters are sent comma-separated. Each threat includes framework mappings and its objective/action flows.
Inputs: limit, offset, severities, affected_os, +10 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 23 tools
Most tools have distinct purposes, with minor overlap between 'latest' and specific run/framework variants. Descriptions clarify the difference, making confusion unlikely.
All tools follow a consistent 'picus_verb_noun' pattern in snake_case, with verbs being 'list', 'get', or 'search'. No mixing or irregular naming.
23 tools cover a broad domain (simulation, threats, agents, integrations, mitigation) without being excessive. Each tool serves a clear functional area.
The tool set provides comprehensive read access to all major entities (simulations, runs, threats, actions, etc.) but entirely lacks mutation (create/update/delete) capabilities, which limits its usefulness for active simulation management.
Related MCP Connectors
Chat with your Zihin.ai agents, list them and load platform skills from any MCP client.
MCP server for Pentest-Tools.com: run scans, manage findings and reports via your preffered LLM.
Build, validate, and manage API simulations in WireMock Cloud from MCP-compatible AI agents.
Enrich, search, assess, and manage threat intelligence through 80+ typed MCP tools.
Related MCP Servers
- AlicenseAqualityDmaintenanceConnects MCP-compatible AI clients to a MITRE Caldera adversary emulation platform, enabling natural language construction of attack scenarios, agent inspection, and operation management.1824 PyPIApache 2.0

AccuKnox MCP Serverofficial
FlicenseNot gradedqualityCmaintenanceEnables interaction with the AccuKnox cloud security platform through MCP, allowing users to query cloud assets, vulnerabilities, and perform security analysis via natural language or API.1-- AlicenseCqualityCmaintenanceEnables LLM agents to interact with and automate operations with the AdaptixC2 framework via the MCP protocol.5434GPL 3.0
- AlicenseNot gradedqualityDmaintenanceEnables AI-powered security investigation and threat analysis by connecting MCP-compatible clients to Uptycs Juno.Apache 2.0