คู่มือการนำระบบรับรองความถูกต้องของเซิร์ฟเวอร์ MCP ไปใช้: ใช้สเปคเวอร์ชันล่าสุด
ให้ประเด็นสำคัญในการนำระบบรับรองความถูกต้องของเซิร์ฟเวอร์ MCP ให้สอดคล้องกับสเปควันที่ 2025-06-18
ให้ประเด็นสำคัญในการนำระบบรับรองความถูกต้องของเซิร์ฟเวอร์ MCP ให้สอดคล้องกับสเปควันที่ 2025-06-18
ไม่กี่วันที่ผ่านมา (18 มิถุนายน 2025) ทีม MCP (Model Context Protocol) ได้ปล่อย MCP Spec (2025-06-18) เวอร์ชันล่าสุด การอัปเดตนี้มีการเปลี่ยนแปลงสำคัญในส่วน auth โดยเซิร์ฟเวอร์ MCP จะไม่ออก access tokens ในฐานะ Authorization Server อีกต่อไป แต่จะทำหน้าที่ตรวจสอบ access token และให้บริการ resource ในฐานะ Resource Server แทน
ในฐานะผู้ดูแลของ MCP Auth (ไลบรารี auth สำหรับ MCP Server ที่พร้อมใช้งาน) ฉันได้อัปเดตโปรเจกต์นี้ให้รองรับสเปค auth ของ MCP เวอร์ชันล่าสุดแล้ว จากประสบการณ์จริง ฉันจะอธิบายขั้นตอนการนำฟีเจอร์รับรองความถูกต้องตามข้อกำหนดของสเปคล่าสุดมาปรับใช้กับ MCP Server ของคุณ
บทความนี้จะช่วยให้คุณ:
โปรดทราบว่าบทความนี้:
ตาม MCP auth spec เวอร์ชันล่าสุด flow การรับรองความถูกต้องของ MCP สรุปได้ใน diagram ต่อไปนี้:
MCP Client ส่งคำขอเพื่อเข้าถึง resource บน MCP Server ที่ https://github-tools.com เพราะผู้ใช้งานยังไม่ได้เข้าสู่ระบบ HTTP authorization header ของ request นี้จึงยังไม่มี access token ที่แทนตัวตนผู้ใช้
MCP Server ไม่พบ access token ใน header ของคำขอจาก MCP Client เซิร์ฟเวอร์จึงตอบกลับด้วย HTTP 401 error และใส่ WWW-Authenticate header ซึ่งประกอบด้วย URL ชี้ไปยัง resource metadata (ค่าของฟิลด์ resource_metadata)
MCP Client ดึงค่า resource_metadata จาก WWW-Authenticate header (เช่น https://github-tools.com/.well-known/oauth-protected-resource) แล้วขอ resource metadata จาก Server ที่อยู่ภายใต้บทบาท Resource Server Metadata นี้จะระบุเช่น authorization_servers และ scopes_supported เพื่อให้ MCP Client ทราบว่าจะขอ token จาก authorization server ไหนและต้องมีสิทธิ์อะไร
4-8. MCP Client ขอ metadata ข้อมูล authorization server จาก URL ที่ได้ในขั้นตอนก่อน จากนั้นทำ OAuth 2.1 flow กับ authorization server และได้รับ access token หลัง authorize สำเร็จ
MCP Client ถือ access token ที่ได้มา ส่งคำขอ resource ใหม่ไปยัง MCP Server
MCP Server ตรวจสอบ token ว่า valid แล้วจึงตอบกลับ resource ที่ร้องขอ หลังจากนั้นการสื่อสารระหว่าง MCP Client กับ MCP Server จะอยู่ภายใต้ token ที่ผ่านการตรวจสอบแล้ว
ต่อไปจะอธิบายวิธีนำกลไก auth ของ MCP server ไปใช้ทีละขั้นตอนตาม workflow ของ MCP auth
ใน flow ด้านบน เมื่อ MCP Client ส่ง request โดยไม่แนบ access token ไป MCP Server ต้องตอบกลับด้วย HTTP 401 Unauthorized และระบุ WWW-Authenticate header ที่มี URL สำหรับรับ resource metadata ของ server นี้
ตามข้อกำหนด MCP auth spec error handling กรณีที่ MCP Server พบ access token ไม่ถูกต้อง ก็ต้องตอบกลับ 401 error พร้อม WWW-Authenticate header ด้วยเช่นกัน
หลังรู้แล้วว่าต้องคืน 401 error เมื่อใด จะสร้าง WWW-Authenticate header อย่างไร?
อ้างอิงจาก RFC9728 Section 5.1 WWW-Authenticate header จะต้องมีพารามิเตอร์ resource_metadata ชี้ไปยัง URL ข้อมูล metadata ของ resource นี้
รูปแบบตัวอย่าง:
คำว่า Bearer คือ authentication scheme ที่แปลว่าการเข้าใช้ resource ที่ได้รับการป้องกันด้วย OAuth 2.0 ต้องใช้ bearer token (ดู: MDN documentation) ส่วนค่าพารามิเตอร์ resource_metadata คือ URL endpoint ของ resource metadata ที่ MCP Server ของคุณให้บริการ
ตัวอย่างโค้ดจริงทำงานดังนี้:
เมื่อ MCP Client ได้รับ 401 error แบบนี้ จะรู้ว่า endpoint ชี้ไปที่ resource metadata ของ MCP Server จาก header resource_metadata ต่อไป client จะใช้ metadata นี้เพื่อขอ access token ไปยัง authorization server ที่ระบุใน metadata ต่อไป
ตอนนี้เรารู้แล้วว่าคืนค่า 401 เมื่อไหร่และต้องแนบ URL ของ resource metadata ด้วย แต่ยังไม่รู้ว่า endpoint URL นี้ควรเป็นที่ไหนหรือ metadata มีอะไรบ้าง ดูต่อไปหัวข้อต่อไป
ตาม flow MCP auth หลัง MCP Client ได้รับ 401 error ต้องร้องขอข้อมูล resource metadata ต่อทันที ดังนั้น MCP Server ซึ่งทำหน้าที่ Resource Server ควรมี endpoint สำหรับ metadata นี้
ในระบบ OAuth ใช้ URL ระบุที่อยู่ของ Resource เรียกว่า "resource indicator" ซึ่งตาม RFC9728 endpoint resource metadata ควรอยู่ที่ path เฉพาะ /.well-known
ถ้า MCP Server ของคุณ (เช่น https://github-tools.com) มีแค่ service เดียว endpoint metadata ก็เป็น:
หากมี service หลายตัวใน host เดียวกัน แต่ละ service ต้องมี endpoint metadata ของตัวเอง ยกตัวอย่าง https://api.acme-corp.com ให้บริการ:
https://api.acme-corp.com/github - เซอร์วิสเชื่อมต่อ GitHubhttps://api.acme-corp.com/slack - เซอร์วิสเชื่อมต่อ Slackhttps://api.acme-corp.com/database - บริการฐานข้อมูลmetadata endpoint ของแต่ละ service คือ:
https://api.acme-corp.com/.well-known/oauth-protected-resource/githubhttps://api.acme-corp.com/.well-known/oauth-protected-resource/slackhttps://api.acme-corp.com/.well-known/oauth-protected-resource/databaseข้อดีของการแยกแบบนี้คือ แต่ละ service กำหนด permission scope และ authorization server ต่างกันได้ เช่น
github:read, github:writeslack:channels:read, slack:messages:writedb:queryสรุป url pattern ของ metadata endpoint จะเป็นดังนี้:
สามารถสร้าง endpoint URL จาก resource identifier ได้แบบนี้:
เมื่อได้ endpoint URL แล้ว ต้องให้ path นี้ส่งคืน metadata แบบ JSON ตามข้อกำหนด RFC9728
โดยทั่วไปให้เน้น 4 ฟิลด์หลัก ๆ คือ
resource - resource identifier ต้องตรงกับ resource address ที่ MCP Client จะใช้authorization_servers - array ของ authorization server ที่ให้ MCP Client ขอ access token ได้ (MCP auth spec บังคับต้องระบุ)scopes_supported - รายการ permission scopes ที่ Resource Server รองรับbearer_methods_supported - วิธีส่ง access token มาที่ server นี้ เช่น ["header"] หมายถึง ส่งใน HTTP Authorization headerตัวอย่าง metadata ของ https://github-tools.com MCP Server:
metadata นี้บอกกับ MCP Client ว่า ต้องการเข้าถึง resource https://github-tools.com ควรขอ access token จาก https://auth.github-tools.com และควรขอ scope ใดได้บ้าง รวมถึงต้องส่ง token ผ่าน HTTP header
กรณีส่วนใหญ่ ระบุ 4 ฟิลด์นี้ก็เพียงพอแล้ว ถ้าต้องการกำหนดฟิลด์อื่นเพิ่มเติม อ่านรายละเอียดทั้งหมดจาก RFC9728
หลัง MCP Client ได้ access token จาก authorization server ก็จะนำ token นั้นมาเข้าใช้งานกับ MCP Server
เวลาตรวจสอบ access token ที่ MCP Server ต้องใส่ใจประเด็นดังนี้:
เมื่อ MCP Server ได้ access token ซึ่งมีข้อมูล issuer (authorization server) อยู่ นักพัฒนาบางคนอาจเลือกข้อมูลสำหรับตรวจสอบ token โดยใช้ค่า issuer จาก token ทันที โดยเฉพาะหาก resource metadata ของ MCP Server มีหลาย authorization server เช่น
กรณีนี้มีความเสี่ยงด้านความปลอดภัย หากมีผู้ไม่หวังดีสร้าง authorization server หลอกและออก access token ปลอมระบุ issuer เป็น server หลอกนี้ หาก MCP Server ใช้ issuer ใน token นี้ไปตรวจสอบกับ server ปลอม จะทำให้ credential ปลอมก็ถูกยอมรับ
วิธีตรวจสอบที่ปลอดภัยควรเป็น:
ตัวอย่างใช้ไลบรารี jose ตรวจสอบ JWT:
ในหัวข้อ Token Audience Binding and Validation ของ MCP auth spec ระบุว่า ตอน client ขอ access token จาก authorization server ต้องระบุ resource ด้วยว่า token จะนำไปใช้ที่ resource server ไหน (เช่น https://github-tools.com)
เมื่อ authorization server ออก token ให้ ต้องผูก resource นี้ไว้ใน JWT field aud (audience) ด้วย
เมื่อ MCP Server รับ access token นี้มา ต้องตรวจสอบว่าค่า audience ใน JWT ตรงกับ resource identifier ของตนเอง
ตัวอย่างเช่น MCP Server https://github-tools.com:
กระบวนการนี้สำคัญในการป้องกันการนำ token ที่ได้จาก service อื่นมาใช้กับ MCP Server ของเราโดยมิชอบ
หาก MCP Server ของคุณมีระบบกำหนด permission รายผู้ใช้ หลังจาก access token ผ่านการตรวจสอบเบื้องต้น ต้องเช็คว่า token นี้มี scope ตรงกับสิทธิ์ที่ต้องการ เช่น
ตาม MCP auth spec หาก token ไม่มี scope ที่ resource ต้องการ ต้องตอบกลับด้วย 403 Forbidden
หลังอ่านบทความนี้ คุณควรนำไปติดตั้งระบบรับรองความถูกต้องตรงตามสเปคล่าสุดของ MCP Server ได้สำเร็จ ประเด็นสำคัญคือ ตรวจสอบ token อย่างเข้มงวด กำหนดค่า metadata ให้ถูกต้อง และตรวจสอบ audience อย่างเคร่งครัด
ถ้าคุณกำลังสร้าง MCP Server แนะนำให้ลองใช้ไลบรารี MCP Auth ซึ่งทำตามฟีเจอร์ทั้งหมดข้างต้น และช่วยให้คุณผสานฟีเจอร์ auth เข้ากับระบบได้รวดเร็ว
หากมีข้อสงสัย พูดคุยกันได้ใน GitHub มาช่วยกันพัฒนา ecosystem ของ MCP ไปด้วยกัน