Generate a complete Kotlin Model Context Protocol server project using io.modelcontextprotocol:kotlin-sdk, Gradle, stdio or Ktor transport, typed tools, configuration, tests, and README documentation. Use when asked to create a Kotlin MCP server, scaffold MCP tools, build a Gradle MCP project, or generate a production-ready MCP server template.
Generate a complete Kotlin MCP server project from a server name, package, tools, transport, and description. Produce a Gradle layout, MCP SDK wiring, typed tool schemas, coroutine-safe implementation, tests, and README instructions that can be copied into a repository.
When to invoke
"Generate a Kotlin MCP server project."
"Create a Gradle MCP server using the Kotlin SDK."
"Scaffold MCP tools with typed inputs and outputs."
"Build a Kotlin stdio MCP server with tests and README."
"Add Ktor SSE transport to a Kotlin MCP server."
Project contract
Area
Required output
Project structure
A Gradle Kotlin project with build.gradle.kts, settings.gradle.kts, gradle.properties, src/main/kotlin/..., src/test/kotlin/..., and README.md.
Dependencies
Official io.modelcontextprotocol:kotlin-sdk, Ktor transport modules, kotlinx-serialization-json, kotlinx-coroutines-core, kotlin-logging-jvm, logback-classic, and kotlinx-coroutines-test.
Runtime
A Main.kt that loads config, creates a Server, connects StdioServerTransport, and logs startup.
Tools
At least two or three useful tools with JSON schemas built with buildJsonObject, required fields, validation, and typed inputs/outputs.
Error handling
Validate required parameters before tool execution and return clear failures through Kotlin exceptions or result types such as Result/Either when the project already uses them.
Testing
Include coroutine tests with runTest, a test server creation case, and a test tool1 execution case or equivalent.
Documentation
Explain requirements, build, run, configuration, tools, development, and license in README.md.
Use placeholders only where generation truly needs user input: PROJECT_NAME, PROJECT_DESCRIPTION, TOOL1_DESCRIPTION, SERVER_NAME, VERSION, and DESCRIPTION.
File layout
Create this structure, replacing myserver and com/example/myserver/ with the requested project and package names:
Keep package declarations consistent across every file. If the artifact name differs from the package, make settings.gradle.kts set rootProject.name = "PROJECT_NAME" and make application.mainClass point at the generated MainKt class.
Gradle and dependencies
Use a JVM Gradle build unless the user explicitly asks for multiplatform. The baseline dependency set is:
If the user asks for Kotlin Multiplatform, add jvm(), js(IR) { nodejs() }, wasmJs(), and put implementation("io.modelcontextprotocol:kotlin-sdk:0.7.2") in commonMain.dependencies. Do not claim multiplatform support in README.md unless the build actually configures it.
Server and transport wiring
File
Required content
Config.kt
A serializable Config with name, version, and description; loadConfig() reads SERVER_NAME, VERSION, and DESCRIPTION, falling back to PROJECT_NAME, 1.0.0, and PROJECT_DESCRIPTION.
Main.kt
runBlocking, KotlinLogging.logger {}, loadConfig(), createServer(config), StdioServerTransport(), and server.connect(transport).
Build JSON schema with buildJsonObject, putJsonObject("properties"), putJsonArray("required"), put("type", ...), and field descriptions.
Request
Type handler parameters as CallToolRequest when using the SDK callback signature.
Required input
Extract param1 or real required fields from request.params.arguments; throw IllegalArgumentException("param1 is required") or a domain-specific message when absent.
Optional input
Convert param2 or numeric optional fields safely with (value as? Number)?.toInt() ?: 0.
Result
Return CallToolResult(content = listOf(TextContent(text = result))) for text tools; use typed serialization for structured results when needed.
Async work
Use suspending functions for I/O and coroutine-friendly APIs; keep blocking work isolated.
Type safety
Prefer data classes, sealed classes for result states, null safety, and kotlinx.serialization.
Testability
Put business logic in private or injectable functions such as performTool1Logic(param1, param2), not inline in the registration lambda.
Documentation
Add KDoc comments for public APIs and meaningful tool descriptions.
Name test fixtures explicitly, for example test-server, and document typed inputs/outputs for every generated tool. Use kotlin-logging consistently so dependency names and imports stay aligned.
README content
The README.md must include this concrete operating information:
Section
Required detail
Requirements
Java 17 or higher and the Kotlin version configured by Gradle.
Installation
./gradlew build.
Usage
./gradlew run; optionally ./gradlew installDist and ./build/install/PROJECT_NAME/bin/PROJECT_NAME.
Configuration
SERVER_NAME, VERSION, and DESCRIPTION environment variables.
Available Tools
Each tool name, TOOL1_DESCRIPTION, inputs such as param1 and param2, and output shape.
Development
./gradlew test, ./gradlew build, and ./gradlew run --continuous for auto-reload development; the install task writes launch scripts under build/install/.
License
State the chosen license, for example MIT, only if the user requested or accepted it.
Gotchas
Keep SDK examples version-consistent: io.modelcontextprotocol:kotlin-sdk:0.7.2, ktor-server-netty, and ktor-client-cio examples should compile together with the selected Kotlin version.
Do not register phantom tools: every call in tools/ToolRegistry.kt must have a matching implementation file.
Do not advertise multiplatform unless configured: JVM-only builds should not claim JVM, Wasm, and iOS support.
Do not leave placeholders in generated code: replace PROJECT_NAME, PROJECT_DESCRIPTION, and TOOL1_DESCRIPTION before final output unless the user explicitly requested a template.
name is kotlin-mcp-server-generator and matches the parent directory.
The project layout includes all required Gradle, source, test, tools, config, and README.md files.
build.gradle.kts includes the MCP SDK, Ktor, serialization, coroutines, logging, and testing dependencies.
Main.kt, Server.kt, Config.kt, and tools/ToolRegistry.kt compile together with consistent packages and imports.
Every generated tool has a JSON schema, validation, implementation, and CallToolResult output.
Environment variables SERVER_NAME, VERSION, and DESCRIPTION are documented and used.
Tests use coroutine test utilities and include server creation plus at least one tool execution path.
The README commands and paths match the generated project name.
1---2name: kotlin-mcp-server-generator3description: Generate a complete Kotlin Model Context Protocol server project using io.modelcontextprotocol:kotlin-sdk, Gradle, stdio or Ktor transport, typed tools, configuration, tests, and README documentation. Use when asked to create a Kotlin MCP server, scaffold MCP tools, build a Gradle MCP project, or generate a production-ready MCP server template.4---56<!-- Generated from harness/github-copilot/skills/kotlin-mcp-server-generator/SKILL.md by harness/claude-code/scripts/convert_from_copilot.py. Edit the source, not this file. -->78# Kotlin MCP server generator910Generate a complete Kotlin MCP server project from a server name, package, tools, transport, and description. Produce a Gradle layout, MCP SDK wiring, typed tool schemas, coroutine-safe implementation, tests, and README instructions that can be copied into a repository.1112## When to invoke1314- "Generate a Kotlin MCP server project."15- "Create a Gradle MCP server using the Kotlin SDK."16- "Scaffold MCP tools with typed inputs and outputs."17- "Build a Kotlin stdio MCP server with tests and README."18- "Add Ktor SSE transport to a Kotlin MCP server."1920## Project contract2122| Area | Required output |23| --- | --- |24| Project structure | A Gradle Kotlin project with `build.gradle.kts`, `settings.gradle.kts`, `gradle.properties`, `src/main/kotlin/...`, `src/test/kotlin/...`, and `README.md`. |25| Dependencies | Official `io.modelcontextprotocol:kotlin-sdk`, Ktor transport modules, `kotlinx-serialization-json`, `kotlinx-coroutines-core`, `kotlin-logging-jvm`, `logback-classic`, and `kotlinx-coroutines-test`. |26| Runtime | A `Main.kt` that loads config, creates a `Server`, connects `StdioServerTransport`, and logs startup. |27| Tools | At least two or three useful tools with JSON schemas built with `buildJsonObject`, required fields, validation, and typed inputs/outputs. |28| Error handling | Validate required parameters before tool execution and return clear failures through Kotlin exceptions or result types such as `Result/Either` when the project already uses them. |29| Testing | Include coroutine tests with `runTest`, a `test server creation` case, and a `test tool1 execution` case or equivalent. |30| Documentation | Explain requirements, build, run, configuration, tools, development, and license in `README.md`. |3132Use placeholders only where generation truly needs user input: `PROJECT_NAME`, `PROJECT_DESCRIPTION`, `TOOL1_DESCRIPTION`, `SERVER_NAME`, `VERSION`, and `DESCRIPTION`.3334## File layout3536Create this structure, replacing `myserver` and `com/example/myserver/` with the requested project and package names:3738```text39myserver/40├── build.gradle.kts41├── settings.gradle.kts42├── gradle.properties43├── src/44│ ├── main/kotlin/com/example/myserver/45│ │ ├── Main.kt46│ │ ├── Server.kt47│ │ ├── config/Config.kt48│ │ └── tools/49│ │ ├── Tool1.kt50│ │ ├── Tool2.kt51│ │ └── ToolRegistry.kt52│ └── test/kotlin/com/example/myserver/ServerTest.kt53└── README.md54```5556Keep package declarations consistent across every file. If the artifact name differs from the package, make `settings.gradle.kts` set `rootProject.name = "PROJECT_NAME"` and make `application.mainClass` point at the generated `MainKt` class.5758## Gradle and dependencies5960Use a JVM Gradle build unless the user explicitly asks for multiplatform. The baseline dependency set is:6162```kotlin63plugins {64 kotlin("jvm") version "2.1.0"65 kotlin("plugin.serialization") version "2.1.0"66 application67}6869dependencies {70 implementation("io.modelcontextprotocol:kotlin-sdk:0.7.2")71 implementation("io.ktor:ktor-server-netty:3.0.0")72 implementation("io.ktor:ktor-client-cio:3.0.0")73 implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")74 implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")75 implementation("io.github.oshai:kotlin-logging-jvm:7.0.0")76 implementation("ch.qos.logback:logback-classic:1.5.12")77 testImplementation(kotlin("test"))78 testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0")79}8081application { mainClass.set("com.example.myserver.MainKt") }82tasks.test { useJUnitPlatform() }83kotlin { jvmToolchain(17) }84```8586If the user asks for Kotlin Multiplatform, add `jvm()`, `js(IR) { nodejs() }`, `wasmJs()`, and put `implementation("io.modelcontextprotocol:kotlin-sdk:0.7.2")` in `commonMain.dependencies`. Do not claim multiplatform support in `README.md` unless the build actually configures it.8788## Server and transport wiring8990| File | Required content |91| --- | --- |92| `Config.kt` | A serializable `Config` with `name`, `version`, and `description`; `loadConfig()` reads `SERVER_NAME`, `VERSION`, and `DESCRIPTION`, falling back to `PROJECT_NAME`, `1.0.0`, and `PROJECT_DESCRIPTION`. |93| `Main.kt` | `runBlocking`, `KotlinLogging.logger {}`, `loadConfig()`, `createServer(config)`, `StdioServerTransport()`, and `server.connect(transport)`. |94| `Server.kt` | `Server`, `ServerOptions`, `Implementation`, `ServerCapabilities.Tools()`, optional `ServerCapabilities.Resources(subscribe = true, listChanged = true)`, optional `ServerCapabilities.Prompts(listChanged = true)`, and `server.registerTools()`. |95| `ToolRegistry.kt` | `fun Server.registerTools()` that calls every generated `registerToolN()` exactly once. |9697For stdio, use:9899```kotlin100val transport = StdioServerTransport()101server.connect(transport)102```103104For SSE transport with Ktor, show the shape without mixing it into the stdio entry point unless requested:105106```kotlin107embeddedServer(Netty, port = 8080) {108 mcp { Server(/* ... */) { "Description" } }109}.start(wait = true)110```111112## Tool implementation rules113114| Concern | Rule |115| --- | --- |116| Schema | Build JSON schema with `buildJsonObject`, `putJsonObject("properties")`, `putJsonArray("required")`, `put("type", ...)`, and field descriptions. |117| Request | Type handler parameters as `CallToolRequest` when using the SDK callback signature. |118| Required input | Extract `param1` or real required fields from `request.params.arguments`; throw `IllegalArgumentException("param1 is required")` or a domain-specific message when absent. |119| Optional input | Convert `param2` or numeric optional fields safely with `(value as? Number)?.toInt() ?: 0`. |120| Result | Return `CallToolResult(content = listOf(TextContent(text = result)))` for text tools; use typed serialization for structured results when needed. |121| Async work | Use suspending functions for I/O and coroutine-friendly APIs; keep blocking work isolated. |122| Type safety | Prefer data classes, sealed classes for result states, null safety, and `kotlinx.serialization`. |123| Testability | Put business logic in private or injectable functions such as `performTool1Logic(param1, param2)`, not inline in the registration lambda. |124| Documentation | Add KDoc comments for public APIs and meaningful tool descriptions. |125126Name test fixtures explicitly, for example `test-server`, and document typed `inputs/outputs` for every generated tool. Use `kotlin-logging` consistently so dependency names and imports stay aligned.127128## README content129130The `README.md` must include this concrete operating information:131132| Section | Required detail |133| --- | --- |134| Requirements | Java 17 or higher and the Kotlin version configured by Gradle. |135| Installation | `./gradlew build`. |136| Usage | `./gradlew run`; optionally `./gradlew installDist` and `./build/install/PROJECT_NAME/bin/PROJECT_NAME`. |137| Configuration | `SERVER_NAME`, `VERSION`, and `DESCRIPTION` environment variables. |138| Available Tools | Each tool name, `TOOL1_DESCRIPTION`, inputs such as `param1` and `param2`, and output shape. |139| Development | `./gradlew test`, `./gradlew build`, and `./gradlew run --continuous` for auto-reload development; the install task writes launch scripts under `build/install/`. |140| License | State the chosen license, for example MIT, only if the user requested or accepted it. |141142## Gotchas143144- **Keep SDK examples version-consistent**: `io.modelcontextprotocol:kotlin-sdk:0.7.2`, `ktor-server-netty`, and `ktor-client-cio` examples should compile together with the selected Kotlin version.145- **Do not register phantom tools**: every call in `tools/ToolRegistry.kt` must have a matching implementation file.146- **Do not advertise multiplatform unless configured**: JVM-only builds should not claim JVM, Wasm, and iOS support.147- **Do not leave placeholders in generated code**: replace `PROJECT_NAME`, `PROJECT_DESCRIPTION`, and `TOOL1_DESCRIPTION` before final output unless the user explicitly requested a template.148149## Output template150151```markdown152## Kotlin MCP server project153154**Status:** generated | blocked155**Project:** `<PROJECT_NAME>`156**Package:** `<package.name>`157**Transport:** stdio | SSE | both158159### Files160| Path | Purpose |161| --- | --- |162| `build.gradle.kts` | Gradle Kotlin build with MCP, Ktor, serialization, coroutines, logging, and test dependencies |163| `src/main/kotlin/<package>/Main.kt` | Server entry point |164| `src/main/kotlin/<package>/Server.kt` | MCP `Server` configuration and capabilities |165| `src/main/kotlin/<package>/config/Config.kt` | Environment-backed configuration |166| `src/main/kotlin/<package>/tools/ToolRegistry.kt` | Tool registration |167| `src/test/kotlin/<package>/ServerTest.kt` | Coroutine tests |168| `README.md` | Build, run, configuration, and tool usage |169170### Commands171- `./gradlew build`172- `./gradlew test`173- `./gradlew run`174175### Notes176- <remaining setup note or "none">177```178179## Quality gate180181- [ ] `name` is `kotlin-mcp-server-generator` and matches the parent directory.182- [ ] The project layout includes all required Gradle, source, test, tools, config, and `README.md` files.183- [ ] `build.gradle.kts` includes the MCP SDK, Ktor, serialization, coroutines, logging, and testing dependencies.184- [ ] `Main.kt`, `Server.kt`, `Config.kt`, and `tools/ToolRegistry.kt` compile together with consistent packages and imports.185- [ ] Every generated tool has a JSON schema, validation, implementation, and `CallToolResult` output.186- [ ] Environment variables `SERVER_NAME`, `VERSION`, and `DESCRIPTION` are documented and used.187- [ ] Tests use coroutine test utilities and include server creation plus at least one tool execution path.188- [ ] The README commands and paths match the generated project name.
Run npx skillmds@latest add paulasilvatech/kotlin-mcp-server-generator in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Generate a complete Kotlin Model Context Protocol server project using io.modelcontextprotocol:kotlin-sdk, Gradle, stdio or Ktor transport, typed tools, configuration, tests, and README documentation. Use when asked to create a Kotlin MCP server, scaffold MCP tools, build a Gradle MCP project, or generate a production-ready MCP server template. It is listed under AI & ML on SkillMD.
SkillMD's automated safety review verdict for this skill is PASS. Independent scanners report: SkillSpector: PASS, Skill Scanner: PASS. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
paulasilvatech (@paulasilvatech) published this skill. Their other Agent Skills are listed on their SkillMD profile.