Comprehensive MCP server for NetBird with full CRUD operations, policy management, and automation wo
3.7K
A comprehensive Model Context Protocol (MCP) server for NetBird providing full CRUD operations, policy management, and automation workflows.
Maintained by XNet Inc.
Lead Developer: Joshua S. Doucette
This MCP server provides complete management capabilities for NetBird networks, including:
Originally derived from the MCP Server for Grafana by Grafana Labs, this project has been substantially extended and enhanced.
Download pre-built binaries for your platform from the releases page.
# Download the .deb package for your architecture
wget https://github.com/XNet-NGO/mcp-netbird/releases/latest/download/mcp-netbird_VERSION_linux_x86_64.deb
sudo dpkg -i mcp-netbird_VERSION_linux_x86_64.deb
# Download and extract the tarball
wget https://github.com/XNet-NGO/mcp-netbird/releases/latest/download/mcp-netbird_VERSION_Linux_x86_64.tar.gz
tar -xzf mcp-netbird_VERSION_Linux_x86_64.tar.gz
sudo mv mcp-netbird /usr/local/bin/
# Intel Macs
wget https://github.com/XNet-NGO/mcp-netbird/releases/latest/download/mcp-netbird_VERSION_Darwin_x86_64.tar.gz
tar -xzf mcp-netbird_VERSION_Darwin_x86_64.tar.gz
sudo mv mcp-netbird /usr/local/bin/
# Apple Silicon Macs
wget https://github.com/XNet-NGO/mcp-netbird/releases/latest/download/mcp-netbird_VERSION_Darwin_arm64.tar.gz
tar -xzf mcp-netbird_VERSION_Darwin_arm64.tar.gz
sudo mv mcp-netbird /usr/local/bin/
Download the ZIP file from the releases page, extract it, and add the directory to your PATH.
git clone https://github.com/XNet-NGO/mcp-netbird
cd mcp-netbird && \
make install
go install github.com/XNet-NGO/mcp-netbird/cmd/mcp-netbird@latest
The NetBird MCP server supports three configuration methods with a clear priority order. This enables flexible deployment in various environments, including stateless containers.
The server accepts configuration through three methods (in priority order):
Pass configuration directly via CLI flags:
mcp-netbird --api-token "your-token" --api-host "api.netbird.io"
Available Flags:
--api-token: Your Netbird API token--api-host: The Netbird API host without protocol (e.g., api.netbird.io)--transport: Transport mode - stdio (default) or sse--sse-address: Address for SSE mode (default: :8001)Example - Stdio Mode:
mcp-netbird \
--api-token "nb_1234567890abcdef" \
--api-host "api.netbird.io"
Example - SSE Mode:
mcp-netbird \
--transport sse \
--sse-address :8001 \
--api-token "nb_1234567890abcdef" \
--api-host "api.netbird.io"
When running in SSE mode, you can pass configuration via HTTP headers with each request:
Available Headers:
X-Netbird-API-Token: Your Netbird API tokenX-Netbird-Host: The Netbird API host without protocolExample - Using curl:
curl -X POST http://localhost:8001/sse \
-H "X-Netbird-API-Token: nb_1234567890abcdef" \
-H "X-Netbird-Host: api.netbird.io" \
-H "Content-Type: application/json" \
-d '{"method": "tools/list"}'
Example - Docker MCP Toolkit:
{
"mcpServers": {
"netbird": {
"url": "http://localhost:8001/sse",
"headers": {
"X-Netbird-API-Token": "nb_1234567890abcdef",
"X-Netbird-Host": "api.netbird.io"
}
}
}
}
Note: HTTP headers are only used in SSE mode. In stdio mode, only CLI arguments and environment variables are available.
Set configuration via environment variables (traditional method):
export NETBIRD_API_TOKEN="nb_1234567890abcdef"
export NETBIRD_HOST="api.netbird.io"
mcp-netbird
Available Variables:
NETBIRD_API_TOKEN: Your Netbird API token (required)NETBIRD_HOST: The Netbird API host (default: api.netbird.io)Example - MCP Client Configuration:
{
"mcpServers": {
"netbird": {
"command": "mcp-netbird",
"args": [],
"env": {
"NETBIRD_API_TOKEN": "nb_1234567890abcdef",
"NETBIRD_HOST": "api.netbird.io"
}
}
}
}
When multiple configuration sources provide the same value, the priority order is:
CLI Arguments > HTTP Headers > Environment Variables
Example:
# Environment variable
export NETBIRD_API_TOKEN="token-from-env"
# CLI argument overrides environment variable
mcp-netbird --api-token "token-from-cli"
# Result: Uses "token-from-cli"
Example - SSE Mode with Multiple Sources:
# Environment variable
export NETBIRD_API_TOKEN="token-from-env"
# Start server with CLI argument
mcp-netbird --transport sse --api-token "token-from-cli"
# Make request with HTTP header
curl -H "X-Netbird-API-Token: token-from-header" http://localhost:8001/sse
# Result: Uses "token-from-cli" (CLI has highest priority)
The server validates all configuration values:
https://api.netbird.io → api.netbird.io)Invalid configurations will result in descriptive error messages:
Error: API token is required but not provided
Error: API token cannot be empty or whitespace-only
Error: API host cannot be empty or whitespace-only
Error: API host 'invalid host!' is not a valid URL format
1. Missing API Token
Error: API token is required but not provided
Solution: Provide the API token via one of the three methods:
# Option 1: CLI argument
mcp-netbird --api-token "your-token"
# Option 2: Environment variable
export NETBIRD_API_TOKEN="your-token"
mcp-netbird
# Option 3: HTTP header (SSE mode only)
curl -H "X-Netbird-API-Token: your-token" http://localhost:8001/sse
2. Empty or Whitespace-Only Values
Error: API token cannot be empty or whitespace-only
Solution: Ensure your token/host values are not empty strings or only whitespace:
# Bad
mcp-netbird --api-token " "
# Good
mcp-netbird --api-token "nb_1234567890abcdef"
3. Invalid API Host Format
Error: API host 'invalid host!' is not a valid URL format
Solution: Use a valid hostname without protocol:
# Bad
mcp-netbird --api-host "https://api.netbird.io"
mcp-netbird --api-host "invalid host!"
# Good
mcp-netbird --api-host "api.netbird.io"
mcp-netbird --api-host "api.yourdomain.com"
Note: If you include a protocol prefix (http:// or https://), it will be automatically stripped.
4. HTTP 401 Unauthorized (SSE Mode)
Error: HTTP 401 response when making SSE requests
Solution: Ensure API token is provided via CLI argument, HTTP header, or environment variable:
# Start server with token
mcp-netbird --transport sse --api-token "your-token"
# Or provide token in request header
curl -H "X-Netbird-API-Token: your-token" http://localhost:8001/sse
5. Configuration Not Taking Effect
Issue: Your configuration seems to be ignored
Solution: Check the priority order. CLI arguments override HTTP headers, which override environment variables:
# If you have an environment variable set
export NETBIRD_API_TOKEN="old-token"
# But pass a CLI argument
mcp-netbird --api-token "new-token"
# The CLI argument "new-token" will be used (higher priority)
6. Stdio Mode Not Reading HTTP Headers
Issue: HTTP headers are not being used in stdio mode
Solution: HTTP headers are only available in SSE mode. Use CLI arguments or environment variables for stdio mode:
# Stdio mode (default) - use CLI args or env vars
mcp-netbird --api-token "your-token"
# SSE mode - can use HTTP headers
mcp-netbird --transport sse --api-token "your-token"
For Docker MCP Toolkit or other stateless container environments, use HTTP headers:
# Dockerfile
FROM golang:1.21-alpine
WORKDIR /app
COPY . .
RUN go build -o mcp-netbird cmd/mcp-netbird/main.go
EXPOSE 8001
CMD ["./mcp-netbird", "--transport", "sse", "--sse-address", ":8001"]
# Run without environment variables
docker run -p 8001:8001 mcp-netbird-sse:v1
# Pass credentials via HTTP headers
curl -H "X-Netbird-API-Token: your-token" http://localhost:8001/sse
Use CLI arguments for quick testing without modifying environment:
# Test with different tokens quickly
mcp-netbird --api-token "test-token-1"
mcp-netbird --api-token "test-token-2"
# Test with self-hosted instance
mcp-netbird --api-token "your-token" --api-host "api.yourdomain.com"
Use environment variables for traditional deployments:
# Set once in your deployment configuration
export NETBIRD_API_TOKEN="production-token"
export NETBIRD_HOST="api.netbird.io"
# Start server
mcp-netbird --transport sse --sse-address :8001
Use HTTP headers to support multiple tenants with different credentials:
# Start server without credentials
mcp-netbird --transport sse
# Each tenant provides their own credentials
curl -H "X-Netbird-API-Token: tenant1-token" http://localhost:8001/sse
curl -H "X-Netbird-API-Token: tenant2-token" http://localhost:8001/sse
This server uses the Netbird API to provide LLMs information about Netbird network. Currently it's a 1:1 mapping of select read-only Netbird API resources to tools.
The MCP-NetBird server provides comprehensive CRUD operations for all NetBird resources:
| Category | Operations | Description |
|---|---|---|
| Peers | list, get, update, delete | Manage network peers |
| Groups | list, get, create, update, delete | Manage peer groups |
| Policies | list, get, create, update, delete | Manage access control policies |
| Networks | list, get, create, update, delete | Manage network configurations |
| Network Resources | list, get, create, update, delete | Manage network resources (subnets) |
| Network Routers | list, get, create, update, delete | Manage network routing peers |
| Nameservers | list, get, create, update, delete | Manage DNS nameserver groups |
| Routes | list, get, create, update, delete | Manage network routes (deprecated) |
| Setup Keys | list, get, create, update, delete | Manage peer setup keys |
| Users | list, get, invite, update, delete | Manage user accounts |
| Posture Checks | list, get, create, update, delete | Manage security posture checks |
| Port Allocations | list, get, create, update, delete | Manage ingress port allocations |
| Account | get, update | Manage account settings |
| Tool | Description |
|---|---|
list_policies_by_group | Find all policies that reference a specific group |
replace_group_in_policies | Replace one group with another across all policies |
get_policy_template | Get example policy structures with documentation |
To add new tools:
tools (e.g., tools/users.go), possibly use existing code as a templatefunc newServer() in cmd/main.goGet your Netbird API token from the Netbird management console.
Install the mcp-netbird binary using one of the installation methods above. Make sure the binary is in your PATH.
Configure the server using one of three methods:
Method 1: Environment Variables (Traditional)
Add the server configuration to your client configuration file. E.g., for Codeium Windsurf add the following to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"netbird": {
"command": "mcp-netbird",
"args": [],
"env": {
"NETBIRD_API_TOKEN": "<your-api-token>",
"NETBIRD_HOST": "api.netbird.io"
}
}
}
}
Method 2: Command-Line Arguments
Pass configuration directly via CLI flags:
{
"mcpServers": {
"netbird": {
"command": "mcp-netbird",
"args": [
"--api-token", "<your-api-token>",
"--api-host", "api.netbird.io"
]
}
}
}
Method 3: HTTP Headers (SSE Mode Only)
For Docker MCP Toolkit or other SSE-based clients:
{
"mcpServers": {
"netbird": {
"url": "http://localhost:8001/sse",
"headers": {
"X-Netbird-API-Token": "<your-api-token>",
"X-Netbird-Host": "api.netbird.io"
}
}
}
}
Note: NETBIRD_HOST (or --api-host or X-Netbird-Host) defaults to api.netbird.io if not specified. For self-hosted instances, set it to your NetBird API host (e.g., api.yourdomain.com).
For more information on how to add a similar configuration to Claude Desktop, see here.
Note: if you see something along the lines of
[netbird] [error] spawn mcp-netbird ENOENTin Claude Desktop logs, you need to specify the full path tomcp-netbird. On macOS Claude Logs are in~/Library/Logs/Claude.
Try asking questions along the lines of "Can you explain my Netbird peers, groups and policies to me?"
When creating or updating policies, rules must follow this format:
{
"name": "Rule Name",
"description": "Optional description",
"enabled": true,
"action": "accept",
"bidirectional": true,
"protocol": "all",
"sources": ["group-id-1", "group-id-2"],
"destinations": ["group-id-3", "group-id-4"],
"port_ranges": [
{"start": 80, "end": 80},
{"start": 443, "end": 443}
]
}
Required Fields:
name (string): Rule nameenabled (boolean): Whether rule is activeaction (string): Either "accept" or "drop"bidirectional (boolean): Whether traffic is allowed in both directionsprotocol (string): One of "tcp", "udp", "icmp", or "all"sources (array of group IDs) OR sourceResource (object with id and type)destinations (array of group IDs) OR destinationResource (object with id and type)Optional Fields:
description (string): Rule descriptionport_ranges (array): Port ranges for TCP/UDP protocolsauthorized_groups (object): Map of group IDs to arrays of authorized group IDsImportant Notes:
["d535b93ngf8s73892nng"]){
"name": "Admin SSH Access",
"description": "Allow admins to SSH to all servers",
"enabled": true,
"rules": [
{
"name": "SSH Rule",
"enabled": true,
"action": "accept",
"bidirectional": false,
"protocol": "tcp",
"sources": ["admin-group-id"],
"destinations": ["server-group-id"],
"port_ranges": [{"start": 22, "end": 22}]
}
]
}
{
"name": "Infrastructure Access",
"description": "Complex access control for infrastructure",
"enabled": true,
"rules": [
{
"name": "HTTP/HTTPS Access",
"enabled": true,
"action": "accept",
"bidirectional": true,
"protocol": "tcp",
"sources": ["user-group-id"],
"destinations": ["web-server-group-id"],
"port_ranges": [
{"start": 80, "end": 80},
{"start": 443, "end": 443}
]
},
{
"name": "Database Access",
"enabled": true,
"action": "accept",
"bidirectional": false,
"protocol": "tcp",
"sources": ["app-server-group-id"],
"destinations": ["database-group-id"],
"port_ranges": [{"start": 5432, "end": 5432}],
"authorized_groups": {
"admin-group-id": ["dba-group-id"]
}
}
]
}
Use the get_policy_template tool to get example policy structures:
# Returns examples of simple and complex policy rules with documentation
get_policy_template
Before deleting or modifying a group, find which policies reference it:
# Find all policies that reference a specific group
list_policies_by_group --group_id "d535b93ngf8s73892nng"
Returns:
{
"group_id": "d535b93ngf8s73892nng",
"group_name": "Admins",
"policies": [
{
"policy_id": "policy-1",
"policy_name": "Admin Access",
"rule_id": "rule-1",
"rule_name": "Admin Rule",
"location": "sources"
}
]
}
Replace one group with another in all policies:
# Replace old group with new group in all policies
replace_group_in_policies \
--old_group_id "old-group-id" \
--new_group_id "new-group-id"
Returns:
{
"old_group_id": "old-group-id",
"new_group_id": "new-group-id",
"updated_policies": ["policy-1", "policy-2"],
"errors": []
}
Delete a group and automatically remove it from all dependent policies:
# Delete group without checking dependencies (removes from all policies)
delete_netbird_group --group_id "group-id" --force true
If force=false and dependencies exist, returns an error with the list of dependent policies.
Build an image and tag it:
docker build -t mcp-netbird-sse:v1 -f Dockerfile.sse .
Run the image with different configuration methods:
Option 1: Environment Variables (Traditional)
docker run --name mcp-netbird -p 8001:8001 \
-e NETBIRD_API_TOKEN=<your-api-token> \
mcp-netbird-sse:v1
Option 2: Command-Line Arguments
docker run --name mcp-netbird -p 8001:8001 \
mcp-netbird-sse:v1 \
--transport sse \
--sse-address :8001 \
--api-token <your-api-token> \
--api-host api.netbird.io
Option 3: HTTP Headers (Stateless Containers)
# Run without credentials (stateless)
docker run --name mcp-netbird -p 8001:8001 mcp-netbird-sse:v1
# Pass credentials via HTTP headers with each request
curl -X POST http://localhost:8001/sse \
-H "X-Netbird-API-Token: <your-api-token>" \
-H "X-Netbird-Host: api.netbird.io" \
-H "Content-Type: application/json" \
-d '{"method": "tools/list"}'
Note: Option 3 is ideal for Docker MCP Toolkit and other stateless container environments where you don't want to bake credentials into the container.
ToolHive (thv) is a lightweight utility designed to simplify the deployment and management of MCP servers.
You can use ToolHive to deploy and run Netbird MCP as follows:
Install thv as described in ToolHive README.
Add Netbird API token to thv secrets:
thv secret set netbird
Build an SSE image as described in the Docker section above
Start Netbird MCP with thv run on port 8080:
thv run --secret netbird,target=NETBIRD_API_TOKEN --transport sse --name thv-mcp-netbird --port 8080 --target-port 8001 mcp-netbird-sse:v1
thv stop thv-mcp-netbird
Contributions are welcome! Please open an issue or submit a pull request if you have any suggestions or improvements.
This project is written in Go. Install Go following the instructions for your platform.
To run the server manually, you can use any of the three configuration methods:
Option 1: Environment Variables
export NETBIRD_API_TOKEN=your-token && \
go run cmd/mcp-netbird/main.go
Option 2: Command-Line Arguments
go run cmd/mcp-netbird/main.go --api-token your-token --api-host api.netbird.io
Option 3: SSE Mode with HTTP Headers
# Start server without credentials
go run cmd/mcp-netbird/main.go --transport sse --sse-address :8001
# In another terminal, make requests with headers
curl -X POST http://localhost:8001/sse \
-H "X-Netbird-API-Token: your-token" \
-H "X-Netbird-Host: api.netbird.io" \
-H "Content-Type: application/json" \
-d '{"method": "tools/list"}'
Or in SSE mode with CLI arguments:
go run cmd/mcp-netbird/main.go \
--transport sse \
--sse-address :8001 \
--api-token your-token \
--api-host api.netbird.io
The MCP Inspector is an interactive developer tool for testing and debugging MCP servers. Read more about it here.
Here's how to start the MCP Inspector with different configuration methods:
Option 1: Environment Variables
export NETBIRD_API_TOKEN=your-token && \
npx @modelcontextprotocol/inspector
Option 2: Command-Line Arguments
npx @modelcontextprotocol/inspector
# Then in the UI, specify: mcp-netbird --api-token your-token --api-host api.netbird.io
Option 3: SSE Mode with HTTP Headers
# Start the server
go run cmd/mcp-netbird/main.go --transport sse --sse-address :8001
# In the MCP Inspector UI, configure SSE transport with headers:
# URL: http://localhost:8001/sse
# Headers: X-Netbird-API-Token: your-token
Netbird MCP Server can then be tested with either stdio or SSE transport type. For stdio specify the full path to mcp-netbird in the UI.
TODO: add more tests
To lint the code, run:
make lint
This project is licensed under the Apache License, Version 2.0.
Copyright 2025-2026 XNet Inc.
Copyright 2025-2026 Joshua S. Doucette
This project was originally derived from the MCP Server for Grafana (https://github.com/grafana/mcp-grafana) developed by Grafana Labs. The current codebase has been substantially modified and extended.
This project uses MCP Go (https://github.com/mark3labs/mcp-go) developed by Mark III Labs.
Maintained by XNet Inc. | Lead Developer: Joshua S. Doucette
Content type
Image
Digest
sha256:007ee9576…
Size
35.6 MB
Last updated
9 months ago
docker pull xnetadmin/mcp-netbird