เจาะลึกข้อผิดพลาดการเชื่อมต่อ MCP: สาเหตุและวิธีแก้ปัญหา 404, 406 และ 400s
สรุปสาเหตุและวิธีแก้ปัญหาข้อผิดพลาดการเชื่อมต่อ Model Context Protocol (MCP) รูปแบบ Streamable HTTP เช่น 404 บน /sse, 406 Not Acceptable และเซสชัน 400s จากบทแนะนำของ Tanod

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
- ข้อผิดพลาด MCP ส่วนใหญ่เกิดจากการใช้ URL ผิดรูปแบบหรือส่ง Header ไม่ถูกต้อง
- ระบบ Streamable HTTP ใช้ URL เดี่ยว แทนที่สถาปัตยกรรม HTTP+SSE แบบเดิม
- คำขอ POST ต้องระบุ Header Accept และ Content-Type เป็น JSON เสมอ
- เซิร์ฟเวอร์แบบมีสถานะต้องส่ง Mcp-Session-Id ทุกครั้งหลังเรียกใช้งาน initialize
การพัฒนาแอปพลิเคชันที่ใช้งาน Model Context Protocol (MCP) มักพบปัญหาการเชื่อมต่อขัดข้องในฝั่งเซิร์ฟเวอร์ บทความจาก Tanod ได้รวบรวมปัญหาที่พบบ่อยที่สุดในการใช้งานโปรโตคอล Streamable HTTP ซึ่งใช้งาน URL เพียงจุดเดียวในการรับส่งข้อมูล JSON-RPC และเปิดสตรีม GET บนเส้นทางเดียวกัน โดยปัญหาหลักมักเกิดจากไคลเอนต์พยายามติดต่อผิดที่หรือตั้งค่าหัวข้อคำขอไม่ตรงตามที่กำหนด
ในโปรโตคอล HTTP+SSE รุ่นเก่า (รอบวันที่ 2024-11-05) ไคลเอนต์จะต้องเปิด GET ไปยัง URL ของ SSE เพื่อรับตำแหน่งปลายทางที่สองสำหรับส่ง POST แต่ในเวอร์ชัน Streamable HTTP (2025-03-26 เป็นต้นมา) ได้ยุบรวมเหลือเพียง URL เดียว ทำให้ไคลเอนต์รุ่นเก่าหรือบริดจ์ที่พยายามต่อท้ายเส้นทางด้วย /sse มักจะได้รับรหัสข้อผิดพลาด 404 จากเซิร์ฟเวอร์ทันที รวมถึงการพยายามเติม /mcp ซ้ำซ้อนลงไปใน URL ที่ถูกต้องอยู่แล้ว
การเปลี่ยนผ่านจาก HTTP+SSE สู่ Streamable HTTP ถือเป็นการยกระดับสถาปัตยกรรมของ MCP ให้มีความซับซ้อนน้อยลงและจัดการการเชื่อมต่อได้ง่ายขึ้น อย่างไรก็ตาม การอัปเดตโค้ดฝั่งไคลเอนต์ให้สอดคล้องกับสเปกใหม่จึงเป็นสิ่งจำเป็นอย่างยิ่งเพื่อป้องกันข้อผิดพลาดที่มักเกิดขึ้นในช่วงเปลี่ยนผ่านนี้
แนวทางการแก้ไขปัญหาดังกล่าวคือการใช้งาน URL ให้ตรงกับที่ประกาศไว้ทุกประการ สำหรับไคลเอนต์ที่รองรับเฉพาะ stdio ควรใช้งานบริดจ์เช่น npx mcp-remote พร้อมระบุพารามิเตอร์ --transport http-only เพื่อป้องกันไม่ให้ระบบสำรองไปเรียกใช้งาน SSE เอง โดยตัวอย่างเซิร์ฟเวอร์ของ Tanod จะใช้งานรูปแบบ Streamable HTTP ทั้งหมด เช่น https://tanod.dev/mcp และ https://tanod.dev/mcp/docs โดยเส้นทางย่อยอย่าง /mcp/docs/sse หรือ /api/mcp จะให้ผลลัพธ์เป็น 404 ทั้งหมด

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
ในส่วนของข้อผิดพลาด 406 Not Acceptable มักเกิดขึ้นเมื่อคำขอแบบ POST ไม่มี Header Accept: application/json, text/event-stream เนื่องจากเซิร์ฟเวอร์อาจตอบกลับด้วย JSON เดี่ยวหรือสตรีม SSE โดยไลบรารี HTTP ทั่วไปมักส่ง Accept: */* มาให้แทน ซึ่งเซิร์ฟเวอร์บางตัวอาจปฏิเสธคำขอนั้น นอกจากนี้คำขอแบบ POST ยังต้องกำหนด Content-Type: application/json ให้ถูกต้องเพื่อป้องกันข้อผิดพลาดจากการเข้ารหัสแบบฟอร์มหรือข้อความธรรมดา
สำหรับปัญหาเกี่ยวกับเซสชันในสถานะ 400s เซิร์ฟเวอร์ที่มีสถานะ (Stateful) จะต้องเริ่มต้นด้วยคำขอ initialize ก่อนเสมอ โดยการตอบกลับจะมี Header Mcp-Session-Id ติดมาด้วย ซึ่งไคลเอนต์จะต้องแนบ Header นี้ไปในทุกคำขอถัดไป การเรียกใช้งานเครื่องมือเช่น tools/list ก่อนเริ่มเซสชันหรือการละเลยไม่ส่งรหัสเซสชันจะทำให้ได้รับรหัสข้อผิดพลาด 400 ทันที และหากเซิร์ฟเวอร์รีสตาร์ท เซสชันเดิมจะหายไปและแสดงข้อผิดพลาด 404 Session not found ซึ่งไคลเอนต์จะต้องเริ่มต้นเซสชันใหม่ด้วยคำขอ initialize อีกครั้ง
"Most connection failures we see in our own server log are a client talking to a different address than the one it was given, or sending the wrong headers."
Tanod
ที่มา: Dev.to
พบข้อมูลผิดพลาดในบทความนี้? แจ้งปัญหาบทความนี้
ความคิดเห็น
แสดงความคิดเห็น