[GH-ISSUE #152] issue: When I use the .NET SSE service of MCPO, I frequently encounter ​ClosedResourceError​ issues. #67

Open
opened 2026-10-18 21:11:13 +00:00 by bsakaguchi · 7 comments
Owner

Originally created by @tamakiramimy on GitHub (May 22, 2025).
Original GitHub issue: https://github.com/open-webui/mcpo/issues/152

Check Existing Issues

  • I have searched the existing issues and discussions.
  • I am using the latest version of mcpo.

mcpo Version

v0.0.12

Open WebUI Version (if applicable)

v0.6.5

Operating System

docker or ocp(red hat) for dotnet mcpo

Browser (if applicable)

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36

Confirmation

  • I have read and followed all instructions in README.md.
  • I am using the latest version of both MCPO and Open WebUI.
  • I have included the browser console logs.
  • I have included the Docker container logs.
  • I have listed steps to reproduce the bug in detail.

Expected Behavior

To ensure stable communication between ​MCPO​ and the ​**.NET SSE service**, even after long idle periods, you should ​create a new session per request​ instead of reusing the same session.

Actual Behavior

When I use the .NET SSE service of MCPO, I frequently encounter ​ClosedResourceError​ issues.

​Local Debug Mode:
When testing locally in debug mode, both the ​**.NET SSE service​ and ​MCPO**​ work flawlessly. Even after prolonged inactivity, reconnecting succeeds without issues.
​Deployment Issues (Docker/Red Hat OCP)​:
After deploying to ​Docker​ or ​Red Hat OpenShift (OCP)​:
Services initially function correctly.
Within ​2-3 minutes, consistent ClosedResourceError occurs.
​Error source: mcp/session.py.
​Attempted fix: Upgraded MCPO to ​v1.9.0​ – issue persists.
​Observation:
MCPO’s main.py initializes a session, but subsequent tool invocations ​reuse the same session​ instead of creating a new request.
​Suspected root cause: Session reuse leads to stale/closed connections.

Steps to Reproduce

1.pubulish mcpo to docker
2.pubulish dotnet sse service to docker
3.request once at both services start
4.wait for 3-5 min,request again

​Error Details;

Unexpected error calling GetCurrentDateTime:
Error traceback: Traceback (most recent call last):
File "/opt/app-root/src/mcpo/utils/main.py", line 268, in tool
result = await session.call_tool(
^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/app-root/lib64/python3.12/site-packages/mcp/client/session.py", line 277, in call_tool
return await self.send_request(
^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/app-root/lib64/python3.12/site-packages/mcp/shared/session.py", line 265, in send_request
await self._write_stream.send(
File "/opt/app-root/lib64/python3.12/site-packages/anyio/streams/memory.py", line 242, in send
self.send_nowait(item)
File "/opt/app-root/lib64/python3.12/site-packages/anyio/streams/memory.py", line 211, in send_nowait
raise ClosedResourceError
anyio.ClosedResourceError
INFO: 127.0.0.6:40397 - "POST /net_sse/GetCurrentDateTime HTTP/1.1" 500 Internal Server Error

Logs & Screenshots

Image

Additional Information

No response

Originally created by @tamakiramimy on GitHub (May 22, 2025). Original GitHub issue: https://github.com/open-webui/mcpo/issues/152 ### Check Existing Issues - [x] I have searched the existing issues and discussions. - [x] I am using the latest version of mcpo. ### mcpo Version v0.0.12 ### Open WebUI Version (if applicable) v0.6.5 ### Operating System docker or ocp(red hat) for dotnet mcpo ### Browser (if applicable) Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 ### Confirmation - [x] I have read and followed all instructions in `README.md`. - [x] I am using the latest version of **both** MCPO and Open WebUI. - [x] I have included the browser console logs. - [x] I have included the Docker container logs. - [x] I have listed steps to reproduce the bug in detail. ### Expected Behavior To ensure stable communication between ​MCPO​ and the ​**.NET SSE service**, even after long idle periods, you should ​create a new session per request​ instead of reusing the same session. ### Actual Behavior When I use the .NET SSE service of MCPO, I frequently encounter ​ClosedResourceError​ issues. ​Local Debug Mode: When testing locally in debug mode, both the ​**.NET SSE service​ and ​MCPO**​ work flawlessly. Even after prolonged inactivity, reconnecting succeeds without issues. ​Deployment Issues (Docker/Red Hat OCP)​: After deploying to ​Docker​ or ​Red Hat OpenShift (OCP)​: Services initially function correctly. Within ​2-3 minutes, consistent ClosedResourceError occurs. ​Error source: mcp/session.py. ​Attempted fix: Upgraded MCPO to ​v1.9.0​ – issue persists. ​Observation: MCPO’s main.py initializes a session, but subsequent tool invocations ​reuse the same session​ instead of creating a new request. ​Suspected root cause: Session reuse leads to stale/closed connections. ### Steps to Reproduce 1.pubulish mcpo to docker 2.pubulish dotnet sse service to docker 3.request once at both services start 4.wait for 3-5 min,request again ​Error Details; Unexpected error calling GetCurrentDateTime: Error traceback: Traceback (most recent call last): File "/opt/app-root/src/mcpo/utils/main.py", line 268, in tool result = await session.call_tool( ^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/app-root/lib64/python3.12/site-packages/mcp/client/session.py", line 277, in call_tool return await self.send_request( ^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/app-root/lib64/python3.12/site-packages/mcp/shared/session.py", line 265, in send_request await self._write_stream.send( File "/opt/app-root/lib64/python3.12/site-packages/anyio/streams/memory.py", line 242, in send self.send_nowait(item) File "/opt/app-root/lib64/python3.12/site-packages/anyio/streams/memory.py", line 211, in send_nowait raise ClosedResourceError anyio.ClosedResourceError INFO: 127.0.0.6:40397 - "POST /net_sse/GetCurrentDateTime HTTP/1.1" 500 Internal Server Error ### Logs & Screenshots ![Image](https://github.com/user-attachments/assets/db61971e-550c-4ff9-b9ca-27826dd1f4ca) ### Additional Information _No response_
Author
Owner

@tamakiramimy commented on GitHub (May 26, 2025):

@tjbck
I've already resolved this issue. I suggest merging my changes into your branch. The main fix handles automatic reconnection when the MCP server restarts or encounters a timeout. Here’s the code:

# 特殊处理,传递headers
if headers:
    userinfo = {}
    if headers.get("x-user-email"):
        userinfo["Email"] = headers.get("x-user-email")
    if headers.get("x-user-id"):
        userinfo["Id"] = headers.get("x-user-id")
    if headers.get("x-user-token"):
        userinfo["Token"] = headers.get("x-user-token")
    final_arguments["user"] = userinfo
        
print(f"Calling endpoint: {endpoint_name}, with args: {final_arguments}")
try:
    result = await current_session.call_tool(endpoint_name, arguments=final_arguments)
    print(f"Calling endpoint: {endpoint_name}, with args: {final_arguments} result: {result}")
    
    if result.isError:
        error_message = "Unknown tool execution error"
        if result.content and isinstance(result.content[0], types.TextContent):
            error_message = result.content[0].text
        
        detail = {"message": error_message}
        raise HTTPException(
            status_code=500,
            detail=detail,
        )
        
    response_data = process_tool_response(result)
    final_response = (
        response_data[0] if len(response_data) == 1 else response_data
    )
    return final_response
    
except McpError as e:
    print(f"MCP Error calling {endpoint_name}: {e.error}")
    # 尝试重新初始化会话
    print("Session terminated, 尝试重新初始化会话...")
    if e.error.message == 'Session terminated' and hasattr(current_session, 'context') and 'request' in current_session.context:
        request = current_session.context['request']
        # 尝试从请求和应用状态获取连接信息
        app = getattr(request, "app", None)
        server_type = getattr(app.state, "server_type", "stdio")
        args = getattr(app.state, "args", [])
        command = getattr(app.state, "command", None)
        env = getattr(app.state, "env", {})
        
        # 调用重试方法
        return await McpReCallTools(
            server_type=server_type, 
            args=args, 
            command=command, 
            env=env, 
            endpoint_name=endpoint_name, 
            arguments=final_arguments
        )

except Exception as e:
    # 处理 ClosedResourceError
    if isinstance(e, ClosedResourceError):
        print(f"Connection closed error: {str(e)}")
        if hasattr(current_session, 'context') and 'request' in current_session.context:
            request = current_session.context['request']
            app = getattr(request, "app", None)
            server_type = getattr(app.state, "server_type", "stdio")
            args = getattr(app.state, "args", [])
            command = getattr(app.state, "command", None)
            env = getattr(app.state, "env", {})
            
            # 调用重试方法
            return await McpReCallTools(
                server_type=server_type, 
                args=args, 
                command=command, 
                env=env, 
                endpoint_name=endpoint_name, 
                arguments=final_arguments
            )

    error_traceback = traceback.format_exc()
    print(f"Unexpected error calling {endpoint_name}: {e}")
    print(f"Error traceback: {error_traceback}")
    raise HTTPException(
        status_code=500,
        detail={
            "message": "Unexpected error",
            "error": str(e),
            "error_type": type(e).__name__,
            "traceback": error_traceback
        },
    )

async def McpReCallTools(
server_type: str,
args: Union[str, List[str]],
command: Optional[str],
env: Dict[str, str],
endpoint_name: str,
arguments: Dict[str, Any]
) -> Any:
"""
重新初始化MCP会话并调用工具

Args:
    server_type: 服务器类型(stdio、sse、streamablehttp)
    args: 服务器参数
    command: 命令(仅用于stdio)
    env: 环境变量(仅用于stdio)
    endpoint_name: 要调用的端点名称
    arguments: 调用参数

Returns:
    调用工具的结果
"""
result = None

if server_type == "stdio":
    server_params = StdioServerParameters(
        command=command,
        args=args,
        env={**env},
    )
    async with stdio_client(server_params) as (read_stream, write_stream):
        async with ClientSession(read_stream, write_stream) as session:
            # 初始化会话
            await session.initialize()
            # 调用工具
            result = await session.call_tool(endpoint_name, arguments=arguments)

elif server_type == "sse" and args:
    # 使用原始URL重新建立SSE连接
    url = args if isinstance(args, str) else args[0]
    print(f"正在重建SSE连接,URL: {url}")
    async with sse_client(url=url) as (read_stream, write_stream):
        async with ClientSession(read_stream, write_stream) as session:
            # 初始化会话
            await session.initialize()
            # 调用工具
            result = await session.call_tool(endpoint_name, arguments=arguments)
            
elif server_type == "streamablehttp" and args:
    # 使用原始URL重建streamablehttp连接
    url = args if isinstance(args, str) else args[0]
    print(f"正在重建StreamableHTTP连接,URL: {url}")
    async with streamablehttp_client(url) as (read_stream, write_stream, _):
        async with ClientSession(read_stream, write_stream) as session:
            # 初始化会话
            await session.initialize()
            # 调用工具
            result = await session.call_tool(endpoint_name, arguments=arguments)

if result:
    print(f"Calling endpoint: {endpoint_name}, with args: {arguments} result: {result}")
    response_data = process_tool_response(result)
    final_response = (response_data[0] if len(response_data) == 1 else response_data)
    return final_response

# 如果没有成功重新连接并获取结果,返回错误
raise HTTPException(
    status_code=500,
    detail={"message": f"Failed to reconnect and call {endpoint_name}"},
)
<!-- gh-comment-id:2909121114 --> @tamakiramimy commented on GitHub (May 26, 2025): @tjbck I've already resolved this issue. I suggest merging my changes into your branch. The main fix handles automatic reconnection when the MCP server restarts or encounters a timeout. Here’s the code: # 特殊处理,传递headers if headers: userinfo = {} if headers.get("x-user-email"): userinfo["Email"] = headers.get("x-user-email") if headers.get("x-user-id"): userinfo["Id"] = headers.get("x-user-id") if headers.get("x-user-token"): userinfo["Token"] = headers.get("x-user-token") final_arguments["user"] = userinfo print(f"Calling endpoint: {endpoint_name}, with args: {final_arguments}") try: result = await current_session.call_tool(endpoint_name, arguments=final_arguments) print(f"Calling endpoint: {endpoint_name}, with args: {final_arguments} result: {result}") if result.isError: error_message = "Unknown tool execution error" if result.content and isinstance(result.content[0], types.TextContent): error_message = result.content[0].text detail = {"message": error_message} raise HTTPException( status_code=500, detail=detail, ) response_data = process_tool_response(result) final_response = ( response_data[0] if len(response_data) == 1 else response_data ) return final_response except McpError as e: print(f"MCP Error calling {endpoint_name}: {e.error}") # 尝试重新初始化会话 print("Session terminated, 尝试重新初始化会话...") if e.error.message == 'Session terminated' and hasattr(current_session, 'context') and 'request' in current_session.context: request = current_session.context['request'] # 尝试从请求和应用状态获取连接信息 app = getattr(request, "app", None) server_type = getattr(app.state, "server_type", "stdio") args = getattr(app.state, "args", []) command = getattr(app.state, "command", None) env = getattr(app.state, "env", {}) # 调用重试方法 return await McpReCallTools( server_type=server_type, args=args, command=command, env=env, endpoint_name=endpoint_name, arguments=final_arguments ) except Exception as e: # 处理 ClosedResourceError if isinstance(e, ClosedResourceError): print(f"Connection closed error: {str(e)}") if hasattr(current_session, 'context') and 'request' in current_session.context: request = current_session.context['request'] app = getattr(request, "app", None) server_type = getattr(app.state, "server_type", "stdio") args = getattr(app.state, "args", []) command = getattr(app.state, "command", None) env = getattr(app.state, "env", {}) # 调用重试方法 return await McpReCallTools( server_type=server_type, args=args, command=command, env=env, endpoint_name=endpoint_name, arguments=final_arguments ) error_traceback = traceback.format_exc() print(f"Unexpected error calling {endpoint_name}: {e}") print(f"Error traceback: {error_traceback}") raise HTTPException( status_code=500, detail={ "message": "Unexpected error", "error": str(e), "error_type": type(e).__name__, "traceback": error_traceback }, ) async def McpReCallTools( server_type: str, args: Union[str, List[str]], command: Optional[str], env: Dict[str, str], endpoint_name: str, arguments: Dict[str, Any] ) -> Any: """ 重新初始化MCP会话并调用工具 Args: server_type: 服务器类型(stdio、sse、streamablehttp) args: 服务器参数 command: 命令(仅用于stdio) env: 环境变量(仅用于stdio) endpoint_name: 要调用的端点名称 arguments: 调用参数 Returns: 调用工具的结果 """ result = None if server_type == "stdio": server_params = StdioServerParameters( command=command, args=args, env={**env}, ) async with stdio_client(server_params) as (read_stream, write_stream): async with ClientSession(read_stream, write_stream) as session: # 初始化会话 await session.initialize() # 调用工具 result = await session.call_tool(endpoint_name, arguments=arguments) elif server_type == "sse" and args: # 使用原始URL重新建立SSE连接 url = args if isinstance(args, str) else args[0] print(f"正在重建SSE连接,URL: {url}") async with sse_client(url=url) as (read_stream, write_stream): async with ClientSession(read_stream, write_stream) as session: # 初始化会话 await session.initialize() # 调用工具 result = await session.call_tool(endpoint_name, arguments=arguments) elif server_type == "streamablehttp" and args: # 使用原始URL重建streamablehttp连接 url = args if isinstance(args, str) else args[0] print(f"正在重建StreamableHTTP连接,URL: {url}") async with streamablehttp_client(url) as (read_stream, write_stream, _): async with ClientSession(read_stream, write_stream) as session: # 初始化会话 await session.initialize() # 调用工具 result = await session.call_tool(endpoint_name, arguments=arguments) if result: print(f"Calling endpoint: {endpoint_name}, with args: {arguments} result: {result}") response_data = process_tool_response(result) final_response = (response_data[0] if len(response_data) == 1 else response_data) return final_response # 如果没有成功重新连接并获取结果,返回错误 raise HTTPException( status_code=500, detail={"message": f"Failed to reconnect and call {endpoint_name}"}, )
Author
Owner

@Anduin2017 commented on GitHub (Jun 26, 2025):

I'm having similar issue. I believe since MCP is a stateful protocol, the session may expired on remote sse server. Try rebooting mcpo may solve.

I believe the mcpo side should have some fallback machenisem that automatically request a new session if the current one was expired.

<!-- gh-comment-id:3007040578 --> @Anduin2017 commented on GitHub (Jun 26, 2025): I'm having similar issue. I believe since MCP is a stateful protocol, the session may expired on remote sse server. Try rebooting mcpo may solve. I believe the mcpo side should have some fallback machenisem that automatically request a new session if the current one was expired.
Author
Owner

@gyk6985432 commented on GitHub (Jun 28, 2025):

java也是同样的问题,但是我把mcpo的端口和java mcp的端口设置成不一样的就没问题了。但是有的是可以正常返回的,有的会报错:

ERROR:      + Exception Group Traceback (most recent call last):
  |   File "C:\Users\XXXX\AppData\Local\uv\cache\archive-v0\bw3DQx-QpBoMJ6ukSaNfb\Lib\site-packages\starlette\routing.py", line 692, in lifespan
  |     async with self.lifespan_context(app) as maybe_state:
  |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "D:\software\anaconda3\Lib\contextlib.py", line 231, in __aexit__
  |     await self.gen.athrow(value)
  |   File "C:\Users\XXXX\AppData\Local\uv\cache\archive-v0\bw3DQx-QpBoMJ6ukSaNfb\Lib\site-packages\mcpo\main.py", line 113, in lifespan
  |     async with stdio_client(server_params) as (reader, writer):
  |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "D:\software\anaconda3\Lib\contextlib.py", line 231, in __aexit__
  |     await self.gen.athrow(value)
  |   File "C:\Users\XXXX\AppData\Local\uv\cache\archive-v0\bw3DQx-QpBoMJ6ukSaNfb\Lib\site-packages\mcp\client\stdio\__init__.py", line 173, in stdio_client
  |     anyio.create_task_group() as tg,
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "C:\Users\XXXX\AppData\Local\uv\cache\archive-v0\bw3DQx-QpBoMJ6ukSaNfb\Lib\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 "C:\Users\XXXX\AppData\Local\uv\cache\archive-v0\bw3DQx-QpBoMJ6ukSaNfb\Lib\site-packages\mcp\client\stdio\__init__.py", line 136, in stdout_reader
    |     async for chunk in TextReceiveStream(
    |   File "C:\Users\XXXX\AppData\Local\uv\cache\archive-v0\bw3DQx-QpBoMJ6ukSaNfb\Lib\site-packages\anyio\abc\_streams.py", line 35, in __anext__
    |     return await self.receive()
    |            ^^^^^^^^^^^^^^^^^^^^
    |   File "C:\Users\XXXX\AppData\Local\uv\cache\archive-v0\bw3DQx-QpBoMJ6ukSaNfb\Lib\site-packages\anyio\streams\text.py", line 48, in receive
    |     decoded = self._decoder.decode(chunk)
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "<frozen codecs>", line 322, in decode
    | UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb2 in position 141: invalid start byte
    +------------------------------------
<!-- gh-comment-id:3015486598 --> @gyk6985432 commented on GitHub (Jun 28, 2025): java也是同样的问题,但是我把mcpo的端口和java mcp的端口设置成不一样的就没问题了。但是有的是可以正常返回的,有的会报错: ``` ERROR: + Exception Group Traceback (most recent call last): | File "C:\Users\XXXX\AppData\Local\uv\cache\archive-v0\bw3DQx-QpBoMJ6ukSaNfb\Lib\site-packages\starlette\routing.py", line 692, in lifespan | async with self.lifespan_context(app) as maybe_state: | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "D:\software\anaconda3\Lib\contextlib.py", line 231, in __aexit__ | await self.gen.athrow(value) | File "C:\Users\XXXX\AppData\Local\uv\cache\archive-v0\bw3DQx-QpBoMJ6ukSaNfb\Lib\site-packages\mcpo\main.py", line 113, in lifespan | async with stdio_client(server_params) as (reader, writer): | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "D:\software\anaconda3\Lib\contextlib.py", line 231, in __aexit__ | await self.gen.athrow(value) | File "C:\Users\XXXX\AppData\Local\uv\cache\archive-v0\bw3DQx-QpBoMJ6ukSaNfb\Lib\site-packages\mcp\client\stdio\__init__.py", line 173, in stdio_client | anyio.create_task_group() as tg, | ^^^^^^^^^^^^^^^^^^^^^^^^^ | File "C:\Users\XXXX\AppData\Local\uv\cache\archive-v0\bw3DQx-QpBoMJ6ukSaNfb\Lib\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 "C:\Users\XXXX\AppData\Local\uv\cache\archive-v0\bw3DQx-QpBoMJ6ukSaNfb\Lib\site-packages\mcp\client\stdio\__init__.py", line 136, in stdout_reader | async for chunk in TextReceiveStream( | File "C:\Users\XXXX\AppData\Local\uv\cache\archive-v0\bw3DQx-QpBoMJ6ukSaNfb\Lib\site-packages\anyio\abc\_streams.py", line 35, in __anext__ | return await self.receive() | ^^^^^^^^^^^^^^^^^^^^ | File "C:\Users\XXXX\AppData\Local\uv\cache\archive-v0\bw3DQx-QpBoMJ6ukSaNfb\Lib\site-packages\anyio\streams\text.py", line 48, in receive | decoded = self._decoder.decode(chunk) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "<frozen codecs>", line 322, in decode | UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb2 in position 141: invalid start byte +------------------------------------ ```
Author
Owner

@ocelotpa commented on GitHub (Jul 5, 2025):

I experience the same issue. The system can be briefly restored after restarting the mcpo container, but it fails again within half an hour. I'm using ModelScope's MCP service.
mcpo Version:v0.0.16
Open WebUI Version:v0.6.15

<!-- gh-comment-id:3037773063 --> @ocelotpa commented on GitHub (Jul 5, 2025): I experience the same issue. The system can be briefly restored after restarting the mcpo container, but it fails again within half an hour. I'm using ModelScope's MCP service. mcpo Version:v0.0.16 Open WebUI Version:v0.6.15
Author
Owner

@StevenAlexanderJohnson commented on GitHub (Aug 12, 2025):

I believe that I've experienced the same error using builder.Services.AddMcpServer().WithHttpTransport().WithToolsFromAssembly(). After some time of inactivity the MCP server would terminate the connection. MCPO would continue to try and use the old connection and would result with a "Session Terminated" error.

My solution was to disable the IdleTimeout of the HttpTransport.

builder.Services
    .AddMcpServer()
    .WithHttpTransport(options => options.IdleTimeout = Timeout.InfiniteTimeSpan)
    .WithToolsFromAssembly();

But it would be nice to have a way for MCPO to reconnect with a new connection after the session has expired to save resources. Especially if you have multiple tools using that MCPO server.

<!-- gh-comment-id:3179045504 --> @StevenAlexanderJohnson commented on GitHub (Aug 12, 2025): I believe that I've experienced the same error using `builder.Services.AddMcpServer().WithHttpTransport().WithToolsFromAssembly()`. After some time of inactivity the MCP server would terminate the connection. MCPO would continue to try and use the old connection and would result with a "Session Terminated" error. My solution was to disable the IdleTimeout of the HttpTransport. ```c# builder.Services .AddMcpServer() .WithHttpTransport(options => options.IdleTimeout = Timeout.InfiniteTimeSpan) .WithToolsFromAssembly(); ``` But it would be nice to have a way for MCPO to reconnect with a new connection after the session has expired to save resources. Especially if you have multiple tools using that MCPO server.
Author
Owner

@Guigxs commented on GitHub (Aug 23, 2025):

Seems to have the same issue proxying codemcp (sse server). If I don't keep alive manually I have a anyio.ClosedResourceError after a few sec.

<!-- gh-comment-id:3216844469 --> @Guigxs commented on GitHub (Aug 23, 2025): Seems to have the same issue proxying codemcp (sse server). If I don't keep alive manually I have a anyio.ClosedResourceError after a few sec.
Author
Owner

@schaveyt commented on GitHub (Sep 5, 2025):

@StevenAlexanderJohnson thanks for sharing that workaround. I have been banging my head on this.

Unfortunately, that workaround does not seem to be working for me 🙃

Make me want to start a Blazor alternative based on the new ASP.NET Blazor AI Chat Template in order to support native MCP over SSE and Streaming HTTP 🤷

<!-- gh-comment-id:3258811985 --> @schaveyt commented on GitHub (Sep 5, 2025): @StevenAlexanderJohnson thanks for sharing that workaround. I have been banging my head on this. Unfortunately, that workaround does not seem to be working for me 🙃 Make me want to start a Blazor alternative based on the new [ASP.NET Blazor AI Chat Template](https://learn.microsoft.com/en-us/dotnet/ai/quickstarts/ai-templates?tabs=visual-studio%2Cconfigure-visual-studio%2Cconfigure-visual-studio-aspire&pivots=openai) in order to support native MCP over SSE and Streaming HTTP 🤷
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
open-webui/mcpo#67
No description provided.