
Live recon and posture auditing for AI agent infrastructure: scans MCP configs, session logs, and APIs for secrets, poisoned catalogs, and CoT leaks.
Renaissance masquerade. Sit in the agent's seat.
Sit in the agent's seat.
A CLI that speaks MCP and OpenAI-compat the way the model does, then reports like linpeas. Findings plus remediations. No exploit payloads. No CoT decrypt.
| What | Live recon of agent infra: MCP configs, listeners, session logs, encrypted chain-of-thought echo, unauth APIs, catalog poison, skill trees. |
| Who | Operators of Hermes, Grok, Claude, Cursor, VS Code, Codex, and local model stacks who need to see what the agent can see. |
| What it is not | Not a jailbreak generator. Not the arXiv:2608.09867 weaker-model decoder. Not a runtime gateway. |
| Status | Beta. Offline cargo test is the public gate. Live --lab is for hosts you own. |
| License | MIT |
Static MCP scanners (Invariant mcp-scan, mcp-security-scan) lint schemas and configs. Health doctors ping initialize. The hole is the seat:
initialize, you are the agent.:11434, :8000) often bind 0.0.0.0 with no bearer.Wheels we ride, not rewrite: existing catalog detectors + pin/check, netstat, ureq GET-only, OWASP MCP Top 10 as the finding taxonomy. We did not clone mcp-scan or mcp-security-scan.
git clone https://gitlab.com/WattoCyber/masq.git
cd masq
cargo install --path .
# binary: masq
cargo test
# expect: exit 0
World suite (binary against fixtures, local mocks, this-host recon):
python scripts/world_suite.py
# field = ~/.grok/sessions lab = allowlisted hosts bench = frozen-corpus wall
python scripts/world_suite.py --lanes all
Kali-style remote box, from the desktop:
MASQ_REMOTE_HOST=user@host bash scripts/deploy_kali.sh
# on the box:
~/.local/bin/masq --plain
MASQ_LAB_HOSTS=... ~/.local/bin/masq --lab --plain
masq # live stream + posture report (includes skills)
masq --lab # same, plus allowlisted homelab hosts
masq tui # boxed TUI, stays until Ctrl+C
masq --plain # report only, no live stream
masq --json # machine report
masq recon # same dump, recon only
masq sniff ~/.grok/sessions # CoT / secrets in session logs
masq sniff --timeline PATH # file-order blob/secret/reason lines (no decrypt)
masq api # GET /v1/models on local (and --lab) ports
masq sit --url http://127.0.0.1:4443/mcp
masq chameleon --url http://127.0.0.1:4443/mcp -o /tmp/chameleon
masq chameleon --url ws://127.0.0.1:9000/mcp -o /tmp/chameleon
masq chameleon --url unix:///tmp/mcp.sock -o /tmp/chameleon
masq chameleon --token-file ~/.secrets/mcp.txt --url http://127.0.0.1:9/mcp -o /tmp/chameleon
masq chameleon -- python -m their_mcp -o /tmp/chameleon
# then: npx -y @copilotkit/aimock --config /tmp/chameleon/aimock.json
masq discover # find VS Code / Cursor / Claude / Grok / Hermes MCP configs
masq proxy --upstream http://127.0.0.1:4443/mcp --block
masq sast ./server # local sinks (semgrep if present)
masq classify --url http://127.0.0.1:4443/mcp --lab
masq overnight --lab --hours 6
masq map --from reports/overnight-YYYYMMDD/latest.json
# catalog
masq fixtures/t3_line_jump.json
masq fixtures/clean_calculator.json --trusted
masq pin fixtures/clean_calculator.json -k calc
masq check fixtures/clean_calculator.json -k calc
masq detectors
Exit: 0 clean · 2 findings ≥ --fail-on (default high) · 1 error.
TUI is opt-in (masq tui or --tui). Default on a tty is a linpeas live stream, then the report. Cron uses --plain / --no-color.
Aliases: doctor / audit → scan. chameleon → mimic. posture → seat.
sit / chameleon speak:
http://)ws://unix: and npipe:--framing auto tries NDJSON then Content-Length)Auth (never dumped to the report):
--token-file PATH (first line becomes Authorization: Bearer …)--token-env VAR--header "Name: value" (repeatable)wss:// is not built in. Stunnel to ws:// or use HTTP. HTTP follows zero redirects.
Stdio initialize does not advertise sampling. Flag server sampling / elicitation. Docs URLs (model-catalog.json, /docs/) are ignored on purpose.
Config + skill roots under $HOME / %USERPROFILE%:
VS Code, Cursor, Windsurf, Claude Desktop, Claude Code, Grok, Hermes, Codex, Continue, Gemini CLI, Amp, Kiro, OpenCode, Amazon Q, Antigravity, OpenClaw.
Plus cwd .mcp.json and MASQ_EXTRA_CONFIG (OS path list).
--lab)--lab is an allowlist, not a /24 scan. It is operator-configured. Nothing
is compiled in beyond loopback.
MASQ_LAB_HOSTS env var: comma-, space-, or newline-separated host:port or hosts..masq/lab-hosts file: one host per line, # comments.Example:
export MASQ_LAB_HOSTS="192.0.2.10,192.0.2.11"
masq --lab
MASQ_LAB_HOSTS is read for API probes and the TUI fleet rollup.
MASQ_SIT_URLS (or a --mcp-url) supplies MCP URLs to sit on with --lab.
Off-loopback sit --url needs --lab and an allowlisted host. Loopback unauth
initialize is High. Off-box is Critical.
Do not point proxy at a host you would not sit.
Sniff priority: chat_history.jsonl first, then Hermes request_dump_*, then other jsonl. Walk finishes. It does not keep the first 300 WalkDir hits. Point masq sniff <one-session-dir> to go deeper.
masq overnight --lab --hours 6 --interval-mins 20
# writes <cwd>/reports/overnight-YYYYMMDD/{latest.json,latest.md,latest.txt,delta.txt}
Does not mutate configs. Does not tools/call the live server. delta.txt is baseline / no_change / CHANGE plus + severity title and - severity title.
classify --llm and the TUI triage add-on are the only completions POSTs (Grok /v1/chat/completions, operator confirm). No key: local remediations only. Key from XAI_API_KEY or ~/.secrets/xai.txt. Never dumped.
CLI (clap) masq
→ seat | recon | sniff | api | sit | chameleon
→ discover | proxy | sast | classify | overnight | map
→ scan | multi | pin | check | detectors | tui
→ client (HTTP / SSE / ws / unix / npipe / stdio)
→ normalize (full-schema walk, caps)
→ detectors + sniff + recon + sit findings
→ report (text / JSON / Markdown) + optional TUI
Library crate: masq (scan_from_tools_list, scan_stdio, run_seat, PostureReport).
Do not dump ~/.secrets. Recon counts files. Path + "loaded".
cargo test
cargo clippy --all-targets -- -D warnings
Expect exit 0.
Fixtures: T1 description poison, T3 line-jump, T6 param names, T8 ANSI, T13 duplicate names, pin rugpull, multi-list, live NDJSON mock under tests/mock_mcp_server.py.
Secrets stay out of git (reports/, data/, .env, *.key, secrets/, .masq/).
MIT. Copyright 2026 SamsonCyber.
| Command | What it does |
|---|
seat (default) | Full posture: recon + sniff + api + skills + optional sit. |
recon | Config files, listeners, shadow URLs, sudo argv, unpinned npx/uvx. |
sniff | Session logs for secrets, plaintext reasoning, encrypted CoT echo. |
sniff --timeline | File-order T0001 lines. No decrypt. Caps at 200 events/file. |
api | GET-only /v1/models (and kin) on loopback; --lab adds allowlisted peers. |
sit | Speak MCP: initialize, notifications/initialized, tools/list, prompts/list, resources/list. Never originates tools/call. |
chameleon / mimic | Sit a live or file catalog, write catalog.json + aimock.json + calls.json. Example tools/call envelopes are for aimock only. |
discover | Print known agent MCP config paths. No spawn. |
proxy | Forward the agent's JSON-RPC. --block refuses secret-shaped tools/call params/results. Default listen 127.0.0.1:9877. |
sast | Local source sinks. Uses semgrep when installed. |
classify | Local IPI / poison review of a live tools/list. --llm asks Grok (operator key). |
overnight | Repeat seat until --hours elapse. Writes reports. Does not mutate configs. |
map | Text attack-path queries over a saved posture JSON. No diagram. |
scan / multi | Static catalog lint (bare .json paths rewrite to this). |
pin / check | Content-hash pin store (.masq/pins.json) for rug-pull CI. |
detectors | Print the catalog rule pack. |
tui | Boxed seat. Stays until Ctrl+C. |
| Module | Covers |
|---|
| recon | MCP01 secrets path, MCP04 unpinned npx/uvx, MCP07/09 listeners and shadow URLs, MCP05 sudo argv |
| catalog | MCP03 schema poison / shadowing / rugpull |
| skills | Same catalog detectors on SKILL.md (Hermes, Grok, Claude, Cursor, Codex, Gemini, Amp, Kiro, OpenCode, OpenClaw). No Snyk cloud. |
| sit | MCP02 scope creep, MCP03 live tools/list, MCP07 unauth initialize, server sampling/elicitation advertise, Streamable HTTP (2025-06-18) then HTTP+SSE (2024-11-05), Origin DNS-rebinding |
| sniff | MCP01 + MCP10 + arXiv:2608.09867 encrypted CoT echo (including thinkingSignature) |
| api | MCP07 unauth /v1/models, MCP09 LAN bind |
| watch | pin-diff on .masq/pins.json + skills. Overnight sets this. Not a proxy. |
| fleet | lab allowlist rollup in one FLEET section |
| map | Text path queries over a posture report |
| Limit | Value |
|---|
| tools/list file | 8 MiB |
| sniff file | 8 MiB (first 2 MiB sampled if larger) |
| sniff files / root | 300 (newest mtime within priority) |
| timeline events / file | 200, then timeline truncated |
| timeline T-lines | 500 (inspect and collapse still run) |
| schema walk depth | 64 |
| tools per inventory | 5_000 |
| HTTP probe | GET only, 2s API / 5s sit |
| sit handshake | timeout + kill |
| This tool | Not this tool |
|---|
| Sit as the agent client (initialize + list) | Originate tools/call against a live server |
| Detect encrypted CoT echo in logs | Decrypt CoT or replay into a weaker model |
GET /v1/models | POST completions (except opt-in TUI triage / classify --llm) |
| Pin-hash rugpull on a catalog | Signed PKI / enterprise pin vault |
Forward the agent's tools/call in proxy --block | Full runtime DLP gateway / SaaS control plane |
| Local skill-tree lint | Snyk / cloud SCA |
| Check | Expect |
|---|
masq fixtures/clean_calculator.json --trusted | exit 0 |
masq fixtures/t3_line_jump.json | exit 2 |
masq fixtures/t13_duplicate_names.json | exit 2 (tool shadowing) |
masq sniff --timeline fixtures/ (non-TTY / --json) | T0001 only with the flag |
masq chameleon fixtures/clean_calculator.json -o <tmpdir> | catalog.json, aimock.json, calls.json |
Live masq --no-color | tokens redacted (…, not full sk-) |