Build an MCP Server in Kotlin: Tools, Transport, and Tests

The MCP Kotlin SDK lets you expose custom tools over a standard connection that AI apps like Claude and Cursor can call. This guide covers project setup, tool registration, transport choice, and client verification.

Updated 4 min read

A Kotlin MCP server exposes custom tools over a standard protocol that AI apps like Claude, Cursor, and others can call directly. The official MCP Kotlin SDK handles the protocol details, so you write the tool logic while it manages JSON-RPC, transport, and capability negotiation. Tools like fenbs keep your design choices and project context available between sessions, so a coding assistant coming back to the work starts with the agreed decisions already recorded.

Before building a custom server, check whether an existing server from the MCP server directory already covers your need. A custom Kotlin server makes sense when you need tools specific to your own services, internal APIs, or data.

Set up a Kotlin MCP server

The MCP Kotlin SDK is published as a Gradle dependency. Add it to your project, create a server instance, register tools, and connect a transport. The steps below assume a Gradle Kotlin DSL project.

  1. Add the dependency to build.gradle.kts: implementation("io.modelcontextprotocol:kotlin-sdk:0.4.0"). Check the MCP Kotlin SDK repository (opens in a new tab) for the current version.
  2. Create a Server instance with a name, version, and the capabilities you want to expose, such as tools.
  3. Register each tool with a name, description, and input schema. The description is what the AI reads when deciding whether to call the tool.
  4. Connect a transport. For local use, StdioServerTransport reads from standard input and writes to standard output. For remote connections, an HTTP transport using Ktor is available.
  5. Build and run the server, then add it to your AI client's config as a local stdio server pointing to your executable.
Minimal Kotlin MCP server
val server = Server(
  serverInfo = Implementation(name = "my-server", version = "1.0.0"),
  options = ServerOptions(
    capabilities = ServerCapabilities(tools = ServerCapabilities.Tools())
  )
)

server.addTool(
  name = "get_status",
  description = "Return the current build status for a given project ID",
  inputSchema = Tool.Input()
) { request ->
  val id = request.arguments["projectId"] as? String ?: return@addTool CallToolResult(
    content = listOf(TextContent("projectId is required")), isError = true
  )
  CallToolResult(content = listOf(TextContent(fetchStatus(id))))
}

server.connect(StdioServerTransport())

Write clear tool descriptions

The tool description is the most important field. The AI reads it to decide when to call the tool and what arguments to pass. Write it as a plain sentence that states the purpose and the expected input. A vague description leads to wrong calls; a precise one cuts the error rate.

Use inputSchema to define required and optional parameters with types and descriptions. The SDK can generate a schema from Kotlin data classes, which keeps the schema in sync with your implementation as you iterate.

Choose a transport

Stdio transport is the simplest option: the AI client starts your server as a subprocess and communicates over standard streams. It requires no port management and works on any machine with the executable available.

An HTTP transport lets multiple clients connect to one running server, which is useful for team use or cloud deployment. The Kotlin SDK includes a Ktor integration for building an HTTP MCP endpoint. See MCP server hosting for deployment options. The MCP server spec covers which transport modes each spec version supports.

Test the connection from a client

The MCP Inspector lets you connect to a server directly, list its tools, call them with custom arguments, and see the raw results. Run npx @modelcontextprotocol/inspector and point it at your server command. This confirms the server starts, registers tools correctly, and returns valid responses before you involve a full AI client.

In Claude Desktop, add the server to your claude_desktop_config.json under mcpServers, restart the app, and check the tool list in a new conversation. The AI should list your tools when asked. See MCP server configuration for the config file format.

Common errors to fix

If the client cannot start the server, check that the command path is correct and the binary is executable. On Windows, you may need to wrap the call in a shell script or use the full path to the JVM. If the tools register but return errors, add logging to the tool handler to see what arguments arrive.

Schema mismatches are a common source of wrong calls: the AI sends arguments that do not match the expected type. Add type coercion and clear error messages at the top of each handler. The MCP server architecture guide explains how the protocol routes tool calls end to end.

A common oversight when building Kotlin MCP servers is letting tool descriptions fall out of sync with the underlying service. If the service renames a field, adds a required parameter, or changes its return format, the tool description should be updated at the same time. An AI that learned the old description may attempt calls that the new implementation rejects. Make reviewing tool descriptions part of your service update process. Run the MCP Inspector after any change to confirm each tool still behaves as described and that the AI receives clear error messages when it passes invalid arguments.

How fenbs helps

Keep design decisions available across coding sessions

Record the framework choices, tool naming conventions, and architectural decisions that shape your Kotlin MCP server in fenbs as Decisions and rules. When a new coding session starts, the assistant reads those rules first and does not re-derive choices you already made or propose alternatives you already ruled out. Add open tasks to the board so each session picks up from a known starting point.

Create a free account

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

How to do this with fenbs

  1. Create a free account and add a project for your Kotlin MCP server.
  2. Record key decisions as Decisions and rules: transport choice, tool naming conventions, schema approach, and any security boundaries the tools must respect.
  3. Add the open build tasks on the board. Note what each tool should do, its current status, and any unresolved design questions.
  4. Connect your coding assistant to fenbs at Integrations. It reads the rules and current task status at the start of each session.
  5. Before you stop, ask the assistant to save progress: which tools are complete, what is still in progress, and what the next session should start with.

fenbs does not read your Kotlin source code directly. It holds the decisions and task status your assistant needs to continue the work between sessions.

Questions people ask.

Is there an official Kotlin SDK for MCP?

Yes. The Model Context Protocol Kotlin SDK is published at github.com/modelcontextprotocol/kotlin-sdk and on Maven Central. It supports stdio and HTTP transports and works with standard Gradle and Maven projects.

What transports does the Kotlin MCP SDK support?

The SDK includes a stdio transport for local subprocess use and an HTTP transport built on Ktor for remote or multi-client deployments. Use stdio for local development and HTTP when you need a shared or cloud-hosted server.

How do I test a Kotlin MCP server without an AI client?

Use the MCP Inspector, available as an npx package from the modelcontextprotocol organization. It connects to your server, lists available tools, and lets you call them with custom arguments to see the raw response.

Does the Kotlin MCP server need a specific port?

Only if you use the HTTP transport. A stdio server runs as a subprocess with no open port. Choose HTTP when multiple clients need to connect simultaneously or when the server runs on a remote host.

How do I keep design decisions available across coding sessions?

Save them as Decisions and rules in a fenbs project linked to your coding assistant. The assistant reads them at the start of each session and treats agreed choices as rules it must follow.

More in Connect your AI tools

All Connect your AI tools articles

Start with one thing.

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

There is nothing to set up first. Write one line and you’ve started.