บทความนี้จะพาคุณเรียนรู้การสร้าง MCP (Model Context Protocol) Server ด้วย TypeScript ตั้งแต่ขั้นตอนแรกจนถึงการนำไปใช้งานจริง โดยเนื้อหาทั้งหมดมาจากประสบการณ์ตรงในการพัฒนา production-grade MCP Server ที่รองรับ AI providers หลายตัว พร้อมแนะนำการประหยัดค่าใช้จ่ายด้วย สมัครที่นี่

ทำไมต้องพัฒนา MCP Server ของตัวเอง?

MCP Server คือ middleware ที่ทำหน้าที่เป็นตัวกลางระหว่าง AI models กับ data sources ต่างๆ ข้อดีหลักคือ:

เปรียบเทียบต้นทุน AI API 2026

ก่อนเริ่มพัฒนา มาดูต้นทุนต่อเดือนสำหรับ 10M tokens/เดือน:

Model ราคา (output/MTok) ต้นทุน 10M tokens/เดือน
Claude Sonnet 4.5 $15.00 $150.00
GPT-4.1 $8.00 $80.00
Gemini 2.5 Flash $2.50 $25.00
DeepSeek V3.2 $0.42 $4.20

หมายเหตุ: DeepSeek V3.2 ประหยัดกว่า Claude Sonnet 4.5 ถึง 97%! หากใช้ HolySheep AI ที่มีอัตรา ¥1=$1 พร้อมรองรับ WeChat/Alipay และ latency <50ms คุณจะได้รับเครดิตฟรีเมื่อลงทะเบียน ช่วยลดต้นทุนได้มากกว่า 85%

การติดตั้ง Project และ Dependencies

mkdir mcp-server-tutorial
cd mcp-server-tutorial
npm init -y
npm install typescript ts-node @types/node zod
npm install -D @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint

Initialize TypeScript config

npx tsc --init

Install MCP SDK (latest version)

npm install @modelcontextprotocol/sdk

ไฟล์ tsconfig.json สำหรับ MCP Server:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "lib": ["ES2022"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

โครงสร้าง MCP Server พื้นฐาน

สร้างไฟล์ src/index.ts หลัก:

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";

// Define tool schemas
const searchSchema = z.object({
  query: z.string().describe("Search query string"),
  limit: z.number().optional().default(10),
});

const analyzeSchema = z.object({
  text: z.string().describe("Text to analyze"),
  model: z.enum(["gpt-4.1", "claude-sonnet-4.5", "deepseek-v3.2"]).default("deepseek-v3.2"),
});

// Create server instance
const server = new Server(
  {
    name: "mcp-tutorial-server",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: "search",
        description: "Search for information using AI",
        inputSchema: {
          type: "object",
          properties: {
            query: { type: "string", description: "Search query string" },
            limit: { type: "number", description: "Max results", default: 10 },
          },
          required: ["query"],
        },
      },
      {
        name: "analyze",
        description: "Analyze text using specified AI model",
        inputSchema: {
          type: "object",
          properties: {
            text: { type: "string", description: "Text to analyze" },
            model: { 
              type: "string", 
              enum: ["gpt-4.1", "claude-sonnet-4.5", "deepseek-v3.2"],
              default: "deepseek-v3.2" 
            },
          },
          required: ["text"],
        },
      },
    ],
  };
});

// Handle tool calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;
  
  try {
    if (name === "search") {
      const { query, limit } = searchSchema.parse(args);
      // Implementation here
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify({ query, limit, results: [] }),
          },
        ],
      };
    }
    
    if (name === "analyze") {
      const { text, model } = analyzeSchema.parse(args);
      // Call HolySheep AI API
      const response = await callHolySheepAPI(text, model);
      return {
        content: [{ type: "text", text: response }],
      };
    }
    
    throw new Error(Unknown tool: ${name});
  } catch (error) {
    return {
      content: [{ type: "text", text: Error: ${error} }],
      isError: true,
    };
  }
});

// Helper function to call HolySheep AI
async function callHolySheepAPI(text: string, model: string): Promise {
  const response = await fetch("https://api.holysheep.ai/v1/chat/completions", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Authorization": Bearer ${process.env.HOLYSHEEP_API_KEY},
    },
    body: JSON.stringify({
      model: model,
      messages: [{ role: "user", content: text }],
      max_tokens: 1000,
    }),
  });
  
  const data = await response.json();
  return data.choices[0].message.content;
}

// Start server
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("MCP Server running on stdio");
}

main().catch(console.error);

การเพิ่ม Resource Management

เพิ่มความสามารถในการจัดการ resources:

import {
  ListResourcesRequestSchema,
  ReadResourceRequestSchema,
  ListPromptsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";

// Register resource handler
server.setRequestHandler(ListResourcesRequestSchema, async () => {
  return {
    resources: [
      {
        uri: "config://ai-models",
        name: "AI Models Configuration",
        mimeType: "application/json",
        description: "Available AI models and pricing",
      },
      {
        uri: "stats://usage",
        name: "Usage Statistics",
        mimeType: "application/json",
        description: "Current API usage data",
      },
    ],
  };
});

// Register resource reader
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
  const { uri } = request.params;
  
  if (uri === "config://ai-models") {
    return {
      contents: [
        {
          uri,
          mimeType: "application/json",
          text: JSON.stringify({
            models: [
              { name: "gpt-4.1", provider: "OpenAI", pricePerMToken: 8 },
              { name: "claude-sonnet-4.5", provider: "Anthropic", pricePerMToken: 15 },
              { name: "deepseek-v3.2", provider: "DeepSeek", pricePerMToken: 0.42 },
              { name: "gemini-2.5-flash", provider: "Google", pricePerMToken: 2.50 },
            ],
          }),
        },
      ],
    };
  }
  
  throw new Error(Unknown resource: ${uri});
});

การ Debug MCP Server

สร้างไฟล์ test-server.ts สำหรับทดสอบ:

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";

async function testServer() {
  const transport = new StdioClientTransport({
    command: "npx",
    args: ["ts-node", "src/index.ts"],
    env: {
      HOLYSHEEP_API_KEY: process.env.HOLYSHEEP_API_KEY || "YOUR_HOLYSHEEP_API_KEY",
    },
  });

  const client = new Client(
    { name: "mcp-test-client", version: "1.0.0" },
    { capabilities: { tools: true, resources: true } }
  );

  try {
    await client.connect(transport);
    console.log("✅ Connected to MCP Server");

    // Test list tools
    const tools = await client.request({ method: "tools/list" }, ListToolsRequestSchema);
    console.log("✅ Available tools:", tools.tools.map(t => t.name));

    // Test call tool
    const result = await client.request(
      {
        method: "tools/call",
        params: {
          name: "analyze",
          arguments: { text: "Hello world", model: "deepseek-v3.2" },
        },
      },
      CallToolRequestSchema
    );
    console.log("✅ Tool result:", result);

  } catch (error) {
    console.error("❌ Error:", error);
  } finally {
    await client.close();
  }
}

testServer();

ข้อผิดพลาดที่พบบ่อยและวิธีแก้ไข

1. Error: Module not found: @modelcontextprotocol/sdk

# ปัญหา: ไม่พบ package หรือ version ไม่ตรงกัน

วิธีแก้: ตรวจสอบ package.json และติดตั้งใหม่

ลบ node_modules และ package-lock.json

rm -rf node_modules package-lock.json

ติดตั้ง dependencies ใหม่

npm install @modelcontextprotocol/sdk@latest typescript@latest

หรือใช้ npm ci สำหรับ production

npm ci

2. Error: Invalid base_url or API key

# ปัญหา: ใช้ base_url ผิดหรือ API key ไม่ถูกต้อง

วิธีแก้: ตรวจสอบ environment variables

สร้างไฟล์ .env

echo 'HOLYSHEEP_API_KEY=YOUR_HOLYSHEEP_API_KEY' > .env

ใช้ dotenv ในโค้ด

npm install dotenv

เพิ่มที่ด้านบนของ index.ts

import 'dotenv/config'; // ตรวจสอบว่า base_url ถูกต้อง

ต้องเป็น: https://api.holysheep.ai/v1

ห้ามใช้: api.openai.com หรือ api.anthropic.com

3. Error: Streaming response timeout

# ปัญหา: Response ใช้เวลานานเกิน timeout

วิธีแก้: เพิ่ม timeout และ retry logic

async function callWithRetry( url: string, options: RequestInit, maxRetries = 3 ): Promise<any> { for (let i = 0; i < maxRetries; i++) { try { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 30000); const response = await fetch(url, { ...options, signal: controller.signal, }); clearTimeout(timeoutId); return response; } catch (error: any) { if (i === maxRetries - 1) throw error; console.log(Retry ${i + 1}/${maxRetries}...); await new Promise(r => setTimeout(r, 1000 * Math.pow(2, i))); } } }

4. Error: Zod validation failed

# ปัญหา: Input schema ไม่ตรงกับ request

วิธีแก้: เพิ่ม error handling และ validation

server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { // ใช้ safeParse แทน parse เพื่อ catch error if (name === "search") { const result = searchSchema.safeParse(args); if (!result.success) { return { content: [{ type: "text", text: Validation error: ${result.error.message} }], isError: true, }; } const { query, limit } = result.data; // Process... } } catch (error) { return { content: [{ type: "text", text: Server error: ${error} }], isError: true, }; } });

สรุป

การพัฒนา MCP Server ด้วย TypeScript ต้องใส่ใจในเรื่อง type safety, error handling, และการจัดการ resources อย่างเหมาะสม จากการเปรียบเทียบต้นทุน 10M tokens/เดือน พบว่า DeepSeek V3.2 ที่ $0.42/MTok ประหยัดที่สุดเมื่อเทียบกับ Claude Sonnet 4.5 ที่ $15/MTok

HolySheep AI เป็นตัวเลือกที่ดีสำหรับ production เพราะมีอัตรา ¥1=$1 รองรับ WeChat/Alipay latency <50ms และให้เครดิตฟรีเมื่อลงทะเบียน ช่วยประหยัดได้มากกว่า