Skip to content

Conversation

adityamj
Copy link
Contributor

@adityamj adityamj commented Jul 9, 2025

Description

HTTP header passthrough to Request struct.
This is useful for situations where out-of band information is passed by API Gateways and needs to be further passed on to downstream APIs.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • MCP spec compatibility implementation
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Code refactoring (no functional changes)
  • Performance improvement
  • Tests only (no functional changes)
  • Other (please describe):

Checklist

  • My code follows the code style of this project
  • I have performed a self-review of my own code
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the documentation accordingly

Summary by CodeRabbit

  • New Features

    • HTTP request headers are now automatically included in all MCP request objects, making them accessible to handlers for authentication, tracing, and other purposes across both HTTP and SSE transports.
  • Documentation

    • Updated documentation for HTTP and SSE transports to describe how handlers can access HTTP request headers directly from request objects, with usage examples provided.
  • Tests

    • Added new tests to verify correct propagation and availability of HTTP headers in tool requests for both HTTP and SSE transports.

Copy link
Contributor

coderabbitai bot commented Jul 9, 2025

"""

Walkthrough

This change introduces an unexported Header field of type http.Header to all MCP request structs, ensuring HTTP headers are accessible within handlers for both SSE and HTTP transports. The server code is updated to extract and propagate headers from incoming requests via context. Documentation and tests are added to verify and demonstrate header access.

Changes

Files/Paths Change Summary
mcp/prompts.go, mcp/tools.go, mcp/types.go Added unexported Header http.Header (with json:"-") field to MCP request structs to carry HTTP headers internally.
server/ctx.go Introduced package-private context key for storing headers in context.
server/request_handler.go, server/sse.go, server/streamable_http.go Extracted HTTP headers from incoming requests, injected them into context, and assigned them to request structs in handlers.
server/sse_test.go, server/streamable_http_test.go Added tests verifying correct propagation and access of HTTP headers in MCP tool request handlers.
www/docs/pages/transports/http.mdx, www/docs/pages/transports/sse.mdx Added documentation and examples showing how to access HTTP headers from MCP request objects in handlers for both transports.

Possibly related issues

Suggested labels

type: enhancement, area: mcp spec

Suggested reviewers

  • ezynda3
  • dugenkui03
    """

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e0ad467 and 55c51e9.

📒 Files selected for processing (2)
  • server/sse.go (1 hunks)
  • server/streamable_http.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • server/streamable_http.go
  • server/sse.go
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
mcp/tools.go (1)

50-52: Consider simplifying the comment.

The Header field implementation is correct, but the multi-line comment could be more concise for consistency with other request structs.

-	// Header must be read from request
-	// Prevent Header being passed as request payload
-	Header http.Header    `json:"-"`
+	Header http.Header `json:"-"` // HTTP headers from the original request
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2d479bb and 29d9dee.

⛔ Files ignored due to path filters (1)
  • server/internal/gen/request_handler.go.tmpl is excluded by !**/gen/**
📒 Files selected for processing (11)
  • mcp/prompts.go (2 hunks)
  • mcp/tools.go (3 hunks)
  • mcp/types.go (11 hunks)
  • server/ctx.go (1 hunks)
  • server/request_handler.go (12 hunks)
  • server/sse.go (1 hunks)
  • server/sse_test.go (2 hunks)
  • server/streamable_http.go (1 hunks)
  • server/streamable_http_test.go (1 hunks)
  • www/docs/pages/transports/http.mdx (1 hunks)
  • www/docs/pages/transports/sse.mdx (2 hunks)
🧰 Additional context used
🧠 Learnings (10)
📓 Common learnings
Learnt from: ezynda3
PR: mark3labs/mcp-go#461
File: server/sampling.go:22-26
Timestamp: 2025-06-30T07:13:17.052Z
Learning: In the mark3labs/mcp-go project, the MCPServer.capabilities field is a struct value (serverCapabilities), not a pointer, so it cannot be nil and doesn't require nil checking. Only pointer fields within the capabilities struct should be checked for nil.
Learnt from: leavez
PR: mark3labs/mcp-go#114
File: client/transport/sse.go:137-179
Timestamp: 2025-04-06T10:07:06.685Z
Learning: The SSE client implementation in the MCP-Go project uses a 30-second timeout for reading SSE events to match the behavior of the original implementation before the transport layer refactoring.
mcp/prompts.go (2)
Learnt from: lariel-fernandes
PR: mark3labs/mcp-go#428
File: www/docs/pages/servers/prompts.mdx:218-234
Timestamp: 2025-06-20T20:39:51.870Z
Learning: In the mcp-go library, the GetPromptParams.Arguments field is of type map[string]string, not map[string]interface{}, so direct string access without type assertions is safe and correct.
Learnt from: ezynda3
PR: mark3labs/mcp-go#461
File: server/sampling.go:22-26
Timestamp: 2025-06-30T07:13:17.052Z
Learning: In the mark3labs/mcp-go project, the MCPServer.capabilities field is a struct value (serverCapabilities), not a pointer, so it cannot be nil and doesn't require nil checking. Only pointer fields within the capabilities struct should be checked for nil.
server/streamable_http.go (1)
Learnt from: ezynda3
PR: mark3labs/mcp-go#461
File: server/sampling.go:22-26
Timestamp: 2025-06-30T07:13:17.052Z
Learning: In the mark3labs/mcp-go project, the MCPServer.capabilities field is a struct value (serverCapabilities), not a pointer, so it cannot be nil and doesn't require nil checking. Only pointer fields within the capabilities struct should be checked for nil.
server/request_handler.go (7)
Learnt from: ezynda3
PR: mark3labs/mcp-go#461
File: server/sampling.go:22-26
Timestamp: 2025-06-30T07:13:17.052Z
Learning: In the mark3labs/mcp-go project, the MCPServer.capabilities field is a struct value (serverCapabilities), not a pointer, so it cannot be nil and doesn't require nil checking. Only pointer fields within the capabilities struct should be checked for nil.
Learnt from: octo
PR: mark3labs/mcp-go#149
File: mcptest/mcptest.go:0-0
Timestamp: 2025-04-21T21:26:32.945Z
Learning: In the mcptest package, prefer returning errors from helper functions rather than calling t.Fatalf() directly, giving callers flexibility in how to handle errors.
Learnt from: lariel-fernandes
PR: mark3labs/mcp-go#428
File: www/docs/pages/servers/prompts.mdx:218-234
Timestamp: 2025-06-20T20:39:51.870Z
Learning: In the mcp-go library, the GetPromptParams.Arguments field is of type map[string]string, not map[string]interface{}, so direct string access without type assertions is safe and correct.
Learnt from: davidleitw
PR: mark3labs/mcp-go#451
File: mcp/tools.go:1192-1217
Timestamp: 2025-06-26T09:38:18.629Z
Learning: In mcp-go project, the maintainer prefers keeping builder pattern APIs simple without excessive validation for edge cases. The WithOutput* functions are designed to assume correct usage rather than defensive programming, following the principle of API simplicity over comprehensive validation.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:0-0
Timestamp: 2025-03-04T07:00:57.111Z
Learning: The Tool struct in the mark3labs/mcp-go project should handle both InputSchema and RawInputSchema consistently between MarshalJSON and UnmarshalJSON methods, even though the tools response from MCP server typically doesn't contain rawInputSchema.
Learnt from: floatingIce91
PR: mark3labs/mcp-go#401
File: server/server.go:1082-1092
Timestamp: 2025-06-23T11:10:42.948Z
Learning: In Go MCP server, ServerTool.Tool field is only used for tool listing and indexing, not for tool execution or middleware. During handleToolCall, only the Handler field is used, so dynamic tools don't need the Tool field populated.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:107-137
Timestamp: 2025-03-04T06:59:43.882Z
Learning: Tool responses from the MCP server shouldn't contain RawInputSchema, which is why the UnmarshalJSON method for the Tool struct is implemented to handle only the structured InputSchema format.
www/docs/pages/transports/http.mdx (1)
Learnt from: floatingIce91
PR: mark3labs/mcp-go#401
File: server/server.go:1082-1092
Timestamp: 2025-06-23T11:10:42.948Z
Learning: In Go MCP server, ServerTool.Tool field is only used for tool listing and indexing, not for tool execution or middleware. During handleToolCall, only the Handler field is used, so dynamic tools don't need the Tool field populated.
mcp/tools.go (5)
Learnt from: floatingIce91
PR: mark3labs/mcp-go#401
File: server/server.go:1082-1092
Timestamp: 2025-06-23T11:10:42.948Z
Learning: In Go MCP server, ServerTool.Tool field is only used for tool listing and indexing, not for tool execution or middleware. During handleToolCall, only the Handler field is used, so dynamic tools don't need the Tool field populated.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:0-0
Timestamp: 2025-03-04T07:00:57.111Z
Learning: The Tool struct in the mark3labs/mcp-go project should handle both InputSchema and RawInputSchema consistently between MarshalJSON and UnmarshalJSON methods, even though the tools response from MCP server typically doesn't contain rawInputSchema.
Learnt from: ezynda3
PR: mark3labs/mcp-go#461
File: server/sampling.go:22-26
Timestamp: 2025-06-30T07:13:17.052Z
Learning: In the mark3labs/mcp-go project, the MCPServer.capabilities field is a struct value (serverCapabilities), not a pointer, so it cannot be nil and doesn't require nil checking. Only pointer fields within the capabilities struct should be checked for nil.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:107-137
Timestamp: 2025-03-04T06:59:43.882Z
Learning: Tool responses from the MCP server shouldn't contain RawInputSchema, which is why the UnmarshalJSON method for the Tool struct is implemented to handle only the structured InputSchema format.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:0-0
Timestamp: 2025-03-04T07:00:57.111Z
Learning: The Tool struct in mark3labs/mcp-go handles both InputSchema and RawInputSchema formats. When unmarshaling JSON, it first tries to parse into a structured ToolInputSchema format, and if that fails, it falls back to using the raw schema format, providing symmetry with the MarshalJSON method.
www/docs/pages/transports/sse.mdx (1)
Learnt from: leavez
PR: mark3labs/mcp-go#114
File: client/transport/sse.go:137-179
Timestamp: 2025-04-06T10:07:06.685Z
Learning: The SSE client implementation in the MCP-Go project uses a 30-second timeout for reading SSE events to match the behavior of the original implementation before the transport layer refactoring.
server/streamable_http_test.go (5)
Learnt from: octo
PR: mark3labs/mcp-go#149
File: mcptest/mcptest.go:0-0
Timestamp: 2025-04-21T21:26:32.945Z
Learning: In the mcptest package, prefer returning errors from helper functions rather than calling t.Fatalf() directly, giving callers flexibility in how to handle errors.
Learnt from: ezynda3
PR: mark3labs/mcp-go#461
File: server/sampling.go:22-26
Timestamp: 2025-06-30T07:13:17.052Z
Learning: In the mark3labs/mcp-go project, the MCPServer.capabilities field is a struct value (serverCapabilities), not a pointer, so it cannot be nil and doesn't require nil checking. Only pointer fields within the capabilities struct should be checked for nil.
Learnt from: floatingIce91
PR: mark3labs/mcp-go#401
File: server/server.go:1082-1092
Timestamp: 2025-06-23T11:10:42.948Z
Learning: In Go MCP server, ServerTool.Tool field is only used for tool listing and indexing, not for tool execution or middleware. During handleToolCall, only the Handler field is used, so dynamic tools don't need the Tool field populated.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:107-137
Timestamp: 2025-03-04T06:59:43.882Z
Learning: Tool responses from the MCP server shouldn't contain RawInputSchema, which is why the UnmarshalJSON method for the Tool struct is implemented to handle only the structured InputSchema format.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:0-0
Timestamp: 2025-03-04T07:00:57.111Z
Learning: The Tool struct in the mark3labs/mcp-go project should handle both InputSchema and RawInputSchema consistently between MarshalJSON and UnmarshalJSON methods, even though the tools response from MCP server typically doesn't contain rawInputSchema.
mcp/types.go (6)
Learnt from: ezynda3
PR: mark3labs/mcp-go#461
File: server/sampling.go:22-26
Timestamp: 2025-06-30T07:13:17.052Z
Learning: In the mark3labs/mcp-go project, the MCPServer.capabilities field is a struct value (serverCapabilities), not a pointer, so it cannot be nil and doesn't require nil checking. Only pointer fields within the capabilities struct should be checked for nil.
Learnt from: lariel-fernandes
PR: mark3labs/mcp-go#428
File: www/docs/pages/servers/prompts.mdx:218-234
Timestamp: 2025-06-20T20:39:51.870Z
Learning: In the mcp-go library, the GetPromptParams.Arguments field is of type map[string]string, not map[string]interface{}, so direct string access without type assertions is safe and correct.
Learnt from: octo
PR: mark3labs/mcp-go#149
File: mcptest/mcptest.go:0-0
Timestamp: 2025-04-21T21:26:32.945Z
Learning: In the mcptest package, prefer returning errors from helper functions rather than calling t.Fatalf() directly, giving callers flexibility in how to handle errors.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:107-137
Timestamp: 2025-03-04T06:59:43.882Z
Learning: Tool responses from the MCP server shouldn't contain RawInputSchema, which is why the UnmarshalJSON method for the Tool struct is implemented to handle only the structured InputSchema format.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:0-0
Timestamp: 2025-03-04T07:00:57.111Z
Learning: The Tool struct in the mark3labs/mcp-go project should handle both InputSchema and RawInputSchema consistently between MarshalJSON and UnmarshalJSON methods, even though the tools response from MCP server typically doesn't contain rawInputSchema.
Learnt from: davidleitw
PR: mark3labs/mcp-go#451
File: mcp/tools.go:1192-1217
Timestamp: 2025-06-26T09:38:18.629Z
Learning: In mcp-go project, the maintainer prefers keeping builder pattern APIs simple without excessive validation for edge cases. The WithOutput* functions are designed to assume correct usage rather than defensive programming, following the principle of API simplicity over comprehensive validation.
server/sse_test.go (6)
Learnt from: floatingIce91
PR: mark3labs/mcp-go#401
File: server/server.go:1082-1092
Timestamp: 2025-06-23T11:10:42.948Z
Learning: In Go MCP server, ServerTool.Tool field is only used for tool listing and indexing, not for tool execution or middleware. During handleToolCall, only the Handler field is used, so dynamic tools don't need the Tool field populated.
Learnt from: ezynda3
PR: mark3labs/mcp-go#461
File: server/sampling.go:22-26
Timestamp: 2025-06-30T07:13:17.052Z
Learning: In the mark3labs/mcp-go project, the MCPServer.capabilities field is a struct value (serverCapabilities), not a pointer, so it cannot be nil and doesn't require nil checking. Only pointer fields within the capabilities struct should be checked for nil.
Learnt from: robert-jackson-glean
PR: mark3labs/mcp-go#214
File: server/sse.go:0-0
Timestamp: 2025-04-28T00:14:49.263Z
Learning: The SSE server in mcp-go implements path sanitization within the `WithDynamicBasePath` function that ensures the dynamic base path starts with "/" and has no trailing "/" to prevent double slashes in URL construction.
Learnt from: octo
PR: mark3labs/mcp-go#149
File: mcptest/mcptest.go:0-0
Timestamp: 2025-04-21T21:26:32.945Z
Learning: In the mcptest package, prefer returning errors from helper functions rather than calling t.Fatalf() directly, giving callers flexibility in how to handle errors.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:107-137
Timestamp: 2025-03-04T06:59:43.882Z
Learning: Tool responses from the MCP server shouldn't contain RawInputSchema, which is why the UnmarshalJSON method for the Tool struct is implemented to handle only the structured InputSchema format.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:0-0
Timestamp: 2025-03-04T07:00:57.111Z
Learning: The Tool struct in the mark3labs/mcp-go project should handle both InputSchema and RawInputSchema consistently between MarshalJSON and UnmarshalJSON methods, even though the tools response from MCP server typically doesn't contain rawInputSchema.
🧬 Code Graph Analysis (1)
mcp/prompts.go (1)
mcp/types.go (1)
  • PaginatedRequest (522-525)
🪛 LanguageTool
www/docs/pages/transports/http.mdx

[grammar] ~655-~655: Use correct spacing
Context: ... jwt.StandardClaims } ``` ### Request Headers The StreamableHTTP transport now passes...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~657-~657: Use correct spacing
Context: ...h the request in your tool and resource handlers. #### Accessing Headers in Handlers Headers ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~659-~659: Use correct spacing
Context: ...ce handlers. #### Accessing Headers in Handlers Headers are available in all MCP reques...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~661-~661: Use correct spacing
Context: ...eaders are available in all MCP request objects: go func handleGetUser(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { // Access request headers headers := req.Header // Use headers for authentication, tracing, etc. authToken := headers.Get("Authorization") if authToken == "" { return nil, fmt.Errorf("authentication required") } // Access other headers requestID := headers.Get("X-Request-ID") userAgent := headers.Get("User-Agent") // Rest of your handler code... } This works for all MCP request types in...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~682-~682: There might be a problem here.
Context: .... } ``` This works for all MCP request types including: - CallToolRequest - `ReadResourceRequest` - `ListToolsRequest` - `ListResourcesRequest` - `InitializeRequest` - And other MCP request types The header...

(QB_NEW_EN_MERGED_MATCH)


[grammar] ~688-~688: Use correct spacing
Context: ...tializeRequest` - And other MCP request types The headers are automatically populated...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~690-~690: Use correct spacing
Context: ...in your handlers without any additional configuration. ## Next Steps - **[In-Process Transport](...

(QB_NEW_EN_OTHER_ERROR_IDS_5)

www/docs/pages/transports/sse.mdx

[grammar] ~335-~335: Use correct spacing
Context: ...broadcast capabilities ``` ### Request Headers Like the StreamableHTTP transport, the ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~337-~337: Use correct spacing
Context: ...SE connection in your tool and resource handlers. #### Accessing Headers in Handlers Headers ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~339-~339: Use correct spacing
Context: ...ce handlers. #### Accessing Headers in Handlers Headers from the SSE connection are ava...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~341-~341: Use correct spacing
Context: ...ection are available in all MCP request objects: go func handleStreamData(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { // Access request headers headers := req.Header // Use headers for authentication, tracing, etc. authToken := headers.Get("Authorization") if authToken == "" { return nil, fmt.Errorf("authentication required") } // Access other headers requestID := headers.Get("X-Request-ID") userAgent := headers.Get("User-Agent") // Rest of your handler code... mcpServer := server.ServerFromContext(ctx) // ... } This works for all MCP request types in...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~364-~364: There might be a problem here.
Context: .... } ``` This works for all MCP request types including: - CallToolRequest - `ReadResourceRequest` - `ListToolsRequest` - `ListResourcesRequest` - `InitializeRequest` - And other MCP request types The header...

(QB_NEW_EN_MERGED_MATCH)


[grammar] ~370-~370: Use correct spacing
Context: ...tializeRequest` - And other MCP request types The headers are automatically populated...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~372-~372: Use correct spacing
Context: ...in your handlers without any additional configuration. Note: Since SSE maintains a persistent ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~374-~374: Use correct spacing
Context: ...r all requests during that connection's lifetime. ## Next Steps - **[HTTP Transport](/trans...

(QB_NEW_EN_OTHER_ERROR_IDS_5)

🔇 Additional comments (21)
server/ctx.go (1)

1-8: LGTM! Clean context key implementation.

The context key implementation follows Go best practices with a custom type and iota for unique key generation. This provides a clean way to store and retrieve HTTP headers throughout the server codebase.

server/streamable_http.go (1)

313-313: LGTM! Proper header injection placement.

The header injection is correctly placed after context preparation but before message handling, ensuring HTTP headers are available during MCP message processing.

server/sse.go (1)

509-509: LGTM! Consistent header injection for SSE transport.

The header injection is correctly placed after creating the detached context but before async message processing, ensuring HTTP headers are available during SSE message handling.

mcp/prompts.go (3)

3-3: LGTM! Proper import addition.

The net/http import is correctly added to support the http.Header type in the request structs.


11-11: LGTM! Consistent header field addition.

The Header field is appropriately added with json:"-" tag to exclude it from JSON serialization while making HTTP headers accessible within the request struct.


26-26: LGTM! Consistent header field addition.

The Header field is appropriately added with json:"-" tag to exclude it from JSON serialization while making HTTP headers accessible within the request struct.

mcp/tools.go (2)

7-7: LGTM! Proper import addition.

The net/http import is correctly added to support the http.Header type in the request structs.


18-18: LGTM! Consistent header field addition.

The Header field is appropriately added with json:"-" tag to exclude it from JSON serialization while making HTTP headers accessible within the request struct.

server/request_handler.go (3)

9-9: LGTM: HTTP import added correctly.

The import is properly added to support the header extraction functionality.


75-82: LGTM: Robust header extraction logic.

The header extraction implementation is well-designed with proper defensive programming:

  • Safe type assertion with ok check
  • Fallback to empty header map when headers are nil or wrong type
  • Clear variable naming and structure

This ensures the feature works reliably even when headers are not properly set in the context.


94-94: LGTM: Consistent header assignment across all request types.

The header assignment is implemented consistently across all MCP request types (Initialize, Ping, SetLevel, ResourcesList, etc.). This ensures that HTTP headers are available in all handlers without any gaps in functionality.

The placement right after unmarshaling and before hook execution is optimal for ensuring headers are available throughout the request lifecycle.

Also applies to: 114-114, 140-140, 166-166, 192-192, 218-218, 244-244, 270-270, 296-296, 322-322

www/docs/pages/transports/http.mdx (1)

655-691: LGTM: Comprehensive documentation for header access.

The documentation clearly explains the new header access feature with:

  • Practical example showing common use cases (authentication, tracing)
  • Complete list of supported MCP request types
  • Clear explanation that no additional configuration is needed
  • Good integration with the existing HTTP transport documentation

The example code is realistic and demonstrates how developers would typically use this feature in production scenarios.

server/streamable_http_test.go (1)

778-829: LGTM: Comprehensive test for header passthrough.

The test effectively verifies the header passthrough functionality:

  • Tests both standard (Content-Type) and custom (X-Custom-Header) headers
  • Follows the established test patterns in the file
  • Properly initializes session and verifies end-to-end functionality
  • Uses realistic header values that would be common in production

The test structure is clean and provides good coverage for the feature, ensuring headers are correctly propagated from HTTP requests to MCP tool handlers.

www/docs/pages/transports/sse.mdx (2)

83-95: LGTM: Well-integrated header access example.

The header access code is seamlessly integrated into the existing handleStreamData function example, showing practical usage patterns for authentication and tracing. The placement at the beginning of the function demonstrates best practices for early validation.


335-375: LGTM: Excellent documentation with SSE-specific context.

The documentation provides comprehensive coverage with an important SSE-specific note about persistent connections. Key strengths:

  • Consistent with HTTP transport documentation for easy developer understanding
  • Clear explanation of automatic header population
  • Important clarification about header lifetime in persistent SSE connections
  • Complete list of supported MCP request types

The note about headers being captured at connection establishment is particularly valuable for SSE usage patterns.

server/sse_test.go (3)

1447-1515: LGTM! Well-structured test for header passthrough.

The test correctly verifies that HTTP headers are passed through to tool requests in the SSE transport. The implementation properly establishes an SSE connection, sends a request with custom headers, and verifies the header reaches the tool handler.


1517-1600: LGTM! Good defensive test for nil safety.

This test ensures that the headers map is never nil even when no headers are sent, preventing potential panics when tools access headers. The use of a custom transport with cleared headers ensures a realistic test scenario.


1612-1623: LGTM! Clean helper function implementation.

The helper function is well-focused and follows the existing pattern for adding tools to the MCP server. It correctly validates the expected header value and returns appropriate error messages.

mcp/types.go (3)

12-12: LGTM! Appropriate import addition.

The net/http import is correctly added to support the http.Header type used in the Header fields throughout the file.


403-403: LGTM! Consistent header field implementation.

The Header field is properly added with the correct type and JSON exclusion tag. This follows the established pattern for internal-only fields that shouldn't be serialized.


494-494: LGTM! Consistent header field additions across all request types.

All Header fields are implemented consistently with:

  • Correct http.Header type
  • json:"-" tag for JSON exclusion
  • Unexported field names
  • Applied only to request structs, not response types

This implementation enables HTTP header passthrough for MCP requests while maintaining clean JSON serialization.

Also applies to: 547-547, 561-561, 575-575, 607-607, 622-622, 728-728, 972-972, 1025-1025

@ezynda3
Copy link
Contributor

ezynda3 commented Jul 15, 2025

@adityamj the PR seems to introduce some potential race conditions. Could you have a look?

@ezynda3 ezynda3 added the status: needs submitter response Waiting for feedback from issue opener label Jul 15, 2025
@adityamj
Copy link
Contributor Author

adityamj commented Jul 15, 2025

@ezynda3 , the race is now fixed.

@ezynda3 ezynda3 merged commit baa7153 into mark3labs:main Jul 15, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs submitter response Waiting for feedback from issue opener
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants