kotlin-mcp-server-generator

Par github · awesome-copilot

Générez un projet serveur MCP Kotlin complet avec une structure appropriée, des dépendances et une implémentation utilisant la bibliothèque officielle `io.modelcontextprotocol:kotlin-sdk`.

npx skills add https://github.com/github/awesome-copilot --skill kotlin-mcp-server-generator

Générateur de Projets de Serveurs Kotlin MCP

Générez un projet de serveur Model Context Protocol (MCP) complet et prêt pour la production en Kotlin.

Exigences du Projet

Vous allez créer un serveur Kotlin MCP avec :

  1. Structure du Projet : Structure de projet Kotlin basée sur Gradle
  2. Dépendances : SDK MCP officiel, Ktor et bibliothèques kotlinx
  3. Configuration du Serveur : Serveur MCP configuré avec transports
  4. Outils : Au moins 2-3 outils utiles avec entrées/sorties typées
  5. Gestion des Erreurs : Gestion appropriée des exceptions et validation
  6. Documentation : README avec instructions de configuration et d'utilisation
  7. Tests : Structure de test basique avec coroutines

Structure des Modèles

myserver/
├── build.gradle.kts
├── settings.gradle.kts
├── gradle.properties
├── src/
│   ├── main/
│   │   └── kotlin/
│   │       └── com/example/myserver/
│   │           ├── Main.kt
│   │           ├── Server.kt
│   │           ├── config/
│   │           │   └── Config.kt
│   │           └── tools/
│   │               ├── Tool1.kt
│   │               └── Tool2.kt
│   └── test/
│       └── kotlin/
│           └── com/example/myserver/
│               └── ServerTest.kt
└── README.md

Modèle build.gradle.kts

plugins {
    kotlin("jvm") version "2.1.0"
    kotlin("plugin.serialization") version "2.1.0"
    application
}

group = "com.example"
version = "1.0.0"

repositories {
    mavenCentral()
}

dependencies {
    implementation("io.modelcontextprotocol:kotlin-sdk:0.7.2")

    // Ktor for transports
    implementation("io.ktor:ktor-server-netty:3.0.0")
    implementation("io.ktor:ktor-client-cio:3.0.0")

    // Serialization
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")

    // Coroutines
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")

    // Logging
    implementation("io.github.oshai:kotlin-logging-jvm:7.0.0")
    implementation("ch.qos.logback:logback-classic:1.5.12")

    // Testing
    testImplementation(kotlin("test"))
    testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0")
}

application {
    mainClass.set("com.example.myserver.MainKt")
}

tasks.test {
    useJUnitPlatform()
}

kotlin {
    jvmToolchain(17)
}

Modèle settings.gradle.kts

rootProject.name = "{{PROJECT_NAME}}"

Modèle Main.kt

package com.example.myserver

import io.modelcontextprotocol.kotlin.sdk.server.StdioServerTransport
import kotlinx.coroutines.runBlocking
import io.github.oshai.kotlinlogging.KotlinLogging

private val logger = KotlinLogging.logger {}

fun main() = runBlocking {
    logger.info { "Starting MCP server..." }

    val config = loadConfig()
    val server = createServer(config)

    // Use stdio transport
    val transport = StdioServerTransport()

    logger.info { "Server '${config.name}' v${config.version} ready" }
    server.connect(transport)
}

Modèle Server.kt

package com.example.myserver

import io.modelcontextprotocol.kotlin.sdk.server.Server
import io.modelcontextprotocol.kotlin.sdk.server.ServerOptions
import io.modelcontextprotocol.kotlin.sdk.Implementation
import io.modelcontextprotocol.kotlin.sdk.ServerCapabilities
import com.example.myserver.tools.registerTools

fun createServer(config: Config): Server {
    val server = Server(
        serverInfo = Implementation(
            name = config.name,
            version = config.version
        ),
        options = ServerOptions(
            capabilities = ServerCapabilities(
                tools = ServerCapabilities.Tools(),
                resources = ServerCapabilities.Resources(
                    subscribe = true,
                    listChanged = true
                ),
                prompts = ServerCapabilities.Prompts(listChanged = true)
            )
        )
    ) {
        config.description
    }

    // Register all tools
    server.registerTools()

    return server
}

Modèle Config.kt

package com.example.myserver.config

import kotlinx.serialization.Serializable

@Serializable
data class Config(
    val name: String = "{{PROJECT_NAME}}",
    val version: String = "1.0.0",
    val description: String = "{{PROJECT_DESCRIPTION}}"
)

fun loadConfig(): Config {
    return Config(
        name = System.getenv("SERVER_NAME") ?: "{{PROJECT_NAME}}",
        version = System.getenv("VERSION") ?: "1.0.0",
        description = System.getenv("DESCRIPTION") ?: "{{PROJECT_DESCRIPTION}}"
    )
}

Modèle Tool1.kt

package com.example.myserver.tools

import io.modelcontextprotocol.kotlin.sdk.server.Server
import io.modelcontextprotocol.kotlin.sdk.CallToolRequest
import io.modelcontextprotocol.kotlin.sdk.CallToolResult
import io.modelcontextprotocol.kotlin.sdk.TextContent
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put
import kotlinx.serialization.json.putJsonObject
import kotlinx.serialization.json.putJsonArray

fun Server.registerTool1() {
    addTool(
        name = "tool1",
        description = "Description of what tool1 does",
        inputSchema = buildJsonObject {
            put("type", "object")
            putJsonObject("properties") {
                putJsonObject("param1") {
                    put("type", "string")
                    put("description", "First parameter")
                }
                putJsonObject("param2") {
                    put("type", "integer")
                    put("description", "Optional second parameter")
                }
            }
            putJsonArray("required") {
                add("param1")
            }
        }
    ) { request: CallToolRequest ->
        // Extract and validate parameters
        val param1 = request.params.arguments["param1"] as? String
            ?: throw IllegalArgumentException("param1 is required")
        val param2 = (request.params.arguments["param2"] as? Number)?.toInt() ?: 0

        // Perform tool logic
        val result = performTool1Logic(param1, param2)

        CallToolResult(
            content = listOf(
                TextContent(text = result)
            )
        )
    }
}

private fun performTool1Logic(param1: String, param2: Int): String {
    // Implement tool logic here
    return "Processed: $param1 with value $param2"
}

Modèle tools/ToolRegistry.kt

package com.example.myserver.tools

import io.modelcontextprotocol.kotlin.sdk.server.Server

fun Server.registerTools() {
    registerTool1()
    registerTool2()
    // Register additional tools here
}

Modèle ServerTest.kt

package com.example.myserver

import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse

class ServerTest {

    @Test
    fun `test server creation`() = runTest {
        val config = Config(
            name = "test-server",
            version = "1.0.0",
            description = "Test server"
        )

        val server = createServer(config)

        assertEquals("test-server", server.serverInfo.name)
        assertEquals("1.0.0", server.serverInfo.version)
    }

    @Test
    fun `test tool1 execution`() = runTest {
        val config = Config()
        val server = createServer(config)

        // Test tool execution
        // Note: You'll need to implement proper testing utilities
        // for calling tools in the server
    }
}

Modèle README.md

# {{PROJECT_NAME}}

A Model Context Protocol (MCP) server built with Kotlin.

## Description

{{PROJECT_DESCRIPTION}}

## Requirements

- Java 17 or higher
- Kotlin 2.1.0

## Installation

Build the project:

\`\`\`bash
./gradlew build
\`\`\`

## Usage

Run the server with stdio transport:

\`\`\`bash
./gradlew run
\`\`\`

Or build and run the jar:

\`\`\`bash
./gradlew installDist
./build/install/{{PROJECT_NAME}}/bin/{{PROJECT_NAME}}
\`\`\`

## Configuration

Configure via environment variables:

- `SERVER_NAME`: Server name (default: "{{PROJECT_NAME}}")
- `VERSION`: Server version (default: "1.0.0")
- `DESCRIPTION`: Server description

## Available Tools

### tool1
{{TOOL1_DESCRIPTION}}

**Input:**
- `param1` (string, required): First parameter
- `param2` (integer, optional): Second parameter

**Output:**
- Text result of the operation

## Development

Run tests:

\`\`\`bash
./gradlew test
\`\`\`

Build:

\`\`\`bash
./gradlew build
\`\`\`

Run with auto-reload (development):

\`\`\`bash
./gradlew run --continuous
\`\`\`

## Multiplatform

This project uses Kotlin Multiplatform and can target JVM, Wasm, and iOS.
See `build.gradle.kts` for platform configuration.

## License

MIT

Instructions de Génération

Lors de la génération d'un serveur Kotlin MCP :

  1. Configuration Gradle : Créez un build.gradle.kts approprié avec toutes les dépendances
  2. Structure des Packages : Suivez les conventions de packages Kotlin
  3. Sécurité des Types : Utilisez des data classes et kotlinx.serialization
  4. Coroutines : Toutes les opérations doivent être des fonctions suspensives
  5. Gestion des Erreurs : Utilisez les exceptions Kotlin et la validation
  6. Schémas JSON : Utilisez buildJsonObject pour les schémas d'outils
  7. Tests : Incluez des utilitaires de test de coroutines
  8. Logging : Utilisez kotlin-logging pour la journalisation structurée
  9. Configuration : Utilisez des data classes et des variables d'environnement
  10. Documentation : Ajoutez des commentaires KDoc pour les APIs publiques

Bonnes Pratiques

  • Utilisez des fonctions suspensives pour toutes les opérations asynchrones
  • Tirez parti de la sécurité des nulls et du système de types de Kotlin
  • Utilisez des data classes pour les données structurées
  • Appliquez kotlinx.serialization pour la gestion JSON
  • Utilisez les sealed classes pour les types de résultats
  • Implémentez une gestion appropriée des erreurs avec des patterns Result/Either
  • Écrivez les tests avec kotlinx-coroutines-test
  • Utilisez l'injection de dépendances pour la testabilité
  • Suivez les conventions de codage Kotlin
  • Utilisez des noms significatifs et des commentaires KDoc

Options de Transport

Transport Stdio

val transport = StdioServerTransport()
server.connect(transport)

Transport SSE (Ktor)

embeddedServer(Netty, port = 8080) {
    mcp {
        Server(/*...*/) { "Description" }
    }
}.start(wait = true)

Configuration Multiplateforme

Pour les projets multiplateformes, ajoutez à build.gradle.kts :

kotlin {
    jvm()
    js(IR) { nodejs() }
    wasmJs()

    sourceSets {
        commonMain.dependencies {
            implementation("io.modelcontextprotocol:kotlin-sdk:0.7.2")
        }
    }
}

Skills similaires