Skip to main content

Skills Discovery

Agent Skills provides three ways to load skills into a toolset, plus a search API for runtime discovery. The three mechanisms can be combined freely.

Loading Skills into a Toolset

1. Path-based loading

Point AgentSkillsToolset at one or more local directories. Every sub-directory containing a SKILL.md file is discovered automatically when the toolset is first used.

When to use: skills checked into the same repository, or mounted at a well-known path at runtime (e.g. a Kubernetes shared volume).

from agent_skills import AgentSkillsToolset, SandboxExecutor
from code_sandboxes import CodeSandboxClient

toolset = AgentSkillsToolset(
directories=["./skills"], # scanned recursively for SKILL.md
executor=SandboxExecutor(CodeSandboxClient.create(variant="eval")),
)

Expected directory layout:

skills/
├── pdf-extractor/
│ ├── SKILL.md
│ └── scripts/
│ └── extract.py
└── data-analyzer/
├── SKILL.md
└── scripts/
└── analyze.py

2. Module-based loading

Use AgentSkill.from_module() to load skills that are packaged inside an installed Python library. Works for both regular packages (with __init__.py) and namespace packages (directories without __init__.py, where __file__ is None).

When to use: skills distributed as part of a pip-installable package, such as the built-in skills in agent-skills itself.

from agent_skills import AgentSkill, AgentSkillsToolset, SandboxExecutor
from code_sandboxes import CodeSandboxClient

toolset = AgentSkillsToolset(
skills=[
AgentSkill.from_module("agent_skills.skills.crawl"),
AgentSkill.from_module("agent_skills.skills.github"),
AgentSkill.from_module("agent_skills.skills.pdf"),
AgentSkill.from_module("agent_skills.skills.events"),
],
executor=SandboxExecutor(CodeSandboxClient.create(variant="eval")),
)

from_module() imports the module, resolves its directory, and delegates to AgentSkill.from_skill_md() — no extra configuration needed.

3. Entrypoint-based loading (automatic)

Installed Python packages that declare entrypoints in the agent_skills.skills group are discovered automatically when the toolset initialises. No explicit configuration is required — just install the package and the skills appear.

When to use: distributing skills as standalone pip-installable packages that consumers can install independently. This is the recommended approach for sharing skills across teams or publishing them on PyPI.

from agent_skills import AgentSkillsToolset, SandboxExecutor
from code_sandboxes import CodeSandboxClient

# Entrypoint skills are found automatically — no skills= or directories= needed
toolset = AgentSkillsToolset(
executor=SandboxExecutor(CodeSandboxClient.create(variant="eval")),
)

The package registers its skills in pyproject.toml:

[project.entry-points."agent_skills.skills"]
whoami = "datalayer_skills.skills.whoami"

Each key is a skill name and each value is a dotted Python module path that contains a SKILL.md file (the same layout used by AgentSkill.from_module()).

To disable entrypoint scanning (e.g. for testing), set discover_entrypoints=False:

toolset = AgentSkillsToolset(
discover_entrypoints=False,
executor=SandboxExecutor(CodeSandboxClient.create(variant="eval")),
)

You can also call the discovery function directly:

from agent_skills import discover_entrypoint_skills

for skill in discover_entrypoint_skills():
print(f"{skill.name}: {skill.description}")

Combining all three

The three approaches stack freely. Skills loaded via skills= are merged with any skills discovered from directories= and from entrypoints:

toolset = AgentSkillsToolset(
directories=["./skills"], # local / custom skills
skills=[
AgentSkill.from_module("agent_skills.skills.crawl"),
],
# discover_entrypoints=True (default) — finds installed packages too
executor=SandboxExecutor(CodeSandboxClient.create(variant="eval")),
)

In a Kubernetes / SaaS pod

In the Datalayer SaaS deployment the agent-runtimes container runs alongside a Jupyter container in the same pod. The two loading patterns map to the two-container architecture as follows:

┌─────────────────────────────── Pod ────────────────────────────────────┐
│ │
│ agent-runtimes :8765 jupyter :2300 │
│ ┌──────────────────────────┐ ┌────────────────────────────┐ │
│ │ AgentSkillsToolset │ │ Jupyter Kernel │ │
│ │ │ │ ┌──────────────────────┐ │ │
│ │ Module-based ──────────►│──reads────► │ skill script code │ │ │
│ │ (agent_skills pip pkg) │ script │ │ (sent as string via │ │ │
│ │ │ content │ │ SandboxExecutor) │ │ │
│ │ Path-based ────────────►│──reads────► └──────────────────────┘ │ │
│ │ (/mnt/shared-agent/ │ SKILL.md │ │ │
│ │ skills/) │ │ Shared Volume: │ │
│ └──────────────────────────┘ │ /mnt/shared-agent/ │ │
│ │ └── skills/ ◄── also │ │
│ │ accessible here │ │
│ └────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
  • Module-basedagent-skills is pip-installed in the image → the agent uses AgentSkill.from_module() to get skill metadata. Script code is read from the installed package and sent as a string to the Jupyter kernel via SandboxExecutor.

  • Path-based — the container entrypoint copies /opt/datalayer/skills//mnt/shared-agent/skills/ (a Kubernetes emptyDir shared by both containers). Set AGENT_RUNTIMES_SKILLS_FOLDER=/mnt/shared-agent/skills so agent-runtimes scans the shared volume for any additional or custom skills.

Regardless of how a skill is loaded, script execution always happens inside the Jupyter kernel — the SandboxExecutor reads the script file content from the agent-runtimes side and sends it as Python source code to the kernel over the Jupyter HTTP API.


Runtime Discovery via the Agent

When AgentSkillsToolset is attached to an agent, the agent can discover skills dynamically through two built-in tools.

list_skills

Lists all available skills with summaries:

# Agent calls: list_skills()
# Returns:
[
{
"name": "data-analyzer",
"description": "Analyzes datasets and provides insights",
"tags": ["data", "analysis"],
"scripts": ["analyze", "summarize"],
"resources": ["reference"]
},
{
"name": "file-processor",
"description": "Process files in batches",
"tags": ["files", "batch"],
"scripts": ["process", "validate"],
"resources": []
}
]

load_skill

Get full details for a specific skill:

# Agent calls: load_skill(skill_name="data-analyzer")
# Returns:
{
"name": "data-analyzer",
"description": "Analyzes datasets and provides insights",
"content": "# Data Analyzer\n\nUse this skill to analyze...",
"scripts": [
{"name": "analyze", "description": "Analyze a data file"},
{"name": "summarize", "description": "Summarize analysis results"}
],
"resources": [
{"name": "reference", "description": "Reference documentation"}
],
"tags": ["data", "analysis"],
"allowed_tools": ["filesystem__read_file"],
"version": "1.0.0"
}

The agent calls list_skills to browse what is available, then load_skill to get the full instructions before executing a skill script.