Build Your Own Claude Code Skill (2026)
The best Claude Code skills are the ones you build yourself, tailored exactly to your team’s workflow. This tutorial walks you through designing, implementing, testing, and distributing a custom skill from scratch. By the end, you will have a working skill that you can share with the community.
Before building, browse existing skills in the Skill Finder to make sure someone has not already built what you need.
What Is a Claude Code Skill?
A skill is a set of instructions, context, or tools that modify Claude Code’s behavior for specific tasks. Skills range from simple (a paragraph of instructions in CLAUDE.md) to complex (an MCP server that provides external data and tools).
The three skill types:
- Instruction skills: Markdown files that tell Claude how to behave
- Context skills: Files that provide reference data (API schemas, style guides, architecture docs)
- Tool skills: MCP servers that give Claude new capabilities (database access, API calls, custom commands)
This tutorial covers all three types.
Step 1: Define the Problem
Every good skill starts with a specific pain point. Ask yourself:
- What task do I repeat multiple times a week?
- Where does Claude Code give me output I always have to fix?
- What team convention does Claude not know about?
Example pain point: “Claude Code generates API endpoints without proper error handling and logging. I fix this on every PR.”
This is a perfect skill candidate: a repeatable problem with a clear solution.
Step 2: Write the Instruction Skill
Start simple. Create a markdown file with clear instructions:
mkdir -p .claude/skills/
Create .claude/skills/api-standards.md:
# API Standards Skill
## Error Handling
Every API endpoint MUST:
1. Wrap the handler body in try/catch
2. Catch specific error types (ValidationError, NotFoundError, AuthError)
3. Return structured error responses: { error: { code, message, details } }
4. Log errors with context: logger.error(message, { endpoint, userId, requestId })
5. Never expose stack traces in production responses
## Logging
Every API endpoint MUST:
1. Log the request: logger.info("Request received", { method, path, userId })
2. Log the response: logger.info("Response sent", { method, path, status, duration })
3. Use correlation IDs: extract X-Request-ID from headers or generate one
4. Include timing: measure and log handler duration in milliseconds
## Response Format
All responses MUST follow this structure:
- Success: { data: <result>, meta: { requestId, timestamp } }
- Error: { error: { code: "ERROR_CODE", message: "Human readable", details: {} } }
- List: { data: [items], meta: { total, page, pageSize, requestId } }
## Status Codes
- 200: Success (GET, PUT, PATCH)
- 201: Created (POST)
- 204: No Content (DELETE)
- 400: Bad Request (validation failure)
- 401: Unauthorized (missing/invalid auth)
- 403: Forbidden (insufficient permissions)
- 404: Not Found
- 409: Conflict (duplicate resource)
- 422: Unprocessable Entity (business logic rejection)
- 500: Internal Server Error (unexpected failures only)
Step 3: Test the Skill
Verify the skill works by testing it against real tasks:
# Start a new Claude Code session
claude
# Ask Claude to generate an endpoint
> Create a GET /api/users/:id endpoint using Express.js
# Check: Does the output include try/catch, logging, structured responses?
# If not, refine the skill instructions
Testing Checklist
- Claude follows error handling rules
- Claude adds logging with correlation IDs
- Claude uses correct status codes
- Claude structures responses correctly
- Claude does not over-engineer (adds only what the skill requires)
If Claude ignores parts of the skill, make those instructions more prominent (add “MUST” or “ALWAYS”) or move them higher in the file.
Step 4: Add Context Data (Optional)
Some skills benefit from reference data. For the API standards skill, you might add an example:
Create .claude/skills/api-example.md:
# API Endpoint Reference Example
Use this as a template for all new endpoints:
```typescript
import { Router, Request, Response, NextFunction } from 'express';
import { logger } from '../utils/logger';
import { AppError, NotFoundError, ValidationError } from '../errors';
const router = Router();
router.get('/api/users/:id', async (req: Request, res: Response, next: NextFunction) => {
const requestId = req.headers['x-request-id'] || crypto.randomUUID();
const startTime = Date.now();
logger.info('Request received', {
method: 'GET',
path: `/api/users/${req.params.id}`,
requestId,
});
try {
const user = await userService.findById(req.params.id);
if (!user) {
throw new NotFoundError(`User ${req.params.id} not found`);
}
const duration = Date.now() - startTime;
logger.info('Response sent', { method: 'GET', path: req.path, status: 200, duration });
res.json({
data: user,
meta: { requestId, timestamp: new Date().toISOString() },
});
} catch (error) {
const duration = Date.now() - startTime;
if (error instanceof AppError) {
logger.warn('Expected error', { code: error.code, message: error.message, requestId, duration });
res.status(error.statusCode).json({
error: { code: error.code, message: error.message, details: error.details },
});
} else {
logger.error('Unexpected error', { error, requestId, duration });
res.status(500).json({
error: { code: 'INTERNAL_ERROR', message: 'An unexpected error occurred' },
});
}
}
});
Context examples are extremely effective because Claude learns patterns from examples better than from abstract rules.
Step 5: Build a Tool Skill (Advanced)
For skills that need to execute code or access external data, create an MCP server:
mkdir -p my-skill-server
cd my-skill-server
npm init -y
npm install @modelcontextprotocol/sdk
Create index.js:
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new Server({
name: 'api-standards-checker',
version: '1.0.0',
}, {
capabilities: { tools: {} },
});
server.setRequestHandler('tools/list', async () => ({
tools: [{
name: 'check_api_standards',
description: 'Checks if an API endpoint follows team standards',
inputSchema: {
type: 'object',
properties: {
filePath: { type: 'string', description: 'Path to the endpoint file' },
},
required: ['filePath'],
},
}],
}));
server.setRequestHandler('tools/call', async (request) => {
if (request.params.name === 'check_api_standards') {
// Implement your checking logic here
return {
content: [{ type: 'text', text: 'Standards check passed.' }],
};
}
});
const transport = new StdioServerTransport();
await server.connect(transport);
Register it in .claude/mcp.json:
{
"servers": {
"api-standards": {
"command": "node",
"args": ["./my-skill-server/index.js"]
}
}
}
Step 6: Share Your Skill
Once your skill is working, share it with the community:
- Create a GitHub repository with a clear README
- Include installation instructions (one-command install preferred)
- Add a LICENSE (MIT is the community standard)
- Submit to the Skill Finder for community discovery
- Tag the repo with
claude-code-skillfor discoverability
Skill README Template
# API Standards Skill for Claude Code
Enforces consistent error handling, logging, and response formats across API endpoints.
## Install
Copy to your project:
\`\`\`bash
curl -o .claude/skills/api-standards.md https://raw.githubusercontent.com/yourname/api-standards-skill/main/api-standards.md
\`\`\`
## What It Does
- Enforces try/catch on all endpoints
- Adds structured logging with correlation IDs
- Standardizes response format
- Uses correct HTTP status codes
## Compatibility
- Claude Code 1.0+
- All plans (Free, Pro, Max, API)
- Works with Express, Fastify, Koa, and Hono
Try It Yourself
Need inspiration for what to build? The Skill Finder shows the most requested skill categories. Check the “Missing Skills” section for gaps that the community wants filled. Your skill could become the next community favorite.
Skill Design Best Practices
- Keep instructions under 5KB. Larger skills waste tokens on every message.
- Be specific, not vague. “Always add error handling” is less effective than “Wrap handler body in try/catch.”
- Include examples. Claude learns patterns better from examples than from rules.
- Test with adversarial prompts. Ask Claude to do something that violates the skill to verify enforcement.
- Version your skill. Use semantic versioning so users can pin to stable versions.
FAQ
How long does it take to build a Claude Code skill?
A simple instruction skill takes 10-15 minutes to write and test. An MCP server skill takes 1-2 hours. The time investment pays off quickly because the skill saves time on every future interaction.
Do I need programming experience to build a Claude Code skill?
Not for instruction skills, which are plain markdown files. MCP server skills require JavaScript/TypeScript knowledge. Most developers start with instruction skills and graduate to MCP servers later.
How do I test if my Claude Code skill is working?
Start a new Claude Code session and ask it to perform a task covered by your skill. Check if the output follows your skill’s rules. Test with edge cases and adversarial prompts to verify enforcement.
Can I sell Claude Code skills?
Yes. There is no restriction on selling skills. Some developers offer premium skills with advanced features, support, and regular updates. The community standard is MIT-licensed free skills.
Get started → Generate your project setup with our Project Starter.
Related Guides
Configure MCP → Build your server config with our MCP Config Generator.
- Building a Custom Claude Code Skill Tutorial — Alternative tutorial with different approach
- Building Your First Claude Skill — Beginner-friendly introduction
- How to Install Claude Code Skills — Installation guide for users
- Top Claude Code Skills Ranked — See what the community has built
- Benchmarking Skills Performance — Measure your skill’s impact
- Skill Finder — Share your skill with the community