เปิดใช้งาน auth สำหรับแอปที่ใช้ MCP ของคุณด้วย Logto
สำรวจ โซลูชัน AI ของ Logto: การยืนยันตัวตน (Authentication) และการอนุญาต (Authorization) สำหรับเซิร์ฟเวอร์ MCP, เอเจนต์ AI และแอป
คู่มือนี้จะแนะนำคุณในการผสาน Logto เข้ากับเซิร์ฟเวอร์ MCP ของคุณโดยใช้ mcp-auth และ MCP official SDK v2 เพื่อให้คุณสามารถยืนยันตัวตนผู้ใช้และอ่านข้อมูลระบุตัวตนที่ได้รับการยืนยันจากโทเค็นการเข้าถึง (Access token) ได้อย่างปลอดภัย
คุณจะได้เรียนรู้วิธี:
- กำหนดค่า Logto ให้เป็นเซิร์ฟเวอร์การอนุญาต (Authorization server) สำหรับเซิร์ฟเวอร์ MCP ของคุณ
- ตั้งค่าเครื่องมือ “whoami” ในเซิร์ฟเวอร์ MCP เพื่อคืนค่าการอ้างสิทธิ์ตัวตนของผู้ใช้ปัจจุบัน
- ทดสอบ flow ด้วย VS Code (MCP client)
หลังจากจบบทเรียนนี้ เซิร์ฟเวอร์ MCP ของคุณจะสามารถ:
- ยืนยันตัวตนผู้ใช้ใน Logto tenant ของคุณ
- ตรวจสอบ JWT access tokens ที่ออกโดย Logto (ลายเซ็น, ผู้ออก (issuer), ผู้รับ (audience), และวันหมดอายุ)
- คืนค่าการอ้างสิทธิ์ตัวตนที่ได้รับการยืนยัน (
sub,iss,audฯลฯ) สำหรับการเรียกใช้เครื่องมือ "whoami"
เมื่อผสานการทำงานเสร็จสมบูรณ์ คุณสามารถแทนที่ VS Code ด้วย MCP client ของคุณเอง เช่น เว็บแอป เพื่อเข้าถึงเครื่องมือและทรัพยากรที่เซิร์ฟเวอร์ MCP ของคุณเปิดเผย
โค้ดตัวอย่างที่สมบูรณ์และสามารถรันได้สำหรับคู่มือนี้ สามารถดูได้ที่ repository mcp-auth/js:
whoami-express: เซิร์ฟเวอร์ "whoami" ในคู่มือนี้ บน Node.js ด้วย Expresswhoami: เซิร์ฟเวอร์เดียวกันที่สร้างด้วย fetch-native (มาตรฐานเว็บRequest/Responseกับ Hono) สามารถนำไปใช้งานบน Cloudflare Workers ได้
ข้อกำหนดเบื้องต้น
- Logto Cloud (หรือแบบ self-hosted) tenant
- สภาพแวดล้อม Node.js >= 20
ทำความเข้าใจสถาปัตยกรรม
- เซิร์ฟเวอร์ MCP: เซิร์ฟเวอร์ที่เปิดเผยเครื่องมือและทรัพยากรให้กับไคลเอนต์ MCP โดยอิงตาม MCP specification ล่าสุด จะทำหน้าที่เป็น resource server ของ OAuth 2.0 ที่ตรวจสอบโทเค็นการเข้าถึง (access token) ที่ออกโดย Logto
- ไคลเอนต์ MCP: ไคลเอนต์ที่ใช้เริ่มต้น flow การยืนยันตัวตนและทดสอบการเชื่อมต่อ เราจะใช้ VS Code (ซึ่งรองรับ MCP ในตัว) เป็นไคลเอนต์ในคู่มือนี้
- Logto: ทำหน้าที่เป็นผู้ให้บริการ OpenID Connect (authorization server) จัดการข้อมูลระบุตัวตนของผู้ใช้ และออกโทเค็นการเข้าถึง JWT ที่ผูกกับผู้รับ (audience-bound) สำหรับเซิร์ฟเวอร์ MCP ของคุณ
ไดอะแกรมลำดับ (sequence diagram) ที่ไม่เป็นทางการนี้แสดงภาพรวมของกระบวนการทั้งหมด:
เนื่องจาก MCP มีการพัฒนาอย่างรวดเร็ว ไดอะแกรมข้างต้นอาจไม่อัปเดตล่าสุดเสมอ โปรดดูเอกสาร mcp-auth สำหรับข้อมูลล่าสุด
ตั้งค่าแอปใน Logto
MCP client ของคุณจำเป็นต้องลงทะเบียนเป็นแอปพลิเคชันใน Logto เพื่อเริ่มต้น flow การอนุญาต (Authorization flow) เราจะลงทะเบียน VS Code เป็น client ในคู่มือนี้:
-
ลงชื่อเข้าใช้ Logto Console ของคุณ
-
ไปที่ Applications → Create application → Create app without framework
-
เลือกประเภท: Native app
-
กรอกชื่อแอป (เช่น "VS Code") และข้อมูลที่จำเป็นอื่น ๆ จากนั้นคลิก Create application
-
ในส่วน Settings / Redirect URIs ให้เพิ่ม redirect URIs ต่อไปนี้สำหรับ VS Code แล้วบันทึกการเปลี่ยนแปลง:
http://127.0.0.1https://vscode.dev/redirect -
บันทึกและคัดลอก App ID และ Issuer endpoint
ตั้งค่าเซิร์ฟเวอร์ MCP
เราจะใช้ MCP official SDK v2 และ mcp-auth เพื่อสร้างเซิร์ฟเวอร์ MCP พร้อมเครื่องมือ "whoami" ที่ส่งคืนการอ้างสิทธิ์ (claims) ของตัวตนผู้ใช้ปัจจุบัน
สร้างโปรเจกต์และติดตั้ง dependencies
mkdir mcp-server
cd mcp-server
npm init -y
npm pkg set type="module"
npm pkg set main="whoami.js"
npm pkg set scripts.start="node whoami.js"
npm install @modelcontextprotocol/server @modelcontextprotocol/express @modelcontextprotocol/node express mcp-auth
@modelcontextprotocol/serverคือ MCP SDK v2 หลัก ซึ่งใช้มาตรฐานเว็บRequest/Response@modelcontextprotocol/expressและ@modelcontextprotocol/nodeใช้สำหรับปรับให้เข้ากับ Express บน Node.jsmcp-authให้ตัวตรวจสอบโทเค็นและข้อมูลเมตา OAuth discovery สำหรับ MCP SDK
MCP SDK v2 และ mcp-auth รองรับเฉพาะ ESM และต้องใช้ Node.js >= 20
ลงทะเบียนเซิร์ฟเวอร์ MCP เป็นทรัพยากร API
MCP specification ล่าสุด กำหนดให้โทเค็นการเข้าถึง (Access tokens) ต้องผูกกับทรัพยากรที่ออกให้ (RFC 8707) และ mcp-auth จะบังคับใช้: การอ้างสิทธิ์ aud ของโทเค็นต้องตรงกับตัวระบุทรัพยากรของเซิร์ฟเวอร์ MCP ของคุณ ใน Logto จะทำได้โดยการสร้างทรัพยากร API ที่ตัวบ่งชี้ (indicator) ตรงกับ URL ของเซิร์ฟเวอร์ MCP ของคุณ:
- ลงชื่อเข้าใช้ Logto Console ของคุณ
- ไปที่ ทรัพยากร API (API resources) → สร้างทรัพยากร API (Create API resource)
- กรอกรายละเอียด แล้วคลิก สร้างทรัพยากร API (Create API resource):
- ชื่อ API (API name): กรอกชื่อ เช่น "Who am I"
- ตัวระบุ API (API identifier): กรอก
http://localhost:3001/ต้องตรงกับตัวระบุทรัพยากรที่เราจะตั้งค่าในเซิร์ฟเวอร์ MCP
ควรใส่เครื่องหมาย / ต่อท้าย (/) ในตัวบ่งชี้ทรัพยากรเสมอ เนื่องจากบั๊กปัจจุบันใน MCP SDK อย่างเป็นทางการ ไคลเอนต์ที่ใช้ SDK จะเติม / ต่อท้ายตัวระบุทรัพยากรโดยอัตโนมัติเมื่อเริ่มต้นคำขอ auth หากตัวบ่งชี้ทรัพยากรของคุณไม่มี / ต่อท้าย การตรวจสอบทรัพยากรจะล้มเหลวสำหรับไคลเอนต์เหล่านั้น
ตั้งค่า MCP Auth กับ Logto
ประกาศเซิร์ฟเวอร์ MCP ของคุณเป็นทรัพยากรที่ได้รับการป้องกัน: ตัวระบุทรัพยากรและเซิร์ฟเวอร์การอนุญาตที่เชื่อถือ จำไว้ว่าต้องแทนที่ <your-logto-issuer-endpoint> ด้วย endpoint ของผู้ออก (issuer) ที่คุณคัดลอกมาก่อนหน้านี้ (ดูได้ในหน้าแอปพลิเคชันที่ Endpoints & Credentials เช่น https://my-project.logto.app/oidc)
ใน whoami.js:
import { MCPAuth } from 'mcp-auth';
const authIssuer = '<your-logto-issuer-endpoint>';
const mcpAuth = new MCPAuth({
protectedResourceMetadata: {
// ตัวระบุทรัพยากร; ต้องตรงกับตัวบ่งชี้ทรัพยากร API ที่ลงทะเบียนใน Logto
resource: 'http://localhost:3001/',
// เซิร์ฟเวอร์การอนุญาตที่เซิร์ฟเวอร์ MCP นี้เชื่อถือ
authorizationServer: { issuer: authIssuer, type: 'oidc' },
},
});
ข้อมูลเมตาของเซิร์ฟเวอร์การอนุญาตจะถูกดึงมาแบบ lazy เมื่อถูกเรียกใช้ครั้งแรกและแคชไว้หลังจากนั้น อินสแตนซ์ MCPAuth จะตรวจสอบโทเค็นการเข้าถึง JWT กับ JWKS ของ Logto — ทั้งลายเซ็น, ผู้ออก, ผู้รับ, และวันหมดอายุถูกบังคับใช้ทั้งหมด ไม่ต้องเขียนโค้ดตรวจสอบโทเค็นเอง
สร้างเครื่องมือ "whoami"
ต่อไป มาสร้างเครื่องมือ "whoami" ที่ส่งคืนการอ้างสิทธิ์ (claims) ของตัวตนผู้ใช้ปัจจุบันจากโทเค็นการเข้าถึงที่ตรวจสอบแล้ว ใช้ getAuthInfo เพื่ออ่านข้อมูล auth ที่ mcp-auth ตรวจสอบแล้วจาก context ของ callback เครื่องมือ
import { McpServer } from '@modelcontextprotocol/server';
import { getAuthInfo } from 'mcp-auth';
// ฟังก์ชัน factory สำหรับสร้างอินสแตนซ์ MCP server
// แต่ละคำขอจะได้อินสแตนซ์ server ของตัวเอง เพื่อแยกคำขอออกจากกัน
const createMcpServer = () => {
const mcpServer = new McpServer({
name: 'WhoAmI',
version: '0.0.0',
});
// เพิ่มเครื่องมือในเซิร์ฟเวอร์ที่ส่งคืนข้อมูลผู้ใช้ปัจจุบัน
mcpServer.registerTool(
'whoami',
{
description: 'รับข้อมูลผู้ใช้ปัจจุบัน',
},
(context) => {
const { claims } = getAuthInfo(context);
return {
content: [{ type: 'text', text: JSON.stringify(claims) }],
};
}
);
return mcpServer;
};
เชื่อมต่อเซิร์ฟเวอร์
สุดท้าย ให้บริการ OAuth discovery documents (RFC 9728 / RFC 8414) เพื่อให้ไคลเอนต์ MCP ค้นหาเซิร์ฟเวอร์การอนุญาตของคุณ และปกป้อง endpoint MCP ด้วย Bearer auth middleware ของ SDK
import {
createMcpExpressApp,
mcpAuthMetadataRouter,
requireBearerAuth,
} from '@modelcontextprotocol/express';
import { toNodeHandler } from '@modelcontextprotocol/node';
import { createMcpHandler } from '@modelcontextprotocol/server';
const PORT = 3001;
// MCP handler ใช้มาตรฐานเว็บ Request / Response; `toNodeHandler` ปรับให้เข้ากับ Express
const mcpNodeHandler = toNodeHandler(createMcpHandler(createMcpServer));
const app = createMcpExpressApp();
// ให้บริการ OAuth discovery documents (`/.well-known/...`) ซึ่งเป็นสาธารณะโดยออกแบบ
app.use(mcpAuthMetadataRouter(await mcpAuth.getAuthMetadataOptions()));
app.all(
'/',
// ต้องการ Bearer token ที่ถูกต้อง; ข้อมูล auth ที่ตรวจสอบแล้วจะถูกส่งต่อไปยัง handler ผ่าน `req.auth`
requireBearerAuth(mcpAuth.getBearerAuthOptions()),
// `createMcpExpressApp` ใช้ `express.json()` ซึ่งจะดึงข้อมูลจาก request stream ดังนั้น
// body ที่แปลงแล้วจะถูกส่งต่ออย่างชัดเจน
async (request, response) => mcpNodeHandler(request, response, request.body)
);
app.listen(PORT);
รันเซิร์ฟเวอร์ด้วย:
npm start
ทดสอบการผสานการทำงาน
-
เริ่มเซิร์ฟเวอร์ MCP:
npm start -
เชื่อมต่อ VS Code กับเซิร์ฟเวอร์ MCP ของคุณ:
- กด
Command + Shift + P(macOS) หรือCtrl + Shift + P(Windows / Linux) เพื่อเปิด Command Palette - พิมพ์
MCP: Add Server...แล้วเลือก - เลือก
HTTPเป็นประเภทเซิร์ฟเวอร์ - กรอก URL ของเซิร์ฟเวอร์ MCP:
http://localhost:3001/ - เมื่อ flow OAuth เริ่มต้น VS Code จะขอ Client ID: วาง App ID ที่คุณคัดลอกไว้ก่อนหน้านี้
- เนื่องจากเป็น public client ที่ไม่มี app secret ให้กด Enter เพื่อข้าม secret
- ดำเนินการ flow การลงชื่อเข้าใช้ในเบราว์เซอร์ของคุณให้เสร็จสมบูรณ์
- กด
-
หลังจากลงชื่อเข้าใช้แล้ว ให้รันเครื่องมือ
whoamiใน VS Code
คุณควรเห็นการอ้างสิทธิ์ที่ได้รับการยืนยันจาก access token เช่น:
{
"iss": "https://my-project.logto.app/oidc",
"sub": "user_XXXX",
"aud": "http://localhost:3001/",
"client_id": "<your-app-id>"
}
อ่านเพิ่มเติม
ขณะนี้เซิร์ฟเวอร์ MCP ของคุณสามารถตรวจสอบ access token ขาเข้าได้แล้ว ขั้นตอนถัดไป เรียนรู้วิธีที่เซิร์ฟเวอร์ MCP สามารถเรียกใช้งาน API ธุรกิจ downstream ของคุณอย่างปลอดภัยในนามของผู้ใช้ โดยไม่ต้องส่งต่อโทเค็นหรือสูญเสีย context ของผู้ใช้:
วิธีที่เซิร์ฟเวอร์ MCP เรียก API ของคุณในนามของผู้ใช้: กลยุทธ์โทเค็นสำหรับ production