Repository navigation
Description
Describe the bug
The Streamable HTTP transport sends POST requests with Content-Type: application/json; charset=utf-8. Per IANA's registration for application/json and RFC 8259 §11, no charset parameter is defined for application/json — JSON is always Unicode and the parameter is meaningless.
GitHub Copilot's MCP endpoint enforces this strictly and rejects every request from the SDK with HTTP 415:
HTTP/1.1 415 Unsupported Media Type
Content-Type must be 'application/json'
This makes it impossible to connect to GitHub's MCP server (and any similarly strict server) without injecting a custom HttpClient that strips the charset parameter.
To Reproduce
Requires a GitHub Copilot–enabled PAT (any scope that can call https://api.githubcopilot.com/mcp — same token used in MCP Inspector).
// dotnet add package ModelContextProtocol --version 1.2.0
using ModelContextProtocol.Client;
var pat = Environment.GetEnvironmentVariable("GITHUB_COPILOT_PAT")
?? throw new InvalidOperationException("Set GITHUB_COPILOT_PAT");
var options = new HttpClientTransportOptions
{
Endpoint = new Uri("https://api.githubcopilot.com/mcp"),
TransportMode = HttpTransportMode.StreamableHttp,
AdditionalHeaders = new Dictionary<string, string>
{
["Authorization"] = $"Bearer {pat}",
},
};
var transport = new HttpClientTransport(options);
await using var client = await McpClient.CreateAsync(transport);
// Throws: 415 Unsupported Media Type — Content-Type must be 'application/json'The same PAT against the same endpoint works in MCP Inspector and with curl, confirming the issue is the SDK's Content-Type header, not the credential or the server.
curl showing the server accepts a bare application/json:
curl -i -X POST https://api.githubcopilot.com/mcp \
-H "Authorization: Bearer $GITHUB_COPILOT_PAT" \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"repro","version":"1.0"}}}'
# 200 OK with an SSE response
# Same request, but with charset=utf-8:
curl -i -X POST https://api.githubcopilot.com/mcp \
-H "Authorization: Bearer $GITHUB_COPILOT_PAT" \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json; charset=utf-8" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"repro","version":"1.0"}}}'
# HTTP/1.1 415 Unsupported Media Type
# Content-Type must be 'application/json'Expected behavior
The SDK should send Content-Type: application/json (no charset parameter) for JSON-RPC POST bodies, matching the IANA registration for application/json.
Actual behavior
System.Net.Http.HttpRequestException: Response status code does not indicate success: 415 (Unsupported Media Type). Response body: Content-Type must be 'application/json'
at ModelContextProtocol.HttpResponseMessageExtensions.EnsureSuccessStatusCodeWithResponseBodyAsync(...)
at ModelContextProtocol.Client.StreamableHttpClientSessionTransport.SendMessageAsync(...)
at ModelContextProtocol.McpSessionHandler.SendRequestAsync(...)
...
Workaround
Inject a custom HttpClient (via the HttpClientTransport(options, httpClient, loggerFactory, ownsHttpClient) constructor) wrapped with a DelegatingHandler that strips the charset parameter before each request:
internal sealed class StrictJsonContentTypeHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken ct)
{
var contentType = request.Content?.Headers?.ContentType;
if (contentType is not null &&
string.Equals(contentType.MediaType, "application/json", StringComparison.OrdinalIgnoreCase) &&
!string.IsNullOrEmpty(contentType.CharSet))
{
contentType.CharSet = null;
}
return base.SendAsync(request, ct);
}
}This works but every consumer hitting a strict server has to discover and re-implement it.
Environment
ModelContextProtocol1.2.0- .NET 8.0
- Windows 11 (also reproduces on Linux)
Additional context
This likely originates from System.Net.Http.Json / JsonContent.Create, which defaults to application/json; charset=utf-8. The fix is either to set Content.Headers.ContentType.CharSet = null after constructing the JsonContent, or to construct the StringContent/ByteArrayContent manually with the bare media type.
Activity
jayaraman-venkatesan commentedon Apr 21, 2026
My triage -
As mentioned the mcp client is adding charset here before making a call -
csharp-sdk/src/ModelContextProtocol.Core/Client/McpHttpClient.cs
Line 27 in 69a7fd3
The spec is silent on Content-Type for the client, it neither requires it nor defines what value it should have
That said, other SDKs like some mentioned below are following this RFC by not including explicit charset :
except Java sdk which adds charset - LINK
This was a recent update - Issue
I have opened a draft PR for this.
If there are plans to address this, please let me know so I can convert my draft PR as open to review accordingly.
@halter73 / @mikekistler / @jeffhandley
mikekistler commentedon Apr 22, 2026
The linked IANA Registration for application/json says:
Does this mean that "compliant recipients" ignore the "charset" parameter, and any recepient that errors because of the "charset" parameter is not "compliant"?