เมื่อเดือนที่ผ่านมา ทีมอีคอมเมิร์ซที่ผมดูแลเจอเหตุการณ์ครั้งใหญ่ แคมเปญ 11.11 ดึงทราฟฟิกเข้าร้านค้ามากกว่าปกติ 12 เท่า แชทบอทเดิมที่เขียนด้วย if-else พังครืน เพราะลูกค้าถามนอกเหนือสคริปต์ เช่น "พัสดุหมายเลข TH1234567890 อยู่ไหน", "ขอใบเสนอราคา 50 ชิ้น", "คืนเงินคำสั่งซื้อ #A9921" ทั้งหมดต้องดึงข้อมูลจาก ERP, WMS และ CRM ภายใน ซึ่ง Claude Code ทั่วไปไม่สามารถเรียก API เหล่านี้ได้โดยตรง ผมจึงตัดสินใจเขียน MCP Server ขึ้นมาเอง เพื่อแปลง API ภายในให้เป็น "เครื่องมือ" ที่ Claude Code เรียกใช้ผ่านโปรโตคอล Model Context Protocol ภายใน 2 วัน แชทบอทรับโหลดได้เกือบ 8 เท่าของระบบเดิมโดยไม่ต้องเทรนโมเดลใหม่แม้แต่ตัวเดียว

MCP Server คืออะไร และทำไมต้องสร้างเอง

Model Context Protocol (MCP) เป็นมาตรฐานเปิดที่ Anthropic เปิดตัวเมื่อปี 2025 ให้ LLM เรียกใช้เครื่องมือภายนอกได้อย่างเป็นระบบ ถ้าเปรียบง่าย ๆ MCP Server ก็เหมือนปลั๊กไฟระหว่าง Claude Code กับโลกภายนอก ฝั่งหนึ่งพูดคุยกับโมเดล อีกฝั่งคุยกับ API ของคุณ ข้อดีคือ

ในบทความนี้ผมจะพาเขียน MCP Server ด้วย Python SDK ตัวอย่างจริง 2 เคส คือ (1) ตรวจสถานะพัสดุ และ (2) ค้นหาคำสั่งซื้อ แล้วต่อเข้ากับ Claude Code ผ่าน HolySheep AI ซึ่งเป็นเกตเวย์ LLM ที่ให้อัตรา 1 เหรียญต่อ 1 ดอลลาร์ ประหยัดกว่าการเรียกตรงมากกว่า 85% รองรับทั้ง WeChat และ Alipay และมี latency ต่ำกว่า 50 มิลลิวินาที

เตรียมสภาพแวดล้อมและติดตั้ง SDK

ก่อนเริ่ม ติดตั้งแพ็กเกจที่จำเป็น ผมแนะนำใช้ uv เพราะจัดการ virtual env ได้เร็วกว่า pip ปกติหลายเท่า

uv init mcp-erp-server
cd mcp-erp-server
uv add "mcp[cli]" httpx pydantic
echo "สร้างโปรเจ็กต์สำเร็จ ตรวจสอบไฟล์ pyproject.toml"

เขียน MCP Server แบบ Async เชื่อม API องค์กร

ผมสมมติ API ภายในองค์กรชื่อ https://erp.internal.local ใช้ token แบบ Bearer เซิร์ฟเวอร์นี้จะเปิด 2 เครื่องมือให้ Claude Code เรียกใช้

import asyncio
import os
import httpx
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("holySheep-erp-bridge")
ERP_BASE = os.environ.get("ERP_BASE", "https://erp.internal.local")
ERP_TOKEN = os.environ.get("ERP_TOKEN", "internal-bearer-token")

async def _get(path: str, params: dict | None = None) -> dict:
    headers = {"Authorization": f"Bearer {ERP_TOKEN}"}
    async with httpx.AsyncClient(timeout=10) as client:
        r = await client.get(f"{ERP_BASE}{path}", headers=headers, params=params)
        r.raise_for_status()
        return r.json()

@mcp.tool()
async def track_parcel(tracking_no: str) -> dict:
    """ตรวจสถานะพัสดุจากหมายเลขติดตาม เช่น TH1234567890TH"""
    data = await _get("/api/v1/shipments/track", {"no": tracking_no})
    return {
        "หมายเลข": data.get("tracking_no"),
        "สถานะ": data.get("status"),
        "ศูนย์กระจาย": data.get("hub"),
        "อัปเดตล่าสุด": data.get("updated_at"),
    }

@mcp.tool()
async def get_order(order_id: str) -> dict:
    """ดึงรายละเอียดคำสั่งซื้อจากรหัสคำสั่งซื้อ เช่น A9921"""
    data = await _get(f"/api/v1/orders/{order_id}")
    return {
        "รหัส": data.get("id"),
        "ยอดรวม": data.get("grand_total"),
        "สถานะการชำระเงิน": data.get("payment_status"),
        "รายการสินค้า": data.get("items", []),
    }

if __name__ == "__main__":
    mcp.run(transport="stdio")

โค้ดข้างต้นใช้ decorator @mcp.tool() เพื่อบอก MCP runtime ว่าฟังก์ชันนี้คือเครื่องมือที่โมเดลเรียกได้ docstring ภายในฟังก์ชันสำคัญมาก เพราะ Claude จะอ่านข้อความนี้เพื่อตัดสินใจว่าจะเรียกเครื่องมือไหนเมื่อไหร่ ผมแนะนำให้เขียนคำอธิบายภาษาไทยให้ชัดเจนและยกตัวอย่างอินพุตเสมอ

เชื่อม Claude Code เข้ากับ HolySheep AI และ MCP Server

เมื่อเซิร์ฟเวอร์พร้อมแล้ว ให้รันในโหมด dev เพื่อตรวจสอบว่า Claude Code ค้นพบเครื่องมือครบทั้ง 2 ตัว

mcp dev server.py

ถ้าเห็นข้อความประมาณ "Found 2 tools: track_parcel, get_order" แสดงว่าฝั่ง MCP พร้อมแล้ว ต่อไปตั้งค่า Claude Code ให้ใช้โมเดลผ่านเกตเวย์ของ HolySheep เปิดไฟล์ ~/.claude/settings.json แล้วใส่ค่าดังนี้

{
  "env": {
    "ANTHROPIC_BASE_URL": "https://api.holysheep.ai/v1",
    "ANTHROPIC_AUTH_TOKEN": "YOUR_HOLYSHEEP_API_KEY",
    "ANTHROPIC_MODEL": "claude-sonnet-4-5"
  },
  "mcpServers": {
    "erp-bridge": {
      "command": "uv",
      "args": ["run", "server.py"],
      "cwd": "/Users/you/mcp-erp-server"
    }
  }
}

เมื่อเปิด Claude Code ใหม่ ลองพิมพ์ "เช็คพัสดุ TH1234567890TH ให้หน่อย" Claude จะเรียกเครื่องมือ track_parcel แล้วนำผลลัพธ์มาตอบเป็นภาษาไทยแบบเป็นธรรมชาติ ทั้งหมดนี้ใช้โมเดล Claude Sonnet 4.5 ที่ราคาตลาดปี 2026 อยู่ที่ 15 ดอลลาร์ต่อล้านโทเคน แต่ผ่าน HolySheep อัตรา 1 ต่อ 1 ทำให้ต้นทุนต่อคำถามลูกค้าลดลงเหลือต่ำกว่า 0.0002 ดอลลาร์ เทียบกับ Gemini 2.5 Flash ที่ 2.50 ดอลลาร์ หรือ GPT-4.1 ที่ 8 ดอลลาร์ต่อล้านโทเคน ประหยัดชัดเจนเมื่อเทียบสเปกเดียวกัน

เทคนิคที่ผมใช้แล้วเวิร์คในงานจริง

ถ้าต้องการโมเดลราคาถูกลงไปอีกสำหรับงานทั่วไป DeepSeek V3.2 ที่ 0.42 ดอลลาร์ต่อล้านโทเคนก็เป็นตัวเลือกที่ดี เมื่อใช้ผ่านเกตเวย์เดียวกัน การสลับโมเดลทำได้แค่เปลี่ยนค่า ANTHROPIC_MODEL ใน settings.json ไม่ต้องแก้โค้ดแม้แต่บรรทัดเดียว

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

ข้อผิดพลาดที่ 1: Claude Code ไม่เห็นเครื่องมือแม้เซิร์ฟเวอร์รันได้

อาการคือเปิด Claude Code แล้ว prompt บอกว่าไม่พบเครื่องมือ สาเหตุส่วนใหญ่เกิดจาก cwd ใน settings.json ชี้ผิดโฟลเดอร์ หรือยังไม่ได้ติดตั้ง dependencies ใน virtual env วิธีแก้คือรัน mcp dev server.py ในโฟลเดอร์เดียวกับไฟล์เซิร์ฟเวอร์ แล้วตรวจดูว่า Found N tools ขึ้นครบ จากนั้นค่อย restart Claude Code

mcp dev server.py
ls .venv/lib/python3.12/site-packages/mcp

ข้อผิดพลาดที่ 2: 401 Unauthorized เมื่อเรียก API ภายใน

เกิดเพราะ token หมดอายุ หรือ Claude Code รันในโหมด sandbox ที่ตัด env ทิ้ง ตรวจด้วยคำสั่ง env | grep ERP_TOKEN ถ้าไม่เจน ให้ export ในไฟล์ ~/.zshrc หรือระบุใน mcpServers.env ของ settings.json โดยตรง

{
  "mcpServers": {
    "erp-bridge": {
      "command": "uv",
      "args": ["run", "server.py"],
      "env": { "ERP_TOKEN": "internal-bearer-token-2026" }
    }
  }
}

ข้อผิดพลาดที่ 3: Claude เรียกเครื่องมือซ้ำจนเกิด loop

อาการคือ log เต็มไปด้วยการเรียก track_parcel รัว ๆ สาเหตุคือ docstring ของเครื่องมือไม่ชัดพอ โมเดลเลยเดา input ผิด ได้ error แล้วลองใหม่ วิธีแก้คือเขียน docstring ให้ละเอียด ยกตัวอย่าง และใช้ Pydantic ระบุ type ชัดเจน รวมถึงเพิ่ม retry limit ใน agent layer

from pydantic import Field
from mcp.server.fastmcp import FastMCP

@mcp.tool()
async def track_parcel(
    tracking_no: str = Field(description="หมายเลขติดตามพัสดุ 13 หลัก ขึ้นต้นด้วย TH เช่น TH1234567890TH"),
) -> dict:
    """ตรวจสถานะพัสดุ คืนสถานะล่าสุด ศูนย์กระจาย และเวลาอัปเดต"""
    return await _get("/api/v1/shipments/track", {"no": tracking_no})

ข้อผิดพลาดที่ 4: latency สูงเมื่อใช้ SSE transport

ถ้า production ใช้ SSE แล้วเจอ delay เกิน 1 วินาที มักเกิดจาก reverse proxy เช่น nginx ไม่ได้ตั้ง proxy_buffering off ให้เพิ่มคอนฟิกดังนี้

location /mcp/sse {
    proxy_pass http://127.0.0.1:8765;
    proxy_http_version 1.1;
    proxy_set_header Connection '';
    proxy_buffering off;
    proxy_cache off;
    chunked_transfer_encoding on;
}

สรุปและขั้นตอนถัดไป

MCP Server เป็นทางลัดที่ทรงพลังที่สุดในการเชื่อม Claude เข้ากับระบบภายในองค์กร โดยไม่ต้องเทรนโมเดลใหม่ ไม่ต้องเปิด public endpoint และควบคุมสิทธิ์ได้ครบถ้วน สำหรับทีมที่อยากเริ่มต้น ผมแนะนำให้เลือก use case ง่าย ๆ ก่อน เช่น ตรวจสถานะพัสดุหรือค้นหาคำสั่งซื้อ แล้วค่อยขยายไปยัง CRM, helpdesk หรือ BI dashboard

ตอนนี้ HolySheep AI มีเครดิตฟรีให้ทดลองเมื่อสมัคร ลองสร้าง MCP Server ตัวแรกของคุณแล้วต่อเข้ากับ Claude Sonnet 4.5 ผ่านเกตเวย์ที่ latency ต่ำกว่า 50 มิลลิวินาที จะเห็นว่าวงจรการพัฒนา agent สั้นลงเหลือไม่กี่ชั่วโมง ไม่ใช่หลายสัปดาห์เหมือนเมื่อก่อนอีกต่อไป

👉 สมัคร HolySheep AI — รับเครดิตฟรีเมื่อลงทะเบียน