admin管理员组文章数量:1391968
I’m trying to create a Model Context Protocol (MCP) server in Python and PHP. The goal is to have both CursorAI and the MCP-Inspector client connect via SSE, perform an initialization call, and then (hopefully) automatically query tools/list, listOfferings, and other methods.
All my attempts have failed—Inspector and CursorAI get stuck somewhere, and I have no idea why. With ChatGPT, I created a basic server script that should handle all possibilities so I can at least see that something is happening. However, nothing happens.
I would expect Inspector and CursorAI to request information about tools and resources in some way, but they don’t seem to do that. Something appears to be wrong. I am not receiving any tools or resources, and both tools run into a timeout after a long time.
Here the Basic Python Server
import uvicorn
import json
import logging
import asyncio
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import PlainTextResponse, JSONResponse
from starlette.routing import Route
# MCP Python SDK: lowlevel server + SSE transport
from mcp.server.lowlevel import Server
from mcp.server.sse import SseServerTransport
from mcp.types import Tool, TextContent
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger("mcp-detailed")
logger.setLevel(logging.DEBUG)
###############################################################################
# MCP-Server
###############################################################################
mcp_server = Server("AllInOneDummyServer") # no "logger=..." argument
# Define some dummy tools
UPCASE_TOOL = Tool(
name="upcase",
description="Convert text to uppercase",
inputSchema={
"type": "object",
"properties": {
"text": {"type": "string", "description": "Text to uppercase"}
},
"required": ["text"]
}
)
AVAILABLE_TOOLS = [UPCASE_TOOL]
@mcp_server.call_tool()
async def call_tool(name: str, arguments: dict):
logger.info(f"[mcp_server.call_tool] name={name}, arguments={arguments}")
if name == "upcase":
text = arguments.get("text", "")
return [TextContent(type="text", text=text.upper())]
else:
raise ValueError(f"Unknown tool: {name}")
@mcp_server.list_tools()
async def list_tools():
logger.info("[mcp_server.list_tools] called")
return AVAILABLE_TOOLS
###############################################################################
# SSE Endpoint (GET /sse)
###############################################################################
async def sse_endpoint(request: Request):
logger.info("[SSE] => sse_endpoint called")
# SSE transport from the MCP SDK
sse_transport = SseServerTransport("/sse/messages")
scope = request.scope
receive = request.receive
send = request._send
async with sse_transport.connect_sse(scope, receive, send) as (read_st, write_st):
logger.info("[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'")
init_opts = mcp_server.create_initialization_options()
# Run the server with read/write streams
await mcp_server.run(read_st, write_st, init_opts)
logger.info("[SSE] => SSE session ended")
return
###############################################################################
# Keepalive-Task
###############################################################################
async def sse_keepalive_loop():
"""
Sends periodic keep-alive pings into SSE (just comment lines).
"""
while True:
logger.debug("[KeepAliveLoop] SSE keep-alive ping (no actual method).")
await asyncio.sleep(20)
###############################################################################
# JSON-RPC Endpoint (POST /sse/messages)
###############################################################################
async def post_handler(request: Request):
raw = await request.body()
body_str = raw.decode("utf-8")
logger.info(f"[POST /sse/messages] => {body_str}")
if not body_str.strip():
return PlainTextResponse("Empty body\n", 400)
try:
msg = json.loads(body_str)
except Exception as e:
logger.error(f"[POST] JSON parse error: {e}")
return PlainTextResponse("Invalid JSON\n", 400)
if msg.get("jsonrpc") != "2.0":
logger.error("[POST] => Missing jsonrpc=2.0")
return PlainTextResponse("Missing jsonrpc=2.0\n", 400)
id_ = msg.get("id")
method = msg.get("method","")
params = msg.get("params",{})
logger.debug(f"[POST] method={method}, id={id_}, params={params}")
server_info = {"name":"AllInOneDummyServer","version":"1.0.0"}
# If no id => it's a notification
if id_ is None:
logger.info(f"Received NOTIFICATION => method={method}, params={params}")
# We do nothing or just debug
return PlainTextResponse("", 200)
# ===============================================================
# The "initialize" method
# ===============================================================
if method == "initialize":
logger.info("Handling 'initialize' in post_handler")
# Build capabilities, offerings, etc.
result = {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {"listChanged": True},
"resources": {"listChanged": True, "subscribe": True},
"prompts": {"listChanged": True},
"logging": True,
"roots": {"listChanged": True},
"sampling": True,
},
"serverInfo": server_info,
"offerings": [
{"name": "upcaseTool", "description": "Tool that upcases text"},
{"name": "fakePrompt", "description": "A dummy prompt"},
{"name": "someResource", "description": "Fake resource for tests"},
],
"tools": [
{
"name": "upcase",
"description": "Convert text to uppercase",
"inputSchema": {
"type": "object",
"properties": {
"text":{"type":"string","description":"Text to uppercase"}
},
"required":["text"]
}
}
]
}
resp = {"jsonrpc":"2.0","id":id_,"result":result}
logger.debug(f"Sending initialize response: {json.dumps(resp)}")
return JSONResponse(resp)
# ===============================================================
# Some other typical methods (ping, listOfferings, tools/list, etc)
# ===============================================================
if method == "ping":
logger.info("Handling 'ping'")
resp = {"jsonrpc":"2.0","id":id_,"result":"pong"}
return JSONResponse(resp)
elif method == "listOfferings":
logger.info("Handling 'listOfferings'")
result = {
"serverInfo": server_info,
"capabilities": {
"tools": {"listChanged": True},
"resources": {"listChanged": True,"subscribe":True},
"prompts": {"listChanged": True},
"logging": True,
"roots": {"listChanged": True},
"sampling": True
},
"offerings":[
{"name":"upcaseTool","description":"tool upcase"},
{"name":"fakePrompt","description":"Dummy prompt"},
{"name":"someResource","description":"Fake resource"},
]
}
resp = {"jsonrpc":"2.0","id":id_,"result":result}
return JSONResponse(resp)
elif method == "tools/list":
logger.info("Handling 'tools/list'")
tools_list = [
{
"name":"upcase",
"description":"Converts text to uppercase",
"inputSchema":{
"type":"object",
"properties":{"text":{"type":"string","description":"The text to uppercase"}},
"required":["text"]
}
}
]
resp = {"jsonrpc":"2.0","id":id_,"result":{
"serverInfo":server_info,
"tools":tools_list
}}
return JSONResponse(resp)
elif method == "tools/call":
logger.info("Handling 'tools/call'")
name = params.get("name","")
arguments = params.get("arguments",{})
if name=="upcase":
text = arguments.get("text","")
upper = text.upper()
ret = {
"jsonrpc":"2.0","id":id_,
"result":{"content":[{"type":"text","text":upper}]}
}
return JSONResponse(ret)
else:
err = {"jsonrpc":"2.0","id":id_,
"error":{"code":-32601,"message":f"Unknown tool: {name}"}}
return JSONResponse(err)
# === Resources
elif method == "resources/list":
logger.info("Handling 'resources/list'")
resources = [
{
"uri":"fake://dummyResource",
"name":"Fake Resource",
"description":"A test resource"
}
]
resp = {"jsonrpc":"2.0","id":id_,
"result":{"serverInfo": server_info,"resources":resources}}
return JSONResponse(resp)
elif method == "resources/subscribe":
logger.info("Handling 'resources/subscribe'")
resp = {"jsonrpc":"2.0","id":id_,"result":{"subscribed":True}}
return JSONResponse(resp)
elif method == "resources/read":
logger.info("Handling 'resources/read'")
uri = params.get("uri","fake://dummyResource")
resp = {
"jsonrpc":"2.0","id":id_,
"result":{
"contents":[{"type":"text","text":f"Dummy contents for {uri}"}]
}
}
return JSONResponse(resp)
# === Prompts
elif method == "prompts/list":
logger.info("Handling 'prompts/list'")
resp = {
"jsonrpc":"2.0","id":id_,
"result":{
"prompts":[
{
"name":"fakePrompt",
"description":"Dummy prompt example",
"arguments":[
{"name":"arg1","description":"Example arg","required":True}
]
}
]
}
}
return JSONResponse(resp)
# Uknown method => error
else:
logger.warning(f"Unknown method => {method}")
err = {
"jsonrpc":"2.0","id":id_,
"error":{
"code":-32601,
"message":f"Method '{method}' not found"
}
}
return JSONResponse(err)
# starlette routing
routes = [
Route("/sse", sse_endpoint, methods=["GET"]),
Route("/sse/messages", post_handler, methods=["POST","OPTIONS"])
]
from starlette.middleware import Middleware
from starlette.middleware.cors import CORSMiddleware
middleware = [
Middleware(CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"])
]
app = Starlette(debug=True, routes=routes, middleware=middleware)
@app.on_event("startup")
async def on_startup():
logger.info("App Startup: launching SSE keepalive background task")
loop = asyncio.get_event_loop()
loop.create_task(sse_keepalive_loop())
if __name__=="__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
My log output what happend you can see here
(venv) root@localhost:/opt/my_mcp_venv# python server.py
DEBUG:mcp.server.lowlevel.server:Initializing server 'AllInOneDummyServer'
DEBUG:mcp.server.lowlevel.server:Registering handler for CallToolRequest
DEBUG:mcp.server.lowlevel.server:Registering handler for ListToolsRequest
DEBUG:asyncio:Using selector: EpollSelector
INFO: Started server process [1082343]
INFO: Waiting for application startup.
INFO:mcp-detailed:App Startup: launching SSE keepalive background task
DEBUG:mcp-detailed:[KeepAliveLoop] SSE keep-alive ping (no actual method).
INFO: Application startup complete.
INFO: Uvicorn running on :8000 (Press CTRL+C to quit)
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 4ce9e4fa-44f1-4f43-a7a9-026ee59faa3b
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO: {IP}:38378 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=4ce9e4fa44f14f43a7a9026ee59faa3b
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=4ce9e4fa44f14f43a7a9026ee59faa3b\r\n\r\n'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 728fd505-8663-4ea4-bf3e-b1ade3cf812c
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO: {IP}:38387 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=728fd50586634ea4bf3eb1ade3cf812c
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=728fd50586634ea4bf3eb1ade3cf812c\r\n\r\n'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 5340a58c-b0d2-449c-bc37-cb42c555b6ee
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 1c108457-e826-4d37-bde9-781f11e4cdb4
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 60c081d1-dc42-461d-be72-c79f0296ed38
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO: {IP}:37888 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
INFO: {IP}:37891 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
INFO: {IP}:38398 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=5340a58cb0d2449cbc37cb42c555b6ee
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=1c108457e8264d37bde9781f11e4cdb4
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=60c081d1dc42461dbe72c79f0296ed38
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=5340a58cb0d2449cbc37cb42c555b6ee\r\n\r\n'
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=1c108457e8264d37bde9781f11e4cdb4\r\n\r\n'
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=60c081d1dc42461dbe72c79f0296ed38\r\n\r\n'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 6427f59a-79f1-4d4a-bd8c-1e1addeb2f90
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 0f929ade-9481-4854-a8c7-2d987c11cd1b
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 4eafb787-1712-449a-bf46-5d7dfb6c3390
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 6db64772-fde7-4f8d-8309-43a999647ee0
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO: {IP}:37914 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
INFO: {IP}:37916 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
INFO: {IP}:37915 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
INFO: {IP}:37917 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=6427f59a79f14d4abd8c1e1addeb2f90
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=0f929ade94814854a8c72d987c11cd1b
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=4eafb7871712449abf465d7dfb6c3390
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=6db64772fde74f8d830943a999647ee0
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=6427f59a79f14d4abd8c1e1addeb2f90\r\n\r\n'
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=0f929ade94814854a8c72d987c11cd1b\r\n\r\n'
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=4eafb7871712449abf465d7dfb6c3390\r\n\r\n'
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=6db64772fde74f8d830943a999647ee0\r\n\r\n'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 4e1e731c-d4be-4ef5-91c5-87dca9c998a0
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO: {IP}:37979 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=4e1e731cd4be4ef591c587dca9c998a0
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=4e1e731cd4be4ef591c587dca9c998a0\r\n\r\n'
INFO:mcp-detailed:[POST /sse/messages] => {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{"sampling":{},"roots":{"listChanged":true}},"clientInfo":{"name":"mcp-inspector","version":"0.0.1"}}}
DEBUG:mcp-detailed:[POST] method=initialize, id=0, params={'protocolVersion': '2024-11-05', 'capabilities': {'sampling': {}, 'roots': {'listChanged': True}}, 'clientInfo': {'name': 'mcp-inspector', 'version': '0.0.1'}}
INFO:mcp-detailed:Handling 'initialize' in post_handler
DEBUG:mcp-detailed:Sending initialize response: {"jsonrpc": "2.0", "id": 0, "result": {"protocolVersion": "2024-11-05", "capabilities": {"tools": {"listChanged": true}, "resources": {"listChanged": true, "subscribe": true}, "prompts": {"listChanged": true}, "logging": true, "roots": {"listChanged": true}, "sampling": true}, "serverInfo": {"name": "AllInOneDummyServer", "version": "1.0.0"}, "offerings": [{"name": "upcaseTool", "description": "Tool that upcases text"}, {"name": "fakePrompt", "description": "A dummy prompt"}, {"name": "someResource", "description": "Fake resource for tests"}], "tools": [{"name": "upcase", "description": "Convert text to uppercase", "inputSchema": {"type": "object", "properties": {"text": {"type": "string", "description": "Text to uppercase"}}, "required": ["text"]}}]}}
INFO: {IP}:37995 - "POST /sse/messages?session_id=4e1e731cd4be4ef591c587dca9c998a0 HTTP/1.1" 200 OK
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.459813+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.463268+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.517800+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.518266+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.518759+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.531301+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.531763+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.533097+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.533400+00:00\r\n\r\n'
DEBUG:mcp-detailed:[KeepAliveLoop] SSE keep-alive ping (no actual method).
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:27.108246+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.462830+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.463590+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.519222+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.519658+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.519876+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.532655+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.533044+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.533501+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.533762+00:00\r\n\r\n'
If i call with CursorAI is see the same the log output of Cursor AI itself look like that
2025-03-13 10:25:28.169 [info] d0c4: Handling CreateClient action
2025-03-13 10:25:28.169 [info] d0c4: getOrCreateClient for sse server
2025-03-13 10:25:28.169 [info] d0c4: Creating SSE transport
2025-03-13 10:26:28.339 [info] d0c4: Client closed for command
2025-03-13 10:26:28.340 [error] d0c4: Error in MCP: Client closed
2025-03-13 10:26:28.340 [error] d0c4: Client error for command This operation was aborted
2025-03-13 10:26:28.341 [error] d0c4: Error in MCP: This operation was aborted
2025-03-13 10:26:28.341 [error] d0c4: Client error for command Failed to send cancellation: AbortError: This operation was aborted
2025-03-13 10:26:28.341 [error] d0c4: Error in MCP: Failed to send cancellation: AbortError: This operation was aborted
2025-03-13 10:26:28.344 [info] d0c4: Handling ListOfferings action
2025-03-13 10:26:28.345 [error] d0c4: No server info found
I really have no clue, why no Tools or ressources transfered to Inspector or CursorAI. What i am missing.
- I tried to create a native PHP implementation, no tools/no ressources transfered and it stucks and run in timeout
- I tried to create a logiscape/mcp-sdk-php implementation, no tools/no ressources transfered and it stucks and run in timeout
- I tried a Python implementation with an SDK, no tools/no ressources transfered and it stucks and run in timeout
I’m trying to create a Model Context Protocol (MCP) server in Python and PHP. The goal is to have both CursorAI and the MCP-Inspector client connect via SSE, perform an initialization call, and then (hopefully) automatically query tools/list, listOfferings, and other methods.
All my attempts have failed—Inspector and CursorAI get stuck somewhere, and I have no idea why. With ChatGPT, I created a basic server script that should handle all possibilities so I can at least see that something is happening. However, nothing happens.
I would expect Inspector and CursorAI to request information about tools and resources in some way, but they don’t seem to do that. Something appears to be wrong. I am not receiving any tools or resources, and both tools run into a timeout after a long time.
Here the Basic Python Server
import uvicorn
import json
import logging
import asyncio
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import PlainTextResponse, JSONResponse
from starlette.routing import Route
# MCP Python SDK: lowlevel server + SSE transport
from mcp.server.lowlevel import Server
from mcp.server.sse import SseServerTransport
from mcp.types import Tool, TextContent
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger("mcp-detailed")
logger.setLevel(logging.DEBUG)
###############################################################################
# MCP-Server
###############################################################################
mcp_server = Server("AllInOneDummyServer") # no "logger=..." argument
# Define some dummy tools
UPCASE_TOOL = Tool(
name="upcase",
description="Convert text to uppercase",
inputSchema={
"type": "object",
"properties": {
"text": {"type": "string", "description": "Text to uppercase"}
},
"required": ["text"]
}
)
AVAILABLE_TOOLS = [UPCASE_TOOL]
@mcp_server.call_tool()
async def call_tool(name: str, arguments: dict):
logger.info(f"[mcp_server.call_tool] name={name}, arguments={arguments}")
if name == "upcase":
text = arguments.get("text", "")
return [TextContent(type="text", text=text.upper())]
else:
raise ValueError(f"Unknown tool: {name}")
@mcp_server.list_tools()
async def list_tools():
logger.info("[mcp_server.list_tools] called")
return AVAILABLE_TOOLS
###############################################################################
# SSE Endpoint (GET /sse)
###############################################################################
async def sse_endpoint(request: Request):
logger.info("[SSE] => sse_endpoint called")
# SSE transport from the MCP SDK
sse_transport = SseServerTransport("/sse/messages")
scope = request.scope
receive = request.receive
send = request._send
async with sse_transport.connect_sse(scope, receive, send) as (read_st, write_st):
logger.info("[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'")
init_opts = mcp_server.create_initialization_options()
# Run the server with read/write streams
await mcp_server.run(read_st, write_st, init_opts)
logger.info("[SSE] => SSE session ended")
return
###############################################################################
# Keepalive-Task
###############################################################################
async def sse_keepalive_loop():
"""
Sends periodic keep-alive pings into SSE (just comment lines).
"""
while True:
logger.debug("[KeepAliveLoop] SSE keep-alive ping (no actual method).")
await asyncio.sleep(20)
###############################################################################
# JSON-RPC Endpoint (POST /sse/messages)
###############################################################################
async def post_handler(request: Request):
raw = await request.body()
body_str = raw.decode("utf-8")
logger.info(f"[POST /sse/messages] => {body_str}")
if not body_str.strip():
return PlainTextResponse("Empty body\n", 400)
try:
msg = json.loads(body_str)
except Exception as e:
logger.error(f"[POST] JSON parse error: {e}")
return PlainTextResponse("Invalid JSON\n", 400)
if msg.get("jsonrpc") != "2.0":
logger.error("[POST] => Missing jsonrpc=2.0")
return PlainTextResponse("Missing jsonrpc=2.0\n", 400)
id_ = msg.get("id")
method = msg.get("method","")
params = msg.get("params",{})
logger.debug(f"[POST] method={method}, id={id_}, params={params}")
server_info = {"name":"AllInOneDummyServer","version":"1.0.0"}
# If no id => it's a notification
if id_ is None:
logger.info(f"Received NOTIFICATION => method={method}, params={params}")
# We do nothing or just debug
return PlainTextResponse("", 200)
# ===============================================================
# The "initialize" method
# ===============================================================
if method == "initialize":
logger.info("Handling 'initialize' in post_handler")
# Build capabilities, offerings, etc.
result = {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {"listChanged": True},
"resources": {"listChanged": True, "subscribe": True},
"prompts": {"listChanged": True},
"logging": True,
"roots": {"listChanged": True},
"sampling": True,
},
"serverInfo": server_info,
"offerings": [
{"name": "upcaseTool", "description": "Tool that upcases text"},
{"name": "fakePrompt", "description": "A dummy prompt"},
{"name": "someResource", "description": "Fake resource for tests"},
],
"tools": [
{
"name": "upcase",
"description": "Convert text to uppercase",
"inputSchema": {
"type": "object",
"properties": {
"text":{"type":"string","description":"Text to uppercase"}
},
"required":["text"]
}
}
]
}
resp = {"jsonrpc":"2.0","id":id_,"result":result}
logger.debug(f"Sending initialize response: {json.dumps(resp)}")
return JSONResponse(resp)
# ===============================================================
# Some other typical methods (ping, listOfferings, tools/list, etc)
# ===============================================================
if method == "ping":
logger.info("Handling 'ping'")
resp = {"jsonrpc":"2.0","id":id_,"result":"pong"}
return JSONResponse(resp)
elif method == "listOfferings":
logger.info("Handling 'listOfferings'")
result = {
"serverInfo": server_info,
"capabilities": {
"tools": {"listChanged": True},
"resources": {"listChanged": True,"subscribe":True},
"prompts": {"listChanged": True},
"logging": True,
"roots": {"listChanged": True},
"sampling": True
},
"offerings":[
{"name":"upcaseTool","description":"tool upcase"},
{"name":"fakePrompt","description":"Dummy prompt"},
{"name":"someResource","description":"Fake resource"},
]
}
resp = {"jsonrpc":"2.0","id":id_,"result":result}
return JSONResponse(resp)
elif method == "tools/list":
logger.info("Handling 'tools/list'")
tools_list = [
{
"name":"upcase",
"description":"Converts text to uppercase",
"inputSchema":{
"type":"object",
"properties":{"text":{"type":"string","description":"The text to uppercase"}},
"required":["text"]
}
}
]
resp = {"jsonrpc":"2.0","id":id_,"result":{
"serverInfo":server_info,
"tools":tools_list
}}
return JSONResponse(resp)
elif method == "tools/call":
logger.info("Handling 'tools/call'")
name = params.get("name","")
arguments = params.get("arguments",{})
if name=="upcase":
text = arguments.get("text","")
upper = text.upper()
ret = {
"jsonrpc":"2.0","id":id_,
"result":{"content":[{"type":"text","text":upper}]}
}
return JSONResponse(ret)
else:
err = {"jsonrpc":"2.0","id":id_,
"error":{"code":-32601,"message":f"Unknown tool: {name}"}}
return JSONResponse(err)
# === Resources
elif method == "resources/list":
logger.info("Handling 'resources/list'")
resources = [
{
"uri":"fake://dummyResource",
"name":"Fake Resource",
"description":"A test resource"
}
]
resp = {"jsonrpc":"2.0","id":id_,
"result":{"serverInfo": server_info,"resources":resources}}
return JSONResponse(resp)
elif method == "resources/subscribe":
logger.info("Handling 'resources/subscribe'")
resp = {"jsonrpc":"2.0","id":id_,"result":{"subscribed":True}}
return JSONResponse(resp)
elif method == "resources/read":
logger.info("Handling 'resources/read'")
uri = params.get("uri","fake://dummyResource")
resp = {
"jsonrpc":"2.0","id":id_,
"result":{
"contents":[{"type":"text","text":f"Dummy contents for {uri}"}]
}
}
return JSONResponse(resp)
# === Prompts
elif method == "prompts/list":
logger.info("Handling 'prompts/list'")
resp = {
"jsonrpc":"2.0","id":id_,
"result":{
"prompts":[
{
"name":"fakePrompt",
"description":"Dummy prompt example",
"arguments":[
{"name":"arg1","description":"Example arg","required":True}
]
}
]
}
}
return JSONResponse(resp)
# Uknown method => error
else:
logger.warning(f"Unknown method => {method}")
err = {
"jsonrpc":"2.0","id":id_,
"error":{
"code":-32601,
"message":f"Method '{method}' not found"
}
}
return JSONResponse(err)
# starlette routing
routes = [
Route("/sse", sse_endpoint, methods=["GET"]),
Route("/sse/messages", post_handler, methods=["POST","OPTIONS"])
]
from starlette.middleware import Middleware
from starlette.middleware.cors import CORSMiddleware
middleware = [
Middleware(CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"])
]
app = Starlette(debug=True, routes=routes, middleware=middleware)
@app.on_event("startup")
async def on_startup():
logger.info("App Startup: launching SSE keepalive background task")
loop = asyncio.get_event_loop()
loop.create_task(sse_keepalive_loop())
if __name__=="__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
My log output what happend you can see here
(venv) root@localhost:/opt/my_mcp_venv# python server.py
DEBUG:mcp.server.lowlevel.server:Initializing server 'AllInOneDummyServer'
DEBUG:mcp.server.lowlevel.server:Registering handler for CallToolRequest
DEBUG:mcp.server.lowlevel.server:Registering handler for ListToolsRequest
DEBUG:asyncio:Using selector: EpollSelector
INFO: Started server process [1082343]
INFO: Waiting for application startup.
INFO:mcp-detailed:App Startup: launching SSE keepalive background task
DEBUG:mcp-detailed:[KeepAliveLoop] SSE keep-alive ping (no actual method).
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 4ce9e4fa-44f1-4f43-a7a9-026ee59faa3b
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO: {IP}:38378 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=4ce9e4fa44f14f43a7a9026ee59faa3b
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=4ce9e4fa44f14f43a7a9026ee59faa3b\r\n\r\n'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 728fd505-8663-4ea4-bf3e-b1ade3cf812c
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO: {IP}:38387 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=728fd50586634ea4bf3eb1ade3cf812c
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=728fd50586634ea4bf3eb1ade3cf812c\r\n\r\n'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 5340a58c-b0d2-449c-bc37-cb42c555b6ee
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 1c108457-e826-4d37-bde9-781f11e4cdb4
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 60c081d1-dc42-461d-be72-c79f0296ed38
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO: {IP}:37888 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
INFO: {IP}:37891 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
INFO: {IP}:38398 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=5340a58cb0d2449cbc37cb42c555b6ee
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=1c108457e8264d37bde9781f11e4cdb4
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=60c081d1dc42461dbe72c79f0296ed38
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=5340a58cb0d2449cbc37cb42c555b6ee\r\n\r\n'
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=1c108457e8264d37bde9781f11e4cdb4\r\n\r\n'
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=60c081d1dc42461dbe72c79f0296ed38\r\n\r\n'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 6427f59a-79f1-4d4a-bd8c-1e1addeb2f90
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 0f929ade-9481-4854-a8c7-2d987c11cd1b
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 4eafb787-1712-449a-bf46-5d7dfb6c3390
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 6db64772-fde7-4f8d-8309-43a999647ee0
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO: {IP}:37914 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
INFO: {IP}:37916 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
INFO: {IP}:37915 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
INFO: {IP}:37917 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=6427f59a79f14d4abd8c1e1addeb2f90
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=0f929ade94814854a8c72d987c11cd1b
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=4eafb7871712449abf465d7dfb6c3390
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=6db64772fde74f8d830943a999647ee0
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=6427f59a79f14d4abd8c1e1addeb2f90\r\n\r\n'
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=0f929ade94814854a8c72d987c11cd1b\r\n\r\n'
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=4eafb7871712449abf465d7dfb6c3390\r\n\r\n'
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=6db64772fde74f8d830943a999647ee0\r\n\r\n'
INFO:mcp-detailed:[SSE] => sse_endpoint called
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /sse/messages
DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 4e1e731c-d4be-4ef5-91c5-87dca9c998a0
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:mcp-detailed:[SSE] run mcp_server with SSE transport => calling 'mcp_server.run'
INFO: {IP}:37979 - "GET /sse HTTP/1.1" 200 OK
DEBUG:mcp.server.sse:Starting SSE writer
DEBUG:mcp.server.sse:Sent endpoint event: /sse/messages?session_id=4e1e731cd4be4ef591c587dca9c998a0
DEBUG:sse_starlette.sse:chunk: b'event: endpoint\r\ndata: /sse/messages?session_id=4e1e731cd4be4ef591c587dca9c998a0\r\n\r\n'
INFO:mcp-detailed:[POST /sse/messages] => {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{"sampling":{},"roots":{"listChanged":true}},"clientInfo":{"name":"mcp-inspector","version":"0.0.1"}}}
DEBUG:mcp-detailed:[POST] method=initialize, id=0, params={'protocolVersion': '2024-11-05', 'capabilities': {'sampling': {}, 'roots': {'listChanged': True}}, 'clientInfo': {'name': 'mcp-inspector', 'version': '0.0.1'}}
INFO:mcp-detailed:Handling 'initialize' in post_handler
DEBUG:mcp-detailed:Sending initialize response: {"jsonrpc": "2.0", "id": 0, "result": {"protocolVersion": "2024-11-05", "capabilities": {"tools": {"listChanged": true}, "resources": {"listChanged": true, "subscribe": true}, "prompts": {"listChanged": true}, "logging": true, "roots": {"listChanged": true}, "sampling": true}, "serverInfo": {"name": "AllInOneDummyServer", "version": "1.0.0"}, "offerings": [{"name": "upcaseTool", "description": "Tool that upcases text"}, {"name": "fakePrompt", "description": "A dummy prompt"}, {"name": "someResource", "description": "Fake resource for tests"}], "tools": [{"name": "upcase", "description": "Convert text to uppercase", "inputSchema": {"type": "object", "properties": {"text": {"type": "string", "description": "Text to uppercase"}}, "required": ["text"]}}]}}
INFO: {IP}:37995 - "POST /sse/messages?session_id=4e1e731cd4be4ef591c587dca9c998a0 HTTP/1.1" 200 OK
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.459813+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.463268+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.517800+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.518266+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.518759+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.531301+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.531763+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.533097+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:20.533400+00:00\r\n\r\n'
DEBUG:mcp-detailed:[KeepAliveLoop] SSE keep-alive ping (no actual method).
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:27.108246+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.462830+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.463590+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.519222+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.519658+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.519876+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.532655+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.533044+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.533501+00:00\r\n\r\n'
DEBUG:sse_starlette.sse:ping: b': ping - 2025-03-13 02:40:35.533762+00:00\r\n\r\n'
If i call with CursorAI is see the same the log output of Cursor AI itself look like that
2025-03-13 10:25:28.169 [info] d0c4: Handling CreateClient action
2025-03-13 10:25:28.169 [info] d0c4: getOrCreateClient for sse server
2025-03-13 10:25:28.169 [info] d0c4: Creating SSE transport
2025-03-13 10:26:28.339 [info] d0c4: Client closed for command
2025-03-13 10:26:28.340 [error] d0c4: Error in MCP: Client closed
2025-03-13 10:26:28.340 [error] d0c4: Client error for command This operation was aborted
2025-03-13 10:26:28.341 [error] d0c4: Error in MCP: This operation was aborted
2025-03-13 10:26:28.341 [error] d0c4: Client error for command Failed to send cancellation: AbortError: This operation was aborted
2025-03-13 10:26:28.341 [error] d0c4: Error in MCP: Failed to send cancellation: AbortError: This operation was aborted
2025-03-13 10:26:28.344 [info] d0c4: Handling ListOfferings action
2025-03-13 10:26:28.345 [error] d0c4: No server info found
I really have no clue, why no Tools or ressources transfered to Inspector or CursorAI. What i am missing.
- I tried to create a native PHP implementation, no tools/no ressources transfered and it stucks and run in timeout
- I tried to create a logiscape/mcp-sdk-php implementation, no tools/no ressources transfered and it stucks and run in timeout
- I tried a Python implementation with an SDK, no tools/no ressources transfered and it stucks and run in timeout
- After one week of try and error here a working example Server in Node.JS github/b3nelof0n/node-mcp-server feel free to use it for learning purpose or… – Patrick Müssig Commented Mar 16 at 2:52
2 Answers
Reset to default 0Here's an example that demonstrates a working pattern for SSE-based MCP servers and standalone MCP clients that use tools from them.
https://github/sidharthrajaram/mcp-sse/tree/main
There is information in this article about how to use SSE to build MCP, which may be helpful to you.
https://github/liaokongVFX/MCP-Chinese-Getting-Started-Guide
本文标签: pythonHow to implement a Model Context Protocol (MCP) server with SSEStack Overflow
版权声明:本文标题:python - How to implement a Model Context Protocol (MCP) server with SSE? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744720418a2621659.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论