Install any skill in seconds. Free to start, no credit card required.
Get Started Free →OpsMill Infrahub — infrastructure source of truth with schema-driven nodes, GraphQL queries, and branch-isolated changes. Use when querying Infrahub for device/IPAM inventory, browsing infrastructure schemas, running GraphQL queries, or making infrastructure changes safely via an auto-created session branch and a Proposed Change for human review.
.claude/skills/automateyournetwork-infrahub-sot/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | 175% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 279% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 211% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 250% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 177% | 0% |
pip install infrahub-mcp), Docker (registry.opsmill.io/opsmill/infrahub-mcp), or from sourceinfrahub-mcp console scriptstdio (default) or streamable-http (remote clients / auth modes)INFRAHUB_ADDRESS + (INFRAHUB_API_TOKEN or INFRAHUB_USERNAME+INFRAHUB_PASSWORD)fastmcp>=3.2.0, infrahub-sdk>=1.20.0> What changed in the rework: the server moved to a modular src/infrahub_mcp/ layout on > FastMCP 3.x, added a branch-isolated write model (writes never touch the default branch), > exposes MCP resources and prompts in addition to tools, serializes schema output with TOON > internally to cut tokens, and ships as a PyPI package + Docker image with optional auth, > rate limiting, caching, and OpenTelemetry/Prometheus observability. The old read-only tool > surface (get_node_filters, get_related_nodes, get_schema_mapping, get_schemas, > get_graphql_schema, get_branches, branch_create) has been replaced — see the table below.
Infrahub is not just another IPAM/DCIM tool. Key differentiators:
The reworked server makes destructive operations safe by construction:
auto-creates a session branch named mcp/session-YYYYMMDD-<hex> (pattern configurable via INFRAHUB_MCP_BRANCH_PATTERN). All node_upsert / node_delete / mutate_graphql land there.
propose_changes opens a Proposed Change (PR) fromthe session branch to the default branch — a human reviews and merges it in the Infrahub UI. The agent never merges.
auto-recovered on the next write; reset_session_branch clears or switches the active branch.
INFRAHUB_MCP_READ_ONLY=true hides all write tools and blocks GraphQLmutations — use it for pure analysis/audit connections.
| Tool | Parameters | What It Does | |------|-----------|--------------| | get_nodes | kind, filters?, partial_match?, include_attributes?, offset?, limit?, branch? | Typed read of nodes of a kind. Supports attribute/relationship filters (attr__value, rel__attr__value), partial matching, and paging (returns total_count/has_more). | | search_nodes | kind, value, branch? | Find nodes of a kind by partial substring via Infrahub's any__value filter. Works on concrete and abstract/generic kinds. | | get_schema | kind?, branch? | Discover schema kinds (catalog) or, given a kind, its attributes/relationships/filter-map (TOON-encoded). Tool fallback for clients without MCP resources. | | get_session_info | none | Report current session state — active session_branch, infrahub_address, has_session_branch. Call before writes to know the target branch. | | query_graphql | query, branch? | Execute a read-only GraphQL query (mutations are rejected here). |
INFRAHUB_MCP_READ_ONLY=true| Tool | Parameters | What It Does | |------|-----------|--------------| | node_upsert | kind, data, ... | Create or update a node on the active session branch. | | node_delete | kind, id | Delete a node on the active session branch. | | mutate_graphql | mutation, ... | Execute a GraphQL mutation (relationship edits / bulk ops typed tools can't express). Branch/schema-management mutations are blocked. | | propose_changes | title?, description? | Open a Proposed Change from the session branch to the default branch for human review. | | reset_session_branch | branch? | Clear the cached session branch (next write creates a fresh one) or point the session at a named branch. Rejects the default branch and merged/read-only branches. |
| Resource URI | Content | |--------------|---------| | infrahub://schema | Kind catalog (JSON) | | infrahub://schema/{kind} | Per-kind schema + filter map (template) | | infrahub://graphql-schema | Full GraphQL SDL (text) | | infrahub://branches | All branches including the session branch (JSON) |
infrahub_agent (system prompt; read-only vs read-write aware), answer_infra_question, make_infra_change, explore_schema.
When first connecting to Infrahub:
infrahub://schema (or get_schema with no kind) — what infrastructure types are modeled?get_schema(kind="InfraDevice") — what attributes and relationships does a device have?get_nodes(kind="InfraDevice") — list all devices (page with offset/limit).When auditing infrastructure state in Infrahub:
get_schema (no kind) — discover all kinds.get_nodes(kind="InfraDevice") — all devices.get_nodes(kind="InfraIPAddress") — all IPs (if IPAM is modeled).get_nodes(kind="InfraPrefix") — all subnets.search_nodes(kind="InfraDevice", value="core") — fuzzy find by substring.When proposing an infrastructure change (the safe write path):
get_session_info — see the active session branch (or that none exists yet).node_upsert(...), node_delete(...), or mutate_graphql(...). The firstwrite auto-creates the mcp/session-* branch — you never edit the default branch directly.
get_nodes(...) on the session branch — confirm changes look correct.propose_changes(title="Add VLAN 200", description="...") — opens a ProposedChange for human review.
reset_session_branch.
When building custom queries:
infrahub://graphql-schema — full SDL, understand query structure.query_graphql(query="{ InfraDevice { edges { node { name { value } } } } }").query_graphql(query="{ InfraDevice(name__value: \"core-rtr\") { ... } }").mutate_graphql (write tool) and land on the session branch — never query_graphql.The MCP server is for live data — querying and changing a running Infrahub instance. For authoring the artifacts that define and validate that data, use the OpsMill infrahub-skills plugin (infrahub@opsmill, 12 skills). Rule of thumb: infrahub-sot (this skill / the MCP) reads and changes live data; infrahub-skills writes the files (schemas, checks, transforms, generators) that shape it.
| Need | Use | |------|-----| | Query live nodes / IPAM, run GraphQL, make a branch-isolated change | infrahub-sot (this skill, MCP-backed) | | Analyze/correlate live data, drift & impact analysis | infrahub-analyzing-data (also MCP-backed) | | Design/validate schema YAML (nodes, generics, relationships) | infrahub-managing-schemas | | Populate object data YAML (devices, sites, orgs) | infrahub-managing-objects | | Write validation checks for Proposed Change pipelines | infrahub-managing-checks | | Build transforms / Jinja2 config artifacts | infrahub-managing-transforms | | Build design-driven generators | infrahub-managing-generators | | Custom web-UI menus | infrahub-managing-menus | | Audit an Infrahub repo against best practices | infrahub-auditing-repo | | Import CSV/TSV into object YAML | infrahub-importing-data | | File a bug/feature to the right opsmill/infrahub-* repo | infrahub-reporting-issues | | Collect a redacted diagnostic bundle for support | infrahub-collecting-diagnostics |
Install: npx skills add opsmill/infrahub-skills (cross-tool) or, in Claude Code, /plugin marketplace add opsmill/claude-marketplace then /plugin install infrahub@opsmill. Only infrahub-analyzing-data requires a connected Infrahub MCP server; the rest are file-authoring/reading and pair naturally with this skill's live-data workflows.
| Skill | How They Work Together | |-------|----------------------| | netbox-reconcile | Infrahub as primary SoT, NetBox as legacy — compare and migrate | | nautobot-sot | Infrahub as primary SoT, Nautobot as legacy — compare IPAM data | | pyats-topology | Infrahub provides intended state; pyATS discovers actual device state for reconciliation | | pyats-network | Cross-reference Infrahub infrastructure model with live device configs | | pyats-routing | Validate routing table entries against Infrahub prefix/IP allocations | | aci-fabric-audit | Infrahub fabric model vs ACI actual state | | meraki-network-ops | Infrahub planned state vs Meraki actual DHCP/VLAN assignments | | aws-network-ops | Infrahub cloud model vs AWS VPC actual state | | radkit-remote-access | Use Infrahub to identify device IPs, then RADKit for remote CLI access | | servicenow-change-workflow | Infrahub Proposed Changes map to ServiceNow CRs — one session branch per change | | gait-session-tracking | Record all Infrahub queries, session-branch writes, and Proposed Changes |
NetClaw supports all three source-of-truth platforms:
| Feature | NetBox | Nautobot | Infrahub | |---------|--------|----------|----------| | Origin | DigitalOcean / NetBox Labs | Network to Code | OpsMill | | Data model | Fixed DCIM/IPAM + custom fields | Fixed DCIM/IPAM + Jobs + custom fields | Fully schema-driven (define any model) | | Versioning | No branching | No branching | Git-like branches for data | | API | REST + GraphQL | REST + GraphQL | GraphQL-native | | MCP tools | Read-write via FastMCP | Read-only IPAM (5 tools) | Read + branch-isolated write + Proposed Changes (10 tools) | | Use when | Standard IPAM/DCIM | Standard IPAM/DCIM (NTC ecosystem) | Custom infrastructure models, versioned & reviewed changes |
infrahub://schema (or get_schema with no kind) first to learn what kinds exist. Don't guess kind names, then get_schema(kind=...) for its filters.node_upsert / node_delete / mutate_graphql). They land on the auto-created session branch by design; query_graphql is read-only.propose_changes and hand the Proposed Change to a human. The agent does not merge to the default branch.get_session_info before writes to see the target branch; reset_session_branch to start a clean, unrelated change.node_upsert, node_delete, and mutate_graphql.INFRAHUB_MCP_READ_ONLY=true for pure analysis so write tools are unavailable.partial_match=True in get_nodes, or search_nodes, for fuzzy value matching.Connection / credentials (consumed by infrahub-sdk; no prefix):
INFRAHUB_ADDRESS — required, Infrahub instance URL (e.g., http://infrahub.example.com:8000)INFRAHUB_API_TOKEN — API token auth, orINFRAHUB_USERNAME + INFRAHUB_PASSWORD — username/password auth (one auth method required)Server behavior (pydantic-settings, prefix INFRAHUB_MCP_; defaults shown):
INFRAHUB_MCP_READ_ONLY (false) — hide write tools and block GraphQL mutationsINFRAHUB_MCP_BRANCH_PATTERN (mcp/session-{date}-{hex}) — session-branch naming; INFRAHUB_MCP_MAX_BRANCH_RETRIES (5)INFRAHUB_MCP_LOG_LEVEL (info)INFRAHUB_MCP_RATE_LIMIT_RPS, INFRAHUB_MCP_RATE_LIMIT_BURST, INFRAHUB_MCP_RETRY_MAX_ATTEMPTS, INFRAHUB_MCP_RETRY_BASE_DELAYINFRAHUB_MCP_CACHE_ENABLED (false), INFRAHUB_MCP_CACHE_LIST_TTL, INFRAHUB_MCP_CACHE_READ_TTLINFRAHUB_MCP_OTEL_ENABLED, INFRAHUB_MCP_PROMETHEUS_ENABLEDnone modes require streamable-http): INFRAHUB_MCP_AUTH_MODE (none|oidc|token-passthrough|basic-passthrough) plus OIDC settings (INFRAHUB_MCP_OIDC_CONFIG_URL, INFRAHUB_MCP_OIDC_CLIENT_ID, INFRAHUB_MCP_OIDC_BASE_URL, …)Transport flags: --transport {stdio,streamable-http} (default stdio), --host (default 127.0.0.1), --port (default 8001).
Other measured skills in the registry, with their headline benchmark lift.