
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
skills-handler
Advanced tools
A framework-agnostic handler for serving Agent Skills via well-known URIs
A framework-agnostic handler for serving Agent Skills via well-known URIs. Implements the Agent Skills Discovery specification.
Repository: github.com/vercel-labs/skills-handler
npm install skills-handler
For file-based skill loading:
npm install skills-handler gray-matter
Create a catch-all route at app/.well-known/skills/[[...path]]/route.ts:
import { createSkillsHandler, createStaticProvider } from "skills-handler";
const handler = createSkillsHandler(
createStaticProvider([
{
name: "git-workflow",
description: "Follow team Git conventions for branching and commits.",
body: `# Git Workflow
Create feature branches from \`main\`:
\`\`\`bash
git checkout -b feature/my-feature main
\`\`\``,
files: ["SKILL.md"],
},
])
);
export { handler as GET, handler as OPTIONS };
Your skills are now available at:
GET /.well-known/skills/index.json - Discovery indexGET /.well-known/skills/git-workflow/SKILL.md - Skill instructionsLoad skills from the filesystem instead of defining them in code:
// app/.well-known/skills/[[...path]]/route.ts
import { createSkillsHandler, createFileProvider } from "skills-handler";
import path from "path";
const provider = await createFileProvider(path.join(process.cwd(), "skills"));
const handler = createSkillsHandler(provider);
export { handler as GET, handler as OPTIONS };
Directory structure:
project/
├── app/.well-known/skills/[[...path]]/route.ts
└── skills/
├── git-workflow/
│ └── SKILL.md
└── pdf-processing/
├── SKILL.md
├── scripts/
│ └── extract.py
└── references/
└── TABLES.md
Each SKILL.md file requires YAML frontmatter:
---
name: git-workflow
description: Follow team Git conventions for branching and commits.
---
# Git Workflow
Your skill instructions here...
createSkillsHandler(provider, config?)Creates the request handler.
const handler = createSkillsHandler(provider, {
basePath: "/.well-known/skills", // URL base path (default)
verboseLogs: false, // Enable debug logging
cacheControl: "public, max-age=3600", // Cache header
cors: "*", // CORS origin (* | string[] | false)
onEvent: (event) => {}, // Analytics callback
});
createStaticProvider(skills, additionalFiles?)Creates a provider from skills defined in code.
const provider = createStaticProvider([
{
name: "my-skill",
description: "What the skill does and when to use it.",
body: "# Skill Instructions\n\nMarkdown content...",
files: ["SKILL.md"],
},
]);
createFileProvider(directory)Creates a provider that loads skills from the filesystem.
const provider = await createFileProvider("./skills");
createCompositeProvider(providers)Merges multiple providers. Later providers override earlier ones for skills with the same name.
const provider = createCompositeProvider([
await createFileProvider("./base-skills"),
createStaticProvider([overrideSkill]),
]);
Initialize a skills endpoint in your project:
npx skills-handler init
Create a new skill:
npx skills-handler create-skill my-skill --description "What it does"
Validate skills:
npx skills-handler validate ./skills
The handler serves these endpoints relative to basePath:
| Endpoint | Description |
|---|---|
/index.json | Skills discovery index |
/{name}/SKILL.md | Skill instructions |
/{name}/{file} | Supporting resources |
Skills follow the Agent Skills specification:
SKILL.md)Subscribe to events for analytics:
const handler = createSkillsHandler(provider, {
onEvent: (event) => {
switch (event.type) {
case "INDEX_REQUESTED":
console.log(`Index served: ${event.skillCount} skills`);
break;
case "SKILL_REQUESTED":
console.log(`Skill loaded: ${event.skillName}`);
break;
case "FILE_REQUESTED":
console.log(`File served: ${event.skillName}/${event.filePath}`);
break;
case "NOT_FOUND":
console.log(`404: ${event.path}`);
break;
case "ERROR":
console.error(`Error: ${event.error.message}`);
break;
}
},
});
Skills support progressive loading to manage context efficiently:
SKILL.md loaded when skill activates (<5k tokens recommended)Reference supporting files with relative links in SKILL.md:
For advanced usage, see [references/ADVANCED.md](references/ADVANCED.md).
Run `scripts/setup.sh` to configure the environment.
MIT
FAQs
A framework-agnostic handler for serving Agent Skills via well-known URIs
The npm package skills-handler receives a total of 8 weekly downloads. As such, skills-handler popularity was classified as not popular.
We found that skills-handler demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.