# birdnet-go-mcp
A high-performance Model Context Protocol (MCP) server & CLI for BirdNET-Go bioacoustic observatories.
Connect Claude, Antigravity, OpenClaw, and local LLMs to your backyard bird monitoring station.
---
## Highlights
- **Native BirdNET-Go Support**: Interfaces directly with BirdNET-Go's v2 REST API over LAN or localhost. No raw database locking or unmaintained Python dependencies.
- **Instant `npx` Run**: Launch immediately with `npx -y birdnet-go-mcp` — zero Go toolchain required.
- **Zero-Dependency Static Binary**: Single Go binary (`CGO_ENABLED=0`) compiled for Linux, macOS, and Windows.
- **Dual-Mode (CLI + MCP)**: Human-friendly CLI for quick terminal health checks (`birdnet-mcp status`), plus full stdio & SSE MCP server for AI agents.
- **Context-Protected (8KB Envelope)**: Hard-capped output preventing multi-hundred detection queries from overflowing model context windows.
- **Read-Only & Parallel-Safe**: Omits all mutating/destructive endpoints. Annotates all tools with `readOnlyHint` and `idempotentHint` for fast parallel agent calls.
- **Audio & Clip Access**: Resolves LAN Caddy/Nginx `.wav` clip URLs, with built-in base64 audio streaming for multimodal models.
---
## Quick Start
### 1. Instant Run via NPX (Recommended for Claude Desktop & Node users)
No Go installation needed. Downloads the native binary for your platform automatically:
```bash
# Check station health in your terminal
npx -y birdnet-go-mcp status
# Or set target host
BIRDNET_BASE_URL="http://192.0.2.10:8080" npx -y birdnet-go-mcp recent
```
### 2. Install via Go
```bash
go install github.com/zax0rz/birdnet-go-mcp/cmd/birdnet-mcp@latest
```
### 3. Pre-Compiled Binaries
Download the latest static binary for your architecture from [GitHub Releases](https://github.com/zax0rz/birdnet-go-mcp/releases):
- `darwin-arm64` (Apple Silicon M1/M2/M3/M4)
- `darwin-amd64` (Intel Mac)
- `linux-amd64` (x86_64 servers, Proxmox LXC, Docker)
- `linux-arm64` (Raspberry Pi 4 / 5)
- `linux-armv7` (Raspberry Pi 2 / 3 / Zero 2 W)
- `windows-amd64`
---
## Client & Harness Setup
### Claude Desktop & Cursor
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS), `%APPDATA%\Claude\claude_desktop_config.json` (Windows), or add under Cursor Settings ➔ Features ➔ MCP:
#### Option A: Using `npx` (Easiest)
```json
{
"mcpServers": {
"birdnet": {
"command": "npx",
"args": ["-y", "birdnet-go-mcp", "serve"],
"env": {
"BIRDNET_BASE_URL": "http://192.0.2.10:8080",
"CLIPS_BASE_URL": "http://192.0.2.10:8091"
}
}
}
}
```
#### Option B: Using Native Binary
```json
{
"mcpServers": {
"birdnet": {
"command": "/usr/local/bin/birdnet-mcp",
"args": ["serve"],
"env": {
"BIRDNET_BASE_URL": "http://192.0.2.10:8080",
"CLIPS_BASE_URL": "http://192.0.2.10:8091"
}
}
}
}
```
---
### Claude Code
Add directly via CLI:
```bash
claude mcp add birdnet -- npx -y birdnet-go-mcp serve
```
---
### Google Antigravity
In your Antigravity MCP configuration (`~/.gemini/antigravity/mcp/` or project settings):
```json
{
"mcpServers": {
"birdnet": {
"command": "birdnet-mcp",
"args": ["serve"],
"env": {
"BIRDNET_BASE_URL": "http://192.0.2.10:8080",
"CLIPS_BASE_URL": "http://192.0.2.10:8091"
}
}
}
}
```
---
### OpenClaw
In `~/.openclaw/openclaw.json`:
```json
{
"mcp": {
"servers": {
"birdnet": {
"command": "/Users/zach/.openclaw/mcp-servers/birdnet-go-mcp/bin/birdnet-mcp",
"args": [],
"env": {
"BIRDNET_BASE_URL": "http://192.0.2.10:8080",
"CLIPS_BASE_URL": "http://192.0.2.10:8091"
},
"toolFilter": {
"include": ["*"]
}
}
}
}
}
```
In your agent's `tools.allow` list:
```json
"tools": {
"allow": [
"birdnet__get_recent_detections",
"birdnet__search_detections",
"birdnet__get_detection_detail",
"birdnet__get_today_summary",
"birdnet__get_new_arrivals",
"birdnet__get_station_health",
"birdnet__get_audio_clip",
"birdnet__get_audio_clip_base64"
]
}
```
---
### Remote / Headless Agents (SSE HTTP Mode)
If your agent runs on another machine or in the cloud without access to local stdio:
```bash
# Start background SSE server on port 8092
birdnet-mcp serve --sse --port 8092
```
Point your agent to:
`http://:8092/sse`
---
## Interactive CLI Commands
`birdnet-mcp` is a full CLI tool for humans as well as an MCP server for agents.
### Check Station & RTSP Mic Health
```bash
$ birdnet-mcp status
🔍 Connecting to BirdNET-Go at http://192.0.2.10:8080...
=== AUDIO STREAMS ===
NAME TYPE HEALTH STATE THROUGHPUT LAST RECEIVED
birdz0rz-pi rtsp 🟢 HEALTHY running 74.8 KB/s 2026-09-04T20:38:53-04:00
=== DETECTOR HOST ===
Host: birdz0rz (Debian Linux, x86_64)
CPU: AMD Ryzen 5 PRO 2400G (2 cores)
Uptime: 15d 3h 6m (Host) | 6d 4h 47m (BirdNET-Go)
Kernel: 7.0.14-12-pve
Environment: LXC
```
### View Recent Sightings
```bash
$ birdnet-mcp recent --limit 5 --min-conf 0.80
ID TIME SPECIES COMMON NAME CONF NEW? CLIP URL
#129 2026-09-04 19:59:35 easblu Eastern Bluebird 84% - http://192.0.2.10:8091/2026/09/sialia_sialis_84p_20260904T195937Z.wav
#128 2026-09-04 19:58:17 easblu Eastern Bluebird 95% - http://192.0.2.10:8091/2026/09/sialia_sialis_95p_20260904T195819Z.wav
#127 2026-09-04 19:05:23 blujay Blue Jay 84% - http://192.0.2.10:8091/2026/09/cyanocitta_cristata_84p_20260904T190525Z.wav
#126 2026-09-04 18:46:16 carwre Carolina Wren 96% - http://192.0.2.10:8091/2026/09/thryothorus_ludovicianus_96p_20260904T184618Z.wav
#124 2026-09-04 18:35:34 houfin House Finch 90% - http://192.0.2.10:8091/2026/09/haemorhous_mexicanus_90p_20260904T183536Z.wav
```
### Download Audio Recording
```bash
$ birdnet-mcp clip sialia_sialis_95p_20260904T195819Z.wav --download --out bluebird.wav
✅ Saved 1440044 bytes to bluebird.wav
```
---
## MCP Tool Reference
| Tool | Parameters | Description |
| :--- | :--- | :--- |
| `get_recent_detections` | `limit` (int, 1-25)
`min_confidence` (0.0-1.0)
`species_code` (string) | Fetches the most recent bird acoustic detections with confidence scores, timestamps, and audio clip URLs. |
| `search_detections` | `date` (YYYY-MM-DD)
`species` (name/code)
`min_confidence` (0.0-1.0)
`limit` (int) | Historical search through detection records stored in SQLite. |
| `get_detection_detail` | `id` (int, required) | Inspects a single detection: weather conditions at detection time, confidence breakdown, and audio clip info. |
| `get_today_summary` | *(none)* | Aggregate summary of today's observatory run: total count, species diversity, and top visitors. |
| `get_new_arrivals` | *(none)* | Identifies species heard for the first time ever or new this season/year (vital for tracking migration). |
| `get_station_health` | *(none)* | Real-time diagnostic telemetry: RTSP mic stream state, ingest bit rate, dropped packets, and host uptime. |
| `get_audio_clip` | `clip_name` (string)
`detection_date` (string) | Resolves the accessible LAN URL on Caddy/Nginx (:8091) for Discord/web embedding. |
| `get_audio_clip_base64` | `clip_name` (string)
`detection_date` (string) | Downloads and base64-encodes the raw `.wav` audio clip for multimodal models with direct audio input capabilities.
⚠️ *Token budget warning: A 15-second WAV clip is ~1.4–1.9MB base64 (~350,000–500,000 tokens into Gemini/Claude multimodal models). Use selectively for verification; never put this in automated high-frequency briefing crons!* |
### MCP Resources
- `birdnet://station/health` — Live JSON snapshot of the Pi mic stream and BirdNET-Go engine.
- `birdnet://detections/recent` — The 10 most recent detections.
- `birdnet://species/summary` — Aggregated species occurrence summary.
### MCP Prompts
- `daily_backyard_brief` — Morning dispatch workflow template for resident bird agents.
- `investigate_detection` — Deep-dive template for evaluating anomalous sightings against eBird.
---
## Configuration Reference
| Environment Variable | CLI Flag | Default | Description |
| :--- | :--- | :--- | :--- |
| `BIRDNET_BASE_URL` | `--birdnet-url` | `http://localhost:8080` | BirdNET-Go v2 REST API base URL |
| `CLIPS_BASE_URL` | `--clips-url` | `http://localhost:8091` | Base URL for audio clips file server |
| `BIRDNET_USERNAME` | `--user` | *(empty)* | Optional HTTP Basic Auth username |
| `BIRDNET_PASSWORD` | `--pass` | *(empty)* | Optional HTTP Basic Auth password |
| `BIRDNET_AUTH_TOKEN`| `--token` | *(empty)* | Optional Bearer authorization token |
| `REQUEST_TIMEOUT_SECONDS` | *(none)* | `5` | HTTP client timeout in seconds |
---
## Field-Tested in Production: The Origin Story & Hardening
`birdnet-go-mcp` wasn't built in a theoretical vacuum — it was forged and verified against a live backyard bioacoustic observatory:
- **Mic Station**: Raspberry Pi Zero 2 W mounted outdoors with a weather-sealed electret microphone streaming 48kHz mono audio via RTSP (`mediamtx`) at ~75 KB/s over Wi-Fi.
- **Detector Host**: [BirdNET-Go](https://github.com/tphakala/birdnet-go) running inside a Debian 12 Proxmox LXC container (`amd64`, AMD Ryzen 5 PRO), analyzing audio chunks with the Cornell Lab of Ornithology neural network.
- **Clip Web Server**: Caddy reverse proxy serving `/var/lib/birdnet-go/clips/` over HTTP on port 8091.
- **Agent Mesh**: [OpenClaw](https://github.com/openclaw/openclaw) on an Apple Silicon Mac Mini running autonomous resident agents:
- **Blenda** (Infra agent, GLM-5.3): Monitors server health, manages gateway restarts, and oversees tool permissions.
- **Leopold** (Resident Naturalist, Gemini 3.8 Flash): Composes daily backyard wildlife briefings, flags unusual species (Eastern Bluebirds, Carolina Wrens, Pileated Woodpeckers), and inspects audio spectrograms.
### Real-World Lessons & "Incident Zero"
1. **The Caddy Directory Permission Trap (Incident Zero)**:
BirdNET-Go creates monthly clip directories (`/clips/YYYY/MM/`) with `750` permissions (`drwxr-x---`). External web servers (Caddy, Nginx) running as their own system user will hit **HTTP 403 Forbidden** when serving audio clips to agents or Discord webhooks.
*Fix*: Set permissions to `755` on existing month folders and add your web server user to the `birdnet` group:
```bash
sudo chmod -R 755 /var/lib/birdnet-go/clips
sudo usermod -aG birdnet caddy
```
2. **Apple Silicon AMFI & Cross-Compilation**:
When cross-compiling Go binaries from Linux for macOS (`GOOS=darwin GOARCH=arm64`) with stripped debug symbols (`-ldflags="-s -w"`), macOS Apple Mobile File Integrity (AMFI) will immediately terminate the process with `SIGKILL` (exit code 137). All Darwin ARM64 releases are properly ad-hoc codesigned (`codesign -s - --force`).
3. **Context Window Token Budget Guard**:
Feeding raw base64 WAV recordings into multimodal LLMs is magical for verifying difficult bird calls, but a single 15-second WAV consumes **~1.9MB (approx. 500,000 tokens)**. That can consume 50% of a 1M-token context window in one tool invocation.
`birdnet-go-mcp` strictly caps all structured JSON tool responses at an **8KB envelope cap**, while keeping `get_audio_clip_base64` explicitly exempt so models can call it intentionally without risk of accidental context blowup in daily briefing routines.
---
## Contributing & Development
```bash
# Clone
git clone https://github.com/zax0rz/birdnet-go-mcp.git
cd birdnet-go-mcp
# Run unit tests
make test
# Build for local OS
make build
# Cross-compile for Darwin ARM64 (Apple Silicon)
make build-mac
```
---
## Credits & License
- Built with [`mark3labs/mcp-go`](https://github.com/mark3labs/mcp-go).
- Designed for [`tphakala/birdnet-go`](https://github.com/tphakala/birdnet-go).
- Bird identification neural network developed by the **Cornell Lab of Ornithology** and **Chemnitz University of Technology**.
- Licensed under the [MIT License](LICENSE).