Skip to content

Conversation

@cryo-zd
Copy link
Contributor

@cryo-zd cryo-zd commented Jun 20, 2025

Description

Implement the subtask of adding protocol version header validation to StreamableHTTPServer in mcp-go.

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

MCP Spec Compliance

  • This PR implements a feature defined in the MCP specification
  • Link to relevant spec section: Link text
  • Implementation follows the specification exactly

Summary by CodeRabbit

  • New Features
    • Added support for validating the protocol version in HTTP request headers for all request types, ensuring only supported protocol versions are accepted.
    • Introduced a default protocol version for requests without an explicit version specified.
  • Bug Fixes
    • Unified and improved request header validation for session IDs and protocol versions across POST, GET, and DELETE requests.
  • Tests
    • Introduced comprehensive tests to verify correct handling of the protocol version header and session validation for all HTTP methods.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 20, 2025

Walkthrough

This change introduces server-side validation of the MCP-Protocol-Version HTTP header in the StreamableHTTPServer. Centralized header validation logic is added for POST, GET, and DELETE methods. A new default negotiated protocol version constant is defined, and comprehensive tests are included to verify protocol version enforcement.

Changes

Files/Groups Change Summary
mcp/types.go Added DEFAULT_NEGOTIATED_VERSION constant for default MCP protocol version.
server/streamable_http.go Added protocol version header constant; centralized and unified request header validation for session ID and protocol version.
server/streamable_http_test.go Added protocol version header tests, centralized protocol version usage in tests, and improved error handling in notification tests.

Possibly related issues

Suggested reviewers

  • pottekkat

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (1.64.8)

Error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2
Failed executing command with error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2


📜 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 337925b and 6d1ca6d.

📒 Files selected for processing (1)
  • server/streamable_http_test.go (5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (5)
server/streamable_http_test.go (5)

26-26: Good centralization of protocol version constant.

The introduction of clientInitializedProtocolVersion constant improves maintainability and consistency across tests.


33-33: Excellent use of the centralized constant.

Replacing the hardcoded protocol version with the constant ensures consistency and makes future updates easier.


510-510: Verify the reason for enabling stateless mode in these tests.

Both TestStreamableHTTP_GET and TestStreamableHTTP_SessionWithTools now create the server with WithStateLess(true). Ensure this change aligns with the test objectives and doesn't mask any session-related functionality that should be tested.

Also applies to: 617-617


630-659: Excellent improvement to error handling.

The asynchronous error handling using channels properly captures and reports errors from the GET request goroutine, preventing potential test hanging and providing clear error messages.


797-971: Comprehensive protocol version header validation test.

The new test thoroughly validates the MCP protocol version header requirements:

  • Tests all HTTP methods (POST, GET, DELETE)
  • Covers negotiated version, supported alternative version, and unsupported version scenarios
  • Expects correct status codes per the MCP specification
  • Well-documented with specification references

However, verify that the hardcoded protocol versions used in tests are actually supported/unsupported by the server implementation.

#!/bin/bash
# Description: Verify the protocol versions used in tests are correctly supported/unsupported by the server
# Expected: Find server-side validation logic that defines supported protocol versions

# Search for protocol version validation logic
ast-grep --pattern 'func $_($$) {
  $$$
  validateProtocolVersion($$$)
  $$$
}'

# Search for supported protocol versions definitions
rg -A 5 -B 5 'validateProtocolVersion|SUPPORTED.*VERSION|protocol.*version.*support'

# Search for hardcoded protocol versions in server code
rg '"2024-11-05"|"2024-06-18"|"2025-03-26"'
✨ 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.

@cryo-zd cryo-zd marked this pull request as ready for review June 22, 2025 09:30
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: 1

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 0fdb197 and 337925b.

📒 Files selected for processing (3)
  • mcp/types.go (1 hunks)
  • server/streamable_http.go (6 hunks)
  • server/streamable_http_test.go (5 hunks)
🔇 Additional comments (7)
mcp/types.go (1)

101-103: LGTM! Well-documented constant addition.

The new DEFAULT_NEGOTIATED_VERSION constant is properly documented and correctly references the MCP specification. The value appropriately matches LATEST_PROTOCOL_VERSION.

server/streamable_http_test.go (3)

26-26: Good practice to centralize the test constant.

Using a centralized constant for the protocol version in tests improves maintainability.


630-648: Excellent error handling improvement!

The addition of the error channel and early failure detection makes the test more robust and easier to debug when failures occur.


797-971: Comprehensive test coverage for protocol version validation!

The test thoroughly covers all HTTP methods (POST, GET, DELETE) with different protocol version scenarios:

  • Negotiated version from initialization
  • Supported but different version
  • Unsupported/invalid version

This aligns perfectly with the MCP specification requirements.

server/streamable_http.go (3)

209-211: Good constant naming consistency.

The new headerKeyProtocolVersion constant follows the established naming pattern and uses the correct header name as specified in the MCP documentation.


509-556: Excellent refactoring of validation logic!

The centralized validation approach with separate methods for session and protocol version validation:

  • Improves code maintainability and readability
  • Ensures consistent validation across all HTTP methods
  • Provides clear error messages with supported versions
  • Correctly defaults to DEFAULT_NEGOTIATED_VERSION when header is missing

The implementation aligns perfectly with the MCP specification requirements.


245-246: Consistent validation across all HTTP methods.

The validation is properly applied to POST (except for initialize requests), GET, and DELETE methods, ensuring uniform enforcement of the protocol version requirement as specified in the MCP documentation.

Also applies to: 349-351, 449-451

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
return
}
} else if !s.validateRequestHeaders(w, r) {
return

Choose a reason for hiding this comment

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

We might need to store this new header in the session state during initialization if the server is stateful. From the mcp spec, I am interpreting that when the header is "invalid" is when the client uses a different protocol version header than what was initialized. Otherwise, what you have is good is my book

If using HTTP, the client MUST include the MCP-Protocol-Version: HTTP header on all subsequent requests to the MCP server, allowing the MCP server to respond based on the MCP protocol version.


The protocol version sent by the client SHOULD be the one negotiated during initialization.


If the server receives a request with an invalid or unsupported MCP-Protocol-Version, it MUST respond with 400 Bad Request.

@ezynda3 ezynda3 added the type: enhancement New feature or enhancement request label Sep 19, 2025
@cryo-zd cryo-zd closed this Oct 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: enhancement New feature or enhancement request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants