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 2 times, most recently from 1a92a5e to ddf9bc9 Compare March 28, 2026 09:18
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Mar 28, 2026

Codecov Report

❌ Patch coverage is 70.00000% 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 70.00% 1 Missing and 2 partials ⚠️

📢 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!

kpavlov
kpavlov previously approved these changes Mar 29, 2026

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — combined with the next nit into a parameterized test using a small 64-byte payload, with maxSize set relative to payload length (length-1, length, length+1).

}

@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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — merged into a single @ParameterizedTest with @MethodSource covering three boundary cases.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Already covered — Content-Length is checked before receiveText() (line 676). The body-length check after receiveText() is a fallback for missing or inaccurate Content-Length headers.

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — added assertFailsWith for Configuration(maxRequestBodySize = -1).

@jskjw157 jskjw157 force-pushed the feature/configurable-max-payload-size branch from ddf9bc9 to 43a79ff Compare March 30, 2026 02:49
@kpavlov
Copy link
Copy Markdown
Contributor

kpavlov commented Mar 30, 2026

lgtm

@kpavlov kpavlov added the tests label Mar 30, 2026
@kpavlov kpavlov force-pushed the feature/configurable-max-payload-size branch from 43a79ff to 3777c6d Compare March 30, 2026 10:50
@kpavlov kpavlov requested a review from devcrocod March 30, 2026 11:50
@kpavlov kpavlov force-pushed the feature/configurable-max-payload-size branch from 3777c6d to 3559b94 Compare March 30, 2026 11:51
@kpavlov kpavlov force-pushed the feature/configurable-max-payload-size branch from 3559b94 to 84952a6 Compare March 30, 2026 21:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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