Skip to content

Commit 0b39f57

Browse files
authored
docs: streamable server sample (#595)
- add a simple streamable http server example with auth - update readme: replace quickstart example from sse server to streamable server - add readme files for samples, simple-streamable-server, notebooks closes #170 ## How Has This Been Tested? knit and inspector ## Breaking Changes NaN ## 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
1 parent 5b58814 commit 0b39f57

20 files changed

Lines changed: 1085 additions & 254 deletions

File tree

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ jobs:
180180
sample:
181181
- kotlin-mcp-client
182182
- kotlin-mcp-server
183+
- simple-streamable-server
183184
- weather-stdio-server
184185

185186
name: "Build Sample: ${{ matrix.sample }}"

.github/workflows/samples.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ jobs:
2929
sample:
3030
- kotlin-mcp-client
3131
- kotlin-mcp-server
32+
- simple-streamable-server
3233
- weather-stdio-server
3334

3435
name: Build Sample (${{ matrix.sample }})

README.md

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -21,34 +21,34 @@ standardized protocol interface.
2121

2222
* [Overview](#overview)
2323
* [Installation](#installation)
24-
* [Artifacts](#artifacts)
25-
* [Gradle setup (JVM)](#gradle-setup-jvm)
26-
* [Multiplatform](#multiplatform)
27-
* [Ktor dependencies](#ktor-dependencies)
24+
* [Artifacts](#artifacts)
25+
* [Gradle setup (JVM)](#gradle-setup-jvm)
26+
* [Multiplatform](#multiplatform)
27+
* [Ktor dependencies](#ktor-dependencies)
2828
* [Quickstart](#quickstart)
29-
* [Creating a Client](#creating-a-client)
30-
* [Creating a Server](#creating-a-server)
29+
* [Creating a Client](#creating-a-client)
30+
* [Creating a Server](#creating-a-server)
3131
* [Core Concepts](#core-concepts)
32-
* [MCP Primitives](#mcp-primitives)
33-
* [Capabilities](#capabilities)
34-
* [Server Capabilities](#server-capabilities)
35-
* [Client Capabilities](#client-capabilities)
36-
* [Server Features](#server-features)
37-
* [Prompts](#prompts)
38-
* [Resources](#resources)
39-
* [Tools](#tools)
40-
* [Completion](#completion)
41-
* [Logging](#logging)
42-
* [Pagination](#pagination)
43-
* [Client Features](#client-features)
44-
* [Roots](#roots)
45-
* [Sampling](#sampling)
32+
* [MCP Primitives](#mcp-primitives)
33+
* [Capabilities](#capabilities)
34+
* [Server Capabilities](#server-capabilities)
35+
* [Client Capabilities](#client-capabilities)
36+
* [Server Features](#server-features)
37+
* [Prompts](#prompts)
38+
* [Resources](#resources)
39+
* [Tools](#tools)
40+
* [Completion](#completion)
41+
* [Logging](#logging)
42+
* [Pagination](#pagination)
43+
* [Client Features](#client-features)
44+
* [Roots](#roots)
45+
* [Sampling](#sampling)
4646
* [Transports](#transports)
47-
* [STDIO Transport](#stdio-transport)
48-
* [Streamable HTTP Transport](#streamable-http-transport)
49-
* [SSE Transport](#sse-transport)
50-
* [WebSocket Transport](#websocket-transport)
51-
* [ChannelTransport (testing)](#channeltransport-testing)
47+
* [STDIO Transport](#stdio-transport)
48+
* [Streamable HTTP Transport](#streamable-http-transport)
49+
* [SSE Transport](#sse-transport)
50+
* [WebSocket Transport](#websocket-transport)
51+
* [ChannelTransport (testing)](#channeltransport-testing)
5252
* [Connecting your server](#connecting-your-server)
5353
* [Examples](#examples)
5454
* [Documentation](#documentation)
@@ -183,17 +183,24 @@ fun main(args: Array<String>) = runBlocking {
183183

184184
### Creating a Server
185185

186-
Create an MCP server that exposes a simple tool and runs on an embedded Ktor server with SSE transport:
186+
Create an MCP server that exposes a simple tool and runs on an embedded Ktor server with Streamable HTTP transport.
187+
For a full working project with all required dependencies, see
188+
the [simple-streamable-server](samples/simple-streamable-server) sample.
187189

188190
<!--- CLEAR -->
191+
189192
```kotlin
193+
import io.ktor.serialization.kotlinx.json.json
194+
import io.ktor.server.application.install
190195
import io.ktor.server.cio.CIO
191196
import io.ktor.server.engine.embeddedServer
197+
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
192198
import io.modelcontextprotocol.kotlin.sdk.server.Server
193199
import io.modelcontextprotocol.kotlin.sdk.server.ServerOptions
194-
import io.modelcontextprotocol.kotlin.sdk.server.mcp
200+
import io.modelcontextprotocol.kotlin.sdk.server.mcpStreamableHttp
195201
import io.modelcontextprotocol.kotlin.sdk.types.CallToolResult
196202
import io.modelcontextprotocol.kotlin.sdk.types.Implementation
203+
import io.modelcontextprotocol.kotlin.sdk.types.McpJson
197204
import io.modelcontextprotocol.kotlin.sdk.types.ServerCapabilities
198205
import io.modelcontextprotocol.kotlin.sdk.types.TextContent
199206
import io.modelcontextprotocol.kotlin.sdk.types.ToolSchema
@@ -228,7 +235,10 @@ fun main(args: Array<String>) {
228235
}
229236

230237
embeddedServer(CIO, host = "127.0.0.1", port = port) {
231-
mcp {
238+
install(ContentNegotiation) {
239+
json(McpJson)
240+
}
241+
mcpStreamableHttp {
232242
mcpServer
233243
}
234244
}.start(wait = true)
@@ -243,7 +253,7 @@ You can run the server and then connect to it using the client or test with the
243253
npx -y @modelcontextprotocol/inspector
244254
```
245255

246-
In the inspector UI, connect to `http://localhost:3000`.
256+
In the inspector UI, connect to `http://localhost:3000/mcp`.
247257

248258
## Core Concepts
249259

@@ -787,13 +797,15 @@ private class MyServer :
787797
788798
fun main() {
789799
-->
800+
790801
```kotlin
791802
embeddedServer(CIO, port = 3000) {
792803
mcpStreamableHttp(path = "/api/mcp") {
793804
MyServer()
794805
}
795806
}.start(wait = true)
796807
```
808+
797809
<!--- SUFFIX
798810
}
799811
-->
@@ -831,6 +843,7 @@ private class MyServer :
831843
832844
fun main() {
833845
-->
846+
834847
```kotlin
835848
embeddedServer(CIO, port = 3000) {
836849
install(SSE)
@@ -841,6 +854,7 @@ embeddedServer(CIO, port = 3000) {
841854
}
842855
}.start(wait = true)
843856
```
857+
844858
<!--- SUFFIX
845859
}
846860
-->
@@ -880,12 +894,9 @@ allowing for easy testing of MCP functionality without the need for network setu
880894

881895
## Examples
882896

883-
| Scenario | Description | Example |
884-
|--------------------------|-----------------------------------------------------------------|--------------------------------------------------------------------------|
885-
| Streamable HTTP server | Full MCP server with prompts, resources, tools, completions | [samples/kotlin-mcp-server](./samples/kotlin-mcp-server) |
886-
| STDIO weather server | Minimal STDIO transport server exposing weather info and alerts | [samples/weather-stdio-server](./samples/weather-stdio-server) |
887-
| Interactive STDIO client | MCP client that connects over STDIO and pipes requests to LLMs | [samples/kotlin-mcp-client](./samples/kotlin-mcp-client) |
888-
| Streamable HTTP client | MCP client demo in a runnable notebook | [samples/notebooks/McpClient.ipynb](./samples/notebooks/McpClient.ipynb) |
897+
The [samples](./samples) directory contains runnable projects demonstrating
898+
MCP server and client implementations with various transports.
899+
See the [samples overview](./samples/README.md) for a comparison table and detailed descriptions.
889900

890901
## Documentation
891902

@@ -899,4 +910,5 @@ Please see the [contribution guide](CONTRIBUTING.md) and the [Code of conduct](C
899910

900911
## License
901912

902-
This project is licensed under Apache 2.0 for new contributions, with existing code under MIT—see the [LICENSE](LICENSE) file for details.
913+
This project is licensed under Apache 2.0 for new contributions, with existing code under MIT—see the [LICENSE](LICENSE)
914+
file for details.

docs/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ plugins {
66
dependencies {
77
implementation(project(":kotlin-sdk"))
88
implementation(libs.ktor.server.cio)
9+
implementation(libs.ktor.serialization)
10+
implementation(libs.ktor.server.content.negotiation)
911
}
1012

1113
tasks.matching {

samples/README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Kotlin MCP SDK Samples
2+
3+
Runnable projects demonstrating MCP server and client implementations with the
4+
[Kotlin MCP SDK](https://github.com/modelcontextprotocol/kotlin-sdk).
5+
For background on the protocol itself, see the [MCP documentation](https://modelcontextprotocol.io/introduction).
6+
7+
## Overview
8+
9+
| Sample | Type | Transport | MCP Features |
10+
|--------------------------------------------------------|-------------------|-----------------|------------------------------------|
11+
| [simple-streamable-server](./simple-streamable-server) | Server | Streamable HTTP | Tools, Resources, Prompts, Logging |
12+
| [kotlin-mcp-server](./kotlin-mcp-server) | Server | STDIO, SSE | Tools, Resources, Prompts |
13+
| [weather-stdio-server](./weather-stdio-server) | Server | STDIO | Tools |
14+
| [kotlin-mcp-client](./kotlin-mcp-client) | Client | STDIO | Tool discovery & invocation |
15+
| [notebooks](./notebooks) | Client (Notebook) | Streamable HTTP | Tool discovery & invocation |
16+
17+
## Getting Started
18+
19+
- **Building a server?** Start with [simple-streamable-server](./simple-streamable-server) — it
20+
uses the recommended Streamable HTTP transport and covers tools, resources, prompts, and logging.
21+
- **Building a client?** Open the [notebooks](./notebooks) sample for a step-by-step walkthrough,
22+
or see [kotlin-mcp-client](./kotlin-mcp-client) for a full CLI client with Anthropic API
23+
integration.
24+
25+
## Samples
26+
27+
### Simple Streamable HTTP Server
28+
29+
A minimal Streamable HTTP server with optional Bearer token authentication. Demonstrates tools
30+
(`greet`, `multi-greet`), a prompt template, a resource, and server-to-client logging notifications.
31+
[Read more →](./simple-streamable-server)
32+
33+
### Kotlin MCP Server
34+
35+
A multi-transport server supporting STDIO, SSE (plain), and SSE (Ktor plugin). Useful for exploring
36+
different transport modes side by side.
37+
[Read more →](./kotlin-mcp-server)
38+
39+
### Weather STDIO Server
40+
41+
A focused STDIO server that exposes weather forecast and alert tools backed by the weather.gov API.
42+
Includes Claude Desktop integration instructions.
43+
[Read more →](./weather-stdio-server)
44+
45+
### Kotlin MCP Client
46+
47+
An interactive CLI client that connects to any MCP server over STDIO and routes queries through
48+
Anthropic's Claude API, bridging MCP tools with LLM conversations.
49+
[Read more →](./kotlin-mcp-client)
50+
51+
### MCP Client Notebook
52+
53+
A Kotlin notebook that connects to a remote MCP server via Streamable HTTP and demonstrates ping,
54+
tool listing, and tool invocation — all in an interactive cell-by-cell format.
55+
[Read more →](./notebooks)
Lines changed: 27 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,50 @@
11
# Kotlin MCP Client
22

3-
This project demonstrates how to build a Model Context Protocol (MCP) client in Kotlin that interacts with an MCP server
4-
via a STDIO transport layer while leveraging Anthropic's API for natural language processing. The client uses the MCP
5-
Kotlin SDK to communicate with an MCP server that exposes various tools, and it uses Anthropic's API to process user
6-
queries and integrate tool responses into the conversation.
7-
8-
For more information about the MCP SDK and protocol, please refer to
9-
the [MCP documentation](https://modelcontextprotocol.io/introduction).
10-
11-
## Prerequisites
12-
13-
- **Java 17 or later**
14-
- **Gradle** (or the Gradle wrapper provided with the project)
15-
- An Anthropic API key set in your environment variable `ANTHROPIC_API_KEY`
16-
- Basic understanding of MCP concepts and Kotlin programming
3+
An interactive CLI client that connects to any MCP server over STDIO and pipes queries through
4+
Anthropic's Claude API.
175

186
## Overview
197

20-
The client application performs the following tasks:
8+
This sample demonstrates a complete MCP client workflow: launching an MCP server as a subprocess,
9+
discovering its tools, converting them to Anthropic's tool format, and running an interactive chat
10+
loop where Claude can call server tools on behalf of the user.
2111

22-
- **Connecting to an MCP server**
23-
launches an MCP server process (implemented in JavaScript, Python, or Java) using STDIO transport.
24-
It connects to the server, retrieves available tools, and converts them to Anthropic’s tool format.
25-
- **Processing queries**
26-
accepts user queries, sends them to Anthropic’s API along with the registered tools, and handles responses.
27-
If the response indicates a tool should be called, it invokes the corresponding MCP tool and continues the
28-
conversation based on the tool’s result.
29-
- **Interactive chat loop**
30-
runs an interactive command-line loop, allowing users to continuously submit queries and receive responses.
12+
## Prerequisites
3113

32-
## Building and Running
14+
- JDK 17+
15+
- An `ANTHROPIC_API_KEY` environment variable set with a valid Anthropic API key
16+
- An MCP server script to connect to (`.js`, `.py`, or `.jar`)
3317

34-
Use the Gradle wrapper to build the application. In a terminal, run:
18+
## Build & Run
3519

36-
```shell
37-
./gradlew clean build
38-
```
20+
Run the client, passing the path to an MCP server:
3921

40-
To run the client, execute the jar file and provide the path to your MCP server script.
22+
```shell
23+
# Connect to a JVM server
24+
./gradlew run --args="path/to/server.jar"
4125

42-
To run the client with any MCP server:
26+
# Connect to a Python server
27+
./gradlew run --args="path/to/server.py"
4328

44-
```shell
45-
java -jar build/libs/<your-jar-name>.jar path/to/server.jar # jvm server
46-
java -jar build/libs/<your-jar-name>.jar path/to/server.py # python server
47-
java -jar build/libs/<your-jar-name>.jar path/to/build/index.js # node server
29+
# Connect to a Node.js server
30+
./gradlew run --args="path/to/build/index.js"
4831
```
4932

5033
> [!NOTE]
51-
> The client uses STDIO transport, so it launches the MCP server as a separate process.
34+
> The client uses STDIO transport, so it launches the MCP server as a subprocess.
5235
> Ensure the server script is executable and is a valid `.js`, `.py`, or `.jar` file.
5336
54-
## Configuration for Anthropic
37+
## MCP Capabilities
5538

56-
Ensure your Anthropic API key is available in your environment:
57-
58-
```shell
59-
export ANTHROPIC_API_KEY=your_anthropic_api_key_here
60-
```
39+
From the **client** perspective, this sample demonstrates:
6140

62-
The client uses `AnthropicOkHttpClient.fromEnv()` to automatically load the API key from `ANTHROPIC_API_KEY` and
63-
`ANTHROPIC_AUTH_TOKEN` environment variables.
41+
- **Tool discovery** — lists tools from the connected server and converts them to Anthropic's tool
42+
format.
43+
- **Tool invocation** — when Claude's response requests a tool call, the client invokes the
44+
corresponding MCP tool and feeds the result back into the conversation.
6445

6546
## Additional Resources
6647

67-
- [MCP Specification](https://spec.modelcontextprotocol.io/)
48+
- [MCP Specification](https://modelcontextprotocol.io/specification/latest)
6849
- [Kotlin MCP SDK](https://github.com/modelcontextprotocol/kotlin-sdk)
69-
- [Anthropic Java SDK](https://github.com/anthropics/anthropic-sdk-java/tree/main)
50+
- [Anthropic Java SDK](https://github.com/anthropics/anthropic-sdk-java)

0 commit comments

Comments
 (0)