mcp-security-proxy
Sends run notifications and summaries to a Telegram chat via a bot, including run started, technique attempted, detection result, containment recommendation, and run summary.
Click on "Install 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., "@mcp-security-proxyRun a red-team simulation against the lab baseline and report anomalies."
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.
MCP Security Proxy
A personal, on-demand red/blue/purple-team lab project. It logs every tool call an AI agent makes through an MCP proxy, baselines each agent's normal behavior, flags anomalies, runs a lab-scoped red-team simulation against that baseline, scores blue's detection rate, and narrates the whole run to Telegram.
Not a daemon. Nothing here runs 24/7 — it's triggered by a CLI command or a cron job, does one run, and exits. Targets are restricted to self-owned lab VMs only, never external systems.
Why
Most anomaly detection assumes the actor being profiled is a human on a network — peers, off-hours logins, transfer volume. This project applies the same behavioral baselining technique to a different actor: an AI agent's MCP tool calls. An agent that suddenly calls a tool it's never touched, at an hour it's never active, with a payload far outside its normal size, or with a burst of distinct tools in one window looks a lot like lateral movement looks on a network — so the same detection approach generalizes to it.
It's built on top of a prior project, lateral-movement-detector, which validated
this baselining approach on real captured network traffic (per-device peer/hours/
volume/fan-out baselines, 4 signal types, 5/5 detection on a simulated SSH-flood
attack with 0 false positives). This project ports that same detector logic
(baseline.py / detector.py) onto a new data source — an MCP call log instead of
a traffic capture — rather than starting the detection approach from scratch.
Related MCP server: Agent Guardrail MCP
Architecture
AI agent (MCP client)
│
▼
┌─────────────────┐ forwards every call ┌────────────────────┐
│ proxy/server │ ──────────────────────────▶ │ real downstream MCP │
│ (stdio MCP │ ◀────────────────────────── │ server │
│ proxy) │ returns result └────────────────────┘
└─────────────────┘
│ writes one hash-chained entry per call
▼
logs/calls.jsonl (proxy/audit_log.py — append-only, tamper-evident)
│
▼
┌───────────────────┐ per-agent stats ┌──────────────────┐
│ detector/baseline │ ───────────────────▶ │ detector/baseline │
│ (learns normal) │ │ .json │
└───────────────────┘ └──────────────────┘
│ │
▼ ▼
┌───────────────────────────────────────────────────────────┐
│ detector/detector — compares new calls to the baseline, │
│ raises NEW_TOOL / OFF_PATTERN / PAYLOAD_OUTLIER / │
│ SEQUENCE_SPIKE / UNKNOWN_AGENT, tiers by signal count │
└───────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────┐
│ detector/suppression — checks config/known_jobs.yaml; │
│ strips signals a documented recurring job explains │
│ (never silently — suppressed signals stay visible in output) │
└───────────────────────────────────────────────────────────┘
│
▼ tier: alert / observation / suppressed
┌───────────────────┐ ┌───────────────────┐
│ red/orchestrator │ scope │ config/lab_scope │
│ picks technique + │◀──────▶│ .yaml (hard │
│ target, runs it via│ │ allowlist, fail- │
│ red/executor │ │ closed, exact- │
│ (MockExecutor — │ │ match only) │
│ no live Caldera yet)│ └───────────────────┘
└───────────────────┘
│ injects the result as an MCP call under an
│ EXISTING baselined agent identity
▼
purple/orchestrator — runs red, injects into logs/calls.jsonl,
runs detector.detect() once over the updated log, reads back
each round's outcome by trace_id, scores alert/observation/
suppressed/missed, logs to logs/purple_runs.jsonl
│
▼
trigger/run.py — the on-demand entrypoint (CLI or cron). Drives
the same red+blue round-trip and narrates each stage via
trigger/telegram.py: run started → technique attempted →
detected/observation/suppressed/missed → containment
recommendation (alert tier only, trigger/containment.py) →
run summary
│
▼
Telegram chatEvery log (logs/calls.jsonl, logs/red_runs.jsonl, logs/purple_runs.jsonl) is
append-only and hash-chained: each entry embeds the SHA-256 hash of the previous
entry, so editing or deleting a prior line breaks the chain for everything after
it. proxy/audit_log.py and red/run_log.py / purple/scoreboard.py are
independent implementations of the same pattern rather than shared code, on
purpose — different domain fields, low duplication cost, avoids coupling logs that
evolve separately.
Components
Package | Role |
| Stdio MCP proxy. Sits between the agent and a real downstream MCP server, forwards every call, writes a hash-chained audit entry ( |
| Learns a per-agent baseline (known tools, active hours, avg/std payload size, avg/std fan-out per time window) from the call log, then flags calls that deviate. Single signal → |
| Checks anomalies against |
| Lab-scoped red-team simulation. |
| Runs a red-team round, injects the result into the same |
| The on-demand entrypoint ( |
Running it
Requires Python 3.12 and the packages in requirements.txt (a venv is expected —
see PROJECT_SPEC.md's environment notes).
pip install -r requirements.txt1. Generate some call traffic through the proxy (dev smoke test against the bundled mock downstream server):
python3 -m proxy.test_clientThis drives proxy/server.py (configured via config/proxy_config.yaml), which
appends entries to logs/calls.jsonl. Run it a number of times (or point a real
MCP agent at the proxy) to build up enough history for a baseline.
2. Build the baseline:
python3 -m detector.baseline logs/calls.jsonlWrites detector/baseline.json.
3. Run the detector standalone:
python3 -m detector.detector logs/calls.jsonlPrints alerts / observations / suppressed calls against config/known_jobs.yaml.
4. Run a red-team simulation on its own (mock executor, targets restricted to
config/lab_scope.yaml):
python3 -m red.orchestrator --runs 35. Run red + blue together and score detection:
python3 -m purple.orchestrator --rounds 5 --impersonate-agent dev-test-agentRequires a baseline that already contains --impersonate-agent's identity (step 2
must have run against call history for that agent first).
6. Run the full on-demand pipeline with Telegram notifications:
cp .env.example .env # fill in TELEGRAM_BOT_TOKEN / TELEGRAM_CHAT_ID, or leave blank
python3 -m trigger.run --rounds 5 --impersonate-agent dev-test-agentWithout Telegram credentials set, notifications print to stdout instead — the pipeline runs the same either way. For scheduled runs, add a cron entry, e.g.:
0 3 * * * cd /path/to/mcp-security-proxy && venv/bin/python3 -m trigger.runKnown limitations
Being upfront about where this project currently overstates or hasn't yet proven itself:
Mock executor only — no live Caldera integration yet.
red/executor.pydefines a scope-gatedExecutorinterface specifically so a real MITRE Caldera (or similar) executor can be dropped in behind it later, but the only executor that exists today isMockExecutor, which never touches the network — it just reports what it would have run. The scope-enforcement design (fail-closed allowlist, exact-match only, re-checked independently by the executor) is built and tested, but it has only ever gated a simulated action, not a real one.target_resourceandreasoning_summaryare best-effort heuristics, not ground truth. MCP tool-call arguments are arbitrary JSON with no first-class "what resource is this touching" or "why" field.proxy/extract.pyscans a fixed list of common argument key names (path,url,host,command, etc.) fortarget_resource, falling back to the first argument key/value if none match.reasoning_summaryonly reflects real agent intent if the calling agent populates the non-standard_meta.reasoningfield this proxy defines; otherwise it's a generated stub listing the argument keys. Both are documented in the code as best-effort — the detector doesn't (and shouldn't) trust either one blindly.Business-logic judgment isn't solved.
config/known_jobs.yamlsuppression only handles patterns a human has explicitly documented in advance (specific agent + tool + hour window + payload range). It does not, and isn't intended to, make any general judgment about whether a novel action is legitimate — an unmatched anomaly is always left for human review, never auto-cleared.Detection has only been exercised against deliberately obvious anomalies. Verification so far (per project history) has been things like a brand-new tool name, an off-hours call, or a payload far outside normal range — synthetic and clearly outside the baseline. It has not been tested against a subtler or evasive adversary deliberately trying to blend into an agent's normal tool-call pattern (e.g. staying inside known tools/hours/payload ranges while still doing something malicious, or slowly drifting a baseline over many legitimate-looking calls before acting). The z-score/count-based signals here are not adversarially hardened.
Other explicit non-goals carried over from
PROJECT_SPEC.md: no least-privilege/access-control enforcement (trigger/containment.pyonly ever produces a human-facing recommendation, never a real action), and this isn't positioned as a competitor to commercial autonomous pentesting tools (XBOW, Pentera, etc.) — it's a smaller, specialized portfolio project.
Safety
red/scope.py is the single source of truth for what the red-team engine is
allowed to target (config/lab_scope.yaml). It fails closed — a missing, empty,
or wildcard/CIDR scope file yields no in-scope targets, never "allow everything"
— and matching is exact-string only. red/executor.py's base class reloads and
re-checks this file itself before any technique runs, independent of whatever the
orchestrator computed, so a planning bug upstream can't get a live action
dispatched to something not on the list. This is process-level, convention-based
scoping, not network-level enforcement — it stops this codebase from acting
out-of-scope, but it is not a substitute for real firewall/segmentation around the
lab VM(s) it targets.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Zero-secret MCP gateway for AI agents: risk-scored, audited calls with human-in-the-loop approval.
Security firewall for AI agents — scans MCP calls for injection, secrets, and risks.
Watchdog for unattended AI agents: alerts, evidence checks and a verifiable proof per run.
AgentGuard — 20-tool AI safety MCP: policy preflight, risk scoring, audit logging, rate limits.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA unified MCP server providing observability, safety control, and behavior evolution for high-agency AI agents through tracing, replaying, and auditing. It features real-time firewall guardrails and ML-driven anomaly detection to monitor, block, or fork agent actions based on risk.7
- AlicenseAqualityBmaintenanceProvides prompt injection detection, PII/secrets redaction, and an audit trail for AI agents via MCP tools.4MIT
- AlicenseNot gradedqualityDmaintenanceProvides unified AI agent observability including tracing, cost tracking, performance monitoring, anomaly detection, and audit trails via MCP.55MIT
- AlicenseBqualityCmaintenanceEnables deterministic security testing of AI agents that use tools by serving synthetic MCP environments with poisoned data, fake secrets, and privileged actions. Records agent tool calls and evaluates security invariants (e.g., canary leaks, forbidden access, approval binding) without an LLM judge or real systems.8MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/shehab6157-design/mcp-security-proxy'
If you have feedback or need assistance with the MCP directory API, please join our Discord server