Active adversarial security testing for AI agent protocols.
Batesian is a red-team CLI that sends crafted adversarial payloads against A2A and MCP protocol implementations to surface vulnerabilities in OAuth flows, push-notification callbacks, JWS handling, cross-session isolation, tool and metadata trust, and related behavior.
Authorized use only. Only run Batesian against systems you own or have explicit written permission to test. Unauthorized use is illegal and unethical.
Secrets and TLS. Prefer
BATESIAN_TOKEN(or your secret manager) over pasting long-lived credentials into shared terminals or CI logs. Use--skip-tlsonly when you must talk to a target with intentionally broken TLS (for example a local lab with self-signed certificates).
A2A and MCP servers sit in sensitive workflows: OAuth and dynamic registration, outbound callbacks, signed agent metadata, long-lived tasks, and tool execution. Many failure modes only show up when the implementation processes attacker-shaped protocol traffic—for example a crafted registration or redirect, a push URL pointed at an unexpected host, or a malformed JWS that should be rejected outright.
Batesian automates that style of check: each rule drives concrete requests (and, where relevant, out-of-band signals) and records whether the target behaved safely. The goal is reproducible evidence and actionable remediation, not a one-time manual poke at the endpoint.
Batesian ships 18 A2A rules and 17 MCP rules, covering SSRF, OAuth abuse, JWS algorithm confusion, prompt injection, protocol downgrade, TLS enforcement, and more.
- A2A rule catalog — Agent-to-Agent protocol attacks
- MCP rule catalog — Model Context Protocol attacks
Each finding is classified as confirmed (exploit succeeded) or indicator (behavioral signal
warranting manual review). All rules ship with CWE references and remediation guidance.
# Install (no API keys, no Python, no setup)
go install github.com/calbebop/batesian/cmd/batesian@latest
# Probe an A2A endpoint and map the attack surface
batesian probe --target https://agent.example.com --protocol a2a
# Full scan with SARIF output for GitHub Code Scanning
batesian scan --target https://agent.example.com --output sarif > results.sarif
# Run specific rules only
batesian scan --target https://agent.example.com --rule-ids a2a-push-ssrf-001,mcp-tool-poison-001
# Scan an authenticated MCP endpoint (static token)
batesian scan --target https://mcp.example.com --token "$TOKEN"
# Scan with automatic OAuth 2.0 client credentials token acquisition
batesian scan --target https://mcp.example.com \
--token-url https://auth.example.com/oauth/token \
--client-id my-client \
--client-secret "$CLIENT_SECRET" \
--oauth-scopes mcp:read,mcp:write
# Scan with OAuth 2.0 authorization code + PKCE (interactive; opens browser)
batesian scan --target https://mcp.example.com \
--auth-url https://auth.example.com/authorize \
--token-url https://auth.example.com/oauth/token \
--client-id my-client \
--oauth-scopes mcp:read
# Generate an annotated batesian.yaml config file
batesian initUse scan for SARIF (for example GitHub Code Scanning uploads). The probe command does not support --output sarif; it is for quick reconnaissance with table or JSON output only.
More options for scan (filters, config file, custom rules, OAuth, and more): run batesian scan --help.
Attack rules are YAML files. Anyone can write new attack patterns without touching Go. Rules load at runtime thus no recompilation needed. See CONTRIBUTING.md for the full authoring guide including the rule schema, validation checklist, and testing requirements.
from batesian import Scanner
scanner = Scanner(target="https://agent.example.com")
results = scanner.run(rules=["a2a-push-ssrf-001", "mcp-tool-poison-001"])
for finding in results.findings:
print(f"[{finding.severity}] {finding.rule_id}: {finding.title}")
assert results.critical_count == 0See sdk/python/ for installation, full API reference, and CI integration examples.
The rule engine and all 34 bundled rules are production-ready. New rules and protocol coverage are in active development. Star or watch to follow progress.
Contributions welcome, especially new attack rules. No engine knowledge required to write a rule.
See CONTRIBUTING.md. Contributions are accepted under the same Apache License 2.0 as the rest of the project.
For vulnerable Python test servers, ports, and how rules map to each server, see
testdata/README.md.
- A2A Protocol Specification
- MCP Authorization Specification
- MCP Security Best Practices
- Unit 42: Agent Session Smuggling in A2A Systems
- OWASP GenAI Security Project
Apache 2.0. See LICENSE.
