Install
$ agentstack add mcp-nislive-pyrit-mcp-server ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
PyRIT MCP Server
A modular MCP (Model Context Protocol) server that wraps Microsoft PyRIT 0.14.0 and exposes 31 composable tools for authorized AI red-teaming — attack execution, scoring, prompt conversion, and result inspection.
It is designed to be the "weapon store + scoring lab" component of a larger autonomous red-team platform. Because it speaks standard MCP, any agent or MCP-capable host can drive it — for example a LangGraph agent that runs the attack loop and stores findings. Instead of one monolithic endpoint, it offers small, independent tools that an agent can freely combine inside a ReAct loop.
> ⚠️ Authorized use only. This project is for security research, CTF, and red-teaming of > systems you own or are explicitly permitted to test. Do not use it against third-party systems > without written authorization.
Architecture
Any MCP agent / host ──► PyRIT MCP Server (this project) ──► target LLM(s)
(the brain — e.g. (attacks + scoring, 31 tools) (victim / adversarial)
LangGraph, Claude
Desktop, custom loop)
pyrit_mcp_server/
├── main.py # FastMCP instance + registers all tool modules
├── __main__.py # python -m pyrit_mcp_server
├── core/
│ ├── memory.py # CentralMemory singleton (idempotent, in-memory SQLite)
│ ├── targets.py # TargetRegistry — create/get/remove OpenAI-compatible targets
│ └── jobs.py # JobManager — background execution via asyncio.Task
└── tools/
├── targets.py # 3 tools
├── attacks.py # 11 tools (4 single-turn + 4 multi-turn + 3 job mgmt)
├── scoring.py # 7 tools
├── converters.py # 3 tools
├── scenarios.py # 2 tools
├── datasets.py # 2 tools
└── memory_tools.py# 3 tools
Key design decisions
- Multi-turn attacks run in the background. MCP tool calls would otherwise time out, so
red_team, crescendo, pair, and tap return a job_id immediately and run as an asyncio.Task. Poll with get_job_status / list_jobs.
- Token-cost guardrails. Hard limits (
MAX_TURNS=30,MAX_TREE_WIDTH=10,
MAX_TREE_DEPTH=15, MAX_BRANCHING=5) are clamped on every attack to prevent runaway spend. tap also returns an estimated LLM-call count.
- Two-stage hybrid scoring.
score_hybridfirst runs a fast static check, then verifies with
an LLM only if it triggers — reducing false positives.
- Ephemeral memory by design. PyRIT's own store is in-memory SQLite (
:memory:); persistence
is expected to live in the host platform, not here.
The 31 tools
Targets (3)
| Tool | Description | |------|-------------| | create_target | Create an OpenAI-compatible chat target (endpoint, model, api_key) | | list_targets | List all registered targets | | remove_target | Remove a target |
Attacks — single-turn, synchronous (4)
| Tool | Description | |------|-------------| | send_prompt | Send a prompt directly (PromptSendingAttack) | | run_skeleton_key_attack | Skeleton Key jailbreak | | run_flip_attack | Flip-based jailbreak | | run_role_play_attack | Role-play jailbreak (needs an adversarial LLM + scenario) |
Attacks — multi-turn, background job (4)
| Tool | Description | |------|-------------| | run_red_team_attack | Adversarial LLM iteratively generates prompts | | run_crescendo_attack | Gradual escalation attack | | run_pair_attack | PAIR — Prompt Automatic Iterative Refinement | | run_tap_attack | TAP — Tree of Attacks with Pruning (most expensive) |
Attacks — job management (3)
| Tool | Description | |------|-------------| | get_job_status | Query a background job's status/result | | list_jobs | List all jobs | | wait_for_job | Block until a job finishes (or timeout_seconds), polling every poll_interval_seconds |
Scoring (7)
| Tool | Type | Description | |------|------|-------------| | score_likert | LLM | 13 categories, float 0–1 (harm, violence, cyber, …) | | score_true_false | LLM | 5 question types (taskachieved, promptinjection, …) | | score_refusal | LLM | Detect whether the AI refused | | score_substring | non-LLM | Substring match | | score_regex | non-LLM | Regex pattern match | | score_security | non-LLM | 6 checks: xss, sqlinjection, shellcommand, pathtraversal, credentialleak, markdown_injection | | score_hybrid | hybrid | Static check + LLM verification (false-positive reduction) |
Converters (3)
| Tool | Description | |------|-------------| | convert_prompt | Transform text with one converter (base64, rot13, leetspeak, …) | | chain_convert | Apply several converters in sequence | | list_converters | List available converters |
Scenarios (2)
| Tool | Description | |------|-------------| | list_scenarios | List PyRIT built-in scenarios (AIRT, Garak, Foundry) | | run_scenario | Run a built-in scenario (supports max_objectives) |
Datasets (2)
| Tool | Description | |------|-------------| | list_seed_datasets | List PyRIT YAML seed datasets | | load_objectives | Load seed objectives (with filtering) |
Memory (3)
| Tool | Description | |------|-------------| | get_attack_history | Query attack history | | get_conversation | Fetch a conversation by id | | export_results | Export results as JSON |
Requirements
- Python 3.11+
pyrit==0.14.0,mcp>=1.27(installed automatically)- An OpenAI-compatible endpoint for the LLM targets — e.g. the OpenAI API or a local
Ollama server (http://127.0.0.1:11434/v1).
Installation
python -m venv .venv
source .venv/bin/activate
pip install -e .
# configure secrets
cp .env.example .env # then edit .env and add your API key(s)
Running
# as an installed entry point
pyrit-mcp-server
# or as a module
python -m pyrit_mcp_server
The server speaks MCP over stdio. Example client (e.g. Claude Desktop) config:
{
"mcpServers": {
"pyrit": {
"command": "/path/to/.venv/bin/python",
"args": ["-m", "pyrit_mcp_server"]
}
}
}
Typical flow
create_targetfor the victim (and one for the adversarial/scorer LLM).- Run an attack —
send_prompt(sync) orrun_crescendo_attack(returns ajob_id). - For multi-turn jobs, poll
get_job_statusuntilcompleted/failed. - Score the response with
score_likert,score_refusal,score_security, etc. - Inspect with
get_attack_history/export_results.
Example
[examples/crescendo_attack.py](examples/crescendoattack.py) is a complete, runnable MCP client that drives the server end-to-end against a local Ollama model (llama3.2:1b): it spins up two targets (victim + adversarial), launches a run_crescendo_attack, polls get_job_status until the job completes, then pulls the result via get_attack_history and scores the last response with score_security.
# requires a local Ollama server running on http://127.0.0.1:11434
.venv/bin/python examples/crescendo_attack.py
It doubles as a smoke test: if it runs to completion and prints a result, the core target → attack → job → history → scoring path is working. API keys for real OpenAI targets are read from the environment (OPENAI_API_KEY) — never hardcode them.
Known limitations
- Concurrent multi-turn contention — launching all four multi-turn attacks at once can leave
jobs stuck in running. Run them sequentially.
- Private-attribute coupling — a couple of code paths reach into PyRIT internals
(OpenAIChatTarget._endpoint/_api_key, a scenario's _default_dataset_config). These may break on a future PyRIT upgrade.
- No job cleanup — completed jobs/tasks are retained for the process lifetime (in-memory only).
run_scenariomax_objectivesis honored by clamping the scenario's default dataset size;
scenarios that don't expose that config silently ignore the limit.
License
Released under the [MIT License](LICENSE). Built on top of Microsoft PyRIT, which is licensed separately (MIT) by Microsoft.
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Nislive
- Source: Nislive/pyrit-mcp-server
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.