freshcrate
Skin:/
Home > MCP Servers > kotlin-sdk

kotlin-sdk

The official Kotlin SDK for Model Context Protocol servers and clients. Maintained in collaboration with JetBrains

Why this rank:Strong adoptionRecent releaseHealthy release cadence

Description

The official Kotlin SDK for Model Context Protocol servers and clients. Maintained in collaboration with JetBrains

README

MCP Kotlin SDK

Maven Central Build

Kotlin Kotlin Multiplatform JVM License

Kotlin Multiplatform SDK for the Model Context Protocol. It enables Kotlin applications targeting JVM, Native, JS, and Wasm to implement MCP clients and servers using a standardized protocol interface.

Table of Contents

Overview

The Model Context Protocol allows applications to provide context for LLMs in a standardized way, separating the concerns of providing context from the actual LLM interaction. This Kotlin SDK implements the MCP specification, making it easy to:

  • Build MCP clients that can connect to any MCP server
  • Create MCP servers that expose resources, prompts, and tools
  • Target JVM, Native, JS, and Wasm from a single codebase
  • Use standard transports like stdio, SSE, Streamable HTTP, and WebSocket
  • Handle MCP protocol messages and lifecycle events with coroutine-friendly APIs

Installation

Artifacts

  • io.modelcontextprotocol:kotlin-sdk – umbrella SDK (client + server APIs)
  • io.modelcontextprotocol:kotlin-sdk-client – client-only APIs
  • io.modelcontextprotocol:kotlin-sdk-server – server-only APIs

Gradle setup (JVM)

Add the Maven Central repository and the SDK dependency:

repositories {
    mavenCentral()
}

dependencies {
    // See the badge above for the latest version
    implementation("io.modelcontextprotocol:kotlin-sdk:$mcpVersion")
}

Use kotlin-sdk-client or kotlin-sdk-server if you only need one side of the API:

dependencies {
    implementation("io.modelcontextprotocol:kotlin-sdk-client:$mcpVersion")
    implementation("io.modelcontextprotocol:kotlin-sdk-server:$mcpVersion")
}

Multiplatform

In a Kotlin Multiplatform project you can add the SDK to commonMain:

commonMain {
    dependencies {
        // Works as a common dependency as well as the platform one
        implementation("io.modelcontextprotocol:kotlin-sdk:$mcpVersion")
    }
}

Ktor dependencies

The Kotlin MCP SDK uses Ktor, but it does not add Ktor engine dependencies transitively. You need to declare Ktor client/server dependencies yourself (or reuse the ones already used in your project), for example:

dependencies {
    // MCP client with Ktor
    implementation("io.ktor:ktor-client-cio:$ktorVersion")
    implementation("io.modelcontextprotocol:kotlin-sdk-client:$mcpVersion")

    // MCP server with Ktor
    implementation("io.ktor:ktor-server-netty:$ktorVersion")
    implementation("io.modelcontextprotocol:kotlin-sdk-server:$mcpVersion")
}

Quickstart

Let's create a simple MCP client and server to demonstrate the basic usage of the Kotlin SDK.

Creating a Client

Create an MCP client that connects to a server via Streamable HTTP transport and lists available tools:

import io.ktor.client.HttpClient
import io.ktor.client.plugins.sse.SSE
import io.modelcontextprotocol.kotlin.sdk.client.Client
import io.modelcontextprotocol.kotlin.sdk.client.StreamableHttpClientTransport
import io.modelcontextprotocol.kotlin.sdk.types.Implementation
import kotlinx.coroutines.runBlocking

fun main(args: Array<String>) = runBlocking {
    val url = args.firstOrNull() ?: "http://localhost:3000/mcp"

    val httpClient = HttpClient { install(SSE) }

    val client = Client(
        clientInfo = Implementation(
            name = "example-client",
            version = "1.0.0"
        )
    )

    val transport = StreamableHttpClientTransport(
        client = httpClient,
        url = url
    )

    // Connect to server
    client.connect(transport)

    // List available tools
    val tools = client.listTools().tools

    println(tools)
}

Creating a Server

Create an MCP server that exposes a simple tool and runs on an embedded Ktor server with Streamable HTTP transport. For a full working project with all required dependencies, see the simple-streamable-server sample.

import io.ktor.server.cio.CIO
import io.ktor.server.engine.embeddedServer
import io.modelcontextprotocol.kotlin.sdk.server.Server
import io.modelcontextprotocol.kotlin.sdk.server.ServerOptions
import io.modelcontextprotocol.kotlin.sdk.server.mcpStreamableHttp
import io.modelcontextprotocol.kotlin.sdk.types.CallToolResult
import io.modelcontextprotocol.kotlin.sdk.types.Implementation
import io.modelcontextprotocol.kotlin.sdk.types.ServerCapabilities
import io.modelcontextprotocol.kotlin.sdk.types.TextContent
import io.modelcontextprotocol.kotlin.sdk.types.ToolSchema
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put

fun main(args: Array<String>) {
    val port = args.firstOrNull()?.toIntOrNull() ?: 3000
    val mcpServer = Server(
        serverInfo = Implementation(
            name = "example-server",
            version = "1.0.0"
        ),
        options = ServerOptions(
            capabilities = ServerCapabilities(
                tools = ServerCapabilities.Tools(listChanged = true),
            ),
        )
    )

    mcpServer.addTool(
        name = "example-tool",
        description = "An example tool",
        inputSchema = ToolSchema(
            properties = buildJsonObject {
                put("input", buildJsonObject { put("type", "string") })
            }
        )
    ) { request ->
        CallToolResult(content = listOf(TextContent("Hello, world!")))
    }
    
    embeddedServer(CIO, host = "127.0.0.1", port = port) {
        mcpStreamableHttp {
            mcpServer
        }
    }.start(wait = true)
}

You can run the server and then connect to it using the client or test with the MCP Inspector:

npx -y @modelcontextprotocol/inspector

In the inspector UI, connect to http://localhost:3000/mcp.

Core Concepts

MCP Primitives

The MCP protocol defines core primitives that enable communication between servers and clients:

Primitive Server Role Client Role Description
Prompts Provides prompt templates with optional arguments Requests and uses prompts Interactive templates for LLM interactions
Resources Exposes data sources (files, API responses, etc.) Reads and subscribes to resources Contextual data for augmenting LLM context
Tools Defines executable functions Calls tools to perform actions Functions the LLM can invoke to take actions
Sampling Requests LLM completions from client Executes LLM calls and returns results Server-initiated LLM requests (reverse direction)

Capabilities

Capabilities define what features a server or client supports. They are declared during initialization and determine what operations are available.

Server Capabilities

Servers declare their capabilities to inform clients what features they provide:

Capability Feature Flags Description
prompts listChanged Prompt template management and notifications
resources subscribe
listChanged
Resource exposure, subscriptions, and update notifications
tools listChanged Tool discovery, execution, and list change notifications
logging - Server logging to client console
completions - Argument autocompletion suggestions
experimental Custom properties Non-standard experimental features

Client Capabilities

Clients declare their capabilities to inform servers what features they support:

Capability Feature Flags Description
sampling - Client can sample from an LLM (execute model requests)
roots listChanged Client exposes root directories and can notify of changes
elicitation - Client can display schema/form dialogs for structured input
experimental Custom properties Non-standard experimental features

Server Features

The Server API lets you wire prompts, resources, and tools with only a few lines of Kotlin. Each feature is registered up front and then resolved lazily when a client asks for it, so your handlers stay small and suspendable.

Prompts

Prompts are user-controlled templates that clients discover via prompts/list and fetch with prompts/get when a user chooses one (think slash commands or saved flows). They’re best for repeatable, structured starters rather than ad-hoc model calls.

val server = Server(
    serverInfo = Implementation(
        name = "example-server",
        version = "1.0.0"
    ),
    options = ServerOptions(
        capabilities = ServerCapabilities(
            prompts = ServerCapabilities.Prompts(listChanged = true),
        ),
    )
)

server.addPrompt(
    name = "code-review",
    description = "Ask the model to review a diff",
    arguments = listOf(
        PromptArgument(name = "diff", description = "Unified diff", required = true),
    ),
) { request ->
    GetPromptResult(
        description = "Quick code review helper",
        messages = listOf(
            PromptMessage(
                role = Role.User,
                content = TextContent(text = "Review this change:\n${request.arguments?.get("diff")}"),
            ),
        ),
    )
}

Use prompts for anything that deserves a template: bug triage questions, onboarding checklists, or saved searches. Set listChanged = true only if your prompt catalog can change at runtime and your server will emit notifications/prompts/list_changed when it does.

Resources

Resources are application-driven context that clients discover via resources/list or resources/templates/list, then fetch with resources/read. Register each one with a stable URI and return a ReadResourceResult when asked—contents can be text or binary blobs.

val server = Server(
    serverInfo = Implementation(
        name = "example-server",
        version = "1.0.0"
    ),
    options = ServerOptions(
        capabilities = ServerCapabilities(
            resources = ServerCapabilities.Resources(subscribe = true, listChanged = true),
        ),
    )
)

server.addResource(
    uri = "note://release/latest",
    name = "Release notes",
    description = "Last deployment summary",
    mimeType = "text/markdown",
) { request ->
    ReadResourceResult(
        contents = listOf(
            TextResourceContents(
                text = "Ship 42 reached production successfully.",
                uri = request.uri,
                mimeType = "text/markdown",
            ),
        ),
    )
}

Resources can be static text, generated JSON, or blobs—anything the client can surface to the user or inject into the model context. Set subscribe = true if you emit notifications/resources/updated for changes to specific URIs, and listChanged = true if you’ll send notifications/resources/list_changed when the catalog itself changes.

Tools

Tools are model-controlled capabilities the client exposes to the model. Clients discover them via tools/list, invoke them with tools/call, and your handlers receive JSON arguments, can emit streaming logs or progress, and return a CallToolResult. Keep a human in the loop for sensitive operations.

val server = Server(
    serverInfo = Implementation(
        name = "example-server",
        version = "1.0.0"
    ),
    options = ServerOptions(
        capabilities = ServerCapabilities(
            tools = ServerCapabilities.Tools(listChanged = true),
        ),
    )
)

server.addTool(
    name = "echo",
    description = "Return whatever the user sent back to them",
) { request ->
    val text = request.arguments?.get("text")?.jsonPrimitive?.content ?: "(empty)"
    CallToolResult(content = listOf(TextContent(text = "Echo: $text")))
}

Register as many tools as you need—long-running jobs can report progress via the request context, and tools can also trigger sampling (see below) when they need the client’s LLM. Set listChanged = true only if your tool catalog can change at runtime and your server will emit notifications/tools/list_changed when it does.

Completion

Completion provides argument suggestions for prompts or resource templates. Declare the completions capability and handle completion/complete requests to return up to 100 ranked values (include total/hasMore if you paginate).

val server = Server(
    serverInfo = Implementation(
        name = "example-server",
        version = "1.0.0"
    ),
    options = ServerOptions(
        capabilities = ServerCapabilities(
            completions = ServerCapabilities.Completions,
        ),
    )
)

val session = server.createSession(
    StdioServerTransport(
        inputStream = System.`in`.asSource().buffered(),
        outputStream = System.out.asSink().buffered()
    )
)

session.setRequestHandler<CompleteRequest>(Method.Defined.CompletionComplete) { request, _ ->
    val options = listOf("kotlin", "compose", "coroutine")
    val matches = options.filter { it.startsWith(request.argument.value.lowercase()) }

    CompleteResult(
        completion = CompleteResult.Completion(
            values = matches.take(3),
            total = matches.size,
            hasMore = matches.size > 3,
        ),
    )
}

Use context.arguments to refine suggestions for dependent fields (e.g., framework list filtered by chosen language).

Logging

Logging lets the server stream structured log notifications to the client using RFC 5424 levels (debugemergency). Declare the logging capability; clients can raise the minimum level with logging/setLevel, and the server emits notifications/message with severity, optional logger name, and JSON data.

val server = Server(
    serverInfo = Implementation("example-server", "1.0.0"),
    options = ServerOptions(
        capabilities = ServerCapabilities(
            logging = ServerCapabilities.Logging,
        ),
    )
)

val session = server.createSession(
    StdioServerTransport(
        inputStream = System.`in`.asSource().buffered(),
        outputStream = System.out.asSink().buffered()
    )
)

session.sendLoggingMessage(
    LoggingMessageNotification(
        LoggingMessageNotificationParams(
            level = LoggingLevel.Info,
            logger = "startup",
            data = buildJsonObject { put("message", "Server started") },
        ),
    ),
)

Keep logs free of sensitive data, and expect clients to surface them in their own UI.

Pagination

List operations return paginated results with an opaque nextCursor, clients echo that cursor to fetch the next page. Supported list calls: resources/list, resources/templates/list, prompts/list, and tools/list. Treat cursors as opaque—don’t parse or persist them across sessions.

val server = Server(
    serverInfo = Implementation("example-server", "1.0.0"),
    options = ServerOptions(
        capabilities = ServerCapabilities(
            resources = ServerCapabilities.Resources(),
        ),
    )
)

val session = server.createSession(
    StdioServerTransport(
        inputStream = System.`in`.asSource().buffered(),
        outputStream = System.out.asSink().buffered()
    )
)

val resources = listOf(
    Resource(uri = "note://1", name = "Note 1", description = "First"),
    Resource(uri = "note://2", name = "Note 2", description = "Second"),
    Resource(uri = "note://3", name = "Note 3", description = "Third"),
)
val pageSize = 2

session.setRequestHandler<ListResourcesRequest>(Method.Defined.ResourcesList) { request, _ ->
    val start = request.params?.cursor?.toIntOrNull() ?: 0
    val page = resources.drop(start).take(pageSize)
    val next = if (start + page.size < resources.size) (start + page.size).toString() else null

    ListResourcesResult(
        resources = page,
        nextCursor = next,
    )
}

Include nextCursor only when more items remain an absent cursor ends pagination.

Client Features

Clients advertise their capabilities (roots, sampling, elicitation, etc.) during initialization. After that they can serve requests from the server while still initiating calls such as listTools or callTool.

Roots

Roots let the client declare where the server is allowed to operate. Declare the roots capability, respond to roots/list, and emit notifications/roots/list_changed if you set listChanged = true. URIs must be file:// paths.

val client = Client(
    clientInfo = Implementation("demo-client", "1.0.0"),
    options = ClientOptions(
        capabilities = ClientCapabilities(roots = ClientCapabilities.Roots(listChanged = true)),
    ),
)

client.addRoot(
    uri = "file:///Users/demo/projects",
    name = "Projects",
)
client.sendRootsListChanged()

Call addRoot/removeRoot whenever your file system view changes, and use sendRootsListChanged() to notify the server. Keep root lists user-controlled and revoke entries that are no longer authorized.

Sampling

Sampling lets the server ask the client to call its preferred LLM. Declare the sampling capability (and sampling.tools if you allow tool-enabled sampling), and handle sampling/createMessage. Keep a human in the loop for approvals.

val client = Client(
    clientInfo = Implementation("demo-client", "1.0.0"),
    options = ClientOptions(
        capabilities = ClientCapabilities(
            sampling = buildJsonObject { putJsonObject("tools") { } }, // drop tools if you don't support tool use
        ),
    ),
)

client.setRequestHandler<CreateMessageRequest>(Method.Defined.SamplingCreateMessage) { request, _ ->
    val content = request.messages.lastOrNull()?.content
    val prompt = if (content is TextContent) content.text else "your topic"
    CreateMessageResult(
        model = "gpt-4o-mini",
        role = Role.Assistant,
        content = TextContent(text = "Here is a short note about $prompt"),
    )
}

Inside the handler you can pick any model/provider, require approvals, or reject the request. If you don’t support tool use, omit sampling.tools from capabilities.

Transports

All transports share the same API surface, so you can change deployment style without touching business logic. Pick the transport that best matches where the server runs.

STDIO Transport

StdioClientTransport and StdioServerTransport tunnel MCP messages over stdin/stdout—perfect for editor plugins or CLI tooling that spawns a helper process. No networking setup is required.

Streamable HTTP Transport

StreamableHttpClientTransport and the Ktor mcpStreamableHttp() / mcpStatelessStreamableHttp() helpers expose MCP over a single HTTP endpoint with optional JSON-only or SSE streaming responses. This is the recommended choice for remote deployments and integrates nicely with proxies or service meshes.

These helpers automatically install ContentNegotiation with McpJson — do not install it yourself, or a warning will be logged. Both accept a path parameter (default: "/mcp") to mount the endpoint at any URL:

embeddedServer(CIO, port = 3000) {
    mcpStreamableHttp(path = "/api/mcp") {
        MyServer()
    }
}.start(wait = true)

CORS for browser-based clients (e.g. MCP Inspector): if you connect from a browser-based client you need to install the Ktor CORS plugin so that MCP-specific headers are allowed and exposed:

install(CORS) {
    anyHost() // restrict to specific origins in production
    allowMethod(HttpMethod.Options)
    allowMethod(HttpMethod.Get)
    allowMethod(HttpMethod.Post)
    allowMethod(HttpMethod.Delete)
    allowNonSimpleContentTypes = true
    allowHeader("Mcp-Session-Id")
    allowHeader("Mcp-Protocol-Version")
    exposeHeader("Mcp-Session-Id")
    exposeHeader("Mcp-Protocol-Version")
}

SSE Transport

Server-Sent Events remain available for backwards compatibility with older MCP clients. Two Ktor helpers are provided:

  • Application.mcp { } — installs SSE and ContentNegotiation with McpJson automatically, then registers MCP endpoints at /. Do not install ContentNegotiation yourself — the SDK handles it.
  • Route.mcp { } — registers MCP endpoints at the current route path; requires install(SSE) in the application first. Use this to host MCP alongside other routes or under a path prefix:
embeddedServer(CIO, port = 3000) {
    install(SSE)
    routing {
        route("/api/mcp") {
            mcp { MyServer() }
        }
    }
}.start(wait = true)

Prefer Streamable HTTP for new projects.

WebSocket Transport

WebSocketClientTransport plus the matching server utilities provide full-duplex, low-latency connections—useful when you expect lots of notifications or long-running sessions behind a reverse proxy that already terminates WebSockets.

ChannelTransport (testing)

ChannelTransport provides a simple, non-networked transport for testing and local development. It uses Kotlin coroutines channels to provide a full-duplex connection between a client and server, allowing for easy testing of MCP functionality without the need for network setup.

Connecting your server

  1. Start a sample HTTP server on port 3000:

    ./gradlew :samples:kotlin-mcp-server:run
  2. Connect with the MCP Inspector or Claude Desktop/Code:

    npx -y @modelcontextprotocol/inspector --connect http://localhost:3000
    # or
    claude mcp add --transport http kotlin-mcp http://localhost:3000
  3. In the Inspector, confirm prompts, tools, resources, completions, and logs show up. Iterate locally until you’re ready to host the server wherever you prefer.

Examples

The samples directory contains runnable projects demonstrating MCP server and client implementations with various transports. See the samples overview for a comparison table and detailed descriptions.

Documentation

Ask DeepWiki

Contributing

Please see the contribution guide and the Code of conduct before contributing.

License

This project is licensed under Apache 2.0 for new contributions, with existing code under MIT—see the LICENSE file for details.

Release History

VersionChangesUrgencyDate
0.13.0## Description Adds a `tasks` capability and a typed `elicitation` capability, hardens transport lifecycle, dispatchers, and back-pressure, and enables DNS rebinding protection by default. ### Breaking Changes **Typed `elicitation` capability and new `tasks` capability** by @devcrocod in [#732](https://github.com/modelcontextprotocol/kotlin-sdk/pull/732) `ClientCapabilities.elicitation` is now a typed `ClientCapabilities.Elicitation` (`form`, `url`) instead of a raw `JsonObject?`, anHigh6/2/2026
0.12.0## Description Adds sampling-with-tools per SEP-1577, JSON Schema dialect declaration on tool schemas, server-side tool name validation, and capability extensions; fixes SSE reconnect on the same session and stops swallowing `CancellationException`. ### Breaking Changes **Sampling messages can carry tool calls and results (SEP-1577)** by @devcrocod in [#718](https://github.com/modelcontextprotocol/kotlin-sdk/pull/718) `SamplingMessage.content` is now typed as a new `SamplingMessageCoHigh4/29/2026
0.11.1### Description Fixes an SSE stream crash on Netty when clients connect to the Streamable HTTP GET endpoint. ### Fixed - Fixed GET SSE stream crash on Netty in Streamable HTTP where `appendSseHeaders()` was called after response headers were already committed, causing `UnsupportedOperationException` and client retry loops by @devcrocod in [#681](https://github.com/modelcontextprotocol/kotlin-sdk/pull/681) ### Dependencies - mcp-kotlin to v0.11.0 in [#672](https://github.com/modelcHigh4/10/2026
0.11.0Adds URL-mode elicitation with typed schema definitions, configurable server payload size limits, and upgrades core dependencies to Kotlin 2.3. ## Breaking Changes **`ElicitRequestParams` is now a sealed interface** by @devcrocod in [#660](https://github.com/modelcontextprotocol/kotlin-sdk/pull/660) Restructured to support both form-based and URL-based elicitation modes per the MCP specification. `ElicitRequestParams` changed from a `data class` to a `sealed interface` with two variantsHigh4/2/2026
0.10.0## Highlights This release adds MCP conformance testing infrastructure, SSE reconnection support, Tasks protocol types, resource template matching, and tool execution properties. It also completes a deprecation cycle — removing all previously deprecated (error-level) symbols from `io.modelcontextprotocol.kotlin.sdk` in favor of their replacements in `io.modelcontextprotocol.kotlin.sdk.types`. ## Breaking Changes - **DeprMedium3/26/2026
0.9.0## What's Changed ### Breaking Changes - **Server call handlers now receive a `RequestContext`** — handler lambdas for tools, prompts, and resources have a new `context` parameter providing access to request metadata (#515) by @rnett - **Ktor extension functions moved from `Routing` to `Route`** — update call sites: `routing { mcpSse() }` → `route("/mcp") { mcpSse() }` or use directly in any `Route` block (#531) by @kpavlov - **`StdioServerTransport` rethrows `CancellationExceptionLow3/5/2026
0.8.4## Changes - feat: Ktor extensions for streamable http (#504) by @devcrocod - fix: Add $defs to ToolSchema and tests (#526) by @i1bro **Full Changelog**: https://github.com/modelcontextprotocol/kotlin-sdk/compare/0.8.3...0.8.4Low2/17/2026
0.8.3# What's Changed ## Bugfixes - **breaking change!:** `StdioClientTransport.send(...)` and `StreamableHttpClientTransport.send(...)` now throw `McpException` when not ready (#487) by @kpavlov - #450 Properly check content type (#451) by @nerzhulart - Fix flaky StdioClientTransportErrorHandlingTest (#457) by @kpavlov - Fix tests for notifications (#446) by @tiginamaria - Fix kotlin-mcp-server sample (#459) by @devcrocod - Fix GitHub Actions build workflow (#474) by @kpavlov - Fix conLow1/21/2026
0.8.1## What's Changed - fix(stdio-client): Monitor STDERR and refactor `StdioClientTransport` to use flows. Fixes #107 by @kpavlov - fix(sse-client): Skip SSE in StreamableHttpClientTransport when data is empty (#433) by @kpavlov - Server feature list changed and resource updated notifications (#441) by @tiginamaria - Add MCP conformance test coverage  (#435) by @skarpovdev ### Chores - Update samples to use new schema (#443) by @kpavlov - Bump org.jetbrains.kotlinx:kotlinx-io-core frLow12/4/2025
0.8.0## 🚨 Breaking changes #### MCP schema types refactor (#386) The MCP schema implementation has been updated to the latest MCP spec and reorganized into dedicated packages: - All MCP types moved to `io.modelcontextprotocol.kotlin.sdk.types` package - Many schema types have new fields and updated constructor signatures - Request/response types now use nested `params` objects **Migration:** ```kotlin // Before: import io.modelcontextprotocol.kotlin.sdk.InitializeRequest import io.Low11/20/2025
0.7.7## What's Changed * **💥 Breaking change:** Replace `Instant` with `String` for `lastModified` in `Annotations` by @kpavlov in https://github.com/modelcontextprotocol/kotlin-sdk/pull/383 **Full Changelog**: https://github.com/modelcontextprotocol/kotlin-sdk/compare/0.7.6...0.7.7Low11/10/2025
0.7.6## What's Changed ## Bugfixes * #355 Handle coroutine cancellation in Server Transports by @kpavlov in https://github.com/modelcontextprotocol/kotlin-sdk/pull/375 ## Dependencies * Bump version to 0.7.6-SNAPSHOT and update version to 0.7.5 in samples by @kpavlov in https://github.com/modelcontextprotocol/kotlin-sdk/pull/374 * Update Gradle to version 9.2.0 across all projects by @kpavlov in https://github.com/modelcontextprotocol/kotlin-sdk/pull/377 **Full Changelog**: https://githLow11/7/2025
0.7.5## What's Changed * Refactor WebSocket dependency by @devcrocod in https://github.com/modelcontextprotocol/kotlin-sdk/pull/350 * Fix: Return CallToolResult with isError for tool errors to conform with MCP spec by @devcrocod in https://github.com/modelcontextprotocol/kotlin-sdk/pull/354 * Relocate `WebSocketIntegrationTest` from `commonTest` to `jvmTest` by @devcrocod in https://github.com/modelcontextprotocol/kotlin-sdk/pull/352 * Fix kotlin-mcp-server example and update samples by @devcroLow11/6/2025
0.7.4# What's Changed ## Features * Add metadata support to callTool method by @maeryo in https://github.com/modelcontextprotocol/kotlin-sdk/pull/289 ## Improvements * Fix decimal separator format in calculator tool tests by @maeryo in https://github.com/modelcontextprotocol/kotlin-sdk/pull/315 * Refactor testClientConnectWithInvalidJson by @devcrocod in https://github.com/modelcontextprotocol/kotlin-sdk/pull/338 ## Build & CI * #302 [part 1] Add GitHub workflow to validate samples by @Low10/24/2025
0.7.3## What's Changed * Introduce server sessions by @tiginamaria in https://github.com/modelcontextprotocol/kotlin-sdk/pull/198 * Capture version at configuration time to avoid configuration cache issue by @jclyne in https://github.com/modelcontextprotocol/kotlin-sdk/pull/291 * Add `instructions` string to the Server and propagate to the `InitializeResult` by @jclyne in https://github.com/modelcontextprotocol/kotlin-sdk/pull/290 * Change sample server host from `0.0.0.0` to `127.0.0.1` by @JLLow10/21/2025
0.6.1## What's Changed * Fix incorrect deserializer mapping for tool and prompt list notifications (https://github.com/modelcontextprotocol/kotlin-sdk/pull/195) **Full Changelog**: https://github.com/modelcontextprotocol/kotlin-sdk/compare/0.6.0...0.6.1Low10/6/2025
0.7.2## What's Changed * migration from `jreleaser` to `mavenPublish` plugin by @devcrocod in https://github.com/modelcontextprotocol/kotlin-sdk/pull/277 * Generate test report by @kpavlov in https://github.com/modelcontextprotocol/kotlin-sdk/pull/271 * Move `generateLibVersion` task to `kotlin-sdk-core` by @devcrocod in https://github.com/modelcontextprotocol/kotlin-sdk/pull/274 * #196 Update build configuration and workflows for enhanced local publ… by @kpavlov in https://github.com/modelconteLow9/19/2025
0.7.2-alpha3Release 0.7.2-alpha3Low9/19/2025
0.7.2-alpha2Release 0.7.2-alpha2Low9/19/2025
0.7.2-alpha1Release 0.7.2-alpha1Low9/18/2025
0.7.1## What's Changed * Bump io.github.oshai:kotlin-logging from 7.0.7 to 7.0.11 by @dependabot[bot] in https://github.com/modelcontextprotocol/kotlin-sdk/pull/211 * Bump org.jlleitschuh.gradle.ktlint from 13.0.0 to 13.1.0 by @dependabot[bot] in https://github.com/modelcontextprotocol/kotlin-sdk/pull/241 * Bump com.anthropic:anthropic-java from 0.8.0 to 2.6.0 by @dependabot[bot] in https://github.com/modelcontextprotocol/kotlin-sdk/pull/246 * Fix upload reports in GitHub actions by @skarpovdevLow9/15/2025
0.7.0## What's Changed * revert jreleaser to 1.17.0 and skip checksums by @devcrocod in https://github.com/modelcontextprotocol/kotlin-sdk/pull/150 * fix deploy for klibs by @devcrocod in https://github.com/modelcontextprotocol/kotlin-sdk/pull/153 * FEAT: Support almost all Tier 1, 2 and 3 Kotlin targets by @nomisRev in https://github.com/modelcontextprotocol/kotlin-sdk/pull/151 * Revert "FEAT: Support all Tier 1, 2 and 3 targets by Kotlin & remove … by @devcrocod in https://github.com/modelconteLow9/11/2025
0.6.0## What's Changed * Update jreleaser to fix publication issue by @e5l in https://github.com/modelcontextprotocol/kotlin-sdk/pull/91 * Disable configuration cache to fix jreleaser issue by @e5l in https://github.com/modelcontextprotocol/kotlin-sdk/pull/92 * feat: Add audio type according to 2025-03-26 spec by @SeanChinJunKai in https://github.com/modelcontextprotocol/kotlin-sdk/pull/68 * fix(client): serialize inputSchema as input_schema by @shiqicao in https://github.com/modelcontextprotocolLow7/16/2025
0.5.0## What's Changed * remove the mention of `onCloseCallback` and replace it to `onClose` by @devcrocod in https://github.com/modelcontextprotocol/kotlin-sdk/pull/62 * Refactor for simplify input schemas by @devcrocod in https://github.com/modelcontextprotocol/kotlin-sdk/pull/65 * Add specific error handling for client connect by @SeanChinJunKai in https://github.com/modelcontextprotocol/kotlin-sdk/pull/64 * Update to Kotlin 2.1.20 and minor refactoring by @devcrocod in https://github.com/modLow4/30/2025
0.4.0## What's Changed * Add org.jetbrains.kotlinx.binary-compatibility-validator plugin by @morisil in https://github.com/modelcontextprotocol/kotlin-sdk/pull/35 * Migrate to kotlin style callbacks. Close #14 by @e5l in https://github.com/modelcontextprotocol/kotlin-sdk/pull/36 * Add merge queue rules by @Mr3zee in https://github.com/modelcontextprotocol/kotlin-sdk/pull/37 * Modify SSE config for server by @Mr3zee in https://github.com/modelcontextprotocol/kotlin-sdk/pull/23 * Add support for tLow3/26/2025
0.3.0- Add multiplatform supportLow1/7/2025
0.2.0## What's Changed * Add required field to tool input by @kaleev in https://github.com/modelcontextprotocol/kotlin-sdk/pull/24 * Accept requestID as a string, fix #25 by @ignatov in https://github.com/modelcontextprotocol/kotlin-sdk/pull/26 ## New Contributors * @kaleev made their first contribution in https://github.com/modelcontextprotocol/kotlin-sdk/pull/24 * @ignatov made their first contribution in https://github.com/modelcontextprotocol/kotlin-sdk/pull/26 **Full Changelog**: httpsLow12/22/2024
0.1.0Release 0.1.0Low12/17/2024

Dependencies & License Audit

Loading dependencies...

Similar Packages

paiml-mcp-agent-toolkitPragmatic AI Labs MCP Agent Toolkit - An MCP Server designed to make code with agents more deterministicv3.17.0
aiA productive AI coworker that learns, self-improves, and ships work.main@2026-06-06
claude-plugins-officialOfficial, Anthropic-managed directory of high quality Claude Code Plugins.main@2026-06-06
justoneapi-mcpProduction-ready MCP server exposing JustOneAPI endpoints to AI agents with raw JSON responses.main@2026-06-06
pipulateLocal First AI SEO Software on Nix, FastHTML & HTMXmain@2026-06-06

More from modelcontextprotocol

python-sdkThe official Python SDK for Model Context Protocol servers and clients
typescript-sdkThe official TypeScript SDK for Model Context Protocol servers and clients
modelcontextprotocolSpecification and documentation for the Model Context Protocol
registryA community driven registry service for Model Context Protocol (MCP) servers.

More in MCP Servers

AstrBotAgentic IM Chatbot infrastructure that integrates lots of IM platforms, LLMs, plugins and AI feature, and can be your openclaw alternative. ✨
agentscopeBuild and run agents you can see, understand and trust.
claude-plugins-officialOfficial, Anthropic-managed directory of high quality Claude Code Plugins.
langchain4jLangChain4j is an open-source Java library that simplifies the integration of LLMs into Java applications through a unified API, providing access to popular LLMs and vector databases. It makes impleme