### MCP Server Startup Examples Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/configuration.md Use these examples to start the MCP server in different environments. Adjust file paths and network configurations as needed. ```bash # Development with stdio (Claude Desktop) python jmcp.py -f devices.json -t stdio ``` ```bash # Development with streamable-http (VSCode) without auth python jmcp.py -f devices.json -t streamable-http -H 127.0.0.1 \ --allow-unauthenticated-http ``` ```bash # Production with streamable-http and authentication python jmcp_token_manager.py generate --id prod-client python jmcp.py -f /etc/junos-mcp/devices.json \ -t streamable-http -H 0.0.0.0 -p 30030 ``` ```bash # Docker docker run --rm -it \ -v /path/to/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 ``` -------------------------------- ### Complete PyEZ Device Connection Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/utilities.md A full example demonstrating how to use prepare_connection_params to get connection arguments and then establish a connection to a Juniper device using PyEZ. ```python from utils.config import prepare_connection_params from jnpr.junos import Device device_info = { "ip": "192.168.1.1", "port": 22, "username": "admin", "auth": { "type": "ssh_key", "private_key_path": "/home/user/.ssh/junos_key.pem" } } try: params = prepare_connection_params(device_info, "router-1") # params = { # "host": "192.168.1.1", # "port": 22, # "user": "admin", # "gather_facts": False, # "timeout": 360, # "ssh_private_key_file": "/home/user/.ssh/junos_key.pem" # } with Device(**params) as junos: print(junos.cli("show version")) except ValueError as e: print(f"Configuration error: {e}") except Exception as e: print(f"Connection error: {e}") ``` -------------------------------- ### Start Junos MCP Server Source: https://github.com/juniper/junos-mcp-server/blob/main/README.md Starts the MCP server using a specified devices configuration file. Ensure Python 3.11 is installed. ```bash 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) ``` -------------------------------- ### Password Authentication Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/types.md Example of a device configuration using password-based authentication. ```json { "router-1": { "ip": "192.168.1.1", "port": 22, "username": "admin", "auth": { "type": "password", "password": "mypassword" } } } ``` -------------------------------- ### Complete Device Configuration Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/configuration.md Provides a comprehensive example of the device configuration JSON file, demonstrating various authentication methods and optional fields. ```json { "router-1": { "ip": "192.168.1.1", "port": 22, "username": "admin", "auth": { "type": "ssh_key", "private_key_path": "/home/user/.ssh/junos_key.pem" } }, "router-2": { "ip": "192.168.1.2", "port": 22, "username": "admin", "auth": { "type": "password", "password": "securepassword" } }, "router-3": { "ip": "172.20.20.11", "port": 22, "username": "admin", "auth": { "type": "ssh_key", "private_key_path": "/home/user/.ssh/junos_key.pem" }, "ssh_config": "/home/user/.ssh/config_jumphost" } } ``` -------------------------------- ### Jump Host Configuration Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/types.md Example of a device configuration including an SSH config file path for jump host support. ```json { "router-3": { "ip": "172.20.20.11", "port": 22, "username": "admin", "auth": { "type": "ssh_key", "private_key_path": "/home/user/.ssh/id_rsa" }, "ssh_config": "/home/user/.ssh/config_jumphost" } } ``` -------------------------------- ### SSH Key Authentication Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/types.md Example of a device configuration using SSH key-based authentication. ```json { "router-2": { "ip": "192.168.1.2", "port": 22, "username": "admin", "auth": { "type": "ssh_key", "private_key_path": "/home/user/.ssh/id_rsa" } } } ``` -------------------------------- ### Install Dependencies Source: https://github.com/juniper/junos-mcp-server/blob/main/CLAUDE.md Installs project dependencies using pip. Ensure requirements.txt is present. ```bash pip install -r requirements.txt ``` -------------------------------- ### Token File Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/types.md An example of a .tokens file containing authentication tokens for streamable-http access. It shows multiple token entries with their respective details. ```json { "vscode-dev": { "token": "jmcp_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8", "description": "VSCode development environment", "created": "2025-01-28T10:30:00Z" }, "prod-client": { "token": "jmcp_x9y8z7w6v5u4t3s2r1q0p9o8n7m6l5k4j3i2", "description": "Production client access", "created": "2025-01-28T09:15:00Z" } } ``` -------------------------------- ### Real-World Performance Example Source: https://github.com/juniper/junos-mcp-server/blob/main/docs/PARALLEL_EXECUTION_EXPLAINED.md Provides a concrete example of performance gains with 10 routers, demonstrating a 5x speedup by comparing serial execution time (15.0s) with parallel execution time (3.0s). ```text 10 routers, average response: 1.5s, slowest: 3.0s Serial: 10 × 1.5s = 15.0s Parallel: 3.0s (limited by slowest) Speedup: 5x faster ``` -------------------------------- ### Example Blocked Configuration Patterns Source: https://github.com/juniper/junos-mcp-server/blob/main/README.md This example shows patterns in `block.cfg` that are blocked during configuration commits. Each line is a regex pattern matched against normalized config lines. ```text # Blocked configuration prefixes/patterns for load_and_commit_config set system root-authentication set system login user ([^ ]+) authentication ``` -------------------------------- ### Password Authentication Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/utilities.md Demonstrates the input device_info structure for password authentication. The returned parameters will include the 'password' key. ```python # Input device_info = { "ip": "192.168.1.1", "port": 22, "username": "admin", "auth": { "type": "password", "password": "mypassword" } } # Returned params include: # "password": "mypassword" ``` -------------------------------- ### Start MCP Server Commands Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/README.md Commands to start the MCP server using different transport modes and authentication settings. ```bash # Claude Desktop (stdio) python jmcp.py -f devices.json -t stdio ``` ```bash # VSCode development (no auth) python jmcp.py -f devices.json -t streamable-http -H 127.0.0.1 \ --allow-unauthenticated-http ``` ```bash # VSCode production (with auth) python jmcp_token_manager.py generate --id mytoken python jmcp.py -f devices.json -t streamable-http -H 0.0.0.0 ``` -------------------------------- ### Token Format Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/configuration.md An example of a valid authentication token, showing the required `jmcp_` prefix followed by 32 base64url-encoded characters. ```text jmcp_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8 ``` -------------------------------- ### Handle Command Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/types.md Example of using the Context object within an async function to handle commands. It demonstrates logging, reporting progress, and returning results. ```python async def handle_command(arguments: dict, context: Context): await context.info(f"Processing {arguments['command']}") await context.report_progress(50, 100) result = perform_operation() return [types.TextContent(type="text", text=result)] ``` -------------------------------- ### SSH Config (Jump Host) Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/utilities.md Illustrates how to include an SSH configuration file path for jump host scenarios. The 'ssh_config' parameter will be set accordingly. ```python # Input device_info = { "ip": "172.20.20.11", "port": 22, "username": "admin", "auth": { "type": "ssh_key", "private_key_path": "/home/user/.ssh/id_rsa" }, "ssh_config": "/home/user/.ssh/config_jumphost" } # Returned params include: # "ssh_config": "/home/user/.ssh/config_jumphost" ``` -------------------------------- ### Initiate Device Addition via Copilot Source: https://github.com/juniper/junos-mcp-server/blob/main/README.md Use this command in VSCode with GitHub Copilot to start the `add_device` process. The tool will then prompt for device details. ```text @jmcp Please add a new device to the MCP server ``` -------------------------------- ### Start MCP Server with Streamable HTTP and Tokens Source: https://github.com/juniper/junos-mcp-server/blob/main/README.md Starts the MCP server with streamable-http transport enabled, requiring token-based authentication. Ensure a valid .tokens file is present. ```bash python jmcp.py -f devices.json -t streamable-http INFO - Token-based authentication enabled INFO - Clients must send 'Authorization: Bearer ' header INFO - Use jmcp_token_manager.py to manage tokens INFO - Streamable HTTP server started on http://127.0.0.1:30030 ``` -------------------------------- ### SSH Key Authentication Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/utilities.md Shows the input device_info for SSH key authentication. The function will return 'ssh_private_key_file' based on this configuration. ```python # Input device_info = { "ip": "192.168.1.2", "port": 22, "username": "admin", "auth": { "type": "ssh_key", "private_key_path": "/home/user/.ssh/id_rsa" } } # Returned params include: # "ssh_private_key_file": "/home/user/.ssh/id_rsa" ``` -------------------------------- ### block.cfg Configuration Blocklist Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/configuration.md This example shows how to define patterns in block.cfg to prevent specific configuration commands from being loaded. It includes patterns for protecting root authentication, user authentication with dynamic usernames, and SNMP community strings. ```configuration # block.cfg - Blocked configuration patterns # Protect root authentication set system root-authentication # Protect user authentication with dynamic username set system login user ([^ ]+) authentication # Protect community strings set snmp community (.*) ``` -------------------------------- ### Direct Threading Example (Won't work with async/await) Source: https://github.com/juniper/junos-mcp-server/blob/main/docs/PARALLEL_EXECUTION_EXPLAINED.md This example demonstrates how direct use of `threading.Thread` does not integrate with Python's `async/await` syntax, making it impossible to `await` the result of the threaded operation. `anyio.to_thread.run_sync` is preferred for bridging synchronous code with asynchronous execution. ```python # This WON'T work with async/await thread = threading.Thread(target=_run_junos_cli_command, args=(...)) thread.start() # How do we await the result? We can't! ``` -------------------------------- ### Example Blocked Operational Command Patterns Source: https://github.com/juniper/junos-mcp-server/blob/main/README.md This example shows patterns in `block.cmd` that are blocked when executing operational commands. Each line is a regex pattern matched against normalized commands. ```text # Blocked operational command prefixes/patterns for execute_junos_command request system reboot request system halt request system power-cycle request system power-off request system zeroize ``` -------------------------------- ### Common Tool Input Schema Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/README.md Illustrates a typical input schema for MCP tools, specifying required parameters like router name and command. ```json { "type": "object", "properties": { "router_name": {"type": "string", "description": "..."}, "command": {"type": "string", "description": "..."}, "timeout": {"type": "integer", "default": 360} }, "required": ["router_name", "command"] } ``` -------------------------------- ### block.cmd Operational Command Blocklist Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/configuration.md This example demonstrates how to use block.cmd to block specific operational commands. It includes patterns for preventing disruptive commands like reboot and halt, as well as sensitive commands like software deletion. ```configuration # block.cmd - Blocked operational commands # Block disruptive operations request system reboot request system halt request system power-cycle request system power-off request system zeroize # Block sensitive operations request system software delete ``` -------------------------------- ### VSCode Configuration with Authorization Header Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/configuration.md Example of how to configure the VSCode settings to include the authentication token in the `Authorization` header for connecting to the Junos MCP Server. ```json { "mcp": { "servers": { "my-junos-mcp-server": { "url": "http://127.0.0.1:30030/mcp/", "headers": { "Authorization": "Bearer jmcp_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8" } } } } } ``` -------------------------------- ### MCP Server Fails to Start Without Tokens Source: https://github.com/juniper/junos-mcp-server/blob/main/README.md Demonstrates the server's default behavior of refusing to start the streamable-http transport when no .tokens file is found. This enforces authentication. ```bash python jmcp.py -f devices.json -t streamable-http ERROR - Refusing to start streamable-http transport without authentication: .tokens file not found ERROR - Generate a token with: python jmcp_token_manager.py generate --id ERROR - Or, for local development on loopback only, re-run with --allow-unauthenticated-http ``` -------------------------------- ### Example Batch Command Response Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/types.md An example JSON response illustrating the structure and typical data for a batch command execution, including successful and failed router results. ```json { "summary": { "total_routers": 3, "successful": 2, "failed": 1, "batch_execution_duration": 5.234 }, "results": [ { "router_name": "router-1", "status": "success", "output": "fxp0.0: up\nge-0/0/0.0: up", "execution_duration": 2.103, "start_time": "2025-06-18T10:30:15.123456Z", "end_time": "2025-06-18T10:30:17.226456Z" }, { "router_name": "router-2", "status": "success", "output": "fxp0.0: up\nge-0/0/1.0: up", "execution_duration": 1.891, "start_time": "2025-06-18T10:30:15.234567Z", "end_time": "2025-06-18T10:30:17.125567Z" }, { "router_name": "router-3", "status": "failed", "output": "Connection error to router-3: [Errno 111] Connection refused", "execution_duration": 5.234, "start_time": "2025-06-18T10:30:15.345678Z", "end_time": "2025-06-18T10:30:20.579678Z" } ] } ``` -------------------------------- ### Device Authentication Methods (PyEZ) Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/README.md Examples of device authentication using password, SSH key, and jump host configurations with PyEZ. ```python auth: {type: "password", password: "pwd"} ``` ```python auth: {type: "ssh_key", private_key_path: "/path/to/key"} ``` ```python ssh_config: "/path/to/config" # SSH config file must define ProxyCommand for the device. ``` -------------------------------- ### JSON Input Schema Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/ANALYSIS.md This is an example of a JSON input schema for an MCP tool, defining parameter types, required fields, and default values. ```json { "type": "object", "properties": { "router_name": {"type": "string"}, "command": {"type": "string"}, "timeout": {"type": "integer", "default": 360} }, "required": ["router_name", "command"] } ``` -------------------------------- ### Docker Mount for SSH Key and Config Source: https://github.com/juniper/junos-mcp-server/blob/main/README.md Example Docker command to run the Junos MCP server, mounting the SSH key and device configuration file. Ensure the paths are correct for your environment. ```bash 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 ``` -------------------------------- ### Run Server with Streamable-HTTP Transport Source: https://github.com/juniper/junos-mcp-server/blob/main/CLAUDE.md Starts the MCP server with streamable-HTTP transport for VSCode integration. Specify host and port for the server. ```bash python3.11 jmcp.py -f devices.json -t streamable-http -H 127.0.0.1 -p 30030 ``` -------------------------------- ### SSH Configuration with ProxyCommand for Jumphost Access Source: https://github.com/juniper/junos-mcp-server/blob/main/README.md Example SSH configuration file demonstrating the use of ProxyCommand to access devices through a jumphost. This is useful when direct access is not possible and an intermediary host with netcat is available. ```bash # 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 ``` -------------------------------- ### Clone Junos MCP Server Repository Source: https://github.com/juniper/junos-mcp-server/blob/main/docs/junos-mcp-server-article.html Clone the official repository to your local machine to begin the installation process. ```bash git clone https://github.com/Juniper/junos-mcp-server.git cd junos-mcp-server ``` -------------------------------- ### Token File Format Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/configuration.md The .tokens file stores authentication tokens in a JSON format. Each entry includes the token itself, a human-readable description, and the creation timestamp. ```json { "token-id": { "token": "jmcp_xxxxx...", "description": "Human-readable description", "created": "2025-01-28T10:30:00Z" } } ``` -------------------------------- ### Get Router List Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/README.md Lists all configured devices managed by the MCP server. ```APIDOC ## get_router_list ### Description Lists all configured devices managed by the MCP server. ### Return Value - **routers** (list) - A list of device names. ### Example ```python router_list = mcp_client.get_router_list() print(router_list) ``` ``` -------------------------------- ### Error: streamable-http Without Authentication Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/configuration.md The streamable-http transport refuses to start without authentication when the .tokens file is not found. Generate a token or use --allow-unauthenticated-http for local development. ```text ERROR - Refusing to start streamable-http transport without authentication: .tokens file not found ERROR - Generate a token with: python jmcp_token_manager.py generate --id ERROR - Or, for local development on loopback only, re-run with --allow-unauthenticated-http Exit code: 1 ``` -------------------------------- ### PyEZ Device Connection and Operations Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/ANALYSIS.md Demonstrates connecting to a Junos device using PyEZ, executing CLI commands, managing configurations, and invoking RPC methods. Ensure PyEZ is installed and device connection parameters are correctly set. ```python from jnpr.junos import Device from jnpr.junos.utils.config import Config # Connection with Device(**params) as junos: # CLI commands result = junos.cli("show version") # Configuration management config = Config(junos) config.load(config_text, format="set") config.commit() # RPC methods facts = junos.rpc.get_route_information() ``` -------------------------------- ### MCP Tool Call Example Source: https://github.com/juniper/junos-mcp-server/blob/main/docs/junos-mcp-server-article.html This JSON-RPC 2.0 message demonstrates how an MCP client might call the 'execute_junos_command' tool to retrieve BGP status from a Junos device. ```json { "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "execute_junos_command", "arguments": { "router_name": "edge-01", "command": "show bgp summary" } }, "id": "call_123" } ``` -------------------------------- ### Invalid YAML Syntax Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/errors.md This example demonstrates incorrect indentation in a YAML file, which can lead to parsing errors when processing variables for template rendering. ```yaml hostname: router1 interfaces: - name: ge-0/0/0 # Wrong indentation ip: 192.168.1.1 ``` -------------------------------- ### Create Device Configuration File Source: https://github.com/juniper/junos-mcp-server/blob/main/docs/junos-mcp-server-article.html Define your network devices, including IP addresses, ports, and authentication details, in a JSON file. ```json { "router1": { "ip": "192.168.1.1", "port": 22, "username": "admin", "auth": { "type": "ssh_key", "private_key_path": "/path/to/key.pem" } } } ``` -------------------------------- ### Configuration Formats Supported (Set) Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/ANALYSIS.md Illustrates the 'set' format for configuration, which uses flat commands. This format is suitable for direct command-line entry or scripting. ```text set system host-name router1 set system domain-name example.com ``` -------------------------------- ### Start MCP Server Unauthenticated (Loopback Only) Source: https://github.com/juniper/junos-mcp-server/blob/main/README.md Starts the MCP server in unauthenticated mode for streamable-http transport, specifically for local development on loopback interfaces. This bypasses token authentication. ```bash python jmcp.py -f devices.json -t streamable-http --allow-unauthenticated-http WARNING - *** Streamable HTTP authentication is DISABLED (--allow-unauthenticated-http). .tokens file not found. Server is open to any client that can reach 127.0.0.1:30030 and can commit configuration to mapped devices. Use only for local development. *** INFO - Streamable HTTP server started on http://127.0.0.1:30030 ``` -------------------------------- ### Show Junos MCP Server Help Source: https://github.com/juniper/junos-mcp-server/blob/main/README.md Use this command to display all available command-line options for the Junos MCP Server. This is useful for understanding the server's configurable parameters. ```bash 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 ``` -------------------------------- ### Get Junos Configuration Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/README.md Retrieves the configuration of a Junos device. ```APIDOC ## get_junos_config ### Description Retrieves the configuration of a Junos device. ### Parameters - **device_name** (string) - Required - The name of the device. - **format** (string) - Optional - The desired configuration format (e.g., 'json', 'text'). Defaults to 'text'. ### Return Value - **configuration** (string) - The device configuration in the specified format. ### Example ```python config = mcp_client.get_junos_config("router1", format="json") print(config) ``` ``` -------------------------------- ### Run with Default Settings (stdio) Source: https://github.com/juniper/junos-mcp-server/blob/main/README.md Runs the Docker container with default stdio transport. Mount your devices.json file to the container's config directory. ```bash docker run --rm -it -v /path/to/your/devices.json:/app/config/devices.json junos-mcp-server:latest ``` -------------------------------- ### Junos Configuration Formats Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/README.md Demonstrates the three supported formats for Junos configuration: set, text, and XML. ```text set system host-name router1 set system domain-name example.com ``` ```text system { host-name router1; domain-name example.com; } ``` ```xml router1 ``` -------------------------------- ### YAML Configuration Variables Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/ANALYSIS.md Example of YAML-based variables used for template substitution in Jinja2. Ensure variables are correctly formatted for substitution. ```yaml hostname: router1 ntp_server: 10.0.0.1 interfaces: - name: ge-0/0/0 ip: 192.168.1.1/24 ``` -------------------------------- ### Specify Device Mapping File Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/configuration.md Specifies the JSON file containing device configuration to be loaded at server startup. The server searches for this file in a defined order. ```bash python jmcp.py -f /path/to/devices.json -t stdio ``` ```bash python jmcp.py --device-mapping /etc/junos-mcp/devices.json -t stdio ``` -------------------------------- ### Main CLI Entry Point Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/utilities.md The main entry point for the token manager CLI. It supports commands for generating, listing, showing, and revoking tokens. ```bash python jmcp_token_manager.py [options] ``` ```bash generate --id [--description ] Generate a new token ``` ```bash list List all tokens (without values) ``` ```bash show --id Show a specific token value ``` ```bash revoke --id Revoke a token ``` ```bash # Generate a token python jmcp_token_manager.py generate --id vscode-dev \ --description "VSCode development environment" ``` ```bash # List tokens python jmcp_token_manager.py list ``` ```bash # Show token value python jmcp_token_manager.py show --id vscode-dev ``` ```bash # Revoke token python jmcp_token_manager.py revoke --id vscode-dev ``` -------------------------------- ### Monitor Thread Pool Size Source: https://github.com/juniper/junos-mcp-server/blob/main/docs/PARALLEL_EXECUTION_EXPLAINED.md Print the current number of active threads in the default thread limiter. Requires the anyio library to be installed. ```python import anyio print(f"Active threads: {anyio.to_thread.current_default_thread_limiter().total_tokens}") ``` -------------------------------- ### List All MCP Server Tokens Source: https://github.com/juniper/junos-mcp-server/blob/main/README.md Lists all generated authentication tokens, including their ID, description, and creation timestamp. This command helps in managing existing tokens. ```bash python jmcp_token_manager.py list # Example output: ID Description Created ------------------------------------------------------------------------------------- vscode-dev VSCode development environment 2025-01-28T10:30:00Z prod-client Production client access 2025-01-28T09:15:00Z ``` -------------------------------- ### Test Tool Handler Directly Source: https://github.com/juniper/junos-mcp-server/blob/main/README.md Provides an example of how to directly test a tool's handler function with mock arguments. This is useful for unit testing. ```python # Test the handler directly result = await handle_my_new_tool({ "router_name": "router-1", "my_param": "test" }) print(result[0].text) ``` -------------------------------- ### Prepare Junos Connection Parameters Source: https://github.com/juniper/junos-mcp-server/blob/main/docs/junos-mcp-server-article.html Prepares connection parameters for Junos devices, supporting password and SSH key authentication. Ensure 'auth' dictionary contains 'type' and relevant credentials. ```python def prepare_connection_params(router_config, router_name): """Prepare connection parameters based on auth type""" base_params = { "host": router_config["ip"], "port": router_config.get("port", 22), "user": router_config["username"], "device_params": {"name": router_name} } auth = router_config.get("auth", {}) auth_type = auth.get("type", "password") if auth_type == "password": base_params["password"] = auth.get("password") elif auth_type == "ssh_key": base_params["ssh_private_key_file"] = auth.get("private_key_path") passphrase = auth.get("passphrase") if passphrase: base_params["ssh_private_key_passphrase"] = passphrase return base_params ``` -------------------------------- ### Regex Blocklist for Configuration Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/README.md Illustrates the use of regular expressions in `block.cfg` to prevent specific configuration commands from being applied. Prefix matching is used. ```regex # block.cfg example set system root-authentication # Blocks all root auth commands set system login user ([^ ]+) password # Blocks user password with any username ``` -------------------------------- ### Prepare Connection Parameters Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/README.md Prepares PyEZ Device connection parameters. ```APIDOC ## prepare_connection_params ### Description Prepares PyEZ Device connection parameters from device information. ### Parameters - **device_name** (string) - Required - The name of the device. ### Return Value - **params** (dict) - A dictionary of connection parameters. ### Example ```python conn_params = utils.config.prepare_connection_params("router1") print(conn_params) ``` ``` -------------------------------- ### Elicitation Flow for Adding a Device Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/ANALYSIS.md Illustrates the interactive prompt sequence for adding a new device to the MCP system. Each step validates user input according to specified constraints. ```text User → "add a device" ↓ 1. Device name? (unique, 1-50 chars) ↓ 2. IP address? (IPv4 validation) ↓ 3. SSH port? (1-65535, default 22) ↓ 4. Username? (min 1 char) ↓ 5. SSH key path? (must exist and be readable) ↓ 6. Confirm and optionally test connection? ↓ Device added to memory ``` -------------------------------- ### Run Junos MCP Server with Docker (Stdio Transport) Source: https://github.com/juniper/junos-mcp-server/blob/main/docs/junos-mcp-server-article.html Deploy the MCP server using Docker with stdio transport, mounting necessary configuration and key files. ```bash docker run --rm -it \ -v /path/to/devices.json:/app/config/devices.json \ -v /path/to/ssh/keys:/app/keys \ junos-mcp-server:latest ``` -------------------------------- ### Command Blocked by Guardrail Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/errors.md This error message signifies that a command matched a pattern in 'block.cmd'. It prevents execution before any device connection. Review 'block.cmd' or use an alternative command. ```text Blocked command rejected: command '{command}' matches blocked pattern '{pattern}' ``` ```text Command: "request system reboot" Blocked pattern: "request system reboot" ``` -------------------------------- ### Load and Commit Configuration Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/README.md Applies and commits a configuration to a Junos device. ```APIDOC ## load_and_commit_config ### Description Applies and commits configurations to Junos devices. ### Parameters - **device_name** (string) - Required - The name of the device. - **configuration** (string) - Required - The configuration to apply. - **commit_options** (dict) - Optional - Options for the commit operation (e.g., {'comment': 'Applied via MCP'}). ### Return Value - **status** (string) - The status of the operation (e.g., 'success', 'failed'). ### Example ```python result = mcp_client.load_and_commit_config("router1", "set system host-name new-hostname", commit_options={'comment': 'Set by MCP'}) print(result.status) ``` ``` -------------------------------- ### Disable HTTP Authentication for Streamable Transport Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/configuration.md Disables token authentication for the streamable-http transport, allowing it to start without a `.tokens` file. This is only permitted with loopback bindings and should only be used for local development. ```bash # Local development without tokens python jmcp.py -f devices.json -t streamable-http -H 127.0.0.1 \ --allow-unauthenticated-http ``` -------------------------------- ### Configuration Blocked by Guardrail Example Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/errors.md This error message indicates that a configuration line matched a pattern defined in 'block.cfg'. It occurs before any device connection. Review and modify the configuration or update 'block.cfg' to resolve. ```text Blocked configuration rejected: line '{line}' matches blocked pattern '{pattern}' ``` ```text Config line: "set system root-authentication encrypted-password ..." Blocked pattern: "set system root-authentication" ``` -------------------------------- ### Check Configuration Blocklist Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/api-reference.md Validates configuration text against a blocklist file. Supports regex and token-based matching for patterns. ```python def check_config_blocklist( config_text: str, block_file: str = "block.cfg" ) -> tuple[bool, str | None]: ``` ```text # block.cfg set system root-authentication set system login user ([^ ]+) authentication ``` -------------------------------- ### Get Junos Configuration Diff Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/api-reference.md Compares the current running configuration with a specified rollback version on a router. The 'version' parameter is optional and defaults to 1 (previous commit). Ensure the rollback version is valid. ```python # See changes from the previous commit result = await client.call_tool("junos_config_diff", { "router_name": "router-1", "version": 1 }) # See changes from 5 commits ago result = await client.call_tool("junos_config_diff", { "router_name": "router-1", "version": 5 }) ``` -------------------------------- ### Configuration Formats Supported (Text) Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/ANALYSIS.md Shows the hierarchical 'text' format for configuration. This is a more human-readable representation of Junos configuration. ```text system { host-name router1; domain-name example.com; } ``` -------------------------------- ### Router Response Time Variation Example Source: https://github.com/juniper/junos-mcp-server/blob/main/docs/PARALLEL_EXECUTION_EXPLAINED.md Visualizes how varying response times across routers affect the total parallel execution time. The total time is determined by the slowest router's response, not the sum of all response times. ```text Router1: [====] (400ms - fast response) Router2: [==========] (1000ms - normal) Router3: [==============] (1400ms - slow) Total: [==============] (1400ms - limited by slowest) ``` -------------------------------- ### Run Server with Stdio Transport Source: https://github.com/juniper/junos-mcp-server/blob/main/CLAUDE.md Launches the MCP server using stdio transport, suitable for Claude Desktop integration. Requires a devices.json configuration file. ```bash python3.11 jmcp.py -f devices.json -t stdio ``` -------------------------------- ### Render and Apply Jinja2 Template Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/README.md Renders Jinja2 templates and applies the resulting configuration to devices. ```APIDOC ## render_and_apply_j2_template ### Description Renders Jinja2 templates and applies the resulting configuration to devices. ### Parameters - **device_name** (string) - Required - The name of the device. - **template_path** (string) - Required - The path to the Jinja2 template file. - **context_data** (dict) - Required - Data to be used for rendering the template. ### Return Value - **status** (string) - The status of the operation. ### Example ```python context = {"hostname": "new-router", "domain": "example.com"} result = mcp_client.render_and_apply_j2_template("router1", "/path/to/template.j2", context) print(result.status) ``` ``` -------------------------------- ### Device Configuration Schema Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/types.md Defines the structure for connecting to Junos devices. Includes IP, port, username, and authentication details. ```python { "router-name": { "ip": str, # Device IP address (required) "port": int, # SSH port (required) "username": str, # SSH username (required) "auth": { "type": "password", "password": str } | { "type": "ssh_key", "private_key_path": str }, "ssh_config": str # Optional: path to SSH config file (for ProxyCommand) } } ``` -------------------------------- ### Run with Streamable-HTTP (Custom Port) Source: https://github.com/juniper/junos-mcp-server/blob/main/README.md Runs the Docker container with streamable-http transport on a custom host port. Mount necessary files and specify the custom port. ```bash 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 ``` -------------------------------- ### List All Tokens Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/configuration.md View all currently managed authentication tokens using the `list` command of the `jmcp_token_manager.py` script. This displays their IDs, descriptions, and creation dates. ```bash python jmcp_token_manager.py list ``` -------------------------------- ### Error Handling with Device Connection Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/README.md Demonstrates how to handle potential connection errors when interacting with Junos devices using a try-except block. Catches specific ConnectError and general Exceptions. ```python # Try connection try: with Device(**connect_params) as junos_device: # Perform operation result = junos_device.cli(command) except ConnectError as ce: result = f"Connection error: {ce}" except Exception as e: result = f"An error occurred: {e}" ``` -------------------------------- ### Run Junos MCP Server with uv Source: https://github.com/juniper/junos-mcp-server/blob/main/README.md This command runs the Junos MCP server using uv, specifying the devices configuration file and the communication transport. ```bash uv run python jmcp.py -f devices.json -t stdio ``` -------------------------------- ### Error: Missing Device Mapping File Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/configuration.md This error occurs when the specified device configuration file cannot be found. Ensure the file path is correct. ```text File not found. Exit code: 1 ``` -------------------------------- ### Context Methods Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/types.md This section details the methods available on the Context object for reporting progress, reading resources, eliciting information, and logging. ```APIDOC ## Context Methods ### Description Provides access to MCP capabilities and lifecycle management. ### Methods #### `report_progress(progress: float, total: float | None = None, message: str | None = None)` Report progress for the current operation. #### `read_resource(uri: str | AnyUrl)` Read a resource by URI. #### `elicit(message: str, schema: type[ElicitSchemaModelT])` Interactively elicit information from the client. #### `log(level: Literal["debug", "info", "warning", "error"], message: str, logger_name: str | None = None)` Send a log message to the client. #### `debug(message: str, **extra)` Convenience method for debug-level log. #### `info(message: str, **extra)` Convenience method for info-level log. #### `warning(message: str, **extra)` Convenience method for warning-level log. #### `error(message: str, **extra)` Convenience method for error-level log. ``` -------------------------------- ### Authentication Token Management Commands Source: https://github.com/juniper/junos-mcp-server/blob/main/_autodocs/README.md Commands for managing authentication tokens, including generation, listing, showing, and revoking. ```bash # Generate token python jmcp_token_manager.py generate --id vscode-dev ``` ```bash # List tokens (no values shown) python jmcp_token_manager.py list ``` ```bash # Show token value (for recovery) python jmcp_token_manager.py show --id vscode-dev ``` ```bash # Revoke token python jmcp_token_manager.py revoke --id vscode-dev ```