-
Notifications
You must be signed in to change notification settings - Fork 1.4k
enable http headers in sse in the context #216
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
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the general idea to give access to headers in the context is great. I think we should focus on exposing the headers from the transport protocol (HTTP Headers in HTTP+SSE transport and no headers in STDIO) inside the context.
src/mcp/types.py
Outdated
@@ -118,6 +118,7 @@ class JSONRPCRequest(Request): | |||
jsonrpc: Literal["2.0"] | |||
id: RequestId | |||
params: dict[str, Any] | None = None | |||
headers: dict[str, str] | None = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we would want to add headers to the types. The types are a direct translation of the schema.ts in the specification. Adding headers here would not be compatible with JSON-RPC in it's most used form.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dsp-ant Thank you! That's fair. I was trying to initially do the change such that only the sse
file is the one with changes, but here's my problem, and a suggestion for an approach to fix it. Please correct me if my understanding of the code is not complete.
- The HTTP request is only available in transport layer (
sse.py
) - The only way to pass stuff down from the transport layer to the server implementation is going to be through the streams, which have
JSONRPCMessage
type - We don't want to extend/change the
JSONRPCMessage
type because it is part of the schema (and honestly it makes sense, since it only applies to certain transports)
To solve this, here are my other 2 suggestions:
- Inject the metadata (one of which is optional headers) in the
params
of theJSONRPCMessage
- Change the streams so that they now hold a new type (a container type with the
JSONRPCMessage + meta
), where themeta
can be anything that is transport-specific?
Let me know what you think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dsp-ant hey, any chance you have given this some thought and have any guidance for the approach? I would love to update the PR
src/mcp/server/lowlevel/server.py
Outdated
headers = {} | ||
try: | ||
# TODO: This try/catch and ignoring the type is wrong. | ||
headers = message.request.root.headers # type: ignore | ||
except Exception: | ||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume we most likely want headers to be extracted from the transport protocol itself. This means providing ways within a session context to access to original request headers for the HTTP Post in the case of SSE. For STDIO this would be empty. If we ever come to the conclusion that headers are absolutely necessary, I think we likely would move to a STDIO transport description that is akin to the header-based JSON-RPC that LSP is doing, which is of the form:
Some-Header: Some-Value
Some-Header: Some-Value
{"jsonrpc": "2.0", ...}
Thanks for doing that. I really like the idea and just working through an alternative option. Will have something soon. |
Adding my input here in case anyone has the same use case as me. I am building an MCP Client. I need to be able to set different headers on a per-request basis. In my use-case, it's to differentiate users interacting with my client, among other things. Right now, you can only set headers when creating a new ClientSession, but I want to maintain semi-persistent ClientSession(s). This PR seems to address this in it's current state, while also making it easier to consume headers on the Server side. I understand there is some discussion on the best way to do this still, but the need is there for all us MCP Client creators. |
@dsp-ant Any update on this ? It will be really useful if this can be achieved out of the box. |
support this pr ,and it will be useful in sse/streamhttp server,like env config in stdio ,i think http metadata is also necessary in sse mcp ,otherwise , the client cannot determine custom config expect request param ,it not suitable , of course ,it should be declared clearly in docs that header metadata just available in sse/streamhttp mcp server! |
I don't think this PR is a good solution.since context was implemented by contextvar,if some one wants to fetch the header of a http request.he can do it in a similar way. |
Motivation and Context
In the server, it seems like a common case to need to access the raw HTTP headers (think a reverse proxy header, or some custom analytics headers).
Example use case, where we have two services that can possibly talk to the MCP server. The servers identify themselves through the
X-Client
HTTP header.How Has This Been Tested?
They were just tested manually locally
Breaking Changes
No
Types of changes
Checklist
Additional context