The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the ChirpStack listing page.
An MCP server for ChirpStack v4. It lets an AI agent (Claude Code, Claude Desktop, or any MCP client) manage a LoRaWAN network and — the part that matters while you are building a device application — debug devices live: queue a downlink, watch the uplinks and events as they arrive, iterate a payload codec, and inspect link quality, all from the coding session.
The server talks to ChirpStack's native gRPC API with a single API key. It carries no device- or vendor-specific logic.

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.
| Variable | Required | Default | Meaning |
|---|---|---|---|
CHIRPSTACK_SERVER | yes | — | host:port of the ChirpStack API (the web-UI port, usually 8080) |
CHIRPSTACK_API_KEY | yes | — | API key from ChirpStack → API keys (tenant or global admin) |
CHIRPSTACK_TOOLSETS | no | devices, debug, applications, profiles, gateways | comma-separated toolsets, or all |
CHIRPSTACK_TLS | no | false | use TLS instead of plain HTTP/2 |
CHIRPSTACK_TRANSPORT | no | stdio | stdio or streamable-http |
CHIRPSTACK_HTTP_PORT | no | 8000 | port for streamable-http (bound to 127.0.0.1) |
Tools are grouped so an agent only sees what it needs. Names are <toolset>_<verb>.
| Toolset | Default | Tools |
|---|---|---|
devices | yes | list, get, create, update, delete, set_keys, activate, deactivate, flush_dev_nonces, enqueue, queue_get, queue_flush, metrics |
debug | yes | server_info, capture_start, capture_read, capture_stop, capture_list, wait_for_event, device_recent_events |
applications | yes | list, get, create, update, delete, list_device_tags |
profiles | yes | list, get, create, update, delete, profile_set_codec, list_vendors, list_adr_algorithms |
gateways | yes | list, get, create, update, delete, metrics |
multicast | no | group CRUD, add/remove device, enqueue, queue_list, queue_flush |
fuota | no | deployment CRUD, start, add/remove/list devices, list_jobs |
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 |
tenants | no | tenant CRUD, tenant users, API keys |
relay | no | relay devices and relay gateways |
Enable more with CHIRPSTACK_TOOLSETS=devices,debug,profiles,multicast or CHIRPSTACK_TOOLSETS=all.
server_info is the first call an agent should make to check the connection and the API key;
its chirpstack_version/regions fields may come back null/empty since ChirpStack only serves
those to a logged-in user session, never to an API key.
ChirpStack keeps the last ~10 events per device and streams new ones. The debug toolset
turns that into something an agent can use between tool calls:
capture_start(target, kind) opens a background stream (events or frames for a device,
gateway_frames for a gateway) into a 500-item ring buffer and returns a session_id.device_enqueue(dev_eui, f_port, data_hex=...) queues the downlink.capture_read(session_id, since_seq) returns everything that arrived since the last read —
decoded uplinks (f_port, f_cnt, data_hex, codec object, per-gateway rssi/snr),
ack/txack for the downlink, log entries when something went wrong.capture_stop(session_id) when done. Idle sessions expire after 30 minutes.For quick looks: wait_for_event(dev_eui, timeout_s) blocks up to 60 s for the next live event —
it only returns events newer than the moment it was called, never the history ChirpStack replays;
device_recent_events(dev_eui) returns that history without keeping a session.
Class A devices only receive a downlink after their next uplink; Class C devices get it right away.
device_get
hides root keys unless asked with include_keys=true.device_get/multicast_get hide session keys unless include_keys=true.integration_get redacts stored credentials unless include_secrets=true.<redacted> is reserved: integration_set/multicast_update keep the stored value
wherever it appears (so an edited _get result can be handed straight back), and
integration_set/multicast_create refuse it when there is nothing to keep.CHIRPSTACK_TLS=true (behind a TLS-terminating proxy that speaks gRPC) or a VPN
elsewhere.streamable-http has no authentication of its own and binds to 127.0.0.1. Do not expose it
on a public interface.Host/Origin headers (DNS-rebinding protection), so a web page
in the operator's browser cannot open an MCP session against the loopback listener.destructiveHint) so MCP clients can ask before running them.tenants toolset lets the agent mint API keys; api_key_create returns the new
token once, in its result.Design notes live in docs/design.md.
MIT © Oldřich Švéda