How to Create and Load Reusable Prompt Modules Using Skills in the Copilot SDK
Skills are self-contained prompt modules defined by a SKILL.md file that the Copilot SDK automatically discovers from configured directories and injects into agent context at runtime.
The Copilot SDK extends agent capabilities through a modular system called Skills. Each Skill is a reusable prompt module—complete with metadata and instructions—that the SDK loads during session initialization. By organizing these modules in scanned directories, you can create domain-specific behaviors that are available via slash commands or programmatic calls. This guide details the implementation based on the github/copilot-sdk source code, covering the SKILL.md schema, discovery mechanisms, and runtime APIs.
Understanding the Skill Module Structure
A Skill is fundamentally a directory containing a SKILL.md file. This markdown file uses front-matter to declare metadata and a body section for the reusable prompt content.
The front-matter must include:
- name: The unique identifier for the Skill.
- description: A short summary of the Skill's purpose.
- allowedTools: An array of tool permissions (can be empty).
The markdown body contains the actual instructions that get injected into the agent's context.
// Example: my-skills/data-analysis/SKILL.md
/*
---
name: data-analysis
description: Analyzes CSV data and generates summary statistics
allowedTools: ["file-read", "code-interpreter"]
---
When invoked, analyze the provided CSV file and return:
1. Column data types
2. Missing value counts
3. Basic statistical summary
*/
According to the source code in test/harness/replayingCapiProxy.ts, the SDK uses normalizeSkillContextFrontmatter to parse and normalize this front-matter, extracting the metadata and prompt content for injection into the session context.
Configuring Skill Discovery Paths
The SDK discovers Skills by walking configured directories at runtime. It scans project-level, user-level, plugin-level, and any custom paths specified during SDK initialization. For each discovered Skill, the SDK creates a SkillSource entry that records the Skill's name, description, source type, and enabled state.
These definitions are located in nodejs/src/generated/session-events.ts, which exports the SkillSource interface used throughout the discovery process.
To specify where the SDK should look for Skills, provide a skillsDirectory path in the Copilot configuration:
import { Copilot } from '@github/copilot-sdk';
const sdk = new Copilot({
skillsDirectory: './my-skills', // Root directory containing Skill folders
enableSkills: true, // Global toggle for skill loading
});
Loading and Enabling Skills at Runtime
During session creation, the SDK loads all discovered Skills and merges their prompts into the agent instructions. You can control which Skills are active using session options.
The enableSkills boolean toggles the feature globally, while the disabledSkills array allows you to exclude specific Skills by name:
const session = await sdk.session.create({
disabledSkills: ['legacy-analysis'], // Exclude specific Skills
});
To modify the disabled list after initialization, use the RPC endpoint skills.config.setDisabledSkills, defined in nodejs/src/generated/rpc.ts. This allows dynamic enablement without restarting the session.
Invoking Skills Programmatically
Once loaded, Skills can be invoked explicitly via RPC calls. The skills.invoke method triggers a specific Skill by name, causing the agent to execute the instructions defined in that Skill's SKILL.md file.
// Invoke the Skill explicitly
await session.rpc.skills.invoke({ skillName: 'data-analysis' });
When a Skill runs, the SDK emits a SkillInvokedEvent containing the Skill's metadata and output. You can listen for these events to handle Skill results or track usage:
session.on('skill.invoked', (event) => {
console.log(`Skill ${event.data.name} executed`);
console.log('Output:', event.data.output);
});
The event definitions, including SkillInvokedEvent and SkillsLoadedEvent, are found in nodejs/src/generated/session-events.ts, providing type-safe access to Skill lifecycle data.
Summary
- Skills are reusable prompt modules defined by a
SKILL.mdfile with front-matter metadata and markdown instructions. - The SDK discovers Skills by scanning configured directories and creates SkillSource entries for each module found in
nodejs/src/generated/session-events.ts. - Use
enableSkillsanddisabledSkillssession options to control loading, or modify settings at runtime via theskills.config.setDisabledSkillsRPC method defined innodejs/src/generated/rpc.ts. - Invoke Skills programmatically using
session.rpc.skills.invoke()and monitor execution throughSkillInvokedEventlisteners. - The front-matter parser
normalizeSkillContextFrontmatterintest/harness/replayingCapiProxy.tshandles standardization of Skill metadata.
Frequently Asked Questions
Where does the Copilot SDK search for Skill modules?
The SDK searches configured skill directories that can be set at the project, user, plugin, or custom level. You specify the root path via the skillsDirectory configuration option when initializing the Copilot client. During session startup, the SDK walks these directories and builds a registry of SkillSource entries for each valid SKILL.md file discovered.
What is the format of the SKILL.md file?
A SKILL.md file must include YAML front-matter delimited by triple dashes, containing name, description, and allowedTools fields. The remainder of the file contains the prompt instructions in markdown format. The SDK uses the normalizeSkillContextFrontmatter function found in test/harness/replayingCapiProxy.ts to parse this structure and extract the reusable prompt content.
Can I disable specific Skills after the session has started?
Yes. While you can pass a disabledSkills array during session creation, you can also update the disabled list at runtime using the skills.config.setDisabledSkills RPC method. This method is defined in nodejs/src/generated/rpc.ts and allows you to dynamically control which Skills are available without reinitializing the entire session.
How do I know when a Skill has been invoked?
The SDK emits a SkillInvokedEvent whenever a Skill runs, whether triggered by a user command or programmatically via RPC. You can listen for this event on the session object to receive the Skill's name, source, and output data. The event type definitions are located in nodejs/src/generated/session-events.ts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →