fastmcp icon indicating copy to clipboard operation
fastmcp copied to clipboard

Client cannot access to local sse sever

Open Geqiandipan opened this issue 8 months ago • 5 comments

Description

As the title indicates, using ''' async with Client(SSETransport("http://localhost:8000/mcp")) as client: ... Use client here... ''' connecting to SSE Server results in an error. The error is as follows:

'''

  • Exception Group Traceback (most recent call last): | File "test_client.py", line 15, in | asyncio.run(main()) | File "/usr/local/lib/python3.12/asyncio/runners.py", line 194, in run | return runner.run(main) | ^^^^^^^^^^^^^^^^ | File "/usr/local/lib/python3.12/asyncio/runners.py", line 118, in run | return self._loop.run_until_complete(task) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/local/lib/python3.12/asyncio/base_events.py", line 664, in run_until_complete | return future.result() | ^^^^^^^^^^^^^^^ | File "test_client.py", line 8, in main | async with Client(SSETransport(url='http://localhost:7796/mcp')) as client: | File ".venv/lib/python3.12/site-packages/fastmcp/client/client.py", line 92, in aenter | self._session = await self._session_cm.aenter() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/local/lib/python3.12/contextlib.py", line 204, in aenter | return await anext(self.gen) | ^^^^^^^^^^^^^^^^^^^^^ | File ".venv/lib/python3.12/site-packages/fastmcp/client/transports.py", line 118, in connect_session | async with sse_client(self.url, headers=self.headers) as transport: | File "/usr/local/lib/python3.12/contextlib.py", line 204, in aenter | return await anext(self.gen) | ^^^^^^^^^^^^^^^^^^^^^ | File ".venv/lib/python3.12/site-packages/mcp/client/sse.py", line 43, in sse_client | async with anyio.create_task_group() as tg: | File ".venv/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 772, in aexit | raise BaseExceptionGroup( | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception) +-+---------------- 1 ---------------- | Traceback (most recent call last): | File ".venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 101, in map_httpcore_exceptions | yield | File ".venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 394, in handle_async_request | resp = await self._pool.handle_async_request(req) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File ".venv/lib/python3.12/site-packages/httpcore/_async/connection_pool.py", line 256, in handle_async_request | raise exc from None | File ".venv/lib/python3.12/site-packages/httpcore/_async/connection_pool.py", line 236, in handle_async_request | response = await connection.handle_async_request( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File ".venv/lib/python3.12/site-packages/httpcore/_async/http_proxy.py", line 206, in handle_async_request | return await self._connection.handle_async_request(proxy_request) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File ".venv/lib/python3.12/site-packages/httpcore/_async/connection.py", line 103, in handle_async_request | return await self._connection.handle_async_request(request) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File ".venv/lib/python3.12/site-packages/httpcore/_async/http11.py", line 136, in handle_async_request | raise exc | File ".venv/lib/python3.12/site-packages/httpcore/_async/http11.py", line 106, in handle_async_request | ) = await self._receive_response_headers(**kwargs) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File ".venv/lib/python3.12/site-packages/httpcore/_async/http11.py", line 177, in _receive_response_headers | event = await self._receive_event(timeout=timeout) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File ".venv/lib/python3.12/site-packages/httpcore/_async/http11.py", line 231, in _receive_event | raise RemoteProtocolError(msg) | httpcore.RemoteProtocolError: Server disconnected without sending a response. | | The above exception was the direct cause of the following exception: | | Traceback (most recent call last): | File ".venv/lib/python3.12/site-packages/mcp/client/sse.py", line 47, in sse_client | async with aconnect_sse( | File "/usr/local/lib/python3.12/contextlib.py", line 204, in aenter | return await anext(self.gen) | ^^^^^^^^^^^^^^^^^^^^^ | File "/home/workspace/rdcloud/10206173_test_project/mcp_test/fastmcp_test/.venv/lib/python3.12/site-packages/httpx_sse/_api.py", line 69, in aconnect_sse | async with client.stream(method, url, headers=headers, **kwargs) as response: | File "/usr/local/lib/python3.12/contextlib.py", line 204, in aenter | return await anext(self.gen) | ^^^^^^^^^^^^^^^^^^^^^ | File ".venv/lib/python3.12/site-packages/httpx/_client.py", line 1583, in stream | response = await self.send( | ^^^^^^^^^^^^^^^^ | File ".venv/lib/python3.12/site-packages/httpx/_client.py", line 1629, in send | response = await self._send_handling_auth( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File ".venv/lib/python3.12/site-packages/httpx/_client.py", line 1657, in _send_handling_auth | response = await self._send_handling_redirects( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File ".venv/lib/python3.12/site-packages/httpx/_client.py", line 1694, in _send_handling_redirects | response = await self._send_single_request(request) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File ".venv/lib/python3.12/site-packages/httpx/_client.py", line 1730, in _send_single_request | response = await transport.handle_async_request(request) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File ".venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 393, in handle_async_request | with map_httpcore_exceptions(): | File "/usr/local/lib/python3.12/contextlib.py", line 155, in exit | self.gen.throw(value) | File ".venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 118, in map_httpcore_exceptions | raise mapped_exc(message) from exc | httpx.RemoteProtocolError: Server disconnected without sending a response. +------------------------------------ '''

Example Code

my demo server code as follows:

'''
from fastmcp import FastMCP

mcp = FastMCP("My MCP Server", port=7796, host="0.0.0.0")

@mcp.tool()
def greet(name: str) -> str:
    return f"Hello, {name}!"


if __name__ == '__main__':
    mcp.run(transport='sse')
'''

my demo client code as follows:
'''
import asyncio

from fastmcp import Client
from fastmcp.client import SSETransport


async def main():
    async with Client(SSETransport(url='http://localhost:7796/mcp')) as client:
        print(f'client is connected ? {client.is_connected()}')
        tools = await client.list_tools()
        print(f'available tools: {tools}')


if __name__ == '__main__':
    asyncio.run(main())

'''

Version Information

fastmcp version
FastMCP version:                                                                                                    2.2.2
MCP version:                                                                                                        1.6.0
Python version:                                                                                                    3.12.0
Platform:                                                               Linux-4.19.112-2.el8.x86_64-x86_64-with-glibc2.28
FastMCP root path: .venv/lib/python3.12/site-packages

Additional Context

I Just use Pycharm to run my server and client.

Geqiandipan avatar Apr 24 '25 02:04 Geqiandipan

the default path is /sse not /mcp

strawgate avatar Apr 24 '25 16:04 strawgate

the default path is /sse not /mcp


Thanks for the clarification. However, using /sse still results in the same error on my side. Any other suggestions on what might be causing this?

Geqiandipan avatar Apr 25 '25 02:04 Geqiandipan

Can you try host '127.0.0.1' instead of '0.0.0.0', this default was recently updated

jlowin avatar Apr 25 '25 15:04 jlowin

Can you try host '127.0.0.1' instead of '0.0.0.0', this default was recently updated


got the same error info..

Geqiandipan avatar Apr 27 '25 00:04 Geqiandipan

facing same error,have you sloved?

litaolaile avatar May 08 '25 06:05 litaolaile

I think this can be closed.

@Geqiandipan Can you update?

A local FastMCP SSE client and server run on 2.6.1 (latest) as follows (adapting the 2.2.0 re-pro example for 2.6.1):

server.py:

from fastmcp import FastMCP

mcp = FastMCP("My MCP Server")

@mcp.tool()
def greet(name: str) -> str:
    return f"Hello, {name}!"


if __name__ == '__main__':
    # Custom port (and host) now belong here
    mcp.run(transport='sse', port=7796)

client.py

import asyncio

from fastmcp import Client

async def main():
    sse_url = 'http://localhost:7796/sse'

    # SSE transport inferred from URL
    async with Client(sse_url) as client:
        print(f'client is connected ? {client.is_connected()}')
        tools = await client.list_tools()
        print(f'available tools: {tools}')


if __name__ == '__main__':
    asyncio.run(main())
$ uv run python server.py
[06/04/25 11:51:04] INFO     Starting MCP server 'My MCP Server' with transport 'sse' on http://127.0.0.1:8000/sse server.py:846
INFO:     Started server process [81795]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:61670 - "GET /sse HTTP/1.1" 200 OK
INFO:     127.0.0.1:61672 - "POST /messages/?session_id=2586106048f9493d876ea2b56ad03dc8 HTTP/1.1" 202 Accepted
INFO:     127.0.0.1:61672 - "POST /messages/?session_id=2586106048f9493d876ea2b56ad03dc8 HTTP/1.1" 202 Accepted
INFO:     127.0.0.1:61672 - "POST /messages/?session_id=2586106048f9493d876ea2b56ad03dc8 HTTP/1.1" 202 Accepted
$ uv run python client.py
client is connected ? True
available tools: [Tool(name='greet', description=None, inputSchema={'properties': {'name': {'title': 'Name', 'type': 'string'}}, 'required': ['name'], 'type': 'object'}, annotations=None)]

FWIW, I experimented with the reported FastMCP 2.2.0 and there was an ASGI exception raised out of Uvicorn and Starlette, but I'm skeptical it's worth investigating since FastMCP has improved since 2.2.0 and moves quickly.

richardkmichael avatar Jun 04 '25 18:06 richardkmichael

I think this can be closed.

@Geqiandipan Can you update?

A local FastMCP SSE client and server run on 2.6.1 (latest) as follows (adapting the 2.2.0 re-pro example for 2.6.1):

server.py:

from fastmcp import FastMCP

mcp = FastMCP("My MCP Server")

@mcp.tool() def greet(name: str) -> str: return f"Hello, {name}!"

if name == 'main': # Custom port (and host) now belong here mcp.run(transport='sse', port=7796) client.py

import asyncio

from fastmcp import Client

async def main(): sse_url = 'http://localhost:7796/sse'

# SSE transport inferred from URL
async with Client(sse_url) as client:
    print(f'client is connected ? {client.is_connected()}')
    tools = await client.list_tools()
    print(f'available tools: {tools}')

if name == 'main': asyncio.run(main())

$ uv run python server.py
[06/04/25 11:51:04] INFO     Starting MCP server 'My MCP Server' with transport 'sse' on http://127.0.0.1:8000/sse server.py:846
INFO:     Started server process [81795]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:61670 - "GET /sse HTTP/1.1" 200 OK
INFO:     127.0.0.1:61672 - "POST /messages/?session_id=2586106048f9493d876ea2b56ad03dc8 HTTP/1.1" 202 Accepted
INFO:     127.0.0.1:61672 - "POST /messages/?session_id=2586106048f9493d876ea2b56ad03dc8 HTTP/1.1" 202 Accepted
INFO:     127.0.0.1:61672 - "POST /messages/?session_id=2586106048f9493d876ea2b56ad03dc8 HTTP/1.1" 202 Accepted
$ uv run python client.py
client is connected ? True
available tools: [Tool(name='greet', description=None, inputSchema={'properties': {'name': {'title': 'Name', 'type': 'string'}}, 'required': ['name'], 'type': 'object'}, annotations=None)]

FWIW, I experimented with the reported FastMCP 2.2.0 and there was an ASGI exception raised out of Uvicorn and Starlette, but I'm skeptical it's worth investigating since FastMCP has improved since 2.2.0 and moves quickly.


Thank U~

Geqiandipan avatar Jun 09 '25 08:06 Geqiandipan