Basic Usage
import { Skill, SkillContext } from '@frontmcp/sdk';
@Skill({
name: 'code-review',
description: 'Complete code review workflow',
instructions: `
# Code Review Workflow
1. Fetch the pull request details
2. Review the code changes
3. Check for common issues
4. Post review comments
`,
tools: ['github_get_pr', 'github_post_comment'],
})
class CodeReviewSkill extends SkillContext {
async loadInstructions() {
return this.metadata.instructions as string;
}
async build() {
return {
id: this.skillId,
name: this.metadata.name,
description: this.metadata.description,
instructions: await this.loadInstructions(),
tools: this.getToolRefs(),
};
}
}
Signature
function Skill(providedMetadata: SkillMetadata): ClassDecorator
Configuration Options
Required Properties
| Property | Type | Constraints | Description |
|---|---|---|---|
name | string | kebab-case, 1-64 chars, no -- | Unique skill identifier |
description | string | 1-1024 chars, no XML tags | Skill description |
instructions | string | { file: string } | { url: string } | Skill instructions |
Optional Properties
| Property | Type | Description |
|---|---|---|
tools | SkillToolInput[] | Tools used by the skill |
id | string | Stable identifier (defaults to name) |
parameters | SkillParameter[] | Input parameters |
examples | SkillExample[] | Usage examples |
tags | string[] | Categorization tags |
priority | number | Search ranking weight (default: 0) |
hideFromDiscovery | boolean | Hide from search results (default: false) |
visibility | 'mcp' | 'http' | 'both' | Discovery visibility (default: 'both') |
toolValidation | 'strict' | 'warn' | 'ignore' | Tool reference validation mode (default: 'warn') |
Agent Skills Spec Properties
These properties align with the Anthropic Agent Skills specification:| Property | Type | Description |
|---|---|---|
license | string | License name or reference (e.g. 'MIT', 'Apache-2.0') |
compatibility | string | Environment requirements (max 500 chars) |
specMetadata | Record<string, string> | Arbitrary key-value metadata (maps to spec metadata) |
allowedTools | string | Space-delimited pre-approved tools (maps to spec allowed-tools) |
resources | SkillResources | Bundled resource directories (scripts, references, assets) |
Instruction Sources
Inline String
@Skill({
name: 'my-skill',
description: 'My skill',
instructions: '# Instructions\n\n1. Step one\n2. Step two',
tools: [],
})
File Reference
@Skill({
name: 'my-skill',
description: 'My skill',
instructions: { file: './skills/my-skill.md' },
tools: [],
})
URL Reference
@Skill({
name: 'my-skill',
description: 'My skill',
instructions: { url: 'https://example.com/skills/my-skill.md' },
tools: [],
})
Tool References
By Name
tools: ['tool_name', 'another_tool']
By Class
tools: [MyToolClass, AnotherToolClass]
With Purpose
tools: [
{ name: 'github_get_pr', purpose: 'Fetch PR details', required: true },
{ name: 'github_comment', purpose: 'Post review feedback', required: false },
]
With Class and Purpose
tools: [
{ class: GitHubGetPRTool, purpose: 'Fetch PR details' },
]
Parameters
Define input parameters for skills:@Skill({
name: 'deploy',
description: 'Deploy application',
instructions: '...',
tools: ['deploy_app'],
parameters: [
{
name: 'environment',
description: 'Target environment',
required: true,
type: 'string',
},
{
name: 'version',
description: 'Version to deploy',
required: false,
type: 'string',
default: 'latest',
},
],
})
Examples
Provide usage examples:@Skill({
name: 'data-analysis',
description: 'Analyze data sets',
instructions: '...',
tools: ['query_database', 'generate_chart'],
examples: [
{
scenario: 'Analyze monthly sales',
parameters: { table: 'sales', period: 'monthly' },
expectedOutcome: 'Sales trends chart and summary report',
},
],
})
Function-Based Alternative
import { skill } from '@frontmcp/sdk';
const codeReviewSkill = skill({
name: 'code-review',
description: 'Code review workflow',
instructions: { file: './code-review.md' },
tools: ['github_get_pr', 'github_comment'],
tags: ['github', 'review'],
});
Skill Content Output
Skills build toSkillContent:
interface SkillContent {
id: string;
name: string;
description: string;
instructions: string;
tools: Array<{
name: string;
purpose?: string;
required?: boolean;
}>;
parameters?: SkillParameter[];
examples?: SkillExample[];
// Agent Skills spec fields
license?: string;
compatibility?: string;
specMetadata?: Record<string, string>;
allowedTools?: string;
resources?: SkillResources;
}
interface SkillResources {
scripts?: string;
references?: string;
assets?: string;
}
Skill Validation
Skills are validated on server startup:@FrontMcp({
info: { name: 'Server', version: '1.0.0' },
apps: [MyApp],
skillsConfig: {
enabled: true,
validation: 'strict', // 'strict' | 'warn' | 'ignore'
},
})
- strict: Fail if skill references missing tools
- warn: Log warnings but continue
- ignore: Skip validation
Skill Sessions
Skills can be loaded into sessions for focused tool access:// Client-side
const client = await connect(config);
// Search for skills
const results = await client.searchSkills('code review');
// Load skill into session
await client.loadSkills(['code-review'], {
activateSession: true,
policyMode: 'strict', // Only allow skill's tools
});
// Now tool calls are restricted to skill's tool allowlist
Full Example
import { Skill, SkillContext, Tool, ToolContext, App, FrontMcp } from '@frontmcp/sdk';
import { z } from 'zod';
// Tools
@Tool({
name: 'jira_get_issue',
inputSchema: { issueKey: z.string() },
})
class JiraGetIssueTool extends ToolContext {
async execute(input) {
return { key: input.issueKey, summary: 'Issue summary' };
}
}
@Tool({
name: 'jira_update_status',
inputSchema: { issueKey: z.string(), status: z.string() },
})
class JiraUpdateStatusTool extends ToolContext {
async execute(input) {
return { success: true };
}
}
@Tool({
name: 'slack_notify',
inputSchema: { channel: z.string(), message: z.string() },
})
class SlackNotifyTool extends ToolContext {
async execute(input) {
return { sent: true };
}
}
// Skill
@Skill({
name: 'sprint-planning',
description: 'Assist with Agile sprint planning',
instructions: `
# Sprint Planning Workflow
## Overview
Help the team plan their next sprint by reviewing backlog items and updating statuses.
## Steps
1. **Review Backlog**
- Use \`jira_get_issue\` to fetch backlog items
- Analyze priority and estimates
2. **Assign to Sprint**
- Use \`jira_update_status\` to move items to sprint
- Verify capacity constraints
3. **Notify Team**
- Use \`slack_notify\` to inform the team
- Share sprint goals and assignments
## Best Practices
- Keep sprint scope realistic
- Balance workload across team members
- Leave buffer for unexpected work
`,
tools: [
{ name: 'jira_get_issue', purpose: 'Fetch issue details from backlog', required: true },
{ name: 'jira_update_status', purpose: 'Move issues to sprint', required: true },
{ name: 'slack_notify', purpose: 'Notify team of sprint plan', required: false },
],
parameters: [
{ name: 'sprintName', description: 'Name of the sprint', required: true, type: 'string' },
{ name: 'capacity', description: 'Team capacity in story points', required: false, type: 'number', default: 40 },
],
examples: [
{
scenario: 'Plan a two-week sprint',
parameters: { sprintName: 'Sprint 23', capacity: 40 },
expectedOutcome: 'Sprint backlog populated with balanced workload',
},
],
tags: ['agile', 'jira', 'planning'],
priority: 10,
})
class SprintPlanningSkill extends SkillContext {
async loadInstructions() {
return this.metadata.instructions as string;
}
async build() {
return {
id: this.skillId,
name: this.metadata.name,
description: this.metadata.description,
instructions: await this.loadInstructions(),
tools: this.getToolRefs().map(ref => ({
name: ref.name,
purpose: ref.purpose,
required: ref.required !== false,
})),
parameters: this.metadata.parameters,
examples: this.metadata.examples,
};
}
}
@App({
name: 'project-management',
tools: [JiraGetIssueTool, JiraUpdateStatusTool, SlackNotifyTool],
skills: [SprintPlanningSkill],
})
class ProjectManagementApp {}
@FrontMcp({
info: { name: 'PM Assistant', version: '1.0.0' },
apps: [ProjectManagementApp],
skillsConfig: {
enabled: true,
validation: 'strict',
},
})
export default class PMAssistantServer {}
SKILL.md Files
Load skills from SKILL.md files with YAML frontmatter (per Agent Skills spec):---
name: review-pr
description: Review a GitHub pull request
license: MIT
compatibility: Requires git CLI
tags:
- github
- code-review
metadata:
author: platform-team
version: "1.0"
allowed-tools: Read Edit Bash(git diff)
---
# PR Review Instructions
1. Fetch the PR details using github_get_pr
2. Review each changed file
3. Add review comments
4. Submit the review
Loading SKILL.md Files
import { loadSkillMdFile, parseSkillMdFrontmatter } from '@frontmcp/sdk';
// High-level: read + parse in one call
const metadata = await loadSkillMdFile('./skills/review-pr/SKILL.md');
// Low-level: parse content you already have
const { frontmatter, body } = parseSkillMdFrontmatter(rawContent);
Skill Directories
Load entire skill directories with theskillDir() helper:
import { skillDir } from '@frontmcp/sdk';
const reviewSkill = await skillDir('./skills/review-pr');
// Reads SKILL.md, auto-detects scripts/, references/, assets/
@App({
name: 'my-app',
skills: [reviewSkill],
})
class MyApp {}
skills/review-pr/
SKILL.md # Required
scripts/ # Optional: automation scripts
references/ # Optional: reference documents
assets/ # Optional: images, templates
Agent Skills Spec Example
A fully spec-compliant skill:@Skill({
name: 'security-audit',
description: 'Perform a security audit on the codebase',
instructions: { file: './skills/security-audit/SKILL.md' },
tools: [
{ name: 'code_search', purpose: 'Search for vulnerability patterns', required: true },
{ name: 'file_read', purpose: 'Read source files', required: true },
{ name: 'create_report', purpose: 'Generate audit report' },
],
tags: ['security', 'audit', 'compliance'],
license: 'Apache-2.0',
compatibility: 'Requires Node.js 24+ and access to source repository',
specMetadata: {
author: 'security-team',
version: '3.0.0',
category: 'security',
},
allowedTools: 'Read Grep Glob',
resources: {
scripts: './skills/security-audit/scripts',
references: './skills/security-audit/references',
},
})
class SecurityAuditSkill extends SkillContext {}
Related
SkillContext
Context class details
SkillRegistry
Skill registry API
@Tool
Define tools
Skills Overview
Skills documentation