About Netbird MCP
Netbird MCP is an MCP server published by netbirdio in the Other category.
The repository has 6 stars and 6 forks, with the last commit 3 months ago. Recent commit activity is the strongest signal that reported issues will get attention.
Install
git clone https://github.com/netbirdio/netbird-mcpThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about Netbird MCP
Powered by Claude · Grounded in docs
Security checks
Static checks derived from the repository 2 days ago. Heuristics on the source, not an audit.
- ✓README presentThe repository ships documentation.
- !License declaredNo license file. Legally you have no right to use it in a product.
- ✓Tests presentA test suite exists in the repository.
- ✓Dependencies pinnedA lockfile pins dependency versions.
- ✓No dynamic code executionSource scan found no eval, dynamic Function, or shell execution.
1 check has not been run yet.
README
NetBird MCP Server
An MCP server for NetBird that lets you manage your network — peers, setup keys, groups, policies, networks and DNS — from Claude in natural language, instead of the dashboard or raw REST calls.
One codebase, two ways to run:
- Local (stdio) — runs as a subprocess of Claude Desktop / Claude Code. Credentials from env.
- Cloud (Streamable HTTP) — hosted and added to Claude as a remote/custom connector. Stateless and multi-tenant; each request carries its own NetBird token.
Everything below the entrypoint (tools, API client) is shared, so both modes expose the
identical tool set. See PLAN.md for the full design and roadmap.
Install & build
npm install
npm run build
npm test # unit tests (mocked NetBird API)
Getting a NetBird token
Create a service user in the NetBird dashboard and issue a Personal Access Token (PAT)
for it (NetBird's recommendation for org-wide API flows). The server sends it as
Authorization: Token <PAT> on every call.
Run locally (stdio)
Claude Desktop — add to claude_desktop_config.json:
{
"mcpServers": {
"netbird": {
"command": "npx",
"args": ["-y", "@netbird/mcp"],
"env": {
"NETBIRD_API_TOKEN": "nb_pat_xxx",
"NETBIRD_API_URL": "https://api.netbird.io"
}
}
}
}
Claude Code:
claude mcp add netbird -e NETBIRD_API_TOKEN=nb_pat_xxx -- npx -y @netbird/mcp
Local dev / debugging with the MCP Inspector:
cp .env.example .env # fill in NETBIRD_API_TOKEN
npm run inspect
Run in the cloud (Streamable HTTP)
docker build -t netbird-mcp .
docker run -p 3000:3000 netbird-mcp
Set PUBLIC_BASE_URL to the externally reachable HTTPS origin (used in the OAuth metadata):
docker run -p 3000:3000 -e PUBLIC_BASE_URL=https://netbird-mcp.example.com netbird-mcp
The server exposes:
POST /mcp— the MCP endpoint (stateless)GET /healthz— health check- OAuth 2.1 endpoints (see below):
/.well-known/oauth-authorization-server,/.well-known/oauth-protected-resource/mcp,/authorize,/token,/register,/revoke
Connect it to your Claude account (OAuth)
Add it in Claude as a remote / custom connector pointing at https://<your-host>/mcp.
Claude then runs a standard OAuth 2.1 flow — it registers itself dynamically, and you'll be
sent to a "Connect NetBird" login page where you paste your NetBird PAT once. Claude
receives an OAuth access token bound to that PAT server-side; the PAT itself never goes to
Claude. This is the recommended path.
The flow implemented: OAuth 2.0 Protected Resource + Authorization Server metadata discovery
(RFC 9728 / 8414), Dynamic Client Registration (RFC 7591), authorization-code grant with
PKCE (S256), and refresh tokens. An unauthenticated POST /mcp returns 401 with a
WWW-Authenticate: Bearer resource_metadata="…" header so Claude can discover the endpoints.
The prototype keeps OAuth token→PAT bindings in memory. For production, back them with a shared, encrypted store (e.g. Redis) so tokens survive restarts and work across replicas.
Behind a reverse proxy or load balancer, set
NETBIRD_TRUST_PROXY(see Configuration) so the per-IP rate limits — the OAuth routes, the/oauth/netbird-loginform, and per-source login PAT verification — key on the real client IP rather than the proxy's. Left unset behind a proxy, every client collapses into one bucket, which throttles everyone instead of isolating abusers.
Direct-PAT alternative (testing / simple deploys)
Instead of OAuth you can pass the NetBird PAT directly per request via the x-netbird-token
header (configurable with NETBIRD_TOKEN_HEADER) or Authorization: Token <pat>. The token is
used only for the life of the request and never persisted, so one deployment still serves many
tenants. Authorization: Bearer is reserved for OAuth.
This path is off by default whenever OAuth is enabled — turn it on explicitly with
NETBIRD_ENABLE_DIRECT_PAT=true (it is on automatically when OAuth is disabled, since it is then
the only way to authenticate). When it is on, each request's base URL must be on the host
allowlist — the configured NETBIRD_API_URL host plus anything in NETBIRD_ALLOWED_API_HOSTS —
and the presented PAT is verified against NetBird before any tool runs, so the server can't be
steered at an arbitrary host or driven with an unverified token.
Configuration
| Variable | Mode | Default | Purpose |
|---|---|---|---|
NETBIRD_API_TOKEN |
local | — | NetBird PAT (required for stdio) |
NETBIRD_API_URL |
both | https://api.netbird.io |
API base URL; set for self-hosted |
NETBIRD_ALLOWED_API_HOSTS |
both | (the NETBIRD_API_URL host) |
Extra hosts a request-supplied base URL may target, comma-separated |
NETBIRD_ENABLE_DESTRUCTIVE |
both | false |
Enable delete_* tools |
NETBIRD_MAX_RPM |
both | 110 |
Client-side rate cap (under NetBird's 120/min) |
NETBIRD_TIMEOUT_MS |
both | 30000 |
Per-request timeout |
LOG_LEVEL |
both | info |
debug | info | warn | error |
PORT |
cloud | 3000 |
HTTP listen port |
PUBLIC_BASE_URL |
cloud | http://localhost:PORT |
Public HTTPS origin advertised in OAuth metadata |
NETBIRD_ENABLE_OAUTH |
cloud | true |
Enable the OAuth 2.1 authorization server |
NETBIRD_ENABLE_DIRECT_PAT |
cloud | off when OAuth on | Allow the direct-PAT header path (auto-on when OAuth is off) |
NETBIRD_VERIFY_PAT_ON_LOGIN |
cloud | true |
Live-check the PAT during OAuth login |
NETBIRD_TRUST_PROXY |
cloud | false |
Express trust proxy for real client IPs behind a proxy: hop count (e.g. 1) or preset (loopback). Bare booleans are rejected — trusting every proxy allows IP spoofing |
NETBIRD_TOKEN_HEADER |
cloud | x-netbird-token |
Header carrying the caller's PAT (direct-PAT mode) |
NETBIRD_URL_HEADER |
cloud | x-netbird-api-url |
Optional per-tenant base URL header |
Boolean variables accept 1, true, yes, or on (case-insensitive) as true; any other
value — including a typo — is treated as false, so a misspelled flag fails closed rather
than silently enabling something.
Tools (v1)
Read tools are always on. Writes use a draft-and-confirm flow: call once to preview the
exact request, then again with confirm: true to apply. Deletes are off by default — set
NETBIRD_ENABLE_DESTRUCTIVE=true to enable them, and they require the exact resource id.
| Group | Tools |
|---|---|
| Peers | list_peers, get_peer, list_accessible_peers, update_peer, delete_peer* |
| Setup keys | list_setup_keys, create_setup_key, update_setup_key |
| Groups | list_groups, create_group, update_group, delete_group* |
| Policies | list_policies, get_policy, create_policy, update_policy, delete_policy* |
| Networks | list_networks, get_network |
| DNS | list_nameserver_groups, get_dns_settings |
| Visibility | list_posture_checks, list_events |
* destructive — gated behind NETBIRD_ENABLE_DESTRUCTIVE.
Out of scope for v1: Users/Accounts admin, Tokens, MSP, Invoice/Usage, and cloud-only IDP/EDR integration configs. DNS writes and posture-check authoring are v2. (OAuth is implemented — see "Connect it to your Claude account" above. Binding it to an upstream IdP login instead of a PAT is the remaining v2 auth step.)
Safety
- Client-side rate limiting under NetBird Cloud's 120 req/min, with exponential backoff
honoring
Retry-Afteron 429/5xx. - Writes preview before applying; deletes are opt-in and require an exact id (never a batch).
- Tokens are never written to logs.
README fetched from the repository 2 days ago. The original is authoritative.