Juniper Junos MCP Server
Un servidor MCP para interactuar con dispositivos de red Juniper Junos utilizando LLMs.
Documentación
junos-mcp-server
Un servidor de Model Context Protocol (MCP) para dispositivos Juniper Junos que permite interacciones de LLM con equipos de red.
Tabla de contenidos
- junos-mcp-server
- Tabla de contenidos
- Aviso de seguridad importante
- Aviso importante de configuración
- Primeros pasos
- Iniciar Junos MCP Server
- Configuración
- Uso de Docker
- Configuración de dispositivos Junos
- Integración con VSCode + GitHub Copilot
- Autenticación para acceso al servidor MCP
- GuardRails para confirmación de configuración
- GuardRails para ejecutar comandos operativos
- Uso del servidor MCP con Juniper Cloud-Native Router (JCNR)
- Guía para desarrolladores
Aviso de seguridad importante
Advertencia: Este servidor permite el acceso de LLM a su infraestructura de red. Revise cuidadosamente estas consideraciones de seguridad.
Requisitos de seguridad
-
Cumplimiento de políticas corporativas: Use este servidor solo si la política de su empresa permite enviar datos de dispositivos Junos a servicios LLM.
-
Seguridad del servidor: Asegure siempre su servidor Junos MCP antes de implementarlo en entornos de producción.
-
Autenticación: No use autenticación por contraseña para implementaciones de producción. Recomendamos encarecidamente usar autenticación basada en claves SSH para mayor seguridad.
-
Estrategia de implementación: Hasta que su servidor MCP esté debidamente asegurado, impleméntelo solo localmente para fines de prueba. No implemente servidores remotos en producción sin las medidas de seguridad adecuadas.
Mejores prácticas de seguridad
- Use autenticación por clave SSH en lugar de contraseñas
- Implemente controles de acceso de red adecuados
- Supervise y registre todas las actividades del servidor MCP
- Realice auditorías y actualizaciones de seguridad periódicas
- Siga las políticas de seguridad de su organización
Aviso importante de configuración
Advertencia: El servidor Junos MCP admite cambios de configuración, pero asegúrese de usar esta funcionalidad únicamente cuando desee que las configuraciones generadas por LLM se carguen y confirmen en su router Junos.
Revise siempre la configuración generada por el LLM y solo permita la ejecución de la herramienta si es la configuración correcta para su caso de uso.
Primeros pasos
Obtenga el código.
git clone https://github.com/Juniper/junos-mcp-server.git
cd junos-mcp-server
pip install -r requirements.txt
Ejecución con uv
Si está usando uv, puede ejecutar el servidor directamente:
uv run python jmcp.py -f devices.json -t stdio
Iniciar 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
El servidor Junos MCP admite transporte streamable-http y stdio. No use --host con transporte stdio.
Variables de entorno
JUNOS_TIMEOUT: Tiempo de espera de comando en segundos para operaciones CLI de Junos.JMCP_POOL_IDLE_TIMEOUT: Tiempo de espera de inactividad en segundos para conexiones SSH/NETCONF agrupadas.- Las sesiones SSH se reutilizan entre llamadas a herramientas mediante un grupo de conexiones; un subproceso de limpieza en segundo plano (que se ejecuta una vez por minuto) cierra las conexiones inactivas por más tiempo que este tiempo de espera.
- Predeterminado:
300. Los valores no válidos se registran y se recurre al valor predeterminado.
Configuración
Configuración para Claude Desktop (transporte stdio)
{
"mcpServers": {
"jmcp": {
"type": "stdio",
"command": "python3",
"args": ["jmcp.py", "-f", "devices.json", "-t", "stdio"]
}
}
}
Configuración para Claude Desktop (usando uv)
{
"mcpServers": {
"jmcp": {
"type": "stdio",
"command": "uv",
"args": ["run", "python", "jmcp.py", "-f", "devices.json", "-t", "stdio"]
}
}
}
Nota: Proporcione la ruta absoluta para jmcp.py y el archivo devices.json.
Configuración para Claude Desktop (contenedor Docker)
{
"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"
]
}
}
}
Uso de Docker
Crear el contenedor Docker
docker build -t junos-mcp-server:latest .
Ejecución con configuración predeterminada
De forma predeterminada, el contenedor Docker se ejecuta con transporte stdio:
docker run --rm -it -v /path/to/your/devices.json:/app/config/devices.json
junos-mcp-server:latest
Esto usa el comando predeterminado: python jmcp.py -f /app/config/devices.json -t stdio
Anulación de argumentos predeterminados
Puede anular cualquier argumento especificando el comando completo:
Para transporte stdio:
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
Para transporte streamable-http:
Seguridad: el transporte streamable-http se niega a iniciarse sin un archivo
.tokensválido. Genere uno conpython jmcp_token_manager.py generate --id <token-id>y móntelo en el contenedor como se muestra a continuación. Consulte Autenticación para obtener detalles, o pase--allow-unauthenticated-httppara desarrollo local solo de bucle de retorno.
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
Para transporte streamable-http con puerto personalizado:
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
Nota:
- Monte siempre su archivo de configuración de dispositivos usando
-v /ruta/a/su/ devices.json:/app/config/devices.json - Para transporte streamable-http, exponga el puerto usando
-p puerto_host:puerto_contenedor - Monte cualquier archivo de clave privada SSH si usa autenticación basada en claves (p. ej.,
-v /ruta/a/clave.pem:/app/config/clave.pem)
Cree el contenedor Docker para Junos MCP Server
docker build -t junos-mcp-server:latest .
Nota: Monte su archivo de configuración devices.json y monte cualquier otro archivo; en mi
caso, estoy usando un archivo pem para la autenticación de clave privada SSH, así que también
monto vsrx_keypair.pem
Configuración de dispositivos Junos
El servidor Junos MCP admite autenticación basada en password y basada en SSH key
(consulte las configuraciones de los primeros 2 routers [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"
}
}
}
El servidor Junos MCP también brinda soporte para ProxyCommand. (Consulte las últimas 2 configuraciones de
routers [router-3, router-4]), lo que le permite acceder a un dispositivo de destino
a través de un host intermediario que admite netcat. Esto es útil cuando solo
puede iniciar sesión en el dispositivo de destino a través del host intermedio (jumphost).
Este es un ejemplo de un archivo de configuración SSH que se usa .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
Nota #1: el valor de Port debe ser un entero (típicamente 22 para SSH).
Nota #2: IdentityFile recomendación: use la ruta completa (p. ej., /home/usuario/.ssh /id_rsa_claude rather than ~/.ssh/id_rsa_claude).
Integración con VSCode + GitHub Copilot
Inicie su servidor
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)
Apunte a esta URL en su configuración de VSCode
{
"mcp": {
"servers": {
"my-junos-mcp-server": {
"url": "http://127.0.0.1:30030/mcp/"
}
}
}
}
Nota: Puede usar Cmd+Shift+P de VSCode para configurar el servidor MCP.
Autenticación para acceso al servidor MCP
El servidor Junos MCP admite autenticación basada en tokens para acceso seguro de clientes cuando se usa transporte streamable-http. Esto evita el acceso no autorizado a su infraestructura de red.
Comportamiento de autenticación
- Transporte stdio (Claude Desktop): no se requiere autenticación; es seguro por diseño ya que se ejecuta localmente
- Transporte streamable-http (VSCode, clientes web): autenticación basada en tokens disponible
Gestión de tokens
El servidor incluye una herramienta CLI dedicada de gestión de tokens:
jmcp_token_manager.py
Generar un nuevo token
# Basic token generation
python jmcp_token_manager.py generate --id "vscode-dev"
# With description
python jmcp_token_manager.py generate --id "vscode-dev" --description "VSCode
development environment"
# Example output:
Generated new token:
ID: vscode-dev
Token: jmcp_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8
Description: VSCode development environment
Save this token securely - it won't be shown again!
Listar todos los tokens
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
Mostrar el valor del token (recuperación)
python jmcp_token_manager.py show --id "vscode-dev"
# Example output:
Token ID: vscode-dev
Token: jmcp_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8
Description: VSCode development environment
Created: 2025-01-28T10:30:00Z
Revocar un token
python jmcp_token_manager.py revoke --id "vscode-dev"
# Example output:
Token 'vscode-dev' has been revoked
Estado de autenticación del servidor
Para el transporte streamable-http, el servidor falla de forma cerrada: se niega
a iniciarse a menos que haya un archivo .tokens válido y no vacío presente. La única forma de
iniciar sin tokens es la bandera explícita --allow-unauthenticated-http,
que a su vez está restringida a enlaces de bucle de retorno (127.0.0.1, ::1,
localhost).
Con tokens configurados:
python jmcp.py -f devices.json -t streamable-http
INFO - Token-based authentication enabled
INFO - Clients must send 'Authorization: Bearer <token>' header
INFO - Use jmcp_token_manager.py to manage tokens
INFO - Streamable HTTP server started on http://127.0.0.1:30030
Sin tokens configurados (predeterminado: se niega a iniciarse):
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 <token-id>
ERROR - Or, for local development on loopback only, re-run with --allow-unauthenticated-http
Modo explícito sin autenticación (solo bucle de retorno, solo desarrollo):
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
La combinación de --allow-unauthenticated-http con un enlace que no sea de bucle de retorno (por
ejemplo, -H 0.0.0.0) se rechaza al inicio.
Configuración del cliente con autenticación
Configuración de VSCode con token
{
"mcp": {
"servers": {
"my-junos-mcp-server": {
"url": "http://127.0.0.1:30030/mcp/",
"headers": {
"Authorization": "Bearer
jmcp_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8"
}
}
}
}
}
Pruebas con curl
# Test authentication with valid token
curl -X POST "http://127.0.0.1:30030/mcp/" \
-H "Authorization: Bearer jmcp_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
# Test without token (should fail with 401)
curl -X POST "http://127.0.0.1:30030/mcp/" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
Nota: MCP streamable-http requiere el encabezado Accept: application/json, tex /event-stream.
Docker con autenticación
Al usar Docker, monte el archivo .tokens para habilitar la autenticación:
# Generate token first (outside container)
python jmcp_token_manager.py generate --id "docker-client"
# Run container with token file mounted
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
Mejores prácticas de seguridad
-
Seguridad de tokens:
- Almacene los tokens de forma segura (gestores de contraseñas, variables de entorno)
- Use identificadores de token descriptivos para una gestión fácil
- Rote los tokens periódicamente revocando los antiguos y generando nuevos
- Nunca confirme tokens en control de versiones
-
Control de acceso:
- Genere tokens separados para diferentes clientes/entornos
- Revoque los tokens inmediatamente cuando ya no sean necesarios
- Supervise los registros del servidor para detectar intentos de acceso no autorizado
-
Seguridad de red:
- Ejecute el servidor streamable-http detrás de un proxy inverso con HTTPS en producción
- Use reglas de firewall para restringir el acceso al puerto del servidor MCP
- Considere el acceso VPN para clientes remotos
Formato del archivo de tokens
El archivo .tokens almacena los tokens en formato 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"
}
}
Importante: Mantenga este archivo seguro y no lo confirme en control de versiones.
GuardRails para confirmación de configuración
La herramienta load_and_commit_config ahora incluye una verificación de guardrail previa a la confirmación que valida la configuración candidata enviada contra patrones en block.cfg antes de que se intenten acciones de confirmación en el dispositivo.
Cómo funciona
- Cada línea que no sea comentario en
block.cfgse trata como un patrón bloqueado. - La coincidencia de patrones se realiza contra líneas de configuración normalizadas del
config_textenviado. - Los patrones admiten tokens regex (por ejemplo, para coincidir con nombres de usuario dinámicos).
- Si alguna línea coincide, la solicitud se rechaza y no se carga ni confirma ninguna configuración.
Ejemplo de block.cfg
# Blocked configuration prefixes/patterns for load_and_commit_config
set system root-authentication
set system login user ([^ ]+) authentication
Esto protege áreas de configuración comunes de alto riesgo (por ejemplo, autenticación raíz o cambios no gestionados de credenciales de usuarios locales) de ser confirmadas por automatización.
GuardRails para ejecutar comandos operativos
Las herramientas execute_junos_command y execute_junos_command_batch ahora incluyen guardrails de comandos usando block.cmd.
Cómo funciona
- Cada línea que no sea comentario en
block.cmdse trata como un patrón de comando regex. - Los comandos enviados se normalizan y verifican antes de la ejecución.
- Si un comando coincide con un patrón bloqueado, la ejecución se rechaza.
- Para ejecución por lotes, el comando bloqueado se rechaza antes de enviarse a los routers.
Ejemplo de block.cmd
# 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
Esto bloquea comandos disruptivos (clases de acción reboot/power/zeroize) mientras que aún permite comandos operativos de solo lectura.
Uso del servidor MCP con Juniper Cloud-Native Router (JCNR)
JCNR es un router nativo de la nube que se ejecuta en varios entornos de nube. Se puede usar este servidor MCP con JCNR también siguiendo los pasos que se indican a continuación. Consulte la documentación de JCNR para obtener más detalles sobre la configuración.
- Configure el acceso SSH en JCNR en un puerto deseado distinto del 22. Esto es necesario porque JCNR se ejecuta como un contenedor en un sistema operativo compartido. No se recomienda ejecutar SSH en el puerto predeterminado. Por defecto, SSH está habilitado en el puerto 24. Pero es preferible cambiarlo al puerto deseado según sus necesidades de red.
- Habilite el método de autenticación para SSH. JCNR es compatible con autenticación basada en clave SSH y contraseña.
- Habilite Netconf sobre SSH. Esto está habilitado por defecto.
set system services netconf ssh
set system services ssh port 3030
set system services ssh root-login allow
set system root-authentication encrypted-password
"$6$3vvMI$RNemhmu9izWXzO46msh38frIg4VoeFNJWJZugxgnU.NQso3OQ00QWOIZmzNePD.MWjDOD
BBEYut/W7kfADdV." (or)
set system root-authentication load-key-file <public key>
Guía de Desarrollo
Esta sección explica la arquitectura del servidor MCP de Junos y cómo extenderlo con nuevas herramientas.
Resumen de la Arquitectura
El servidor MCP de Junos utiliza el Protocolo de Contexto de Modelo (MCP) para permitir que los LLM interactúen con dispositivos de red de Juniper. La arquitectura del servidor consta de:
- Núcleo del Servidor MCP (
jmcp.py): Maneja la comunicación del protocolo MCP - Manejadores de Herramientas: Funciones individuales que implementan operaciones de red específicas
- Registro de Herramientas: Asigna nombres de herramientas a sus funciones manejadoras
- Capa de Transporte: Compatible con stdio (Claude Desktop) y streamable-http (VSCode)
Cómo Funcionan las Herramientas
Cada herramienta del servidor MCP sigue este flujo:
Añadir una Nueva Herramienta
Añadir una nueva herramienta es un proceso simple de 3 pasos:
Paso 1: Crear una Función Manejadora
Cree una función manejadora asíncrona en jmcp.py (antes del diccionario TOOL_HANDLERS):
async def handle_my_new_tool(arguments: dict) -> list[types.ContentBlock]:
"""Handler for my_new_tool - describe what it does"""
# Extract arguments
router_name = arguments.get("router_name", "")
my_param = arguments.get("my_param", "default_value")
# Validate router exists
if router_name not in devices:
result = f"Router {router_name} not found in the device mapping."
else:
# Your tool logic here
log.debug(f"Executing my_new_tool on router {router_name}")
result = _run_junos_cli_command(router_name, f"show {my_param}")
return [types.TextContent(type="text", text=result)]
Paso 2: Registrar el Manejador
Añada su manejador al diccionario TOOL_HANDLERS (alrededor de la línea 330):
TOOL_HANDLERS = {
"execute_junos_command": handle_execute_junos_command,
"get_junos_config": handle_get_junos_config,
"junos_config_diff": handle_junos_config_diff,
"gather_device_facts": handle_gather_device_facts,
"get_router_list": handle_get_router_list,
"load_and_commit_config": handle_load_and_commit_config,
"my_new_tool": handle_my_new_tool, # Add your tool here
}
Paso 3: Definir Metadatos de la Herramienta
Añada la definición de la herramienta al método list_tools() (alrededor de la línea 410):
types.Tool(
name="my_new_tool",
description="Brief description of what your tool does",
inputSchema={
"type": "object",
"properties": {
"router_name": {"type": "string", "description": "The name of the
router"},
"my_param": {"type": "string", "description": "Description of
parameter"}
},
"required": ["router_name"] # List required parameters
}
)
Ejemplo: Crear una Herramienta de Vecinos BGP
Aquí tiene un ejemplo completo de cómo añadir una herramienta para mostrar vecinos BGP:
# Step 1: Handler function
async def handle_show_bgp_neighbors(arguments: dict) -> list[types.ContentBloc
]:
"""Handler for show_bgp_neighbors tool"""
router_name = arguments.get("router_name", "")
neighbor_address = arguments.get("neighbor_address", "")
if router_name not in devices:
result = f"Router {router_name} not found in the device mapping."
else:
log.debug(f"Getting BGP neighbors from router {router_name}")
if neighbor_address:
cmd = f"show bgp neighbor {neighbor_address}"
else:
cmd = "show bgp summary"
result = _run_junos_cli_command(router_name, cmd)
return [types.TextContent(type="text", text=result)]
# Step 2: Add to TOOL_HANDLERS
TOOL_HANDLERS = {
# ... existing tools ...
"show_bgp_neighbors": handle_show_bgp_neighbors,
}
# Step 3: Add to list_tools()
types.Tool(
name="show_bgp_neighbors",
description="Show BGP neighbor information",
inputSchema={
"type": "object",
"properties": {
"router_name": {"type": "string", "description": "The name of the
router"},
"neighbor_address": {"type": "string", "description": "Optional:
specific neighbor IP"}
},
"required": ["router_name"]
}
)
Mejores Prácticas para el Desarrollo de Herramientas
- Manejo de Errores: Maneje siempre los errores de conexión y las entradas inválidas con elegancia
- Registro: Utilice el registrador global
logpara la depuración - Validación: Compruebe si el router existe antes de intentar operaciones
- Documentación: Escriba descripciones claras para las herramientas y los parámetros
- Tiempos de Espera: Compatibilidad con tiempos de espera configurables para operaciones de larga duración
- Formato de Retorno: Devuelva siempre
list[types.ContentBlock]con contenido de texto - Parámetro de Contexto: Utilice el parámetro
context: Contextpara enviar mensajes de progreso y registro al cliente
Uso de PyEZ para Operaciones Avanzadas
Para operaciones más allá de los comandos CLI, use PyEZ directamente:
from jnpr.junos import Device
from jnpr.junos.utils.config import Config
# Example: Using PyEZ tables
async def handle_get_interfaces(arguments: dict) -> list[types.ContentBlock]:
router_name = arguments.get("router_name", "")
if router_name not in devices:
result = f"Router {router_name} not found in the device mapping."
else:
device_info = devices[router_name]
try:
connect_params = prepare_connection_params(device_info, router_name)
with Device(**connect_params) as junos_device:
# Use PyEZ tables or other utilities
interfaces = junos_device.rpc.get_interface_information()
# Process interfaces...
result = "Interface information..."
except Exception as e:
result = f"Error: {e}"
return [types.TextContent(type="text", text=result)]
Prueba de sus Herramientas
- Pruebas Unitarias: Pruebe las funciones manejadoras con argumentos simulados
- Pruebas de Integración: Pruebe con dispositivos Junos reales o vSRX
- Casos de Error: Pruebe con routers inválidos, fallos de red, etc.
Ejemplo de prueba:
# Test the handler directly
result = await handle_my_new_tool({
"router_name": "router-1",
"my_param": "test"
})
print(result[0].text)
Consejos de Depuración
- Habilite el registro de depuración para ver la ejecución detallada:
logging.basicConfig(level=logging.DEBUG)
- Use el transporte stdio para una depuración más sencilla:
python jmcp.py -f devices.json -t stdio
- Pruebe comandos individuales manualmente:
result = _run_junos_cli_command("router-1", "show version")
print(result)