modelcontextprotocol / modelcontextprotocol/csharp-sdk
In the StreamableHttp mode MCP server, Scoped type dependencies are not properly injected into classes marked with [McpServerToolType].
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 4.5k
- Forks
- 814
- Avg merge
- 9d 19h
- Merged PRs (30d)
- 4
Description
Describe the bug
I'm trying to access RouteValues from HttpContext by adding a Middleware that stores them in an Argument class, registered as Scoped in the DI container. However, when invoking the MCP tool method, I can't retrieve the correct Argument instance in the TestTools class. The logs indicate that the Argument instance differs between the Middleware and the TestTools.
// Program.cs
var builder = WebApplication.CreateBuilder(args);
// Add McpServer services
builder.Services.AddMcpServer()
.WithHttpTransport()
.WithToolsFromAssembly();
builder.Services.AddScoped<Arguements>();
var app = builder.Build();
app.UseRouting();
app.Use((context, next) =>
{
// The Middleware to capture route values and set them in Arguements
var arguements = context.RequestServices.GetRequiredService<Arguements>();
arguements.SetRouteValue(context.Request.RouteValues["value"]?.ToString());
return next();
});
app.Map("/", (Arguements arguements) => arguements.Guid.ToString());
app.MapMcp("mcp/{value}");
app.Run();
[McpServerToolType]
public class TestTools
{
private readonly Arguements arguements;
public TestTools(Arguements arguements, ILogger<TestTools> logger)
{
this.arguements = arguements;
logger.LogInformation($"TestTools created.");
}
[McpServerTool]
[Description("Test")]
public Task<string> TestAsync(CancellationToken cancellationToken = default)
{
return Task.FromResult($"RouteValue: {arguements.RouteValue}");
}
}
public class Arguements
{
private readonly ILogger<Arguements> _logger;
public Guid Guid { get; private set; }
public string? RouteValue { get; private set; }
public Arguements(ILogger<Arguements> logger)
{
this._logger = logger;
Guid = Guid.NewGuid();
logger.LogInformation($"Arguements created ID: {Guid}");
}
public void SetRouteValue(string? value)
{
RouteValue = value;
_logger.LogInformation($"RouteValue set to: {RouteValue}");
}
}
To Reproduce
Steps to reproduce the behavior:
- Start the ASP.NET Core project
- Use the MCP debug tool - MCP Inspector, connect to
http://localhost:xxxx/mcp/abcand call theTesttool - The return value is
RouteValue:
Expected behavior
The return value should be RouteValue: abc
Logs
info: CS.API.Arguements[0]
Arguements created ID: f7616e71-1756-43c1-aed6-5f085f817e99
info: CS.API.Arguements[0]
RouteValue set to: abc
info: ModelContextProtocol.Server.McpServer[570385771]
Server (CS.API 1.0.0.0), Client (mcp-inspector 0.14.3) method 'tools/call' request handler called.
info: CS.API.Arguements[0]
Arguements created ID: 6c51f94c-51e0-4ad9-ad44-cdbe722b1e64
info: CS.API.TestTools[0]
TestTools created.
info: ModelContextProtocol.Server.McpServer[1867955179]
Server (CS.API 1.0.0.0), Client (mcp-inspector 0.14.3) method 'tools/call' request handler completed.
Additional context
The log details show that the Arguments are created and RouteValues are correctly assigned in the Middleware. However, when resolving TestTools, a new Argument instance is created. It seems TestTool is resolved in a different scope from the HTTP request pipeline, which is confusing.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue with the Streamable HTTP setup using WithHttpTransport, WithToolsFromAssembly, MapMcp, and MCP Inspector. Trace how the scoped Arguements instance is resolved in the HTTP pipeline versus TestTools; done means both use the same instance and calling Test returns the route value, such as abc.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100