Junos MCP
MCP server for Juniper Networks device operations via junos-ops
Versions
No versions found.
Tools 24
get_device_facts Get basic device information (model, hostname, serial, version, etc.). Args: hostname: Target device hostname (must exist in config.ini) config_path: Path to config.ini (empty string uses default search)
get_version Get JUNOS version information with upgrade status. Shows running version, planning version, pending version, local/remote package status, and reboot schedule. Args: hostname: Target device hostname (must exist in config.ini) config_path: Path to config.ini (empty string uses default search)
run_show_command Run a CLI show command on the device and return output. Args: hostname: Target device hostname (must exist in config.ini) command: CLI command to execute (e.g., "show bgp summary") output_format: Output format — "text" (default), "json", or "xml". Note: pipe stages (| match, | last, | count, etc.) are silently dropped regardless of output_format — PyEZ's Device.cli() sends the command over NETCONF RPC, which JunOS does not pipe-process. Run the command without pipes; for line filtering, use run_show_command_batch's grep_pattern argument instead (works for a single host too — pass a one-element hostnames list). That workaround always fetches text output internally, so it cannot be combined with output_format="json"/"xml" — for structured output you must filter the result client-side instead. config_path: Path to config.ini (empty string uses default search)
run_show_commands Run multiple CLI show commands on the device in a single session. Commands are executed in sequence and stop on the first failure. To run all commands regardless of individual errors, call run_show_command once per command instead. Args: hostname: Target device hostname (must exist in config.ini) commands: List of CLI commands to execute output_format: Output format — "text" (default), "json", or "xml". Note: pipe stages (| match, | last, | count, etc.) are silently dropped regardless of output_format — PyEZ's Device.cli() sends the command over NETCONF RPC, which JunOS does not pipe-process. Run commands without pipes and filter client-side. run_show_command_batch's grep_pattern argument offers server-side-style filtering, but it only accepts one command at a time — it does not cover this tool's multi-command case, so it is not a drop-in workaround here. config_path: Path to config.ini (empty string uses default search)
run_show_command_batch Run a CLI show command on multiple devices in parallel. Uses ThreadPoolExecutor for concurrent execution. Either ``hostnames`` or ``tags`` selects the targets; if both are omitted, every router in config.ini is targeted. When both are given, the intersection is used. Args: command: CLI command to execute on all devices hostnames: List of target device hostnames (must exist in config.ini) tags: Tag filter. Each list element is one tag group (comma-separated tags AND together within a group). Multiple list elements OR together across groups. E.g. ``["tokyo,core", "backup"]`` means ``(tokyo AND core) OR backup``. Combined with ``hostnames`` the result is the intersection. grep_pattern: Optional Python ``re`` pattern. When set, only lines matching the pattern (via ``re.search``) are kept from each host's output. Header lines (starting with ``#``) are always preserved. Hosts with no matching lines show ``(no match)``. Reduces large batch outputs to the essential lines. This tool always fetches text output internally (there is no ``output_format`` parameter here) — ``grep_pattern`` filters plain-text lines and cannot be combined with structured JSON/XML output. max_workers: Maximum parallel threads (default 5) config_path: Path to config.ini (empty string uses default search)
list_remote_files List files on the remote device path (/var/tmp by default). Args: hostname: Target device hostname (must exist in config.ini) config_path: Path to config.ini (empty string uses default search)
check_upgrade_readiness Check if a device is ready for upgrade. Verifies whether the device is already running the target version, and performs a dry-run to check local/remote package availability. Args: hostname: Target device hostname (must exist in config.ini) config_path: Path to config.ini (empty string uses default search)
compare_version Compare two JUNOS version strings. Returns whether left is greater than, equal to, or less than right. No device connection required. Args: left: First JUNOS version string (e.g., "22.4R3-S6.5") right: Second JUNOS version string (e.g., "23.2R1.0")
get_router_list List routers defined in config.ini, optionally filtered by tags. Returns section names from config.ini, which represent the hostnames that can be used with other tools. No device connection required. Args: tags: Tag filter. Each list element is one tag group (comma-separated tags AND together within a group); multiple list elements OR together across groups. E.g. ``["tokyo,core", "backup"]`` means ``(tokyo AND core) OR backup``. None/empty returns all. config_path: Path to config.ini (empty string uses default search)
get_package_info Get package file name and expected hash for a specific device model. Retrieves model-specific package information from config.ini. No device connection required. Args: hostname: Target device hostname (must exist in config.ini) model: Device model name (e.g., "EX2300-24T") config_path: Path to config.ini (empty string uses default search)
get_config Get device configuration. Args: hostname: Target device hostname (must exist in config.ini) output_format: Output format - "text" (default), "set", or "xml" config_path: Path to config.ini (empty string uses default search)
get_config_diff Show configuration difference compared to a rollback version. Args: hostname: Target device hostname (must exist in config.ini) rollback_id: Rollback version to compare against (0-49, default 1) config_path: Path to config.ini (empty string uses default search)
collect_rsi Collect RSI (Request Support Information) and SCF (Show Configuration) from a device. Saves two files: {hostname}.SCF (show configuration) and {hostname}.RSI (request support information). Model-specific timeouts are applied automatically (e.g., SRX Branch: 1200s, Virtual Chassis: 1800s). Args: hostname: Target device hostname (must exist in config.ini) output_dir: Directory to save output files (empty uses config RSI_DIR or current dir) config_path: Path to config.ini (empty string uses default search)
collect_rsi_batch Collect RSI/SCF from multiple devices in parallel. Uses ThreadPoolExecutor for concurrent collection. Default 20 workers matches junos-ops CLI default for RSI collection. Either ``hostnames`` or ``tags`` selects the targets; if both are omitted, every router in config.ini is targeted. When both are given, the intersection is used. Args: hostnames: List of target device hostnames tags: Tag filter. Each list element is one tag group (comma-separated tags AND together within a group); multiple list elements OR together across groups. Combined with ``hostnames`` the result is the intersection. output_dir: Directory to save output files (empty uses config RSI_DIR or current dir) max_workers: Maximum parallel threads (default 20) config_path: Path to config.ini (empty string uses default search)
check_reachability Probe NETCONF reachability for one or more devices. Equivalent to ``junos-ops check --connect``. Opens a fast NETCONF handshake (no full PyEZ facts gathering, 5-second TCP probe) and reports per-host status as a table. Args: hostnames: List of target device hostnames (must exist in config.ini) tags: Tag filter. Each list element is one tag group (comma-separated tags AND together within a group); multiple list elements OR together across groups. Combined with ``hostnames`` the result is the intersection. max_workers: Maximum parallel threads (default 20, matches junos-ops) config_path: Path to config.ini (empty string uses default search)
check_local_inventory Verify local firmware checksums against the config.ini inventory. Equivalent to ``junos-ops check --local``. Iterates every ``<model>.file`` / ``<model>.hash`` pair in the DEFAULT section of ``config.ini`` and verifies the file on the staging server. No device connection required. Args: model: Restrict to a single model (empty = all configured models) config_path: Path to config.ini (empty string uses default search)
check_remote_packages Verify the staged firmware checksum on one or more devices. Equivalent to ``junos-ops check --remote``. Connects to each device via NETCONF and verifies the package file (``<model>.file``) sitting on the device against ``<model>.hash``. Doubles as post-SCP copy verification. Per-host model resolution: ``model`` arg > config.ini ``[host].model`` > device facts. Args: hostnames: List of target device hostnames (must exist in config.ini) tags: Tag filter. Each list element is one tag group (comma-separated tags AND together within a group); multiple list elements OR together across groups. Combined with ``hostnames`` the result is the intersection. model: Override model resolution for all hosts (empty = per-host resolution) max_workers: Maximum parallel threads (default 20) config_path: Path to config.ini (empty string uses default search)
push_config Push configuration to a device with commit confirmed and health check. Supports two input methods (exactly one required): - config_file: Path to a .set or .j2 file containing set commands - set_commands: List of set command strings (inline) Safety features (not available in Juniper's official MCP server): - dry_run mode (default True): shows diff without committing - commit confirmed: auto-rollback if not confirmed within timeout - health check: auto-rollback on connectivity failure after commit Commit flow (normal): lock -> load -> diff -> commit_check -> commit confirmed -> health check -> confirm -> unlock Commit flow (no_commit=True — intentional auto-rollback): lock -> load -> diff -> commit_check -> commit confirmed -> unlock (health check and final confirm are skipped; JUNOS rolls back automatically after confirm_timeout minutes) Args: hostname: Target device hostname (must exist in config.ini) config_file: Path to .set or .j2 file (mutually exclusive with set_commands) set_commands: List of set commands (mutually exclusive with config_file) dry_run: If True (default), show diff only without committing confirm_timeout: Minutes before auto-rollback (default 1, used with commit confirmed) no_commit: If True, issue commit confirmed but intentionally skip the final commit so JUNOS auto-rolls back after confirm_timeout minutes. Useful for triggering service restarts (e.g. syslog on EX3400) where no ``request ...restart`` command exists. dry_run=True takes precedence over no_commit (diff is shown but nothing is committed). health_check: Fallback health check commands tried in order after commit. Passes if ANY command succeeds. Supports "ping ..." (checks packets received), "uptime" (NETCONF RPC probe), or any CLI command (success if no exception). Default: ["uptime"] — uses the existing NETCONF session and does not depend on ICMP reachability. (Changed from broadcast ping in junos-mcp 0.11.0 to match junos-ops 0.16.8+.) Ignored when no_commit=True. config_path: Path to config.ini (empty string uses default search)
copy_package Copy firmware package to remote device via SCP with checksum verification. Checks if copy is needed (already running target version, or package already present on device). Cleans up storage before copying. Args: hostname: Target device hostname (must exist in config.ini) dry_run: If True (default), show what would be done without copying force: If True, skip version checks and force copy config_path: Path to config.ini (empty string uses default search)
install_package Install firmware package on device with pre-flight checks. Full upgrade flow: version check -> rollback pending if needed -> copy (with checksum) -> clear reboot schedule -> rescue config save -> request system software add (with validation). Args: hostname: Target device hostname (must exist in config.ini) dry_run: If True (default), show what would be done without installing force: If True, skip version checks and force install unlink: If True, run ``request system software add <pkg> unlink`` via CLI instead of PyEZ SW.install(). Use for low-flash devices (EX2300 / EX3400, ~1.3 GB /dev/gpt/junos) where major version upgrades fail with "ERROR: insufficient space" because PyEZ does not expose the unlink parameter. The CLI path frees ~330 MB by unlinking the source tgz during extraction. config_path: Path to config.ini (empty string uses default search)
rollback_package Rollback to previously installed package version. Checks pending version first. If no pending version exists, rollback is skipped. Args: hostname: Target device hostname (must exist in config.ini) dry_run: If True (default), show what would be done without rolling back config_path: Path to config.ini (empty string uses default search)
schedule_reboot Schedule device reboot at a specified time. Checks for existing reboot schedules. If one exists and force is False, the existing schedule is preserved. Args: hostname: Target device hostname (must exist in config.ini) reboot_at: Reboot time in YYMMDDHHMM format (e.g., "2601020304" = 2026-01-02 03:04) dry_run: If True (default), show what would be done without scheduling force: If True, clear existing reboot schedule and set new one config_path: Path to config.ini (empty string uses default search)
daily_brief Run a morning health check across multiple devices in parallel. Checks per host (Phase 1): - ``show system alarms`` / ``show chassis alarms`` - ``show interfaces descriptions`` — a physical interface is flagged ``[IF_DOWN]`` only when it has a description (``Admin=up``, ``Link=down``) and its ``Last flapped`` time is within ``since_hours``. Undescribed unused ports and chronically-down ports are suppressed (loopback / mgmt / internal logical units are also excluded). - ``show log messages | last 200`` — alert patterns within ``since_hours`` - dual-RE redundancy — an explicit routing-engine fault is flagged ``[RE_FAULT]`` (skipped on SRX chassis clusters, whose facts misreport RE status; a failed cluster node raises chassis alarms instead) - ``route_baseline`` (optional) — when > 0, a device whose ``inet.0`` destination count differs from this value is flagged ``[ROUTE_BASELINE]``. Scope with ``tags`` (e.g. ``tags=["main"], route_baseline=152``), since full-table routers carry far more routes than access routers. Syslog patterns watched: BGP state change away from Established, STP port role change, OSPF neighbor down, ARP address conflict, IF_DOWN. ``since_hours`` defaults to 18 (≈ previous 15:00 for a 09:00 morning run). Tags default to none (all routers); pass ``tags=["main"]`` to limit scope. Output tiers: - CRITICAL — connection failure - WARNING — at least one anomaly found - OK — clean Returns a Markdown summary with anomaly details for CRITICAL/WARNING hosts and a collapsed OK list.
health_check Report server version and config status — without connecting to any device. Call this at session start (or after a tool-call timeout) to confirm the MCP is up, see which version is running, and verify that config.ini loads and how many routers it defines. Lightweight by design: junos-mcp fans out to many Juniper devices, so this check ONLY loads config.ini and counts hosts — it opens NO NETCONF/SSH connection to any device. Always returns the same keys: ``status`` (healthy / error), ``service``, ``version``, ``config_path`` (the resolved config.ini path it would use), ``router_count`` (number of host sections in config.ini), ``tags`` (sorted list of distinct tags across configured hosts), and ``config`` (ok / error / missing). On an error result, ``detail`` carries the reason. There is no degraded state: this check either loads config.ini or it does not. Args: config_path: Path to config.ini (empty string uses default search).
Permissions 2
filesystem low env_vars low