ข้ามไปยังเนื้อหา
แก่น Kaen
ค้นหา
Ctrl
K
ยกเลิก
เลือกธีม
มืด
สว่าง
อัตโนมัติ
ออกแบบ MCP Server ที่ดี
มอง Tool ทุกตัวเหมือน Anti-Corruption Layer — 8 บทเรียน ตั้งแต่ MCP คืออะไร จนถึงเมื่อไรควร (และไม่ควร) ทำ MCP server
เริ่มบทที่ 1
ความคืบหน้า
0 / 8 บทเรียน
เส้นทางการเรียน
หัวข้อที่มีชื่อว่า “เส้นทางการเรียน”
●
01
MCP คืออะไร แก้ปัญหาอะไร
เริ่มตรงนี้
Model Context Protocol (MCP)
มาตรฐานเปิดที่นิยามวิธีให้ app AI เชื่อมต่อกับเครื่องมือและระบบภายนอกอย่างเป็นระบบเดียวกัน แทนการเขียนสายเชื่อมเฉพาะกิจทีละคู่ — Anthropic เป็นผู้เปิดตัว (พ.ย. 2024) แล้วบริจาคให้ Agentic AI Foundation (AAIF) ภายใต้ Linux Foundation ดูแลต่อ (9 ธ.ค. 2025) ปัจจุบันจึงเป็นมาตรฐานที่เป็นกลางทางค่าย ไม่ใช่ 'โพรโทคอลของ Anthropic' อีกต่อไป — spec ฉบับปัจจุบันคือ 2025-11-25
Host
application ที่ผู้ใช้เห็นและคุยด้วยโดยตรง เช่น Claude Desktop, Claude Code หรือ IDE ที่ผูก LLM ไว้ข้างใน — เป็นผู้คุม MCP Client หนึ่งตัวหรือหลายตัว จัดการสิทธิ์ ขอความยินยอมจากผู้ใช้ และรวมผลลัพธ์จากหลาย Server เข้ากับบทสนทนาเดียว
Client
ส่วนประกอบภายใน Host ที่ผูกการเชื่อมต่อแบบหนึ่งต่อหนึ่งกับ MCP Server หนึ่งตัว คุยกันด้วย JSON-RPC เจรจาความสามารถ (capability negotiation) ตอนเริ่ม session แล้วส่งต่อ Tool/Resource/Prompt ที่ Server มีให้ Host ใช้
Server
โปรแกรมที่ห่อหุ้มระบบภายนอกจริง (ฐานข้อมูล, API, file ระบบ, SaaS) แล้วเปิดให้ Client เรียกใช้ผ่าน Primitive สามแบบคือ Tool, Resource, Prompt — Server ไม่รู้จักและไม่ต้องรู้จัก Host หรือ Server ตัวอื่นเลย งานออกแบบที่ดีคือเลือกว่าจะเปิดอะไร ปิดอะไร และแปล model ภายในให้ปลอดภัยก่อนส่งออก
JSON-RPC
spec ข้อความระดับสายส่งที่ MCP ใช้เป็นฐาน — นิยามรูปแบบ request, response, notification เป็น JSON มาตรฐานเดียว ทำให้ Client กับ Server ฝั่งไหนก็คุยกันได้โดยไม่ต้องรู้ว่าอีกฝั่งเขียนด้วยภาษาอะไร
○
02
3 primitive: tools / resources / prompts
Primitive
หน่วยพื้นฐานสามแบบที่ MCP Server เปิดให้ใช้ คือ Tool (model เลือกเรียกเอง), Resource (app เป็นผู้แนบเข้า context), และ Prompt (ผู้ใช้เป็นผู้เรียกเอง) — สามแบบนี้ต่างกันตรง 'ใครเป็นผู้ตัดสินใจว่าจะเรียกเมื่อไร' ไม่ใช่แค่รูปแบบข้อมูลที่ส่งมา
Tool
function ที่ Server ประกาศให้ model เรียกเองได้ระหว่างให้เหตุผล เช่น ค้นหาออเดอร์ หรือยิง refund มักมีผลข้างเคียงจริง (side effect) — เป็น Primitive แบบ Model-controlled ต้องระวัง parameter ผิด สิทธิ์เกินจำเป็น และคำอธิบาย tool ที่ถูกฝังคำสั่งแฝง
Resource
ข้อมูลที่ Server เปิดให้ Host แนบเข้า context ได้ เช่น file log แถวในฐานข้อมูล หรือเอกสารนโยบาย — เป็น Primitive แบบ App-driven: app หรือผู้ใช้เป็นผู้เลือกว่าจะแนบอันไหนเมื่อไร ไม่ใช่ model เรียกเอง คล้าย endpoint อ่านอย่างเดียวที่ไม่มีผลข้างเคียง
Prompt (MCP primitive)
template คำสั่ง/ขั้นตอนสำเร็จรูปที่ Server เตรียมไว้ให้ผู้ใช้เรียกเองตรง ๆ เช่นผ่านเมนูหรือ slash command — เป็น Primitive ที่ผู้ใช้เป็นผู้ควบคุม ต่างจาก Tool ที่ model เรียกเอง และต่างจาก Resource ที่ app เป็นผู้แนบให้ ใช้มาตรฐานขั้นตอนงานที่ทำซ้ำบ่อย
○
03
ออกแบบ tool ที่ดี (tool = ACL)
Tool
function ที่ Server ประกาศให้ model เรียกเองได้ระหว่างให้เหตุผล เช่น ค้นหาออเดอร์ หรือยิง refund มักมีผลข้างเคียงจริง (side effect) — เป็น Primitive แบบ Model-controlled ต้องระวัง parameter ผิด สิทธิ์เกินจำเป็น และคำอธิบาย tool ที่ถูกฝังคำสั่งแฝง
Anti-Corruption Layer (ACL)
แนวคิดจาก DDD ที่ยืมมาใช้มองงานออกแบบ MCP Server: มอง Tool แต่ละตัวเป็นชั้นแปลระหว่าง model กับระบบภายนอกจริง ไม่ปล่อยให้ model ของระบบเดิม (schema, error code, id ที่ไม่มีความหมาย) รั่วตรงเข้าสู่บริบทของ agent — Tool ที่ดีคือ ACL ที่รักษา model ของ agent ไม่ให้ปนเปื้อน
○
04
Resources vs tools — เลือกให้ถูก
Resource
ข้อมูลที่ Server เปิดให้ Host แนบเข้า context ได้ เช่น file log แถวในฐานข้อมูล หรือเอกสารนโยบาย — เป็น Primitive แบบ App-driven: app หรือผู้ใช้เป็นผู้เลือกว่าจะแนบอันไหนเมื่อไร ไม่ใช่ model เรียกเอง คล้าย endpoint อ่านอย่างเดียวที่ไม่มีผลข้างเคียง
Resource Template
URI ที่มี parameter (เช่น orders://{orderId}) ให้ Server ประกาศชุด Resource ที่มีรูปแบบเดียวกันได้โดยไม่ต้องแจงทีละรายการ — Host เติมค่า parameter ก่อนขอ Resource จริงตามรูปแบบนั้น รองรับการ subscribe ฟังการอัปเดตได้ด้วย
Model-controlled
ลักษณะของ Primitive ที่ตัว model เป็นผู้ตัดสินใจเองว่าจะเรียกเมื่อไรและเรียกอย่างไร เช่น Tool — ต่างจาก App-driven ที่ app เป็นผู้ตัดสินใจแทน ความแตกต่างนี้กำหนดว่าควรตรวจสอบสิทธิ์และผลลัพธ์เข้มงวดแค่ไหน ไม่ใช่แค่ดูว่าข้อมูลนั้น 'อ่านอย่างเดียว' หรือ 'แก้ไขได้'
App-driven
ลักษณะของ Primitive ที่ Host/Client เป็นผู้ตัดสินใจว่าจะดึงเข้ามาเมื่อไรและอันไหน ไม่ใช่ model เรียกเอง เช่น Resource — ความเสี่ยงจึงต่างจาก Tool เพราะ model ไม่ได้เลือกเอง แต่เนื้อหาที่ดึงมายังปนเปื้อน prompt injection ได้เหมือนกัน
○
05
Ubiquitous Language ของ MCP server
Tool
function ที่ Server ประกาศให้ model เรียกเองได้ระหว่างให้เหตุผล เช่น ค้นหาออเดอร์ หรือยิง refund มักมีผลข้างเคียงจริง (side effect) — เป็น Primitive แบบ Model-controlled ต้องระวัง parameter ผิด สิทธิ์เกินจำเป็น และคำอธิบาย tool ที่ถูกฝังคำสั่งแฝง
Anti-Corruption Layer (ACL)
แนวคิดจาก DDD ที่ยืมมาใช้มองงานออกแบบ MCP Server: มอง Tool แต่ละตัวเป็นชั้นแปลระหว่าง model กับระบบภายนอกจริง ไม่ปล่อยให้ model ของระบบเดิม (schema, error code, id ที่ไม่มีความหมาย) รั่วตรงเข้าสู่บริบทของ agent — Tool ที่ดีคือ ACL ที่รักษา model ของ agent ไม่ให้ปนเปื้อน
○
06
Security & trust (บทเสี่ยงสุด)
Trust Boundary
เส้นแบ่งระหว่างสิ่งที่ควบคุมได้กับสิ่งที่ควบคุมไม่ได้ ทุกครั้งที่ agent เรียก Tool หรือดึง Resource จาก Server ภายนอก ถือว่าข้าม trust boundary — annotation อย่าง readOnlyHint ไม่ใช่ trust boundary เอง (Server ที่ไม่น่าเชื่อถือโกหกได้) ต้องรักษาเส้นนี้ด้วยการตรวจสอบและจำกัดสิทธิ์จริง ไม่ใช่เชื่อคำประกาศของ Server เฉย ๆ
Prompt Injection
การลอบฝังคำสั่งของผู้โจมตีไว้ในเนื้อหาที่ model จะอ่าน เช่น ในผลลัพธ์ของ Tool หรือเนื้อหาของ Resource เพื่อหลอกให้ model ทำตามคำสั่งแฝงนั้นแทนที่จะทำตามผู้ใช้จริง — อันตรายเพราะ model แยกไม่ออกเองว่าข้อความไหนคือคำสั่ง ข้อความไหนคือข้อมูล
Confused Deputy
ปัญหาความปลอดภัยคลาสสิกที่โปรแกรมซึ่งมีสิทธิ์ถูกต้องตามกฎหมาย (เช่น agent ที่ต่อ MCP Server ด้วยสิทธิ์ของผู้ใช้) ถูกอีกฝ่ายหลอกให้ใช้สิทธิ์นั้นทำสิ่งที่เจ้าของสิทธิ์ไม่ได้ตั้งใจ — agent กลายเป็น 'ตัวแทนที่ถูกหลอก' ใช้อำนาจของตัวเองไปทำร้ายเจ้าของอำนาจเอง จึงห้ามส่งต่อ token ของผู้ใช้ตรง ๆ ให้ระบบปลายทางโดยไม่ตรวจสอบ
Tool Poisoning
การโจมตีที่ Server ซึ่งเป็นอันตราย (หรือถูกยึด) ฝังคำสั่งแฝงไว้ใน description/metadata ของ Tool เอง ซึ่งผู้ใช้มักไม่เห็นแต่ model อ่านเข้าไปเต็ม ๆ ตอนตัดสินใจว่าจะเรียก Tool ไหน — ต่างจาก Prompt Injection ทั่วไปตรงที่คำสั่งแฝงมาจากตัว Server ที่เชื่อมต่ออยู่แล้ว ไม่ใช่จากเนื้อหาที่ดึงเข้ามาชั่วคราว แก้ได้ด้วยหลัก least-privilege ไม่ใช่แค่เชื่อ Server ที่รู้จัก
Lethal Trifecta
เงื่อนไขสามอย่างที่พบพร้อมกันแล้วอันตรายถึงขั้นข้อมูลรั่วไหล: (1) เข้าถึงข้อมูลลับ/ส่วนตัวได้ (2) รับเนื้อหาที่ควบคุมไม่ได้เข้ามา (เสี่ยง prompt injection) และ (3) มีช่องทางส่งข้อมูลออกสู่ภายนอกได้ — มีครบสามข้อเมื่อไร agent ที่ต่อ MCP Server หลายตัวก็เสี่ยงถูกหลอกให้ขโมยข้อมูลออกไปเอง ทางแก้คือถอดขาใดขาหนึ่งออกเสมอ แนวคิดโดย Simon Willison
○
07
Composition & ecosystem (sampling, elicitation)
Sampling
กลไกที่ Server ขอให้ Client ยิง completion จาก LLM แทนตัวเอง (Server เองไม่ต้องผูก LLM key ของตัวเอง) เช่น ให้ model ช่วยสรุปผลลัพธ์กลางทางก่อนทำขั้นต่อไป — เป็นความสามารถฝั่ง Client สลับทิศทางจากปกติที่การเรียกไปทาง Host/Client → Server เท่านั้น ต้องผ่านมนุษย์รีวิว prompt และผลลัพธ์
Elicitation
กลไกที่ Server ขอข้อมูลเพิ่มจากผู้ใช้กลางทางผ่าน Client เช่น ถามยืนยันก่อนลบข้อมูล หรือขอ parameter ที่ยังไม่ครบ — เป็นความสามารถฝั่ง Client เหมือน Sampling ทำให้ Server ไม่ต้องเดาหรือปฏิเสธ request เปล่า ๆ เมื่อข้อมูลไม่พอ
○
08
เมื่อไรควร (และไม่ควร) ทำ MCP server
Model Context Protocol (MCP)
มาตรฐานเปิดที่นิยามวิธีให้ app AI เชื่อมต่อกับเครื่องมือและระบบภายนอกอย่างเป็นระบบเดียวกัน แทนการเขียนสายเชื่อมเฉพาะกิจทีละคู่ — Anthropic เป็นผู้เปิดตัว (พ.ย. 2024) แล้วบริจาคให้ Agentic AI Foundation (AAIF) ภายใต้ Linux Foundation ดูแลต่อ (9 ธ.ค. 2025) ปัจจุบันจึงเป็นมาตรฐานที่เป็นกลางทางค่าย ไม่ใช่ 'โพรโทคอลของ Anthropic' อีกต่อไป — spec ฉบับปัจจุบันคือ 2025-11-25
Lethal Trifecta
เงื่อนไขสามอย่างที่พบพร้อมกันแล้วอันตรายถึงขั้นข้อมูลรั่วไหล: (1) เข้าถึงข้อมูลลับ/ส่วนตัวได้ (2) รับเนื้อหาที่ควบคุมไม่ได้เข้ามา (เสี่ยง prompt injection) และ (3) มีช่องทางส่งข้อมูลออกสู่ภายนอกได้ — มีครบสามข้อเมื่อไร agent ที่ต่อ MCP Server หลายตัวก็เสี่ยงถูกหลอกให้ขโมยข้อมูลออกไปเอง ทางแก้คือถอดขาใดขาหนึ่งออกเสมอ แนวคิดโดย Simon Willison