{
  "markdown": "# chirpstack-mcp-server\n\n<!-- mcp-name: io.github.oliveres/chirpstack-mcp-server -->\n\nAn [MCP](https://modelcontextprotocol.io) server for [ChirpStack](https://www.chirpstack.io) v4.\nIt lets an AI agent (Claude Code, Claude Desktop, or any MCP client) manage a LoRaWAN network\nand — the part that matters while you are building a device application — **debug devices live**:\nqueue a downlink, watch the uplinks and events as they arrive, iterate a payload codec, and\ninspect link quality, all from the coding session.\n\nThe server talks to ChirpStack's native gRPC API with a single API key. It carries no\ndevice- or vendor-specific logic.\n\n![Claude Code fixes a payload decoder and verifies it on the next live uplink](docs/demo.gif)\n\n*Real, unedited Claude Code session (2.5× speed, only the ChirpStack MCP tools): the agent reads the device profile's codec, spots the disconnected-probe sentinel in a raw uplink, deploys a fix with `profile_set_codec`, then waits for the device's next uplink with `wait_for_event` and confirms the decoded object.*\n\n## Install\n\n```bash\nuvx chirpstack-mcp-server        # run directly (needs uv: https://docs.astral.sh/uv/)\n# or\npip install chirpstack-mcp-server\n```\n\n## Configure\n\n| Variable | Required | Default | Meaning |\n|---|---|---|---|\n| `CHIRPSTACK_SERVER` | yes | — | `host:port` of the ChirpStack API (the web-UI port, usually `8080`) |\n| `CHIRPSTACK_API_KEY` | yes | — | API key from *ChirpStack → API keys* (tenant or global admin) |\n| `CHIRPSTACK_TOOLSETS` | no | `devices, debug, applications, profiles, gateways` | comma-separated toolsets, or `all` |\n| `CHIRPSTACK_TLS` | no | `false` | use TLS instead of plain HTTP/2 |\n| `CHIRPSTACK_TRANSPORT` | no | `stdio` | `stdio` or `streamable-http` |\n| `CHIRPSTACK_HTTP_PORT` | no | `8000` | port for `streamable-http` (bound to `127.0.0.1`) |\n\n### Claude Code\n\n```bash\nclaude mcp add chirpstack -e CHIRPSTACK_SERVER=192.168.1.10:8080 -e CHIRPSTACK_API_KEY=eyJ... -- uvx chirpstack-mcp-server\n```\n\n### Claude Desktop / generic MCP config\n\n```json\n{\n  \"mcpServers\": {\n    \"chirpstack\": {\n      \"command\": \"uvx\",\n      \"args\": [\"chirpstack-mcp-server\"],\n      \"env\": {\n        \"CHIRPSTACK_SERVER\": \"192.168.1.10:8080\",\n        \"CHIRPSTACK_API_KEY\": \"eyJ...\"\n      }\n    }\n  }\n}\n```\n\n## Toolsets\n\nTools are grouped so an agent only sees what it needs. Names are `<toolset>_<verb>`.\n\n| Toolset | Default | Tools |\n|---|---|---|\n| `devices` | yes | list, get, create, update, delete, set_keys, activate, deactivate, flush_dev_nonces, enqueue, queue_get, queue_flush, metrics |\n| `debug` | yes | `server_info`, `capture_start`, `capture_read`, `capture_stop`, `capture_list`, `wait_for_event`, `device_recent_events` |\n| `applications` | yes | list, get, create, update, delete, list_device_tags |\n| `profiles` | yes | list, get, create, update, delete, `profile_set_codec`, list_vendors, list_adr_algorithms |\n| `gateways` | yes | list, get, create, update, delete, metrics |\n| `multicast` | no | group CRUD, add/remove device, enqueue, queue_list, queue_flush |\n| `fuota` | no | deployment CRUD, start, add/remove/list devices, list_jobs |\n| `integrations` | no | `integration_list/get/set/delete` — one generic set for all ten ChirpStack integration kinds; `integration_get` redacts stored credentials unless `include_secrets=true` |\n| `tenants` | no | tenant CRUD, tenant users, API keys |\n| `relay` | no | relay devices and relay gateways |\n\nEnable more with `CHIRPSTACK_TOOLSETS=devices,debug,profiles,multicast` or `CHIRPSTACK_TOOLSETS=all`.\n`server_info` is the first call an agent should make to check the connection and the API key;\nits `chirpstack_version`/`regions` fields may come back null/empty since ChirpStack only serves\nthose to a logged-in user session, never to an API key.\n\n## Live debugging\n\nChirpStack keeps the last ~10 events per device and streams new ones. The `debug` toolset\nturns that into something an agent can use between tool calls:\n\n1. `capture_start(target, kind)` opens a background stream (`events` or `frames` for a device,\n   `gateway_frames` for a gateway) into a 500-item ring buffer and returns a `session_id`.\n2. `device_enqueue(dev_eui, f_port, data_hex=...)` queues the downlink.\n3. `capture_read(session_id, since_seq)` returns everything that arrived since the last read —\n   decoded uplinks (`f_port`, `f_cnt`, `data_hex`, codec `object`, per-gateway `rssi`/`snr`),\n   `ack`/`txack` for the downlink, `log` entries when something went wrong.\n4. `capture_stop(session_id)` when done. Idle sessions expire after 30 minutes.\n\nFor quick looks: `wait_for_event(dev_eui, timeout_s)` blocks up to 60 s for the next live event —\nit only returns events newer than the moment it was called, never the history ChirpStack replays;\n`device_recent_events(dev_eui)` returns that history without keeping a session.\n\nClass A devices only receive a downlink after their next uplink; Class C devices get it right away.\n\n## Security notes\n\n- The API key is read from the environment and never appears in tool output. `device_get`\n  hides root keys unless asked with `include_keys=true`.\n- `device_get`/`multicast_get` hide session keys unless `include_keys=true`.\n- `integration_get` redacts stored credentials unless `include_secrets=true`.\n- `<redacted>` is reserved: `integration_set`/`multicast_update` keep the stored value\n  wherever it appears (so an edited `_get` result can be handed straight back), and\n  `integration_set`/`multicast_create` refuse it when there is nothing to keep.\n- Plain HTTP/2 (h2c) is the default because ChirpStack's API port is plain by default. Plain\n  h2c sends the API key as a cleartext bearer token on the wire; use it only on a trusted LAN,\n  and set `CHIRPSTACK_TLS=true` (behind a TLS-terminating proxy that speaks gRPC) or a VPN\n  elsewhere.\n- `streamable-http` has no authentication of its own and binds to `127.0.0.1`. Do not expose it\n  on a public interface.\n- The HTTP transport validates `Host`/`Origin` headers (DNS-rebinding protection), so a web page\n  in the operator's browser cannot open an MCP session against the loopback listener.\n- Destructive tools are annotated (`destructiveHint`) so MCP clients can ask before running them.\n- Enabling the `tenants` toolset lets the agent mint API keys; `api_key_create` returns the new\n  token once, in its result.\n\n## Development\n\n```bash\nuv sync\nuv run pytest                     # unit tests\nuv run ruff check . && uv run pyright\ntests/integration/up.sh           # throwaway ChirpStack in Docker + API key\nset -a; . .integration/env; set +a\nuv run pytest -m integration\ntests/integration/down.sh\n```\n\nDesign notes live in `docs/design.md`.\n\n## License\n\nMIT © Oldřich Švéda\n",
  "bytes": 6693,
  "sha": "6dd670942c1ca90be4d46d43ca7569fe1866e24551a07b2568d699005fd0ff06",
  "repo_slug": "oliveres/chirpstack-mcp-server",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_oliveres_chirpstack_mcp_server_3dff7011/readme"
}