Interactsh Mcp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Interactsh Mcp (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
An MCP server that gives LLMs first-class access to ProjectDiscovery's Interactsh — the out-of-band (OOB) interaction collector behind tools like Nuclei.
Use it to let an agent validate OOB-style vulnerabilities end-to-end: blind SSRF, log4shell-style JNDI callbacks, blind XXE, blind SQLi exfil, DNS exfiltration, command-injection callbacks, blind XSS, etc. The agent gets a fresh payload URL, embeds it in a request to the target, and polls for the callback to confirm the bug.
Works against the public Interactsh service (the public oast.* rotation) out of the box, and against any self-hosted server — with or without a token.
The package ships two things in one install:
interactsh-mcp) for Claude Code, Codex CLI, etc.interactsh_mcp) you can import directlyif you'd rather drive Interactsh from your own code — see Use as a Python library below.
pip install interactsh-mcp
# or, with uv:
uv tool install interactsh-mcpAfter install the interactsh-mcp command starts the MCP server on stdio.
pip install git+https://github.com/rek7/interactsh-mcp.git
# or, run without installing:
uvx --from git+https://github.com/rek7/interactsh-mcp.git interactsh-mcpgit clone https://github.com/rek7/interactsh-mcp.git
cd interactsh-mcp
pip install .# Build locally
docker build -t interactsh-mcp .
docker run --rm -i interactsh-mcp # smoke test; Ctrl-D to exitThe image runs as a non-root user and only needs outbound HTTPS to the Interactsh server.
Claude Code reads MCP servers from ~/.claude.json (or a project-local .mcp.json). Add an entry under "mcpServers":
Local Python install — public servers
{
"mcpServers": {
"interactsh": {
"command": "interactsh-mcp"
}
}
}Local Python install — self-hosted server
{
"mcpServers": {
"interactsh": {
"command": "interactsh-mcp",
"env": {
"INTERACTSH_SERVER": "interact.example.com",
"INTERACTSH_TOKEN": "your-server-token"
}
}
}
}Omit INTERACTSH_TOKEN if your self-hosted server was started without -auth.
Docker
{
"mcpServers": {
"interactsh": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "INTERACTSH_SERVER",
"-e", "INTERACTSH_TOKEN",
"interactsh-mcp"
],
"env": {
"INTERACTSH_SERVER": "interact.example.com",
"INTERACTSH_TOKEN": "your-server-token"
}
}
}
}You can also register the server with the CLI:
claude mcp add interactsh -- interactsh-mcp
# with env vars:
claude mcp add interactsh \
-e INTERACTSH_SERVER=interact.example.com \
-e INTERACTSH_TOKEN=your-server-token \
-- interactsh-mcpCodex CLI (OpenAI's terminal coding agent) reads MCP servers from ~/.codex/config.toml:
Public servers
[mcp_servers.interactsh]
command = "interactsh-mcp"Self-hosted with token
[mcp_servers.interactsh]
command = "interactsh-mcp"
env = { INTERACTSH_SERVER = "interact.example.com", INTERACTSH_TOKEN = "your-server-token" }Docker
[mcp_servers.interactsh]
command = "docker"
args = ["run", "--rm", "-i", "-e", "INTERACTSH_SERVER", "-e", "INTERACTSH_TOKEN", "interactsh-mcp"]
env = { INTERACTSH_SERVER = "interact.example.com", INTERACTSH_TOKEN = "your-server-token" }~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows. Same shape as the Claude Code example above.
| Variable | Purpose |
|---|---|
INTERACTSH_SERVER | Default hostname (e.g. interact.example.com). If unset, a random host from the public oast.* rotation is used. Per-call server argument overrides. |
INTERACTSH_TOKEN | Default Authorization token for -auth-protected servers. Per-call token argument overrides. |
INTERACTSH_LOG_LEVEL | Python log level (default WARNING). |
| Tool | What it does |
|---|---|
create_session | Registers a new Interactsh session, starts background polling, and returns session_id + payload_url. Optional args: server, token, poll_interval, scheme, correlation_id_length. |
list_sessions | Lists active sessions with their buffer counts. |
poll_interactions | Drains buffered interactions for a session. wait (seconds) blocks until the first event arrives; clear=false peeks without consuming. |
new_payload | Vends an additional payload URL on an existing session (different nonce, same correlation-id — all routed back to the same session). |
destroy_session | Deregisters and frees the session. |
get_default_servers | Returns the public oast.* host list. |
create_session → gets payload_url e.g.c7lci09s8mts0o3og0g0abc12.oast.pro.
payload_url — a JNDI string in a User-Agentheader, a ?url=http://payload_url/ SSRF, a DNS subdomain in a SQL payload, etc.
poll_interactions(session_id, wait=10) and, if interactionscome back, reports the vuln as confirmed (with the source IP / raw request from the callback as evidence).
destroy_session when done.For multiple test variants in one conversation the agent can either call create_session per variant or call new_payload to get distinct URLs that share a session.
The package exports an async client you can import directly — no MCP, no LLM, just interactsh_mcp:
import asyncio
from interactsh_mcp import InteractshClient
async def main():
# No args → random public oast.* server. Pass server=/token= to target a
# self-hosted instance (token only needed if it was started with -auth).
async with InteractshClient() as client:
payload_url = client.generate_payload()
print(f"send something to: {payload_url}")
# ... fire your exploit / trigger the target with that URL ...
for event in await client.poll():
print(f"{event.protocol} from {event.remote_address}")
asyncio.run(main())For longer-lived setups (multiple payloads, background polling, buffered events), use the session manager:
from interactsh_mcp import SessionManager
mgr = SessionManager()
session = await mgr.create(poll_interval=2.0)
url_a = mgr.new_payload(session) # different nonce, same correlation-id
url_b = mgr.new_payload(session)
# ... trigger both ...
events = await session.drain(wait=15) # blocks until first event or timeout
await mgr.aclose()Exports at the package root:
| Name | What it is |
|---|---|
InteractshClient | Async client. Context-manage it; register() / poll() / deregister() / generate_payload(). |
Interaction | Dataclass for a single decoded event: protocol, unique_id, full_id, q_type, raw_request, raw_response, remote_address, timestamp, raw (full JSON). |
InteractshError | Raised on registration/poll failures. |
Session / SessionManager | Background-polling multi-session helpers. |
DEFAULT_SERVERS | Tuple of public oast.* hostnames. |
The package ships type stubs (py.typed), so mypy / pyright pick the types up automatically. If you need to call from sync code, wrap with asyncio.run(...) — see examples/04_sync_wrapper.py.
More runnable examples: examples/.
Quick reminder of how to stand up a server you can point this MCP at:
# Public, no auth:
interactsh-server -domain interact.example.com
# Token-protected (server prints a random token; pass it as INTERACTSH_TOKEN):
interactsh-server -domain interact.example.com -authSee the interactsh server docs for DNS, TLS, and infra setup.
git clone https://github.com/rek7/interactsh-mcp.git
cd interactsh-mcp
python -m venv .venv && source .venv/bin/activate
pip install -e '.[test]'
pytestLive integration tests (DNS-callback against a real server) are opt-in:
INTERACTSH_LIVE=1 pytest tests/test_live.py
# or against a self-hosted server:
INTERACTSH_LIVE=1 INTERACTSH_SERVER=interact.example.com INTERACTSH_TOKEN=... pytest tests/test_live.pyThe mocked test suite exercises the full register → poll → decrypt → drain path against an in-process fake server, so the crypto and HTTP wiring are covered without network access.
MIT. Interactsh itself is MIT-licensed and developed by ProjectDiscovery.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.