ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

使用 kotlin-sdk 构建 Kotlin MCP Server:从 Server 创建到工具、资源、提示词与传输的完整实战指南

使用 kotlin-sdk 构建 Kotlin MCP Server:从 Server 创建到工具、资源、提示词与传输的完整实战指南 使用 kotlin-sdk 构建 Kotlin MCP Server从 Server 创建到工具、资源、提示词与传输的完整实战指南【免费下载链接】awesome-copilotCommunity-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilot本文以 awesome-copilot 仓库中的 Kotlin MCP Server 开发指南 为骨架结合仓库内配套的 kotlin-mcp-server-generator 技能、kotlin-mcp-development 插件 与 kotlin-mcp-expert Agent系统讲解使用官方io.modelcontextprotocol:kotlin-sdk在 Kotlin 中构建 Model Context ProtocolMCP服务端的完整路径。读完本文你将掌握 MCP Server 的创建与能力声明、Tool/Resource/Prompt 三类原语的注册方法、Stdio 与 SSE 两种传输配置、协程并发与错误处理模式以及 Gradle 构建、多平台支持、测试和工程化最佳实践可直接落地为可运行、可测试的生产级 Kotlin MCP 服务。前置准备Gradle 依赖与工程配置构建 Kotlin MCP Server 的第一步是配置build.gradle.kts。官方 SDK 以io.modelcontextprotocol:kotlin-sdk为核心配合 Ktor负责 SSE/HTTP 传输、kotlinx.serialization负责 JSON 序列化与 Schema 构建以及 kotlinx.coroutines异步支持。指南给出的完整依赖配置如下plugins { kotlin(jvm) version 2.1.0 kotlin(plugin.serialization) version 2.1.0 } repositories { mavenCentral() } dependencies { implementation(io.modelcontextprotocol:kotlin-sdk:0.7.2) // For client transport implementation(io.ktor:ktor-client-cio:3.0.0) // For server transport implementation(io.ktor:ktor-server-netty:3.0.0) // For JSON serialization implementation(org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3) // For coroutines implementation(org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0) }各依赖在工程中的职责可归纳如下依赖版本职责io.modelcontextprotocol:kotlin-sdk0.7.2MCP 协议核心Server、ServerCapabilities、CallToolRequest等类型均由此提供io.ktor:ktor-client-cio3.0.0客户端传输如需作为 MCP 客户端访问其他服务io.ktor:ktor-server-netty3.0.0服务端传输为 SSE 模式的embeddedServer提供 Netty 引擎kotlinx-serialization-json1.7.3类型安全的 JSON 序列化与buildJsonObjectSchema DSLkotlinx-coroutines-core1.9.0协程与结构化并发支持若你的目标是直接生成一个完整的可运行工程仓库中的 kotlin-mcp-server-generator 技能 给出了更为工程化的模板它在上述依赖基础上额外补充了kotlin(jvm)的application插件、日志依赖kotlin-logging-jvm与logback-classic、测试依赖kotlinx-coroutines-test并通过jvmToolchain(17)锁定 JDK 17 工具链README 模板中同样要求「Java 17 or higher / Kotlin 2.1.0」。技能模板的标准项目结构如下myserver/ ├── build.gradle.kts ├── settings.gradle.kts ├── gradle.properties ├── src/ │ ├── main/ │ │ └── kotlin/ │ │ └── com/example/myserver/ │ │ ├── Main.kt # 入口加载配置、创建 Server、连接 stdio │ │ ├── Server.kt # createServer(config)组装 Server 与能力 │ │ ├── config/ │ │ │ └── Config.kt # Serializable 配置数据类 │ │ └── tools/ │ │ ├── Tool1.kt # 单个工具注册扩展函数形式 │ │ └── Tool2.kt │ └── test/ │ └── kotlin/ │ └── com/example/myserver/ │ └── ServerTest.kt └── README.md从源码结构可以推断该技能倾向于「一个工具一个文件、以Server扩展函数组织注册逻辑、配置与主流程分离」的分层风格这与后续「依赖注入」「扩展函数」等模式一脉相承。创建 MCP ServerServer 类与能力声明MCP 协议中服务端通过initialize握手向客户端上报身份信息Implementation与所支持的能力ServerCapabilities。指南推荐的创建方式如下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 val server Server( serverInfo Implementation( name my-server, version 1.0.0 ), options ServerOptions( capabilities ServerCapabilities( tools ServerCapabilities.Tools(), resources ServerCapabilities.Resources( subscribe true, listChanged true ), prompts ServerCapabilities.Prompts(listChanged true) ) ) ) { Server description goes here }关键点说明Implementation(name, version)向客户端声明服务身份name 与 version 会被客户端用于展示与版本协商。ServerCapabilities.Tools()声明支持 Tools 能力。若服务不注册任何工具可不声明。ServerCapabilities.Resources(subscribe true, listChanged true)声明资源能力subscribe表示支持客户端订阅资源变更listChanged表示服务端会在资源列表变化时推送通知。ServerCapabilities.Prompts(listChanged true)声明提示词模板能力listChanged表示提示词列表变化时可推送变更通知。末尾的 lambda 块用于提供服务的文本描述即示例中的Server description goes here该描述会随initialize响应或服务信息返回给客户端。仓库中的 kotlin-mcp-server-generator 技能模板 Server.kt 将这一过程封装为createServer(config: Config): Server工厂函数并使用config.description作为服务描述随后统一调用server.registerTools()完成工具注册——这种「工厂函数 扩展函数注册」的组合正是该技能推荐的工程化组织方式。注册 Tool输入 Schema、参数提取与结果构造Tool 是 MCP 中模型可主动调用的能力单元。使用server.addTool()注册需要提供名称、描述、JSON Schema 格式的inputSchema以及一个以CallToolRequest为入参的挂起处理函数import io.modelcontextprotocol.kotlin.sdk.CallToolRequest import io.modelcontextprotocol.kotlin.sdk.CallToolResult import io.modelcontextprotocol.kotlin.sdk.TextContent server.addTool( name search, description Search for information, inputSchema buildJsonObject { put(type, object) putJsonObject(properties) { putJsonObject(query) { put(type, string) put(description, The search query) } putJsonObject(limit) { put(type, integer) put(description, Maximum results to return) } } putJsonArray(required) { add(query) } } ) { request: CallToolRequest - val query request.params.arguments[query] as? String ?: throw IllegalArgumentException(query is required) val limit (request.params.arguments[limit] as? Number)?.toInt() ?: 10 // Perform search val results performSearch(query, limit) CallToolResult( content listOf( TextContent( text results.joinToString(\n) ) ) ) }实战要点Schema 与参数解耦inputSchema用buildJsonObjectDSL 描述参数类型处理函数内再通过request.params.arguments[query]取出实际值。注意arguments是MapString, JsonElement类型的结构化数据因此字符串需用as? String安全转换整数需经(as? Number)?.toInt()转换——这也是处理函数内的典型「解码」步骤。默认值limit在缺省时回退为10这种「可空安全转换 ?:兜底」的写法是 Kotlin 空安全的自然表达。结果构造CallToolResult(content listOf(TextContent(text ...)))返回文本内容MCP 客户端会把content数组作为模型可见的返回体。必要参数校验对必填参数缺失直接throw IllegalArgumentException配合后续错误处理模式统一转换为带isError标记的结果返回。从 kotlin-mcp-expert Agent 的指导风格可以确认这类「Schema 定义 → 挂起处理函数 → 参数提取与校验 → 结果构造」的流程是该 SDK 下 Tool 开发的标准套路Agent 在回答时会始终遵循此顺序给出完整可运行代码。注册 ResourceURI 驱动的数据提供与变更通知Resource 用于向客户端暴露结构化或文件类数据客户端通过 URI 读取。使用server.addResource()注册import io.modelcontextprotocol.kotlin.sdk.ReadResourceRequest import io.modelcontextprotocol.kotlin.sdk.ReadResourceResult import io.modelcontextprotocol.kotlin.sdk.TextResourceContents server.addResource( uri file:///data/example.txt, name Example Data, description Example resource data, mimeType text/plain ) { request: ReadResourceRequest - val content loadResourceContent(request.uri) ReadResourceResult( contents listOf( TextResourceContents( text content, uri request.uri, mimeType text/plain ) ) ) }要点uri是资源的全局标识示例为file:///data/example.txt客户端发起resources/read请求时携带该 URI。注册时即可声明mimeType如text/plain、application/json返回内容时再次携带以保持一致性。处理函数入参为ReadResourceRequest可从request.uri获知客户端请求的资源地址从而按需加载内容。资源生命周期动态数据与变更通知对于频繁更新的动态资源指南给出了「读取当前状态 主动推送变更」的完整模式server.addResource( uri file:///dynamic/data, name Dynamic Data, description Frequently updated data, mimeType application/json ) { request - // Provide current state ReadResourceResult( contents listOf( TextResourceContents( text getCurrentData(), uri request.uri, mimeType application/json ) ) ) } // Notify clients when resource changes server.notifyResourceListChanged()结合 Server 创建时ServerCapabilities.Resources(subscribe true, listChanged true)的声明这里的notifyResourceListChanged()会将「资源列表已变更」的服务器推送通知发给已订阅的客户端从而实现动态资源的生命周期管理客户端可以订阅某个资源、感知列表变化并重新拉取最新内容。这组 API 与 kotlin-mcp-expert Agent 中列出的「Resource update notifications withnotifyResourceListChanged()」要点完全对应。注册 Prompt可复用提示词模板Prompt 用于暴露可复用的提示词模板模型或用户可按模板名填充参数后获取结构化消息。使用server.addPrompt()注册import io.modelcontextprotocol.kotlin.sdk.GetPromptRequest import io.modelcontextprotocol.kotlin.sdk.GetPromptResult import io.modelcontextprotocol.kotlin.sdk.PromptMessage import io.modelcontextprotocol.kotlin.sdk.Role server.addPrompt( name analyze, description Analyze a topic, arguments listOf( PromptArgument( name topic, description The topic to analyze, required true ) ) ) { request: GetPromptRequest - val topic request.params.arguments?.get(topic) as? String ?: throw IllegalArgumentException(topic is required) GetPromptResult( description Analyze the given topic, messages listOf( PromptMessage( role Role.User, content TextContent( text Analyze this topic: $topic ) ) ) ) }要点arguments声明模板的入参清单PromptArgument(name, description, required)描述每个参数的语义与是否必填。处理函数从request.params.arguments中提取参数并拼接提示词文本。返回GetPromptResult其中messages为PromptMessage列表每条消息包含role如Role.User与content复用TextContent。这为「将常用分析、审查、写作任务固化为模板」提供了协议层面的支持。传输层配置Stdio 与 SSEKtorMCP Server 需要选定一种传输方式与客户端通信。指南覆盖了两种主流方式。Stdio 传输适合本地 CLI 集成Stdio标准输入/输出模式适合作为本地进程由宿主如编辑器、CLI拉起通过 stdin/stdout 交换 JSON-RPC 消息import io.modelcontextprotocol.kotlin.sdk.server.StdioServerTransport suspend fun main() { val transport StdioServerTransport() server.connect(transport) }server.connect(transport)是挂起函数会一直运行到连接结束。在 kotlin-mcp-server-generator 技能模板 Main.kt 中入口写作fun main() runBlocking { ...; server.connect(transport) }并先通过loadConfig()读取环境变量、createServer(config)组装服务再打印启动日志后连接——这是 Stdio 模式的标准启动序列。SSE 传输基于 Ktor 的 HTTP 服务SSEServer-Sent Events模式将 MCP Server 暴露为 HTTP 服务适合远程部署与多客户端访问import io.ktor.server.application.* import io.ktor.server.engine.* import io.ktor.server.netty.* import io.modelcontextprotocol.kotlin.sdk.server.mcp fun main() { embeddedServer(Netty, port 8080) { mcp { Server( serverInfo Implementation( name sse-server, version 1.0.0 ), options ServerOptions( capabilities ServerCapabilities( tools ServerCapabilities.Tools() ) ) ) { SSE-based MCP server } } }.start(wait true) }要点embeddedServer(Netty, port 8080)启动 Ktor Netty 引擎port可按需调整。mcp { ... }是 SDK 提供的 Ktor 插件式扩展io.modelcontextprotocol.kotlin.sdk.server.mcp在插件块内直接构造Server实例即可完成挂载。.start(wait true)阻塞当前线程直至服务器关闭。两种传输的选型建议场景推荐传输说明本地 CLI / 编辑器集成的子进程服务Stdio进程级通信无需开放端口适合./gradlew run或安装脚本直接拉起远程 HTTP 服务 / 多客户端并发访问SSEKtor端口暴露适合部署到服务器或容器开发期热更新Stdio ./gradlew run --continuous技能模板 README 中的开发模式命令改代码即自动重启协程与并发挂起函数与结构化并发MCP SDK 中所有操作均为挂起函数suspending functions这意味着工具处理函数天然运行在协程上下文中可以安全地执行异步 IO。指南特别演示了在单个 Tool 内并行调用多个数据源的结构化并发模式import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.async server.addTool( name parallel-search, description Search multiple sources in parallel ) { request - coroutineScope { val source1 async { searchSource1(query) } val source2 async { searchSource2(query) } val results source1.await() source2.await() CallToolResult( content listOf(TextContent(text results.joinToString(\n))) ) } }要点使用coroutineScope { }建立结构化并发作用域保证所有子协程在返回前完成、异常会被统一传播。async { }启动并行任务await()汇总结果将串行的多次网络请求改写为并行缩短工具整体响应时间。从 kotlin-mcp-expert Agent 的能力清单可确认suspend修饰符、coroutineScope、async/await并行与协程内错误传播是 Agent 回答协程问题时的固定要点集。错误处理异常捕获与协议级错误标记工具处理函数抛出的异常需要被妥善处理。MCP 提供了协议级的错误表达方式在CallToolResult上设置isError true使客户端把该次调用视为「工具执行失败」而非协议故障server.addTool( name validate-input, description Process validated input ) { request - try { val input request.params.arguments[input] as? String ?: throw IllegalArgumentException(input is required) require(input.isNotBlank()) { input cannot be blank } val result processInput(input) CallToolResult( content listOf(TextContent(text result)) ) } catch (e: IllegalArgumentException) { CallToolResult( isError true, content listOf(TextContent(text Validation error: ${e.message})) ) } }模式解析输入校验优先先处理「缺失参数」?: throw IllegalArgumentException与「非法取值」require(input.isNotBlank())两类校验再执行业务逻辑。require是 Kotlin 标准库的快速失败工具失败时抛出IllegalArgumentException。统一错误出口catch (e: IllegalArgumentException)捕获校验类异常返回isError true的CallToolResult并把错误消息写入TextContent保证客户端能拿到可读的错误原因。分层处理IllegalArgumentException之外的运行时异常可在外层继续捕获或记录日志见下文 Logging 模式避免裸异常导致协议断连。JSON Schema 与 kotlinx.serialization类型安全的 Schema 构建指南提供了两条构建工具输入 Schema 的路径命令式 DSL 与声明式序列化。方式一buildJsonObjectDSL命令式buildJsonObject配合put/putJsonObject/putJsonArray可精确控制嵌套结构import kotlinx.serialization.json.* fun createToolSchema(): JsonObject buildJsonObject { put(type, object) putJsonObject(properties) { putJsonObject(query) { put(type, string) put(description, Search query) } putJsonObject(limit) { put(type, integer) put(default, 10) } putJsonObject(filters) { put(type, array) putJsonObject(items) { put(type, string) } } } putJsonArray(required) { add(query) } }此方式可表达string、integer含default默认值、array含items子结构等复杂类型与 JSON Schema 语法一一对应。方式二Serializable数据类 自定义 Schema声明式对于参数本身指南推荐先用Serializable数据类建模让编译期类型检查替你把关import kotlinx.serialization.Serializable import kotlinx.serialization.json.* Serializable data class SearchInput( val query: String, val limit: Int 10, val filters: ListString emptyList() )该数据类同时可作为参数提取后的类型载体query必填、limit默认 10、filters默认空列表。配合 kotlin-mcp-server-generator 技能 的实践「Type Safety: Use data classes and kotlinx.serialization」「JSON Schemas: UsebuildJsonObjectfor tool schemas」推荐的组合是用数据类描述参数结构、用buildJsonObject生成对外的 Schema、在 handler 中把 JSON 反序列化为数据类后再校验。Kotlin Multiplatform 支持JVM / JS / Wasm / iOS官方 Kotlin SDK 面向 Kotlin Multiplatform 设计。指南给出的多平台build.gradle.kts配置如下kotlin { jvm() js(IR) { browser() nodejs() } wasmJs() sourceSets { commonMain.dependencies { implementation(io.modelcontextprotocol:kotlin-sdk:0.7.2) implementation(org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0) } } }要点声明目标平台jvm()JVM、js(IR)含browser与nodejs两个子目标、wasmJs()WebAssembly。SDK 与协程依赖放入commonMain.dependencies使核心 MCP 逻辑在多个平台共享。从 kotlin-mcp-server-generator 技能 的 Multiplatform 章节可知该项目可同时面向 JVM、Wasm 与 iOSkotlin-mcp-expert Agent 也将其列为关键能力「Supported targets (JVM, Wasm, iOS)」以及expect/actual声明。需要留意的是不同平台可用的传输方式存在差异例如 Stdio 面向 JVM 本地进程SSE 面向 HTTP落地多平台时需要为平台特定部分使用expect/actual或保持传输层单平台实现。测试基于 kotlinx-coroutines-test 的协议级验证由于所有 MCP 操作都是挂起函数测试需借助kotlinx.coroutines.test.runTest在虚拟时间内执行。指南给出的测试骨架如下import kotlinx.coroutines.test.runTest import kotlin.test.Test import kotlin.test.assertEquals class ServerTest { Test fun testSearchTool() runTest { val server createTestServer() val request CallToolRequest( params CallToolParams( name search, arguments mapOf(query to test, limit to 5) ) ) val result server.callTool(request) assertEquals(false, result.isError) assert(result.content.isNotEmpty()) } }要点runTest为协程测试提供可控的调度器避免真实等待。构造CallToolRequest(params CallToolParams(name ..., arguments mapOf(...)))模拟客户端请求直接调用server.callTool(request)走完整处理链路无需真实传输连接——这是协议级单测的核心价值。断言关注两点isError false调用成功与content非空返回了内容。测试依赖需在build.gradle.kts中加入testImplementation(kotlin(test))与testImplementation(org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0)见 技能模板。技能模板的ServerTest.kt还示范了通过createServer(config)工厂构造服务后断言server.serverInfo.name/version与配置一致形成「配置→服务→工具调用」三层测试思路。工程化常用模式日志、配置与依赖注入指南最后给出三个贯穿工程化实践的通用模式。结构化日志kotlin-logging使用KotlinLogging记录工具调用的入参与执行结果便于排障与审计import io.github.oshai.kotlinlogging.KotlinLogging private val logger KotlinLogging.logger {} server.addTool( name logged-operation, description Operation with logging ) { request - logger.info { Tool called with args: ${request.params.arguments} } try { val result performOperation(request) logger.info { Operation succeeded } result } catch (e: Exception) { logger.error(e) { Operation failed } throw e } }注意此模式与「错误处理」章节的区别这里捕获后记录日志并重新抛出让协议层决定如何处理而校验类错误则应转换为isError结果返回给客户端。仓库技能模板在依赖中加入了io.github.oshai:kotlin-logging-jvm:7.0.0与ch.qos.logback:logback-classic:1.5.12Main.kt入口在启动、就绪阶段均输出结构化日志。配置管理数据类 环境变量用Serializable数据类承载配置并从环境变量读取保持零配置默认值import kotlinx.serialization.Serializable Serializable data class ServerConfig( val name: String my-server, val version: String 1.0.0, val port: Int 8080, val enableTools: Boolean true ) fun loadConfig(): ServerConfig { // Load from environment or config file return ServerConfig( name System.getenv(SERVER_NAME) ?: my-server, version System.getenv(VERSION) ?: 1.0.0 ) }技能模板的Config.kt将其扩展为SERVER_NAME、VERSION、DESCRIPTION三个环境变量并默认值注入{{PROJECT_NAME}}等占位符README 模板中亦有对应的环境变量说明表——这种「环境变量驱动、数据类承载、默认值兜底」的配置模式适合部署到容器与 CI 场景。依赖注入构造器注入将数据服务等依赖通过构造函数注入使 Server 组件可独立测试class MyServer( private val dataService: DataService, private val config: ServerConfig ) { fun createServer() Server( serverInfo Implementation( name config.name, version config.version ) ) { MCP Server with DI }.apply { addTool( name fetch-data, description Fetch data using injected service ) { request - val data dataService.fetchData() CallToolResult( content listOf(TextContent(text data)) ) } } }apply { addTool(...) }在 Server 创建后立即注册工具既保持了 DSL 式的可读性又通过构造器注入让DataService可以被 Mock 替换从而把工具逻辑与真实数据源解耦——这正是 kotlin-mcp-expert Agent 强调的「constructor injection for testability」与「scope functions for configuration」两大 Kotlin 惯用法的落地点。仓库配套资源插件、技能与专家 Agent上述指南在仓库中并非孤立存在而是组成了一条完整的「指导 → 生成 → 咨询」工具链指南本体instructions/kotlin-mcp-server.instructions.md 通过 frontmatter 声明applyTo: **/*.kt, **/*.kts, **/build.gradle.kts, **/settings.gradle.kts即 Copilot 在处理 Kotlin 源文件与 Gradle 构建脚本时会自动套用本指南。项目生成技能skills/kotlin-mcp-server-generator/SKILL.md 提供从零生成完整 Kotlin MCP 工程的一体化模板含build.gradle.kts、settings.gradle.kts、Main.kt、Server.kt、Config.kt、Tool1.kt、ToolRegistry.kt、ServerTest.kt与 README 模板并给出 10 条生成指令与最佳实践清单。专家 Agentagents/kotlin-mcp-expert.agent.md 以「Kotlin MCP Server 开发专家」身份提供对话式指导覆盖 SDK 关键组件、常见任务、Kotlin 特性运用与多平台注意事项。插件打包plugins/kotlin-mcp-development/README.md 与 plugin.json 将上述技能与 Agent 打包为kotlin-mcp-development插件版本 1.0.0MIT 许可可通过copilot plugin install kotlin-mcp-developmentawesome-copilot安装并暴露/kotlin-mcp-development:kotlin-mcp-server-generator斜杠命令与kotlin-mcp-expertAgent。从零到一的实战清单综合指南与仓库配套资源一个生产级 Kotlin MCP Server 的落地路径可总结为工程搭建配置build.gradle.ktskotlin-jvm 2.1.0、serialization 插件、MCP SDK 0.7.2、Ktor 3.0.0、kotlinx 系列依赖、测试与日志依赖JDK 17。Server 组装Server(Implementation(name, version), ServerOptions(capabilities))声明身份与能力lambda 提供服务描述。能力注册按需实现 23 个addToolJSON Schema 挂起 handler、addResourceURI 变更通知、addPrompt参数化模板。传输接入本地用StdioServerTransportserver.connect()远程用 KtorembeddedServer(Netty) { mcp { Server(...) } }。质量保障协程结构化并发、校验类错误转isError、runTest协议级单测、结构化日志、构造器注入。文档与交付README 覆盖安装、运行./gradlew run、配置环境变量与工具说明可参考 技能模板 直接生成。遵循以上路径你就能在 Kotlin 生态内构建出类型安全、异步高效、可测试可部署的 MCP 服务端并通过io.modelcontextprotocol:kotlin-sdk与 MCP 客户端如支持 MCP 的编辑器与 AI 应用完成协议级对接。【免费下载链接】awesome-copilotCommunity-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表