Cómo arreglar cannot import name streamablehttp_client y McpError en el SDK de MCP 2
Índice de contenidos
- Puntos clave
- ImportError: cannot import name 'streamablehttp_client' from 'mcp.client.streamable_http'
- ImportError: cannot import name 'McpError' from 'mcp.shared.exceptions'
- ¿Por qué aparecen estos errores sin haber cambiado nada?
- Arreglo inmediato: fijar mcp por debajo de 2
- Si el que falla es un servidor lanzado con uvx
- Cómo portar el cliente a mcp 2.x
- httpx2, no httpx
- Cómo comprobar que la migración funciona
- ClientSession negocia 2025-11-25; Client llega a 2026-07-28
- Preguntas frecuentes
- ¿Hay un alias de compatibilidad para streamablehttp_client en mcp 2?
- ¿Puedo escribir un cliente que funcione con mcp 1.x y 2.x a la vez?
- ¿Cuánto tiempo seguirá recibiendo parches mcp 1.x?
- Conclusión
- Fuentes
El error cannot import name streamablehttp_client aparece porque el paquete mcp 2.x de Python borró esa función, y McpError pasó a llamarse MCPError. Para salir del paso fija mcp
El error cannot import name 'streamablehttp_client' from 'mcp.client.streamable_http' significa que tienes instalado el paquete mcp 2.x y tu código está escrito para el 1.x. La versión 2.0.0 del SDK de Python del Model Context Protocol (MCP), publicada el 28 de julio de 2026, borró esa función y renombró McpError a MCPError, que es el segundo ImportError que vas a ver. El arreglo inmediato es fijar mcp<2; el definitivo, portar el cliente a streamable_http_client. Lo reproduje el 18 de octubre de 2026 en Docker con Python 3.14.7, mcp 1.30.0 y mcp 2.3.0. Tienes la versión en inglés de esta guía.
Puntos clave
mcp2.0.0 salió el 28 de julio de 2026 y la versión actual es la 2.3.0, del 2 de octubre; unpip install -U mcpo un requisito sin techo la instala sola.- Los dos errores salen en la primera línea que importa el nombre viejo: primero
streamablehttp_clienty, cuando arreglas ese,McpError. - Fijar
mcp<2resuelve hoy a la 1.30.0, la rama de mantenimiento que sigue recibiendo parches de seguridad, y el cliente 1.x vuelve a funcionar sin tocar código. - El port tiene cuatro cambios:
streamable_http_client, cabeceras y tiempos en unhttpx2.AsyncClient, un par(read, write)en lugar de tres valores yMCPErrorcone.codeye.message. - Los servidores de referencia
mcp-server-fetchymcp-server-time2026.7.10 no ponían techo amcp; conuvxfallan con elImportErrordeMcpError, y se arreglan con--with "mcp<2"o actualizando.
ImportError: cannot import name ‘streamablehttp_client’ from ‘mcp.client.streamable_http’
Este es el primer error, y aparece al importar el módulo, antes de abrir ninguna conexión. Lo obtuve ejecutando con mcp 2.3.0 un cliente que funcionaba con 1.30.0:
Traceback (most recent call last):
File "/work/v1/client.py", line 5, in <module>
from mcp.client.streamable_http import streamablehttp_client
ImportError: cannot import name 'streamablehttp_client' from
'mcp.client.streamable_http' (/work/venv2/lib/python3.14/site-packages/
mcp/client/streamable_http.py)
En tu terminal el mensaje ocupa una sola línea; aquí lo he partido para que quepa. La función no se ha movido: ya no existe. En la rama 1.x convivían dos nombres, streamablehttp_client y streamable_http_client, y en mcp 1.30.0 el primero ya lleva un decorador @deprecated que remite a streamable_http_client. La 2.0.0 borró el alias viejo, y en este caso Python no añade ninguna sugerencia de nombre al mensaje.
Comprueba qué versión tienes con pip show mcp. Si dice 2.x y el código importa streamablehttp_client, ya tienes el diagnóstico.
ImportError: cannot import name ‘McpError’ from ‘mcp.shared.exceptions’
Este es el segundo error, y lo verás en cuanto cambies el nombre de la función o si tu código solo captura excepciones. Con el import anterior ya corregido, el mismo cliente se paró aquí:
File "/work/v1/client_half.py", line 6, in <module>
from mcp.shared.exceptions import McpError
ImportError: cannot import name 'McpError' from 'mcp.shared.exceptions'
(/work/venv2/lib/python3.14/site-packages/mcp/shared/exceptions.py).
Did you mean: 'MCPError'?
Aquí Python sí acierta con la sugerencia, pero renombrar no basta. En 2.x la excepción expone e.code y e.message directamente, mientras que en 1.x estaban en e.error.code y e.error.message. Si además lanzas el error desde un servidor, el constructor cambió de McpError(ErrorData(...)) a MCPError(code, message); ese lado lo cubre la guía para migrar un servidor MCP a FastMCP 4 y al SDK 2.
¿Por qué aparecen estos errores sin haber cambiado nada?
Porque algo instaló mcp 2.x por ti. Las causas que me encontré son tres:
- Requisito sin techo:
mcp>=1.2en unrequirements.txto unpyproject.tomlresuelve a la 2.3.0 desde el 2 de octubre de 2026 pip install -Uo una imagen reconstruida: cualquier entorno nuevo sin fichero de bloqueo toma la última versiónuvxcon un servidor antiguo:uvx mcp-server-fetch==2026.7.10crea un entorno temporal y elige lamcpmás reciente que permite el paquete
Este es el calendario de PyPI que explica cuándo empezó a fallar cada caso:
| Versión | Fecha en PyPI | Qué significa |
|---|---|---|
mcp 2.0.0 y 1.29.0 |
28 de julio de 2026 | Sale la rama 2; la 1.x sigue en paralelo |
mcp-server-fetch 2026.8.18 |
18 de agosto de 2026 | Los servidores de referencia pasan a mcp>=1.29.0,<2 |
mcp 1.30.0 |
7 de septiembre de 2026 | Última de la rama 1.x a fecha de hoy |
mcp 2.3.0 |
2 de octubre de 2026 | Versión que instala un requisito sin techo |
Arreglo inmediato: fijar mcp por debajo de 2
Pon un techo a mcp y el código 1.x vuelve a funcionar sin cambiar una línea. Es lo que recomienda la propia guía de migración del SDK[1]: "The v1.x maintenance line keeps receiving critical bug fixes and security patches", y "If your package depends on mcp, keep a <2 upper bound until you’ve migrated". Estos son los comandos que ejecuté sobre un entorno que ya tenía la 2.3.0:
pip install "mcp<2"
python v1/client.py http://b9p04-srv1:8000/mcp
pip desinstaló la 2.3.0, instaló la 1.30.0 junto con httpx 0.28.1 y httpx-sse 0.4.3, y el cliente sin tocar respondió como el primer día:
server: demo proto: 2025-11-25
session: True
add -> 5
McpError: 0 Error creating resource from template: ... 'missing'
La última línea es la excepción esperada, una lectura de un recurso que no existe. En pyproject.toml escribe la dependencia como "mcp>=1.25,<2"; en un entorno limpio esa restricción resolvió también a la 1.30.0. El paso atrás deja instalados mcp-types 2.3.0 y httpx2 2.13.1, que la 1.30.0 no usa; puedes desinstalarlos o dejarlos.
Si el que falla es un servidor lanzado con uvx
El arreglo es el mismo, aplicado al entorno temporal de uvx. Esto es lo que vi con mcp-server-fetch 2026.7.10, que declaraba mcp>=1.1.3:
$ uvx mcp-server-fetch==2026.7.10
File ".../mcp_server_fetch/server.py", line 6, in <module>
from mcp.shared.exceptions import McpError
ImportError: cannot import name 'McpError' from 'mcp.shared.exceptions'
(...). Did you mean: 'MCPError'?
Con uv 0.11.3, ese entorno resolvió mcp 2.3.0; añadiendo --with "mcp<2" resolvió la 1.30.0 y el servidor arrancó. mcp-server-time 2026.7.10 falló y se arregló igual. La otra salida es quitar el ==2026.7.10 de la configuración de tu editor: la versión 2026.10.10 ya declara mcp>=1.29.0,<2, como muestra el pyproject.toml de mcp-server-fetch[2]. En un fichero de configuración de cliente MCP queda así:
{
"mcpServers": {
"fetch": {
"command": "uvx",
"args": ["--with", "mcp<2", "mcp-server-fetch==2026.7.10"]
}
}
}
Si montas servidores propios con este patrón, la guía de cómo instalar un servidor MCP local para tu editor explica dónde vive ese fichero en cada cliente.
Cómo portar el cliente a mcp 2.x
El port del cliente de bajo nivel son cuatro cambios, y el resto del código (ClientSession, initialize(), call_tool()) sigue igual. Este es el cliente 1.x de partida, recortado a la parte que cambia:
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
from mcp.shared.exceptions import McpError
HEADERS = {"Authorization": "Bearer your_access_token_here"}
async def main() -> None:
async with streamablehttp_client(URL, headers=HEADERS) as (
read, write, get_session_id,
):
async with ClientSession(read, write) as session:
init = await session.initialize()
print("server:", init.serverInfo.name)
try:
await session.read_resource("notes://missing")
except McpError as e:
print("McpError:", e.error.code, e.error.message)
Y este es el mismo cliente portado a mcp 2.3.0, que funcionó a la primera contra un servidor 1.30.0 y contra uno 2.3.0:
import httpx2
from mcp import ClientSession, MCPError
from mcp.client.streamable_http import streamable_http_client
HEADERS = {"Authorization": "Bearer your_access_token_here"}
async def main() -> None:
http = httpx2.AsyncClient(headers=HEADERS,
timeout=httpx2.Timeout(30, read=300))
async with http, streamable_http_client(URL, http_client=http) as (
read, write,
):
async with ClientSession(read, write) as session:
init = await session.initialize()
print("server:", init.server_info.name)
try:
await session.read_resource("notes://missing")
except MCPError as e:
print("MCPError:", e.code, e.message)
Los cambios, uno por uno:
- Nombre y argumentos:
streamable_http_client(url, http_client=...)ya no aceptaheaders,timeout,sse_read_timeoutniauth. Si solo cambias el nombre, falla conTypeError: streamable_http_client() got an unexpected keyword argument 'headers' - Cliente HTTP propio: las cabeceras, los tiempos y la autenticación van en un
httpx2.AsyncClient.Timeout(30, read=300)reproduce los valores por defecto del 1.x; sin él,httpx2aplica 5 s planos, cortos para el flujo GET que queda abierto - Dos valores, no tres: el contexto devuelve
(read, write). Si dejas los tres nombres, falla conValueError: not enough values to unpack (expected 3, got 2). Para el identificador de sesión, la guía usa unevent_hookdehttpx2que lee la cabeceramcp-session-id - Campos en snake_case y
MCPError:serverInfopasa aserver_info,protocolVersionaprotocol_version, y la excepción exponee.codeye.message
Comprobé que la cabecera viaja con un event_hook de petición: el POST y el GET salieron con Authorization: Bearer your_access_token_here.
httpx2, no httpx
El paquete mcp 2.x depende de httpx2[3], un fork de httpx con soporte de eventos enviados por el servidor (SSE) integrado, y ya no instala httpx. En mi entorno con mcp 2.3.0, pip list mostraba httpx2 2.13.1 y ningún httpx. Si sigues un ejemplo que pasa un httpx.AsyncClient, primero verás ModuleNotFoundError: No module named 'httpx'. Si instalas httpx por tu cuenta, la guía avisa de que ese cliente "degrades in subtle ways (server-initiated messages stop arriving) instead of raising immediately".
Cómo comprobar que la migración funciona
Lanza el cliente portado contra tu servidor y contra uno de la otra rama, porque los dos cruces deben funcionar. Monté dos servidores en una red de Docker, uno con FastMCP de mcp 1.30.0 y otro con MCPServer de mcp 2.3.0, cada uno con una herramienta add y un recurso notes://{name}:
docker network create b9p04-net
docker run -d --name b9p04-srv2 --network b9p04-net --user 1000:1000 \
-e HOME=/work -v "$PWD":/work -w /work/v2 python:3.14-slim-trixie \
/work/venv2/bin/python server.py
docker run --rm --network b9p04-net --user 1000:1000 -e HOME=/work \
-v "$PWD":/work -w /work/v2 python:3.14-slim-trixie \
/work/venv2/bin/python client.py http://b9p04-srv2:8000/mcp
Las tres combinaciones respondieron así:
== cliente 2.3.0 -> servidor 2.3.0
server: demo proto: 2025-11-25
add -> 5
MCPError: -32603 Error creating resource from template notes://missing
== cliente 2.3.0 -> servidor 1.30.0
server: demo proto: 2025-11-25
add -> 5
MCPError: 0 Error creating resource from template: ... 'missing'
== cliente 1.30.0 -> servidor 2.3.0
server: demo proto: 2025-11-25
session: True
add -> 5
McpError: -32603 Error creating resource from template notes://missing
El mismo error de recurso llega con código 0 desde un servidor 1.30.0 y con -32603 (error interno de JSON-RPC) desde uno 2.3.0. Si tu cliente decide algo según e.code, prueba contra las dos ramas.
ClientSession negocia 2025-11-25; Client llega a 2026-07-28
ClientSession.initialize() siempre hace el saludo anterior a 2026, por eso las tres salidas dicen 2025-11-25. Para usar la revisión 2026-07-28 de la especificación de MCP, el SDK 2 trae un cliente de alto nivel, Client, que acepta el mismo transporte:
from mcp import Client, MCPError
async def main(url: str) -> None:
http = httpx2.AsyncClient(headers=HEADERS,
timeout=httpx2.Timeout(30, read=300))
transport = streamable_http_client(url, http_client=http)
async with http, Client(transport) as c:
print("server:", c.server_info.name,
"proto:", c.protocol_version)
r = await c.call_tool("add", {"a": 2, "b": 3})
print("add ->", r.content[0].text)
Contra el servidor 2.3.0 imprimió proto: 2026-07-28, y contra el 1.30.0, proto: 2025-11-25. Client usa por defecto mode="auto": primero envía server/discover y, si el servidor no lo entiende, repite con initialize. Al lanzar mcp-server-fetch por stdio con --with "mcp<2", el servidor 1.x escribió en stderr una advertencia con 31 errores de validación por esa sonda antes de responder bien. Con Client(..., mode="legacy") el saludo va directo y el registro sale limpio.
Preguntas frecuentes
¿Hay un alias de compatibilidad para streamablehttp_client en mcp 2?
No en el SDK oficial. En mcp 2.3.0 ni streamablehttp_client ni McpError existen, y la guía de migración los da por eliminados. FastMCP 4 sí conserva McpError como alias en fastmcp.exceptions, pero solo te sirve si usas ese paquete.
¿Puedo escribir un cliente que funcione con mcp 1.x y 2.x a la vez?
No con el mismo código. En 1.30.0 streamable_http_client ya existe, pero devuelve tres valores y espera un httpx.AsyncClient; en 2.x devuelve dos y espera un httpx2.AsyncClient. MCPError tampoco existe en 1.30.0. Elige una rama y fíjala en tus dependencias.
¿Cuánto tiempo seguirá recibiendo parches mcp 1.x?
La documentación oficial habla de "critical bug fixes and security patches" para la rama 1.x, sin fecha de fin publicada a 18 de octubre de 2026. La 1.30.0, del 7 de septiembre, es la última hasta hoy. Fijar mcp<2 te da tiempo, pero no sustituye a la migración.
Conclusión
cannot import name 'streamablehttp_client' y cannot import name 'McpError' son el mismo problema: código del SDK 1.x ejecutándose con mcp 2.x. Para seguir trabajando hoy, fija mcp<2 o añade --with "mcp<2" a uvx. Cuando migres, sustituye la función por streamable_http_client, mueve cabeceras y tiempos a un httpx2.AsyncClient, desempaqueta dos valores y captura MCPError. Si mantienes también el servidor, sigue con la guía para migrar un servidor MCP a FastMCP 4, y para empezar uno desde cero, la de construir un servidor MCP propio.
Fuentes: [1] Guía de migración del SDK de Python de MCP de v1 a v2[1], [2] Historial de versiones del paquete mcp en PyPI[4], [3] Notas de la versión 2.0.0 del SDK de Python de MCP[5], [4] Notas de la versión 2.3.0 del SDK de Python de MCP[6], [5] pyproject.toml de mcp-server-fetch[2], [6] Versiones de mcp-server-fetch en PyPI[7], [7] Repositorio de httpx2[3].
Fuentes
Código fuente
Accede a todo el código fuente de este artículo en GitHub.
Ver en GitHub