Skip to main content

MCP server for junos-ops: expose Juniper device operations to AI assistants

Project description

junos-mcp

English | 日本語

MCP (Model Context Protocol) server for junos-ops.

Exposes Juniper Networks device operations to MCP-compatible AI assistants (Claude Desktop, Claude Code, etc.) via STDIO transport. While junos-ops is the CLI tool for humans, junos-mcp is the AI-facing interface to the same powerful engine.

Features

Device Information

Tool Description Connection
get_device_facts Get basic device information (model, hostname, serial, version) Yes
get_version Get JUNOS version with upgrade status Yes
get_router_list List routers from config.ini (optionally filtered by tags) No

CLI Command Execution

Tool Description Connection
run_show_command Run a single CLI show command Yes
run_show_commands Run multiple CLI commands in a single session Yes
run_show_command_batch Run a command on multiple devices in parallel (supports tag filter and grep_pattern) Yes

Configuration Management

Tool Description Connection
get_config Get device configuration (text/set/xml format) Yes
get_config_diff Show config diff against a rollback version Yes
push_config Push config with commit confirmed + health check Yes

Upgrade Operations

Tool Description Connection
check_upgrade_readiness Check if device is ready for upgrade Yes
compare_version Compare two JUNOS version strings No
get_package_info Get model-specific package file and hash No
list_remote_files List files on remote device path Yes
copy_package Copy firmware package via SCP with checksum Yes
install_package Install firmware with pre-flight checks Yes
rollback_package Rollback to previous package version Yes
schedule_reboot Schedule device reboot at specified time Yes

Diagnostics

Tool Description Connection
collect_rsi Collect RSI/SCF with model-specific timeouts Yes
collect_rsi_batch Collect RSI/SCF from multiple devices in parallel (supports tag filter) Yes

Pre-flight Checks

Equivalent to the junos-ops check subcommand modes. All three reuse the junos-ops display layer for table rendering.

Tool Description Connection
check_reachability Probe NETCONF reachability per host (fast: no facts, 5s TCP probe) Yes
check_local_inventory Verify local firmware checksums against config.ini inventory No
check_remote_packages Verify staged firmware checksum on devices (post-SCP verification) Yes

Safety by Design

All destructive operations (push_config, copy_package, install_package, rollback_package, schedule_reboot) default to dry-run mode (dry_run=True). The AI assistant must explicitly set dry_run=False to make changes.

push_config provides additional safety features not found in other Junos MCP servers:

  • commit confirmed with configurable timeout (auto-rollback if not confirmed)
  • Fallback health check after commit (ping, NETCONF uptime probe, or any CLI command)
  • Automatic rollback if health check fails (commit is not confirmed, timer expires)

Requirements

Installation

pip install junos-mcp

Or for development:

git clone https://github.com/shigechika/junos-mcp.git
cd junos-mcp
python3 -m venv .venv
. .venv/bin/activate
pip install -e ".[test]"

CLI options

python -m junos_mcp --help
Option Description
-V, --version Print version and exit
--check Load config.ini, list routers, and exit (exit code 1 on error)
--check-host HOSTNAME With --check, also open a NETCONF session to verify reachability/auth
--transport {stdio,streamable-http} Transport protocol (default: stdio)

--check is handy to verify JUNOS_OPS_CONFIG and config.ini are reachable before registering the server with an AI assistant. Combine with --check-host rt1 to also confirm that credentials actually authenticate against a real device.

Tag-based host filtering

run_show_command_batch, collect_rsi_batch, and get_router_list accept an optional tags argument. The grammar matches the junos-ops --tags CLI flag (since junos-mcp 0.9.0 / junos-ops 0.16.6):

  • Each list element is one tag group. Comma-separated tags inside a group AND together.
  • Multiple list elements OR together across groups.
  • When combined with hostnames on batch tools, the result is the intersection (tags filter further narrowed by names). An empty intersection returns an error.
# 1 group, 1 tag — hosts tagged "main"
run_show_command_batch(command="show route summary", tags=["main"])

# 1 group, 2 tags — AND within the group: tokyo AND edge
collect_rsi_batch(tags=["tokyo,edge"])

# 2 groups — OR across groups: main OR backup
get_router_list(tags=["main", "backup"])

# Mixed: (tokyo AND core) OR backup
run_show_command_batch(command="show version", tags=["tokyo,core", "backup"])

# Intersection: among backup-tagged hosts, only rt1/rt2
run_show_command_batch(
    command="show version",
    hostnames=["rt1.example.jp", "rt2.example.jp"],
    tags=["backup"],
)

See the junos-ops tag documentation for how to tag sections in config.ini and for the matching CLI grammar.

Server-side output filtering

run_show_command_batch accepts an optional grep_pattern argument (Python re pattern). When set, only lines matching the pattern are kept from each host's output. Header lines (starting with #) are always preserved. Hosts with no matching lines show (no match).

This reduces large batch results — for example, 93 routers × show route summary — from hundreds of KB to a few hundred bytes by extracting just the relevant lines:

# Extract only the inet.0 destination count from 93 routers
run_show_command_batch(
    command="show route summary",
    tags=["main"],
    grep_pattern=r"inet\.0:\s+\d+ destinations",
)

Connection pool

junos-mcp maintains a per-host NETCONF connection pool. Reusing an idle Device avoids the TCP/NETCONF handshake on every tool call; the pool serialises concurrent operations on the same host through a per-host lock.

Environment variable Default Description
JUNOS_MCP_POOL 1 (enabled) Set to 0 to disable the pool and open a fresh connection per call
JUNOS_MCP_POOL_IDLE 60 Idle timeout in seconds. Connections unused longer than this are closed on the next call. Set to 0 to disable eviction

Security note: pooled connections are long-lived SSH sessions. In environments where session duration is restricted by policy, set JUNOS_MCP_POOL_IDLE to a value shorter than the inactivity limit, or set JUNOS_MCP_POOL=0 to disable the pool entirely.

Configuration

This server uses the same config.ini as junos-ops. See junos-ops README for details.

Each tool accepts an optional config_path parameter. If omitted, the default search order is used:

  1. Environment variable JUNOS_OPS_CONFIG
  2. ./config.ini
  3. ~/.config/junos-ops/config.ini

Usage

Claude Code

Register the MCP server with claude mcp add:

claude mcp add junos-mcp \
  -e JUNOS_OPS_CONFIG=~/.config/junos-ops/config.ini \
  -- python -m junos_mcp

The --scope (-s) option controls where the configuration is stored:

Scope Description Config location
local (default) Current project, current user only ~/.claude.json
project Current project, shared with team .mcp.json in project root
user All projects, current user only ~/.claude.json

Claude Desktop

Add to Claude Desktop config file:

OS Config file
macOS ~/Library/Application Support/Claude/claude_desktop_config.json
Windows %APPDATA%\Claude\claude_desktop_config.json
Linux ~/.config/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "junos-mcp": {
      "command": "python",
      "args": ["-m", "junos_mcp"],
      "env": {
        "JUNOS_OPS_CONFIG": "/path/to/config.ini"
      }
    }
  }
}

Restart Claude Desktop after editing.

Remote Access with OAuth (via mcp-stdio)

junos-mcp supports Streamable HTTP transport, enabling remote access from Claude Desktop or Claude Code through mcp-stdio as an OAuth proxy.

graph TB
    A[junos-mcp<br/>remote server] <-- "OAuth 2.1 + HTTPS" --> B[mcp-stdio<br/>proxy]
    B <-- "STDIO" --> C[Claude Desktop<br/>Claude Code]

Step 1: Start junos-mcp with Streamable HTTP on the remote server

JUNOS_OPS_CONFIG=~/.config/junos-ops/config.ini \
  python -m junos_mcp --transport streamable-http

The server listens on http://localhost:8000/mcp by default.

Step 2: Register mcp-stdio as the MCP server on your local machine

claude mcp add junos-mcp -- mcp-stdio https://your-server:8000/mcp

mcp-stdio handles OAuth 2.1 authentication (RFC 8414 discovery, RFC 7591 dynamic client registration, PKCE) and relays STDIO ↔ Streamable HTTP.

See mcp-stdio README for detailed configuration including OAuth provider setup.

MCP Inspector (development)

mcp dev junos_mcp/server.py

Testing

pytest tests/ -v

94 tests covering all 22 tools, the connection pool, helper functions, and edge cases.

Architecture

Stdout-safe by construction

Since junos-ops 0.14.1, core functions return structured dict values and never print to stdout; MCP tools render output via junos_ops.display.format_*(). No contextlib.redirect_stdout is needed, so the MCP STDIO JSON-RPC channel stays clean.

Global State Initialization

junos-ops uses common.args and common.config as global variables. The MCP server initializes these using the same pattern as the test fixtures in junos-ops (conftest.py).

Parallel Execution

Batch tools (run_show_command_batch, collect_rsi_batch) use ThreadPoolExecutor via junos-ops common.run_parallel() with configurable max_workers.

License

Apache License 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

junos_mcp-0.12.0.tar.gz (37.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

junos_mcp-0.12.0-py3-none-any.whl (24.4 kB view details)

Uploaded Python 3

File details

Details for the file junos_mcp-0.12.0.tar.gz.

File metadata

  • Download URL: junos_mcp-0.12.0.tar.gz
  • Upload date:
  • Size: 37.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for junos_mcp-0.12.0.tar.gz
Algorithm Hash digest
SHA256 06a5e9e85aadd55e18dddf2ed9529100f02dc936b518f4258bc3d5ac629dbeb2
MD5 05155626c704d097621591fabb162a02
BLAKE2b-256 1727c4ccabb687190dcf92f6cdfc57ea44371d0a19e5a349abb43c2323effa5b

See more details on using hashes here.

Provenance

The following attestation bundles were made for junos_mcp-0.12.0.tar.gz:

Publisher: release.yml on shigechika/junos-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file junos_mcp-0.12.0-py3-none-any.whl.

File metadata

  • Download URL: junos_mcp-0.12.0-py3-none-any.whl
  • Upload date:
  • Size: 24.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for junos_mcp-0.12.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d1c553359a31435af193718d1f40b5f8a2e70de61fd27e10dca0d8d3843c554e
MD5 f38f0dea535eff7bea702dff42257b2c
BLAKE2b-256 6cdc136a57db7c25bb3bd747176ca17dd2256248cd169773d8af58c86d43672d

See more details on using hashes here.

Provenance

The following attestation bundles were made for junos_mcp-0.12.0-py3-none-any.whl:

Publisher: release.yml on shigechika/junos-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page