Skip to content

feat(server): support configurable max request payload size#646

Open
jskjw157 wants to merge 1 commit intomodelcontextprotocol:mainfrom
jskjw157:feature/configurable-max-payload-size
Open

feat(server): support configurable max request payload size#646
jskjw157 wants to merge 1 commit intomodelcontextprotocol:mainfrom
jskjw157:feature/configurable-max-payload-size

Conversation

@jskjw157
Copy link
Copy Markdown
Contributor

Summary

Add maxRequestBodySize parameter to StreamableHttpServerTransport.Configuration, allowing consumers to set a custom request body size limit lower than the default 4 MB.

  • Add maxRequestBodySize: Long property to Configuration with a default of 4 MB (4,194,304 bytes)
  • Replace hardcoded MAXIMUM_MESSAGE_SIZE constant with the configurable value in parseBody()
  • Use Long for content-length comparison to avoid Int overflow on large values

Motivation and Context

Closes #521

The StreamableHttpServerTransport has a hardcoded 4 MB request body limit. Consumers who need a lower limit currently have to manually count the request payload size before passing it to the SDK. This change makes the limit configurable via Configuration.

How Has This Been Tested?

  • Existing unit tests continue to pass (default 4 MB behavior unchanged)
  • Added POST with custom max request body size rejects oversized payload — verifies PayloadTooLarge is returned for payloads exceeding the custom limit
  • Added POST at exactly custom max request body size is not rejected as payload too large — verifies payloads at exactly the limit are not rejected by the size check
./gradlew :kotlin-sdk-server:jvmTest --tests "*.StreamableHttpServerTransportTest"

Breaking Changes

None. The new parameter has a default value matching the previous hardcoded limit.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

@jskjw157 jskjw157 force-pushed the feature/configurable-max-payload-size branch from 7a50a35 to 1a92a5e Compare March 28, 2026 09:11
…textprotocol#521)

Add maxRequestBodySize parameter to StreamableHttpServerTransport.Configuration,
defaulting to 4 MB. This allows consumers to set a lower request body size limit
without manual payload counting.

- Add maxRequestBodySize: Long to Configuration with require(> 0) validation
- Replace hardcoded MAXIMUM_MESSAGE_SIZE with configurable value in parseBody()
- Use Long for content-length comparison to avoid Int overflow
- Error message displays exact byte limit for clarity at any configured size
- Note: body.length check after receiveText() uses character count (pre-existing
  behavior); byte-accurate fallback is tracked separately
@jskjw157 jskjw157 force-pushed the feature/configurable-max-payload-size branch from 1a92a5e to ddf9bc9 Compare March 28, 2026 09:18
@codecov-commenter
Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 57.14286% with 3 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...kotlin/sdk/server/StreamableHttpServerTransport.kt 57.14% 2 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@jskjw157
Copy link
Copy Markdown
Contributor Author

@kpavlov Hey! I’ve addressed the feedback on this PR and all checks are passing now. Would you mind taking a look when you get a chance? Thanks!


configureTransportEndpoint(transport)

val oversizedPayload = "x".repeat(customMaxSize.toInt() + 1)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: Maybe let's use small valid payload and set the max size to payload length + 1. It ensures that rejection reason is size.

}

@Test
fun `POST at exactly custom max request body size is not rejected as payload too large`() = testApplication {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: This and previous tests could be combined into one parametrized test

return null
}

val body = call.receiveText()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: If there is a content length header and it's bigger than max body size, then receiving text is a waste of time and memory. Request can be immediately rejected.

val transport = StreamableHttpServerTransport(
StreamableHttpServerTransport.Configuration(
enableJsonResponse = true,
maxRequestBodySize = customMaxSize,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

  • test for negative value throwong IllegalArgumentException

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support configuration of the max request payload size for Streamable HTTP impl

3 participants