fix: disable InMemoryMcpTaskStore to avoid ObjectDisposedException (upstream SDK bug)#411
Conversation
MCP SDK v1.1.0's ExecuteToolAsTaskAsync disposes the request-scoped IServiceProvider before the background task resolves services, causing ObjectDisposedException on every tool call when a task store is registered. Comment out InMemoryMcpTaskStore registration until the upstream SDK fixes the DI scope lifetime issue. Upstream: modelcontextprotocol/csharp-sdk#1430 TaskSupport = Optional is kept on dotnet_project so the attribute is ready to activate when the store is re-enabled.
There was a problem hiding this comment.
Pull request overview
Disables MCP Task support in the .NET MCP server as a workaround for an upstream MCP SDK v1.1.0 DI scope disposal bug that triggers ObjectDisposedException during tool execution.
Changes:
- Commented out
InMemoryMcpTaskStoreregistration to force synchronous tool execution. - Updated
dotnet_server_capabilitiesto reportsupports.asyncTasks = false. - Adjusted conformance/capabilities tests to validate graceful degradation (no tasks capability advertised) and updated assertions.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| DotNetMcp/Program.cs | Disables task store registration with TODO + upstream issue reference. |
| DotNetMcp/Tools/Cli/DotNetCliTools.Misc.cs | Reports AsyncTasks = false in server capabilities output. |
| DotNetMcp.Tests/Server/McpConformanceTests.cs | Replaces task lifecycle tests with degradation/synchronous execution checks. |
| DotNetMcp.Tests/Server/ServerCapabilitiesTests.cs | Updates assertions to expect asyncTasks to be false. |
You can also share your feedback on Copilot code review. Take the survey.
| Telemetry = true, // SDK v0.6+ supports request duration logging and OpenTelemetry semantic conventions | ||
| Metrics = true, // In-memory per-tool metrics via MCP message filter (dotnet_server_metrics tool) | ||
| AsyncTasks = true, // MCP Task support enabled: long-running operations (build, test, publish) can run as async tasks | ||
| AsyncTasks = false, // Disabled: MCP SDK DI scope bug (https://github.com/modelcontextprotocol/csharp-sdk/issues/1430) |
| // Assert - the tool attribute declares TaskSupport = Optional so it's ready when | ||
| // task support is enabled via Features:EnableTaskSupport. Without a task store | ||
| // registered, the SDK runs it synchronously inline (graceful degradation). |
…ding comment Co-authored-by: jongalloway <68539+jongalloway@users.noreply.github.com>
|
Addressed both review comments in commit
All 55 conformance + capabilities tests continue to pass. |
Problem
MCP SDK v1.1.0's
ExecuteToolAsTaskAsyncdisposes the request-scopedIServiceProviderbefore the background task resolves services, causingObjectDisposedExceptionon every tool call whenInMemoryMcpTaskStoreis registered — not justdotnet_project, but alsodotnet_solutionand any other tool the client invokes.Root Cause
This is an upstream SDK bug: modelcontextprotocol/csharp-sdk#1430
Fix
Comment out
InMemoryMcpTaskStoreregistration. Without a task store, the SDK runs all tools synchronously inline — reliable and compatible with all clients.Program.cs: commented-out registration with TODO and upstream linkDotNetCliTools.Misc.cs:AsyncTasks = falsein ServerCapabilitiesMcpConformanceTests.cs: task lifecycle tests replaced with graceful degradation testsServerCapabilitiesTests.cs: updated assertionsTaskSupport = ToolTaskSupport.Optionalis kept ondotnet_projectso it's ready to activate when the upstream fix ships.Tracking issue: #410
Testing
55/55 conformance + capabilities tests pass.