Koog 1.0 idioms, gotchas, and scaffolding skills for Kotlin agents on the JVM
88
88%
Does it follow best practices?
Impact
88%
1.95xAverage score across 43 eval scenarios
Passed
No known issues
Process steps in order. Do not skip ahead.
Ask the user, one question at a time:
If the user doesn't know which transport the server supports, default to Streamable HTTP and plan a fallback to SSE if connection fails — the primary 1.0 transport is Streamable HTTP (MCP SDK 0.11.x), but a number of in-the-wild servers still only expose SSE.
Proceed immediately to Step 2.
Open build.gradle.kts and confirm the MCP client artifact is in the dependencies block. The umbrella ai.koog:koog-agents does not pull MCP — it must be added explicitly. If absent, add it:
implementation("ai.koog:agents-mcp-jvm:1.0.0-beta")Two gotchas the umbrella version hides:
agents-mcp (and agents-mcp-server) ship as 1.0.0-beta — Koog 1.0's stable release did not publish them at 1.0.0. Pin 1.0.0-beta (or later when stable).-jvm suffix (agents-mcp-jvm, not bare agents-mcp) — without it, Gradle KMP variant resolution can't pick the JVM artifact at this version and the build fails with "could not find" errors.Re-run ./gradlew --refresh-dependencies if the project is already imported into the IDE.
Proceed immediately to Step 3.
ToolRegistryIn the file that constructs the agent, build the MCP registry before the agent. Pick the form matching the transport.
Two-import rule for the registry builder:
McpToolRegistryProvider — the objectstreamableHttp, fromSseUrl, or fromProcessai.koog.agents.mcp, not members of the provider objectStreamable HTTP (preferred):
import ai.koog.agents.mcp.McpToolRegistryProvider
import ai.koog.agents.mcp.streamableHttp
val mcpRegistry = McpToolRegistryProvider.streamableHttp {
url = "https://<your-mcp-server>/mcp"
// headers, auth, timeouts — see McpToolRegistryProvider source
}SSE (fallback):
import ai.koog.agents.mcp.McpToolRegistryProvider
import ai.koog.agents.mcp.fromSseUrl
val mcpRegistry = McpToolRegistryProvider.fromSseUrl("https://<your-mcp-server>/sse")stdio (locally launched):
import ai.koog.agents.mcp.McpToolRegistryProvider
import ai.koog.agents.mcp.fromProcess
val process = ProcessBuilder("npx", "-y", "@playwright/mcp@latest").start()
val mcpRegistry = McpToolRegistryProvider.fromProcess(process)This is a suspending call. Run it inside the same runBlocking { ... } (or coroutine scope) that constructs the agent.
Proceed immediately to Step 4.
If the agent already has a ToolRegistry, merge with +; if not, pass the MCP registry as the toolRegistry:
// merge case
val combined = ToolRegistry { tools(<ExistingTools>().asTools()) } + mcpRegistry
val agent = AIAgent(
promptExecutor = ...,
llmModel = ...,
toolRegistry = combined,
systemPrompt = ...,
)Do not mutate the registry after constructing the agent — features wire up during installFeatures and read the registry then. Reorder the construction so the registry is final before AIAgent(...) runs.
Proceed immediately to Step 5.
./gradlew build to confirm the project still compiles. If it doesn't, the most common cause is a missing import — surface the exact errortools/list endpoint directly to confirm. Finish here.evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10
scenario-11
scenario-12
scenario-13
scenario-14
scenario-15
scenario-16
scenario-17
scenario-18
scenario-19
scenario-20
scenario-21
scenario-22
scenario-23
scenario-24
scenario-25
scenario-26
scenario-27
scenario-28
scenario-29
scenario-30
scenario-31
scenario-32
scenario-33
scenario-34
scenario-35
scenario-36
scenario-37
scenario-38
scenario-39
scenario-40
scenario-41
scenario-42
scenario-43
skills
add-observability
add-persistence
add-rag
add-structured-output
add-token-budgeting
add-tool
cache-llm-calls
define-prompt
domain-model-subtask-pipeline
references
enable-prompt-caching
handle-agent-events
manage-state
migrate-from-0-x
model-planner-subtasks
persist-chat-history
query-sql-from-agent
scaffold-agent
snapshot-and-restore
test-koog-agents
trace-agent-internals
use-attachments
use-functional-agent
use-llm-node-variants
use-planner
wire-a2a
wire-acp-server
wire-ktor-server
wire-mcp-server
wire-spring-boot