Streamable HTTP Transport
The new Streamable HTTP transport replaces the HTTP+SSE transport from protocol version 2024-11-05.
This transport enables the MCP server to handle multiple client connections, and can also use SSE for server-to-client streaming.
To use it, initialize the MCPTools passing the URL of the MCP server and setting the transport to streamable-http:
1from kern.agent import Agent2from kern.models.openai import OpenAIResponses3from kern.tools.mcp import MCPTools45# Initialize and connect to the Streamable HTTP MCP server6mcp_tools = MCPTools(url="https://kern.ndx.rocks/mcp", transport="streamable-http")7await mcp_tools.connect()89try:10 agent = Agent(model=OpenAIResponses(id="gpt-5.2"), tools=[mcp_tools])11 await agent.aprint_response("What can you tell me about MCP support in Kern?", stream=True)12finally:13 # Always close the connection when done14 await mcp_tools.close()You can also use the server_params argument to define the MCP connection. This way you can specify the headers to send to the MCP server with every request, and the timeout values:
1from kern.tools.mcp import MCPTools, StreamableHTTPClientParams23server_params = StreamableHTTPClientParams(4 url=...,5 headers=...,6 timeout=...,7 sse_read_timeout=...,8 terminate_on_close=...,9)1011# Initialize and connect using server parameters12mcp_tools = MCPTools(server_params=server_params, transport="streamable-http")13await mcp_tools.connect()1415try:16 # Use mcp_tools with your agent17 pass18finally:19 await mcp_tools.close()Complete example
Let's set up a simple local server and connect to it using the Streamable HTTP transport:
Setup the server
1from mcp.server.fastmcp import FastMCP23mcp = FastMCP("calendar_assistant")456@mcp.tool()7def get_events(day: str) -> str:8 return f"There are no events scheduled for {day}."91011@mcp.tool()12def get_birthdays_this_week() -> str:13 return "It is your mom's birthday tomorrow"141516if __name__ == "__main__":17 mcp.run(transport="streamable-http")Setup the client
1import asyncio23from kern.agent import Agent4from kern.models.openai import OpenAIResponses5from kern.tools.mcp import MCPTools, MultiMCPTools67# This is the URL of the MCP server we want to use.8server_url = "http://localhost:8000/mcp"91011async def run_agent(message: str) -> None:12 # Initialize and connect to the Streamable HTTP MCP server13 mcp_tools = MCPTools(transport="streamable-http", url=server_url)14 await mcp_tools.connect()1516 try:17 agent = Agent(18 model=OpenAIResponses(id="gpt-5.2"),19 tools=[mcp_tools],20 markdown=True,21 )22 await agent.aprint_response(message=message, stream=True, markdown=True)23 finally:24 await mcp_tools.close()252627# Using MultiMCPTools, we can connect to multiple MCP servers at once, even if they use different transports.28# In this example we connect to both our example server (Streamable HTTP transport), and a different server (stdio transport).29async def run_agent_with_multimcp(message: str) -> None:30 # Initialize and connect to multiple MCP servers with different transports31 mcp_tools = MultiMCPTools(32 commands=["npx -y @openbnb/mcp-server-airbnb --ignore-robots-txt"],33 urls=[server_url],34 urls_transports=["streamable-http"],35 )36 await mcp_tools.connect()3738 try:39 agent = Agent(40 model=OpenAIResponses(id="gpt-5.2"),41 tools=[mcp_tools],42 markdown=True,43 )44 await agent.aprint_response(message=message, stream=True, markdown=True)45 finally:46 await mcp_tools.close()474849if __name__ == "__main__":50 asyncio.run(run_agent("Do I have any birthdays this week?"))51 asyncio.run(52 run_agent_with_multimcp(53 "Can you check when is my mom's birthday, and if there are any AirBnb listings in SF for two people for that day?"54 )55 )Run the server
1python streamable_http_server.pyRun the client
1python streamable_http_client.py