Skip to content

feat: introduce StreamableHttpServerTransport.Configuration#560

Merged
kpavlov merged 3 commits intomainfrom
kpavlov/streaming-http-config
Feb 26, 2026
Merged

feat: introduce StreamableHttpServerTransport.Configuration#560
kpavlov merged 3 commits intomainfrom
kpavlov/streaming-http-config

Conversation

@kpavlov
Copy link
Contributor

@kpavlov kpavlov commented Feb 23, 2026

Introduce Configuration class for StreamableHttpServerTransport

Replace the six-parameter flat constructor of StreamableHttpServerTransport with a typed Configuration class. This improves API ergonomics, enables structural equality and copy(), and provides a stable extension point for future options without further breaking the constructor signature.

Changes:

  • Add Configuration as a public class nested directly on StreamableHttpServerTransport, with enableJsonResponse as the first parameter (most commonly set)
  • Change the primary constructor to accept Configuration.
  • Rename retryIntervalMillis: Long? to retryInterval: Duration? in Configuration, aligning with Kotlin's type-safe time API
  • Deprecate the old flat constructor with a compatibility bridge
  • Update KotlinTestBase integration test to use the new constructor
  • Enable test AbstractResourceIntegrationTest.testSubscribeAndUnsubscribe() since Fix notification pipeline #249 is closed

Motivation and Context

The current StreamableHttpServerTransport API cannot be easily extended: adding more parameters would be a breaking change. But this is already needed for #521.
This PR is a prerequisite for #535

How Has This Been Tested?

Regression tests

Breaking Changes

No. Current StreamableHttpServerTransport constructor was deprecated

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

@kpavlov kpavlov added enhancement New feature or request api API Update 🎭 labels Feb 23, 2026
assertEquals(testResourceContent, content.text, "Resource content should match")
}

@Ignore("Blocked by https://github.com/modelcontextprotocol/kotlin-sdk/issues/249")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This test is passing now

@kpavlov kpavlov force-pushed the kpavlov/streaming-http-config branch from ef8ba32 to 6ab4187 Compare February 23, 2026 13:10
@kpavlov kpavlov marked this pull request as ready for review February 23, 2026 13:23
aozherelyeva
aozherelyeva previously approved these changes Feb 23, 2026
Copy link
Collaborator

@aozherelyeva aozherelyeva left a comment

Choose a reason for hiding this comment

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

LGtM, thanks

@kpavlov kpavlov force-pushed the kpavlov/streaming-http-config branch 2 times, most recently from 8c63aa8 to f649ff0 Compare February 23, 2026 14:30
@kpavlov kpavlov removed the request for review from tiginamaria February 23, 2026 14:35
Copy link
Contributor

@devcrocod devcrocod left a comment

Choose a reason for hiding this comment

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

Except for one place where I left a comment, it looks good

Comment on lines 146 to 148
public companion object {
public val Default: Configuration = Configuration()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is a companion object needed?
In my view, it’s redundant, considering that Configuration already has all the parameters with default values

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It serves as a constant avoid creating Configuration instances every time. Does it make sense?

Copy link
Contributor

Choose a reason for hiding this comment

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

Not really.
Is it actually expected that users will be creating thousands of Configuration instances?
Also, this adds it to the public Companion

Copy link
Contributor Author

@kpavlov kpavlov Feb 23, 2026

Choose a reason for hiding this comment

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

Is it actually expected that users will be creating thousands of Configuration instances?

Thank you, @devcrocod.
When I took a closer look at the code, I noticed a more important problem here: the custom config object is being created on every POST request, anda one-time StreamableHttpServerTransport is also being created.

The Configuration object would have been reused if this method had accepted it as a parameter.

Given this, let’s remove the default parameter value from the StreamableHttpServerTransport constructor completely. So, StreamableHttpServerTransport.Default is also not needed.

Changing Application.mcpStatelessStreamableHttp(...) parameters from plain parameter list to configuration object should be separate PR.

@kpavlov kpavlov changed the title feat: introduce Configuration data class for StreamableHttpServerTransport feat: introduce StreamableHttpServerTransport.Configuration Feb 23, 2026
@kpavlov
Copy link
Contributor Author

kpavlov commented Feb 23, 2026

Please, have a look at #563 after this one

e5l
e5l previously approved these changes Feb 24, 2026
Copy link
Contributor

@e5l e5l left a comment

Choose a reason for hiding this comment

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

lgtm

*/
@OptIn(ExperimentalUuidApi::class, ExperimentalAtomicApi::class)
@Suppress("TooManyFunctions")
public class StreamableHttpServerTransport(
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we add a method for backward source compatibility?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

aozherelyeva
aozherelyeva previously approved these changes Feb 24, 2026
@kpavlov kpavlov dismissed stale reviews from aozherelyeva and e5l via 41eb756 February 26, 2026 08:21
@kpavlov kpavlov force-pushed the kpavlov/streaming-http-config branch from 0df06f5 to 41eb756 Compare February 26, 2026 08:21
@kpavlov kpavlov requested a review from e5l February 26, 2026 08:54
Copy link
Contributor

@devcrocod devcrocod left a comment

Choose a reason for hiding this comment

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

👍

Replace the six-parameter flat constructor of StreamableHttpServerTransport with a typed Configuration class. This improves API ergonomics and provides a stable extension point for future options without further breaking the constructor signature.

Changes:

  - Add `Configuration` as a public class nested directly on `StreamableHttpServerTransport`, with `enableJsonResponse` as the first
    parameter (most commonly set)
  - Change the primary constructor to accept `Configuration`
  - Rename `retryIntervalMillis: Long?` to `retryInterval: Duration?` in Configuration, aligning with Kotlin's type-safe time API
  - Deprecate the old flat constructor with a compatibility bridge
  - Update KotlinTestBase integration test to use the new constructor
…simplify `StreamableHttpServerTransport` constructor
…uctor

- Revert default constructor and mark it as deprecated
- Add ReplaceWith expression for multi-parameter constructor
@kpavlov kpavlov force-pushed the kpavlov/streaming-http-config branch from 41eb756 to 7da7675 Compare February 26, 2026 11:06
@kpavlov kpavlov merged commit ec53adc into main Feb 26, 2026
13 checks passed
@kpavlov kpavlov deleted the kpavlov/streaming-http-config branch February 26, 2026 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api API Update 🎭 enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants