Files
2026-02-16 14:02:42 +09:00

4.8 KiB

name, description
name description
ck-mcp-builder 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

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:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./dist",
    "strict": true
  }
}

2. Create the Server

// 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

// 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

// 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

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

// 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:

{
  "mcpServers": {
    "my-server": {
      "command": "node",
      "args": ["/absolute/path/to/dist/server.js"],
      "env": {
        "API_KEY": "..."
      }
    }
  }
}

8. Test with MCP Inspector

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