Install
$ agentstack add mcp-juniper-junos-mcp-server ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
junos-mcp-server
A Model Context Protocol (MCP) server for Juniper Junos devices that enables LLM interactions with network equipment.
Table of Contents
- [junos-mcp-server](#junos-mcp-server)
- [Table of Contents](#table-of-contents)
- [Important Security Notice](#important-security-notice)
- [Security Requirements](#security-requirements)
- [Security Best Practices](#security-best-practices)
- [Important Configuration Notice](#important-configuration-notice)
- [Getting Started](#getting-started)
- [Running with uv](#running-with-uv)
- [Start Junos MCP Server](#start-junos-mcp-server)
- [Configuration](#configuration)
- [Config for Claude Desktop (stdio transport)](#config-for-claude-desktop-stdio-transport)
- [Config for Claude Desktop (using uv)](#config-for-claude-desktop-using-uv)
- [Config for Claude Desktop (Docker container)](#config-for-claude-desktop-docker-container)
- [Docker Usage](#docker-usage)
- [Build Docker Container](#build-docker-container)
- [Running with Default Settings](#running-with-default-settings)
- [Overriding Default Arguments](#overriding-default-arguments)
- [Junos Device Configuration](#junos-device-configuration)
- [Dynamic Device Management with Elicitation](#dynamic-device-management-with-elicitation)
- [Elicitation Compatibility Notice](#elicitation-compatibility-notice)
- [The
add_deviceTool](#the-add_device-tool) - [How It Works](#how-it-works)
- [Security Note](#security-note)
- [Example Usage](#example-usage)
- [SSH Key Requirements](#ssh-key-requirements)
- [Limitations](#limitations)
- [VSCode + GitHub Copilot Integration](#vscode--github-copilot-integration)
- [Start Your Server](#start-your-server)
- [Point to This URL in Your VSCode Config](#point-to-this-url-in-your-vscode-config)
- [Authentication for MCP Server Access](#authentication-for-mcp-server-access)
- [Authentication Behavior](#authentication-behavior)
- [Token Management](#token-management)
- [Generate a New Token](#generate-a-new-token)
- [List All Tokens](#list-all-tokens)
- [Show Token Value (Recovery)](#show-token-value-recovery)
- [Revoke a Token](#revoke-a-token)
- [Server Authentication Status](#server-authentication-status)
- [Client Configuration with Authentication](#client-configuration-with-authentication)
- [VSCode Configuration with Token](#vscode-configuration-with-token)
- [Testing with curl](#testing-with-curl)
- [Docker with Authentication](#docker-with-authentication)
- [Security Best Practices](#security-best-practices-1)
- [Token File Format](#token-file-format)
- [GuardRails for Config Commit](#guardrails-for-config-commit)
- [GuardRails for Executing Operational Commands](#guardrails-for-executing-operational-commands)
- [Using MCP Server with Juniper Cloud-Native Router (JCNR)](#using-mcp-server-with-juniper-cloud-native-router-jcnr)
- [Developer Guide](#developer-guide)
- [Architecture Overview](#architecture-overview)
- [How Tools Work](#how-tools-work)
- [Adding a New Tool](#adding-a-new-tool)
- [Step 1: Create a Handler Function](#step-1-create-a-handler-function)
- [Step 2: Register the Handler](#step-2-register-the-handler)
- [Step 3: Define Tool Metadata](#step-3-define-tool-metadata)
- [Example: Creating a BGP Neighbors Tool](#example-creating-a-bgp-neighbors-tool)
- [Using Elicitation in Tools](#using-elicitation-in-tools)
- [Best Practices for Tool Development](#best-practices-for-tool-development)
- [Using PyEZ for Advanced Operations](#using-pyez-for-advanced-operations)
- [Testing Your Tools](#testing-your-tools)
- [Debugging Tips](#debugging-tips)
Important Security Notice
> Warning: This server enables LLM access to your network infrastructure. Please review these security considerations carefully.
Security Requirements
- Corporate Policy Compliance: Only use this server if your company's
policy allows sending data of Junos devices to LLM services.
- Server Security: Always secure your Junos MCP server before deployment in
production environments.
- Authentication: Do not use password authentication for production
deployments. We strongly recommend using SSH key-based authentication for enhanced security.
- Deployment Strategy: Until your MCP server is properly secured, only
deploy locally for testing purposes. Do not deploy remote servers in production without proper security measures.
Security Best Practices
- Use SSH key authentication instead of passwords
- Implement proper network access controls
- Monitor and log all MCP server activities
- Regular security audits and updates
- Follow your organization's security policies
Important Configuration Notice
> Warning: The Junos MCP server supports configuration changes, but please ensure you only use this functionality when you want LLM-generated configurations to be loaded and committed on your Junos router.
Always review the configuration being generated by the LLM and only allow tool execution if it's the correct configuration for your use case.
Getting Started
Get the code.
git clone https://github.com/Juniper/junos-mcp-server.git
cd junos-mcp-server
pip install -r requirements.txt
Running with uv
If you're using uv, you can run the server directly:
uv run python jmcp.py -f devices.json -t stdio
Start Junos MCP Server
python3.11 jmcp.py --help
Junos MCP Server
options:
-h, --help show this help message and exit
-f DEVICE_MAPPING, --device-mapping DEVICE_MAPPING
the name of the JSON file containing the device mapping
-H HOST, --host HOST Junos MCP Server host
-t TRANSPORT, --transport TRANSPORT
Junos MCP Server transport
-p PORT, --port PORT Junos MCP Server port
Junos MCP server supports both streamable-http and stdio transport. Do not use --host with stdio transport.
Environment Variables
JUNOS_TIMEOUT: Command timeout in seconds for Junos CLI operations.JMCP_STATELESS: Controls streamable-http session mode.- Default:
false(stateful sessions, required for elicitation workflows such asadd_device). - Accepted true values:
1,true,yes,y,on - Accepted false values:
0,false,no,n,off
Configuration
Config for Claude Desktop (stdio transport)
{
"mcpServers": {
"jmcp": {
"type": "stdio",
"command": "python3",
"args": ["jmcp.py", "-f", "devices.json", "-t", "stdio"]
}
}
}
Config for Claude Desktop (using uv)
{
"mcpServers": {
"jmcp": {
"type": "stdio",
"command": "uv",
"args": ["run", "python", "jmcp.py", "-f", "devices.json", "-t", "stdio"]
}
}
}
Note: Please provide absolute path for jmcp.py and devices.json file.
Config for Claude Desktop (Docker container)
{
"mcpServers": {
"jmcp": {
"type": "stdio",
"command": "/usr/local/bin/docker",
"args": [
"run",
"--rm",
"-i",
"-v",
"devices.json:/app/config/devices.json",
"-v",
"vsrx_keypair.pem:/app/config/vsrx_keypair.pem",
"junos-mcp-server:latest"
]
}
}
}
Docker Usage
Build Docker Container
docker build -t junos-mcp-server:latest .
Running with Default Settings
By default, the Docker container runs with stdio transport:
docker run --rm -it -v /path/to/your/devices.json:/app/config/devices.json
junos-mcp-server:latest
This uses the default command: python jmcp.py -f /app/config/devices.json -t stdio
Overriding Default Arguments
You can override any arguments by specifying the full command:
For stdio transport:
docker run --rm -it -v /path/to/your/devices.json:/app/config/devices.json
junos-mcp-server:latest python jmcp.py -f /app/config/devices.json -t stdio
For streamable-http transport:
> Security: the streamable-http transport refuses to start without a valid > .tokens file. Generate one with python jmcp_token_manager.py generate > --id and mount it into the container as shown below. See > [Authentication](#authentication) for details, or pass > --allow-unauthenticated-http for loopback-only local development.
docker run --rm -it \
-v /path/to/your/devices.json:/app/config/devices.json \
-v /path/to/.tokens:/app/.tokens \
-p 30030:30030 \
junos-mcp-server:latest \
python jmcp.py -f /app/config/devices.json -t streamable-http -H 0.0.0.0
For streamable-http in stateless mode:
$ docker run --rm -it -e JMCP_STATELESS=true \
-v /path/to/your/devices.json:/app/config/devices.json \
-v /path/to/.tokens:/app/.tokens \
-p 30030:30030 \
junos-mcp-server:latest \
python jmcp.py -f /app/config/devices.json -t streamable-http -H 0.0.0.0
For streamable-http with custom port:
docker run --rm -it \
-v /path/to/your/devices.json:/app/config/devices.json \
-v /path/to/.tokens:/app/.tokens \
-p 8080:8080 \
junos-mcp-server:latest \
python jmcp.py -f /app/config/devices.json -t streamable-http -p 8080 -H 0.0.0.0
Note:
- Always mount your device configuration file using `-v /path/to/you/
devices.json:/app/config/devices.json`
- For streamable-http transport, expose the port using `-p
hostport:containerport`
- Mount any SSH private key files if using key-based authentication (e.g., `-v
/path/to/key.pem:/app/config/key.pem`)
Build docker container for Junos MCP Server
docker build -t junos-mcp-server:latest .
Note: Mount your config file devices.json and mount any other files, in my case I am using pem file for ssh priv key authentication so I am also mounting vsrx_keypair.pem
Junos Device Configuration
Junos MCP server supports both password based auth as well as SSH key based authentication (See first 2 routers configs [router-1, router-2]).
{
"router-1": {
"ip": "ip-addr",
"port": 22,
"username": "user",
"auth": {
"type": "password",
"password": "pwd"
}
},
"router-2": {
"ip": "ip-addr",
"port": 22,
"username": "user",
"auth": {
"type": "ssh_key",
"private_key_path": "/path/to/private/key.pem"
}
},
"router-3": {
"ip": "ip-addr",
"port": 22,
"username": "user",
"ssh_config": "~/.ssh/config_dc",
"auth": {
"type": "ssh_key",
"private_key_path": "/path/to/private/key.pem"
}
},
"router-4": {
"ip": "ip-addr",
"port": 22,
"username": "user",
"ssh_config": "/home/user/.ssh/config_jumphost",
"auth": {
"type": "password",
"password": "pwd"
}
}
}
Junos MCP server also provides support for ProxyCommand. (See last 2 routers configs [router-3, router-4]), which enables you to access a target device through an intermediary host that supports netcat. This is useful when you can only log in to the target device through the intermediate host (jumphost).
This is an example of an SSH config file being used .ssh/config_jumphost:
# Jumphost VM Connection
Host jumphost-vm
HostName 10.2.11.200
User root
# Used for MCP server
IdentityFile /home/user/.ssh/id_rsa_claude
IdentitiesOnly yes
StrictHostKeyChecking no
# cRPD Devices (via jump host)
Host dt-crpd1 dtwin-crpd1 digital-twin-crpd1 clab-digital-twin-eop6-pe1
HostName 172.20.20.11
User claude
IdentityFile c
# ProxyJump jumphost-vm # Not working with JunOS MCP
ProxyCommand ssh -l root jumphost-vm nc %h 22 2>/dev/null
StrictHostKeyChecking no
Note #1: Port value should be an integer (typically 22 for SSH).
Note #2: IdentityFile recommendation use full path (e.g /home/user/.ssh /id_rsa_claude rather than ~/.ssh/id_rsa_claude).
Dynamic Device Management with Elicitation
Elicitation Compatibility Notice
> Important: The elicitation feature currently only works with VSCode (using streamable-http transport). Claude Desktop does not yet support elicitation, so the add_device tool will not work with Claude Desktop.
The add_device Tool
The Junos MCP server includes a powerful add_device tool that allows you to dynamically add new Junos devices without modifying the configuration file. This tool uses MCP's elicitation feature to interactively collect device information.
How It Works
When you use the add_device tool, it will interactively ask for:
- Device Name: A unique identifier for your device (e.g., "router1-east")
- IP Address: The device's IP address
- SSH Port: The SSH port (defaults to 22)
- Username: The username for authentication
- SSH Key Path: The path to the SSH private key file on the MCP server
The tool validates each input:
- Device names must be unique
- IP addresses must be valid
- SSH key files must exist and be readable
- Optional connection test before adding the device
Security Note
The add_device tool only supports SSH key authentication. Password authentication has been disabled for security reasons and because VSCode's elicitation UI doesn't properly mask password fields.
Example Usage
In VSCode with GitHub Copilot:
@jmcp Please add a new device to the MCP server
The tool will then guide you through the process:
- Enter device name:
vsrx-lab1 - Enter IP address:
10.0.1.100 - Enter SSH port:
22(or press Enter for default) - Enter username:
admin - Enter SSH key path:
/home/user/.ssh/junos_key.pem - Confirm and optionally test connection
After successful addition, the device is immediately available for use with all other Junos MCP tools.
SSH Key Requirements
- The SSH private key file must exist on the MCP server filesystem
- The file must be readable by the process running the MCP server
- For Docker deployments, mount the SSH key file into the container
Example Docker mount:
docker run --rm -it \
-v /path/to/devices.json:/app/config/devices.json \
-v /path/to/ssh_key.pem:/app/config/ssh_key.pem \
-p 30030:30030 \
junos-mcp-server:latest \
python jmcp.py -f /app/config/devices.json -t streamable-http -H 0.0.0.0
Limitations
- VSCode Only: Elicitation is not supported in Claude Desktop
- SSH Key Only: No password authentication support
- No Persistence: Added devices are only stored in memory; they will be
lost when the server restarts
- Timeout: Users have 5 minutes to respond to each prompt
For Claude Desktop users, devices must still be configured in the devices.json file as described in the [Junos device config](#junos-device-configuration) section.
VSCode + GitHub Copilot Integration
Start Your Server
python3.11 jmcp.py -f devices.json
[06/11/25 08:26:11] INFO Starting MCP server 'jmcp-server' with transport
'streamable-http' on http://127.0.0.1:30030/mcp
INFO: Started server process [33512]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:30030 (Press CTRL+C to quit)
Point to This URL in Your VSCode Config
{
"mcp": {
"servers": {
"my-junos-mcp-server": {
"url": "http://127.0.0.1:30030/mcp/"
}
}
}
}
Note: You can use VSCode's Cmd+Shift+P to configure MCP server.
Authentication for MCP Server Access
The Junos MCP server supports token-based authentication for secure client access when using streamable-http transport.
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Juniper
- Source: Juniper/junos-mcp-server
- License: Apache-2.0
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.