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
{
"context": "Tests whether the agent picks the primary 1.0 MCP transport (Streamable HTTP) when the server supports it, rather than defaulting to the older SSE transport that hosted Koog docs may still lead with.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Uses the Streamable HTTP transport",
"description": "Builds the MCP tool registry with McpToolRegistryProvider.streamableHttp { ... }. Does NOT use fromSseUrl (the older transport) when the server supports the modern one",
"max_score": 30
},
{
"name": "Adds the agents-mcp dependency",
"description": "Adds the MCP client dependency `ai.koog:agents-mcp-jvm:1.0.0-beta` to build.gradle.kts. The umbrella koog-agents does not include MCP, so the dependency must be added explicitly. The artifact requires the `-jvm` suffix (only JVM variants are published at this version) and the `1.0.0-beta` version (Koog 1.0 stable did not publish `agents-mcp` at `1.0.0`)",
"max_score": 20
},
{
"name": "Passes the server URL to the transport configuration",
"description": "Sets the url to the developer's value (https://mcp.github.example/v1) inside the streamableHttp configuration block",
"max_score": 10
},
{
"name": "Builds the registry before constructing the agent",
"description": "Calls McpToolRegistryProvider.streamableHttp(...) and assigns its result to a variable BEFORE the AIAgent(...) call, then passes that variable as toolRegistry. Does not try to add MCP tools after the agent is constructed",
"max_score": 15
},
{
"name": "Calls the suspending builder inside a coroutine context",
"description": "The streamableHttp builder is invoked inside the existing runBlocking { ... } (or another coroutine scope) — not at top-level outside a suspending context",
"max_score": 10
},
{
"name": "Reads the GitHub token from the environment",
"description": "Reads the personal access token from an environment variable (e.g., GITHUB_PERSONAL_ACCESS_TOKEN) via System.getenv. Does not embed the token literal in source",
"max_score": 10
},
{
"name": "Passes the token as a bearer header in the transport config",
"description": "Configures the transport (within the streamableHttp block, via the supported headers / auth mechanism) to send the token as a bearer Authorization header on requests to the server",
"max_score": 5
}
]
}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