kotlin-sdk/samples/kotlin-mcp-client
Repository files (latest commit first)
Filename Latest commit message Latest commit date
dependabot[bot] c59b87f273
chore(deps): bump io.ktor:ktor-bom from 3.3.3 to 3.5.1 in /samples/kotlin-mcp-client (#859)
Bumps [io.ktor:ktor-bom](https://github.com/ktorio/ktor) from 3.3.3 to
3.5.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/ktorio/ktor/releases">io.ktor:ktor-bom's
releases</a>.</em></p>
<blockquote>
<h2>3.5.1</h2>
<blockquote>
<p>Published 25 June 2026</p>
</blockquote>
<h3>Improvements</h3>
<ul>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9492">KTOR-9492</a>
OpenAPI plugin: handle requireXxx functions in compiler plugin</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9569">KTOR-9569</a> Add
more details for KDoc of BearerAuthConfig.sendWithoutRequest</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9571">KTOR-9571</a> Add
KDoc for BearerAuthConfig.realm</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9570">KTOR-9570</a> Add
Kdoc for BearerAuthConfig.refreshTokens</li>
</ul>
<h3>Bugfixes</h3>
<ul>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9646">KTOR-9646</a> Fix
Kotlin 2.4.0 compiler plugin breaking changes</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9585">KTOR-9585</a>
OpenAPI: JsonSchema title is truncated when it contains a dot</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9591">KTOR-9591</a>
OpenAPI: <code>@JsonClassDiscriminator</code> on sealed types is ignored
when generating OpenAPI discriminator schema</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9597">KTOR-9597</a>
OpenAPI: Schema name collisions because<code>@SerialName</code> of
sealed subtypes is used as <code>components.schemas</code> key</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9601">KTOR-9601</a>
OpenAPI: nullable <a
href="https://github.com/JvmInline"><code>@​JvmInline</code></a> value
class loses nullability in generated schema</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9620">KTOR-9620</a> Some
issues related to digest authentication in 3.5.0</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9623">KTOR-9623</a>
Digest Auth: server must respond with one WWW-Authenticate header for
each supported algorithm</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9624">KTOR-9624</a>
Digest Auth: &quot;Unsupported charset in digest authentication
header&quot; for a charset name in lowercase</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9630">KTOR-9630</a>
Digest Auth: The plugin sends incorrect nonce when server responds with
multiple WWW-Authenticate headers</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9565">KTOR-9565</a>
WebRTC: Peer stops receiving messages after a while on iOS</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9610">KTOR-9610</a>
WebRtcPeerConnection::close causes ClosedReceiveChannelException for
other peer</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9633">KTOR-9633</a>
WebRTC statistics fetching race condition</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9603">KTOR-9603</a>
Structured concurrency is violated in WebRTC tests</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9671">KTOR-9671</a>
Darwin: Semicolons in URL path are sanitized</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9639">KTOR-9639</a>
Darwin: WebSocket client crashes the process when a PONG arrives after
the session is closed</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9575">KTOR-9575</a>
Darwin: findCharset(&quot;UTF-16&quot;) maps to
NSUTF16LittleEndianStringEncoding causing decoding failure for UTF-16
content with BOM</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9661">KTOR-9661</a>
HttpCache: InvalidCacheStateException is thrown on 304 when no cached
entry matches varyKeys</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9673">KTOR-9673</a>
Caching always missing with Content Negotiation</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9596">KTOR-9596</a>
HttpTimeout: HttpRequestTimeoutException on any request with runTest and
request timeout defined since 3.5.0</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9632">KTOR-9632</a>
HttpRequestBuilder.timeout call removes capabilities set in
DefaultRequest</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9252">KTOR-9252</a>
ContentEncoding: Incomplete gzip response causes client/server to hang
indefinitely</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9670">KTOR-9670</a>
Compression: The plugin ignores Accept-Encoding q=0 and most-specific
matching</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9614">KTOR-9614</a> Zstd
Compression: &quot;Destination buffer is too small&quot; exception for a
particular sequence of bytes</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9636">KTOR-9636</a> CORS
plugin drops OPTIONS preflight requests when allowSameOrigin is on</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9659">KTOR-9659</a> CORS
is skipped when the Origin header contains an IPv6 address</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9574">KTOR-9574</a>
ContentNegotiation: The charset of <code>Accept-Charset</code> header is
used for response deserialization</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9606">KTOR-9606</a>
KotlinxSerializationConverter: it fails to deserialize an empty channel
closed with a delay</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9617">KTOR-9617</a>
OutputStreamContent and WriterContent can exhaust Dispatchers.IO</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9629">KTOR-9629</a>
RawSourceChannel: coroutine cancellation is not propagated to the
RawSource</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-8870">KTOR-8870</a>
File.readChannel: do not close a non-opened file and ignore closing
exceptions</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9460">KTOR-9460</a>
Curl: Can't build shared library with Ktor 3.4.2</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9607">KTOR-9607</a>
Crash on Android 7: NoSuchMethodError getInstanceStrong() since
3.5.0</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9595">KTOR-9595</a> CIO:
The engine imports <code>node:net</code> statically and breaks
wasmJsBrowser webpack build</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9615">KTOR-9615</a>
Apache5: The underlying request is not aborted when coroutine Job is
cancelled</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-8443">KTOR-8443</a>
RoutingBuilder.contentType does not use parameters when matching</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9425">KTOR-9425</a>
SessionTransportTransformerEncrypt init block uses wrong IV size for
AES-256 (regression of KTOR-661)</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9621">KTOR-9621</a>
RateLimit plugin is bypassed when the nested authenticate block rejects
the request</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-8766">KTOR-8766</a> DI:
The close method is called twice on cleanup of AutoCloseable</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-8695">KTOR-8695</a>
GMTDate() being offset by 369 years on Windows</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9589">KTOR-9589</a>
Duplicate PROPERTY_SETTER target in <code>@InternalAPI</code>
annotation</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/ktorio/ktor/blob/main/CHANGELOG.md">io.ktor:ktor-bom's
changelog</a>.</em></p>
<blockquote>
<h1>3.5.1</h1>
<blockquote>
<p>Published 25 June 2026</p>
</blockquote>
<h3>Improvements</h3>
<ul>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9492">KTOR-9492</a>
OpenAPI plugin: handle requireXxx functions in compiler plugin</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9569">KTOR-9569</a> Add
more details for KDoc of BearerAuthConfig.sendWithoutRequest</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9571">KTOR-9571</a> Add
KDoc for BearerAuthConfig.realm</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9570">KTOR-9570</a> Add
Kdoc for BearerAuthConfig.refreshTokens</li>
</ul>
<h3>Bugfixes</h3>
<ul>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9646">KTOR-9646</a> Fix
Kotlin 2.4.0 compiler plugin breaking changes</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9585">KTOR-9585</a>
OpenAPI: JsonSchema title is truncated when it contains a dot</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9591">KTOR-9591</a>
OpenAPI: <code>@JsonClassDiscriminator</code> on sealed types is ignored
when generating OpenAPI discriminator schema</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9597">KTOR-9597</a>
OpenAPI: Schema name collisions because<code>@SerialName</code> of
sealed subtypes is used as <code>components.schemas</code> key</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9601">KTOR-9601</a>
OpenAPI: nullable <a
href="https://github.com/JvmInline"><code>@​JvmInline</code></a> value
class loses nullability in generated schema</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9620">KTOR-9620</a> Some
issues related to digest authentication in 3.5.0</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9623">KTOR-9623</a>
Digest Auth: server must respond with one WWW-Authenticate header for
each supported algorithm</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9624">KTOR-9624</a>
Digest Auth: &quot;Unsupported charset in digest authentication
header&quot; for a charset name in lowercase</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9630">KTOR-9630</a>
Digest Auth: The plugin sends incorrect nonce when server responds with
multiple WWW-Authenticate headers</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9565">KTOR-9565</a>
WebRTC: Peer stops receiving messages after a while on iOS</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9610">KTOR-9610</a>
WebRtcPeerConnection::close causes ClosedReceiveChannelException for
other peer</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9633">KTOR-9633</a>
WebRTC statistics fetching race condition</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9603">KTOR-9603</a>
Structured concurrency is violated in WebRTC tests</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9671">KTOR-9671</a>
Darwin: Semicolons in URL path are sanitized</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9639">KTOR-9639</a>
Darwin: WebSocket client crashes the process when a PONG arrives after
the session is closed</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9575">KTOR-9575</a>
Darwin: findCharset(&quot;UTF-16&quot;) maps to
NSUTF16LittleEndianStringEncoding causing decoding failure for UTF-16
content with BOM</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9661">KTOR-9661</a>
HttpCache: InvalidCacheStateException is thrown on 304 when no cached
entry matches varyKeys</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9673">KTOR-9673</a>
Caching always missing with Content Negotiation</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9596">KTOR-9596</a>
HttpTimeout: HttpRequestTimeoutException on any request with runTest and
request timeout defined since 3.5.0</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9632">KTOR-9632</a>
HttpRequestBuilder.timeout call removes capabilities set in
DefaultRequest</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9252">KTOR-9252</a>
ContentEncoding: Incomplete gzip response causes client/server to hang
indefinitely</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9670">KTOR-9670</a>
Compression: The plugin ignores Accept-Encoding q=0 and most-specific
matching</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9614">KTOR-9614</a> Zstd
Compression: &quot;Destination buffer is too small&quot; exception for a
particular sequence of bytes</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9636">KTOR-9636</a> CORS
plugin drops OPTIONS preflight requests when allowSameOrigin is on</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9659">KTOR-9659</a> CORS
is skipped when the Origin header contains an IPv6 address</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9574">KTOR-9574</a>
ContentNegotiation: The charset of <code>Accept-Charset</code> header is
used for response deserialization</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9606">KTOR-9606</a>
KotlinxSerializationConverter: it fails to deserialize an empty channel
closed with a delay</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9617">KTOR-9617</a>
OutputStreamContent and WriterContent can exhaust Dispatchers.IO</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9629">KTOR-9629</a>
RawSourceChannel: coroutine cancellation is not propagated to the
RawSource</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-8870">KTOR-8870</a>
File.readChannel: do not close a non-opened file and ignore closing
exceptions</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9460">KTOR-9460</a>
Curl: Can't build shared library with Ktor 3.4.2</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9607">KTOR-9607</a>
Crash on Android 7: NoSuchMethodError getInstanceStrong() since
3.5.0</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9595">KTOR-9595</a> CIO:
The engine imports <code>node:net</code> statically and breaks
wasmJsBrowser webpack build</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9615">KTOR-9615</a>
Apache5: The underlying request is not aborted when coroutine Job is
cancelled</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-8443">KTOR-8443</a>
RoutingBuilder.contentType does not use parameters when matching</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9425">KTOR-9425</a>
SessionTransportTransformerEncrypt init block uses wrong IV size for
AES-256 (regression of KTOR-661)</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9621">KTOR-9621</a>
RateLimit plugin is bypassed when the nested authenticate block rejects
the request</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-8766">KTOR-8766</a> DI:
The close method is called twice on cleanup of AutoCloseable</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-8695">KTOR-8695</a>
GMTDate() being offset by 369 years on Windows</li>
<li><a
href="https://youtrack.jetbrains.com/issue/KTOR-9589">KTOR-9589</a>
Duplicate PROPERTY_SETTER target in <a
href="https://github.com/InternalAPI"><code>@​InternalAPI</code></a>
annotation</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5ba9d6fdf1"><code>5ba9d6f</code></a>
Release 3.5.1 (<a
href="https://redirect.github.com/ktorio/ktor/issues/5719">#5719</a>)</li>
<li><a
href="a4f145d16d"><code>a4f145d</code></a>
KTOR-9661 HttpCache: InvalidCacheStateException is thrown on 304 when…
(<a
href="https://redirect.github.com/ktorio/ktor/issues/5701">#5701</a>)</li>
<li><a
href="2caf27824c"><code>2caf278</code></a>
Fix failing :ktor-io:compileDarwinMainKotlinMetadata (<a
href="https://redirect.github.com/ktorio/ktor/issues/5716">#5716</a>)</li>
<li><a
href="257de90b60"><code>257de90</code></a>
KTOR-8766 Fix multiple invocations of close from DI</li>
<li><a
href="e77a16813c"><code>e77a168</code></a>
Fix cache misses with content negotiation 3x (<a
href="https://redirect.github.com/ktorio/ktor/issues/5714">#5714</a>)</li>
<li><a
href="ed22950b63"><code>ed22950</code></a>
Make huge post test less huge</li>
<li><a
href="f329069ed4"><code>f329069</code></a>
Update dependency com.github.luben:zstd-jni to v1.5.7-11</li>
<li><a
href="6ecd072937"><code>6ecd072</code></a>
Update dependency io.swagger.parser.v3:swagger-parser to v2.1.44</li>
<li><a
href="a0534cd2e6"><code>a0534cd</code></a>
Update dependency io.pebbletemplates:pebble to v4.1.2</li>
<li><a
href="8647e53f4b"><code>8647e53</code></a>
Update dependency com.typesafe:config to v1.4.9</li>
<li>Additional commits viewable in <a
href="https://github.com/ktorio/ktor/compare/3.3.3...3.5.1">compare
view</a></li>
</ul>
</details>
<br />

<details>
<summary>Most Recent Ignore Conditions Applied to This Pull
Request</summary>

| Dependency Name | Ignore Conditions |
| --- | --- |
| io.ktor:ktor-bom | [>= 3.4.a, < 3.5] |
</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-02 12:34:29 +02:00
..
gradle chore(deps): bump io.ktor:ktor-bom from 3.3.3 to 3.5.1 in /samples/kotlin-mcp-client (#859) 2026-07-02 12:34:29 +02:00
src/main docs: update client and server samples (#598) 2026-03-13 10:23:51 +01:00
build.gradle.kts Add Ktor BOM for dependency management across all modules, run Kotlin-MCP-Server Sample (#367) 2025-11-04 11:44:39 +02:00
gradle.properties #302 Update samples build workflow (#330) 2025-10-23 13:02:22 +03:00
gradlew chore(deps): bump the other-dependencies group across 5 directories with 3 updates (#854) 2026-06-24 15:31:46 +02:00
gradlew.bat chore(deps): bump the other-dependencies group across 5 directories with 3 updates (#854) 2026-06-24 15:31:46 +02:00
README.md docs: streamable server sample (#595) 2026-03-10 12:45:21 +01:00
settings.gradle.kts #302 Update samples build workflow (#330) 2025-10-23 13:02:22 +03:00

Kotlin MCP Client

An interactive CLI client that connects to any MCP server over STDIO and pipes queries through Anthropic's Claude API.

Overview

This sample demonstrates a complete MCP client workflow: launching an MCP server as a subprocess, discovering its tools, converting them to Anthropic's tool format, and running an interactive chat loop where Claude can call server tools on behalf of the user.

Prerequisites

  • JDK 17+
  • An ANTHROPIC_API_KEY environment variable set with a valid Anthropic API key
  • An MCP server script to connect to (.js, .py, or .jar)

Build & Run

Run the client, passing the path to an MCP server:

# Connect to a JVM server
./gradlew run --args="path/to/server.jar"

# Connect to a Python server
./gradlew run --args="path/to/server.py"

# Connect to a Node.js server
./gradlew run --args="path/to/build/index.js"

Note

The client uses STDIO transport, so it launches the MCP server as a subprocess. Ensure the server script is executable and is a valid .js, .py, or .jar file.

MCP Capabilities

From the client perspective, this sample demonstrates:

  • Tool discovery — lists tools from the connected server and converts them to Anthropic's tool format.
  • Tool invocation — when Claude's response requests a tool call, the client invokes the corresponding MCP tool and feeds the result back into the conversation.

Additional Resources