Initial commit: antigravity-claudekit
This commit is contained in:
193
skills/ck-mcp-builder/SKILL.md
Normal file
193
skills/ck-mcp-builder/SKILL.md
Normal file
@@ -0,0 +1,193 @@
|
||||
---
|
||||
name: ck-mcp-builder
|
||||
description: >
|
||||
Scaffolds and implements Model Context Protocol (MCP) servers with tools, resources, and prompts.
|
||||
Activate when user says 'build an MCP server', 'create MCP tools', 'scaffold MCP',
|
||||
'add MCP integration', or 'expose API as MCP'. Accepts tool definitions,
|
||||
resource schemas, and target transport (stdio, SSE, HTTP).
|
||||
---
|
||||
|
||||
## Overview
|
||||
Generates complete MCP server implementations using the official MCP SDK. Covers tool registration, resource endpoints, prompt templates, and transport configuration for Claude Desktop or other MCP clients.
|
||||
|
||||
## When to Use
|
||||
- Exposing custom tools or APIs to Claude via MCP protocol
|
||||
- Building a server that Claude can use to access databases, APIs, or file systems
|
||||
- Creating reusable MCP integrations for a team or organization
|
||||
- Adding MCP support to an existing service
|
||||
|
||||
## Don't Use When
|
||||
- Simple one-off script that doesn't need to be invocable by an LLM
|
||||
- Task requires an existing MCP server configuration (use ck-mcp-management)
|
||||
- Building a client that consumes MCP servers (different SDK surface)
|
||||
|
||||
## Steps / Instructions
|
||||
|
||||
### 1. Initialize Project
|
||||
|
||||
```bash
|
||||
mkdir my-mcp-server && cd my-mcp-server
|
||||
npm init -y
|
||||
npm install @modelcontextprotocol/sdk zod
|
||||
npm install -D typescript @types/node tsx
|
||||
```
|
||||
|
||||
`tsconfig.json`:
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "Node16",
|
||||
"moduleResolution": "Node16",
|
||||
"outDir": "./dist",
|
||||
"strict": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Create the Server
|
||||
|
||||
```typescript
|
||||
// src/server.ts
|
||||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
||||
import { z } from "zod";
|
||||
|
||||
const server = new McpServer({
|
||||
name: "my-mcp-server",
|
||||
version: "1.0.0",
|
||||
});
|
||||
```
|
||||
|
||||
### 3. Register Tools
|
||||
|
||||
```typescript
|
||||
// Simple tool with input schema
|
||||
server.tool(
|
||||
"get_weather",
|
||||
"Get current weather for a city",
|
||||
{
|
||||
city: z.string().describe("City name to get weather for"),
|
||||
units: z.enum(["celsius", "fahrenheit"]).default("celsius"),
|
||||
},
|
||||
async ({ city, units }) => {
|
||||
// implementation
|
||||
const data = await fetchWeather(city, units);
|
||||
return {
|
||||
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
// Tool that returns multiple content types
|
||||
server.tool(
|
||||
"capture_screenshot",
|
||||
"Take a screenshot of a URL",
|
||||
{ url: z.string().url() },
|
||||
async ({ url }) => {
|
||||
const imageBuffer = await screenshot(url);
|
||||
return {
|
||||
content: [
|
||||
{ type: "text", text: `Screenshot of ${url}` },
|
||||
{ type: "image", data: imageBuffer.toString("base64"), mimeType: "image/png" },
|
||||
],
|
||||
};
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### 4. Register Resources
|
||||
|
||||
```typescript
|
||||
// Static resource
|
||||
server.resource(
|
||||
"config",
|
||||
"app://config",
|
||||
async (uri) => ({
|
||||
contents: [{
|
||||
uri: uri.href,
|
||||
mimeType: "application/json",
|
||||
text: JSON.stringify({ version: "1.0.0", env: process.env.NODE_ENV }),
|
||||
}],
|
||||
})
|
||||
);
|
||||
|
||||
// Dynamic resource with URI template
|
||||
server.resource(
|
||||
"user-profile",
|
||||
new ResourceTemplate("users://{userId}/profile", { list: undefined }),
|
||||
async (uri, { userId }) => ({
|
||||
contents: [{
|
||||
uri: uri.href,
|
||||
mimeType: "application/json",
|
||||
text: JSON.stringify(await getUser(userId)),
|
||||
}],
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
### 5. Register Prompt Templates
|
||||
|
||||
```typescript
|
||||
server.prompt(
|
||||
"code-review",
|
||||
"Generate a code review for a file",
|
||||
{
|
||||
filename: z.string(),
|
||||
focus: z.string().optional().describe("Specific aspect to focus on"),
|
||||
},
|
||||
({ filename, focus }) => ({
|
||||
messages: [{
|
||||
role: "user",
|
||||
content: {
|
||||
type: "text",
|
||||
text: `Review the code in ${filename}${focus ? ` focusing on ${focus}` : ""}.
|
||||
Check for: correctness, performance, security, readability.`,
|
||||
},
|
||||
}],
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
### 6. Start the Server
|
||||
|
||||
```typescript
|
||||
// Stdio transport (for Claude Desktop)
|
||||
async function main() {
|
||||
const transport = new StdioServerTransport();
|
||||
await server.connect(transport);
|
||||
console.error("MCP server running on stdio");
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
```
|
||||
|
||||
### 7. Configure in Claude Desktop
|
||||
|
||||
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"my-server": {
|
||||
"command": "node",
|
||||
"args": ["/absolute/path/to/dist/server.js"],
|
||||
"env": {
|
||||
"API_KEY": "..."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8. Test with MCP Inspector
|
||||
|
||||
```bash
|
||||
npx @modelcontextprotocol/inspector node dist/server.js
|
||||
```
|
||||
|
||||
## Notes
|
||||
- Use `console.error` for logging — stdout is reserved for the MCP protocol
|
||||
- Never hardcode secrets; pass via environment variables in the config
|
||||
- Tool descriptions are critical — the LLM uses them to decide when to call the tool
|
||||
- Keep tools focused and single-purpose; compose complex behavior at the LLM level
|
||||
- Zod schemas auto-generate JSON Schema for tool input validation
|
||||
Reference in New Issue
Block a user