Skip to main content
Glama

nautobot-mcp

CI Python License

Ein MCP-Server für Nautobot, gebaut für Instanzen, deren API zu groß zum Aufzählen ist: Nautobot 3.2 bringt 1.673 REST-Operationen über 477 Pfade mit, und jede installierte App fügt weitere hinzu. Dieser Server stellt 15 schema-getriebene Tools bereit statt eines Tools pro Endpunkt, sodass die gesamte API – Kern und Plugins gleichermaßen – erreichbar ist, ohne den Kontext eines Agents zu überfluten.

Was ihn funktionieren lässt

Ein Build-Schritt, kein Runtime-Parsing. Das OpenAPI-Dokument von Nautobot ist 18 MB groß und die GraphQL-Introspection weitere 10 MB. Ein Build-Skript verschmilzt beide zu einem ~1,1 MB großen SQLite-Index mit einer FTS5-Suchtabelle. Der Server öffnet ihn schreibgeschützt und beantwortet Lookups in Mikrosekunden; der Start hängt nicht von der Größe der API ab.

Fremdschlüssel aus GraphQL rekonstruiert. OpenAPI allein kann die Beziehungen von Nautobot nicht beschreiben – jedes verknüpfte Feld serialisiert als identisches opakes Objekt:

// dcim.device: device_type, role, status and location are indistinguishable here
"device_type": { "id": {...}, "object_type": {"pattern": "^[a-z]+\\.[a-z]+$"}, "url": {...} }

Das Typsystem von GraphQL benennt die Ziele direkt (device_type → DeviceTypeType), also werden beide über den OpenAPI-Komponentennamen verbunden, um 441 typisierte FK-Kanten zu rekonstruieren. Dieser Graph ist es, der die Abhängigkeitsplanung möglich macht.

Filter komprimiert. dcim.device stellt 250 Filterparameter bereit, die in Wirklichkeit ~74 Basisfelder mal einer Familie von Lookup-Suffixen sind (__ic, __n, __isnull, __gte, …). Der Index speichert Basisfelder plus deren Suffixmengen und beschreibt das Vokabular einmal.

Related MCP server: Advanced Hasura GraphQL MCP Server

Installation

uv venv && uv pip install -e ".[dev]"
cp .env.example .env        # then set NAUTOBOT_URL and NAUTOBOT_TOKEN
cp .mcp.json.example .mcp.json   # optional: for stdio-based clients
python -m nautobot_mcp.schema.build --probe

Oder überspringen Sie den Checkout ganz und führen Sie ihn in einem Container aus – siehe Docker.

Der Build-Schritt holt die Schemas und schreibt var/index.sqlite. Führen Sie ihn nach der Installation oder dem Upgrade einer Nautobot-App erneut aus – oder rufen Sie das Tool nautobot_refresh_schema auf.

Konfiguration

Variable

Standard

Zweck

NAUTOBOT_URL

Basis-URL, z. B. http://nautobot.example.com:8080

NAUTOBOT_TOKEN

API-Token

NAUTOBOT_ALLOW_WRITE

false

Master-Schalter für Create/Update/Delete

NAUTOBOT_VERIFY_SSL

true

TLS-Verifizierung

NAUTOBOT_TIMEOUT

30

Timeout pro Anfrage (Sekunden)

NAUTOBOT_CACHE_DIR

./var

Wo Schemaquellen und der Index liegen

NAUTOBOT_MAX_PAGE

1000

Obergrenze für die fetch_all-Paginierung

Nur für Container geltende Stellschrauben, die vom Entrypoint statt vom Server gelesen werden:

Variable

Standard

Zweck

MCP_TRANSPORT

streamable-http

Transport, den der Container bedient (stdio für einen client-gespawnten Container)

MCP_HOST

0.0.0.0

Bind-Adresse für HTTP-Transports

MCP_PORT

8000

Bind-Port für HTTP-Transports

NAUTOBOT_AUTO_INDEX

true

Fehlenden Schema-Index beim Start aufbauen statt die Ausführung zu verweigern

Bei einem Client registrieren

{
  "mcpServers": {
    "nautobot": {
      "command": "/path/to/nautobot-mcp/.venv/bin/python",
      "args": ["-m", "nautobot_mcp"],
      "env": {
        "NAUTOBOT_URL": "http://nautobot.example.com:8080",
        "NAUTOBOT_TOKEN": "...",
        "NAUTOBOT_CACHE_DIR": "/path/to/nautobot-mcp/var"
      }
    }
  }
}

HTTP-Transports sind ebenfalls verfügbar: python -m nautobot_mcp --transport streamable-http --port 8000.

Docker

cp .env.example .env        # then set NAUTOBOT_URL and NAUTOBOT_TOKEN
docker compose up -d        # or: make docker-up

Der erste Start baut den Schema-Index gegen Ihre Instanz und speichert ihn auf dem index-Volume; spätere Starts verwenden ihn erneut. Der Server lauscht auf 127.0.0.1:8000/mcp.

Der Index ist nicht ins Image eingebacken und kann es auch nicht sein: Er wird aus den Schemas einer bestimmten Nautobot-Instanz verschmolzen, einschließlich aller Apps, die diese Instanz installiert hat. Bauen Sie ihn nach der Installation oder dem Upgrade einer App neu auf – make docker-index oder das Tool nautobot_refresh_schema, das in dasselbe Volume schreibt.

make docker-index                 # rebuild the index in place
make docker-logs                  # follow the server log
make docker-down                  # stop; VOLUMES=1 also drops the index
docker compose run --rm server index --offline   # rebuild from cached sources only

Den Container bei einem Client registrieren

Über HTTP zeigen Sie den Client auf den veröffentlichten Port:

{
  "mcpServers": {
    "nautobot": { "url": "http://127.0.0.1:8000/mcp" }
  }
}

Oder lassen Sie den Client pro Sitzung einen Container über stdio spawnen und dabei dasselbe Index-Volume wiederverwenden:

{
  "mcpServers": {
    "nautobot": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "--env-file", "/path/to/nautobot-mcp/.env",
        "-e", "MCP_TRANSPORT=stdio",
        "-v", "nautobot-mcp_index:/data",
        "nautobot-mcp:latest"
      ]
    }
  }
}

Alles, was nach dem Image-Namen übergeben wird, geht direkt an python -m nautobot_mcp, also funktioniert auch docker run ... nautobot-mcp:latest --transport sse --host 0.0.0.0 --port 8000.

Was die Compose-Datei voraussetzt

  • Der Port wird nur auf Loopback veröffentlicht. Abschnitt Sicherheit gilt in vollem Umfang: Dies ist ein unauthentifizierter Proxy, der ein Token mit Ihren Berechtigungen hält. Wenn er also von einem anderen Host erreichbar sein soll, muss Authentifizierung davor geschaltet werden, nicht die Port-Zuordnung erweitert werden.

  • Schreibzugriffe bleiben aus, außer NAUTOBOT_ALLOW_WRITE=true steht in Ihrer .env.

  • Der Container ist standardmäßig gehärtet – nicht-root (uid 1000), read-only Root-Dateisystem, alle Capabilities entfernt, no-new-privileges. Der einzige beschreibbare Pfad ist das /data-Volume, auf dem der Index und seine gecachten Quellen liegen.

  • Health ist ein TCP-Connect, keine MCP-Anfrage: Eine Anfrage ohne Session an /mcp veranlasst den Session-Manager, einen Transport zu allozieren, den nichts aufräumt. Das Protokoll alle 30s zu sondieren würde also eine Session pro Sondierung leaken.

  • .env wird von Compose wörtlich gelesen. Halten Sie Kommentare auf einer eigenen Zeile; ein nachgestellter # comment wird nicht zuverlässig von einem Wert getrennt.

Tools

Tool

Zweck

nautobot_search_schema

Modelle nach Name, Beschreibung oder Feldname finden

nautobot_describe_model

Felder, Pflichtfelder, FK-Ziele, Filter, Aktionen

nautobot_list_apps

App-Namespaces (Kern und Plugin), Versionen, Indexzustand

nautobot_plan_create

Geordnete Voraussetzungen zum Erstellen eines Objekts

nautobot_resolve

Menschenlesbarer Name → UUID, auf das referenzierende Modell begrenzt

nautobot_list / nautobot_get

Beliebiges Modell lesen, verschlankt oder projiziert

nautobot_create / nautobot_update / nautobot_delete

Gesteuerte Schreibzugriffe

nautobot_graphql

Beliebige GraphQL-Abfragen

nautobot_graphql_schema

Introspection, ein Typ nach dem anderen

nautobot_model_actions

Nicht-CRUD-Endpunkte (trace, napalm, notes, …)

nautobot_call

Beliebiger REST-Endpunkt – Plugins, Bulk-Operationen, benutzerdefinierte Aktionen

nautobot_refresh_schema

Schemas neu holen und den Index neu aufbauen

Modellreferenzen sind nachsichtig: dcim.device, device, devices, Device, /dcim/devices/ und DeviceType lösen alle auf, und Tippfehler erhalten Vorschläge (dvice → "Meinten Sie: dcim.device?").

Abhängigkeitsplanung

Das Erstellen eines Device auf einer leeren Instanz bedeutet, zuerst vier andere Objekte zu erstellen. nautobot_plan_create("dcim.device") durchläuft den FK-Graphen, prüft die Live-Instanz auf bereits Vorhandenes und gibt sie in Reihenfolge zurück:

dcim.manufacturer → dcim.devicetype → dcim.locationtype → dcim.location → extras.role → dcim.device

Es behandelt auch die Content-Type-Scoping von Nautobot. Role, Status und Tag sind nur Modellen zuweisbar, die in ihren content_types aufgeführt sind. Eine globale Zählung ist die falsche Frage – eine Instanz kann 20 Rollen enthalten, während keine auf ein Device zutrifft:

{
  "model": "extras.role",
  "action": "create",                      // not "use_existing", despite 20 existing
  "content_type_scoped": true,
  "by_referrer": { "dcim.device": { "valid_count": 0 } },
  "note": "No extras.role is assignable to dcim.device yet. Create one with
           content_types including ['dcim.device'] ..."
}

Welche Modelle auf diese Weise gescoped werden, wird entdeckt, nicht hartkodiert: content_types bedeutet "was hier leben darf" bei LocationType und "wer mich referenzieren darf" bei Role. Der Planer versucht die gescopte Abfrage und behandelt eine 400 als Beweis, dass Scoping nicht zutrifft – Plugin-Modelle verhalten sich also ohne zusätzlichen Code korrekt.

Schreibzugriffe

Schreibzugriffe sind aus, bis NAUTOBOT_ALLOW_WRITE=true gesetzt ist. Selbst dann sind Mutationen zweistufig: Der erste Aufruf gibt eine Vorschau und einen confirm_token zurück, und der Aufruf wird mit diesem Token wiederholt, um ihn anzuwenden. Tokens werden aus der Payload abgeleitet, sodass ein für einen Body ausgestelltes Token nicht gegen einen anderen wiederverwendet werden kann. nautobot_update zeigt eine Vorschau eines Diffs auf Feldebene; nautobot_delete zeigt eine Vorschau des Objekts und von allem, was darauf referenziert.

Sicherheit

Dieser Server ist ein unauthentifizierter privilegierter Proxy zu Nautobot. Er hält ein API-Token und führt keine eigene Authentifizierung durch: Jeder Client, der ihn erreichen kann, handelt mit den vollen Berechtigungen dieses Tokens, ohne jemals das Token zu besitzen.

Die Standardwerte sind bewusst sicher – --host bindet 127.0.0.1 und NAUTOBOT_ALLOW_WRITE ist false. Die riskante Konfiguration ist die Kombination aus einem Nicht-Loopback-Bind mit aktivierten Schreibzugriffen, was unauthentifiziertes Create/Update/Delete über Ihre Quelle der Wahrheit für alles gewährt, was den Port erreichen kann.

Der Confirm-Token-Ablauf ist eine Unfallschutzmaßnahme, keine Zugriffskontrolle – jeder Client kann das Token aus der Vorschauantwort lesen und sofort bestätigen.

Wenn der Server von anderen Hosts erreichbar sein muss, setzen Sie Authentifizierung davor (einen Reverse-Proxy mit mTLS, ein OAuth-fähiges Gateway oder einen SSH-Tunnel) und geben Sie ihm ein Nautobot-Token, das nur auf das beschränkt ist, was der Agent benötigt. Siehe SECURITY.md.

Reaktionsfähigkeit

  • Ein gepoolter HTTP/2-Client wird von allen Tools gemeinsam genutzt; der Planer führt Existenzprüfungen parallel aus.

  • Antworten werden verschlankt, bevor sie den Agent erreichen. Nautobot hat keine Unterstützung für spärliche Feldsets (?fields= wird als unbekannter Filter abgelehnt), also werden url, natural_slug, notes_url, Zeitstempel und leere Custom-Field-Blöcke clientseitig entfernt, und verschachtelte verknüpfte Objekte werden auf Identität reduziert. Übergeben Sie fields=[...] zum Projizieren oder full=true zum Opt-out.

Erweiterung

Jedes Toolset ist ein Modul, das register(server, ctx) exponiert und in tools/__init__.py::TOOLSETS aufgeführt ist. Die Registrierung ist so umhüllt, dass jedes Tool einen strukturierten Fehler zurückgibt statt zu werfen – eine unbehandelte Ausnahme würde den Agent als undurchsichtigen "Fehler beim Ausführen von Tool X" erreichen.

Plugin-Endpunkte benötigen keinen Code: Sie erscheinen in /api/swagger.json, also macht das Neuaufbauen des Index sie für jedes Tool verfügbar.

Tests

pytest

82 Tests laufen gegen Fixtures, die aus dem Live-Schema geschnitten sind, mit per respx gemocktem HTTP. Sie fixieren die Fallstricke, die beim Bauen gefunden wurden: die Slug-Kollision, die virtualization.vminterface auf DCIMs InterfaceType abbildet, das content_types-Scoping, das stillschweigend unbrauchbare Pläne erzeugt, und die FK-Heuristik, die DynamicGroupMembership.group zu Djangos auth.Group auflöst statt zu extras.DynamicGroup.

Agent-Konfiguration

AGENT.md enthält einen gebrauchsfertigen System-Prompt und eine Registry-Beschreibung für einen Agent, der diesen Server steuert, einschließlich des Schreibprotokolls und der Content-Type-Scoping-Regel, die am häufigsten dazu führt, dass ein Create fehlschlägt.

Mitwirken

Issues und Pull Requests sind willkommen. pytest muss bestehen und ruff check / ruff format --check müssen sauber sein; CI erzwingt beides über Python 3.11-3.13. Die Suite benötigt keine Nautobot-Instanz und kein Netzwerk – sie läuft gegen Schema-Fixtures in tests/fixtures mit per respx gemocktem HTTP.

Lizenz

Apache 2.0 – siehe LICENSE.

Aufbau

src/nautobot_mcp/
  schema/build.py     fuses OpenAPI + GraphQL + content types into the index
  schema/index.py     read-only query layer (lookup, FTS search, graph)
  client.py           pooled async HTTP, slimming, error normalisation
  depgraph.py         creation planning and reference resolution
  safety.py           write gate, confirm tokens, diffs
  tools/              one module per toolset, registered through a guard
  server.py           MCP server assembly
A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables comprehensive interaction with NetBox infrastructure management through both read and write operations. Supports full CRUD operations for devices, IP addresses, sites, racks, and other NetBox objects through natural language commands.
    9
    16
    Apache 2.0
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to interact with Hasura GraphQL endpoints to discover schema structures and execute queries or mutations. It provides specialized tools for table introspection, data previewing, and performing data aggregations through natural language.
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to interact with any GraphQL API by introspecting the schema and exposing queries and mutations as MCP tools, with built-in pagination, semantic search, and framework adapters.
    13
    MIT

View all related MCP servers

Related MCP Connectors

  • Gateway between LLM agents and world data through eight tools and a bundled endpoint catalog.

  • SaaS intelligence for AI agents. 5 unified tools cover 1,000+ services with 91-96% token savings.

  • Provides cloud browser automation capabilities using Stagehand and Browserbase, enabling LLMs to i…

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/shamalawy/nautobot-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server