Skip to content

Fix Extensions not being copied to ServerCapabilities during initialization#1399

Merged
stephentoub merged 6 commits intomainfrom
copilot/fix-deserialization-issue
Feb 28, 2026
Merged

Fix Extensions not being copied to ServerCapabilities during initialization#1399
stephentoub merged 6 commits intomainfrom
copilot/fix-deserialization-issue

Conversation

Copy link
Contributor

Copilot AI commented Feb 27, 2026

  • Fix ConfigureExperimental in McpServerImpl.cs to copy Extensions from options to ServerCapabilities
  • Use public Extensions property instead of internal ExtensionsCore
  • Remove redundant #pragma warning disable MCPEXP001 in test (already suppressed in tests/Directory.Build.props)
  • Rename ConfigureExperimentalConfigureExperimentalAndExtensions
  • Remove redundant = new() from ServerCapabilities property (already set in ctor)
  • Verify no equivalent issue on client side
  • Add test verifying Extensions in initialize response
  • Add test verifying Experimental in initialize response
  • Add reflection-based test to catch future missing capability copies
  • Build and tests passing
Original prompt

This section details on the original issue you should resolve

<issue_title>Extensions are not being deserialized into server capabilities</issue_title>
<issue_description>Describe the bug
When setting extensions in server capabilities, they are not being included in the initialize message.

To Reproduce
Steps to reproduce the behavior:

  1. Start up a very minimal asp.net server with the following (add an extension):
using System.Text.Json.Nodes;
using ModelContextProtocol.Protocol;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
builder
    .Services.AddMcpServer(options =>
    {
        options.Capabilities ??= new ServerCapabilities();

#pragma warning disable MCPEXP001
        options.Capabilities.Extensions ??= new Dictionary<string, object>();
        options.Capabilities.Extensions.Add("io.myext", new JsonObject { ["required"] = true });
#pragma warning restore MCPEXP001
    })
    .WithHttpTransport();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
}

app.UseHttpsRedirection();
app.MapMcp("/mcp");
app.Run();
  1. Use postman, send a json request. Observe extensions are not included:
Image

Expected behavior
The server capabilities should have the extensions property, which should include io.myext as configured.

Logs

Additional context

</issue_description>

<agent_instructions>It looks like in

ServerCapabilities = new();
ConfigureInitialize(options);
ConfigureTools(options);
ConfigurePrompts(options);
ConfigureResources(options);
ConfigureTasks(options);
ConfigureLogging(options);
ConfigureCompletion(options);
ConfigureExperimental(options);
we're failing to copy Experimental over to the server's used options from the input options. Please fix, check if there's an equivalent issue on the client side (and fix it if there is), and ensure this scenario is tested. Also, see if there's a good way to add a test that will help us catch such issues in the future when we add additional capabilities and forget to copy them; maybe something using reflection (but only public reflection if that's the best route, not private reflection).</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits February 27, 2026 21:45
In McpServerImpl.ConfigureExperimental, the Extensions property from
the options was not being copied to the server's ServerCapabilities.
This caused Extensions to be missing from the initialize response.

Also added:
- Test for Extensions in initialize response
- Test for Experimental in initialize response
- Reflection-based test to catch future missing capability copies

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix deserialization of extensions into server capabilities Fix Extensions not being copied to ServerCapabilities during initialization Feb 27, 2026
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
…ory.Build.props)

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
@stephentoub stephentoub marked this pull request as ready for review February 27, 2026 22:19
@stephentoub stephentoub requested a review from halter73 February 27, 2026 22:19
…d remove redundant = new() initializer

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
@stephentoub stephentoub merged commit 94aa695 into main Feb 28, 2026
10 checks passed
@stephentoub stephentoub deleted the copilot/fix-deserialization-issue branch February 28, 2026 00:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extensions are not being deserialized into server capabilities

3 participants