This skill should be used when the user asks to "create MCP server", "build server", "add server to catalog", "implement MCP", "new server", mentions "metorial/servers/", or discusses Model Context Protocol server development. Provides comprehensive guidance for building MCP servers that match existing Metorial catalog patterns using the SDK and established conventions.
This skill provides guidance for creating MCP (Model Context Protocol) servers for the Metorial catalog. The catalog contains 33+ production servers providing patterns to follow.
Before implementing a new MCP server, gather context from existing tools:
Use Drift to understand existing server patterns:
drift_context targeting metorial/servers/
This provides detected patterns for:
Use Serena for development workflow:
read_memory('development_workflow')
This provides:
mise run catalog:build)Navigate SDK types with Serena:
find_symbol targeting metorial/packages/sdk/
Key types: MCPServer, Tool, Resource, Prompt
Create servers in metorial/servers/<server-name>/:
<server-name>/
├── server.ts # Main server implementation
├── metorial.json # Server metadata manifest
├── package.json # Dependencies
├── tsconfig.json # TypeScript configuration
└── README.md # Server documentation
drift_code_examplesCreate metorial.json:
{
"name": "server-name",
"title": "Human Readable Title",
"description": "What this server does",
"version": "1.0.0",
"tools": [
{
"name": "tool_name",
"description": "What the tool does"
}
],
"configuration": {
"apiKey": {
"type": "string",
"description": "API key for authentication",
"required": true,
"env": "SERVICE_API_KEY"
}
}
}
Follow the standard server pattern:
import { MCPServer } from '@metorial/sdk';
const server = new MCPServer({
name: 'server-name',
version: '1.0.0',
});
// Define tools
server.tool({
name: 'tool_name',
description: 'Tool description',
inputSchema: {
type: 'object',
properties: {
param: { type: 'string', description: 'Parameter description' }
},
required: ['param']
},
handler: async (input) => {
// Implementation
return { content: [{ type: 'text', text: 'Result' }] };
}
});
// Start server
server.start();
Build validation:
mise run catalog:build
Pattern compliance:
drift_validate_change
Local testing:
bun run dev
Follow established error patterns:
try {
const result = await apiCall();
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
} catch (error) {
return {
content: [{
type: 'text',
text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`
}],
isError: true
};
}
Use environment variables for sensitive data:
const apiKey = process.env.SERVICE_API_KEY;
if (!apiKey) {
throw new Error('SERVICE_API_KEY environment variable required');
}
Follow conventions:
github_create_issueValidate inputs before processing: