สร้าง MCP server ให้พร้อม production: 7 เรื่องที่ tutorial ไม่บอก
โดย Nokka (นก-กา) | 17 กันยายน 2026
บทความนี้เขียนโดย AI (โมเดล deepseek-v4.1-flash ของผู้ให้บริการ ollama-cloud) ผ่าน Hermes Agent จาก Nous Research ตรวจสอบและเรียบเรียงโดย Nokka
มีข้อมูลชุดหนึ่งที่ผมอ่านแล้วหยุดคิดนาน
การตรวจสอบข้อมูลรับรองของ server มากกว่า 5,200 ตัว พบว่า 88% ต้องใช้ข้อมูลรับรอง แต่มีเพียง 8.5% ที่ใช้ OAuth ขณะที่ 53% ใช้ static API key และ 79% ส่ง key ผ่าน environment variable [1]
⇒ ตัวเลขนี้บอกอะไรที่ตรงไปตรงมา คือทีมส่วนใหญ่ทำการยืนยันตัวตนแล้ว แต่ทำด้วยวิธีที่ไม่มีวันหมดอายุ ไม่ผูกกับ server ใด และไม่มีอะไรกันมันได้ถ้ามันไปอยู่ใน log [1]
และมีข้อมูลอีกชุดที่หนักกว่า ⇒ 492 server ถูกเปิดสู่อินเทอร์เน็ตโดยไม่มีการยืนยันตัวตนและไม่เข้ารหัสการสื่อสารเลย ให้เข้าถึง tool ได้ 1,402 ตัว โดย กว่า 90% เปิดให้อ่านข้อมูลได้ตรง ๆ และเมื่อตรวจซ้ำ จำนวนนั้นเพิ่มเป็น 1,467 [1]
⇒ และมีตัวเลขที่อธิบายว่าทำไมเรื่องนี้ถึงถูกมองข้าม ⇒ 86% ของ MCP server รันอยู่บนเครื่องนักพัฒนา และมีเพียง 5% ที่รันใน production [1]
⇒ นั่นแปลว่าบทความและ tutorial ส่วนใหญ่ที่คุณอ่าน ถูกเขียนจากประสบการณ์ของ 5% นั้น ซึ่งอธิบายได้ว่าทำไมเรื่อง deployment ถึงถูกข้ามบ่อย [1]
บทความนี้เขียนสำหรับคนที่สร้าง MCP server แรกเสร็จแล้ว และกำลังจะเอาไปใช้จริง ไม่ใช่บทเรียน hello world
หนึ่ง: transport เป็นการตัดสินใจเชิงสถาปัตยกรรม ไม่ใช่รสนิยม
การเลือก stdio หรือ Streamable HTTP กำหนดวิธี deploy ทั้งหมดของคุณ [2]
สัญญาณเตือนที่ตรงที่สุดจากคู่มือ deploy [3] ⇒ คู่มือนี้แยกหัวข้อ "Cloud Platform Notes" ไว้ต่างหาก
"Google Cloud Run: transport แบบ
stdio*ล้มเหลวเงียบ ๆ ใช้ Streamable HTTP เท่านั้น จบ*""AWS ECS with Fargate: ปัญหาเดียวกัน *วาง ALB ข้างหน้า แล้วใช้ Streamable HTTP*"
"Fly.io: รองรับ HTTP connection แบบคงอยู่อย่างเป็นธรรมชาติ ทำงานกับ MCP ได้ดี"
และคู่มือนี้ให้ตัวเลขที่ผมคิดว่ามีค่ามาก ⇒ "ประมาณ **70% ของ MCP deployment ใน production ใช้ Streamable HTTP แล้ว* เหลือเพียง 30% ที่ยังใช้ stdio และ 30% นั้นเกือบทั้งหมดเป็นเครื่องมือสำหรับนักพัฒนาในเครื่อง"* ซึ่ง [3] ระบุว่าอ้างจาก The New Stack (ค.ศ. 2026)
ตารางเทียบที่ผมใช้ตัดสินใจ [1][3][4]
| มิติ | stdio | Streamable HTTP |
|---|---|---|
| เหมาะกับ | พัฒนาบนเครื่อง · แอปเดสก์ท็อป | server ระยะไกลใน production |
| ขยายแนวนอน | ทำไม่ได้ (โปรเซสเดียว) | ทำได้ตามปกติ |
| เข้ากับ load balancer | ไม่เข้ากับ persistent connection | เข้ากับ HTTP มาตรฐาน |
| พื้นผิวความปลอดภัย | ต่ำ (โปรเซสในเครื่อง) | ต้องยืนยันตัวตนต่อคำขอ |
| วิธีเก็บข้อมูลรับรอง | environment variable | OAuth 2.1 resource server |
| การค้นพบบริการ | ไม่เกี่ยวข้อง | รองรับ .well-known
|
สองข้อที่คนมักเข้าใจผิด [1][4]
หนึ่ง ⇒ stdio ไม่ได้ปลอดภัยโดยอัตโนมัติ เพราะการยืนยันตัวตนของมันคือ environment variable ⇒ และตัวเลข 79% ที่ส่ง key ทาง env var ก็คือผลของวิธีคิดนี้ [1]
สอง ⇒ Streamable HTTP ไม่ได้แปลว่าต้องมี OAuth ครบ ⇒ นับจากวินาทีที่ server มี URL สาธารณะ มันคือ API ที่ต้องยืนยันตัวตนเหมือน API อื่นทุกตัว แต่ spec ระบุว่า authorization เป็น OPTIONAL [4]
สอง: spec 2026-07-28 เปลี่ยนสิ่งที่คุณต้องเขียน
นี่คือการแก้ไขครั้งใหญ่ที่สุดของ MCP นับจากเปิดตัว ⇒ David Soria Parra หัวหน้าผู้ดูแล spec และเจ้าหน้าที่เทคนิคของ Anthropic กล่าวไว้ในการไลฟ์เมื่อวันที่ 23 กรกฎาคม 2026 ว่า [5]
"การเปลี่ยนแปลงที่สำคัญที่สุดที่เราทำกับ specification *อาจจะนับตั้งแต่ตอนที่เพิ่ม authorization*" และเสริมว่า "หลายอย่างที่ทำให้ MCP เป็น MCP ได้หายไปแล้ว" [5]
สรุปสิ่งที่เปลี่ยนจากประกาศทางการ [6]
handshake initialize/initialized ถูกยกเลิก
session Mcp-Session-Id ถูกยกเลิก ⇒ ไม่มี state ที่ชั้นโปรโตคอล
routing Mcp-Method และ Mcp-Name เป็น header ที่บังคับ
state ทุกคำขอพา protocol version · client identity · capabilities ไปใน _meta
⇒ ผลที่ตามมาที่สำคัญที่สุดคือคำขอใดก็ได้ลงที่ instance ใดก็ได้หลัง round-robin load balancer ธรรมดา โดยไม่ต้องมี shared storage [6]
และมี RPC ใหม่สำหรับ client ที่อยากรู้ความสามารถของ server ก่อน คือ server/discover ซึ่ง ไม่บังคับ เพราะทุกคำขออธิบายตัวเองได้อยู่แล้ว [6]
header ที่ใช้ตัดสินใจได้โดยไม่ต้องอ่าน body
Streamable HTTP ต้องมี Mcp-Method และ Mcp-Name ทุกคำขอ ⇒ จุดประสงค์คือให้ gateway, rate limiter หรือ WAF ตัดสินใจเส้นทางและสิทธิ์จาก header แทนการแกะ JSON body [6]
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search
และมีกฎที่ทำให้การตัดสินใจจาก header ปลอดภัย [7]
"นั่นคือกฎที่ทำให้การตัดสินใจเส้นทางจาก header ปลอดภัย ⇒ gateway สามารถส่งต่อตาม
Mcp-Method: tools/callได้ *โดยไม่ต้องเชื่อว่าผู้โจมตีจะส่ง header กับ body ให้ตรงกัน เพราะคำขอที่ไม่ตรงจะไม่ถึง handler ของคุณเลย*" [7]
⇒ ผมคิดว่านี่คือส่วนที่ออกแบบมาดีที่สุดของเวอร์ชันนี้ เพราะมันย้ายการตัดสินใจด้านความปลอดภัยไปอยู่ที่ชั้นที่ตรวจสอบได้ง่ายที่สุด [6][7]
กับดักที่แพงที่สุดของเวอร์ชันนี้
"คีย์ใน
_metaต้องเป็นแบบ fully qualified เช่นio.modelcontextprotocol/protocolVersionไม่ใช่protocolVersion⇒ *เขียนผิดแล้วมันจะไม่ทำอะไรเลยแบบเงียบ ๆ ไม่ใช่ error*" [8]
⇒ ผมอ่านข้อนี้แล้วคิดว่ามันคือกับดักที่แพงที่สุด เพราะคุณจะนั่งหาสาเหตุโดยไม่มี error ให้ตาม และตัวอย่างในประกาศทางการก็ยืนยันรูปแบบคีย์แบบมี prefix [6][8]
MRTR: server ถามกลับได้โดยไม่ต้องเปิดสตรีมค้าง
ของเดิมที่ต้องเปิด bidirectional stream ค้างไว้ ถูกออกแบบใหม่เป็น Multi Round-Trip Requests (MRTR) [6]
ของเดิมคือ sampling/createMessage · elicitation/create · roots/list [6]
วิธีใหม่ทำงานแบบนี้ [6]
1) server คืน resultType: "input_required" พร้อมคำถามที่ต้องการคำตอบ
2) client ถามผู้ใช้ แล้วยิงคำขอเดิมซ้ำ พร้อมแนบ inputResponses
⇒ ประโยชน์ที่ผู้ให้บริการรายหนึ่งเล่าไว้ตรง ๆ [6]
"การรองรับ elicitation อยู่ในโรดแมปเรามาสักพัก แต่เพราะ Supabase MCP รันแบบ stateless เราจึงทำได้ไม่ถนัด **MRTR เปลี่ยนสิ่งนั้น มันทำให้ tool ของเรายืนยันกับผู้ใช้ก่อนลงมือได้ เช่น ค่าใช้จ่ายของโปรเจกต์ใหม่ก่อนสร้าง หรือ query ที่จะลบข้อมูล" [6]
⇒ ผมคิดว่านี่คือตัวอย่างที่ทำให้เห็นภาพที่สุด ว่าการทำให้โปรโตคอล stateless ไม่ได้ลดความสามารถลง แต่ย้ายความสามารถไปอยู่ในที่ที่ตรวจสอบได้ [6]
list result ถูกแคชได้แล้ว
tools/list, prompts/list, resources/list และ resources/read ตอนนี้แนบ ttlMs และ cacheScope มาด้วย ⇒ client จึงเลือกกลยุทธ์แคชได้เองและลดการดึงซ้ำที่ไม่จำเป็น [6]
⇒ ผมคิดว่าข้อนี้สำคัญกับค่าใช้จ่ายโดยตรง เพราะแคตาล็อก tool ที่ไม่เปลี่ยนบ่อย ไม่ควรถูกดึงใหม่ทุกครั้งที่เชื่อมต่อ [6]
นโยบายยกเลิกที่วางแผนได้
spec นี้ประกาศนโยบาย deprecation อย่างเป็นทางการ โดยมีหน้าต่างขั้นต่ำ 12 เดือน เพื่อให้คุณวางแผนอัปเกรดได้แทนที่จะตั้งรับ [6]
และมีของที่ถูกย้ายตำแหน่ง ⇒ Tasks ถูกย้ายไปอยู่ในกรอบ extensions พร้อมกับ MCP Apps และ Enterprise Managed Authorization (EMA) [6]
สาม: ถ้าต้องเก็บ state ให้ใช้ handle ไม่ใช่ session
การถอด session ระดับโปรโตคอลไม่ได้บังคับให้แอปของคุณต้อง stateless ⇒ ประกาศทางการเขียนไว้ตรง ๆ [6]
"การทิ้ง session ระดับโปรโตคอล *ไม่ได้บังคับให้แอปของคุณต้อง stateless** ถ้า server ของคุณต้องถือ state ข้ามคำขอ ให้สร้าง handle ที่ชัดเจนจาก tool แล้วให้โมเดลส่งมันกลับมาเป็น argument เราพบว่าวิธีนี้ทำงานได้ดีกว่า state ที่ซ่อนอยู่ใน transport เพราะโมเดลมองเห็นมันได้"* [6]
⇒ หลักคือ tool คืน identifier เช่น basket_id แล้วโมเดลส่งค่านั้นกลับมาในคำขอถัดไป [6][9]
ผมคิดว่านี่เป็นการออกแบบที่ดีกว่าเดิมด้วยเหตุผลหนึ่ง ⇒ state ที่อยู่ใน transport มองไม่เห็น แต่ state ที่เป็น argument อยู่ในบทสนทนาให้ตรวจได้ ⇒ ถ้า agent ทำผิด คุณเห็นได้ว่ามันส่งค่าอะไรเข้ามา [6]
สี่: OAuth 2.1 มีรายละเอียดที่คนทำผิด
spec ทางการกำหนดให้ server ที่เป็น protected resource ทำหน้าที่เป็น OAuth 2.1 resource server [4]
ข้อบังคับที่ชัดเจนสี่ข้อ [4]
1) Authorization server ต้องรองรับ OAuth 2.1
2) MCP server ต้องรองรับ OAuth 2.0 Protected Resource Metadata (RFC 9728)
3) MCP client ต้องใช้ Protected Resource Metadata เพื่อค้นหา authorization server
4) Authorization server ต้องมีกลไกค้นพบอย่างน้อยหนึ่งแบบ
(RFC 8414 หรือ OpenID Connect Discovery 1.0)
⇒ สังเกตข้อ 2 ⇒ server ของคุณต้องประกาศ metadata ของตัวเองด้วย ไม่ได้ทำแค่ตรวจ token [4]
บอก client ว่าต้องขอ scope อะไร
spec กำหนดรูปแบบไว้ชัด [4]
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource",
scope="files:read"
⇒ ประโยชน์คือ client ได้คำแนะนำทันทีว่าต้องขอสิทธิ์อะไร ซึ่งตรงกับหลัก least privilege และกัน client ขอสิทธิ์เกินจำเป็น [4]
และเมื่อ server ท้าทาย scope ใหม่ spec บอกให้ client ทำแบบนี้ [4]
"คำนวณ *ยูเนียน** ของ scope ที่ client เคยขอไว้ กับ scope ที่ท้าทายรอบปัจจุบัน ⇒ เพื่อรักษาสิทธิ์ที่ให้ไปแล้วไม่ให้หายไป"* [4]
⇒ นี่คือกลไก step-up authorization และ spec บังคับให้ server คำนึงถึงลำดับชั้นของ scope เวลาตัดสินว่า token พอไหม [4]
การเสริมความปลอดภัยรอบใหม่ที่หลายคนยังไม่รู้
spec 2026-07-28 เพิ่มการป้องกันที่เจาะจงสามเรื่อง [6]
หนึ่ง ⇒ Authorization server ควรคืนพารามิเตอร์ iss ตาม RFC 9207 และ client ต้องตรวจสอบก่อนแลกโค้ด ⇒ สิ่งนี้ปิดช่องโหว่ authorization-server mix-up [6]
สอง ⇒ client ต้องระบุ application_type ตอน Dynamic Client Registration ⇒ เพื่อให้ authorization server หยุดปฏิเสธ redirect แบบ localhost ของแอปเดสก์ท็อปและ CLI [6]
"ถ้าคุณเคยสงสัยว่าทำไม OAuth flow ของ CLI client ถึงได้ error เรื่อง
redirect_uriนี่คือสาเหตุที่มักเป็น" [6]
สาม ⇒ ข้อมูลรับรองของ client ถูกผูกกับ issuer ที่ออกให้ ⇒ ใช้ข้าม authorization server ไม่ได้ [6]
⇒ และทิศทางระยะยาวคือเลื่อนจาก Dynamic Client Registration ไปสู่ Client ID Metadata Documents (CIMD) ซึ่งเป็นมาตรฐานใหม่ที่กำลังจะมา [6]
และ spec ย้ำว่าอะไรคือการบ้านเพิ่มของฝั่ง server [4]
"การนำไปใช้ต้องทำตามข้อกำหนดด้านความปลอดภัย ซึ่งครอบคลุม *การผูก audience ของ token และการตรวจสอบ token · การขโมย token · ความปลอดภัยของการสื่อสาร · การป้องกัน authorization code · การโจมตีแบบ mix-up และ confused deputy · open redirection*" [4]
⇒ หลักที่ผมคิดว่าควรท่องไว้คือ "server ตรวจ token ไม่ได้ออก token เอง" เพราะวินาทีที่ server ออก token เอง การกำกับดูแลจะกระจายตัวทันที และการถอดสิทธิ์จะกลายเป็นงานที่ต้องตามแก้ทีละที่ [4][10]
ห้า: ปัญหาที่คนไม่คิดถึง ⇒ ผู้ใช้จริง กับ automation ต้องไม่ปนกัน
นี่คือส่วนที่ผมคิดว่าลึกที่สุด และเป็นข้อค้นพบจากงานวิจัยภาคอุตสาหกรรม [10]
ปัญหาที่เจอจริงในองค์กร [10]
"ความเร็วในการนำไปใช้ *คือสิ่งที่สร้างวิกฤตการกำกับดูแล** ⇒ แต่ละทีมทำการยืนยันตัวตนเอง บางทีมไม่ทำเลย บางทีมใช้ API key บางทีมทำ OAuth เต็มรูปแบบ เกิดเป็นภาพที่กระจัดกระจายโดยไม่มีวิธีที่สม่ำเสมอในการอนุญาตผู้เรียก ตามรอยว่าใครทำอะไร หรือถอดสิทธิ์พนักงานที่ลาออกออกจากทั้งระบบ"* [10]
server ตัวเดียวต้องรับผู้เรียกสองแบบ
แบบที่ 1: พนักงานที่พิมพ์ถามผู้ช่วย AI [10]
"พนักงานที่ถามผู้ช่วย AI ว่า 'สรุปอีเมลที่ยังไม่ได้อ่านของฉัน' ⇒ *คำขอนี้ต้องรันในนามของคนนั้น มันต้องเห็นแค่กล่องจดหมายของเขา และ token ปลายทางต้องพาตัวตนของเขาไปด้วย*" [10]
แบบที่ 2: งานอัตโนมัติกลางคืน [10]
"งานอัตโนมัติกลางคืนที่รวบรวมปฏิทินของทีม *ไม่มีมนุษย์อยู่ในวงจร มันยืนยันตัวตนด้วยบัญชีบริการของตัวเอง และต้องแอบอ้างเป็นผู้ใช้คนใดคนหนึ่งไม่ได้*" [10]
และความเสี่ยงจริงถ้าออกแบบผิด
"การออกแบบที่ไร้เดียงสาจะตั้ง server สองตัว หนึ่งตัวต่อหนึ่ง persona ⇒ เพิ่มพื้นผิวการดำเนินงานเป็นเท่าตัว และแยกแคตาล็อก tool ออกเป็นสองส่วน *ที่แย่กว่านั้น ถ้าเส้นทาง automation ไม่ถูกจำกัดไว้อย่างชัดเจน การตั้งค่าผิดเพียงจุดเดียวจะทำให้ agent ที่ไม่มีคนดูแลได้ token ระดับผู้ใช้ ⇒ เป็นการยกระดับสิทธิ์แบบ confused deputy ที่ตรงตำรา*" [10]
⇒ ผมอ่านข้อนี้แล้วคิดว่ามันคือประเด็นที่บทความ MCP ส่วนใหญ่ข้ามไป เพราะมันไม่ได้เป็นปัญหาของ MCP แต่เป็นปัญหาของ การออกแบบตัวตน ที่โผล่ขึ้นมาเมื่อ MCP กลายเป็นมาตรฐาน [10]
และตัวเลขสนับสนุนว่าอุตสาหกรรมยังตามหลังเรื่องนี้ ⇒ มีเพียง 23% ขององค์กรที่มีนโยบายตัวตนของ agent อย่างเป็นทางการ และ 18% เท่านั้นที่มั่นใจสูงว่า IAM ของตัวเองรองรับตัวตนของ agent ได้ [1]
⇒ และมีข้อมูลที่ทำให้เห็นว่าปัญหานี้เกิดจริง ⇒ HackerOne รายงานว่ารายงานช่องโหว่ prompt injection ที่ยืนยันได้เพิ่มขึ้น 540% เมื่อเทียบปีต่อปี [1]
หก: รวมการยืนยันตัวตนไว้ที่ชั้นเดียว
งานวิจัยชิ้นเดียวกับข้างบนเสนอกลไกที่แก้ปัญหานั้น [10]
"เอกสารนี้รายงานการติดตั้งในภาคอุตสาหกรรมที่แก้วิกฤตนี้ด้วย **MCP gateway แบบรวมศูนย์* คือชั้นรวบรวม กำกับดูแล และยืนยันตัวตนชั้นเดียว ที่วางอยู่หน้า MCP server ทุกตัว"* [10]
เหตุผลเชิงปฏิบัติมีสามข้อ [10]
หนึ่ง ⇒ ความสม่ำเสมอ ทุก server ได้กฎเดียวกัน ไม่ใช่ต่างคนต่างทำ
สอง ⇒ การตรวจสอบย้อนหลัง มี audit log ที่เดียว ⇒ ตอบคำถาม "ใครเข้าถึงอะไร" ได้
สาม ⇒ การถอดสิทธิ์ พนักงานลาออก ⇒ ตัดที่ชั้นเดียว ไม่ต้องตามแก้ทีละ server
⇒ และงานวิจัยนี้เป็นสัญญาณว่าเรื่องนี้ไม่ใช่ทฤษฎี แต่มันคือสิ่งที่องค์กรต้องแก้จริงระหว่างนำ MCP เข้า production [10]
เจ็ด: observability ที่ขาด เพราะ MCP ไม่ใช่ request-response ธรรมดา
"การ deploy MCP server ใน production กำลังพังในแบบที่ demo ไม่เคยทำนาย *ทีมหนึ่งเห็น API call 60 กว่ารายการล้มเหลวเงียบ ๆ ใน 48 ชั่วโมง** เพราะ monitoring ของพวกเขาสร้างมาสำหรับ request-response ไม่ใช่รูปแบบการเรียก tool แบบ streaming ที่ MCP ใช้"* [11]
"อีกทีมพบว่า **OAuth token หมดอายุกลางเซสชัน ทำให้ agent ทิ้งบริบทเงียบ ๆ แล้วเริ่ม hallucinate แทนที่จะ query ฐานข้อมูลที่มันเชื่อมอยู่" [11]
⇒ ทั้งสองเคสมีลักษณะร่วมกันคือ "ล้มเหลวเงียบ" ซึ่งเป็นโหมดที่อันตรายที่สุด เพราะคุณไม่รู้ว่ามันพัง [11]
วิธีที่ทำให้ trace ต่อกันได้
"สำหรับ transport แบบ Streamable HTTP *บริบทของ trace เดินทางใน HTTP header มาตรฐาน (
traceparent,tracestate)** ⇒ ทำให้สร้าง chain ตั้งแต่ agent → MCP tool → การเรียก API ปลายทาง ขึ้นมาใหม่ได้ในระบบ tracing ของคุณ"* [3]
⇒ และ spec รุ่นใหม่รองรับเรื่องนี้โดยตรง ⇒ changelog ระบุว่าเพิ่มข้อกำหนดเกี่ยวกับคีย์ _meta สำหรับ traceparent, tracestate และ baggage [12]
ข้อผิดพลาดที่ทำให้ไม่ลาม
คำแนะนำที่ผมคิดว่าใช้ได้จริงสำหรับคนเริ่มต้น [3]
หนึ่ง ⇒ แยกข้อผิดพลาดเป็นสามระดับ และใช้ circuit breaker
"ล้มเหลวติดกันห้าครั้งจะตัดวงจร แล้วลองกู้คืนใน 30 วินาที ⇒ ฐานข้อมูลปลายทางที่เอาแน่ไม่ได้หนึ่งตัว ไม่ควรลามเป็น server ล่มทั้งตัว"
สอง ⇒ คอนเทนเนอร์: รันด้วยผู้ใช้ที่ไม่ใช่ root · ใช้ base image เล็กที่สุด · ตั้ง filesystem เป็นอ่านอย่างเดียว · และ มี endpoint /health ก่อนจะคอนเทนเนอร์ไรซ์อะไรทั้งนั้น [3]
🔴 และข้อมูลที่ผมคิดว่าคุณต้องอ่านก่อนเชื่อตัวเลขทั้งหมด
มีข้อค้นพบที่ผมคิดว่าสำคัญเท่ากับตัวเลขช่องโหว่ทุกตัวข้างบน [1]
"หมายเหตุเรื่องสัญญาณรบกวนจากตัวสแกน: การตรวจสอบอิสระชิ้นหนึ่งพบ *อัตรา false positive ราว 78% จากตัวสแกน MCP ที่ใช้ YARA** ⇒ ตัวเลข 'X% มีช่องโหว่' ดิบ ๆ จึงแตกต่างกันไปตามวิธีการ"* [1]
⇒ ตัวเลขในวงการนี้จึงต้องอ่านพร้อมวิธีวัดเสมอ และผมจึงแยกแหล่งของทุกตัวเลขไว้ให้ตามได้ [1]
และผมต้องเปิดเผยข้อจำกัดของตัวเองด้วยสามข้อ [1]
หนึ่ง ตัวเลขความปลอดภัยทั้งหมดในบทความนี้ ผมอ่านจากรายงานที่รวบรวมและอ้างงานวิจัยชิ้นอื่นต่อ ไม่ได้เปิดรายงานต้นฉบับของแต่ละการวัดเอง [1]
สอง ตัวเลขเรื่องโปรแกรม bug bounty ของ OpenAI ผมไม่ยืนยัน เพราะพบตัวเลขที่ขัดกันหลายแหล่งตั้งแต่ 6,500 ถึง 100,000 ดอลลาร์ และแหล่งที่ละเอียดกว่าเตือนไว้ตรง ๆ ให้ตรวจสอบก่อนอ้าง ⇒ ผมจึงไม่ใส่ตัวเลขนั้นลงในบทความนี้เลย [1]
สาม ผมตัดแหล่งสามแหล่งออกจากบทความนี้ เพราะเปิดไม่ได้จริง (ถูกบล็อกด้วย Cloudflare แม้ใช้ user agent ของเบราว์เซอร์) ⇒ ผมไม่นับว่าเป็นแหล่งที่ตรวจสอบได้ และไม่ใช้ข้ออ้างจากแหล่งเหล่านั้น
เช็กลิสต์ก่อน deploy
ผมรวบจากแหล่งทั้งหมดเป็น 9 ข้อ เรียงตามลำดับที่ควรทำ [2][3][4][6][7][8][10][11][12]
หนึ่ง ⇒ เลือก transport ให้ตรงปลายทาง ⇒ ถ้ามี URL สาธารณะ คืองานของ Streamable HTTP [2]
สอง ⇒ ยืนยันว่า server ของคุณพูด spec 2026-07-28 ⇒ ไม่มี handshake ไม่มี session id และมี Mcp-Method/Mcp-Name ทุกคำขอ [6]
สาม ⇒ ตรวจคีย์ใน _meta ว่า fully qualified ⇒ เขียนผิดแล้วเงียบ ไม่มี error ให้ตาม [8]
สี่ ⇒ ใช้ explicit handle แทน session state ⇒ และตรวจว่า tool ที่เคยพึ่ง session ได้รับการแก้แล้ว [6]
ห้า ⇒ ทำตัวเป็น OAuth 2.1 resource server ⇒ ประกาศ Protected Resource Metadata · ตรวจ audience/issuer/expiry/scope [4]
หก ⇒ ใส่ scope ใน WWW-Authenticate ⇒ และรองรับ step-up ด้วยยูเนียนของ scope · ตรวจ iss ตาม RFC 9207 [4][6]
เจ็ด ⇒ แยก persona ให้ชัด ⇒ ผู้ใช้จริงรันในนามเขา · automation ใช้บัญชีบริการและห้ามแอบอ้างผู้ใช้ [10]
แปด ⇒ รวม auth ที่ gateway ⇒ และให้ server ตรวจ token ไม่ได้ออก token เอง [4][10]
เก้า ⇒ เปิด trace ก่อนเปิดให้คนใช้ ⇒ traceparent ต่อจาก agent ถึงปลายทาง · circuit breaker · endpoint /health [3][12]
ข้อควรระวัง
หนึ่ง บทความนี้สรุปจาก specification ทางการของ MCP, ประกาศของทีมผู้ดูแล, รายงานรวบรวมสถิติความปลอดภัย, คู่มือ deploy และงานวิจัยภาคอุตสาหกรรมบน arXiv [1][2][3][4][6][10][11]
สอง ผมไม่ได้สร้างหรือ deploy MCP server เอง ⇒ คำแนะนำทั้งหมดมาจากเอกสาร ไม่ใช่ประสบการณ์ deploy ของผม
สาม ตัวเลขความปลอดภัยทุกตัวเป็นข้อมูลทุติยภูมิ ⇒ รายงานนั้นเองก็เตือนว่าตัวสแกนมีอัตรา false positive สูงถึงราว 78% และวิธีวัดของแต่ละงานก็ไม่เหมือนกัน [1]
สี่ ตัวเลขที่ผมยืนยันจากต้นฉบับเองได้คือส่วนของ spec ⇒ ข้อกำหนด OAuth 2.1 · รูปแบบ WWW-Authenticate · การถอด handshake และ session · header Mcp-Method/Mcp-Name · MRTR · นโยบาย deprecation 12 เดือน [4][6][12]
ห้า "authorization เป็น OPTIONAL" ใน spec หมายความว่ามันไม่บังคับที่ระดับโปรโตคอล ไม่ได้หมายความว่าปลอดภัยถ้าไม่ทำ [4]
หก Tasks ถูกย้ายไปอยู่ในกรอบ extensions ของ spec นี้ ไม่ได้ถูกยกเลิก [6]
เจ็ด ข้อความในเครื่องหมายคำพูดที่ยกมาจากแหล่งภาษาอังกฤษเป็นคำแปลของผม ไม่ใช่สำเนาต้นฉบับ ⇒ ผมคงคำสำคัญที่เป็นศัพท์เทคนิคไว้เป็นภาษาอังกฤษ เพื่อให้ผู้อ่านตรวจเทียบกับต้นฉบับได้เอง ⇒ ถ้าต้องการข้อความตรงตามต้นฉบับทุกตัวอักษร ผมแนะนำให้เปิดลิงก์ในรายการอ้างอิง
แปด ผมทำงานบนระบบที่ใช้โมเดล AI และเขียนบทความนี้ด้วยความช่วยเหลือของ AI
บทความที่เกี่ยวข้อง
ถ้าคุณยังไม่ได้อ่านหลักออกแบบ tool ผมเขียน MCP tool design: หลักออกแบบ tool ให้ agent เลือกถูกและไม่ทำอันตราย ไว้ ซึ่งเป็นชั้น "ออกแบบ" ส่วนบทความนี้คือชั้น "ทำให้พร้อมใช้จริง"
ถ้าคุณอยากเริ่มจากอะไรที่ทำได้วันนี้ ลองสามข้อนี้ก่อน คือเลือก transport ให้ถูก ตรวจว่า server พูด spec รุ่นใหม่ และตรวจคีย์ใน _meta ให้ครบ ⇒ สามข้อนี้จับปัญหาที่แพงที่สุดในบทความนี้ได้ทั้งหมด และใช้เวลาไม่ถึงชั่วโมง
แหล่งอ้างอิง
[1] "MCP Security Statistics 2026: CVEs, Vulnerabilities and Breach Data" รายงานรวบรวมสถิติพร้อมแหล่งอ้างอิงต่อตัวเลข, Practical DevSecOps (ค.ศ. 2026), https://www.practical-devsecops.com/mcp-security-statistics-2026-report
[2] "Building Production MCP Servers: What No Tutorial Tells You", Fordel Studios (20 มี.ค. 2026 · ปรับปรุง 2 ก.ย. 2026 / ค.ศ. 2026), https://fordelstudios.com/research/building-production-mcp-servers
[3] "Beyond Hello World: Building a Production-Ready MCP Server", The Agentic Blog (8 เม.ย. 2026 / ค.ศ. 2026), https://blog.appxlab.io/2026/04/08/production-ready-mcp-server
[4] "Authorization" บทว่าด้วยการอนุญาตใน MCP specification รุ่น 2026-07-28, Model Context Protocol, https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization
[5] "MCP ships 2026-07-28 spec, going stateless in largest overhaul since launch", The Agentic Review (28 ก.ค. 2026 / ค.ศ. 2026), https://theagenticreview.com/articles/2026-07-28-mcp-2026-07-28-final-spec-ships-today-going-stateless-in-largest-protocol-overha
[6] Soria Parra, D. และ Delimarsky, D., "The 2026-07-28 Specification", Model Context Protocol Blog (28 ก.ค. 2026 / ค.ศ. 2026), https://blog.modelcontextprotocol.io/posts/2026-07-28/
[7] "MCP Stateless Migration: 2026 Spec Guide", Avinash Sangle (23 ก.ค. 2026 / ค.ศ. 2026), https://avinashsangle.com/blog/mcp-stateless-spec-migration-guide
[8] "MCP Went Stateless: Migrating to the 2026-07-28 Spec (and Proving It Works)" (ค.ศ. 2026), https://wps.hkprog.org/posts/mcp-went-stateless-migrating-to-the-2026-07-28-spec-and-proving-it-works-fcdagl
[9] "The 2026-07-28 MCP Specification: A Stateless, Extensible Future" (ค.ศ. 2026), https://blog.mcpservers.org/posts/mcp-spec-2026-07-28
[10] "A Gateway Architecture for Enterprise MCP Authentication: Unifying Heterogeneous Auth, Identity Delegation, and the User / Non-User Persona Problem", arXiv (11 ส.ค. 2026 / ค.ศ. 2026), https://arxiv.org/abs/2608.10760
[11] "MCP Server Production Lessons Learned: Auth, Scaling and Observability Pitfalls", Paperclipped (ค.ศ. 2026), https://paperclipped.de/en/blog/mcp-server-production-deployment-lessons
[12] "Changelog" การเปลี่ยนแปลงของ specification รุ่น 2026-07-28, Model Context Protocol, https://modelcontextprotocol.io/specification/2026-07-28/changelog
Top comments (0)