{"id":"1dd09810-0f10-4cfa-b97a-47b0caca7f69","shortId":"m94FJV","kind":"skill","title":"Kotlin Mcp Server Generator","tagline":"Awesome Copilot skill by Github","description":"# Kotlin MCP Server Project Generator\n\nGenerate a complete, production-ready Model Context Protocol (MCP) server project in Kotlin.\n\n## Project Requirements\n\nYou will create a Kotlin MCP server with:\n\n1. **Project Structure**: Gradle-based Kotlin project layout\n2. **Dependencies**: Official MCP SDK, Ktor, and kotlinx libraries\n3. **Server Setup**: Configured MCP server with transports\n4. **Tools**: At least 2-3 useful tools with typed inputs/outputs\n5. **Error Handling**: Proper exception handling and validation\n6. **Documentation**: README with setup and usage instructions\n7. **Testing**: Basic test structure with coroutines\n\n## Template Structure\n\n```\nmyserver/\n├── build.gradle.kts\n├── settings.gradle.kts\n├── gradle.properties\n├── src/\n│   ├── main/\n│   │   └── kotlin/\n│   │       └── com/example/myserver/\n│   │           ├── Main.kt\n│   │           ├── Server.kt\n│   │           ├── config/\n│   │           │   └── Config.kt\n│   │           └── tools/\n│   │               ├── Tool1.kt\n│   │               └── Tool2.kt\n│   └── test/\n│       └── kotlin/\n│           └── com/example/myserver/\n│               └── ServerTest.kt\n└── README.md\n```\n\n## build.gradle.kts Template\n\n```kotlin\nplugins {\n    kotlin(\"jvm\") version \"2.1.0\"\n    kotlin(\"plugin.serialization\") version \"2.1.0\"\n    application\n}\n\ngroup = \"com.example\"\nversion = \"1.0.0\"\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(\"io.modelcontextprotocol:kotlin-sdk:0.7.2\")\n    \n    // Ktor for transports\n    implementation(\"io.ktor:ktor-server-netty:3.0.0\")\n    implementation(\"io.ktor:ktor-client-cio:3.0.0\")\n    \n    // Serialization\n    implementation(\"org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3\")\n    \n    // Coroutines\n    implementation(\"org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0\")\n    \n    // Logging\n    implementation(\"io.github.oshai:kotlin-logging-jvm:7.0.0\")\n    implementation(\"ch.qos.logback:logback-classic:1.5.12\")\n    \n    // Testing\n    testImplementation(kotlin(\"test\"))\n    testImplementation(\"org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0\")\n}\n\napplication {\n    mainClass.set(\"com.example.myserver.MainKt\")\n}\n\ntasks.test {\n    useJUnitPlatform()\n}\n\nkotlin {\n    jvmToolchain(17)\n}\n```\n\n## settings.gradle.kts Template\n\n```kotlin\nrootProject.name = \"{{PROJECT_NAME}}\"\n```\n\n## Main.kt Template\n\n```kotlin\npackage com.example.myserver\n\nimport io.modelcontextprotocol.kotlin.sdk.server.StdioServerTransport\nimport kotlinx.coroutines.runBlocking\nimport io.github.oshai.kotlinlogging.KotlinLogging\n\nprivate val logger = KotlinLogging.logger {}\n\nfun main() = runBlocking {\n    logger.info { \"Starting MCP server...\" }\n    \n    val config = loadConfig()\n    val server = createServer(config)\n    \n    // Use stdio transport\n    val transport = StdioServerTransport()\n    \n    logger.info { \"Server '${config.name}' v${config.version} ready\" }\n    server.connect(transport)\n}\n```\n\n## Server.kt Template\n\n```kotlin\npackage com.example.myserver\n\nimport io.modelcontextprotocol.kotlin.sdk.server.Server\nimport io.modelcontextprotocol.kotlin.sdk.server.ServerOptions\nimport io.modelcontextprotocol.kotlin.sdk.Implementation\nimport io.modelcontextprotocol.kotlin.sdk.ServerCapabilities\nimport com.example.myserver.tools.registerTools\n\nfun createServer(config: Config): Server {\n    val server = Server(\n        serverInfo = Implementation(\n            name = config.name,\n            version = config.version\n        ),\n        options = ServerOptions(\n            capabilities = ServerCapabilities(\n                tools = ServerCapabilities.Tools(),\n                resources = ServerCapabilities.Resources(\n                    subscribe = true,\n                    listChanged = true\n                ),\n                prompts = ServerCapabilities.Prompts(listChanged = true)\n            )\n        )\n    ) {\n        config.description\n    }\n    \n    // Register all tools\n    server.registerTools()\n    \n    return server\n}\n```\n\n## Config.kt Template\n\n```kotlin\npackage com.example.myserver.config\n\nimport kotlinx.serialization.Serializable\n\n@Serializable\ndata class Config(\n    val name: String = \"{{PROJECT_NAME}}\",\n    val version: String = \"1.0.0\",\n    val description: String = \"{{PROJECT_DESCRIPTION}}\"\n)\n\nfun loadConfig(): Config {\n    return Config(\n        name = System.getenv(\"SERVER_NAME\") ?: \"{{PROJECT_NAME}}\",\n        version = System.getenv(\"VERSION\") ?: \"1.0.0\",\n        description = System.getenv(\"DESCRIPTION\") ?: \"{{PROJECT_DESCRIPTION}}\"\n    )\n}\n```\n\n## Tool1.kt Template\n\n```kotlin\npackage com.example.myserver.tools\n\nimport io.modelcontextprotocol.kotlin.sdk.server.Server\nimport io.modelcontextprotocol.kotlin.sdk.CallToolRequest\nimport io.modelcontextprotocol.kotlin.sdk.CallToolResult\nimport io.modelcontextprotocol.kotlin.sdk.TextContent\nimport kotlinx.serialization.json.buildJsonObject\nimport kotlinx.serialization.json.put\nimport kotlinx.serialization.json.putJsonObject\nimport kotlinx.serialization.json.putJsonArray\n\nfun Server.registerTool1() {\n    addTool(\n        name = \"tool1\",\n        description = \"Description of what tool1 does\",\n        inputSchema = buildJsonObject {\n            put(\"type\", \"object\")\n            putJsonObject(\"properties\") {\n                putJsonObject(\"param1\") {\n                    put(\"type\", \"string\")\n                    put(\"description\", \"First parameter\")\n                }\n                putJsonObject(\"param2\") {\n                    put(\"type\", \"integer\")\n                    put(\"description\", \"Optional second parameter\")\n                }\n            }\n            putJsonArray(\"required\") {\n                add(\"param1\")\n            }\n        }\n    ) { request: CallToolRequest ->\n        // Extract and validate parameters\n        val param1 = request.params.arguments[\"param1\"] as? String\n            ?: throw IllegalArgumentException(\"param1 is required\")\n        val param2 = (request.params.arguments[\"param2\"] as? Number)?.toInt() ?: 0\n        \n        // Perform tool logic\n        val result = performTool1Logic(param1, param2)\n        \n        CallToolResult(\n            content = listOf(\n                TextContent(text = result)\n            )\n        )\n    }\n}\n\nprivate fun performTool1Logic(param1: String, param2: Int): String {\n    // Implement tool logic here\n    return \"Processed: $param1 with value $param2\"\n}\n```\n\n## tools/ToolRegistry.kt Template\n\n```kotlin\npackage com.example.myserver.tools\n\nimport io.modelcontextprotocol.kotlin.sdk.server.Server\n\nfun Server.registerTools() {\n    registerTool1()\n    registerTool2()\n    // Register additional tools here\n}\n```\n\n## ServerTest.kt Template\n\n```kotlin\npackage com.example.myserver\n\nimport kotlinx.coroutines.test.runTest\nimport kotlin.test.Test\nimport kotlin.test.assertEquals\nimport kotlin.test.assertFalse\n\nclass ServerTest {\n    \n    @Test\n    fun `test server creation`() = runTest {\n        val config = Config(\n            name = \"test-server\",\n            version = \"1.0.0\",\n            description = \"Test server\"\n        )\n        \n        val server = createServer(config)\n        \n        assertEquals(\"test-server\", server.serverInfo.name)\n        assertEquals(\"1.0.0\", server.serverInfo.version)\n    }\n    \n    @Test\n    fun `test tool1 execution`() = runTest {\n        val config = Config()\n        val server = createServer(config)\n        \n        // Test tool execution\n        // Note: You'll need to implement proper testing utilities\n        // for calling tools in the server\n    }\n}\n```\n\n## README.md Template\n\n```markdown\n# {{PROJECT_NAME}}\n\nA Model Context Protocol (MCP) server built with Kotlin.\n\n## Description\n\n{{PROJECT_DESCRIPTION}}\n\n## Requirements\n\n- Java 17 or higher\n- Kotlin 2.1.0\n\n## Installation\n\nBuild the project:\n\n\\`\\`\\`bash\n./gradlew build\n\\`\\`\\`\n\n## Usage\n\nRun the server with stdio transport:\n\n\\`\\`\\`bash\n./gradlew run\n\\`\\`\\`\n\nOr build and run the jar:\n\n\\`\\`\\`bash\n./gradlew installDist\n./build/install/{{PROJECT_NAME}}/bin/{{PROJECT_NAME}}\n\\`\\`\\`\n\n## Configuration\n\nConfigure via environment variables:\n\n- `SERVER_NAME`: Server name (default: \"{{PROJECT_NAME}}\")\n- `VERSION`: Server version (default: \"1.0.0\")\n- `DESCRIPTION`: Server description\n\n## Available Tools\n\n### tool1\n{{TOOL1_DESCRIPTION}}\n\n**Input:**\n- `param1` (string, required): First parameter\n- `param2` (integer, optional): Second parameter\n\n**Output:**\n- Text result of the operation\n\n## Development\n\nRun tests:\n\n\\`\\`\\`bash\n./gradlew test\n\\`\\`\\`\n\nBuild:\n\n\\`\\`\\`bash\n./gradlew build\n\\`\\`\\`\n\nRun with auto-reload (development):\n\n\\`\\`\\`bash\n./gradlew run --continuous\n\\`\\`\\`\n\n## Multiplatform\n\nThis project uses Kotlin Multiplatform and can target JVM, Wasm, and iOS.\nSee `build.gradle.kts` for platform configuration.\n\n## License\n\nMIT\n```\n\n## Generation Instructions\n\nWhen generating a Kotlin MCP server:\n\n1. **Gradle Setup**: Create proper `build.gradle.kts` with all dependencies\n2. **Package Structure**: Follow Kotlin package conventions\n3. **Type Safety**: Use data classes and kotlinx.serialization\n4. **Coroutines**: All operations should be suspending functions\n5. **Error Handling**: Use Kotlin exceptions and validation\n6. **JSON Schemas**: Use `buildJsonObject` for tool schemas\n7. **Testing**: Include coroutine test utilities\n8. **Logging**: Use kotlin-logging for structured logging\n9. **Configuration**: Use data classes and environment variables\n10. **Documentation**: KDoc comments for public APIs\n\n## Best Practices\n\n- Use suspending functions for all async operations\n- Leverage Kotlin's null safety and type system\n- Use data classes for structured data\n- Apply kotlinx.serialization for JSON handling\n- Use sealed classes for result types\n- Implement proper error handling with Result/Either patterns\n- Write tests using kotlinx-coroutines-test\n- Use dependency injection for testability\n- Follow Kotlin coding conventions\n- Use meaningful names and KDoc comments\n\n## Transport Options\n\n### Stdio Transport\n```kotlin\nval transport = StdioServerTransport()\nserver.connect(transport)\n```\n\n### SSE Transport (Ktor)\n```kotlin\nembeddedServer(Netty, port = 8080) {\n    mcp {\n        Server(/*...*/) { \"Description\" }\n    }\n}.start(wait = true)\n```\n\n## Multiplatform Configuration\n\nFor multiplatform projects, add to `build.gradle.kts`:\n\n```kotlin\nkotlin {\n    jvm()\n    js(IR) { nodejs() }\n    wasmJs()\n    \n    sourceSets {\n        commonMain.dependencies {\n            implementation(\"io.modelcontextprotocol:kotlin-sdk:0.7.2\")\n        }\n    }\n}\n```","tags":["kotlin","mcp","server","generator","awesome","copilot","github"],"capabilities":["skill","source-github","category-awesome-copilot"],"categories":["awesome-copilot"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/github/awesome-copilot/kotlin-mcp-server-generator","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"install_from":"skills.sh"}},"qualityScore":"0.300","qualityRationale":"deterministic score 0.30 from registry signals: · indexed on skills.sh · published under github/awesome-copilot","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T08:40:12.552Z","embedding":null,"createdAt":"2026-04-18T20:26:13.861Z","updatedAt":"2026-04-22T08:40:12.552Z","lastSeenAt":"2026-04-22T08:40:12.552Z","tsv":"'-3':70 '/bin':622 '/build/install':619 '/gradlew':598,608,617,671,675,684 '0':445 '0.7.2':146,902 '1':39,715 '1.0.0':137,333,353,522,536,641 '1.5.12':193 '1.7.3':171 '1.9.0':179,204 '10':786 '17':212,588 '2':48,69,724 '2.1.0':128,132,592 '3':57,731 '3.0.0':156,163 '4':65,739 '5':76,747 '6':84,755 '7':92,763 '7.0.0':187 '8':769 '8080':873 '9':778 'add':419,885 'addit':490 'addtool':382 'api':792 'appli':816 'applic':133,205 'assertequ':530,535 'async':800 'auto':680 'auto-reload':679 'avail':645 'awesom':5 'base':44 'bash':597,607,616,670,674,683 'basic':94 'best':793 'build':594,599,611,673,676 'build.gradle.kts':102,121,701,720,887 'buildjsonobject':392,759 'built':580 'call':564 'calltoolrequest':422 'calltoolresult':454 'capabl':293 'category-awesome-copilot' 'ch.qos.logback':189 'cio':162 'class':323,506,736,782,812,823 'classic':192 'client':161 'code':848 'com.example':135 'com.example.myserver':223,266,497 'com.example.myserver.config':318 'com.example.myserver.mainkt':207 'com.example.myserver.tools':363,482 'com.example.myserver.tools.registertools':276 'com/example/myserver':108,118 'comment':789,855 'commonmain.dependencies':896 'complet':17 'config':111,242,247,279,280,324,341,343,515,516,529,545,546,550 'config.description':307 'config.kt':112,314 'config.name':256,288 'config.version':258,290 'configur':60,625,626,704,779,881 'content':455 'context':22,576 'continu':686 'convent':730,849 'copilot':6 'core':178 'coroutin':98,172,177,202,740,766,839 'creat':33,718 'createserv':246,278,528,549 'creation':512 'data':322,735,781,811,815 'default':634,640 'depend':49,140,723,842 'descript':335,338,354,356,358,385,386,404,413,523,583,585,642,644,649,876 'develop':667,682 'document':85,787 'embeddedserv':870 'environ':628,784 'error':77,748,829 'except':80,752 'execut':542,553 'extract':423 'first':405,654 'follow':727,846 'fun':234,277,339,380,461,485,509,539 'function':746,797 'generat':4,14,15,707,710 'github':9 'gradl':43,716 'gradle-bas':42 'gradle.properties':104 'group':134 'handl':78,81,749,820,830 'higher':590 'illegalargumentexcept':434 'implement':141,150,157,165,173,181,188,286,468,559,827,897 'import':224,226,228,267,269,271,273,275,319,364,366,368,370,372,374,376,378,483,498,500,502,504 'includ':765 'inject':843 'input':650 'inputs/outputs':75 'inputschema':391 'instal':593 'installdist':618 'instruct':91,708 'int':466 'integ':411,657 'io':699 'io.github.oshai':182 'io.github.oshai.kotlinlogging.kotlinlogging':229 'io.ktor':151,158 'io.modelcontextprotocol':142,898 'io.modelcontextprotocol.kotlin.sdk.calltoolrequest':367 'io.modelcontextprotocol.kotlin.sdk.calltoolresult':369 'io.modelcontextprotocol.kotlin.sdk.implementation':272 'io.modelcontextprotocol.kotlin.sdk.server.server':268,365,484 'io.modelcontextprotocol.kotlin.sdk.server.serveroptions':270 'io.modelcontextprotocol.kotlin.sdk.server.stdioservertransport':225 'io.modelcontextprotocol.kotlin.sdk.servercapabilities':274 'io.modelcontextprotocol.kotlin.sdk.textcontent':371 'ir':892 'jar':615 'java':587 'js':891 'json':170,756,819 'jvm':126,186,696,890 'jvmtoolchain':211 'kdoc':788,854 'kotlin':1,10,28,35,45,107,117,123,125,129,144,184,196,210,215,221,264,316,361,480,495,582,591,691,712,728,751,773,803,847,860,869,888,889,900 'kotlin-log':772 'kotlin-logging-jvm':183 'kotlin-sdk':143,899 'kotlin.test.assertequals':503 'kotlin.test.assertfalse':505 'kotlin.test.test':501 'kotlinlogging.logger':233 'kotlinx':55,168,176,201,838 'kotlinx-coroutines-cor':175 'kotlinx-coroutines-test':200,837 'kotlinx-serialization-json':167 'kotlinx.coroutines.runblocking':227 'kotlinx.coroutines.test.runtest':499 'kotlinx.serialization':738,817 'kotlinx.serialization.json.buildjsonobject':373 'kotlinx.serialization.json.put':375 'kotlinx.serialization.json.putjsonarray':379 'kotlinx.serialization.json.putjsonobject':377 'kotlinx.serialization.serializable':320 'ktor':53,147,153,160,868 'ktor-client-cio':159 'ktor-server-netti':152 'layout':47 'least':68 'leverag':802 'librari':56 'licens':705 'listchang':301,305 'listof':456 'll':556 'loadconfig':243,340 'log':180,185,770,774,777 'logback':191 'logback-class':190 'logger':232 'logger.info':237,254 'logic':448,470 'main':106,235 'main.kt':109,219 'mainclass.set':206 'markdown':571 'mavencentr':139 'mcp':2,11,24,36,51,61,239,578,713,874 'meaning':851 'mit':706 'model':21,575 'multiplatform':687,692,880,883 'myserv':101 'name':218,287,326,329,344,347,349,383,517,573,621,624,631,633,636,852 'need':557 'netti':155,871 'nodej':893 'note':554 'null':805 'number':443 'object':395 'offici':50 'oper':666,742,801 'option':291,414,658,857 'org.jetbrains.kotlinx':166,174,199 'output':661 'packag':222,265,317,362,481,496,725,729 'param1':399,420,428,430,435,452,463,474,651 'param2':408,439,441,453,465,477,656 'paramet':406,416,426,655,660 'pattern':833 'perform':446 'performtool1logic':451,462 'platform':703 'plugin':124 'plugin.serialization':130 'port':872 'practic':794 'privat':230,460 'process':473 'product':19 'production-readi':18 'project':13,26,29,40,46,217,328,337,348,357,572,584,596,620,623,635,689,884 'prompt':303 'proper':79,560,719,828 'properti':397 'protocol':23,577 'public':791 'put':393,400,403,409,412 'putjsonarray':417 'putjsonobject':396,398,407 'readi':20,259 'readm':86 'readme.md':120,569 'regist':308,489 'registertool1':487 'registertool2':488 'reload':681 'repositori':138 'request':421 'request.params.arguments':429,440 'requir':30,418,437,586,653 'resourc':297 'result':450,459,663,825 'result/either':832 'return':312,342,472 'rootproject.name':216 'run':601,609,613,668,677,685 'runblock':236 'runtest':513,543 'safeti':733,806 'schema':757,762 'sdk':52,145,901 'seal':822 'second':415,659 'see':700 'serial':164,169 'serializ':321 'server':3,12,25,37,58,62,154,240,245,255,281,283,284,313,346,511,520,525,527,533,548,568,579,603,630,632,638,643,714,875 'server.connect':260,864 'server.kt':110,262 'server.registertool1':381 'server.registertools':311,486 'server.serverinfo.name':534 'server.serverinfo.version':537 'servercap':294 'servercapabilities.prompts':304 'servercapabilities.resources':298 'servercapabilities.tools':296 'serverinfo':285 'serveropt':292 'servertest':507 'servertest.kt':119,493 'settings.gradle.kts':103,213 'setup':59,88,717 'skill':7 'source-github' 'sourceset':895 'src':105 'sse':866 'start':238,877 'stdio':249,605,858 'stdioservertransport':253,863 'string':327,332,336,402,432,464,467,652 'structur':41,96,100,726,776,814 'subscrib':299 'suspend':745,796 'system':809 'system.getenv':345,351,355 'target':695 'tasks.test':208 'templat':99,122,214,220,263,315,360,479,494,570 'test':93,95,116,194,197,203,508,510,519,524,532,538,540,551,561,669,672,764,767,835,840 'test-serv':518,531 'testabl':845 'testimplement':195,198 'text':458,662 'textcont':457 'throw':433 'toint':444 'tool':66,72,113,295,310,447,469,491,552,565,646,761 'tool1':384,389,541,647,648 'tool1.kt':114,359 'tool2.kt':115 'tools/toolregistry.kt':478 'transport':64,149,250,252,261,606,856,859,862,865,867 'true':300,302,306,879 'type':74,394,401,410,732,808,826 'usag':90,600 'use':71,248,690,734,750,758,771,780,795,810,821,836,841,850 'usejunitplatform':209 'util':562,768 'v':257 'val':231,241,244,251,282,325,330,334,427,438,449,514,526,544,547,861 'valid':83,425,754 'valu':476 'variabl':629,785 'version':127,131,136,289,331,350,352,521,637,639 'via':627 'wait':878 'wasm':697 'wasmj':894 'write':834","prices":[{"id":"0936455d-789c-48c9-b6f1-1bd32044d9df","listingId":"1dd09810-0f10-4cfa-b97a-47b0caca7f69","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"github","category":"awesome-copilot","install_from":"skills.sh"},"createdAt":"2026-04-18T20:26:13.861Z"}],"sources":[{"listingId":"1dd09810-0f10-4cfa-b97a-47b0caca7f69","source":"github","sourceId":"github/awesome-copilot/kotlin-mcp-server-generator","sourceUrl":"https://github.com/github/awesome-copilot/tree/main/skills/kotlin-mcp-server-generator","isPrimary":false,"firstSeenAt":"2026-04-18T21:49:59.899Z","lastSeenAt":"2026-04-22T06:52:24.376Z"},{"listingId":"1dd09810-0f10-4cfa-b97a-47b0caca7f69","source":"skills_sh","sourceId":"github/awesome-copilot/kotlin-mcp-server-generator","sourceUrl":"https://skills.sh/github/awesome-copilot/kotlin-mcp-server-generator","isPrimary":true,"firstSeenAt":"2026-04-18T20:26:13.861Z","lastSeenAt":"2026-04-22T08:40:12.552Z"}],"details":{"listingId":"1dd09810-0f10-4cfa-b97a-47b0caca7f69","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"github","slug":"kotlin-mcp-server-generator","source":"skills_sh","category":"awesome-copilot","skills_sh_url":"https://skills.sh/github/awesome-copilot/kotlin-mcp-server-generator"},"updatedAt":"2026-04-22T08:40:12.552Z"}}