Table of Contents
Adding Agent Skills support means teaching an agent application to discover skill packages, show their metadata to the model, load selected instructions and retrieve supporting resources when needed. The skill file supplies guidance; your application remains responsible for permissions, trust and tool execution.
This guide describes an implementation design, not a complete runnable client. Read the Agent Skills specification for file-format requirements and the official integration guide for additional implementation options.
Choose the loading model
Separate discovery from activation so that installing many skills does not require inserting every instruction file into every conversation.
| Stage | Content exposed | When it is needed | Context cost |
|---|---|---|---|
| Catalog | Skill names and descriptions | When the model needs to select a skill | Depends on catalog size and descriptions |
| Activation | Selected SKILL.md instructions | When the skill is selected | Depends on instruction length |
| Resources | Referenced files or tool results | When a step requires them | Depends on the material retrieved |
Metadata is smaller than complete instructions, but it still consumes context. Measure actual token usage with your model rather than treating an approximate per-skill estimate as a fixed cost.
1. Discover packages within explicit roots
Configure which directories or remote sources the application accepts. A local agent might support project, user and administrator-managed packages. A hosted agent can use checked-out project files, uploaded bundles or an authenticated registry; it does not automatically have access to a user's home directory.
| Scope | Illustrative location | Policy decision |
|---|---|---|
| Project convention | <project>/.agents/skills/ | Require appropriate project trust. |
| Project-specific client | <project>/.myagent/skills/ | Document whether this overrides other project roots. |
| User convention | ~/.agents/skills/ | Keep access tied to the current user. |
| User-specific client | ~/.myagent/skills/ | Document its precedence. |
These paths are examples of host conventions. The specification defines package contents, not a universal installation directory. In particular, a project-relative path is not the same as /.agents/skills/ at the filesystem root.
Find directories containing the exact filename SKILL.md. For example, .agents/skills/pdf-processing/SKILL.md identifies one package, while a standalone README in the root does not.
Bound the scan and resolve conflicts
Avoid searching an entire disk or recursively entering dependency and version-control directories. Set limits on depth, package count and file size that fit your deployment. Handle symlinks and canonical paths explicitly so discovery cannot silently escape approved roots.
Choose deterministic precedence for duplicate names and show which package was selected. Do not depend on an unspecified filesystem enumeration order. An organization may also need reserved names that a repository cannot override.
Evaluate trust before presenting a repository's skill description to the model. Metadata is also text from the package author, so checking only the full instructions at activation leaves an earlier injection opportunity.
2. Parse and validate SKILL.md
The file starts with YAML frontmatter between separate --- delimiter lines, followed by a Markdown body. Parse YAML with a safe data parser; do not execute constructors or embedded code during discovery.
---
name: pdf-processing
description: "Extract text from supplied PDFs. Use when: the user requests PDF text extraction."
---
# PDF processing
Explain the required input, permitted tools, output and failure handling here.The quoted description illustrates a value containing a colon followed by a space. Preserve real newlines and do not confuse the three-hyphen delimiter with two hyphens or an ellipsis.
Validate required fields, types and length constraints. Record errors with the source location. If compatibility with a permissive client matters, make any relaxed behavior explicit; do not silently repair malformed YAML in a way that could change its meaning. A missing description or an unparseable header should not produce a usable catalog entry.
| Stored field | Purpose |
|---|---|
name | Resolve a catalog selection. |
description | Explain the intended task to the model. |
location | Locate the approved local file or remote package. |
root | Resolve bundled resource paths. |
source_id, version or digest | Distinguish packages and detect content changes. |
| Trust and eligibility state | Support authorization checks and useful diagnostics. |
Cache the body or read it when activated. Caching provides a stable snapshot; reading later can pick up edits. Whichever approach you choose, ensure the instructions activated are the version that passed the relevant checks.
3. Expose a concise catalog
Provide eligible skill names and descriptions in a clearly labeled structured section. Serialize values correctly rather than concatenating unescaped package text into JSON or XML. An illustrative catalog is:
{
"skills": [
{
"name": "pdf-processing",
"description": "Extract text from supplied PDF files."
}
]
}Do not include disabled, unauthorized or incompatible skills as options the model can activate. Keep their diagnostic status available to the user separately. If the catalog is empty, omit the selection instructions and any unusable activation tool.
Give the model a short host-authored instruction explaining how to load a selected skill. Catalog text should not acquire the authority of application policy merely because it appears beside that instruction.
4. Implement activation and resource access
There are two common approaches:
- File-reader activation: the model reads an approved SKILL.md path using an existing file tool. This is straightforward when filesystem access and its permissions already fit the application.
- Dedicated activation tool: a tool such as
activate_skill(name)resolves the name, checks eligibility and returns instructions. This is useful for remote packages, auditing and centralized policy enforcement.
Validate the selected name against the actual catalog. An enum can help the model choose, but the server must still check the value and current authorization. A slash command or other explicit user invocation should pass through the same checks.
Return enough provenance to keep instructions and supporting files associated with the right package. For example:
{
"skill": "pdf-processing",
"source_id": "approved-package-17",
"root": "/approved/skills/pdf-processing",
"instructions": "The validated Markdown body is returned here.",
"resources": ["scripts/extract.py", "references/formats.md"]
}This is an illustrative response shape, not a required standard. If you strip frontmatter, retain relevant compatibility information elsewhere. Listing resources need not load their contents.
Separate reading instructions from granting capabilities
Resolve relative resource paths against the approved package root, normalize them and enforce the application's path policy. A reference to ../ or a symlink must not bypass that policy.
Permission to read a skill is not permission to execute all its scripts, access unrelated files or send data to an external service. Apply the normal tool, network and action controls. A skill's declaration of allowed tools is not sufficient by itself to create those permissions.
For examples of how extensions affect real developer workflows, see these OpenCode plugin capabilities and permission checks.
5. Preserve active instructions across context changes
When the conversation is compacted, keep an accurate record of the active skill, its version and relevant instructions. You can retain its instruction block or reload the verified package before continuing. Do not assume that a brief summary preserves every constraint.
Deduplicate only when the same version's instructions are still available in context. A record saying “activated earlier” is insufficient if the actual instructions have since been removed. Define whether updates take effect immediately, at the next activation or in a new session, and disclose meaningful changes.
If work is delegated to another agent, supply the needed skill version and task context explicitly. Apply the same permission limits to that agent. Delegation is optional and should solve a real workflow need, not be required for basic skill support.
Verify the integration before enabling broad use
- A valid package is discovered and activated with the expected content.
- Malformed YAML and missing metadata produce clear diagnostics.
- Duplicate names resolve consistently and visibly.
- Untrusted or disabled packages do not enter the model's catalog.
- Resource traversal and unauthorized actions are rejected.
- Package edits cannot silently substitute unchecked instructions.
- Compaction and repeated activation preserve the correct version without unnecessary duplication.
These checks evaluate the integration, not whether every skill will perform well. Test task behavior separately. If you are choosing an application architecture, this AI agent framework comparison can help distinguish built-in capabilities from components you need to implement.
Reader Comments 0
Sign in with email or Google to join the discussion.