Skip to main content
Glama
shigechika

io.github.shigechika/junos-mcp

by shigechika

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 (output_format: text/json/xml)

Yes

run_show_commands

Run multiple CLI commands in a single session (output_format: text/json/xml)

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 (unlink flag for EX2300/EX3400)

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 + available disk space 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 + available disk space on devices (post-SCP verification)

Yes

Daily Operations

Tool

Description

Connection

daily_brief

Morning health check across multiple devices in parallel — alarms, interface up/down, and syslog alert patterns within a look-back window (since_hours, default 18 h). Returns a CRITICAL/WARNING/OK Markdown summary.

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)

  • no_commit=True — issues commit confirmed but intentionally skips the final commit. JUNOS auto-rolls back after confirm_timeout minutes. Useful for restarting services that lack a request ...restart command (e.g. syslog daemon on EX3400 post-upgrade).

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.

Structured output format

run_show_command and run_show_commands accept an optional output_format parameter:

Value

Description

"text"

Default. Plain-text CLI output (same as typing the command)

"json"

NETCONF JSON output — device returns a structured dict

"xml"

NETCONF XML output — device returns pretty-printed XML

Note: JunOS drops CLI pipe stages (| match, | last, | count) under json/xml output. Use "text" when pipe filtering is needed.

# Get structured BGP summary data
run_show_command("router-a", "show bgp summary", output_format="json")

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

115 tests covering all 23 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

Install Server
A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
1hResponse time
3dRelease cycle
15Releases (12mo)
Issues opened vs closed

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Latest Blog Posts

MCP directory API

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

curl -X GET 'https://glama.ai/api/mcp/v1/servers/shigechika/junos-mcp'

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