Removes the `eventStore` parameter from `mcpStatelessStreamableHttp`,
where it was never read or written.
closes#908
## Breaking Changes
Source-breaking only
## Types of changes
- [x] 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
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
The header is now parsed into media ranges (`parseHeaderValue` +
`ContentType.match`)
## Breaking Changes
none
## Types of changes
- [x] 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
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
Streamable HTTP responses now keep their status when the client accepts
only `text/event-stream`.
## How Has This Been Tested?
New `StreamableHttpResponseDeliveryTest`
## Breaking Changes
None
## Types of changes
- [x] 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
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Summary
Adds optional SSE heartbeat configuration for streamable HTTP MCP server
connections.
This lets `Application.mcpStreamableHttp` callers pass Ktor's
`Heartbeat` configuration for SSE streams, including heartbeat period
and event payload. Heartbeats remain disabled by default, preserving the
existing stream behavior unless the new option is explicitly provided.
## Motivation and Context
Some MCP clients need heartbeat messages on SSE connections to keep the
connection alive. Without those heartbeats, the client may proactively
disconnect from the MCP server. MCP server developers need a way to
configure an SSE heartbeat mechanism so they can avoid unexpected client
disconnects.
In my case, my MCP server was consistently disconnected by Gemini CLI. I
worked around the issue with some fallback approaches, but I believe the
best implementation is to add heartbeat support by using Ktor's built-in
API.
## Implementation Notes
- Added a function overload of `Application.mcpStreamableHttp` to
introduce heartbeat parameter `sseHeartbeatConfig: (Heartbeat.() ->
Unit)?`.
- Applied the configuration inside the Ktor `sse { ... }` block before
handling the existing streamable HTTP transport request.
- Updated the server API dump for the new public API surface.
## How Has This Been Tested?
Added `StreamableHttpHeartbeatIntegrationTest` covering:
- Configured GET SSE streams apply the provided heartbeat configuration.
- GET SSE streams do not send default heartbeats when
`sseHeartbeatConfig` is omitted.
- Configured GET SSE streams emit heartbeat events repeatedly.
- Legacy MCP over SSE APIs do not expose the new heartbeat
configuration.
Verified locally with:
```bash
./gradlew :integration-test:jvmTest --tests "io.modelcontextprotocol.kotlin.sdk.integration.streamablehttp.StreamableHttpHeartbeatIntegrationTest"
```
Result: `BUILD SUCCESSFUL`.
## Breaking Changes
None.
This change adds a new `Application.mcpStreamableHttp` overload that
accepts
`sseHeartbeatConfig: (Heartbeat.() -> Unit)?` while keeping the existing
overload
unchanged. Existing callers continue to compile and keep the previous
behavior:
SSE heartbeats are not sent unless the new overload is used with an
explicit
heartbeat configuration.
## Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Additional context
Heartbeat behavior is delegated to Ktor's SSE heartbeat support, so
applications can use the same configuration semantics they would use in
native Ktor SSE routes.
Related issue: [SSE needs a heartbeat #344
](https://github.com/modelcontextprotocol/kotlin-sdk/issues/344)
---------
Co-authored-by: Pavel Gorgulov <devcrocod@gmail.com>
## Summary
Fixes#866.
## Changes
- Preserve the parsed JSON-RPC request id when Streamable HTTP rejects a
duplicate `initialize` request.
- Keep pre-parse and transport-level rejection paths unchanged when the
request id is not available.
- Extend the duplicate-initialize regression test to assert the error
response id as well as the HTTP status.
## Verification
```bash
./gradlew :kotlin-sdk-server:jvmTest --tests 'io.modelcontextprotocol.kotlin.sdk.server.StreamableHttpServerTransportTest.second initialization request returns JSON-RPC error with request id'
./gradlew :kotlin-sdk-server:jvmTest --tests 'io.modelcontextprotocol.kotlin.sdk.server.StreamableHttpServerTransportTest'
./gradlew :kotlin-sdk-server:jvmTest
./gradlew :kotlin-sdk-server:ktlintCheck :kotlin-sdk-server:detekt
```
Co-authored-by: Pavel Gorgulov <devcrocod@gmail.com>
Reject duplicate feature registration instead of silently overwriting
the existing entry.
## Motivation and Context
`FeatureRegistry.add`/`addAll` silently replaced a feature registered
under the same key and emitted a spurious `list_changed` notification.
Tool/prompt names and resource URIs are unique identifiers in MCP, and
the TypeScript SDK already rejects duplicates at registration time
(`Tool X is already registered`).
- `addTool`/`addPrompt`/`addResource`/`addResourceTemplate` now throw
`IllegalArgumentException` on a duplicate name/URI; the existing
registration stays intact and no notification is emitted.
- `addTools`/`addPrompts`/`addResources` are all-or-nothing: batches
with intra-batch duplicates or conflicts with existing keys are rejected
without registering anything.
- To replace a feature, remove it first (`removeTool` + `addTool`),
matching the TypeScript SDK's remove-then-re-register path. No new
public API.
## How Has This Been Tested?
New `FeatureRegistryTest` unit suite (duplicate rejection, batch
atomicity, no notification on rejection, re-add after remove) plus
integration tests for tools, prompts, resources, and resource templates.
The check also surfaced a real duplicate `addResource` in
`AbstractResourceIntegrationTest`, fixed here. `jvmTest` (all modules),
`apiCheck`, `ktlintCheck`, and `detekt` pass locally.
## Breaking Changes
No public API signature changes (`apiCheck` passes against the existing
dump). Behavioral: registering a duplicate name/URI now throws
`IllegalArgumentException` instead of silently overwriting; remove the
feature first to replace it.
## Types of changes
- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
Validate accepted form-mode elicitation `content` against the
`requestedSchema` on the server, rejecting mismatches with an
`INVALID_PARAMS` error.
fixes#895
<!-- Provide a brief summary of your changes -->
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
`createElicitation` returned accepted content to server code as-is. The
specification's
form-mode security guidance says "Servers SHOULD validate received data
matches the requested
schema" ([2025-11-25, Form Mode
Security](https://modelcontextprotocol.io/specification/2025-11-25/client/elicitation#form-mode-security)).
Comparable validation already exists in the TypeScript SDK's
`elicitInput` and Python's `elicit_with_validation` helper. Details and
design notes are in #895.
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
New unit tests for the validator and integration tests over an in-memory
client–server pair.
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
No API changes. Behavioral note: an accepted form-mode response that
does not match the requested schema now fails `createElicitation` with
`McpException` (`INVALID_PARAMS`) instead of being returned to the
caller.
## Types of changes
<!-- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
Co-authored-by: Pavel Gorgulov <devcrocod@gmail.com>
fixes#786
stateless streamable http endpoint never closed its per request session,
so the session registry and notification subscriptions grew forever. now
the session is closed in a finally block after each request, which
triggers the existing cleanup. also removed the per request
server.onClose logging callback that accumulated on shared servers.
added tests proving sessions are removed after normal and rejected
requests. jvmTest, ktlint, detekt, apiCheck all pass. no public api
changes.
Co-authored-by: Pavel Gorgulov <devcrocod@gmail.com>
Make inbound message handling concurrent after the initialization
handshake, so a slow or peer-awaiting handler no longer blocks other
messages on the same connection
fixes#176, #572
## Motivation and Context
Inbound messages were processed serially on the transport read loop. One
slow or peer-awaiting request handler (sampling, elicitation, roots)
blocked every later message on that connection, including the responses
and `notifications/cancelled` those handlers depend on which could
deadlock request/response flows.
## How Has This Been Tested?
New and old tests
## Breaking Changes
- after the handshake, inbound handlers may run concurrently (processing
stays serial during initialization). There is no opt-out flag by design,
concurrency is bounded by `maxConcurrentHandlers` /
`maxInFlightHandlers`.
- `ProtocolOptions` / `ClientOptions` / `ServerOptions` gain new
parameters with defaults
- `RequestHandlerExtra` is now a coroutine-context element and is no
longer user-constructible
## Types of changes
- [x] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
Caps the size of incoming HTTP POST bodies in both server transports so
an oversized request can no longer exhaust server memory
## How Has This Been Tested?
new tests
## Breaking Changes
binary incompatible for SseServerTransport constuctors
## Types of changes
- [x] Bug fix (non-breaking change which fixes a
- [x] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would to change)
- [ ] Documentation update
## Checklist
- [x] I have read the [MCP Documentation](https:
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
Default the `Origin` allowlist to localhost when
`DnsRebindingProtection` relies on the localhost host defaults, so a
request with a valid `Host` but a hostile (or `null`) `Origin` is no
longer accepted.
## How Has This Been Tested?
unit tests
## Breaking Changes
Behavioral change only
## Types of changes
- [x] 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
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
closes#410
## How Has This Been Tested?
integration and unit tests
## Breaking Changes
none
## Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Summary
- reject empty sampling content in SamplingMessage and
CreateMessageResult constructors
- clarify sampling validation docs and emit an explicit error when
tool_use is not followed by tool_result
- return sampled text from the conformance test_sampling tool instead of
content object strings
Fixes#730
## Testing
- ./gradlew
-Dorg.gradle.java.installations.paths="/Users/ubl/Documents/New
project/oss-contributions/.jdks/jdk-21.0.11+10/Contents/Home"
:kotlin-sdk-core:jvmTest :kotlin-sdk-server:jvmTest
:conformance-test:compileKotlin
Co-authored-by: Pavel Gorgulov <devcrocod@gmail.com>
fixes#573fixes#574fixes#708
- Handlers ran on `Dispatchers.IO` → now `Dispatchers.Default`,
configurable via `handlerDispatcher`.
- Reader/writer dispatcher exposed as `ioDispatcher` (default
`IODispatcher.limitedParallelism(2)`).
- Optional caller-supplied `CoroutineScope` so the pipeline isn't
detached from the caller's tree.
- `CancellationException` consistently rethrown across all pumps.
- Unbounded channels → bounded with graceful drain on close (in-flight
outbound flushed before `onClose`).
- Input `Source` now closed on natural EOF / reader error (was leaking
for non-`System.in` sources).
- Race between `start()` and `close()` fixed via 3-state CAS +
`setupComplete` barrier replacing `AtomicBoolean`.
## How Has This Been Tested?
unit and integration tests
## Breaking Changes
- Handlers default to `Dispatchers.Default` (was `Dispatchers.IO`).
Override with `handlerDispatcher = Dispatchers.IO` if your handlers
perform blocking I/O.
- `send()` suspends under back-pressure instead of buffering unbounded.
- `StdioServerTransport(input, output)` ctor is `@Deprecated` (WARNING)
in favor of `StdioServerTransport(input, output) { ... }`. Still
binary-compatible.
## Types of changes
- [x] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
closes#544
Replaces opaque `JsonObject?` modelling of `elicitation` with a typed
`ClientCapabilities.Elicitation` (`form`, `url`), and adds the new
`tasks` capability on both `ClientCapabilities` and `ServerCapabilities`
(with `list`, `cancel`, per-request-type augmentation). Wires capability
assertions for `tasks/*` methods and `notifications/tasks/status` into
`Client` and `ServerSession`
## How Has This Been Tested?
unit tests
## Breaking Changes
yes
now elicitation is a specific class in capabilities
## Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
Add `DnsRebindingProtection` Ktor route-scoped plugin and enable it by
default across all http transports
## Motivation and Context
DNS rebinding protection was disabled by default
(`enableDnsRebindingProtection = false`), and sse endpoints
(`Route.mcp()`) had zero protection. Same vulnerability as typescript
sdk
[GHSA-w48q-cv73-mx4w](https://github.com/modelcontextprotocol/typescript-sdk/security/advisories/GHSA-w48q-cv73-mx4w)
## How Has This Been Tested?
all tests pass
## Breaking Changes
- `Route.mcp()`, `Application.mcp()` signatures changed (new
`enableDnsRebindingProtection`, `allowedHosts`, `allowedOrigins`
params), binary incompatible on JVM
- `enableDnsRebindingProtection` default changed from `false` to `true`
on `mcpStreamableHttp`/`mcpStatelessStreamableHttp`
- Default allowed hosts: `localhost`, `127.0.0.1`, `[::1]` — opt out
with `enableDnsRebindingProtection = false`
- Host validation is now port-agnostic (matches ts sdk)
- Origin validation now allows missing `Origin` header (non-browser
clients)
- `Configuration.enableDnsRebindingProtection`, `.allowedHosts`,
`.allowedOrigins` deprecated in favor of the plugin
## Types of changes
- [x] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
Migrate detekt to a convention plugin in `buildSrc`, switch the project
to a fully explicit YAML config (`buildUponDefaultConfig = false`), fix
the real findings that this stricter setup revealed, and remove
`@Suppress` annotations that became unnecessary after the rule changes.
## Motivation and Context
- Explicit visibility into the rule set
- Lock against detekt version upgrades
## Breaking Changes
None
## Types of changes
- [x] 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)
- [x] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Motivation and Context
When a GET SSE stream disconnects and the client reconnects on the same
session, the new GET is silently rejected because the previous stream's
`STANDALONE_SSE_STREAM_ID` entry in `streamsMapping` hasn't been cleaned
up yet. Cleanup via `invokeOnCompletion` is asynchronous — there is a
race window where the stale entry persists and blocks reconnection.
Additionally, Ktor's `sse {}` handler commits 200 OK headers before
`handleGetRequest` runs, so the intended
`call.reject(HttpStatusCode.Conflict, ...)` cannot change the
already-committed HTTP status. On all tested engines (test host, CIO,
Netty), clients receive a 200 OK with an immediately-closed empty SSE
stream rather than a 409 Conflict. Server-side `CallLogging` reports 409
(from the response object, not the wire status), which is misleading.
### What this PR does
1. **Explicitly closes the old SSE session** before establishing a new
stream. If the old session is already dead, `close()` is a no-op. This
is the synchronous cleanup that the async `invokeOnCompletion` couldn't
provide.
2. **Replaces `invokeOnCompletion` with `try/finally`** around
`awaitCancellation()` — cleanup runs during cancellation propagation
(earlier in the lifecycle) rather than after job completion. An identity
check (`=== newContext`) ensures only this stream's entry is removed,
not a replacement's.
3. **Adds identity-based removal in `emitOnStream`** — a failed `send()`
on an old stream can no longer accidentally evict the new stream's
mapping.
4. **Rethrows `CancellationException`** instead of swallowing it,
preserving structured concurrency.
The TypeScript reference implementation avoids this race via synchronous
`ReadableStream.cancel()` cleanup. The Kotlin coroutine equivalent
(`invokeOnCompletion`) is inherently async. The Go SDK uses `defer
stream.release()` under a mutex for the same reason. The Java SDK uses
unconditional `AtomicReference.set()` replacement with
`compareAndExchange` on close.
Fixes#715
## How Has This Been Tested?
All tests run against latest `main` (`bf8dc6d`). ktlint and detekt pass
clean.
- 2 new unit tests (Ktor test host): reconnect after disconnect,
concurrent stream takeover
- 2 new integration tests (real CIO embedded server): same scenarios
over real HTTP
- Manual verification against a live Ktor+Netty MCP server (curl):
confirmed 200 OK on the wire with immediately-closed stream on reconnect
(pre-fix), live stream on reconnect (post-fix)
- All existing server unit tests pass (76 total)
- All existing integration tests pass (306 total)
## Breaking Changes
The server no longer returns 409 Conflict for a second GET SSE stream on
the same session. Instead, the old stream is explicitly closed and the
new stream takes over. The 409 was already unreachable as an HTTP status
— Ktor's `sse {}` handler commits 200 OK before the transport handler
runs on all tested engines (test host, CIO, Netty), so clients never
received 409 on the wire.
## Types of changes
- [x] 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
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Additional context
This bug likely became reachable after #681 (April 10) fixed the Netty
`appendSseHeaders` crash that previously prevented GET SSE from working
at all on Netty.
Cross-SDK comparison of how each SDK handles a second GET SSE on the
same session:
| SDK | Behavior | Cleanup mechanism | Stale mapping bug? |
|-----|----------|-------------------|-------------------|
| TypeScript (reference) | 409 Conflict | Synchronous
`ReadableStream.cancel()` | No |
| Go | 409 Conflict | `defer stream.release()` under mutex | No |
| Java | Replaces (no 409) | `AtomicReference.set()` +
`compareAndExchange` on close | No |
| C# | 400 Bad Request | Boolean flag, never reset (no reconnect
support) | No |
| Kotlin (before fix) | 409 (unreachable on wire) | Async
`invokeOnCompletion` | **Yes** |
| Kotlin (this PR) | Closes old + replaces | `try/finally` +
identity-based removal | No |
---------
Co-authored-by: devcrocod <devcrocod@gmail.com>
Implements SEP-1577 sampling With tools
closes#409
## How Has This Been Tested?
unit + integration
## Breaking Changes
- binary changes
- MediaContent -> SamplingMessageContent
-
## Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
fixes#242
## How Has This Been Tested?
new and existing tests pass
## Breaking Changes
none
## Types of changes
- [x] 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
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
Validate `mcp-protocol-version` HTTP header during `InitializeRequest`
Fix `DEFAULT_NEGOTIATED_PROTOCOL_VERSION` to match the spec
fixes#547
## How Has This Been Tested?
Updated existing test (removed TODO referencing #547) to verify init
request
## Breaking Changes
none
## Types of changes
- [x] 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
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
Add warn-only validation for tool names at registration time, following
the MCP tool naming standard (SEP-986)
closes#417
## How Has This Been Tested?
unit tests
## Breaking Changes
none
## Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
`appendSseHeaders()` was called inside Ktor's `sse {}` block where
response headers are already committed. On Netty this throws
`UnsupportedOperationException`, killing the SSE stream and causing the
client to retry in a loop
## How Has This Been Tested?
unit, simple-streamable-server sample
## Breaking Changes
none
## Types of changes
- [x] 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
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x ] I have added appropriate error handling
- [ x] I have added or updated documentation as needed
- enable rule for checking undocumented public api
- add kdoc skill
## How Has This Been Tested?
./gradlew detekt
## Breaking Changes
none
## 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)
- [x] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [ ] I have added appropriate error handling
- [x] I have added or updated documentation as needed
---------
Co-authored-by: Konstantin Pavlov <1517853+kpavlov@users.noreply.github.com>
closes#546
## How Has This Been Tested?
unit
## Breaking Changes
none
## Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [ ] I have added appropriate error handling
- [ ] I have added or updated documentation as needed
Users currently must manually `install(ContentNegotiation) {
json(McpJson) }` before calling `mcp()`,
`mcpStreamableHttp()`, or `mcpStatelessStreamableHttp()`. Forgetting
this or using the default `json()`
instead of `json(McpJson)` causes silent serialization failures at
runtime (e.g., explicit null fields in JSON-RPC
responses). This PR makes the SDK install it automatically.
Fixes#664
## Changes
- **Core feature** — `mcp()`, `mcpStreamableHttp()`, and
`mcpStatelessStreamableHttp()` now auto-install `ContentNegotiation`
configured with `McpJson`. If the user already installed
`ContentNegotiation`, a warning is logged instead of crashing with
`DuplicatePluginException`.
- **`KtorServerHelpers.kt`** (new) — `installMcpContentNegotiation()`
internal helper with `pluginOrNull` guard and warning
- **`KtorServer.kt`** — calls the helper from all three entry points
- **`build.gradle.kts`** — adds `ktor-server-content-negotiation` and
`ktor-serialization` as `implementation` deps to `kotlin-sdk-server`
- **Removed manual installs** from `ConformanceServer.kt` and
`AbstractStreamableHttpIntegrationTest.kt`.
- **Test infrastructure** — replaced `slf4j-simple` with Logback and use
`ListAppender` (`LogCapture` utility) for deterministic log assertion.
Added `logback-test.xml` matching previous log levels.
- **`StreamableHttpServerConfigurationTest.kt`** (new) — verifies the
warning for all three entry points: `mcpStreamableHttp`,
`mcpStatelessStreamableHttp`, and `mcp` (SSE).
- **README.md** — removed manual `ContentNegotiation` boilerplate from
examples, documented automatic installation, added CORS configuration
snippet for browser-based clients.
- **CI** — added `ktlintCheck` to the Linux build matrix job.
## How Has This Been Tested?
Unit/integration tests. Conformance tests updated
## Breaking Changes
No
## Types of changes
- [x] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [x] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## 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
```bash
./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)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
Add URL mode elicitation support and typed `PrimitiveSchemaDefinition`
hierarchy to align with MCP specification 2025-11-25
closes#540
## How Has This Been Tested?
unit/integration/conformance
## Breaking Changes
- `ElicitRequestParams` changed from `data class` to `sealed interface`.
A deprecated factory function preserves source compatibility for
`ElicitRequestParams(message, requestedSchema)`.
- `RequestedSchema.properties` changed from `JsonObject` to `Map<String,
PrimitiveSchemaDefinition>`.
- `ElicitRequest.requestedSchema` is deprecated, use `(params as
ElicitRequestFormParams).requestedSchema`.
## Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
`ServerSession.handleInitialize()` now rejects duplicate `initialize`
requests with `INVALID_REQUEST` (-32600) error. `clientCapabilities` and
`clientVersion` changed from `var` to `AtomicRef`-backed `val`, with
atomic `compareAndSet(null, ...)` serving as both the guard and the
write
## How Has This Been Tested?
second `initialize` returns error, original capabilities preserved
## Breaking Changes
none
## Types of changes
- [x] 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
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
Remove all deprecation with error level
## Motivation and Context
next minor release
## How Has This Been Tested?
-
## Breaking Changes
Removing it is a binary-incompatible change
## 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
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Changes
- fix(server): keep SSE connection open until explicitly cancelled
- conformance: add logging to test_tool_with_logging and update
troubleshooting documentation
- chore(conformance): remove 5 passing server tests from conformance
baselines:
- tools-call-with-logging
- tools-call-with-progress
- tools-call-sampling
- tools-call-elicitation
- elicitation-sep1034-defaults
## Motivation and Context
Two bugs in StreamableHttpServerTransport caused server-to-client
notifications (e.g. notifications/message during tool calls) to be
silently dropped.
**Bug 1 — GET SSE stream closed immediately**
`handleGetRequest` rejected GET requests with 405 when
`enableJsonResponse = true` (which `mcpStreamableHttp` always sets).
Since the Ktor `sse {}` handler commits response headers before the body
runs, the reject failed silently and the function returned, causing Ktor
to close the SSE stream. There was also no `awaitCancellation()` to keep
the connection alive.
**Bug 2 — Notifications discarded in JSON mode**
In `send()`, notifications with a relatedRequestId entered the
POST-stream path but hit `if (!isTerminated) return` without being
forwarded anywhere.
**Fix**
- Remove the enableJsonResponse guard from handleGetRequest. The GET SSE
stream is an always-required notification channel, orthogonal to how
POST responses are delivered.
- Add `awaitCancellation()` to keep the GET SSE connection open until
the client disconnects or the transport closes.
- In `send()`, route notifications with a relatedRequestId to the
standalone GET SSE stream when `enableJsonResponse = true`.
## How Has This Been Tested?
Verified against the MCP conformance test suite — the
ToolsCallWithLogging scenario now passes. ngrep confirms the `GET /mcp`
stream stays open and `notifications/message` events arrive before the
`tools/call` response.
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
## Types of changes
<!-- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->
- [x] 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
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] 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
## Additional context
Fixes#587
Requires #585 to be merged first.
---------
Co-authored-by: devcrocod <devcrocod@gmail.com>
Adds a comprehensive conformance test suite for the Kotlin MCP SDK,
covering core protocol operations, tool calls, elicitation, resources,
prompts, and 20 OAuth/auth scenarios
- Conformance server and client implementations
- OAuth/auth test scenarios: JWT, authorization code flow, client
credentials, PKCE, scope handling, cross-app access, client registration
- CI workflow
- Baseline file for tracking expected failures
- Shell script
fixes:
- #592
- #593
- #596
## Remaining known failures (tracked issues, will be fixed directly in
`main`)
- [x] `tools-call-with-logging`, `tools-call-with-progress`,
`tools-call-sampling`, `tools-call-elicitation`,
`elicitation-sep1034-defaults`- see #599,
- [x] `elicitation-sep1330-enums` - #587#600
- [x] `initialize` - #588
- [x] `tools_call`, `auth/scope-step-up`, `auth/scope-retry-limit` -
#589
- [ ] `elicitation-sep1034-client-defaults` - #414
- [x] `sse-retry` - #590
- [ ] `resources-templates-read` - #591
## Breaking Changes
from #596
- `StreamableHttpClientTransport` and
`mcpStreamableHttp`/`mcpStreamableHttpTransport`: old constructors
accepting `Duration` timeout are now `@Deprecated` — use the new
overloads with `ReconnectionOptions` instead
- `StreamableHttpClientTransport.close()` no longer calls
`terminateSession()` automatically
## Types of changes
- [x] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
---------
Co-authored-by: Konstantin Pavlov <1517853+kpavlov@users.noreply.github.com>
closes#543
## How Has This Been Tested?
unit
## Breaking Changes
binary compatibility in the Tool class
## Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [ ] I have added appropriate error handling
- [ ] I have added or updated documentation as needed
---------
Co-authored-by: Konstantin Pavlov <1517853+kpavlov@users.noreply.github.com>
## Rethrow CancellationException in StdioServerTransport, fix ReadBuffer
### Changes
1. StdioServerTransport
- Replace generic `Throwable` catches with specific
`CancellationException` and `Exception` for clarity and correctness.
**breaking change** `Throwable` is not handled any more!
- Refactor launching jobs to separate methods
- Introduce `READ_BUFFER_SIZE` constant to replace inline buffer size
literals.
- Add suppress annotations for clearer intent and constructor
documentation for better usability.
- Extend StdioServerTransportTest
2. ReadBuffer
Previously, readMessage() returned null after consuming an unparseable
line even when more complete lines existed in the buffer. This caused
valid messages following a bad line in the same chunk to be silently
dropped until the next chunk arrived (or forever, in tests).
Fix the loop so null means only "no complete line available", not
"encountered a parse failure". Blank/whitespace-only lines are now
silently skipped via isBlank() rather than forwarded to the deserializer
and logged as errors.
Refactor the method into three focused helpers:
- readMessage() — outer loop over lines
- readLine() — consume the next newline-delimited line from the buffer
- tryRecover() — attempt deserialization from the first '{' onward
3. Add utility method `runIntegrationTest` for integration testing
(`runBlocking` + `withTimeout`). Use it in StdioServerTransportTest
4. Store processing Job reference and `calcelAndJoin()` it on close.
Partially addressing #574
## Motivation and Context
See #575, #564, #242
## How Has This Been Tested?
Unit test added
## Breaking Changes
Semantic change: `Throwable` and CancellationException are not handled
any more!
## Types of changes
- [x] 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
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [ ] I have added appropriate error handling
- [ ] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
## 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 #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
<!-- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [ ] I have added appropriate error handling
- [ ] I have added or updated documentation as needed
## Motivation and Context
Adds a `ClientConnection` context receiver to server call handlers,
which provides access to the client communication channel. This is
necessary to allow tools to send notifications, logging, elicitations,
etc.
Supersedes https://github.com/modelcontextprotocol/kotlin-sdk/pull/144,
discussed in
https://github.com/modelcontextprotocol/kotlin-sdk/issues/295.
## How Has This Been Tested?
With the added integration test.
## Breaking Changes
It breaks binary compatibility and breaks source compatibility for tool
handlers that already use `this`.
If you care a lot about maintaining compatibility, I could add some
overloads to ease the transition. But the new methods would likely need
to be named differently for resolution.
Future compatibility should be easier to maintain - `Context` is an
interface (with experimental opt-in subclassing), so new fields can be
added without breaking compatibility. Different types could also be
introduced for different handles without breaking compatibility, as long
as they extend `ClientConnection`.
## Types of changes
<!-- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
---------
Co-authored-by: Konstantin Pavlov <1517853+kpavlov@users.noreply.github.com>
# Migrate Ktor extension functions from `Routing` to `Route` (#237)
- Replaced `Routing` with `Route` in MCP-related functions for better
composability in nested contexts.
- Updated tests to verify compatibility with nested routes and subpaths.
- Deprecated legacy signatures and removed redundant overloads.
## How Has This Been Tested?
Unit test
## Breaking Changes
`Routing.mcp(...) `extension was replaced with `Route.mcp(...)`
## Types of changes
- [X] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] 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
## Additional context
Based on #314 by @IainHull but that PR is too outdated.
# Detekt setup hardeing; address some issues
- Address some detekt findings: missing KDocs, formatting, use `check*`
& `orEmpty()``
- Remove unnecessary KDoc comments from deprecated classes in `types.kt`
- Add Detekt baseline XML files for all modules
- Enforce stricter Detekt rules by setting `failOnSeverity` from `None`
to `Error`
## Motivation and Context
Detekt is not actually failing the build on violations. This PR is
enabling Detekt to fail on errors. Baseline fines added for historical
issues. Follow-up for #501
## How Has This Been Tested?
Regressions
## Breaking Changes
No breaking changes.
## Types of changes
<!-- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] Refactoring
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [x] Documentation update
## Checklist
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [ ] I have added appropriate error handling
- [ ] I have added or updated documentation as needed
## refactor: Introduce AbstractClientTransport and simplify client
transport lifecycle
This PR unifies state management logic across client transports, except
for the websocket transport, as it needs more refactoring first and is
not the primary transport.
- Introduce `AbstractClientTransport` as base class for other client
transports.
- Migrate to `ClientTransportState` states with state machine,
streamline state management.
- Ensure proper cleanup and error handling consistency across transport
implementations.
- Add unit tests to validate `AbstractClientTransport` behavior and
state transitions.
- Update related documentation and API contract.
- Make sure `onClose` callback is called at most once
- fix
[StreamableHttpClientTransportTest.kt](https://github.com/modelcontextprotocol/kotlin-sdk/pull/516/changes#diff-b9fe8891d08a492448a7ed2dc782151c6a915ae1403a4d70c2034c6062c84cb5)
to throw `McpException` on connect when received invalid Json
## Motivation and Context
Unify lifecycle handling and eliminate duplication in client Transport
implementations.
## How Has This Been Tested?
Unit test, regression tests
## Breaking Changes
- `onClose` callback is now called only once
- send(...) will throw McpException with message "Transport is not
ready" when `ClientTransportState != Operational`
## Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] Refactoring
- [ ] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] 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
## Additional context
See #517
## Motivation and Context
Adds Ktor extensions for streaming data over the server-side HTTP
transport
## How Has This Been Tested?
Integration test
## Breaking Changes
-
## Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
#162
## Motivation and Context
- update readme
- add more snippets
- add knit
## How Has This Been Tested?
knit on CI
## Breaking Changes
None
## 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)
- [x] Documentation update
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [ ] I have added appropriate error handling
- [x] I have added or updated documentation as needed
---------
Co-authored-by: devcrocod <devcrocod@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- increase the deprecation level
- remove tests that use deprecated objects with deprecation level =
error
## Motivation and Context
deprecation lifecycle
## How Has This Been Tested?
-
## Breaking Changes
-
## 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
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [ ] I have added appropriate error handling
- [ ] I have added or updated documentation as needed
- generate detekt config
- enable several rules
- disable ktlint backing property check
## Motivation and Context
Centralized control of detekt rules. Using detekt 2 configuration
## How Has This Been Tested?
locally
## Breaking Changes
-
## 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
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [ ] I have added appropriate error handling
- [ ] I have added or updated documentation as needed
# Update/Fix build workflow
- `macos-latest-xlarge` is no longer available. Switch to cheaper
runner: `macos-latest-xlarge` -> `macos-latest`
- Refactor build to run matrix job under Linux and macOS
- Tune caching GH caching
- Add junit and logger properties
- Downgrade Junit to 5.14.2
- Extract `ProcessBuilder` creation logic into helper functions
- Disable `StdioClientTransportTest` on windows temporary
## How Has This Been Tested?
CI
## Breaking Changes
Functionally - no. Outdated/broken TypeScript tests were disabled
## Types of changes
<!-- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->
- [x] Bug fix (non-breaking change which fixes an issue)
- [x] CI Update
## Checklist
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [ ] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [ ] 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
## Additional context
GitHub actions workflows were blocked because the selected
"macos-latest-xlarge" runner, which is not available for the free
open-source plan. With "macos-latest" workflow works.