New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

skills-handler

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

skills-handler

A framework-agnostic handler for serving Agent Skills via well-known URIs

latest
Source
npmnpm
Version
0.1.2
Version published
Weekly downloads
8
14.29%
Maintainers
1
Weekly downloads
 
Created
Source

skills-handler

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

Installation

npm install skills-handler

For file-based skill loading:

npm install skills-handler gray-matter

Quick Start (Next.js)

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 index
  • GET /.well-known/skills/git-workflow/SKILL.md - Skill instructions

File-Based Skills

Load 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...

API Reference

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]),
]);

CLI

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

Endpoints

The handler serves these endpoints relative to basePath:

EndpointDescription
/index.jsonSkills discovery index
/{name}/SKILL.mdSkill instructions
/{name}/{file}Supporting resources

Skill Format

Skills follow the Agent Skills specification:

  • name: 1-64 chars, lowercase alphanumeric and hyphens, no leading/trailing/consecutive hyphens
  • description: Max 1024 chars, explains what the skill does and when to use it
  • files: Array of files in the skill directory (must include SKILL.md)

Events

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;
    }
  },
});

Progressive Disclosure

Skills support progressive loading to manage context efficiently:

  • Index metadata - Name and description loaded at startup (~100 tokens per skill)
  • Skill instructions - Full SKILL.md loaded when skill activates (<5k tokens recommended)
  • Supporting resources - Scripts, references, assets loaded on demand

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.

License

MIT

Keywords

agent

FAQs

Package last updated on 29 Jan 2026

Did you know?

Socket

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.

Install

Related posts