diff --git a/docs/skills/index.md b/docs/skills/index.md
index 9143a7dad4..1e9d3dcc84 100644
--- a/docs/skills/index.md
+++ b/docs/skills/index.md
@@ -1,7 +1,7 @@
# Skills for ADK agents
- Supported in ADKPython v1.25.0TypeScript v0.6.1Go v1.2.0Experimental
+ Supported in ADKPython v1.25.0TypeScript v0.6.1Go v1.2.0Kotlin v0.1.0Experimental
An agent ***Skill*** is a self-contained unit of functionality that an ADK agent
@@ -17,7 +17,8 @@ impact on the operating context window of the agent.
respective ADK GitHub repositories:
[ADK Python](https://github.com/google/adk-python/issues/new?template=feature_request.md&labels=skills),
[ADK TypeScript](https://github.com/google/adk-js/issues/new?template=feature_request.md&labels=skills),
- [ADK Go](https://github.com/google/adk-go/issues/new?template=feature_request.md&labels=skills).
+ [ADK Go](https://github.com/google/adk-go/issues/new?template=feature_request.md&labels=skills),
+ [ADK Kotlin](https://github.com/google/adk-kotlin/issues/new).
## Get started
@@ -101,6 +102,15 @@ You can define [skills in code](#inline-skills) or load
For a complete example, see the code sample in
[skills](https://github.com/google/adk-go/tree/main/examples/skills).
+=== "Kotlin"
+
+ ```kotlin
+ --8<-- "examples/kotlin/snippets/skills/SkillsExample.kt:get_started"
+ ```
+
+ For a complete example, see the code sample in
+ [skills](https://github.com/google/adk-kotlin/tree/main/examples/src/main/kotlin/com/google/adk/kt/examples/skills).
+
!!! note "Check your working directory"
Ensure that 'skills/' directory exist in your current working directory and contains the sub-directories for the Skills you want to use in your agent.
@@ -288,6 +298,17 @@ You can define Skills within the code of your agent, as shown below.
}
```
+=== "Kotlin"
+
+ !!! note
+ ADK Kotlin does not currently provide a standard Source for inline skills.
+ To define skills directly in code, you must implement the `SkillSource`
+ interface yourself, as shown below.
+
+ ```kotlin
+ --8<-- "examples/kotlin/snippets/skills/SkillsExample.kt:inline_skill"
+ ```
+
!!! note
The `Source` interface can be backed by any data store (such as a database)
to support dynamic use cases like live updates and personalization.
@@ -343,6 +364,12 @@ You can define Skills within the code of your agent, as shown below.
}
```
+=== "Kotlin"
+
+ ```kotlin
+ --8<-- "examples/kotlin/snippets/skills/SkillsExample.kt:filesystem_skill"
+ ```
+
## Skill processing and validation
When you include skills in your agent, the agent uses a standardized process
@@ -356,4 +383,5 @@ Check out these resources for building agents with Skills:
- [Skills in Python - code sample](https://github.com/google/adk-python/tree/main/contributing/samples/environment_and_skills/skills_agent)
- [Skills in Go - code sample](https://github.com/google/adk-go/tree/main/examples/skills)
+- [Skills in Kotlin - code sample](https://github.com/google/adk-kotlin/tree/main/examples/src/main/kotlin/com/google/adk/kt/examples/skills)
- Agent Skills [specification documentation](https://agentskills.io/)
diff --git a/examples/kotlin/snippets/skills/SkillsExample.kt b/examples/kotlin/snippets/skills/SkillsExample.kt
new file mode 100644
index 0000000000..5d4e0d9bd9
--- /dev/null
+++ b/examples/kotlin/snippets/skills/SkillsExample.kt
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.adk.kt.examples.skills
+
+import com.google.adk.kt.agents.Instruction
+import com.google.adk.kt.agents.LlmAgent
+import com.google.adk.kt.models.Gemini
+import com.google.adk.kt.skills.Frontmatter
+import com.google.adk.kt.skills.NewFileSystemSource
+import com.google.adk.kt.skills.SkillSource
+import com.google.adk.kt.skills.SkillSourceException
+import com.google.adk.kt.tools.SkillToolset
+
+// --8<-- [start:get_started]
+// NewFileSystemSource discovers every skill directory under the base directory,
+// so there is no per-skill load call.
+val mySkillToolset = SkillToolset(NewFileSystemSource("skills"))
+
+val skillUserAgent =
+ LlmAgent(
+ name = "skill_user_agent",
+ model = Gemini(name = "gemini-flash-latest"),
+ description = "An agent that can use specialized skills.",
+ instruction =
+ Instruction("You are a helpful assistant that can leverage skills to perform tasks."),
+ // A SkillToolset contributes only the skill tools. Any other tool the agent
+ // needs is passed separately in `tools`.
+ toolsets = listOf(mySkillToolset),
+ )
+// --8<-- [end:get_started]
+
+// --8<-- [start:inline_skill]
+
+/**
+ * ADK Kotlin does not provide a standard [SkillSource] for skills defined in code, so implement the
+ * interface yourself to serve them from memory.
+ */
+class StaticSkillSource : SkillSource {
+ private val greetingSkill =
+ Frontmatter(
+ name = "greeting-skill",
+ description = "A friendly greeting skill that can say hello to a specific person.",
+ )
+
+ private val instructions =
+ "Step 1: Read the 'references/hello_world.txt' file to understand how to greet the " +
+ "user. Step 2: Return a greeting based on the reference."
+
+ private val resources =
+ mapOf(
+ "references/hello_world.txt" to "Hello! So glad to have you here!",
+ "references/example.md" to "This is an example reference.",
+ )
+
+ private fun notFound(skillName: String) = SkillSourceException("Skill $skillName not found.")
+
+ override suspend fun listFrontmatters(): Result> =
+ Result.success(listOf(greetingSkill))
+
+ override suspend fun loadFrontmatter(skillName: String): Result =
+ if (skillName == greetingSkill.name) {
+ Result.success(greetingSkill)
+ } else {
+ Result.failure(notFound(skillName))
+ }
+
+ override suspend fun loadInstructions(skillName: String): Result =
+ if (skillName == greetingSkill.name) {
+ Result.success(instructions)
+ } else {
+ Result.failure(notFound(skillName))
+ }
+
+ override suspend fun listResources(
+ skillName: String,
+ resourceDirectoryPath: String,
+ ): Result> {
+ if (skillName != greetingSkill.name) return Result.failure(notFound(skillName))
+ val prefix = resourceDirectoryPath.removePrefix("./").removeSuffix("/")
+ if (prefix.isEmpty() || prefix == ".") return Result.success(resources.keys.toList())
+ // Skill resources live only under references/, assets/ and scripts/.
+ if (prefix.substringBefore("/") !in SkillSource.VALID_RESOURCE_DIRS) {
+ return Result.failure(
+ SkillSourceException("Invalid resource path: $resourceDirectoryPath"),
+ )
+ }
+ return Result.success(resources.keys.filter { it.startsWith("$prefix/") })
+ }
+
+ override suspend fun loadResource(
+ skillName: String,
+ resourcePath: String,
+ ): Result {
+ if (skillName != greetingSkill.name) return Result.failure(notFound(skillName))
+ val content =
+ resources[resourcePath]
+ ?: return Result.failure(
+ SkillSourceException("Resource $resourcePath not found in skill $skillName."),
+ )
+ return Result.success(content.encodeToByteArray())
+ }
+}
+
+val inlineSkillAgent =
+ LlmAgent(
+ name = "greeting_agent",
+ model = Gemini(name = "gemini-flash-latest"),
+ instruction = Instruction("Greet the user by following the greeting skill."),
+ toolsets = listOf(SkillToolset(StaticSkillSource())),
+ )
+// --8<-- [end:inline_skill]
+
+// --8<-- [start:filesystem_skill]
+// Every immediate subdirectory of "skills" that contains a SKILL.md is exposed as
+// a skill, so individual skills are discovered rather than named one by one.
+val filesystemSource = NewFileSystemSource("skills")
+
+val filesystemSkillToolset = SkillToolset(filesystemSource)
+// --8<-- [end:filesystem_skill]
diff --git a/tools/kotlin-snippets/files_to_test.txt b/tools/kotlin-snippets/files_to_test.txt
index b1902c362c..0c16697d27 100644
--- a/tools/kotlin-snippets/files_to_test.txt
+++ b/tools/kotlin-snippets/files_to_test.txt
@@ -40,3 +40,4 @@ snippets/tools/overview/UserPreferenceTools.kt
snippets/tools/overview/CustomerSupport.kt
snippets/tools/overview/DocAnalysisTools.kt
snippets/tools/overview/OrderTools.kt
+snippets/skills/SkillsExample.kt