Koog 1.0 idioms, gotchas, and scaffolding skills for Kotlin agents on the JVM
87
88%
Does it follow best practices?
Impact
87%
1.85xAverage score across 45 eval scenarios
Advisory
Suggest reviewing before use
{
"context": "Tests whether the agent recognizes the MCP server-authoring path (publishing a ToolSet as a stdio MCP service) rather than confusing it with the MCP client path (consuming a remote server) or rolling a bespoke RPC layer.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Calls startStdioMcpServer",
"description": "Produces a main() that calls ai.koog.agents.mcp.server.startStdioMcpServer(registry) inside runBlocking. Does NOT reach for McpToolRegistryProvider.fromProcess (that's the client side) or hand-roll a JSON-RPC server on top of stdin/stdout",
"max_score": 30
},
{
"name": "Adds the agents-mcp-server dependency",
"description": "Adds ai.koog:agents-mcp-server-jvm:1.0.0-beta to build.gradle.kts. Both the -jvm suffix AND the 1.0.0-beta version are required — the umbrella koog-agents does not pull this module, the artifact does not publish at 1.0.0 stable, and Gradle KMP variant resolution needs the -jvm suffix at this version",
"max_score": 25
},
{
"name": "Wraps the existing ToolSet in a ToolRegistry",
"description": "Builds ToolRegistry { tools(CalendarTools().asTools()) } from the developer's existing class. Reuses the existing @Tool/@LLMDescription annotations as-is — does not introduce a parallel annotation scheme or rewrite the ToolSet",
"max_score": 20
},
{
"name": "Keeps the process alive after startup",
"description": "Calls awaitCancellation() (or equivalent suspending hold) after startStdioMcpServer so the process stays alive while the parent MCP client drives requests over stdio. Without this the main() returns immediately and the server exits",
"max_score": 15
},
{
"name": "Does not reach for the client transport surface",
"description": "Does NOT call McpToolRegistryProvider.streamableHttp / fromSseUrl / fromProcess. The developer wants to PUBLISH tools, not consume someone else's MCP server — the client transports are the wrong side of the boundary",
"max_score": 10
}
]
}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
scenario-44
scenario-45
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