Skip to content

add client sample #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ The Model Context Protocol allows applications to provide context for LLMs in a
## Samples

- [kotlin-mcp-server](./samples/kotlin-mcp-server): shows how to set up a Kotlin MCP server with different tools and other features.
- [weather-stdio-server](./samples/weather-stdio-server): shows how to build a Kotlin MCP server providing weather forecast and alerts using STDIO transport.
- [kotlin-mcp-client](./samples/kotlin-mcp-client): demonstrates building an interactive Kotlin MCP client that connects to an MCP server via STDIO and integrates with Anthropic’s API.

## Installation

Expand Down
42 changes: 42 additions & 0 deletions samples/kotlin-mcp-client/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

### IntelliJ IDEA ###
.idea/
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

### Kotlin ###
.kotlin

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/

### Mac OS ###
.DS_Store
69 changes: 69 additions & 0 deletions samples/kotlin-mcp-client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Kotlin MCP Client

This project demonstrates how to build a Model Context Protocol (MCP) client in Kotlin that interacts with an MCP server
via a STDIO transport layer while leveraging Anthropic's API for natural language processing. The client uses the MCP
Kotlin SDK to communicate with an MCP server that exposes various tools, and it uses Anthropic's API to process user
queries and integrate tool responses into the conversation.

For more information about the MCP SDK and protocol, please refer to
the [MCP documentation](https://modelcontextprotocol.io/introduction).

## Prerequisites

- **Java 17 or later**
- **Gradle** (or the Gradle wrapper provided with the project)
- An Anthropic API key set in your environment variable `ANTHROPIC_API_KEY`
- Basic understanding of MCP concepts and Kotlin programming

## Overview

The client application performs the following tasks:

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

## Building and Running

Use the Gradle wrapper to build the application. In a terminal, run:

```shell
./gradlew clean build -x test
```

To run the client, execute the jar file and provide the path to your MCP server script.

To run the client with any MCP server:

```shell
java -jar build/libs/<your-jar-name>.jar path/to/server.jar # jvm server
java -jar build/libs/<your-jar-name>.jar path/to/server.py # python server
java -jar build/libs/<your-jar-name>.jar path/to/build/index.js # node server
```

> [!NOTE]
> The client uses STDIO transport, so it launches the MCP server as a separate process.
> Ensure the server script is executable and is a valid `.js`, `.py`, or `.jar` file.

## Configuration for Anthropic

Ensure your Anthropic API key is available in your environment:

```shell
export ANTHROPIC_API_KEY=your_anthropic_api_key_here
```

The client uses `AnthropicOkHttpClient.fromEnv()` to automatically load the API key from `ANTHROPIC_API_KEY` and
`ANTHROPIC_AUTH_TOKEN` environment variables.

## Additional Resources

- [MCP Specification](https://spec.modelcontextprotocol.io/)
- [Kotlin MCP SDK](https://github.com/modelcontextprotocol/kotlin-sdk)
- [Anthropic Java SDK](https://github.com/anthropics/anthropic-sdk-java/tree/main)
31 changes: 31 additions & 0 deletions samples/kotlin-mcp-client/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
plugins {
kotlin("jvm") version "2.1.10"
application
id("com.github.johnrengelman.shadow") version "8.1.1"
}

application {
mainClass.set("io.modelcontextprotocol.sample.client.MainKt")
}


group = "org.example"
version = "0.1.0"

val mcpVersion = "0.3.0"
val slf4jVersion = "2.0.9"
val anthropicVersion = "0.8.0"

dependencies {
implementation("io.modelcontextprotocol:kotlin-sdk:$mcpVersion")
implementation("org.slf4j:slf4j-nop:$slf4jVersion")
implementation("com.anthropic:anthropic-java:$anthropicVersion")
}

tasks.test {
useJUnitPlatform()
}

kotlin {
jvmToolchain(17)
}
1 change: 1 addition & 0 deletions samples/kotlin-mcp-client/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
kotlin.code.style=official
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading