# Ktor Server Mcp

> Session-aware MCP server integration for Ktor. A thin wrapper around the official MCP Kotlin SDK, designed to work with ktor-server-oauth and any authenticate {} flow.

- **Type:** MCP server
- **Install:** `agentstack add mcp-vctrl-ktor-server-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [vctrl](https://agentstack.voostack.com/s/vctrl)
- **Installs:** 0
- **Category:** [Security](https://agentstack.voostack.com/c/security)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [vctrl](https://github.com/vctrl)
- **Source:** https://github.com/vctrl/ktor-server-mcp

## Install

```sh
agentstack add mcp-vctrl-ktor-server-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# ktor-server-mcp

Session-aware MCP server integration for Ktor.

A thin wrapper around the official [MCP Kotlin SDK](https://github.com/modelcontextprotocol/kotlin-sdk), designed to work with [ktor-server-oauth](https://github.com/vctrl/ktor-server-oauth) and any Ktor `authenticate {}` flow. Build MCP servers where tools have access to authenticated user sessions and principals.

## Why This Library?

The official MCP Kotlin SDK provides excellent protocol support but doesn't integrate with Ktor sessions or authentication blocks. 
This library bridges that gap:

- **Works inside `authenticate {}`** - Respects Ktor's route hierarchy, so MCP endpoints can be protected by any auth provider.
- **Session & Principal access** - Read user-specific data via `call.sessions` and `call.principal()`.
- **Designed for ktor-server-oauth** - Seamlessly integrates with OAuth provision flows.
- **Idiomatic Kotlin DSL** - Clean `tool()` syntax with automatic error handling.
- **Full MCP Kotlin SDK passthrough** - Use `configure {}` for prompts, resources, and all official SDK features.

## Installation

This library was built to bring MCP support to [ktor-server-oauth](https://github.com/vctrl/ktor-server-oauth), enabling OAuth-protected MCP servers with session-aware tools.

```kotlin
dependencies {
    implementation("com.vcontrol:ktor-server-mcp:0.3.0")
    implementation("io.modelcontextprotocol:kotlin-sdk:0.8.1")

    // Recommended: OAuth 2.0 support
    implementation("com.vcontrol:ktor-server-oauth:0.5.0")
}
```

## Quick Start

```kotlin
fun Application.module() {
    install(SSE)
    install(Authentication) {
        bearer("api-key") { /* ... */ }
    }

    routing {
        authenticate("api-key") {
            mcp("/mcp") {
                name = "my-server"
                version = "1.0.0"

                tool("greet", "Greets the user") {
                    val name = args["name"] ?: "World"
                    textResult("Hello, $name!")
                }
            }
        }
    }
}
```

## Session & Principal Access

Access authenticated user data from your tools:

```kotlin
@Serializable
data class UserSession(val apiKey: String, val name: String)

routing {
    authenticate {
        mcp("/mcp") {
            val user = call.sessions.get()
            val principal = call.principal()

            tool("whoami", "Returns current user") {
                textResult("Hello, ${user?.name ?: principal?.name ?: "stranger"}!")
            }

            tool("call_api", "Calls API with user's key") {
                val endpoint = args["endpoint"] ?: "/default"
                val result = apiClient.call(endpoint, user?.apiKey)
                textResult(result)
            }
        }
    }
}
```

## Helper Functions

Simple helpers for common response patterns:

```kotlin
// Single text result
textResult("Hello!")

// Multiple text results
textResult("Line 1", "Line 2", "Line 3")

// Error result
errorResult("Something went wrong")
```

## Error Handling

Exceptions are automatically caught and returned as error results:

```kotlin
tool("risky", "Might fail") {
    if (args["value"] == null) {
        throw IllegalArgumentException("value is required")
    }
    textResult("Success!")
}
// Errors returned as: CallToolResult(isError = true, content = "Error: value is required")
```

## With ktor-server-oauth

Pair with [ktor-server-oauth](https://github.com/vctrl/ktor-server-oauth) for OAuth 2.0 protected MCP servers:

```kotlin
fun Application.module() {
    install(OAuth) {
        server { clients { registration = true } }  // Accept all registrations
    }
    install(OAuthSessions) {
        session()
    }
    install(Authentication) {
        oauthJwt()
    }

    routing {
        provision {
            get { call.respondHtml { apiKeyForm() } }
            post {
                call.sessions.set(ApiKeySession(call.receiveParameters()["api_key"]!!))
                call.provision.complete()
            }
        }

        authenticate {
            mcp("/mcp") {
                val session = call.sessions.get()

                tool("query", "Query using user's API key") {
                    val result = queryWithKey(session?.apiKey)
                    textResult(result)
                }
            }
        }
    }
}
```

See [ktor-oauth-mcp-samples](https://github.com/vctrl/ktor-oauth-mcp-samples) for complete working examples.

## SDK Passthrough

Use `configure {}` for full SDK access (prompts, resources, advanced features):

```kotlin
mcp("/mcp") {
    tool("hello", "Says hello") {
        textResult("Hello!")
    }

    configure {
        val user = call.sessions.get()

        server.addPrompt("summarize", "Summarizes text") { request ->
            GetPromptResult(messages = listOf(...))
        }

        server.addResource("config://settings", "User settings") { request ->
            ReadResourceResult(contents = listOf(...))
        }
    }
}
```

## API Reference

### Route.mcp()

```kotlin
fun Route.mcp(path: String = "", configure: McpConfig.() -> Unit): Route
```

Registers MCP SSE and POST endpoints at the given path.

### McpConfig

| Property | Description |
|----------|-------------|
| `name` | Server name (shown to clients) |
| `version` | Server version |
| `title` | Human-readable title (optional) |
| `websiteUrl` | Server website URL (optional) |
| `icons` | Server icons (optional) |
| `capabilities` | `ServerCapabilities` - auto-set when using `tool()` |
| `call` | Ktor `ApplicationCall` for sessions, principal, etc. |

### tool()

```kotlin
fun tool(
    name: String,
    description: String,
    inputSchema: ToolSchema = ToolSchema(),
    handler: suspend ToolScope.() -> CallToolResult
)
```

Register a tool. Use `textResult()` helper for simple responses. Errors are caught automatically.

### ToolScope

| Property | Description |
|----------|-------------|
| `args` | Tool arguments as `Map` |
| `call` | Ktor `ApplicationCall` for sessions, principal, etc. |

### Helper Functions

```kotlin
fun textResult(text: String): CallToolResult
fun textResult(vararg texts: String): CallToolResult
fun errorResult(message: String): CallToolResult
```

### configure {}

```kotlin
fun configure(block: suspend ConfigureScope.() -> Unit)
```

Direct SDK access. `ConfigureScope` provides:
- `server` - the MCP `ServerSession` for SDK methods
- `call` - Ktor `ApplicationCall`

## License

Apache 2.0

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [vctrl](https://github.com/vctrl)
- **Source:** [vctrl/ktor-server-mcp](https://github.com/vctrl/ktor-server-mcp)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-vctrl-ktor-server-mcp
- Seller: https://agentstack.voostack.com/s/vctrl
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
