Skip to main content
Glama

Infrahub MCP Server

Infrahub MCP Server connects AI assistants and IDE agents to Infrahub using the open Model Context Protocol standard — so agents can query, create, update, and propose changes to your infrastructure data through a consistent, audited interface. It works with any MCP-compatible client (Claude Desktop, VS Code, Cursor, CLI agents, and more) with no custom glue code required.

All writes are branch-isolated and require human approval before merging — agents never modify your default branch directly.

Installation

pip install infrahub-mcp
# or
uv pip install infrahub-mcp

Docker:

docker pull registry.opsmill.io/opsmill/infrahub-mcp:latest
# or use Docker Compose:
docker compose up -d

Related MCP server: python-openstackmcp-server

Quickstart

Point the server at your Infrahub instance via environment variables, then run it over the transport your client expects.

stdio (default — for Claude Desktop, VS Code, Cursor):

export INFRAHUB_ADDRESS=http://localhost:8000
export INFRAHUB_API_TOKEN=<your-token>
infrahub-mcp

Streamable HTTP (for remote clients, sidecar deployments):

infrahub-mcp --transport streamable-http --host 0.0.0.0 --port 8001

What you can do with it

  • Query your infrastructure data from natural language — find devices, interfaces, IP addresses, or any kind in your schema, with attribute filtering and partial-match search.

  • Explore your schema without leaving the conversation — the server exposes your catalog, per-kind attribute/filter maps, and the GraphQL SDL as MCP resources.

  • Make changes on isolated branches — writes land on an auto-created session branch (mcp/session-YYYYMMDD-<hex>); the default branch is never touched directly.

  • Submit changes for human review — call propose_changes to open a Proposed Change for approval before merging.

  • Run arbitrary GraphQL — execute any query or mutation against the Infrahub API when you need full control.

Documentation

Full documentation, including client configuration for Cursor, VS Code, Claude Desktop, and Claude Code, is available at the Infrahub MCP Server docs site.

About Infrahub

Infrahub is an open source infrastructure data management and automation platform (AGPLv3), developed by OpsMill. It gives infrastructure and network teams a unified, schema-driven source of truth — devices, topology, IP space, configuration — with built-in version control, a generator framework for automation, and native integrations with Git, Ansible, Terraform, and CI/CD pipelines.

License

Apache 2.0 — see LICENSE.

Available Tools

12 tools
find_pathsFind PathsA
Read-only

Find the shortest path(s) between two nodes in the Infrahub graph.

Use this to answer "how are these two objects connected?". A result with count of 0 means no path exists within max_depth. Requires Infrahub 1.10+.

ParametersJSON Schema
NameRequiredDescriptionDefault
branchNoBranch to query. Defaults to the default branch.
sourceYesStart node: a UUID or kind-qualified HFID (e.g. 'InfraDevice__atl1-edge1').
max_depthNoMaximum relationship hops to explore (1-30).
destinationYesEnd node: a UUID or kind-qualified HFID.
kind_filterNoOnly traverse through nodes of these kinds.
relationship_filterNoOnly follow these schema relationship identifiers (e.g. 'device__interface').

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

readOnlyHint=true already covers the safety profile, and the description adds real value on top: it explains the meaning of a zero-count result and states a version prerequisite (Infrahub 1.10+). It does not describe the shape of the path result itself, but the constraint disclosure is substantive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core action, then usage framing, then the edge-case and prerequisite. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only traversal tool with no output schema, the description covers purpose, usage framing, a key result-interpretation rule, and a version prerequisite. What it lacks is any indication of the returned path structure (node lists, hop counts) or limits on result size.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all six parameters including source/destination formats, max_depth range, and both filters are already documented in the schema. The description adds only the max_depth interaction with count=0, which is baseline-level added meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Find the shortest path(s) between two nodes in the Infrahub graph'), which is precise and unambiguous. It does not, however, differentiate itself from the sibling find_reachable, which an agent would plausibly confuse with it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete usage framing ('how are these two objects connected?') and clarifies that count of 0 means no path exists within max_depth. It stops short of naming the alternative tool (find_reachable) or stating when this should be preferred over it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

find_reachableFind ReachableA
Read-only

Find nodes of the given kinds reachable from a source node (impact analysis).

Use this to answer "what depends on / is connected to this object?" — for blast-radius and dependency discovery. Requires Infrahub 1.10+.

ParametersJSON Schema
NameRequiredDescriptionDefault
branchNoBranch to query. Defaults to the default branch.
sourceYesSource node: a UUID or kind-qualified HFID.
max_depthNoMaximum traversal depth (1-30).
max_resultsNoMaximum distinct reachable nodes to return (1-200).
target_kindsYesNode kinds to search for, reachable from the source.
shortest_paths_onlyNoReturn only the shortest path to each target.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so safety is covered. The description adds genuinely useful context beyond that: the version requirement (Infrahub 1.10+) and the analytical semantics of traversal. It does not discuss result limits or traversal cost, which max_depth/max_results imply matter.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core action, then the use case, then the prerequisite. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 6-parameter read-only traversal tool with no output schema, the description covers purpose, use case, and version prerequisite, which is enough to call it correctly. It is slightly thin on what a result actually contains (nodes vs paths, shortest-path behavior), which would help given the absent output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all six parameters including ranges (1-30 depth, 1-200 results) and defaults are already documented. The description only implicitly references source and target_kinds ('given kinds', 'source node') and adds no format or syntax detail beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource with scope: 'Find nodes of the given kinds reachable from a source node'. The parenthetical '(impact analysis)' anchors the intent, and it is distinguishable from the sibling find_paths because it returns reachable nodes rather than paths.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear usage context — 'what depends on / is connected to this object?', blast-radius and dependency discovery — which tells the agent when this tool is the right pick. It does not name alternatives such as find_paths explicitly or state when not to use it, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_nodesGet NodesA
Read-only

List nodes of a specific kind — the default read path for typed queries with optional filtering and pagination.

Prefer this over query_graphql when you just need objects of one kind: results come back as display labels (fast, token-cheap) or full attribute dicts (include_attributes=True).

To discover available kinds, read the infrahub://schema resource. If your client does not support MCP resources, call the get_schema tool instead. To discover available filters for a kind, read infrahub://schema/{kind} or call get_schema(kind='...').

Filter keys follow the schema's filter map. Attribute filters use <attr>__value (e.g. {"name__value": "atl1"}) and relationship filters chain via <rel>__<attr>__value (e.g. {"site__name__value": "atl1"}). See infrahub://schema/{kind} for the full list of valid keys.

Use offset and limit to page through large result sets. The response always includes total_count and has_more so you know when to stop.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindYesKind of the objects to retrieve. Check infrahub://schema for valid kinds.
limitNoMaximum nodes to return. Default 50. Pass -1 for all results (caution: may be expensive).
branchNoBranch to query. Defaults to the default branch.
offsetNoNumber of results to skip for pagination. Use with limit to page through results.
filtersNoAttribute/relationship filters. Keys follow the schema's filter map (e.g. {"name__value": "atl1"} or {"site__name__value": "atl1"}). See infrahub://schema/{kind} for the full filter map.
partial_matchNoUse partial (substring) matching for string filters.
include_attributesNoWhen True, return full attribute values in TOON tabular format instead of just display labels. More expensive — omit when you only need names/counts.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, but the description adds real behavioral context: two result modes with differing cost (display labels vs full attribute dicts), and a termination signal via 'total_count' and 'has_more'. It doesn't cover permission/auth requirements or branch-resolution behavior, which is the remaining gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose and the query_graphql comparison, then structured into discovery, filter syntax, and paging. Slightly long, and the resource-vs-tool discovery instruction is repeated in two forms, but every block carries usable guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter read tool with no output schema, the description covers what an agent needs: how to find kinds and filter keys, how filters are shaped, and what the response looks like (labels vs attributes, plus total_count/has_more). Nothing essential to a correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema carries the field-level burden, but the description adds semantics the schema only gestures at: the filter-key convention ('<attr>__value', relationship chaining via '<rel>__<attr>__value') and the paging contract pairing offset/limit with total_count/has_more. Genuinely additive over the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb+resource ('List nodes of a specific kind') and characterizes itself as the 'default read path for typed queries with optional filtering and pagination.' It explicitly distinguishes itself from the sibling 'query_graphql', so an agent can route between the two without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use ('Prefer this over query_graphql when you just need objects of one kind') and concrete discovery paths for both kinds and filters, including the fallback 'get_schema' tool for clients without MCP resource support. Exclusions and alternatives are both named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_schemaGet SchemaA
Read-only

Discover available schema kinds — call this first when you don't know what kinds or filters exist.

Without a kind, returns the catalog of all kinds (compact JSON). With a kind, returns its attributes, relationships, and the full set of filter keys accepted by get_nodes (TOON-encoded for token efficiency). Each relationship inlines one level of its peer schema unless expand is False (or the server default disables it).

Prefer reading the infrahub://schema resource if your client supports MCP resources — this tool provides the same data for clients that don't.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNoKind to get detail for. Omit to list all available kinds.
branchNoBranch to query. Defaults to the default branch.
expandNoInline one level of each relationship's peer schema. Defaults to the server's INFRAHUB_MCP_SCHEMA_EXPAND_PEERS setting when omitted.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With only readOnlyHint=true in annotations, the description carries real behavioral weight: it explains the two output modes (catalog vs. per-kind detail with attributes, relationships, and get_nodes filter keys), flags TOON encoding for token efficiency, and documents that expand inlines one peer-schema level subject to a server default. That is far beyond what the annotation declares.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and the 'call this first' rule, then behavior, then the resource alternative. Every sentence does work; the parenthetical and TOON note are informative rather than filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description must explain return values — and it does, distinguishing the two response shapes and their encoding. For a zero-required-parameter discovery tool, nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds output-level meaning: omitting kind yields the full kind catalog while supplying it yields attributes/relationships/filter keys, and expand's effect is restated in terms of relationship inlining. The added value is real but partially overlaps the schema's own parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Discover available schema kinds') and immediately scopes it against siblings: it's the thing you call to learn kinds and filter keys that get_nodes consumes. An agent can distinguish it from get_nodes/query_graphql without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit routing guidance: 'call this first when you don't know what kinds or filters exist', plus a named alternative for capable clients (the infrahub://schema resource) with the condition that selects the tool instead. Both when-to-use and when-not are covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_session_infoGet Session InfoA
Read-only

Return the current MCP session state — call before writes to know which branch they target.

Reports the active session branch (if any) and the Infrahub instance address. A session branch is lazily auto-created on the first write tool call (node_upsert / node_delete / mutate_graphql) and is named mcp/session-YYYYMMDD-<hex>. Before that first write, session_branch is None and all read tools target the default branch.

Typical uses:

  • Confirm which branch a proposed change would merge from.

  • Decide whether a write is about to open a new session branch.

  • Display the active branch to the user.

Returns: Dict with session_branch (str or null), infrahub_address, and has_session_branch.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint=true; the description goes well beyond that by disclosing lazy session-branch auto-creation on the first write, the exact branch naming pattern (mcp/session-YYYYMMDD-<hex>), and the pre-write state where session_branch is None and reads target the default branch.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the key action and precondition, then a Returns block; every sentence earns its place, but there is mild redundancy between the prose paragraph and the bullet list restating when the session branch is vs. isn't active.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description compensates by naming the three returned keys (session_branch, infrahub_address, has_session_branch) and explaining their possible values. An agent has everything needed to call it and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes no parameters, so the baseline is high; the description correctly supplies no parameter discussion. The 'Returns:' block shifts useful semantics to the result, though that is not a parameter concern.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (return the current MCP session state) and immediately scopes it against the write tools that trigger branch creation. It is clearly distinguishable from siblings like reset_session_branch, which mutates that same state.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit precondition ('call before writes to know which branch they target') plus a bulleted list of concrete use cases, and explains the lazy-creation timing that determines when the answer matters. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mutate_graphqlMutate GraphqlA
Destructive

Execute a GraphQL mutation against Infrahub — use only for complex writes that typed tools can't express.

Prefer node_upsert (create/update scalar attributes) or node_delete (remove a node) for straightforward changes; they validate against the schema and produce clearer audit entries. Reach for mutate_graphql when you need relationship edits, bulk operations, or any mutation shape not covered by the typed tools. For reads, use query_graphql.

The mutation always runs on the active session branch (auto-created on the first write of the session, mcp/session-YYYYMMDD-<hex>). There is no branch override — writes are isolated to the session, and changes reach the default branch only through propose_changes and human review. To target a different branch deliberately, switch the session with reset_session_branch first. Branch- and schema-management mutations are rejected.

To discover available kinds and their attributes, read the infrahub://schema resource or call the get_schema tool. For the full GraphQL SDL, read infrahub://graphql-schema.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesGraphQL mutation to execute on the active session branch.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: explains writes run on the auto-created session branch (mcp/session-YYYYMMDD-<hex>), that there is no branch override, that changes only reach the default branch via propose_changes plus human review, and that branch- and schema-management mutations are rejected. This is exactly the mutation-safety context an agent needs and that destructiveHint alone cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads purpose, then alternatives, then the branching model, then discovery resources — a logical order with little filler. It is on the long side and the discovery pointers to infrahub://schema and infrahub://graphql-schema could arguably be trimmed, but each block carries actionable content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter mutation tool with no output schema and annotations covering only the safety profile, the description supplies the missing operational model: branch isolation, promotion path, rejection rules, and how to discover valid mutation shapes. Nothing an agent needs to call this correctly is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single query parameter is already documented as targeting the active session branch, so the baseline is 3. The description adds real semantic constraints on what may be placed in that string — relationship edits, bulk ops, and no branch/schema-management mutations — which meaningfully narrows valid inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (execute a GraphQL mutation) and resource (Infrahub), and immediately scopes it as the escape hatch for complex writes typed tools cannot express. It names the siblings it is not (node_upsert, node_delete, query_graphql), so the agent can route without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use (relationship edits, bulk operations, uncovered mutation shapes), when-not-to (straightforward create/update/delete), and the exact alternatives for each case, plus a redirect to query_graphql for reads. Includes a prerequisite path (reset_session_branch) for targeting another branch.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

node_deleteNode DeleteA
Destructive

Delete a node in Infrahub on the active session branch.

The deletion is applied to the session branch only and is not visible on the default branch until a proposed change is merged. To discover available kinds, read the infrahub://schema resource. If your client does not support MCP resources, call the get_schema tool instead.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoUUID of the node to delete.
hfidNoHuman-friendly ID of the node to delete, as a list of string segments.
kindYesKind of the node to delete. Check infrahub://schema.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, readOnlyHint=false and idempotentHint=false, so the safety profile is covered. The description adds genuinely useful context beyond that: the mutation is branch-scoped and therefore not immediately propagated, which tells the agent the operation is contained and recoverable via the proposed-change flow.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, followed by the branch-visibility caveat and a compact fallback instruction for clients without resource support. Each sentence earns its place; only slight redundancy between the resource mention in the description and the schema's kind note.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 3-parameter destructive tool with no output schema, the description covers the essential branch semantics, the schema location for valid kinds, and a non-resource fallback. It is complete enough to call correctly, though it omits what a successful deletion returns or how errors surface.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents id, hfid and kind. The description only reinforces kind discovery via infrahub://schema / get_schema and adds no syntax or selection guidance for id vs hfid beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Delete a node in Infrahub') with a clear scope qualifier (active session branch). It does not explicitly contrast itself with the closest sibling node_upsert, but the verb makes the distinction inferable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear operational context: deletion affects the session branch only and is not visible on the default branch until a proposed change is merged, plus routing advice for discovering valid kinds. It stops short of stating when to prefer this over node_upsert or alternate deletion paths.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

node_upsertNode UpsertA

Create or update a node in Infrahub on the active session branch.

The session branch is auto-created on the first write of the session (mcp/session-YYYYMMDD-<hex>). Use propose_changes to open a review once your changes are ready. To discover available kinds and attributes, read the infrahub://schema resource. If your client does not support MCP resources, call the get_schema tool instead.

  • Create: omit both id and hfid.

  • Update: supply either id or hfid to identify the target node.

Only scalar attribute fields are accepted in data. To set relationship fields, use mutate_graphql with an appropriate GraphQL mutation.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoUUID of an existing node to update. Omit to create a new node.
dataYesFlat {attribute: value} map. See infrahub://schema/{kind} for valid names. Scalar attributes only; use mutate_graphql for relationships.
hfidNoHuman-friendly ID of an existing node to update, as a list of string segments. Omit to create a new node.
kindYesKind of the node to create or update. Check infrahub://schema.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false, idempotentHint=false, destructiveHint=false, so the write/non-destructive profile is already structured. The description adds real contextual behavior beyond that: a session branch is auto-created on the first write with a concrete naming pattern, and changes require propose_changes to enter review. It does not describe error/validation behavior or what the call returns, so it falls short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core verb and scope, then usage flow, then discovery, then the two create/update bullets. Bullets and code spans make it scannable, and every sentence carries operational information – no filler or restatement of the name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no output schema, the description covers the essentials: write target, session branch semantics, create vs update identification, and the escape hatch to mutate_graphql. It still omits the shape of the success response and failure modes (e.g., schema validation errors, id/hfid both supplied), leaving a small gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the schema already documents id, hfid, data and kind individually. The description still adds meaning beyond the schema by framing id and hfid as mutually alternative identifiers for update (the schema documents each in isolation but not the either/or relationship) and by reinforcing the scalar-only constraint on data.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence gives a specific verb (create or update) and resource (node in Infrahub), and immediately localizes the operation to the active session branch. It further distinguishes the two modes and names the sibling (mutate_graphql) reserved for relationship fields, so an agent can separate this from query_graphql/mutate_graphql without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit decision rules are provided: omit id and hfid to create, supply either to update. It also routes to alternatives with conditions – propose_changes once changes are ready, mutate_graphql for relationships, and the infrahub://schema resource or get_schema tool for discovery. Nothing about when/when-not is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

propose_changesPropose ChangesA

Open a proposed change (pull request) from the active session branch to the default branch.

Creates a CoreProposedChange in Infrahub so a human can review, approve, and merge the changes made during this session. The session branch remains active after calling this — you can continue making changes.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYesTitle for the proposed change (equivalent to a PR title).
descriptionNoOptional description explaining the motivation for the changes.
destination_branchNoBranch to merge into. Defaults to the instance's default branch (resolved automatically). Override only when merging into a non-default branch.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare a non-read-only, non-idempotent, non-destructive mutation. The description adds real value beyond them: it names the created entity (CoreProposedChange), explains that human review/approval/merge is required, and clarifies that the session branch remains active so work can continue. It does not state whether calling twice produces duplicate proposals, which the idempotentHint=false implies.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the action and branch semantics. The second and third sentences add distinct, non-redundant value (what object is created and that the session branch survives), so nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation with no output schema, the description covers the action, the side effect on the session branch, and the human-review workflow. It does not say what the call returns (e.g., an identifier for the new proposed change), which is the one remaining gap given there is no output schema to fall back on.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so title, description, and destination_branch are already fully documented in the schema, including the default-branch resolution behavior. The description adds no parameter detail beyond what the structured fields provide, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a precise verb and resource: 'Open a proposed change (pull request) from the active session branch to the default branch.' This is unmistakably different in function from siblings like reset_session_branch or node_upsert. It stops short of explicitly naming an alternative, but the operation is unique enough that sibling confusion is unlikely.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: 'so a human can review, approve, and merge the changes made during this session' tells the agent this is the wrap-up step for a work session. There is no explicit when-not guidance (e.g., what to do instead of a proposal, or when the session branch should be discarded via reset_session_branch).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

query_graphqlQuery GraphqlA
Read-only

Execute a read-only GraphQL query against Infrahub — use for reads only, never mutations.

Mutations are rejected at the AST level: use mutate_graphql instead (available when write mode is enabled). For simple attribute reads, prefer get_nodes / search_nodes — use GraphQL only when you need relationship traversal, aggregation, or fields not exposed by the typed tools.

To discover available kinds and their attributes, read the infrahub://schema resource. If your client does not support MCP resources, call the get_schema tool instead. For the full GraphQL SDL, read infrahub://graphql-schema.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesGraphQL query string. Only queries are allowed — use mutate_graphql for mutations.
branchNoBranch to execute the query against. Defaults to None (uses default branch).

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial behavioral context beyond the readOnlyHint annotation: mutations are rejected at the AST level, and mutate_graphql is availability-gated by write mode. However, it does not describe error behavior, query complexity/pagination limits, or auth/permission requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well front-loaded: the read-only constraint leads, followed by the mutation routing, typed-tool preference, and schema-discovery paths. Slightly more content than a minimal tool needs, but each sentence carries routing or behavioral value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete enough to call correctly: read-only scope, mutation rejection, alternative tools, and two schema-discovery paths are all covered. It omits return-shape and error/pagination behavior, though the absence of an output schema slightly raises the expected burden.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both parameters, including that only queries are allowed and branch defaults to the default branch. The description adds no syntax or format guidance beyond the schema, which is the correct baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource ('Execute a read-only GraphQL query against Infrahub') with an explicit scope constraint (reads only, never mutations). It clearly distinguishes itself from mutate_graphql and from the typed read tools (get_nodes/search_nodes).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use: reads only, never mutations (use mutate_graphql instead). Also names alternatives and the condition that selects them: prefer get_nodes/search_nodes for simple attribute reads, use GraphQL only when relationship traversal, aggregation, or unexposed fields are needed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

reset_session_branchReset Session BranchA

Reset or switch the active session branch for the current MCP session.

Use this to recover or take control of which branch your writes target:

  • No branch — clears the cached session branch; the next write auto-creates a fresh one. Useful after you have merged your work and want to start a new change set.

  • With branch — points this session at the named branch. If it does not exist and the name matches the configured branch pattern, it is created and reported. The instance default branch and merged/read-only branches are rejected.

Note: a merged or deleted session branch is recovered automatically on the next write — this tool is the explicit override on top of that.

Affects only the calling session; other sessions are unaffected.

ParametersJSON Schema
NameRequiredDescriptionDefault
branchNoTarget branch. Omit to drop the cached session branch so the next write creates a fresh one. Provide a name to switch this session to that branch (created if it does not exist and the name matches the configured pattern).

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false, idempotentHint=false, destructiveHint=false, and the description adds real behavior beyond them: auto-creation when the name matches the configured pattern, rejection of the instance default and merged/read-only branches, and session-local scope. It stops short of stating what happens to a branch left dangling or whether the switch is transactional, so a 4 rather than 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then cleanly split into the two argument modes and a clarification note about automatic recovery. No sentence is filler; the bullets map one-to-one onto the decisions an agent must make.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single optional-parameter mutator with no output schema and full annotation coverage, the description closes every gap an agent needs: scope, side effects, fallback behavior, and the automatic-recovery baseline against which the tool is an override.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds semantics not in the schema: the rejection rule for the default/merged/read-only branches and the report-back behavior on creation. The omit-vs-provide distinction is well covered in both places.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (reset/switch) and resource (active session branch for the current MCP session), with the scope delimited up front. No sibling tool touches session-branch state, so it is trivially distinguishable from query_graphql, node_upsert, and the rest.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says when to use it (recover or take control of write targets, or start a new change set after merging) and, unusually, when it is NOT needed — automatic recovery on the next write — so the agent knows this is the explicit override. Both argument modes are given matching conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_nodesSearch NodesA
Read-only

Find nodes of a specific kind by partial substring — use when you only know part of a value.

Matches the query as a substring against all attributes of the kind via Infrahub's any__value filter with partial_match=True. Works uniformly on concrete kinds (e.g. LocationSite) and abstract/generic kinds (e.g. CoreNode) — agents can ping any kind without first checking whether it has a name attribute.

For a filter on one specific attribute (or combining multiple filters), use get_nodes with an explicit filters dict instead.

Each result is labelled with the node's display_label when present, falling back to its HFID (kind-prefixed) and finally its UUID — so generic-kind results that lack a display_label still return a human-readable identifier rather than a bare UUID.

To discover available kinds, read the infrahub://schema resource. If your client does not support MCP resources, call the get_schema tool instead.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindYesKind to search within. Check infrahub://schema for valid kinds.
limitNoMaximum number of results to return.
queryYesPartial substring matched across all attributes of the kind via Infrahub's ``any__value`` filter with ``partial_match=True``. Works for both concrete kinds (e.g. ``LocationSite``) and abstract/generic kinds (e.g. ``CoreNode``).
branchNoBranch to query. Defaults to the default branch.

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

readOnlyHint=true already establishes this is a safe read, and the description goes beyond that by explaining the any__value partial_match mechanism, uniform behavior across concrete vs abstract kinds, and the display_label/HFID/UUID labelling fallback for results. That is genuine behavioral context, though no pagination or result-count semantics are disclosed. Given annotations already cover the safety profile, a 3 reflects solid added value without full behavioral coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core discriminator in the first sentence, then adds matching semantics, the alternative, and the result-labelling behavior. Slightly long, and the display_label/FHID/UUID explanation is verbose, but each paragraph carries information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only search tool with no output schema, the description compensates by explaining what results look like (labelled with display_label/HFID/UUID) and how to discover valid kinds. Combined with the explicit alternative routing, an agent has everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so query, kind, limit, and branch are all documented in the schema. The description restates the query substring semantics and concrete/abstract behavior but adds no new syntax, format, or defaulting detail beyond what the schema provides. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource plus the discriminating condition ('partial substring — use when you only know part of a value'). It explicitly separates itself from the sibling get_nodes, so an agent can route correctly without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

States when to use it (partial value, any kind), when not to (a filter on one specific attribute or multiple filters), and names the alternative (get_nodes with explicit filters dict). It also adds a kind-discovery path via infrahub://schema or get_schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 12 tool updatesv1.2.0
    • Changedfind_paths1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "type": "object",
        -  "x-fastmcp-wrap-result": true
        -}New value: +null
    • Changedfind_reachable1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "type": "object",
        -  "x-fastmcp-wrap-result": true
        -}New value: +null
    • Changedget_nodes1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}New value: +null
    • Changedget_schema1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "type": "object",
        -  "x-fastmcp-wrap-result": true
        -}New value: +null
    • Changedget_session_info1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}New value: +null
    • Changedmutate_graphql1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}New value: +null
    • Changednode_delete1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}New value: +null
    • Changednode_upsert1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}New value: +null
    • Changedpropose_changes1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}New value: +null
    • Changedquery_graphql1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}New value: +null
    • Changedreset_session_branch1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}New value: +null
    • Changedsearch_nodes1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "items": {
        -        "type": "string"
        -      },
        -      "type": "array"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "type": "object",
        -  "x-fastmcp-wrap-result": true
        -}New value: +null
  2. 3 tool updatesv1.1.7
    • Addedfind_paths
    • Addedfind_reachable
    • Changedget_schema1 field changed
      • addedInput schema / properties / expand
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "boolean"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Inline one level of each relationship's peer schema. Defaults to the server's INFRAHUB_MCP_SCHEMA_EXPAND_PEERS setting when omitted."
        +}
  3. 3 tool updatesv1.1.6
    • Changedmutate_graphql2 fields changed
      • removedInput schema / properties / branch
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "description": "Branch to execute the mutation against. Defaults to the auto-created session branch (recommended). Override only when targeting a specific non-default branch."
        -}
      • changedInput schema / properties / query / description
        Previous value: -"GraphQL mutation to execute."New value: +"GraphQL mutation to execute on the active session branch."
    • Addedreset_session_branch
    • Changedsearch_nodes1 field changed
      • changedInput schema / properties / query / description
        Previous value: -"Partial name/label to search for. Matched against the 'name' attribute of each node."New value: +"Partial substring matched across all attributes of the kind via Infrahub's ``any__value`` filter with ``partial_match=True``. Works for both concrete kinds (e.g. ``LocationSite``) and abstract/generic kinds (e.g. ``CoreNode``)."
  4. 9 tool updatesv1.1.5
    • First observedget_nodes
    • First observedget_schema
    • First observedget_session_info
    • First observedmutate_graphql
    • First observednode_delete
    • First observednode_upsert
    • First observedpropose_changes
    • First observedquery_graphql
    • First observedsearch_nodes

TDQS

A4.3/5.0

Scored across 12 tools

Disambiguation5/5

Each tool targets a clearly distinct action or resource: reads (get_nodes, search_nodes, query_graphql), graph analysis (find_paths, find_reachable), writes (node_upsert, node_delete, mutate_graphql), schema discovery (get_schema), and session/branch workflow (get_session_info, reset_session_branch, propose_changes). Descriptions explicitly clarify boundaries, such as when to prefer get_nodes/search_nodes over query_graphql and when to use node_upsert versus mutate_graphql.

Naming Consistency4/5

Most tools follow a snake_case verb_noun pattern (query_graphql, get_nodes, search_nodes, find_paths, propose_changes, reset_session_branch). A few deviate with noun_verb ordering (node_upsert, node_delete) and a slightly shortened form (find_reachable), but the overall naming remains predictable and readable.

Tool Count5/5

The 12 tools are well-scoped for a graph data platform that requires reads, writes, traversal, schema discovery, and branch/session management. Each tool has a clear role, and the set avoids both thinness and bloat.

Completeness4/5

Core lifecycle operations are covered: schema discovery, typed and GraphQL reads, graph traversal, node upsert/delete, complex mutations, session branch switching, and proposing changes. Minor gaps exist around the proposed-change lifecycle after creation, such as listing, inspecting, merging, or closing proposed changes.

Maintenance

ActivityActive
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to interact with GitHub repositories, issues, pull requests, and content via the Model Context Protocol.
    1
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI assistants to manage Prismatic integrations, components, and flows via the Model Context Protocol, supporting code-native integration development and component lifecycle.
    122 npm
    26
    MIT