Skip to content

The Python MCP server hangs when the /messages endpoint gives an unexpected response #410

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
samuelcolvin opened this issue Apr 2, 2025 · 2 comments

Comments

@samuelcolvin
Copy link
Member

samuelcolvin commented Apr 2, 2025

When the /messages endpoint returns say 404 or 405, a client hangs rather than raise the exception I would expect.

I get the error summary printed:

Error in post_writer: Client error '404 Not Found' for url 'http://localhost:8000/wrong?sessionId=d9e6a07d-e96f-420a-99f0-90f5444ddd43'
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404

Then nothing until I ctrl+c, when I get the traceback:

Traceback
^CTraceback (most recent call last):
  File "/Users/samuel/Library/Caches/uv/environments-v2/mcp-client-error-5fc93589004e4f10/lib/python3.12/site-packages/anyio/streams/memory.py", line 111, in receive
    return self.receive_nowait()
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/samuel/Library/Caches/uv/environments-v2/mcp-client-error-5fc93589004e4f10/lib/python3.12/site-packages/anyio/streams/memory.py", line 106, in receive_nowait
    raise WouldBlock
anyio.WouldBlock

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/samuel/.local/share/uv/python/cpython-3.12.7-macos-aarch64-none/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/samuel/.local/share/uv/python/cpython-3.12.7-macos-aarch64-none/lib/python3.12/asyncio/base_events.py", line 687, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/Users/samuel/code/pydantic-ai/mcp_client_error.py", line 13, in run
    async with ClientSession(read, write) as session:
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/samuel/Library/Caches/uv/environments-v2/mcp-client-error-5fc93589004e4f10/lib/python3.12/site-packages/mcp/shared/session.py", line 210, in __aexit__
    return await self._task_group.__aexit__(exc_type, exc_val, exc_tb)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/samuel/Library/Caches/uv/environments-v2/mcp-client-error-5fc93589004e4f10/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 776, in __aexit__
    raise exc_val
  File "/Users/samuel/code/pydantic-ai/mcp_client_error.py", line 14, in run
    await session.initialize()
  File "/Users/samuel/Library/Caches/uv/environments-v2/mcp-client-error-5fc93589004e4f10/lib/python3.12/site-packages/mcp/client/session.py", line 122, in initialize
    result = await self.send_request(
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/samuel/Library/Caches/uv/environments-v2/mcp-client-error-5fc93589004e4f10/lib/python3.12/site-packages/mcp/shared/session.py", line 252, in send_request
    response_or_error = await response_stream_reader.receive()
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/samuel/Library/Caches/uv/environments-v2/mcp-client-error-5fc93589004e4f10/lib/python3.12/site-packages/anyio/streams/memory.py", line 119, in receive
    await receive_event.wait()
  File "/Users/samuel/Library/Caches/uv/environments-v2/mcp-client-error-5fc93589004e4f10/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 1774, in wait
    await self._event.wait()
  File "/Users/samuel/.local/share/uv/python/cpython-3.12.7-macos-aarch64-none/lib/python3.12/asyncio/locks.py", line 212, in wait
    await fut
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/samuel/code/pydantic-ai/mcp_client_error.py", line 26, in <module>
    asyncio.run(run())
  File "/Users/samuel/.local/share/uv/python/cpython-3.12.7-macos-aarch64-none/lib/python3.12/asyncio/runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/Users/samuel/.local/share/uv/python/cpython-3.12.7-macos-aarch64-none/lib/python3.12/asyncio/runners.py", line 123, in run
    raise KeyboardInterrupt()
KeyboardInterrupt

MRE code:

Client:

# /// script
# requires-python = ">=3.12"
# dependencies = [
#     "mcp==1.6.0",
# ]
# ///
from mcp import ClientSession
from mcp.client.sse import sse_client


async def run():
    async with sse_client('http://localhost:8000/sse') as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            prompts = await session.list_prompts()
            print('prompts:', prompts)
            resources = await session.list_resources()
            print('resources:', resources)
            tools = await session.list_tools()
            print('tools:', tools)


if __name__ == "__main__":
    import asyncio
    asyncio.run(run())

Server

# /// script
# requires-python = ">=3.12"
# dependencies = [
#     "fastapi",
#     "uvicorn",
# ]
# ///
import json
from fastapi import FastAPI, Response

app = FastAPI()

sse_connect_response = json.dumps(
    {
        'result': {
            'protocolVersion': '2024-11-05',
            'capabilities': {'logging': {}, 'tools': {}},
            'serverInfo': {'name': 'Foobar', 'version': '0.0.1'},
        },
        'jsonrpc': '2.0',
        'id': 0,
    }
)

response = f"""\
event: endpoint
data: /wrong?sessionId=d9e6a07d-e96f-420a-99f0-90f5444ddd43

event: message
data: {sse_connect_response}
"""


@app.get('/sse')
def sse():
    return Response(content=response, media_type='text/event-stream')


if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app, port=8000)
@kavinkumar807
Copy link

I want to contribute to MCP actively, I’m happy to help with this issue and excited to start looking into it. Shall I begin investigating this ??

@gdoctor
Copy link

gdoctor commented Apr 4, 2025

I also experienced this hang for a similar but different reason. When the sse_client context manager raises the exception in line 81, the code will hang when you get to line 107 of sse_client (send call).

I suspect it's because there is nothing consuming the data we send yet. Of course nothing could be consuming the read_stream because we haven't yielded it yet since the above failure comes during startup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants