Sourced from io.modelcontextprotocol:kotlin-sdk-server's releases.
0.15.0
Description
This release makes inbound message handling concurrent after the initialization handshake, adds SSE heartbeats and elicitation schema validation, and fixes several Streamable HTTP response and session-lifecycle bugs.
Breaking Changes
Concurrent inbound dispatch by
@devcrocodin #884Inbound messages were processed serially on the transport read loop, so one slow or peer-awaiting handler (sampling, elicitation, roots) blocked every later message on the connection, including the responses and
notifications/cancelledthose handlers depend on. After the handshake, handlers may now run concurrently; processing stays serial during initialization.
ProtocolOptions/ClientOptions/ServerOptionsgain ahandlerCoroutineContextparameter (defaults toDispatchers.Default). Concurrency is bounded internally; there is no opt-out flag by design.RequestHandlerExtrais now aCoroutineContext.Elementand is no longer user-constructible. It exposesrequestId,method,sendRequest, andsendNotification, and can be read inside a handler via the newcurrentRequestHandlerExtra().- val extra = RequestHandlerExtra() + val extra = currentRequestHandlerExtra()Duplicate feature names are rejected at registration by
@devcrocodin #883
addTool/addPrompt/addResource/addResourceTemplatesilently replaced an existing entry and emitted a spuriouslist_changednotification. They now throwIllegalArgumentExceptionand leave the existing registration intact. The batch variants (addTools/addPrompts/addResources) are all-or-nothing. To replace a feature, remove it first.- server.addTool(name = "search", ...) // silently overwrote + server.removeTool("search") + server.addTool(name = "search", ...)
eventStoreremoved frommcpStatelessStreamableHttpby@devcrocodin #909The parameter was never read or written: a stateless endpoint answers
GETwith405, so no stream exists to store or replay events on. The old overload is retained atDeprecationLevel.ERRORwith aReplaceWithmigration hint. UsemcpStreamableHttpwhen you need resumability.application.mcpStatelessStreamableHttp( path = "/mcp", - eventStore = myEventStore, ) { server }Features
- Optional SSE heartbeats for Streamable HTTP servers via
mcpStreamableHttp(sseHeartbeatConfig = { ... }), keeping long-lived streams alive against clients that disconnect on idle. Heartbeats stay off by default, by@UnscientificJsZhaiin #761- Accepted form-mode elicitation content is now validated against
requestedSchema; a mismatch failscreateElicitationwithMcpException(INVALID_PARAMS) instead of reaching server code unchecked, by@rea9rin #896- The Streamable HTTP client now sends the standard
Mcp-MethodandMcp-NamePOST headers, by@AndreKalbererin #894Fixed
- Stateless Streamable HTTP now closes its per-request session, fixing unbounded growth of the session registry and notification subscriptions, by
@KlyneChryslerin #872- Streamable HTTP responses keep their status and body when the client accepts only
text/event-stream, by@devcrocodin #911
... (truncated)
76b8e7d
release: 0.15.0 (#918)dab340f
fix(server): drop inert eventStore from stateless Streamable HTTP (#909)24c3cd3
fix(server): match Accept header as media ranges (#912)7fa438c
feat(client): send MCP standard POST headers (#894)94745e6
chore(deps): bump the kotest group across 1 directory with 3 updates (#915)2b494b7
chore(deps): bump the other-dependencies group across 5 directories with
3 up...82fe56e
fix(server): preserve Streamable HTTP response status and body (#911)a06d699
feat: SSE heartbeat (#761)cab669b
fix: classify malformed request params as invalid params (#886)b6cb547
fix(server): preserve id on duplicate initialize errors (#868)Sourced from io.modelcontextprotocol:kotlin-sdk-client's releases.
0.15.0
Description
This release makes inbound message handling concurrent after the initialization handshake, adds SSE heartbeats and elicitation schema validation, and fixes several Streamable HTTP response and session-lifecycle bugs.
Breaking Changes
Concurrent inbound dispatch by
@devcrocodin #884Inbound messages were processed serially on the transport read loop, so one slow or peer-awaiting handler (sampling, elicitation, roots) blocked every later message on the connection, including the responses and
notifications/cancelledthose handlers depend on. After the handshake, handlers may now run concurrently; processing stays serial during initialization.
ProtocolOptions/ClientOptions/ServerOptionsgain ahandlerCoroutineContextparameter (defaults toDispatchers.Default). Concurrency is bounded internally; there is no opt-out flag by design.RequestHandlerExtrais now aCoroutineContext.Elementand is no longer user-constructible. It exposesrequestId,method,sendRequest, andsendNotification, and can be read inside a handler via the newcurrentRequestHandlerExtra().- val extra = RequestHandlerExtra() + val extra = currentRequestHandlerExtra()Duplicate feature names are rejected at registration by
@devcrocodin #883
addTool/addPrompt/addResource/addResourceTemplatesilently replaced an existing entry and emitted a spuriouslist_changednotification. They now throwIllegalArgumentExceptionand leave the existing registration intact. The batch variants (addTools/addPrompts/addResources) are all-or-nothing. To replace a feature, remove it first.- server.addTool(name = "search", ...) // silently overwrote + server.removeTool("search") + server.addTool(name = "search", ...)
eventStoreremoved frommcpStatelessStreamableHttpby@devcrocodin #909The parameter was never read or written: a stateless endpoint answers
GETwith405, so no stream exists to store or replay events on. The old overload is retained atDeprecationLevel.ERRORwith aReplaceWithmigration hint. UsemcpStreamableHttpwhen you need resumability.application.mcpStatelessStreamableHttp( path = "/mcp", - eventStore = myEventStore, ) { server }Features
- Optional SSE heartbeats for Streamable HTTP servers via
mcpStreamableHttp(sseHeartbeatConfig = { ... }), keeping long-lived streams alive against clients that disconnect on idle. Heartbeats stay off by default, by@UnscientificJsZhaiin #761- Accepted form-mode elicitation content is now validated against
requestedSchema; a mismatch failscreateElicitationwithMcpException(INVALID_PARAMS) instead of reaching server code unchecked, by@rea9rin #896- The Streamable HTTP client now sends the standard
Mcp-MethodandMcp-NamePOST headers, by@AndreKalbererin #894Fixed
- Stateless Streamable HTTP now closes its per-request session, fixing unbounded growth of the session registry and notification subscriptions, by
@KlyneChryslerin #872- Streamable HTTP responses keep their status and body when the client accepts only
text/event-stream, by@devcrocodin #911
... (truncated)
76b8e7d
release: 0.15.0 (#918)dab340f
fix(server): drop inert eventStore from stateless Streamable HTTP (#909)24c3cd3
fix(server): match Accept header as media ranges (#912)7fa438c
feat(client): send MCP standard POST headers (#894)94745e6
chore(deps): bump the kotest group across 1 directory with 3 updates (#915)2b494b7
chore(deps): bump the other-dependencies group across 5 directories with
3 up...82fe56e
fix(server): preserve Streamable HTTP response status and body (#911)a06d699
feat: SSE heartbeat (#761)cab669b
fix: classify malformed request params as invalid params (#886)b6cb547
fix(server): preserve id on duplicate initialize errors (#868)Sourced from io.modelcontextprotocol:kotlin-sdk-testing's releases.
0.15.0
Description
This release makes inbound message handling concurrent after the initialization handshake, adds SSE heartbeats and elicitation schema validation, and fixes several Streamable HTTP response and session-lifecycle bugs.
Breaking Changes
Concurrent inbound dispatch by
@devcrocodin #884Inbound messages were processed serially on the transport read loop, so one slow or peer-awaiting handler (sampling, elicitation, roots) blocked every later message on the connection, including the responses and
notifications/cancelledthose handlers depend on. After the handshake, handlers may now run concurrently; processing stays serial during initialization.
ProtocolOptions/ClientOptions/ServerOptionsgain ahandlerCoroutineContextparameter (defaults toDispatchers.Default). Concurrency is bounded internally; there is no opt-out flag by design.RequestHandlerExtrais now aCoroutineContext.Elementand is no longer user-constructible. It exposesrequestId,method,sendRequest, andsendNotification, and can be read inside a handler via the newcurrentRequestHandlerExtra().- val extra = RequestHandlerExtra() + val extra = currentRequestHandlerExtra()Duplicate feature names are rejected at registration by
@devcrocodin #883
addTool/addPrompt/addResource/addResourceTemplatesilently replaced an existing entry and emitted a spuriouslist_changednotification. They now throwIllegalArgumentExceptionand leave the existing registration intact. The batch variants (addTools/addPrompts/addResources) are all-or-nothing. To replace a feature, remove it first.- server.addTool(name = "search", ...) // silently overwrote + server.removeTool("search") + server.addTool(name = "search", ...)
eventStoreremoved frommcpStatelessStreamableHttpby@devcrocodin #909The parameter was never read or written: a stateless endpoint answers
GETwith405, so no stream exists to store or replay events on. The old overload is retained atDeprecationLevel.ERRORwith aReplaceWithmigration hint. UsemcpStreamableHttpwhen you need resumability.application.mcpStatelessStreamableHttp( path = "/mcp", - eventStore = myEventStore, ) { server }Features
- Optional SSE heartbeats for Streamable HTTP servers via
mcpStreamableHttp(sseHeartbeatConfig = { ... }), keeping long-lived streams alive against clients that disconnect on idle. Heartbeats stay off by default, by@UnscientificJsZhaiin #761- Accepted form-mode elicitation content is now validated against
requestedSchema; a mismatch failscreateElicitationwithMcpException(INVALID_PARAMS) instead of reaching server code unchecked, by@rea9rin #896- The Streamable HTTP client now sends the standard
Mcp-MethodandMcp-NamePOST headers, by@AndreKalbererin #894Fixed
- Stateless Streamable HTTP now closes its per-request session, fixing unbounded growth of the session registry and notification subscriptions, by
@KlyneChryslerin #872- Streamable HTTP responses keep their status and body when the client accepts only
text/event-stream, by@devcrocodin #911
... (truncated)
76b8e7d
release: 0.15.0 (#918)dab340f
fix(server): drop inert eventStore from stateless Streamable HTTP (#909)24c3cd3
fix(server): match Accept header as media ranges (#912)7fa438c
feat(client): send MCP standard POST headers (#894)94745e6
chore(deps): bump the kotest group across 1 directory with 3 updates (#915)2b494b7
chore(deps): bump the other-dependencies group across 5 directories with
3 up...82fe56e
fix(server): preserve Streamable HTTP response status and body (#911)a06d699
feat: SSE heartbeat (#761)cab669b
fix: classify malformed request params as invalid params (#886)b6cb547
fix(server): preserve id on duplicate initialize errors (#868)