You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Sometimes I get ObjectDisposedException from DI services like the IServiceProvider itself or DbContext
inside the tool call handler.
It looks like OpenAI closes the connection for too-long-running tools,
and instead of canceling the CancellationToken, the service scope gets disposed.
Or the scope gets disposed of without waiting for the handler to cancel cleanly.
To Reproduce
Steps to reproduce the behavior:
Setup: Stateless, Http Transport
Call a long-running tool
Close the connection to simulate a read-timeout.
Note
I use it with OpenAI
OpenAI requires statelessness and closes the connection after some timeout.
services.AddMcpServer(options =>options.ScopeRequests=true).WithHttpTransport(options =>{options.Stateless=true;}).AddAuthorizationFilters().WithToolsFromAssemblyFixed(toolAssembly).AddCallToolFilter(next =>(context,token)=>ToolCallErrorHandler(next,context,token));// ...app.MapMcp("/mcp").RequireAuthorization("mcp");staticasyncValueTask<CallToolResult>ToolCallErrorHandler(McpRequestHandler<CallToolRequestParams,CallToolResult>next,RequestContext<CallToolRequestParams>context,CancellationTokencancellationToken){try{returnawaitnext(context,cancellationToken);}catch(Exceptionex){if(xis not OperationCanceledException){// Error here inside `GetRequiredService` - the `ex` error is also an ObjectDisposedException with origin in DbContext.SaveChanges()context.Services!.GetRequiredService<ILogger<McpFeatureAttribute>>().LogCritical(ex,"MCP Error {tool}: {message}",context.Params?.Name,ex.Message);}returnnewCallToolResult{Content=[newTextContentBlock{Text=$"Error: {ex.Message}"}],IsError=true};}}
Expected behavior
I expect the handler to either complete or cancel through CancellationToken before the service scope is disposed.
Logs
ERRORModelContextProtocol.Server.McpServer "{ToolName}" threw anunhandledexception.System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'IServiceProvider'.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ThrowHelper.ThrowObjectDisposedException()
at ModelContextProtocol.Server.RequestServiceProvider`1.GetService(TypeserviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProviderprovider)
at Nomos.Web.Features.Mcp.Abstructions.McpFeatureInstaller.ToolCallErrorHandler(McpRequestHandler`2next, RequestContext`1context,CancellationTokencancellationToken)in/src/Nomos.Web/Features/Mcp/Abstructions/McpFeatureInstaller.cs:line 42
at ModelContextProtocol.AspNetCore.AuthorizationFilterSetup.<>c__DisplayClass7_0.<<ConfigureCallToolFilter>b__1>d.MoveNext()---Endof stack trace from previous location ---atModelContextProtocol.Server.McpServerImpl.<>c__DisplayClass51_2.<<ConfigureTools>b__5>d.MoveNext()
Additional context
Add any other context about the problem here.
Describe the bug
Sometimes I get
ObjectDisposedExceptionfrom DI services like theIServiceProvideritself orDbContextinside the tool call handler.
It looks like OpenAI closes the connection for too-long-running tools,
and instead of canceling the
CancellationToken, the service scope gets disposed.Or the scope gets disposed of without waiting for the handler to cancel cleanly.
To Reproduce
Steps to reproduce the behavior:
Note
I use it with OpenAI
OpenAI requires statelessness and closes the connection after some timeout.
Expected behavior
I expect the handler to either complete or cancel through
CancellationTokenbefore the service scope is disposed.Logs
Additional context
Add any other context about the problem here.