# Una consulta MCP local entre dos programas propios

Ejemplo de Ranquia: un cliente Python inicia un servidor Python, descubre una herramienta y consulta una ficha ficticia. Los programas usan un subconjunto de MCP 2026-07-28 sobre stdio. No intervienen Codex, Claude Code, Copilot ni un modelo. No es una certificación de conformidad completa con MCP.

## Requisitos y ejecución

Necesitas Python 3.11 o posterior, una terminal y permiso para crear una carpeta de resultados y un directorio temporal. La ejecución editorial se hizo con Python 3.11.4 en Windows (versión del sistema 10.0.19045). Otras combinaciones no se han probado.

1. Extrae el ZIP en una carpeta nueva y revisa `client.py` y `server.py`.
2. Abre la terminal en esa carpeta.
3. Ejecuta:

```text
python client.py --output mi-resultado
```

Usa `python3` o `py -3` si ese es el comando de tu instalación. La carpeta `mi-resultado` debe ser nueva; el programa se niega a sobrescribirla. No hace falta instalar paquetes, configurar un asistente ni iniciar sesión. El ensayo no llama servicios de red o de pago. Ambos programas rechazan eventos de auditoría Python `socket.*`; eso limita este ejemplo, no convierte el código en una sandbox para ejecutar servidores ajenos.

## Qué ocurre

El cliente comprueba el hash congelado de `fixture.json`, copia la ficha y el servidor a un directorio temporal y lo inicia como subproceso. Envía ocho peticiones, con timeout de cinco segundos por respuesta:

- Descubrimiento de versión y capacidades, y listado de la herramienta `consultar_taller`.
- Consulta de `taller-documentacion`: 5 de noviembre de 2026, 10:00–11:30 y 12 plazas.
- Cinco controles negativos: herramienta inexistente, taller inexistente, argumento de tipo incorrecto, metadatos sin capacidades y versión no admitida.

Al terminar, cierra stdin, comprueba el código de salida y verifica que la ficha conserva su hash. La carpeta temporal se elimina. El cliente guarda un registro de mensajes y un informe en la carpeta indicada; no edita configuraciones globales.

Salida editorial observada:

```text
PASS: 8 peticiones, 9 comprobaciones; ficha intacta; servidor terminado.
```

`PASS` significa que se cumplieron esas comprobaciones del ejemplo. No acredita instalación en un asistente, selección automática de herramientas, acceso a datos reales ni soporte de todas las funciones de MCP. La validación de entrada cubre el esquema fijo de esta herramienta; no implementa un validador general de JSON Schema. El servidor es didáctico y no está preparado para producción.

## Archivos y trazabilidad

- `fixture.json` y `fixture-sha256.txt`: entrada ficticia y hash congelado antes del ensayo.
- `client.py` y `server.py`: fuentes originales del ejemplo.
- `transcript.jsonl` y `results.json`: mensajes y resultado de la ejecución editorial del 4 de octubre de 2026 en Santiago (5 de octubre UTC), sin rutas de usuario ni credenciales.
- `manifest-sha256.json`: hashes de los archivos incluidos; el manifiesto no se incluye a sí mismo.

El SHA-256 detecta cambios de bytes, no certifica que un archivo sea seguro. Un primer intento terminó después del intercambio al recopilar metadatos del sistema: `platform.system()` intentó consultar el nombre del equipo y el control de socket lo rechazó. Se cambió por `sys.platform` y `sys.getwindowsversion()`. Los resultados incluidos corresponden al código corregido.

## Referencias del protocolo consultadas

- [Metadatos por petición](https://modelcontextprotocol.io/specification/2026-07-28/basic/index).
- [Transporte stdio](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/stdio).
- [Schema Reference](https://modelcontextprotocol.io/specification/2026-07-28/schema): `DiscoverResult`, `ListToolsResult` y `CallToolResult`.
- [Herramientas y errores](https://modelcontextprotocol.io/specification/2026-07-28/server/tools).

El ejemplo incluye `resultType` en los resultados; descubrimiento y listado también incluyen `ttlMs` y `cacheScope`. Las peticiones válidas llevan versión, identidad y capacidades del cliente en `params._meta`. Las dos peticiones de metadatos negativos modifican deliberadamente esos campos.
