@@ -17,27 +17,33 @@ standardized protocol interface.
1717
1818* [ Overview] ( #overview )
1919* [ Installation] ( #installation )
20+ * [ Artifacts] ( #artifacts )
21+ * [ Gradle setup (JVM)] ( #gradle-setup-jvm )
22+ * [ Multiplatform] ( #multiplatform )
23+ * [ Ktor dependencies] ( #ktor-dependencies )
2024* [ Quickstart] ( #quickstart )
2125 * [ Creating a Client] ( #creating-a-client )
2226 * [ Creating a Server] ( #creating-a-server )
2327* [ Core Concepts] ( #core-concepts )
2428 * [ MCP Primitives] ( #mcp-primitives )
2529 * [ Capabilities] ( #capabilities )
30+ * [ Server Capabilities] ( #server-capabilities )
31+ * [ Client Capabilities] ( #client-capabilities )
2632 * [ Server Features] ( #server-features )
2733 * [ Prompts] ( #prompts )
2834 * [ Resources] ( #resources )
2935 * [ Tools] ( #tools )
36+ * [ Completion] ( #completion )
37+ * [ Logging] ( #logging )
38+ * [ Pagination] ( #pagination )
3039 * [ Client Features] ( #client-features )
3140 * [ Roots] ( #roots )
3241 * [ Sampling] ( #sampling )
33- * [ Utilities] ( #utilities )
34- * [ Completion] ( #completion )
35- * [ Logging] ( #logging )
36- * [ Transports] ( #transports )
37- * [ STDIO Transport] ( #stdio-transport )
38- * [ Streamable HTTP Transport] ( #streamable-http-transport )
39- * [ SSE Transport] ( #sse-transport )
40- * [ WebSocket Transport] ( #websocket-transport )
42+ * [ Transports] ( #transports )
43+ * [ STDIO Transport] ( #stdio-transport )
44+ * [ Streamable HTTP Transport] ( #streamable-http-transport )
45+ * [ SSE Transport] ( #sse-transport )
46+ * [ WebSocket Transport] ( #websocket-transport )
4147* [ Connecting your server] ( #connecting-your-server )
4248* [ Examples] ( #examples )
4349* [ Documentation] ( #documentation )
@@ -277,40 +283,316 @@ Clients declare their capabilities to inform servers what features they support:
277283
278284### Server Features
279285
286+ The ` Server ` API lets you wire prompts, resources, and tools with only a few lines of Kotlin. Each feature is registered
287+ up front and then resolved lazily when a client asks for it, so your handlers stay small and suspendable.
288+
280289#### Prompts
281290
291+ Prompts are reusable templates that help users or clients start conversations in a consistent way.
292+
293+ <!-- - INCLUDE
294+ import io.modelcontextprotocol.kotlin.sdk.server.Server
295+ import io.modelcontextprotocol.kotlin.sdk.server.ServerOptions
296+ import io.modelcontextprotocol.kotlin.sdk.types.GetPromptResult
297+ import io.modelcontextprotocol.kotlin.sdk.types.Implementation
298+ import io.modelcontextprotocol.kotlin.sdk.types.PromptArgument
299+ import io.modelcontextprotocol.kotlin.sdk.types.PromptMessage
300+ import io.modelcontextprotocol.kotlin.sdk.types.Role
301+ import io.modelcontextprotocol.kotlin.sdk.types.ServerCapabilities
302+ import io.modelcontextprotocol.kotlin.sdk.types.TextContent
303+
304+ fun main() {
305+ -->
306+
307+ ``` kotlin
308+ val server = Server (
309+ serverInfo = Implementation (
310+ name = " example-server" ,
311+ version = " 1.0.0"
312+ ),
313+ options = ServerOptions (
314+ capabilities = ServerCapabilities (
315+ prompts = ServerCapabilities .Prompts (listChanged = true ),
316+ ),
317+ )
318+ )
319+
320+ server.addPrompt(
321+ name = " code-review" ,
322+ description = " Ask the model to review a diff" ,
323+ arguments = listOf (
324+ PromptArgument (name = " diff" , description = " Unified diff" , required = true ),
325+ ),
326+ ) { request ->
327+ GetPromptResult (
328+ description = " Quick code review helper" ,
329+ messages = listOf (
330+ PromptMessage (
331+ role = Role .User ,
332+ content = TextContent (text = " Review this change:\n ${request.arguments?.get(" diff" )} " ),
333+ ),
334+ ),
335+ )
336+ }
337+ ```
338+
339+ <!-- - SUFFIX
340+ }
341+ -->
342+
343+ <!-- - KNIT example-server-prompts-01.kt -->
344+
345+ Use prompts for anything that deserves a template: bug triage questions, onboarding checklists, or saved searches.
346+
282347#### Resources
283348
349+ Resources expose read-only context. Register them with a stable URI and return a ` ReadResourceResult ` when the client
350+ reads the resource.
351+
352+ <!-- - INCLUDE
353+ import io.modelcontextprotocol.kotlin.sdk.server.Server
354+ import io.modelcontextprotocol.kotlin.sdk.server.ServerOptions
355+ import io.modelcontextprotocol.kotlin.sdk.types.Implementation
356+ import io.modelcontextprotocol.kotlin.sdk.types.ReadResourceResult
357+ import io.modelcontextprotocol.kotlin.sdk.types.ServerCapabilities
358+ import io.modelcontextprotocol.kotlin.sdk.types.TextResourceContents
359+
360+ fun main() {
361+ -->
362+
363+ ``` kotlin
364+ val server = Server (
365+ serverInfo = Implementation (
366+ name = " example-server" ,
367+ version = " 1.0.0"
368+ ),
369+ options = ServerOptions (
370+ capabilities = ServerCapabilities (
371+ resources = ServerCapabilities .Resources (subscribe = true , listChanged = true ),
372+ ),
373+ )
374+ )
375+
376+ server.addResource(
377+ uri = " note://release/latest" ,
378+ name = " Release notes" ,
379+ description = " Last deployment summary" ,
380+ mimeType = " text/markdown" ,
381+ ) { request ->
382+ ReadResourceResult (
383+ contents = listOf (
384+ TextResourceContents (
385+ text = " Ship 42 reached production successfully." ,
386+ uri = request.uri,
387+ mimeType = " text/markdown" ,
388+ ),
389+ ),
390+ )
391+ }
392+ ```
393+
394+ <!-- - SUFFIX
395+ }
396+ -->
397+
398+ <!-- - KNIT example-server-resources-01.kt -->
399+
400+ Resources can be static text, generated JSON, or blobs—anything the client can surface to the user or inject into the
401+ model context.
402+
284403#### Tools
285404
405+ Tools are the imperative side of MCP. Each tool gets JSON arguments, can emit streaming logs or progress, and returns a
406+ ` CallToolResult ` .
407+
408+ <!-- - INCLUDE
409+ import io.modelcontextprotocol.kotlin.sdk.server.Server
410+ import io.modelcontextprotocol.kotlin.sdk.server.ServerOptions
411+ import io.modelcontextprotocol.kotlin.sdk.types.CallToolResult
412+ import io.modelcontextprotocol.kotlin.sdk.types.Implementation
413+ import io.modelcontextprotocol.kotlin.sdk.types.ServerCapabilities
414+ import io.modelcontextprotocol.kotlin.sdk.types.TextContent
415+ import kotlinx.serialization.json.jsonPrimitive
416+
417+ fun main() {
418+ -->
419+
420+ ``` kotlin
421+ val server = Server (
422+ serverInfo = Implementation (
423+ name = " example-server" ,
424+ version = " 1.0.0"
425+ ),
426+ options = ServerOptions (
427+ capabilities = ServerCapabilities (
428+ tools = ServerCapabilities .Tools (listChanged = true ),
429+ ),
430+ )
431+ )
432+
433+ server.addTool(
434+ name = " echo" ,
435+ description = " Return whatever the user sent back to them" ,
436+ ) { request ->
437+ val text = request.arguments?.get(" text" )?.jsonPrimitive?.content ? : " (empty)"
438+ CallToolResult (content = listOf (TextContent (text = " Echo: $text " )))
439+ }
440+ ```
441+
442+ <!-- - SUFFIX
443+ }
444+ -->
445+
446+ <!-- - KNIT example-server-tools-01.kt -->
447+
448+ Register as many tools as you need—long-running jobs can report progress via the request context, and tools can also
449+ trigger sampling (see below) when they need the client’s LLM.
450+
451+ #### Completion
452+
453+ #### Logging
454+
455+ #### Pagination
456+
286457### Client Features
287458
459+ Clients advertise their capabilities (roots, sampling, elicitation, etc.) during initialization. After that they can
460+ serve requests from the server while still initiating calls such as ` listTools ` or ` callTool ` .
461+
288462#### Roots
289463
464+ Roots describe folders or logical mounts that the client is willing to expose. Servers can list them to understand what
465+ paths are available before proposing file operations.
466+
467+ <!-- - INCLUDE
468+ import io.modelcontextprotocol.kotlin.sdk.client.Client
469+ import io.modelcontextprotocol.kotlin.sdk.client.ClientOptions
470+ import io.modelcontextprotocol.kotlin.sdk.types.ClientCapabilities
471+ import io.modelcontextprotocol.kotlin.sdk.types.Implementation
472+
473+ suspend fun main() {
474+ -->
475+
476+ ``` kotlin
477+ val client = Client (
478+ clientInfo = Implementation (" demo-client" , " 1.0.0" ),
479+ options = ClientOptions (
480+ capabilities = ClientCapabilities (roots = ClientCapabilities .Roots (listChanged = true )),
481+ ),
482+ )
483+
484+ client.addRoot(
485+ uri = " file:///Users/demo/projects" ,
486+ name = " Projects" ,
487+ )
488+ client.sendRootsListChanged()
489+ ```
490+
491+ <!-- - SUFFIX
492+ }
493+ -->
494+
495+ <!-- - KNIT example-client-roots-01.kt -->
496+
497+ Call ` addRoot ` /` removeRoot ` whenever your file system view changes, and use ` sendRootsListChanged() ` to notify the
498+ server.
499+
290500#### Sampling
291501
292- [ // ] : # ( TODO: add elicitation section )
502+ Sampling lets a server ask the client to call its preferred LLM. Enable it by declaring the ` sampling ` capability and
503+ handling the ` sampling/createMessage ` request.
293504
294- [ // ] : # ( #### Elicitation )
505+ <!-- - INCLUDE
506+ import io.modelcontextprotocol.kotlin.sdk.client.Client
507+ import io.modelcontextprotocol.kotlin.sdk.client.ClientOptions
508+ import io.modelcontextprotocol.kotlin.sdk.types.ClientCapabilities
509+ import io.modelcontextprotocol.kotlin.sdk.types.CreateMessageRequest
510+ import io.modelcontextprotocol.kotlin.sdk.types.CreateMessageResult
511+ import io.modelcontextprotocol.kotlin.sdk.types.Implementation
512+ import io.modelcontextprotocol.kotlin.sdk.types.Method
513+ import io.modelcontextprotocol.kotlin.sdk.types.Role
514+ import io.modelcontextprotocol.kotlin.sdk.types.TextContent
295515
296- ### Utilities
516+ fun main() {
517+ -->
297518
298- #### Completion
519+ ``` kotlin
520+ val client = Client (
521+ clientInfo = Implementation (" demo-client" , " 1.0.0" ),
522+ options = ClientOptions (
523+ capabilities = ClientCapabilities (sampling = ClientCapabilities .sampling),
524+ ),
525+ )
526+
527+ client.setRequestHandler<CreateMessageRequest >(Method .Defined .SamplingCreateMessage ) { request, _ ->
528+ val content = request.messages.lastOrNull()?.content
529+ val prompt = if (content is TextContent ) content.text else " your topic"
530+ CreateMessageResult (
531+ model = " gpt-4o-mini" ,
532+ role = Role .Assistant ,
533+ content = TextContent (text = " Here is a short note about $prompt " ),
534+ )
535+ }
536+ ```
299537
300- #### Logging
538+ <!-- - SUFFIX
539+ }
540+ -->
541+
542+ <!-- - KNIT example-client-sampling-01.kt -->
543+
544+ Inside the handler you are free to choose any model/provider, collect extra approvals, or reject the request.
545+
546+ [ // ] : # ( TODO: add elicitation section )
547+
548+ [ // ] : # ( #### Elicitation )
301549
302550## Transports
303551
552+ All transports share the same API surface, so you can change deployment style without touching business logic. Pick the
553+ transport that best matches where the server runs.
554+
304555### STDIO Transport
305556
557+ ` StdioClientTransport ` and ` StdioServerTransport ` tunnel MCP messages over stdin/stdout—perfect for editor plugins or
558+ CLI tooling that spawns a helper process. No networking setup is required.
559+
306560### Streamable HTTP Transport
307561
562+ ` StreamableHttpClientTransport ` and the Ktor ` streamableHttpApp() ` helpers expose MCP over a single HTTP endpoint with
563+ optional JSON-only or SSE streaming responses. This is the recommended choice for remote deployments and integrates
564+ nicely with proxies or service meshes.
565+
308566### SSE Transport
309567
568+ Server-Sent Events remain available for backwards compatibility with older MCP clients. Use ` SseServerTransport ` or the
569+ SSE Ktor plugin when you need drop-in compatibility, but prefer Streamable HTTP for new projects.
570+
310571### WebSocket Transport
311572
573+ ` WebSocketClientTransport ` plus the matching server utilities provide full-duplex, low-latency connections—useful when
574+ you expect lots of notifications or long-running sessions behind a reverse proxy that already terminates WebSockets.
575+
312576## Connecting your server
313577
578+ 1 . Start a sample server:
579+
580+ ``` bash
581+ ./gradlew :samples:kotlin-mcp-server:run
582+ ```
583+
584+ 2 . Point the [ MCP Inspector] ( https://github.com/modelcontextprotocol/inspector ) or Claude Desktop/Code at the running
585+ endpoint:
586+
587+ ``` bash
588+ npx -y @modelcontextprotocol/inspector --connect http://localhost:3000/mcp
589+ # or
590+ claude mcp add --transport http kotlin-mcp http://localhost:3000/mcp
591+ ```
592+
593+ 3 . Watch the Inspector UI to verify prompts, tools, resources, and logs are all available, then iterate on your server
594+ locally until it’s ready for production hosting.
595+
314596## Examples
315597
316598- [ kotlin-mcp-server] ( ./samples/kotlin-mcp-server ) : demonstrates a MCP server setup with
@@ -322,6 +604,10 @@ Clients declare their capabilities to inform servers what features they support:
322604
323605## Documentation
324606
607+ - [ API Reference] ( https://modelcontextprotocol.github.io/kotlin-sdk/ )
608+ - [ Model Context Protocol documentation] ( https://modelcontextprotocol.io )
609+ - [ MCP specification] ( https://modelcontextprotocol.io/specification/latest )
610+
325611## Contributing
326612
327613Please see the [ contribution guide] ( CONTRIBUTING.md ) and the [ Code of conduct] ( CODE_OF_CONDUCT.md ) before contributing.
0 commit comments