Picus Security MCP Server

Picus Security MCP Server

Enables interaction with Picus Security's Breach & Attack Simulation API, allowing natural language queries for simulations, threat library searches, and agent management through MCP-compatible clients.

Category
访问服务器

README

<div align="center">

<img src="assets/picus-logo.png" alt="Picus" width="260" />

Picus Security MCP Server

Drive the Picus Breach & Attack Simulation platform from Claude — and any MCP client.

License: MIT Python 3.10+ MCP Picus API

29 tools · 8 Picus API groups · 23 read-only + 6 write (opt-in)

</div>

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

<div align="center"> <img src="assets/architecture.svg" width="820" alt="An MCP client calls picus-mcp over stdio; picus-mcp calls the Picus REST API over HTTPS with a Bearer token, backed by an auto-refreshing token cache." /> </div>

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.


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 /v1 and /v2 paths, 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

  1. Sign in to the Picus dashboard and go to Settings → REST API Token.
  2. Click Generate Token. Choose a name, description, expiration (up to 6 months), and the scopes you need.
  3. 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
PICUS_REFRESH_TOKEN yes Picus REST API refresh token
PICUS_API_BASE no https://api.picussecurity.com/v1 API base; the host origin is derived from it (both /v1 and /v2 endpoints are used)
PICUS_ENABLE_WRITE_TOOLS no false Register the mutating tools when true
PICUS_REQUEST_TIMEOUT no 30 Per-request timeout (seconds)
PICUS_TOKEN_LEEWAY_SECONDS no 120 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.py

Expected 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-mcp

Response 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
picus_create_simulation POST /v1/simulations
picus_update_simulation PUT /v1/simulations/{id}
picus_delete_simulation DELETE /v1/simulations/{id}
picus_cancel_simulation PUT /v1/simulations/{id}/cancel
picus_simulate_now POST /v1/simulations/{id}/simulate-now
picus_create_template POST /v1/templates

Tools reference (read-only)

Tool Endpoint
picus_list_simulations GET /v1/simulations
picus_get_simulation GET /v1/simulations/{id}
picus_get_run_result GET /v1/simulations/{id}/run/{runId}
picus_get_latest_run_result GET /v1/simulations/{id}/run/latest
picus_get_run_threats GET /v1/simulations/{id}/run/{runId}/threats
picus_get_action_alerts GET …/run/latest/threats/{t}/actions/{a}/integrations/{i}/alerts
picus_get_run_frameworks GET /v1/simulations/{id}/run/{runId}/frameworks
picus_get_latest_run_frameworks GET /v1/simulations/{id}/run/latest/frameworks
picus_search_threats GET /v1/threat-library/threats
picus_get_threat GET /v1/threat-library/threats/{id}
picus_get_threat_action GET /v1/threat-library/actions/{id}
picus_list_threat_actions GET /v2/threat-library/actions
picus_list_threat_actors GET /v1/threat-library/threat-actors
picus_list_templates GET /v1/templates
picus_get_template GET /v1/templates/{id}
picus_list_agents GET /v1/agents
picus_get_agent GET /v1/agents/{id}
picus_list_integrations GET /v1/integrations
picus_list_integration_agents GET /v1/integrations/agents
picus_list_mitigation_devices GET /v2/mitigation/devices
picus_get_mitigation_device_stats GET /v2/mitigation/devices/{id}
picus_get_device_signatures GET /v1/mitigation/devices/{id}/signatures
picus_list_not_blocked_actions GET /v1/mitigation/generic/not-blocked-actions

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 reference

Troubleshooting

  • configuration error: PICUS_REFRESH_TOKEN is not set — create .env from .env.example and 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 the command path in .mcp.json is 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 a pages object with total_count; picus_list_not_blocked_actions uses pagination instead, and a few list endpoints return a bare array.
  • The API mixes /v1 and /v2 paths, 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.


<sub>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.</sub>

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选