chore: add skills library
This commit is contained in:
parent
57560319f0
commit
c369e62409
1 changed files with 72 additions and 0 deletions
72
claude-skills/mcp-builder.md
Normal file
72
claude-skills/mcp-builder.md
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
---
|
||||||
|
name: mcp-builder
|
||||||
|
description: Build MCP (Model Context Protocol) servers — stdio, HTTP/SSE, or remote. Covers tool design, auth, deployment, and testing.
|
||||||
|
---
|
||||||
|
|
||||||
|
# MCP Builder Skill
|
||||||
|
|
||||||
|
Use when building a new MCP server or adding tools to an existing one.
|
||||||
|
|
||||||
|
## MCP Server Types
|
||||||
|
- **stdio** — subprocess, local only, simplest
|
||||||
|
- **HTTP/SSE** — network accessible, supports auth, deployable
|
||||||
|
- **Remote (Cloudflare Workers, etc.)** — edge-deployed, global
|
||||||
|
|
||||||
|
## Tool Design Principles
|
||||||
|
1. **One tool = one atomic action.** Don't bundle list+get into one tool.
|
||||||
|
2. **Names are verbs**: `get_user`, `list_orders`, `create_invoice`.
|
||||||
|
3. **Required params only** — use optional sparingly with sensible defaults.
|
||||||
|
4. **Return structured JSON** — always. Never plain strings.
|
||||||
|
5. **Descriptive tool descriptions** — the model reads these to decide which tool to call.
|
||||||
|
6. **Error objects not exceptions** — return `{error: "message"}` in the result, don't throw.
|
||||||
|
|
||||||
|
## Minimal stdio Server (Node.js)
|
||||||
|
```js
|
||||||
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
||||||
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
||||||
|
|
||||||
|
const server = new Server({ name: "my-server", version: "1.0.0" }, {
|
||||||
|
capabilities: { tools: {} }
|
||||||
|
});
|
||||||
|
|
||||||
|
server.setRequestHandler("tools/list", async () => ({
|
||||||
|
tools: [{ name: "say_hello", description: "Say hello", inputSchema: {
|
||||||
|
type: "object", properties: { name: { type: "string" } }, required: ["name"]
|
||||||
|
}}]
|
||||||
|
}));
|
||||||
|
|
||||||
|
server.setRequestHandler("tools/call", async (req) => {
|
||||||
|
if (req.params.name === "say_hello") {
|
||||||
|
return { content: [{ type: "text", text: `Hello, ${req.params.arguments.name}!` }] };
|
||||||
|
}
|
||||||
|
throw new Error(`Unknown tool: ${req.params.name}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
await server.connect(new StdioServerTransport());
|
||||||
|
```
|
||||||
|
|
||||||
|
## Auth (HTTP servers)
|
||||||
|
- Static API key: `Authorization: Bearer <key>` header check
|
||||||
|
- OAuth 2.1 with PKCE for user-facing servers
|
||||||
|
- Never put secrets in tool responses
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# Test with MCP inspector
|
||||||
|
npx @modelcontextprotocol/inspector node ./server.js
|
||||||
|
|
||||||
|
# Test tool call directly
|
||||||
|
echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"say_hello","arguments":{"name":"world"}}}' | node server.js
|
||||||
|
```
|
||||||
|
|
||||||
|
## .mcp.json Registration
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"my-server": {
|
||||||
|
"command": "node",
|
||||||
|
"args": ["/path/to/server.js"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
Loading…
Reference in a new issue