Version-Based Tool Registration for MCP Server
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
- Issue type
- Feature
- Clarity
- Needs clarification
- Activity status
- Quiet
- Tech stack
- csharp
- Domain
- api, backend-api-design
Research direction
Start by reading the existing WithTools() and assembly-wide tool registration APIs, then inspect MapMcp and its HTTP transport options. The issue proposes namespace-based discovery and version-aware endpoint constraints, but the supported API shape and implementation scope still need to be decided; done would require an agreed design that enables selective, versioned tool registration without duplicated server configuration.
Written by the indexing model from the issue text.
Description
Is your feature request related to a problem? Please describe.
When building MCP servers in .NET, especially HTTP-based servers with versioned endpoints, there is currently no first-class support for tool versioning and selective tool registration.
All tools are typically registered globally (e.g. via WithTools() or assembly-wide scanning), which makes it difficult to:
- Expose multiple API versions (/v1, /v2, …) in parallel
- Maintain backward compatibility while evolving tools
- Avoid duplicating MCP server registrations per version
- Keep tool discovery explicit and predictable in larger codebases
This becomes especially painful in real-world services where:
- Tools are organized by namespace (e.g. MyNamespace.Mcp.v1, MyNamespace.Mcp.v2)
- Different MCP endpoints should only expose a subset of tools
- Versioning logic must be reimplemented manually outside the SDK
Describe the solution you'd like
I propose adding official support for namespace- and version-based tool registration, enabling clean MCP API versioning.
- Namespace-based tool discovery helper
A built-in extension similar to the following:
public static class McpVersioningExtensions
{
public static IMcpServerBuilder WithToolsFromNamespaces(
this IMcpServerBuilder builder,
Assembly assembly,
params string[] namespaceNames)
{
IEnumerable<Type> toolTypes =
from t in assembly.GetTypes()
where t.GetCustomAttribute<McpServerToolTypeAttribute>() is not null
where t.Namespace != null
&& namespaceNames.Any(ns =>
t.Namespace.StartsWith(ns, StringComparison.Ordinal))
select t;
return builder.WithTools(toolTypes);
}
}
Usage:
builder.Services.AddMcpServer(options =>
{
options.ServerInfo.Version = "1.0.0";
})
.WithHttpTransport()
.WithToolsFromNamespaces(
typeof(Program).Assembly,
"MyNamespace.Mcp.v1");
This allows:
- Clear separation of tools by namespace
- Explicit control over which tools belong to which API version
- No reflection boilerplate in application code
- Version-aware endpoint mapping
Combine tool versioning with HTTP endpoint constraints:
app.MapMcp("/v1", options =>
{
options.RequiredServerVersion = "1.0.0";
});
app.MapMcp("/v2", options =>
{
options.RequiredServerVersion = "2.0.0";
});
This enables:
- Parallel MCP versions in the same service
- Clean routing and contract enforcement
- Safe evolution of tools without breaking clients
Describe alternatives you've considered
- Multiple MCP servers per version
→ Leads to duplicated configuration, duplicated transports, and higher maintenance cost. - Manual reflection and filtering outside the SDK
→ Works, but reimplements logic that many users will need and reduces consistency across projects. - Tool-level version attributes only
→ Still requires custom registration logic and does not integrate naturally with HTTP endpoint versioning.
Additional context
This feature would be particularly valuable for:
- Enterprise services with long-lived clients
- Public MCP endpoints with semantic versioning
- Teams migrating from REST/gRPC APIs to MCP while preserving version contracts
Providing an official abstraction for namespace- or version-based tool registration would:
- Reduce boilerplate
- Encourage best practices
- Make the SDK significantly more production-ready for real-world API versioning scenarios
- Dominant language
- C#
- Stars
- 4.5k
- Forks
- 814
- Avg merge
- 9d 19h
- Merged PRs (30d)
- 4
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.
More from modelcontextprotocol/csharp-sdk
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
modelcontextprotocol/csharp-sdk#1867 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
modelcontextprotocol/csharp-sdk#1840 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
modelcontextprotocol/csharp-sdk#1836 ·
-
enhancement needs confirmation
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
modelcontextprotocol/csharp-sdk#678 · 1 comment ·
-
enhancement needs confirmation P3 ready for work
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
modelcontextprotocol/csharp-sdk#515 · 6 comments · 3 reactions ·
All issues in modelcontextprotocol/csharp-sdk
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
bug needs response
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Adyen/adyen-dotnet-api-library#1869 ·
-
Status: Needs Triage Type: Bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
bug effort:S P3
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
nightscout/nocturne#1602 ·