Stateless MCP ha recapturado mi interés (e inspirado mcp-explorer y datasette-mcp)
El martes fue el día del Stateless MCP, marcando el despliegue de MCP 2.0, o la especificación del Model Context Protocol del 28 de julio de 2026, para usar el nombre más formal aunque menos memorable. Este es el cambio más significativo en la especificación MCP desde su lanzamiento original y ha servido para reavivar mi interés personal en el protocolo.
Como contexto: MCP es el Model Context Protocol, que describe una manera estándar de exponer nuevas herramientas a frameworks de agentes basados en LLM. Fue introducido por Anthropic en noviembre de 2024, tuvo un pico de interés enorme durante gran parte de 2025, y luego fue eclipsado por Skills (otra invención de Anthropic) cuando se hizo evidente que un agente con acceso a una terminal y curl podía hacer la mayoría de lo que MCP lograba de una manera más flexible. Escribí sobre eso en mi revisión de 2025.
Estoy volviendo a interesarme en MCP ahora. Darle a un agente un entorno de shell con la capacidad de acceder a internet está lleno de riesgos y requiere un modelo potente capaz de gestionar eficazmente dicho entorno. Las herramientas MCP son más fáciles de auditar y controlar, siendo lo suficientemente simples para que modelos más pequeños que corren en un computador portátil puedan manejarlas razonablemente bien.
La nueva especificación stateless de MCP también disminuye enormemente la complejidad de implementar tanto clientes como servidores para el protocolo. ¡Construí tres de ellos esta semana!
¿Qué es más fácil con el Stateless MCP?
La mejor demostración de la diferencia entre MCP stateful y stateless se encuentra en esta publicación de blog del 21 de mayo que introdujo la RC para la nueva especificación. Incluía un ejemplo claro de antes y después.
El MCP stateful antiguo (lo llamaré “MCP legado”) requería dos solicitudes HTTP: la primera para inicializar una sesión y obtener un Mcp-Session-Id, y la segunda para realmente llamar a la herramienta:
POST /mcp HTTP/1.1
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-11-25",
"capabilities": {},
"clientInfo": {
"name": "my-app",
"version": "1.0"
}
}
}
POST /mcp HTTP/1.1
Mcp-Session-Id: 1868a90c-3a3f-4f5b
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "search",
"arguments": {
"q": "otters"
}
}
}La nueva forma stateless utiliza una única solicitud HTTP que se ve así:
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search",
"arguments": {
"q": "otters"
},
"_meta": {
"io.modelcontextprotocol/clientInfo": {
"name": "my-app",
"version": "1.0"
}
}
}
}Esto es mucho más limpio desde la perspectiva de implementación tanto del cliente como del servidor. También es un mejor ajuste para construir aplicaciones web escalables, ya que ahora no necesitas mantener el estado del lado del servidor para realizar un seguimiento de esos IDs de sesión, ni preocuparte por enrutar la misma sesión a la misma máquina backend.
mcp-explorer
No pude encontrar una gran herramienta CLI para probar interactivamente un servidor MCP, así que hice que Codex me ayudara a construir la mía propia.
mcp-explorer es el resultado. Es una herramienta CLI de Python stateless, por lo que ni siquiera necesitas instalarla para probarla; funciona con uvx de esta manera:
uvx mcp-explorer list https://agentic-mermaid.dev/mcpEsto consulta el MCP de demostración agentic-mermaid.dev de Ade Oshineye. El comando anterior devuelve la siguiente lista de herramientas:
execute(code: string, timeoutMs?: integer) - Ejecutar código del SDK de Mermaid
Ejecuta JavaScript en un sandbox aislado; devuelve un valor.
describe_sdk(family: string, detail?: string) - Describe operaciones del SDK de Mermaid
Devuelve operaciones de mutación coincidentes con la versión para una familia de diagramas.
render_svg(source: string, options?: object) - Renderiza Mermaid como SVG
Renderiza una cadena fuente de Mermaid como SVG temático. Devuelve { ok, svg }.
render_ascii(source: string, useAscii?: boolean, targetWidth?: integer, options?: object) - Renderiza Mermaid como texto
Renderiza una cadena fuente de Mermaid como texto. Devuelve { ok, text }.
render_png(source: string, scale?: number, background?: string, fitTo?: object, options?: object) - Renderiza Mermaid como PNG
Rasteriza una cadena fuente de Mermaid como PNG. Devuelve { ok, png_base64 }.
...Luego, para inspeccionar una herramienta:
uvx mcp-explorer inspect render_svgEsto genera un montón de información, incluido el esquema JSON de las entradas y salidas. Para llamar a esa herramienta y pasarle argumentos:
uvx mcp-explorer call \
https://agentic-mermaid.dev/mcp \
render_svg \
-a source 'graph TD; A-->B' \
-a options '{"padding":24}'{"ok":true,"svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=...Para obtener solo el SVG sin procesar, intenta agregar | jq .svg -r a ese comando. Obtuve esta imagen:
El diagrama resultante muestra cómo el protocolo permite renderizar visualizaciones complejas mediante llamadas directas a herramientas especializadas. Hay algunos comandos más en el README, pero ya se entiende la idea general. Encuentro que construir herramientas CLI como esta es una forma muy productiva de familiarizarse con una especificación, incluso si un agente escribe la mayor parte del código real.
datasette-mcp
El segundo proyecto es datasette-mcp, un plugin de Datasette que agrega un endpoint /-/mcp a cualquier instancia de Datasette.
Esta es probablemente la cuarta vez que intento construir este plugin, pero gracias a la nueva especificación stateless de MCP finalmente tengo una versión que se siente bien para lanzar. Proporciona solo tres herramientas: list_databases(), get_database_schema(database_name) y execute_sql(database_name, sql). Hacen exactamente lo que esperarías que hicieran, aunque execute_sql() es de solo lectura por el momento.
Conecta esto a un agente, o a una herramienta de chat como ChatGPT o Claude, y obtendrán la capacidad de ejecutar consultas SQL contra tu instancia de Datasette alojada. Hasta ahora lo estoy ejecutando en el espejo de Datasette de mi blog, en datasette.simonwillison.net/-/mcp. Tomó un poco de ajuste averiguar cómo conectar eso a ChatGPT y Claude, pero finalmente lo logré. Aquí hay un nuevo TIL que muestra exactamente cómo hacerlo.
Aquí hay una sesión compartida de Claude donde le pregunté:
listar tablas en simonwillison.net>¿qué ha dicho Simon recientemente sobre MCP?
Ejecutó 7 consultas SQL separadas para encontrar la respuesta.
llm-mcp-client
Mi herramienta LLM ha tardado mucho en tener una integración oficial con MCP. El nuevo plugin alfa llm-mcp-client es mi intento de lograr exactamente eso:
llm install llm-mcp-client
llm -T 'MCP("https://datasette.simonwillison.net/-/mcp")' 'cuenta las notas'Aquí está el resultado (incluyendo el rastro de razonamiento, estoy usando LLM 0.32rc2):
Considerando el conteo de notas: veo que la pregunta “cuenta las notas” probablemente me pide que haga un recuento de las notas del blog. También podría significar notas publicadas o borradores, así que hay algo de ambigüedad. Tendré que verificar.
Vía Simon Willison.




