Skip to main content
Glama

Oxidized MCP Server

Let AI agents search, compare and back up network device configs stored in Oxidized

PyPI Python License

Pre-commit Checks Docker MCP Registry

Installation ยท Tools ยท Configuration ยท Security

Oxidized MCP Server is a Python-based Model Context Protocol (MCP) server that gives AI assistants access to Oxidized, the network device configuration backup tool. It talks to the oxidized-web REST API to list devices, check backup health, read and search device configurations, browse and diff configuration history, and queue backups. It supports read-only mode, tag-based tool filtering, and bearer token authentication for HTTP transports.

โœจ Features

Core Features

  • List and filter managed devices by group, model and last backup status

  • Find devices by partial name, full name (group/name) or IP address

  • Summarise backup health: failures, devices never backed up and stale backups

  • Read the latest backed-up configuration of any device, paged for large configs

  • Search all configurations for a regular expression or literal text, with matching lines and context

Configuration History

  • List the stored configuration versions of a device (git output)

  • Read a device's configuration as it was at any version (full oid or short prefix)

  • Diff two versions, or just see the most recent change, as a unified diff

Operations

  • Queue an immediate backup of a device, optionally with a commit message and author

  • Reload the node list from its source (router.db, SQL, HTTP, ...)

  • Read-only mode hides every operation for safe monitoring

Advanced Capabilities

  • Node vars (often device credentials) are redacted in tool output by default

  • HTTP Basic auth for oxidized-web behind a reverse proxy

  • Rate limiting, SSL/TLS verification and configurable timeouts

  • Tag-based tool filtering and an optional tool-search transform

  • Bearer token authentication for HTTP transports

Related MCP server: network-mcp-server

๐Ÿš€ Installation

Prerequisites

  • Python 3.11 to 3.15

  • A running Oxidized instance with oxidized-web enabled

  • For version history and diffs: the Oxidized git (or gitcrypt) output

Quick Install from PyPI

The easiest way to get started is to install from PyPI:

# Using UV (recommended)
uvx oxidized-mcp

# Or using pip
pip install oxidized-mcp

Remember to configure the environment variables for your Oxidized instance before running the server:

# Create environment configuration
export OXIDIZED_URL=http://localhost:8888

For more details, visit: https://pypi.org/project/oxidized-mcp/

Install from Source

  1. Clone the repository:

git clone https://github.com/mhajder/oxidized-mcp.git
cd oxidized-mcp
  1. Install dependencies:

# Using UV (recommended)
uv sync

# Or using pip
pip install -e .
  1. Configure environment variables:

cp .env.example .env
# Edit .env with your Oxidized URL (and Basic auth credentials if needed)
  1. Run the server:

# Using UV (recommended)
uv run oxidized-mcp

# Or using the installed command directly
oxidized-mcp

Development Setup

For development with additional tools:

# Clone and install with development dependencies
git clone https://github.com/mhajder/oxidized-mcp.git
cd oxidized-mcp
uv sync --group dev

# Run tests
uv run pytest

# Run with coverage
uv run pytest --cov=src/

# Run linting and formatting
uv run ruff check .
uv run ruff format .

# Run type checking
uv run ty check .

# Setup prek hooks
uv run prek install

๐Ÿ”ง Configuration

Environment Variables

# Oxidized Connection Details
# Base URL of oxidized-web (include the url_prefix if one is configured).
# A query string (?...) is rejected; use the Basic auth settings below, or
# percent-encode special characters in credentials put in the URL.
OXIDIZED_URL=http://localhost:8888

# Optional HTTP Basic auth, e.g. for a reverse proxy in front of oxidized-web
# OXIDIZED_USERNAME=
# OXIDIZED_PASSWORD=

# SSL Configuration
OXIDIZED_VERIFY_SSL=true
OXIDIZED_TIMEOUT=30
# Timeout for search_configs (oxidized-web reads every configuration)
OXIDIZED_SEARCH_TIMEOUT=300

# Redact node vars (often device credentials) in tool output
OXIDIZED_REDACT_NODE_VARS=true

# Read-Only Mode
# Set READ_ONLY_MODE true to disable operations (trigger_node_backup, reload_nodes)
READ_ONLY_MODE=false

# Disabled Tags
# Comma-separated list of tags to disable tools for (empty by default)
# Example: OXIDIZED_DISABLED_TAGS=search,diff
OXIDIZED_DISABLED_TAGS=

# Logging Configuration
LOG_LEVEL=INFO

# Rate Limiting (requests per minute)
# Set RATE_LIMIT_ENABLED true to enable rate limiting
RATE_LIMIT_ENABLED=false
RATE_LIMIT_MAX_REQUESTS=60
RATE_LIMIT_WINDOW_MINUTES=1

# Tool Search Transform (Optional)
# Set TOOL_SEARCH_ENABLED true to replace full tool listings with search_tools + call_tool
TOOL_SEARCH_ENABLED=false
# Search strategy: bm25 (natural language) or regex (pattern match)
TOOL_SEARCH_STRATEGY=bm25
# Maximum number of tools returned by search_tools
TOOL_SEARCH_MAX_RESULTS=5

# Sentry Error Tracking (Optional)
# Set SENTRY_DSN to enable error tracking and performance monitoring
# SENTRY_DSN=https://your-key@o12345.ingest.us.sentry.io/6789
# Optional Sentry configuration
# SENTRY_TRACES_SAMPLE_RATE=1.0
# SENTRY_SEND_DEFAULT_PII=false
# SENTRY_ENVIRONMENT=production
# SENTRY_RELEASE=1.2.3
# SENTRY_PROFILE_SESSION_SAMPLE_RATE=1.0
# SENTRY_PROFILE_LIFECYCLE=trace
# SENTRY_ENABLE_LOGS=true

# MCP Transport Configuration
# Transport type: 'stdio' (default), 'sse' (Server-Sent Events), or 'http' (HTTP Streamable)
# 'streamable-http' is accepted as an alias for 'http'. Any other value stops
# the server at startup.
# MCP_TRANSPORT=stdio

# HTTP Transport Settings (used when MCP_TRANSPORT=sse or MCP_TRANSPORT=http)
# Host to bind the HTTP server (default: 127.0.0.1)
# MCP_HTTP_HOST=127.0.0.1
# Port to bind the HTTP server (default: 8000)
# MCP_HTTP_PORT=8000
# Optional bearer token for authentication (leave empty for no auth)
# MCP_HTTP_BEARER_TOKEN=

Sentry Error Tracking & Monitoring (Optional)

The server optionally supports Sentry for error tracking, performance monitoring, and debugging. Sentry integration is completely optional and only initialized if configured.

Installation

To enable Sentry monitoring, install the optional dependency:

# Using UV (recommended)
uv sync --extra sentry

Configuration

Enable Sentry by setting the SENTRY_DSN environment variable in your .env file:

# Required: Sentry DSN for your project
SENTRY_DSN=https://your-key@o12345.ingest.us.sentry.io/6789

# Optional: Performance monitoring sample rate (0.0-1.0, default: 1.0)
SENTRY_TRACES_SAMPLE_RATE=1.0

# Optional: Include personally identifiable information (default: false).
# Keep it off: with the MCP integration it records tool results, which are
# full device configurations including secrets.
SENTRY_SEND_DEFAULT_PII=false

# Optional: Environment name (e.g., "production", "staging")
SENTRY_ENVIRONMENT=production

# Optional: Release version (auto-detected from package if not set)
SENTRY_RELEASE=1.2.2

# Optional: Profiling - continuous profiling sample rate (0.0-1.0, default: 1.0)
SENTRY_PROFILE_SESSION_SAMPLE_RATE=1.0

# Optional: Profiling - lifecycle mode for profiling (default: "trace")
# Options: "all", "continuation", "trace"
SENTRY_PROFILE_LIFECYCLE=trace

# Optional: Enable log capture as breadcrumbs and events (default: true)
SENTRY_ENABLE_LOGS=true

Features

When enabled, Sentry automatically captures:

  • Exceptions & Errors: All unhandled exceptions with full context

  • Performance Metrics: Request/response times and traces

  • MCP Integration: Detailed MCP server activity and interactions

  • Logs & Breadcrumbs: Application logs and event trails for debugging

  • Context Data: Environment, client info, and request parameters

Getting a Sentry DSN

  1. Create a free account at sentry.io

  2. Create a new Python project

  3. Copy your DSN from the project settings

  4. Set it in your .env file

Disabling Sentry

Sentry is completely optional. If you don't set SENTRY_DSN, the server will run normally without any Sentry integration, and no monitoring data will be collected.

๐Ÿงฐ Available Tools

Node Tools

  • list_nodes: List devices with optional filters (group, model, last run status, name/IP substring) and paging; group/model are filtered by Oxidized itself (/nodes/<group|model>/<value>.json), so large inventories are not transferred in full

  • get_node: Get a single device's details and last backup run (accepts name or IP)

  • find_nodes: Find devices by partial name, full name or IP, exact matches first

  • get_backup_stats: Backup health summary - counts per status, group and model, success rate, failed / never backed up / stale devices; optionally for a single group or model

Configuration Tools

  • get_node_config: Get the latest backed-up configuration of a device (by name or IP), paged by lines (offset / max_lines)

  • search_configs: Search all configurations for a regex or literal text; returns matching lines with line numbers and optional context

Version History Tools

Require the Oxidized git or gitcrypt output.

  • list_node_versions: List stored configuration versions (oid, date, author, message), newest first

  • get_node_version: Get the configuration at a given version (full oid or unique prefix), paged by lines

  • diff_node_versions: Unified diff between two versions; defaults to the most recent change

Operation Tools

Hidden when READ_ONLY_MODE=true.

  • trigger_node_backup: Queue an immediate backup of a device, optionally recording a commit message and author

  • reload_nodes: Reload the whole node list from its source (a per-node reload is deliberately not offered: oxidized-web's /reload?node=X replaces the entire in-memory node list with the matching nodes)

๐Ÿ”’ Security & Safety Features

Read-Only Mode

The server supports a read-only mode that disables all write operations for safe monitoring:

READ_ONLY_MODE=true

When enabled, only tools tagged read-only are exposed: trigger_node_backup and reload_nodes are hidden, while every node, configuration and history tool stays available.

Tag-Based Tool Filtering

You can disable specific categories of tools by setting disabled tags:

OXIDIZED_DISABLED_TAGS=search,diff

Available tags include:

  • node - Node listing and lookup tools (and the backup/reload operations)

  • stats - Backup health statistics

  • config - Configuration read tools

  • search - Configuration search and node search tools

  • version - Version history tools

  • diff - Version diff tool

  • backup - Backup trigger operation

  • reload - Node list reload operation

  • read-only - Every tool that does not change Oxidized state

Rate Limiting

The server supports rate limiting to control API usage and prevent abuse. If enabled, requests are limited per client using a sliding window algorithm.

Enable rate limiting by setting the following environment variables in your .env file:

RATE_LIMIT_ENABLED=true
RATE_LIMIT_MAX_REQUESTS=60    # Maximum requests allowed per window
RATE_LIMIT_WINDOW_MINUTES=1   # Window size in minutes

If RATE_LIMIT_ENABLED is set to true, the server will apply rate limiting middleware. Adjust RATE_LIMIT_MAX_REQUESTS and RATE_LIMIT_WINDOW_MINUTES as needed for your environment. Both must be at least 1 when rate limiting is on; while it is off they are not read.

Tool Search for Large Toolsets

FastMCP tool search can reduce prompt size for servers with many tools. When enabled, list_tools returns two synthetic tools:

  • search_tools: Finds matching tools and returns their full schemas

  • call_tool: Executes any discovered tool by name

Enable it with:

TOOL_SEARCH_ENABLED=true
TOOL_SEARCH_STRATEGY=bm25      # bm25 or regex
TOOL_SEARCH_MAX_RESULTS=8      # optional, default is 5

bm25 supports natural language queries, while regex uses a regex pattern input for deterministic matching. With tool search enabled, any other TOOL_SEARCH_STRATEGY value stops the server at startup, and TOOL_SEARCH_MAX_RESULTS must be at least 1.

Tool search respects existing visibility controls (read-only mode and disabled tags).

SSL/TLS Configuration

The server supports SSL certificate verification and custom timeout settings:

OXIDIZED_VERIFY_SSL=true    # Enable SSL certificate verification
OXIDIZED_TIMEOUT=30         # Request timeout in seconds

Upstream Authentication

oxidized-web has no authentication of its own and is usually published behind a reverse proxy with HTTP Basic auth. Set both variables to send Basic auth with every request:

OXIDIZED_USERNAME=oxidized
OXIDIZED_PASSWORD=your-password

Node Vars Redaction

Node vars from the Oxidized source (router.db, SQL, HTTP) often contain per-device credentials, and oxidized-web returns them unredacted from /nodes.json. The server replaces every var value with <redacted> (keeping the keys) unless you opt out:

OXIDIZED_REDACT_NODE_VARS=false

Transport Configuration

The server supports multiple transport protocols for different deployment scenarios:

STDIO Transport (Default)

The default transport uses standard input/output for communication. This is ideal for local usage and integration with tools that communicate via stdin/stdout:

MCP_TRANSPORT=stdio

HTTP SSE Transport (Server-Sent Events)

For network-based deployments, you can use HTTP with Server-Sent Events. This allows the MCP server to be accessed over HTTP with real-time streaming:

MCP_TRANSPORT=sse
MCP_HTTP_HOST=127.0.0.1        # Localhost
MCP_HTTP_PORT=8000           # Port to listen on
MCP_HTTP_BEARER_TOKEN=your-secret-token  # Optional authentication token

When using SSE transport with a bearer token, clients must include the token in their requests:

curl -H "Authorization: Bearer your-secret-token" http://localhost:8000/sse

HTTP Streamable Transport

The HTTP Streamable transport provides HTTP-based communication with request/response streaming. This is ideal for web integrations and tools that need HTTP endpoints:

MCP_TRANSPORT=http
MCP_HTTP_HOST=127.0.0.1        # Localhost
MCP_HTTP_PORT=8000           # Port to listen on
MCP_HTTP_BEARER_TOKEN=your-secret-token  # Optional authentication token

When using streamable transport with a bearer token:

curl -H "Authorization: Bearer your-secret-token" \
     -H "Accept: application/json, text/event-stream" \
     -H "Content-Type: application/json" \
     -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
     http://localhost:8000/mcp

Note: The HTTP transport requires proper JSON-RPC formatting with jsonrpc and id fields. The server may also require session initialization for some operations.

Health Endpoint

Both HTTP transports (sse and http) serve GET /health, which answers 200 ok when the server is handling requests. It needs no bearer token and does not contact Oxidized, so an Oxidized outage does not mark the MCP server unhealthy. The Docker image's HEALTHCHECK uses it:

curl http://localhost:8000/health

๐Ÿ“ Oxidized Notes

  • Version history (list_node_versions, get_node_version, diff_node_versions) needs the git or gitcrypt output. With the file output Oxidized reports no versions.

  • Groups: node names should be unique. Tools accept an optional group to disambiguate; get_node_config and the history tools look the group up automatically when it is omitted (with the git output's single_repo the group is part of the stored path, so it is required by oxidized-web). Nodes without a group are shown as group default, and passing default back is treated as "no group". search_configs filters groups the same way as list_nodes (exact match). trigger_node_backup takes no group because Oxidized queues backups by node name or IP only.

  • Filtering large inventories: group and model in list_nodes / get_backup_stats are filtered by Oxidized itself. The group must match exactly (case-sensitive, as shown by list_nodes), so a misspelt group returns nothing instead of downloading the whole inventory. Built-in model names are case-insensitive (ios and the IOSXE alias are sent as IOS, from a catalog of Oxidized's models); custom models must be spelled exactly. Neither filter ever falls back to downloading the whole inventory.

  • Search runs in two steps: oxidized-web's conf_search finds matching devices (it reads every configuration server-side, so it can be slow on large installations), then only those configurations are fetched to extract matching lines. max_nodes caps the fetches; nodes that were never backed up (whose placeholder text can match) are skipped without counting. The server-side step uses OXIDIZED_SEARCH_TIMEOUT (default 300 s) instead of OXIDIZED_TIMEOUT. Patterns run as Ruby regexps on the server and Python regexps locally, line by line, so stick to common syntax.

  • Backups are asynchronous: trigger_node_backup moves the device to the head of the queue. Check get_node for the result.

  • Errors: oxidized-web answers unknown node names with HTTP 500. When it runs with RACK_ENV=production the reason is hidden, so a 500 on a node route is reported with a hint that it may be an unknown node name.

๐Ÿณ Using Docker

A Docker image is available on GitHub Packages for easy deployment.

docker pull ghcr.io/mhajder/oxidized-mcp:latest

docker run --rm -p 8000:8000 \
  -e OXIDIZED_URL=http://oxidized:8888 \
  -e MCP_HTTP_BEARER_TOKEN=your-secret-token \
  ghcr.io/mhajder/oxidized-mcp:latest

The image defaults to the HTTP Streamable transport on port 8000 (http://localhost:8000/mcp).

๐Ÿค Contributing

Contributions are welcome. See CONTRIBUTING.md for the dev setup, checks and commit message format, and use the issue templates for bugs and feature requests.

Found a security problem? Please report it privately as described in SECURITY.md.

๐Ÿ“œ License

MIT License - see LICENSE for details.

Available Tools

11 tools
diff_node_versionsDiff Node VersionsA
Read-onlyIdempotent

Show what changed in a node's configuration between two versions.

Returns a unified diff from 'base_oid' (older) to 'oid' (newer). With no arguments besides the node it shows the most recent change.

NameRequiredDescriptionDefault
oidNoNewer version oid (full or prefix); defaults to the latest version
nodeYesNode name or IP address (e.g. 'core-sw01')
groupNoNode group; looked up automatically when omitted
offsetNoZero-based first diff line to return
base_oidNoOlder version oid to compare against; defaults to the version before 'oid'
max_linesNoMaximum diff lines to return (0 = whole diff)
context_linesNoUnchanged lines of context around each change

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

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

Annotations already declare readOnly/idempotent/non-destructive safety. The description adds meaningful context beyond that: the output is a unified diff and the default no-argument behavior surfaces the most recent change. It doesn't cover rate limits or auth, but the safety profile is already handled.

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?

Two sentences, front-loaded with the core purpose, then the diff direction and default behavior. No wasted words.

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?

An output schema exists, so return values need not be re-explained, and annotations cover the safety profile. The description supplies the diff direction and default behavior, leaving only sibling routing unstated.

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 all 7 parameters. The description reinforces the base_oidโ†’oid comparison direction, but adds little beyond what the schema fields already state. 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 (diff/show what changed) and resource (a node's configuration between two versions), and clarifies the return is a unified diff. An agent can distinguish this from get_node_version or list_node_versions, which do not compute differences.

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?

The description explains default behavior (no arguments shows the most recent change) but never states when to prefer this over siblings like get_node_version or list_node_versions. Usage is implied rather than explicit, with no exclusions.

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

find_nodesFind NodesA
Read-onlyIdempotent

Find nodes by partial name, full name or IP address.

Useful to resolve an ambiguous device name before calling other tools. Exact matches are listed first, then prefix matches, then other substring matches (all case-insensitive).

NameRequiredDescriptionDefault
limitNoMaximum nodes to return
queryYesPart of a node name, full name (group/name) or IP address

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnly and idempotent, so the description adds value by disclosing result ordering (exact, prefix, then substring) and case-insensitive matching. These are meaningful behavioral traits not visible in the schema or annotations.

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 with no filler. The core lookup behavior is first, the workflow use is second, and the ordering/case details close it out efficiently.

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 simple two-parameter read-only search tool with an output schema and full schema coverage, the description provides everything needed: what to search, why to use it, and how results are ordered. No critical gap remains.

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 coverage is 100%: both query and limit are documented there, including the full set of query forms (part of a name, full name, IP address). The description mostly restates the query semantics rather than adding new parameter-level detail.

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: 'Find nodes' by partial name, full name, or IP address. The phrase 'resolve an ambiguous device name before calling other tools' clearly distinguishes it from siblings like list_nodes or get_node.

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 context: use it to resolve ambiguous node names before invoking other tools. It does not explicitly name alternatives or give when-not-to-use guidance, but the intended placement in a workflow is clear.

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

get_backup_statsGet Backup StatsA
Read-onlyIdempotent

Summarise backup health across Oxidized nodes.

Computed from the node list (oxidized-web's own stats JSON is not usable): counts per last-run status, per group and per model, the success rate, and lists of failed nodes, nodes never backed up and stale nodes. Optionally limited to one group or model, filtered by Oxidized itself.

"Stale" means Oxidized has not attempted a backup within the threshold (e.g. it is not polling the node); nodes that are attempted but keep failing are listed under failed_nodes instead. Oxidized does not expose the time of the last successful backup, and its run history is kept in memory only (reset on restart). Right after trigger_node_backup a node briefly shows as never backed up, because Oxidized clears its last run while it is queued.

NameRequiredDescriptionDefault
groupNoOnly include nodes in this group (exact, case-sensitive name)
modelNoOnly include nodes of this Oxidized model (e.g. 'IOS')
max_listedNoMaximum nodes listed in each of the failed/never/stale lists
stale_hoursNoReport nodes whose last backup attempt (successful or not) is older than this many hours

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

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

The description adds significant context beyond the readOnly/idempotent annotations: it defines 'stale' precisely (last backup attempt, not success), explains that Oxidized does not expose last successful backup time, notes that run history is in-memory and resets on restart, and warns that a node may briefly show as never backed up right after trigger_node_backup. These are critical behavioral quirks an agent must know to interpret results correctly.

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?

The description is a bit long but every sentence carries useful information. It is front-loaded with the core summary, then explains the stale definition and important caveats. While it could be trimmed slightly, the length is justified by the need to convey data-source limitations and behavioral quirks. No wasted words.

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?

Given the tool's complexity (multiple optional filters, nuanced data-source limitations) and that an output schema exists, the description covers all essential context: data source, what counts are computed, the stale definition, and known edge cases (after trigger_node_backup). The output schema handles return format, so no need to describe it. An agent has everything needed to call it correctly and interpret results.

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 four parameters are fully documented in the schema. The description does not add parameter-specific details beyond what the schema provides; it only mentions 'optionally limited to one group or model' and clarifies the stale threshold concept, which is already in the schema. Baseline of 3 is appropriate since the schema does the heavy lifting.

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 description clearly states the tool's purpose: 'Summarise backup health across Oxidized nodes.' It specifies the exact resource (backup health across nodes) and the action (summarise). It also lists the specific outputs (counts, success rate, lists of failed/never/stale nodes), distinguishing it from sibling tools that handle node listing, config retrieval, or backup triggering.

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?

The description implicitly tells the agent when to use this tool: when backup health metrics are needed, explicitly noting that oxidized-web's own stats JSON is not usable. It does not name alternatives or give explicit when-not-to-use conditions, but the unique purpose among siblings makes the usage context clear. It also explains filtering by group/model, giving a sense of optionality.

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

get_nodeGet NodeA
Read-onlyIdempotent

Get details of a single Oxidized node.

Returns the node's name, full name, IP, group, model, vars and details of its last backup run (start, end, status, duration).

NameRequiredDescriptionDefault
nodeYesNode name or IP address (e.g. 'core-sw01')

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is clear. The description adds value by specifying the exact return fields (name, full name, IP, group, model, vars, last backup run details), which is useful behavioral context. However, it doesn't disclose potential errors (e.g., node not found) or any rate limits, but given the annotations, a 3 is appropriate.

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?

The description is two sentences with no waste. The first sentence states the core function, and the second lists the return fields. It is front-loaded and every sentence earns its place.

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?

Given the tool's simplicity (1 parameter, no nested objects, output schema present), the description is complete enough. It covers what the tool does and what it returns. The only minor gap is not mentioning error cases, but for a read-only single-node fetch, this is acceptable. The output schema likely covers return structure, so the description doesn't need to.

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 the 'node' parameter with an example. The description doesn't add much beyond what the schema provides, but it does mention that the node can be identified by name or IP, which aligns with the schema. Baseline 3 is correct since the schema does the heavy lifting.

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 description clearly states the tool's function: 'Get details of a single Oxidized node.' It specifies the resource (a single node) and the verb (get), and distinguishes it from siblings like list_nodes and find_nodes by focusing on a single node's details. The description also enumerates the returned fields, making the purpose unambiguous.

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?

The description implies usage for retrieving details of a single node, which is distinct from listing or searching nodes. It doesn't explicitly state when not to use it or name alternatives, but the context signals and sibling names provide enough clarity. The description could be improved by explicitly mentioning that this is for a single node, not a list, but the 'single' qualifier already does that.

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

get_node_configGet Node ConfigA
Read-onlyIdempotent

Get the latest backed-up configuration of a node.

Large configurations are paged by lines: when 'truncated' is true, call again with offset set to 'next_offset' to read the rest.

NameRequiredDescriptionDefault
nodeYesNode name or IP address (e.g. 'core-sw01')
groupNoNode group, to disambiguate nodes with the same name in different groups
offsetNoZero-based first line to return
max_linesNoMaximum lines to return (0 = whole configuration)

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior5/5

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

The description discloses a non-obvious pagination behavior: large configurations are paged by lines, and the caller must follow 'truncated' and 'next_offset' to fetch all data. This adds meaningful behavioral context beyond the readOnly/idempotent annotations and explains exactly how to handle partial results.

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?

Two short sentences: the first states the core purpose, the second gives the necessary paging detail. No wasted words and the most important behavioral information is front-loaded.

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?

Given the simple, read-only nature of the tool, the fully documented input schema, the output schema, and annotations, the description covers everything needed to invoke it correctly. The pagination caveat is the main non-obvious detail, and it is included.

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 parameters are already documented. The description adds value by clarifying how 'offset' interacts with 'truncated' and 'next_offset', giving the agent a fuller mental model of pagination than the schema alone provides.

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 clearly states the resource ('latest backed-up configuration of a node') and the action ('Get'), so an agent can understand what the tool returns. It does not explicitly distinguish itself from sibling tools like get_node or get_node_version, though the phrase 'backed-up configuration' narrows the scope.

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

Usage Guidelines2/5

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

The description gives no guidance on when to use this tool versus siblings such as get_node, list_node_versions, or get_node_version. The intended use case is only implied by the name and subject matter, with no exclusions or alternative routing.

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

get_node_versionGet Node VersionA
Read-onlyIdempotent

Get the configuration of a node as it was at a specific version.

Large configurations are paged by lines: when 'truncated' is true, call again with offset set to 'next_offset' to read the rest.

NameRequiredDescriptionDefault
oidYesVersion oid from list_node_versions (full or unique prefix)
nodeYesNode name or IP address (e.g. 'core-sw01')
groupNoNode group; looked up automatically when omitted
offsetNoZero-based first line to return
max_linesNoMaximum lines to return (0 = whole configuration)

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

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

Annotations already declare read-only and idempotent, so the description only needs to add operational behavior. It adds the paging mechanism (truncated/next_offset), which is critical for large configurations. It also clarifies that it returns a historical snapshot. No contradiction with annotations.

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?

Two sentences, each earning its place. The purpose is stated first, followed by a critical operational detail about pagination. No fluff.

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 historical retrieval tool with an output schema, the description covers the key operational caveat (pagination) and the purpose. It doesn't explain error conditions or version lookup specifics, but those are likely in the output schema or parameter descriptions. Given the complexity, it's adequate.

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 descriptions cover all parameters at 100%, so the baseline is 3. The description adds context about paging that relates to offset and max_lines, but doesn't add new semantic meaning to the parameters beyond what the schema already provides. It doesn't explain the 'group' optional behavior beyond the schema's auto-lookup note.

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?

Clearly states it retrieves the configuration of a node at a specific version, distinguishing it from get_node_config (current config) and list_node_versions (version list). The verb 'get' and resource 'configuration of a node' are specific.

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?

The description implies it's for historical config retrieval but does not explicitly state when to use this over get_node_config or diff_node_versions. It lacks explicit alternatives or exclusion conditions, leaving the agent to infer the use case.

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

list_nodesList NodesA
Read-onlyIdempotent

List nodes (network devices) managed by Oxidized.

Returns each node's name, full name (group/name), IP, group, model, last run status and time, and last run details. Node vars are redacted unless redaction is disabled in the server configuration. Pass a group or model on large installations: they are filtered by Oxidized itself, so only matching nodes are transferred. The group must match exactly; use find_nodes when unsure of the name.

NameRequiredDescriptionDefault
groupNoOnly nodes in this group - exact, case-sensitive name as shown by list_nodes (e.g. 'core'); 'default' selects nodes without a group
limitNoMaximum nodes to return
modelNoOnly nodes of this Oxidized model (e.g. 'IOS', 'JunOS', 'RouterOS'); built-in model names are case-insensitive
offsetNoNumber of matching nodes to skip
statusNoOnly nodes whose last run had this status (e.g. 'success', 'no_connection', 'fail', 'never')
name_containsNoOnly nodes whose name, full name or IP contains this text (case-insensitive)

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, covering the mutation profile. The description adds meaningful behavioral detail: node vars are redacted unless server redaction is disabled, and filtering is done server-side so only matching nodes are transferred. This goes beyond annotations and helps the agent set expectations.

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?

The description is a tight two-sentence paragraph. It front-loads the core purpose and return fields, then delivers usage advice and a pointer to an alternative. Every sentence earns its place; no filler or redundancy.

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 listing tool with an output schema already present, the description covers the return shape, filtering behavior, redaction caveat, and large-installation recommendations. Nothing an agent needs to decide when and how to call it is missing. The combination of schema, annotations, and description is fully self-sufficient.

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 description coverage is 100%, so parameters are already documented. The description enriches semantics by explaining when to pass group/model ('on large installations') and clarifies that group matching is exact and case-sensitive, with 'default' selecting nodes without a group. This practical guidance adds value beyond 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?

The description starts with a clear verb-resource pair: 'List nodes (network devices) managed by Oxidized.' It then enumerates the exact fields returned (name, full name, IP, group, model, last run status/time, details), making the tool's function unambiguous. It also implicitly distinguishes from siblings by pointing to find_nodes for fuzzy group name lookup.

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 recommends passing group or model filters on large installations and explains why (server-side filtering reduces transfer). It also gives a precise when-not: 'use find_nodes when unsure of the name' for groups, directing the agent to the correct alternative.

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

list_node_versionsList Node VersionsA
Read-onlyIdempotent

List the stored configuration versions of a node, newest first.

Each version has its git oid, date, author and commit message. Requires the Oxidized 'git' (or 'gitcrypt') output.

NameRequiredDescriptionDefault
nodeYesNode name or IP address (e.g. 'core-sw01')
groupNoNode group; looked up automatically when omitted
limitNoMaximum versions to return

Output Schema

NameRequiredDescription

No output parameters

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, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds meaningful behavioral context: it lists what each version includes (git oid, date, author, commit message) and the ordering ('newest first'). It also discloses the backend requirement (git/gitcrypt output), which is beyond the annotations.

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?

The description is compact and front-loaded: the main purpose is stated in the first sentence, and the second sentence adds useful detail about the version contents and a prerequisite. Every sentence earns its place, with no fluff or repetition of the schema.

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?

The tool has a clear purpose, a complete schema, and an output schema, so the description does not need to explain return values. The description covers the key behavioral details (ordering, version contents, backend requirement). It could have explicitly mentioned pagination or the default limit, but the schema already covers the limit parameter, so the description is sufficiently complete.

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 all three parameters. The description adds a bit of context by mentioning the git oid, date, author, and commit message, which indirectly clarifies what the 'limit' parameter controls, but it does not add significant new meaning beyond the schema. Baseline 3 is appropriate.

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 description states a specific verb ('List'), a specific resource ('stored configuration versions of a node'), and a clear ordering ('newest first'). It also distinguishes itself from siblings like get_node_version and diff_node_versions by focusing on the list of stored versions rather than a single version or a diff.

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?

The description clearly implies when to use this tool: when you need the list of stored configuration versions for a node. It also notes a prerequisite ('Requires the Oxidized 'git' (or 'gitcrypt') output'), which is useful context. It does not explicitly name alternatives or exclusions, but the sibling list and the description's focus make the usage context clear.

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

reload_nodesReload NodesA
Idempotent

Reload the Oxidized node list from its source (router.db, SQL, HTTP, ...).

Use after devices were added, removed or changed in the source so Oxidized picks up the change without waiting for its next refresh. Always reloads every node: oxidized-web's per-node reload (/reload?node=X) replaces the whole in-memory node list with just the matching nodes, so it is deliberately not offered.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=false and idempotentHint=true, so the mutation/idempotency profile is covered. The description adds real behavioral context: it always reloads the entire node list and cannot target a single node, plus the rationale about in-memory list replacement. It does not mention permissions or failure modes, keeping it 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.

Conciseness4/5

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

Front-loaded with the core action, followed by the when-to-use condition and a short note on the omitted per-node variant. Three sentences, all earning their place, though the parenthetical endpoint path is slightly more detail than strictly necessary.

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 zero-parameter tool with an output schema and annotations covering safety/idempotency, the description supplies everything the agent needs: purpose, trigger condition, scope, and the reason no per-node variant exists.

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 (count 0), so the schema has nothing to document and the baseline is 4. The description correctly implies no filtering or targeting options exist.

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 (reload) and resource (the Oxidized node list) plus the origin of the data (router.db, SQL, HTTP), and clarifies the scope is all nodes. The contrast with oxidized-web's per-node reload makes the behavior unambiguous without needing the 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?

Explicitly says when to use it ('after devices were added, removed or changed in the source') and why (avoid waiting for the next refresh). It also explains why the per-node alternative is deliberately not offered, heading off a likely agent confusion.

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

search_configsSearch ConfigsA
Read-onlyIdempotent

Search the latest configurations of all nodes for a pattern.

oxidized-web first finds the nodes whose configuration matches, then those configurations are fetched to return the matching lines with line numbers. Use this to answer questions such as "which devices still have telnet enabled" or "where is VLAN 42 configured".

The pattern must be valid in both Ruby (oxidized-web) and Python regular expressions - stick to common syntax. Lines are matched one at a time, so patterns spanning several lines find nodes but no lines.

NameRequiredDescriptionDefault
groupNoOnly search nodes in this group - exact, case-sensitive name as shown by list_nodes; 'default' selects nodes without a group
literalNoTreat the pattern as literal text
patternYesRegular expression (or literal text with literal=true) to search for, e.g. 'snmp-server community'
max_nodesNoMaximum matching nodes whose configurations are searched (nodes without a stored configuration are skipped and not counted)
max_matchesNoMaximum matching lines to return in total
context_linesNoLines of context to include before and after each match
case_sensitiveNoMatch case-sensitively

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already flag read-only, idempotent, and non-destructive behavior. The description adds meaningful behavioral detail beyond those flags: it explains the two-phase search process, that matching lines come with line numbers, that patterns must be valid in both Ruby and Python regex, and that multi-line patterns will find nodes but produce no matching lines. No contradiction with annotations.

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?

The description is well-structured: a one-sentence summary comes first, followed by the operational flow, concrete usage examples, and then an important cross-language regex caveat. Every sentence earns its place without unnecessary padding.

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?

The description is complete for an agent to use this tool correctly. It explains the search behavior, the regex constraint, the line-matching limitation, and when to reach for the tool. The input schema fully documents all seven parameters, and an output schema exists, so return-value details are not the description's responsibility.

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 description adds parameter-level value by warning that the pattern must be valid in both Ruby and Python regex and that lines are matched one at a time, which directly affects how the pattern parameter should be authored. This goes beyond the schema's short 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?

Purpose is stated with a specific verb and resource: "Search the latest configurations of all nodes for a pattern." It clarifies the two-step process (find matching nodes, then fetch and return matching lines), distinguishing it from sibling tools like get_node_config, which fetches a single config, or list_nodes, which enumerates nodes.

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?

The description gives concrete, recognizable use cases: "which devices still have telnet enabled" and "where is VLAN 42 configured". This tells an agent when this tool is appropriate, though it does not explicitly contrast it with alternatives or state when not to use it.

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

trigger_node_backupTrigger Node BackupA
Idempotent

Queue an immediate configuration backup of a node.

Oxidized moves the node to the head of its queue; the backup itself runs asynchronously. Check get_node afterwards for the run result, and list_node_versions for a new version if the configuration changed. Oxidized picks the node by name or IP only (no group), so node names must be unique - otherwise the first node with that name is queued.

NameRequiredDescriptionDefault
nodeYesNode name or IP address (e.g. 'core-sw01')
userNoAuthor name recorded if this backup produces a new version
messageNoCommit message recorded if this backup produces a new version

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

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

Annotations only indicate readOnlyHint=false, idempotentHint=true, and destructiveHint=false. The description adds crucial behavioral context beyond those: the node moves to the head of the queue, the backup runs asynchronously, and name/IP matching is group-less with a uniqueness requirement. It also explains the consequence of a changed configuration (a new version appears), giving the agent a full picture of the tool's runtime behavior.

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?

The description is compact and front-loaded with the primary purpose. The first sentence states the action immediately, followed by two sentences that earn their place by covering async behavior, follow-up steps, and a critical uniqueness constraint. No fluff or repetition.

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 tool with three parameters, an output schema, and annotations, the description covers everything an agent needs to invoke it correctly: what happens (queued async backup), how to verify the result (get_node, list_node_versions), and a key constraint (unique node names). The output schema handles return-value details, so no critical context is missing.

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%, with clear descriptions for node, user, and message. The tool description adds no additional meaning about parameters beyond what the schema already states. Since the schema fully documents each parameter, the baseline of 3 is appropriate.

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 description opens with a specific verb and resource: 'Queue an immediate configuration backup of a node.' It clearly distinguishes this from sibling retrieval tools like get_node_config or list_node_versions by focusing on triggering a backup rather than reading data. The follow-up references to get_node and list_node_versions further disambiguate its role.

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?

The description gives clear context for when to use the tool: when an immediate backup is needed. It also provides post-invocation guidance ('Check get_node afterwards... list_node_versions for a new version') and a uniqueness prerequisite. It does not explicitly state when not to use it or name direct alternatives, but the usage context is strong enough for an agent to select it correctly.

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. 1 tool updatev0.2.0
    • Changeddiff_node_versions1 field changed
      • addedInput schema / properties / offset
        Added value: +{
        +  "default": 0,
        +  "description": "Zero-based first diff line to return",
        +  "minimum": 0,
        +  "type": "integer"
        +}
  2. 11 tool updatesv0.1.0
    • First observeddiff_node_versions
    • First observedfind_nodes
    • First observedget_backup_stats
    • First observedget_node
    • First observedget_node_config
    • First observedget_node_version
    • First observedlist_node_versions
    • First observedlist_nodes
    • First observedreload_nodes
    • First observedsearch_configs
    • First observedtrigger_node_backup

TDQS

A4.3/5.0

Scored across 11 tools

Disambiguation4/5

Most tools target clearly distinct actions on nodes (list, find, get, get_config, get_version, diff, list_versions, search, trigger_backup, stats, reload). The only mild overlap is between get_node_config (latest) and get_node_version (specific version), but the descriptions make the boundary clear.

Naming Consistency5/5

Every tool follows a consistent snake_case verb_noun pattern (get_node, list_nodes, diff_node_versions, trigger_node_backup, search_configs, reload_nodes). No mixed conventions or vague verb styles.

Tool Count5/5

11 tools is well-scoped for an Oxidized backup management server, covering the distinct facets of node management, config retrieval, versioning, health, and search without bloat.

Completeness4/5

The surface covers the full lifecycle of inspecting nodes, backups, versions, diffs, health, and search. Missing operations like adding/removing nodes are out of scope (nodes come from router.db/SQL/HTTP sources), so gaps are minor.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Exposes Cisco Network Services Orchestrator (NSO) operations and data as MCP tools and resources, enabling AI-powered network automation through natural language. It supports tasks like retrieving device configurations, checking sync status, and managing services via the NSO RESTCONF API.
    9
    14
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server for network operations that lets AI assistants interact with Cisco/Juniper network devices through safe, well-defined tools like compliance audits and configuration backups.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Provides MCP tools for governed multi-vendor network device operations, including configuration management (backup, diff, merge, replace, rollback) and read-only queries (facts, interfaces, BGP, LLDP, ARP) via NAPALM, with optional NetBox source-of-truth integration.
    33
    MIT
  • F
    license
    A
    quality
    D
    maintenance
    Provides MCP tools to query, compare, and analyze network device configurations managed by Oxidized, such as listing devices, viewing backup status, and generating diffs between configuration versions.
    8
    -