Upload firmware images, unpack them, explore the filesystem, analyze binaries, and conduct security assessments β all powered by AI analysis via Model Context Protocol (MCP).
Connect any MCP-compatible AI agent to Wairz's 60+ analysis tools β Claude Code, Claude Desktop, OpenCode, Codex, Cursor, VS Code + Copilot, Gemini CLI, Windsurf, and more.
- Firmware Unpacking β Automatic extraction of SquashFS, JFFS2, UBIFS, CramFS, ext, and CPIO filesystems via binwalk, with multi-partition support
- File Explorer β Browse extracted filesystems with a virtual tree, view text/binary/hex content, and search across files
- Binary Analysis β Disassemble and decompile binaries using radare2 and Ghidra headless, with cross-reference and taint analysis
- Component Map β Interactive dependency graph showing binaries, libraries, scripts, and their relationships
- Security Assessment β Detect hardcoded credentials, crypto material, setuid binaries, insecure configs, and weak permissions
- SBOM & CVE Scanning β Generate Software Bill of Materials (CycloneDX) and scan components against the NVD for known vulnerabilities
- Firmware Emulation β Boot firmware in QEMU (user-mode for single binaries, system-mode for full OS) in isolated containers, with GDB support
- Fuzzing β AFL++ with QEMU mode for cross-architecture binary fuzzing, with automatic dictionary/corpus generation and crash triage
- Firmware Comparison β Diff filesystem trees, binaries, and decompiled functions across firmware versions
- Live Device UART β Connect to physical devices via a host-side serial bridge for interactive console access
- AI Analysis via MCP β 60+ analysis tools exposed to Claude for autonomous security research
- Findings & Reports β Record security findings with severity ratings and evidence, export as Markdown or PDF
Claude Code / Claude Desktop / OpenCode
β
β MCP (stdio)
βΌ
βββββββββββββββββββ ββββββββββββββββββββββββββββββββββββ
β wairz-mcp ββββββΆβ FastAPI Backend β
β (MCP server) β β β
β 60+ tools β β Services: firmware, analysis, β
β β β emulation, fuzzing, sbom, uart β
βββββββββββββββββββ β β
β Ghidra headless Β· QEMU Β· AFL++ β
ββββββββββββ¬ββββββββββββββββββββββββ
β
ββββββββββββββββ ββββββββββββββββΌβββββββββββββββ
β React SPA βββββΆβ PostgreSQL β Redis β
β (Frontend) β β β β
ββββββββββββββββ ββββββββββββββββ΄βββββββββββββββ
Optional:
wairz-uart-bridge.py (host) ββ TCP:9999 ββ Docker backend
WAIRZ is currently in public beta. You may encounter bugs or rough edges. If you run into any issues, please open an issue on GitHub or reach out at andrew@digitalandrew.io.
WAIRZ is currently designed for embedded Linux firmware samples. Support for RTOS and bare-metal firmware is planned for future releases.
git clone https://github.com/digitalandrew/wairz.git
cd wairz
cp .env.example .env
docker compose up --build- Frontend: http://localhost:3000
- API docs: http://localhost:8000/docs
# Start PostgreSQL and Redis
docker compose up -d postgres redis
# Backend
cd backend
uv sync
uv run alembic upgrade head
uv run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
# Frontend (separate terminal)
cd frontend
npm install
npm run devOr use the helper script:
./launch.shWairz uses MCP to give AI agents access to firmware analysis tools. After starting the backend, register the MCP server with your preferred client:
claude mcp add wairz -- docker exec -i wairz-backend-1 uv run wairz-mcp --project-id <PROJECT_ID>Add to your Claude Desktop config (~/.config/Claude/claude_desktop_config.json on Linux, ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"wairz": {
"command": "docker",
"args": [
"exec", "-i", "wairz-backend-1",
"uv", "run", "wairz-mcp",
"--project-id", "<PROJECT_ID>"
]
}
}
}Add to your opencode.json (project root or ~/.config/opencode/opencode.json):
{
"mcp": {
"wairz": {
"type": "local",
"command": ["docker", "exec", "-i", "wairz-backend-1", "uv", "run", "wairz-mcp", "--project-id", "<PROJECT_ID>"],
"timeout": 30000,
"enabled": true
}
}
}Note: The
timeoutmust be increased from the default 5000ms because Wairz registers 90+ tools.
Once connected, your AI agent can autonomously explore firmware, analyze binaries, run emulation, fuzz targets, and generate security findings. The MCP server supports dynamic project switching via the switch_project tool β no restart needed to change projects.
| Category | Tools |
|---|---|
| Project | get_project_info, switch_project, list_projects |
| Filesystem | list_directory, read_file, search_files, file_info, find_files_by_type, get_component_map, get_firmware_metadata, extract_bootloader_env |
| Strings | extract_strings, search_strings, find_crypto_material, find_hardcoded_credentials |
| Binary Analysis | list_functions, disassemble_function, decompile_function, list_imports, list_exports, xrefs_to, xrefs_from, get_binary_info, check_binary_protections, check_all_binary_protections, find_string_refs, resolve_import, find_callers, search_binary_content, get_stack_layout, get_global_layout, trace_dataflow, cross_binary_dataflow |
| Security | check_known_cves, analyze_config_security, check_setuid_binaries, analyze_init_scripts, check_filesystem_permissions, analyze_certificate |
| SBOM | generate_sbom, get_sbom_components, check_component_cves, run_vulnerability_scan |
| Emulation | start_emulation, run_command_in_emulation, stop_emulation, check_emulation_status, get_emulation_logs, enumerate_emulation_services, diagnose_emulation_environment, troubleshoot_emulation, get_crash_dump, run_gdb_command, save_emulation_preset, list_emulation_presets, start_emulation_from_preset |
| Fuzzing | analyze_fuzzing_target, generate_fuzzing_dictionary, generate_seed_corpus, generate_fuzzing_harness, start_fuzzing_campaign, check_fuzzing_status, stop_fuzzing_campaign, triage_fuzzing_crash |
| Comparison | list_firmware_versions, diff_firmware, diff_binary, diff_decompilation |
| UART | uart_connect, uart_send_command, uart_read, uart_send_break, uart_send_raw, uart_disconnect, uart_status, uart_get_transcript |
| Reporting | add_finding, list_findings, update_finding, read_project_instructions, list_project_documents, read_project_document |
| Code | save_code_cleanup |
For live device access via UART, run the bridge on the host machine (USB serial adapters can't easily pass through to Docker):
pip install pyserial
python3 scripts/wairz-uart-bridge.py --bind 0.0.0.0 --port 9999The bridge is a TCP server β the serial device path and baud rate are specified via the uart_connect MCP tool, not on the command line.
On Linux, allow Docker traffic to reach the bridge and ensure .env is configured correctly:
sudo iptables -I INPUT -p tcp --dport 9999 -j ACCEPTUART_BRIDGE_HOST in .env must be host.docker.internal (not localhost). Restart the backend after changing .env: docker compose restart backend.
See UART Console docs for full setup details.
| Layer | Technology |
|---|---|
| Frontend | React 19, Vite, TypeScript, Tailwind CSS, shadcn/ui |
| Code Viewer | Monaco Editor |
| Component Graph | ReactFlow + Dagre |
| Terminal | xterm.js |
| State Management | Zustand |
| Backend | Python 3.12, FastAPI, SQLAlchemy 2.0 (async), Alembic |
| Database | PostgreSQL 16 |
| Cache | Redis 7 |
| Firmware Extraction | binwalk, sasquatch, jefferson, ubi_reader, cramfs-tools |
| Binary Analysis | radare2 (r2pipe), pyelftools |
| Decompilation | Ghidra 11.3.1 (headless) with custom analysis scripts |
| Emulation | QEMU user-mode + system-mode (ARM, MIPS, MIPSel, AArch64) |
| Fuzzing | AFL++ with QEMU mode |
| SBOM | CycloneDX, NVD API (nvdlib) |
| UART | pyserial (host-side bridge) |
| AI Integration | MCP (Model Context Protocol) |
| Containers | Docker + Docker Compose |
wairz/
βββ backend/
β βββ app/
β β βββ main.py # FastAPI application
β β βββ config.py # Settings (pydantic-settings)
β β βββ database.py # Async SQLAlchemy engine/session
β β βββ mcp_server.py # MCP server with dynamic project switching
β β βββ models/ # SQLAlchemy ORM models
β β βββ schemas/ # Pydantic request/response schemas
β β βββ routers/ # REST API endpoints
β β βββ services/ # Business logic
β β βββ ai/ # MCP tool registry + 60+ tool implementations
β β β βββ tools/ # Organized by category (filesystem, binary, security, etc.)
β β βββ utils/ # Path sandboxing, output truncation
β βββ alembic/ # Database migrations
β βββ pyproject.toml
βββ frontend/
β βββ src/
β β βββ pages/ # Route pages (explorer, emulation, fuzzing, SBOM, etc.)
β β βββ components/ # UI components (file tree, hex viewer, component map, etc.)
β β βββ api/ # API client functions
β β βββ stores/ # Zustand state management
β β βββ types/ # TypeScript type definitions
β βββ package.json
βββ ghidra/
β βββ Dockerfile # Ghidra headless container
β βββ scripts/ # Custom Java analysis scripts
βββ emulation/
β βββ Dockerfile # QEMU container (ARM, MIPS, MIPSel, AArch64)
β βββ scripts/ # Emulation helper scripts
βββ fuzzing/
β βββ Dockerfile # AFL++ container with QEMU mode
βββ scripts/
β βββ wairz-uart-bridge.py # Host-side UART serial bridge
βββ docker-compose.yml
βββ launch.sh # Local development launcher
βββ .env.example
βββ CLAUDE.md
All settings are configured via environment variables or .env file:
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
postgresql+asyncpg://wairz:wairz@postgres:5432/wairz |
PostgreSQL connection |
REDIS_URL |
redis://redis:6379/0 |
Redis connection |
STORAGE_ROOT |
/data/firmware |
Firmware storage directory |
MAX_UPLOAD_SIZE_MB |
500 |
Maximum firmware upload size |
MAX_TOOL_OUTPUT_KB |
30 |
MCP tool output truncation limit |
GHIDRA_PATH |
/opt/ghidra |
Ghidra installation path |
GHIDRA_TIMEOUT |
120 |
Ghidra decompilation timeout (seconds) |
FUZZING_IMAGE |
wairz-fuzzing |
Fuzzing container image name |
FUZZING_TIMEOUT_MINUTES |
120 |
Max fuzzing campaign duration |
FUZZING_MAX_CAMPAIGNS |
1 |
Max concurrent fuzzing campaigns |
UART_BRIDGE_HOST |
host.docker.internal |
UART bridge hostname |
UART_BRIDGE_PORT |
9999 |
UART bridge TCP port |
NVD_API_KEY |
(empty) | Optional NVD API key for higher rate limits |
LOG_LEVEL |
INFO |
Logging level |
Good firmware images for testing:
