Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SseClientTransport AdditionalHeaders not work #185

Open
gamma-chen-avepoint opened this issue Apr 2, 2025 · 9 comments
Open

SseClientTransport AdditionalHeaders not work #185

gamma-chen-avepoint opened this issue Apr 2, 2025 · 9 comments
Assignees
Labels
bug Something isn't working

Comments

@gamma-chen-avepoint
Copy link

Describe the bug
By checking code, look like when use the sse Transport, the header should pass like this

TransportOptions = new Dictionary<string, string>
{
    ["header.ACCESS_TOKEN"] = ""
}

then the header key and value pass to a property named AdditionalHeaders. But this property not be used when send request.

@gamma-chen-avepoint gamma-chen-avepoint added the bug Something isn't working label Apr 2, 2025
@essenbee2
Copy link

essenbee2 commented Apr 2, 2025

I was just about to add the same issue! I am trying to pass an API Key to an ASP.NET Core SSE server, but the additional headers do not show up on the server when I examine the HTTP headers in my middleware.

@stephentoub
Copy link
Contributor

cc: @halter73

@fxvarga
Copy link

fxvarga commented Apr 3, 2025

I am facing the same issue with this looks like the SseClientSessionTransport is making the call but only sends in text/event-stream mediatype header. I'm assuming this is where we can map the additional options?

request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/event-stream"));

@halter73
Copy link
Contributor

halter73 commented Apr 4, 2025

It looks like nothing is currently reading SseClientTransportOptions.AdditionalHeaders. I'll fix that. In the meantime, you should be able to work around this using this SseClientTransport constructor that takes a custom HttpClient you can configure DefaultRequestHeaders on.

@halter73 halter73 self-assigned this Apr 4, 2025
@taimurlak
Copy link

Btw guys, anyone know how can we read the header in mcp server Tool:

Image

let's suppose this is the code of my tool, how can i read the token and validate, or what is the way to authenticate the user in SSE.

@halter73
Copy link
Contributor

halter73 commented Apr 7, 2025

@taimurlak This is something I'm actively looking into. As of a few minutes ago (see #225), I added a Func<HttpContext, McpServerOptions, CancellationToken, Task>? configureOptionsAsync = null parameter to MapMcp. This gives you the HttpContext from the initial request to the /sse endpoint, and you can read headers there to configure tools if you need to.

This is far from a complete solution though. It doesn't give you the headers from the JSON-RPC request to invoke the tool (although this often doesn't matter), and it isn't easy to get at from a [McpServerToolType], so this is definitely an area we're looking to improve on.

It'd be nice if HttpContextAccessor worked, but that doesn't play super well with reading from a Channel.

@taimurlak
Copy link

@halter73 Thanks you so much for quick response. can you please show me the example code so i can understand it well.

@halter73
Copy link
Contributor

I just confirmed that with the latest preview7 package, IHttpContextAccessor works. The ExecutionContext flows from the /sse request to the call to McpServer.RunAsync into the McpSession.ProcessMessagesAsync loop that ultimately calls the tool. This is despite the fact that the incoming JSON-RPC messages are coming in on a separate messages endpoint.

using ModelContextProtocol.Server;
using System.ComponentModel;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpContextAccessor();
builder.Services
    .AddMcpServer()
    .WithToolsFromAssembly();

var app = builder.Build();

app.MapMcp();

app.Run("http://localhost:3001");

[McpServerToolType]
public class EchoTool(IHttpContextAccessor contextAccessor)
{
    [McpServerTool, Description("Echoes the message back to the client.")]
    public string Echo(string message)
        => $"hello {message}, {contextAccessor.HttpContext?.Request.Path ?? "(no HttpContext)"}";
}

⚠️ WARNING ⚠️

Be careful how you use this. MapMcp() is not in a state where you should be accepting untrusted connections. For example, it will not verify that the incoming /message requests come from the same HttpContext.User as the initial /sse request the IHttpContextAccessor gives you access to.

Screenshot of tool invoked by GitHub Copilot in VS Code using IHttpContextAccessor

@taimurlak
Copy link

@halter73 Thanks alot dude 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants