How to Build an AI Agent Skill: Beginner's Complete Guide
How to build an AI agent skill from scratch โ create, test, and publish your first MCP skill to the TrustedSkills registry. Complete guide with working code examples and publishing steps.
๐Last updated 4 March 2026
Create a Node.js project, install @modelcontextprotocol/sdk, write a server that declares tools and handles calls, create a SKILL.md file, publish to npm, submit to TrustedSkills. About 30 minutes for a simple skill. Here's the full walkthrough.
When I built my first MCP skill โ a simple unit converter โ I was surprised how little code it actually took. The MCP SDK handles all the protocol plumbing; you just write the tool logic. Here's the step-by-step guide I wish I'd had.
What You'll Build
A temperature converter skill: two tools, celsius_to_fahrenheit and fahrenheit_to_celsius. Simple enough to understand quickly, complete enough to be a real template for anything more complex.
What You'll Need
- Node.js v18+ โ check with
node --version - An npm account for publishing
- A GitHub account for the TrustedSkills submission
- A code editor โ VS Code is ideal
Step 1: Project Setup
mkdir temperature-converter-mcp
cd temperature-converter-mcp
npm init -y
npm install @modelcontextprotocol/sdk
Step 2: Write the Server
Create index.js โ this is your entire skill:
#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
const server = new Server(
{ name: 'temperature-converter', version: '1.0.0' },
{ capabilities: { tools: {} } }
);
// Tell Claude what tools you have
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: 'celsius_to_fahrenheit',
description: 'Convert a temperature from Celsius to Fahrenheit',
inputSchema: {
type: 'object',
properties: {
celsius: { type: 'number', description: 'Temperature in Celsius' }
},
required: ['celsius']
}
},
{
name: 'fahrenheit_to_celsius',
description: 'Convert a temperature from Fahrenheit to Celsius',
inputSchema: {
type: 'object',
properties: {
fahrenheit: { type: 'number', description: 'Temperature in Fahrenheit' }
},
required: ['fahrenheit']
}
}
]
}));
// Handle the actual tool calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (name === 'celsius_to_fahrenheit') {
const f = (args.celsius * 9/5) + 32;
return {
content: [{ type: 'text', text: `${args.celsius}ยฐC = ${f.toFixed(1)}ยฐF` }]
};
}
if (name === 'fahrenheit_to_celsius') {
const c = (args.fahrenheit - 32) * 5/9;
return {
content: [{ type: 'text', text: `${args.fahrenheit}ยฐF = ${c.toFixed(1)}ยฐC` }]
};
}
throw new Error(`Unknown tool: ${name}`);
});
const transport = new StdioServerTransport();
await server.connect(transport);
Update package.json:
{
"name": "@yourusername/temperature-converter-mcp",
"version": "1.0.0",
"type": "module",
"bin": { "temperature-converter-mcp": "./index.js" }
}
chmod +x index.js # Mac/Linux only
Step 3: Create SKILL.md
This is what TrustedSkills reads. Don't skip it.
---
name: temperature-converter
description: Convert temperatures between Celsius and Fahrenheit
version: 1.0.0
platforms: [mcp, openclaw, claude, cursor]
tags: [utility, temperature]
metadata:
npm: "@yourusername/temperature-converter-mcp"
tools: [celsius_to_fahrenheit, fahrenheit_to_celsius]
---
Step 4: Test Locally First
Don't publish until you've tested. Add a local path config:
{
"mcpServers": {
"temp-converter": {
"command": "node",
"args": ["/absolute/path/to/temperature-converter-mcp/index.js"]
}
}
}
Restart Claude Desktop and ask: "What's 100 Celsius in Fahrenheit?" โ you should get "100ยฐC = 212.0ยฐF".
I've seen several first-time skill builders publish to npm before testing locally โ then spend an hour debugging a bug that would've been obvious in 30 seconds with local testing. Always test with the full local path config before publishing. It's much faster to iterate locally.
Step 5: Publish to npm
npm login
npm publish --access public # --access public for scoped packages
Test the published version:
npx -y @yourusername/temperature-converter-mcp
Step 6: Submit to TrustedSkills
- Fork the registry repo
- Create
skills/temperature-converter/SKILL.md - Open a Pull Request
- Review, merge โ your skill appears on the site within minutes
SKILL.md Fields
| Field | Required | Notes |
|---|---|---|
name | Yes | Lowercase, hyphens only |
description | Yes | 10โ500 characters |
version | Yes | Semantic version e.g. 1.0.0 |
platforms | Yes | mcp, openclaw, claude, cursor, openai |
metadata.npm | Recommended | npm package name |
Frequently Asked Questions
Do I need TypeScript to build a skill?
No. JavaScript works perfectly, as shown in this guide. TypeScript adds type safety but isn't required. The MCP SDK supports both equally.
Can I build skills in Python?
Yes. The mcp package on PyPI provides the same SDK in Python. Concepts are identical โ you just write Python instead of JavaScript.
How do I add API keys to my skill?
Read them from process.env: const apiKey = process.env.MY_API_KEY. Document required env vars in SKILL.md. Users add them to the "env" block in their MCP config.
How long until a submitted skill appears on TrustedSkills?
Minutes after the PR is merged. Community verification takes days (depends on reviewer availability). Formal Verified status takes weeks โ it's a proper security review.
TrustedSkills Team
The TrustedSkills team builds and tests AI agent integrations across Claude, OpenClaw, Cursor, and VS Code. We verify every skill in our registry and have set up hundreds of MCP configs across every major platform.