Open in
เชื่อมต่อด้วย OAuth
อนุญาต MCP ไคลเอนต์และ ThunderPhone CLI โดยไม่ต้องแชร์คีย์ API
OAuth ช่วยให้แอปเชื่อมต่อกับองค์กร ThunderPhone หนึ่งองค์กรด้วยสิทธิ์ที่คุณอนุมัติ ไคลเอนต์ไดเรกทอรีควรใช้ OAuth เป็นค่าเริ่มต้น คีย์ API ขององค์กรยังคงพร้อมใช้งานสำหรับไคลเอนต์ที่ต้องใช้โทเค็น Bearer ซึ่งกำหนดค่าด้วยตนเอง
อนุมัติการเชื่อมต่อ
เริ่มการเชื่อมต่อในไคลเอนต์ MCP ของคุณ ลงชื่อเข้าใช้ ThunderPhone ตรวจสอบชื่อแอปและสิทธิ์ที่ร้องขอ เลือกองค์กร แล้วเลือก อนุมัติ เลือก ปฏิเสธ หากคุณไม่ได้เริ่มการเชื่อมต่อหรือไม่ไว้วางใจแอป ชื่อแอปจัดส่งโดยนักพัฒนาของแอปและไม่ใช่ตราสัญลักษณ์การยืนยัน
สิทธิ์การอ่านจะแสดงข้อมูลที่ระบุ รวมถึงไฟล์บันทึกเสียงและข้อความถอดเสียงเมื่อมีการร้องขอ calls:read สิทธิ์การเขียนสามารถเปลี่ยนแปลงหรือลบทรัพยากรได้ การโทร แคมเปญ การซื้อหมายเลขโทรศัพท์ และการปรับใช้ อาจมีค่าใช้จ่ายหรือส่งผลต่อระบบที่ใช้งานจริง บทบาทของคุณในองค์กรยังคงมีผลบังคับใช้
สำหรับการเชื่อมต่อ CLI ให้เปิดลิงก์ยืนยันที่แสดงในเทอร์มินัลของคุณ เปรียบเทียบรหัสแปดอักขระ เลือกองค์กรของคุณ แล้วอนุมัติ การเปิดลิงก์เพียงอย่างเดียวไม่ได้ให้สิทธิ์เข้าถึง รหัสจะหมดอายุหลังจาก 15 นาที
ยกเลิกการเชื่อมต่อแอป
เปิด องค์กร → คีย์ API → แอปที่ได้รับอนุญาต ในแดชบอร์ด แล้วเลือก เพิกถอน การดำเนินการนี้จะเพิกถอนการอนุญาตที่คุณเลือกสำหรับองค์กรปัจจุบัน รวมถึงโทเค็นการเข้าถึงและโทเค็นรีเฟรช เชื่อมต่อใหม่จากแอปหากคุณต้องการอนุญาตแอปอีกครั้ง
การค้นหาสำหรับไคลเอนต์ MCP
ใช้ URL ของเซิร์ฟเวอร์ https://api.thunderphone.com/v1/mcp คำขอที่ไม่มีการยืนยันตัวตนที่ถูกต้องจะได้รับ 401 พร้อมข้อมูลดังนี้:
WWW-Authenticate: Bearer resource_metadata="https://api.thunderphone.com/.well-known/oauth-protected-resource"ดึงเอกสารนั้น จากนั้นดึงเมทาดาทาของเซิร์ฟเวอร์การอนุญาตที่ https://api.thunderphone.com/.well-known/oauth-authorization-server เมทาดาทาของทรัพยากรยังมีให้ใช้งานที่ /.well-known/oauth-protected-resource/v1/mcp ใช้ปลายทางที่ส่งกลับมาแทนการสร้างปลายทางเอง ตัวระบุทรัพยากรคือ https://api.thunderphone.com/v1/mcp
เซิร์ฟเวอร์รองรับรหัสการอนุญาตพร้อม S256 PKCE โทเค็นรีเฟรชแบบหมุนเวียน การลงทะเบียนไคลเอนต์สาธารณะแบบไดนามิก การเพิกถอน และการอนุญาตอุปกรณ์ ไม่มีข้อมูลลับของไคลเอนต์หรือการอนุญาตโดยนัย นอกจากนี้ยังมีการค้นหา OpenID ที่ /.well-known/openid-configuration ซึ่งมีฟิลด์เซิร์ฟเวอร์การอนุญาตเดียวกัน พร้อม subject_types_supported: ["public"] และปลายทาง userinfo ไม่รองรับ ID token และเอกสาร Client ID Metadata Document (CIMD)
ลงทะเบียนไคลเอนต์สาธารณะ
ส่ง JSON ไปยัง POST /v1/oauth/register:
{
"client_name": "My MCP client",
"redirect_uris": ["http://127.0.0.1:8765/callback"],
"token_endpoint_auth_method": "none",
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"]
}บันทึก client_id ที่ส่งกลับมา การเปลี่ยนเส้นทางต้องใช้ HTTPS หรือ HTTP บน 127.0.0.1 หรือ localhost ลงทะเบียน URI ของคอลแบ็กให้ตรงกันทุกประการ รวมถึงพอร์ตและพาธ ไม่อนุญาตให้ใช้แฟรกเมนต์และข้อมูลรับรองที่ฝังอยู่ client_uri และ logo_uri ที่ระบุเพิ่มเติมต้องใช้ HTTPS โดย ThunderPhone จะไม่ดึงข้อมูลเหล่านี้ระหว่างการลงทะเบียน การลงทะเบียนมีการจำกัดอัตรา ไคลเอนต์ที่ลงทะเบียนแล้วจะไม่หมดอายุและยังคงลงทะเบียนอยู่เมื่อมีการเพิกถอนการเชื่อมต่อ คอลแบ็ก HTTPS รวมถึง https://chatgpt.com/connector/oauth/<id> และ https://chatgpt.com/connector_platform_oauth_redirect การเชื่อมต่อแต่ละรายการอาจลงทะเบียนไคลเอนต์ของตนเองได้
รหัสการอนุญาต
เปิดปลายทางการอนุญาตที่ค้นพบด้วย client_id redirect_uri ที่ลงทะเบียนไว้ตรงกันทุกประการ response_type=code state แบบสุ่ม scope code_challenge code_challenge_method=S256 และ resource=https://api.thunderphone.com/v1/mcp คำนวณแชลเลนจ์เป็นไดเจสต์ SHA-256 แบบ base64url ที่ไม่มีการเติมของตัวตรวจสอบ PKCE ใหม่ที่มีเอนโทรปีสูง ตรวจสอบ state และ iss ที่ส่งกลับมาก่อนแลกรหัส การตอบกลับการอนุญาตทุกรายการ รวมถึงการปฏิเสธและข้อผิดพลาดของโปรโตคอล จะระบุผู้ออกด้วย iss ซึ่งต้องตรงกับ issuer ที่ค้นพบทุกประการ ข้อผิดพลาดสำหรับไคลเอนต์หรือคอลแบ็กที่ไม่ถูกต้องจะส่งกลับภายในเครื่องโดยไม่มีการเปลี่ยนเส้นทางไปยังคอลแบ็กนั้น
แลกเปลี่ยนที่ POST /v1/oauth/token โดยใช้การเข้ารหัสแบบฟอร์ม (ยอมรับ JSON ด้วย):
grant_type=authorization_code
client_id=<your client id>
code=<single-use authorization code>
redirect_uri=<exact registered redirect URI>
code_verifier=<original PKCE verifier>
resource=https://api.thunderphone.com/v1/mcpยอมรับพารามิเตอร์ resource ที่ระบุเพิ่มเติมได้ทั้งในคำขอการอนุญาตและคำขอโทเค็น รวมถึงการแลกเปลี่ยนรีเฟรชและอุปกรณ์ เมื่อไม่ระบุ ระบบจะใช้ทรัพยากร MCP ที่ค้นพบเป็นค่าเริ่มต้น เมื่อระบุ ต้องตรงกับทรัพยากรนั้นทุกประการ ค่าอื่นจะส่งกลับ invalid_target โทเค็นการเข้าถึงจะมีผู้รับตามนั้น และ MCP จะปฏิเสธโทเค็นที่ไม่มีผู้รับหรือมีผู้รับต่างกันด้วย 401 และแชลเลนจ์การค้นหา
คำขอการอนุญาตและรหัสจะหมดอายุหลัง 10 นาที การตอบกลับโทเค็นทุกรายการมี access_token token_type (Bearer) expires_in (ค่าเริ่มต้น 3600 วินาที) refresh_token scope organization_id และ organization_name ส่งโทเค็นการเข้าถึงผ่านส่วนหัว Authorization: Bearer เท่านั้น ห้ามใส่โทเค็นใน URL บันทึก ซอร์สคอนโทรล หรือแชต
รีเฟรชและเพิกถอน
รีเฟรชด้วย grant_type=refresh_token client_id refresh_token และ resource ที่ปลายทางโทเค็น บันทึกโทเค็นรีเฟรชใหม่แบบอะตอมิกและหยุดใช้โทเค็นเดิม โทเค็นรีเฟรชจะหมดอายุหลัง 30 วันหากไม่มีการรีเฟรชสำเร็จ scope ที่ระบุเพิ่มเติมอาจจำกัดสิทธิ์ที่ได้รับ offline_access จะถูกรวมเสมอและจะออกโทเค็นรีเฟรชเสมอ คำขอเริ่มต้นที่ไม่มี scope จะให้เพียง offline_access ดังนั้นไคลเอนต์ควรขอสิทธิ์ที่ต้องการ
การใช้รหัสซ้ำและการใช้โทเค็นรีเฟรชแบบหมุนเวียนซ้ำจะเพิกถอนการอนุญาตทั้งหมด ทำให้การรีเฟรชภายในไคลเอนต์เป็นลำดับเดียวกัน การเล่นซ้ำข้อมูลรับรองที่แลกเปลี่ยนสำเร็จแล้วไม่ใช่กลยุทธ์การลองใหม่ที่ปลอดภัย
หากต้องการตัดการเชื่อมต่อ ให้ส่ง token และ client_id ไปยัง POST /v1/oauth/revoke การเพิกถอนโทเค็นใดโทเค็นหนึ่งจะเพิกถอนการอนุญาตของโทเค็นนั้น รวมถึงโทเค็นทั้งหมดที่ออกจากโทเค็นนั้น โทเค็นที่ไม่รู้จักจะส่งกลับผลสำเร็จโดยไม่เปิดเผยว่ามีอยู่หรือไม่ เซสชันแดชบอร์ดสามารถแสดงรายการการอนุญาตของตนเองได้ที่ GET /v1/oauth/grants และเพิกถอนรายการหนึ่งได้ที่ DELETE /v1/oauth/grants/<id> โดยใช้ X-ThunderPhone-Org เพื่อเลือกองค์กร
การอนุญาตอุปกรณ์
การอนุญาตอุปกรณ์จำกัดเฉพาะไคลเอนต์ที่ลงทะเบียนล่วงหน้า ไคลเอนต์ที่ลงทะเบียนแบบไดนามิกจะได้รับ unauthorized_client ไคลเอนต์สาธารณะที่ลงทะเบียนล่วงหน้า thunderphone-cli รองรับการอนุญาตอุปกรณ์และการรีเฟรช ส่ง client_id=thunderphone-cli และ scope ไปยัง POST /v1/oauth/device/code แสดง user_code และ verification_uri ให้ผู้ใช้ หรือเปิด verification_uri_complete
สำรวจปลายทางโทเค็นด้วย grant_type=urn:ietf:params:oauth:grant-type:device_code client_id และ device_code โดยรออย่างน้อยตาม interval ที่ส่งกลับมา (5 วินาที) ดำเนินการต่อเมื่อได้รับ authorization_pending สำหรับ slow_down ให้ใช้ interval ใหม่ที่ส่งกลับมาในคำตอบ (เพิ่มขึ้น 5 วินาที) สำหรับคำขอถัดไปทุกรายการ หยุดเมื่อได้รับ access_denied expired_token หรือข้อผิดพลาดอื่นใด ห้ามอนุมัติรหัสอุปกรณ์โดยอัตโนมัติ
ไคลเอนต์ thunderphone-mcp ที่ลงทะเบียนล่วงหน้ารับ http://127.0.0.1/callback และ http://localhost/callback บนพอร์ตใดก็ได้ สคีม โฮสต์ พาธ และคิวรีต้องตรงกัน การแลกเปลี่ยนโทเค็นต้องใช้ URI การเปลี่ยนเส้นทางที่ตรงกันทุกประการ รวมถึงพอร์ต จากการอนุญาต ไคลเอนต์ที่ลงทะเบียนแบบไดนามิกต้องจับคู่ URI การเปลี่ยนเส้นทางให้ตรงกันทุกประการ รวมถึงพอร์ต ลงทะเบียนคอลแบ็กอื่นแบบไดนามิกหากต้องการพาธอื่น
การตรวจสอบข้อมูลประจำตัวบัญชีและโดเมนเวิร์กสเปซ
ขอทั้ง openid email พร้อมกับขอบเขตการดำเนินการที่ไคลเอนต์ต้องการ เรียก userinfo_endpoint ที่ค้นพบ (GET /v1/oauth/userinfo) ด้วยโทเค็นการเข้าถึงในส่วนหัว Bearer การตอบกลับที่สำเร็จประกอบด้วย:
{
"sub": "123",
"email": "person@example.com",
"email_verified": true,
"name": "Example User",
"org_id": 456
}sub คือตัวระบุผู้ใช้แบบคงที่ ส่วน org_id คือองค์กรที่เลือกไว้ระหว่างการให้ความยินยอม ปลายทางนี้ต้องมีขอบเขตข้อมูลประจำตัวทั้งสองรายการ และจะส่งกลับ 403 หากไม่มีรายการใดรายการหนึ่ง จะส่งกลับ 403 พร้อม error=access_denied หากบัญชีไม่มีโปรไฟล์อีเมลที่ยืนยันแล้ว แทนที่จะยืนยันว่าอีเมลที่ยังไม่ได้ยืนยันนั้นเชื่อถือได้ โทเค็นที่ไม่ถูกต้อง หมดอายุ ถูกเพิกถอน หรือมีผู้รับไม่ถูกต้องจะส่งกลับ 401 โทเค็นเซสชันของผู้ใช้และคีย์ API ขององค์กรไม่สามารถเรียก userinfo ได้ ไม่มีการออก ID token
สิทธิ์ที่ใช้ได้
| กลุ่ม | ขอบเขตสิทธิ์ |
|---|---|
| เอเจนต์และการนำเข้าเอเจนต์ | agents:read, agents:write |
| การโทร | calls:read, calls:write |
| หมายเลขโทรศัพท์และ VoIP | numbers:read, numbers:write |
| ฐานความรู้ | knowledge:read, knowledge:write |
| แคมเปญ | campaigns:read, campaigns:write |
| การผสานรวม ปลายทาง webhook เซิร์ฟเวอร์ MCP | integrations:read, integrations:write |
| เสียง | voices:read |
| สถานการณ์ทดสอบ การทดสอบ และการตรวจสอบความถูกต้อง | testing:read, testing:write |
| การเรียกเก็บเงิน | billing:read |
| ข้อมูลระบุตัวตนของบัญชีและอีเมลที่ยืนยันแล้ว | openid, email (ต้องใช้ทั้งคู่สำหรับ userinfo) |
| การเชื่อมต่อแบบต่อเนื่อง | offline_access (รวมไว้เสมอ) |
GET, HEAD และ OPTIONS ใช้ขอบเขตสิทธิ์อ่าน เมธอดอื่นใช้ขอบเขตสิทธิ์เขียน การเปลี่ยนแปลงข้อมูลเสียงและการเรียกเก็บเงินไม่พร้อมใช้งานผ่าน OAuth ส่วน POST /v1/voices/preview ใช้ voices:read เพราะเป็นการแสดงตัวอย่างเสียงโดยไม่เปลี่ยนการกำหนดค่า เครื่องมือ MCP บังคับใช้ขอบเขตสิทธิ์ของการดำเนินการ REST ที่รองรับ การโอนข้ามองค์กรจะถูกปฏิเสธ แม้ว่าผู้ใช้ที่อนุญาตจะอยู่ในทั้งสององค์กรก็ตาม กลุ่ม API อื่น รวมถึงการจัดการ API key และการตั้งค่าบัญชีของผู้ใช้ ไม่พร้อมใช้งานผ่าน OAuth หากการดำเนินการ REST ไม่มีสิทธิ์ที่จำเป็น ระบบจะส่งคืน 403 พร้อม WWW-Authenticate: Bearer error="insufficient_scope", scope="..." โทเค็นการเข้าถึงที่ไม่ถูกต้องหรือหมดอายุจะส่งคืน 401
สัญญาณการตรวจสอบสิทธิ์ของเครื่องมือ MCP
ทุกเครื่องมือใน tools/list มี securitySchemes: [{"type": "oauth2", "scopes": ["agents:read"]}] โดยใช้ขอบเขตสิทธิ์ของการดำเนินการ REST ของเครื่องมือนั้น เครื่องมือเอกสารสาธารณะใช้รายการขอบเขตสิทธิ์ว่างเปล่าและยังคงต้องมีการเชื่อมต่อที่ผ่านการตรวจสอบสิทธิ์
โทเค็นที่ถูกต้องแต่ไม่มีขอบเขตสิทธิ์ของเครื่องมือจะได้รับ HTTP 200 พร้อม JSON-RPC result ที่มี isError: true ข้อความอธิบายใน content และ _meta["mcp/www_authenticate"] ส่วนหลังเป็นอาร์เรย์ที่มีคำขอท้าทายแบบ Bearer พร้อม resource_metadata, error="insufficient_scope", error_description และ scope ที่จำเป็น เครื่องมือจะไม่ถูกดำเนินการ ใช้คำขอท้าทายนี้เพื่อขอความยินยอมเพิ่มเติม การตรวจสอบสิทธิ์ที่หายไปหรือไม่ถูกต้องจะยังคงส่งคืน HTTP 401 พร้อม WWW-Authenticate ส่วนความล้มเหลวของขอบเขตสิทธิ์ REST จะยังคงส่งคืน HTTP 403
การเก็บรักษาข้อมูลรับรอง
API รัน python manage.py oauth_cleanup ทุกชั่วโมงใน staging และ production โดยจะลบคำขออนุญาตและรหัสอุปกรณ์ที่หมดอายุ โทเค็นการเข้าถึง รหัสอนุญาต และแฮชของ refresh token ที่หมดอายุจะถูกตัดออกก็ต่อเมื่อการให้สิทธิ์ถูกเพิกถอน หรือตระกูลโทเค็นทั้งหมดใช้งานไม่ได้แล้ว แฮชที่ใช้แล้วจะถูกเก็บไว้ตราบใดที่ตระกูลนั้นยังมี refresh token รหัสอนุญาต รหัสอุปกรณ์ที่อนุมัติแล้ว หรือโทเค็นการเข้าถึงที่ใช้งานได้ เพื่อให้การล้างข้อมูลไม่สามารถปิดใช้การตรวจจับการนำกลับมาใช้ซ้ำได้