Comet Opik

ทางการ

สอบถามและวิเคราะห์ Opik logs, traces, prompts และข้อมูลเทเลเมทรีอื่นๆ ทั้งหมดจาก LLMs ของคุณด้วยภาษาธรรมชาติ

คุณทำอะไรได้บ้างด้วย Comet Opik MCP?

  • ค้นหาร่องรอยตามโปรเจกต์ — ถามว่าร่องรอยใดในโปรเจกต์ล้มเหลววันนี้ โดยกรองตามข้อมูลข้อผิดพลาด ระยะเวลา หรือการใช้โทเค็นได้
  • อ่านเอนทิตี Opik ใดก็ได้ — ดึงข้อมูลโปรเจกต์ ร่องรอย สแปน ชุดข้อมูล การทดลอง พรอมป์ต์ เธรด หรือปัญหา Diagnostics ด้วย id ชื่อ หรือ URI opik://
  • บันทึกคะแนนและความคิดเห็น — ให้คะแนนร่องรอยตามเมตริกความคิดเห็นพร้อมระบุเหตุผล หรือเพิ่มความคิดเห็นผ่านเครื่องมือเขียนข้อมูล
  • บันทึกเวอร์ชันพรอมป์ต์ — สร้างและจัดเก็บเวอร์ชันพรอมป์ต์ใหม่ควบคู่กับชุดข้อมูลและการทดลอง
  • ตรวจสอบสคีมาการเขียนข้อมูล — ขอรับสคีมาของการดำเนินการเขียนข้อมูลเพื่อสร้างเพย์โหลดที่ถูกต้องก่อนส่ง
  • ตรวจสอบสถานะโปรเจกต์ — อ่านข้อมูลโปรเจกต์เพื่อดูจำนวนร่องรอย อัตราข้อผิดพลาด ระยะเวลาเฉลี่ย และค่าใช้จ่ายรวมในช่วง 7 วันที่ผ่านมา

เอกสาร

Opik MCP Server

เซิร์ฟเวอร์ Model Context Protocol (MCP) อย่างเป็นทางการสำหรับ Opik แพลตฟอร์มโอเพนซอร์สสำหรับการสังเกตการณ์และประเมินผล LLM ที่สร้างโดย Comet เชื่อมต่อโฮสต์ AI ของคุณ (Claude Code, Cursor, VS Code Copilot, Codex, opencode หรือไคลเอ็นต์ MCP ใดก็ได้) เข้ากับเวิร์กสเปซ Opik โดยตรง: อ่าน trace บันทึกคะแนน และบันทึกเวอร์ชันพรอมป์ต์ ทั้งหมดจากแชต

สร้างขึ้นสำหรับวิศวกร LLM ที่ใช้งาน Opik อยู่แล้วและต้องการควบคุมการทำงานผ่านผู้ช่วย AI ตัวเดียวกับที่ใช้เขียนโค้ด

You:    "Which traces in project 'demo' failed today?"
Claude: → list(entity_type="trace", project_name="demo") → "Three traces failed…"

You:    "Score trace 7f2e… 0.9 on helpfulness with reason 'great recovery'."
Claude: → write(score.create) → done

เริ่มต้นอย่างรวดเร็ว

คำสั่งเดียวตั้งค่า Opik ในไคลเอ็นต์ AI บนเครื่องของคุณ รวมถึง Claude Code โดยจะค้นหา Opik ของคุณ (ตัวที่บันทึกไว้ใน ~/.opik.config ตัวที่ทำงานอยู่บน localhost หรือถามว่าต้องการใช้ตัวใด) ลงทะเบียนเซิร์ฟเวอร์ MCP ติดตั้งชุดทักษะ Opik และตรวจสอบการเชื่อมต่อ สำหรับ Opik Cloud ไม่ต้องจัดการ API key: ไคลเอ็นต์ของคุณลงชื่อเข้าใช้ผ่านเบราว์เซอร์ ต้องใช้ uv และไม่ต้องใช้ Opik SDK:

uvx opik@latest mcp configure

หากไม่มีเทอร์มินัล เช่น ใช้งานจาก coding agent หรือสคริปต์ ให้ระบุชื่อไคลเอ็นต์:

uvx opik@latest mcp configure --ai-client claude-code --skills

--ai-client ยังรับ codex, cursor, vscode และ opencode ด้วย เมื่อเรียกใช้ในลักษณะนี้ ระบบจะใช้ Opik ที่บันทึกไว้ใน ~/.opik.config ซึ่งรวม API key ไว้ด้วย หรือใช้ตัวที่ตอบสนองบน localhost หากไม่มีทั้งสองอย่าง ระบบจะหยุดและถามหา --deployment

coding agent ที่ได้รับคำขอให้ "install opik mcp" จะได้รับขั้นตอนทั้งหมด รวมถึงสิ่งที่ต้องถามผู้ใช้ จาก uvx opik-mcp@latest --help ซึ่งเหมือนกับ ติดตั้งด้วย coding agent ด้านล่าง

การลงทะเบียนเซิร์ฟเวอร์ด้วยตนเองโดยใช้คำสั่งของไคลเอ็นต์ใน ตั้งค่าด้วยตนเอง จะข้ามการตรวจสอบว่าคุณใช้ Opik ตัวใดและไม่ติดตั้งชุดทักษะ จึงเหมาะสำหรับไคลเอ็นต์ที่ตัวติดตั้งไม่รองรับ

Opik ของคุณเซิร์ฟเวอร์การขนส่งการลงชื่อเข้าใช้
Opik Cloud (www.comet.com)เซิร์ฟเวอร์ที่โฮสต์ไว้ ซึ่ง Comet เป็นผู้ดูแลStreamable HTTPผ่านเบราว์เซอร์ (OAuth); ไม่ต้องใช้ API key
Comet แบบโฮสต์เอง, Opik โอเพนซอร์สเซิร์ฟเวอร์ภายในเครื่อง ซึ่งเป็นแพ็กเกจนี้stdioenv vars; ใช้ API key เฉพาะเมื่อการติดตั้งใช้งานกำหนดให้ต้องใช้

ไคลเอ็นต์จะโหลดเซิร์ฟเวอร์ MCP เมื่อเริ่มเซสชัน ดังนั้นให้เริ่มเซสชันใหม่หลังจากนั้น

คู่มือการตั้งค่า การแก้ไขปัญหา และคำถามที่พบบ่อย: comet.com/docs/opik/mcp-server


Opik Cloud: เซิร์ฟเวอร์ที่โฮสต์ไว้

Comet ดูแลเซิร์ฟเวอร์ที่ https://www.comet.com/opik/api/v1/mcp ไคลเอ็นต์ของคุณเชื่อมต่อผ่าน HTTP และเปิดเบราว์เซอร์ให้ลงชื่อเข้าใช้ในครั้งแรก ไม่ต้องติดตั้งอะไร ไม่ต้องใช้ API key และไม่ต้องตั้งค่าเวิร์กสเปซ: เซิร์ฟเวอร์จะทำงานในเวิร์กสเปซที่คุณเลือกเมื่อลงชื่อเข้าใช้ หลังจากเพิ่มแล้ว ให้เริ่มเซสชันใหม่และถามว่า "list my Opik projects"

คำสั่ง เริ่มต้นอย่างรวดเร็ว จะตั้งค่านี้ให้ Claude Code, Codex, Cursor, VS Code Copilot และ opencode พร้อมติดตั้งชุดทักษะ ใน Claude Code ปลั๊กอิน ทำสิ่งเดียวกันได้ด้วยคำสั่งเดียว ปุ่มด้านล่างเพิ่มเซิร์ฟเวอร์ให้ Cursor หรือ VS Code ได้ในคลิกเดียว ส่วนวิธีอื่นในการลงทะเบียนด้วยตนเองอยู่ในหัวข้อ ตั้งค่าด้วยตนเอง

Add to Cursor Install in VS Code

ปลั๊กอิน Claude Code

ปลั๊กอิน opik ติดตั้งทักษะ Opik และลงทะเบียนเซิร์ฟเวอร์ MCP ที่โฮสต์ไว้สำหรับ Opik Cloud:

/plugin install opik --marketplace comet-ml/opik-mcp

สำหรับ Claude Code เวอร์ชันก่อน 2.1.275 ให้เรียกใช้ /plugin marketplace add comet-ml/opik-mcp แล้วตามด้วย /plugin install opik@opik ทักษะจะโหลดเป็น opik:<skill> เช่น opik:opik-instrument และ /mcp จะแสดงเซิร์ฟเวอร์เป็น plugin:opik:opik-cloud เซิร์ฟเวอร์นี้เป็นของ Opik Cloud เริ่มเซสชันใหม่ แล้วลงชื่อเข้าใช้จาก /mcp → Authenticate สำหรับ Comet แบบโฮสต์เองที่ใช้งานเซิร์ฟเวอร์ MCP OAuth ให้เพิ่มด้วย claude mcp add --transport http opik-mcp https://<host>/opik/api/v1/mcp; สำหรับ Opik แบบโฮสต์เองหรือโอเพนซอร์สประเภทอื่น ให้ใช้คำสั่ง เริ่มต้นอย่างรวดเร็ว จากนั้นปิดใช้ plugin:opik:opik-cloud ใน /mcp Claude Code จะไม่อัปเดตปลั๊กอินจากมาร์เก็ตเพลสนี้โดยอัตโนมัติ: ให้เรียกใช้ /plugin marketplace update opik แล้วตามด้วย /plugin update opik@opik หรือเปิดการอัปเดตอัตโนมัติสำหรับมาร์เก็ตเพลสใน /plugin มาร์เก็ตเพลสนี้ให้บริการ main ซึ่งอาจใหม่กว่ารีลีสล่าสุด การอัปเดตจะมาถึงเมื่อเวอร์ชันของปลั๊กอินเปลี่ยนแปลงในแต่ละรีลีสเท่านั้น

หากคุณเคยเพิ่ม opik-mcp ที่ URL เดียวกันไว้ก่อน Claude Code จะเก็บรายการของคุณไว้และข้ามรายการของปลั๊กอิน หากรายการของคุณเป็นเซิร์ฟเวอร์อื่น เช่น uvx opik-mcp ภายในเครื่อง ทั้งสองรายการจะโหลด: เรียกใช้ claude mcp remove opik-mcp เพื่อเก็บไว้เฉพาะรายการของปลั๊กอิน ทักษะจากชุดทักษะจะโหลดควบคู่ไปกับสำเนาของปลั๊กอินด้วย; ลบออกได้ด้วย npx skills remove --global --agent claude-code ซึ่งจะถามว่าต้องการลบรายการใด


Opik แบบโฮสต์เองและโอเพนซอร์ส: เซิร์ฟเวอร์ภายในเครื่อง

opik-mcp ทำงานบนเครื่องของคุณ: ไคลเอ็นต์จะเริ่มทำงานด้วย uvx opik-mcp และสื่อสารกับเซิร์ฟเวอร์ผ่าน stdio คำสั่ง เริ่มต้นอย่างรวดเร็ว จะตั้งค่าจาก ~/.opik.config หรือ Opik ภายในเครื่องของคุณ หากต้องการลงทะเบียนด้วยตนเอง โปรดดู ตั้งค่าด้วยตนเอง ติดตั้ง uv เพียงครั้งเดียว; ในการใช้งานครั้งแรก ระบบจะดาวน์โหลดแพ็กเกจและ Python 3.13 หากจำเป็น:

curl -LsSf https://astral.sh/uv/install.sh | sh   # macOS / Linux
# or: brew install uv

uvx opik-mcp ใช้สำเนาที่ uv แคชไว้ซ้ำ จึงเริ่มทำงานได้รวดเร็ว; uv cache clean opik-mcp ทำให้การเริ่มครั้งถัดไปดาวน์โหลดรีลีสล่าสุด uvx opik-mcp@latest จะตรวจสอบ PyPI ทุกครั้งที่เริ่มทำงาน ซึ่งเพิ่มเวลาประมาณหนึ่งวินาทีครึ่ง Codex รอ mcp_optional_startup_grace_ms (ค่าเริ่มต้น 1 s) ให้เซิร์ฟเวอร์ก่อนสร้างรายการเครื่องมือชุดแรก ดังนั้นหากเริ่มทำงานช้า เครื่องมืออาจไม่ปรากฏในเทิร์นแรก คำสั่งแบบใช้ครั้งเดียวใน README นี้ (opik mcp configure, opik mcp status, --help, --check) มี @latest จึงไม่เรียกใช้สำเนาที่ uv แคชไว้นานหลายเดือน

env vars ใช้ระบุ Opik ให้เซิร์ฟเวอร์:

Opik ของคุณEnv vars
Opik โอเพนซอร์สบนเครื่องนี้OPIK_URL=http://localhost:5173/api
Opik โอเพนซอร์สบนเซิร์ฟเวอร์OPIK_URL=https://<host>/api และ OPIK_API_KEY เฉพาะเมื่อการติดตั้งใช้งานเพิ่มการยืนยันตัวตน
แพลตฟอร์ม Comet แบบโฮสต์เอง (UI ของ Opik อยู่ที่ https://<host>/opik)COMET_URL_OVERRIDE=https://<host>, OPIK_WORKSPACE, OPIK_API_KEY
  • โอเพนซอร์สให้บริการ API ที่ /api และมีเวิร์กสเปซเดียวคือ default จึงไม่ต้องใช้ OPIK_WORKSPACE ส่วน COMET_URL_OVERRIDE จะชี้เซิร์ฟเวอร์ไปที่ /opik/api ซึ่งโอเพนซอร์สไม่ได้ให้บริการ
  • Comet แบบโฮสต์เองมีเวิร์กสเปซที่ตั้งชื่อไว้ กำหนด OPIK_WORKSPACE เป็นส่วนที่อยู่ถัดจาก /opik/ ใน URL ของ Opik หากไม่ระบุ การอ่านข้อมูลจะใช้เวิร์กสเปซเริ่มต้นของบัญชี โดยไม่มีข้อผิดพลาดแจ้งให้ทราบ
  • Comet แบบโฮสต์เองที่ใช้งานเซิร์ฟเวอร์ MCP OAuth (ปิดไว้โดยค่าเริ่มต้น) สามารถใช้ขั้นตอนการโฮสต์แทนได้ที่ https://<host>/opik/api/v1/mcp
  • แทนค่าทุกค่า เซิร์ฟเวอร์จะปฏิเสธเวิร์กสเปซตัวอย่าง เช่น <your-workspace> หรือ ${input:OPIK_WORKSPACE}; URL ตัวอย่างจะถูกส่งไปตามเดิมและเชื่อมต่อไม่สำเร็จ
  • OPIK_MCP_ANALYTICS_SOURCE="" ในบล็อก env ใช้ยกเลิกการติดป้ายแหล่งที่มาของ cloud-Comet ในเหตุการณ์ telemetry สำหรับการติดตั้งแบบโฮสต์เอง

ก่อนเพิ่มเซิร์ฟเวอร์ให้ไคลเอ็นต์ ให้ตรวจสอบการตั้งค่าโดยเรียกใช้เซิร์ฟเวอร์ด้วย env และ --check เดียวกัน เซิร์ฟเวอร์จะเรียก Opik หนึ่งครั้งและพิมพ์ชื่อเวิร์กสเปซกับจำนวนโปรเจกต์ที่พบ หรือแจ้งสิ่งที่ต้องแก้ไขพร้อมลิงก์ไปยังเอกสาร จากนั้นออกด้วยรหัส 0 หรือ 1 ไคลเอ็นต์ไม่สามารถแจ้งเรื่องนี้ให้คุณทราบก่อนเริ่มเซสชันใหม่ได้: Claude Code แสดงสถานะ Connected แม้ใช้คีย์ผิด และ Codex จะยังไม่เริ่มอะไรจนกว่าจะถึงตอนนั้น

OPIK_URL=http://localhost:5173/api uvx opik-mcp@latest --check

จากนั้นลงทะเบียนกับไคลเอ็นต์ของคุณ: เซิร์ฟเวอร์ภายในเครื่อง ตั้งค่าด้วยตนเอง


ติดตั้งด้วย coding agent

สำหรับ AI agent ที่ได้รับคำขอให้ติดตั้งเซิร์ฟเวอร์ เช่น "install opik mcp" เป้าหมายคือการลงทะเบียนเซิร์ฟเวอร์สำหรับ Opik ของผู้ใช้ ติดตั้งชุดทักษะ Opik และให้ผู้ใช้ลงชื่อเข้าใช้ ตรวจสอบว่าเครื่องนี้ใช้ Opik ตัวใด และถามผู้ใช้เฉพาะสิ่งที่คุณตรวจสอบเองไม่ได้เท่านั้น: ถามหนึ่งคำถามต่อข้อความ และรอคำตอบแต่ละข้อก่อนถามข้อต่อไป ตัวติดตั้งในขั้นตอนที่ 3 จะตั้งค่าทั้งหมดในการเรียกใช้ครั้งเดียว ดังนั้นให้จัดการขั้นตอนที่ 1 และ 2 ให้เรียบร้อยก่อนเรียกใช้ uvx opik-mcp@latest --help จะแสดงขั้นตอนเหล่านี้

  1. ตรวจสอบว่ามีอะไรอยู่บ้าง

    uvx opik@latest mcp status
    

    คำสั่งนี้แสดง Opik ที่บันทึกไว้ใน ~/.opik.config (URL และเวิร์กสเปซ โดยไม่แสดงคีย์) และไคลเอ็นต์ที่ลงทะเบียนเซิร์ฟเวอร์ไว้แล้ว ใน Claude Code ให้เรียกใช้ claude mcp list ด้วย: คำสั่งนี้แสดงตัวเชื่อมต่อ claude.ai และรายการที่ใช้ชื่ออื่น นอกจากนี้ยังพิมพ์คำสั่งของแต่ละรายการ ซึ่งสำหรับรายการ npx เก่าอาจมี API key อยู่ด้วย: อย่านำค่านั้นไปแสดงซ้ำ

    • หากมีเซิร์ฟเวอร์สำหรับ https://www.comet.com/opik/api/v1/mcp ไม่ว่าจะใช้ชื่อใด เช่น ตัวเชื่อมต่อ claude.ai แสดงว่าลงทะเบียนไว้แล้ว: อย่าเพิ่มรายการที่สอง ให้ติดตั้งชุดทักษะเพียงอย่างเดียวด้วย npx skills add comet-ml/opik-skills -g --all หากเซิร์ฟเวอร์แสดง ! Needs authentication ให้ไปขั้นตอนที่ 4
    • ตัวติดตั้งจะแทนที่รายการ opik-mcp ที่มีอยู่โดยไม่ถาม เช่น รายการสำหรับเซิร์ฟเวอร์ npx รุ่นเก่า ให้ถามผู้ใช้ก่อนเรียกใช้
  2. ค้นหา Opik ของผู้ใช้

    • บันทึกไว้ใน ~/.opik.config: ใช้รายการนั้นและแจ้งผู้ใช้ว่าคุณกำลังตั้งค่ารายการใด ตัวติดตั้งจะอ่านค่าดังกล่าว รวมถึง API key ด้วย จึงไม่ต้องถามหาคีย์
    • ไม่มี ~/.opik.config: curl -s http://localhost:5173/api/is-alive/ping คำตอบที่ได้หมายถึงมี Opik โอเพนซอร์สอยู่บนเครื่องนี้ ใน shell ที่ถูกจำกัด เช่นของ Codex การไม่มีคำตอบอาจหมายถึง shell ไม่มีเครือข่าย ไม่ใช่ไม่มี Opik
    • ไม่มีทั้งสองอย่าง: ให้ถามและอย่าเลือกเอง URL ของ Opik ในโปรเจกต์ เช่น OPIK_URL_OVERRIDE ใน .env ทำให้ถามแบบใช่หรือไม่ใช่ได้ หากไม่มี ให้ถามว่า: "คุณใช้ Opik ตัวใด: Opik Cloud (www.comet.com), Opik โอเพนซอร์ส (URL ของบริการ) หรือแพลตฟอร์ม Comet แบบโฮสต์เอง (URL และเวิร์กสเปซ)?"
  3. เรียกใช้ตัวติดตั้ง สำหรับไคลเอ็นต์ที่คุณกำลังใช้งาน ตัวติดตั้งจะติดตั้งชุดทักษะ Opik พร้อมกับเซิร์ฟเวอร์ ไม่ว่าจะมี --skills หรือไม่ก็ตาม; ให้คงแฟล็กนี้ไว้ในคำสั่งที่คุณให้ผู้ใช้เรียกใช้ภายหลัง สำหรับ Opik Cloud ตัวติดตั้งจะเปิดเบราว์เซอร์ให้ลงชื่อเข้าใช้และรอหนึ่งนาที ดังนั้นให้แจ้งผู้ใช้ก่อน

    uvx opik@latest mcp configure --ai-client claude-code --skills
    

    --ai-client ยังรับ codex, cursor, vscode และ opencode ด้วย หาก Opik บันทึกไว้ใน ~/.opik.config หรือทำงานอยู่บน localhost ให้เรียกใช้ตามเดิม: --deployment จะเก็บการตั้งค่าที่บันทึกไว้แยกไว้ รวมถึง API key ด้วย หากไม่มีทั้งสองอย่าง ให้เพิ่มแฟล็กสำหรับ Opik ที่ผู้ใช้ระบุในขั้นตอนที่ 2:

    Opik ของผู้ใช้เพิ่ม
    Opik Cloud, www.comet.com--deployment cloud
    Opik โอเพนซอร์ส--deployment local และ --url <url> เมื่อไม่ได้อยู่บน localhost
    แพลตฟอร์ม Comet แบบโฮสต์เอง โดยมี /opik/ ใน URL--deployment self-hosted --url <url> --workspace <workspace> พร้อมกำหนด OPIK_API_KEY ใน shell

    หากคำสั่งล้มเหลว เช่น Opik ไม่ตอบสนอง ให้แจ้งผู้ใช้ว่าคำสั่งแสดงอะไรและควรตรวจสอบอะไร เช่น VPN หรือ URL อย่าสลับไปใช้ Opik ตัวอื่น

  4. ลงชื่อเข้าใช้สำหรับ Opik Cloud หากตัวติดตั้งแจ้งว่าเซิร์ฟเวอร์ยังไม่ได้ลงชื่อเข้าใช้ ให้ผู้ใช้เรียกใช้ claude mcp login opik-mcp หรือ /mcp ในเซสชัน Claude Code แทนการเรียกใช้เอง เพราะคำสั่งจะรอให้ดำเนินการผ่านเบราว์เซอร์ ตัวเชื่อมต่อ claude.ai ลงชื่อเข้าใช้จาก /mcp ขั้นตอนลงชื่อเข้าใช้จะถามหาเวิร์กสเปซ; หากมีเวิร์กสเปซบันทึกไว้ใน ~/.opik.config ให้ระบุชื่อนั้น

  5. ดำเนินการให้เสร็จ แจ้งว่าติดตั้งอะไรแล้วและยังเหลืออะไรบ้าง ระบุชื่อชุดทักษะ: ทักษะ Opik ซึ่งติดตั้งสำหรับทุกโปรเจกต์ และสอน agent ให้เพิ่ม instrumentation ประเมินผล และแก้ไขข้อบกพร่องด้วย Opik ไคลเอ็นต์จะโหลดเซิร์ฟเวอร์ MCP และทักษะเมื่อเริ่มเซสชัน: ขอให้ผู้ใช้เริ่มเซสชันใหม่ แล้วลองถามว่า "list my Opik projects"

ไม่ว่าจะใช้ขั้นตอนใด:

  • อย่าขอให้ผู้ใช้วาง API key ในแชต เซิร์ฟเวอร์ที่โฮสต์ไว้ไม่ต้องใช้คีย์; หากจำเป็น ให้ดึงจากสภาพแวดล้อมของ shell ("$OPIK_API_KEY") หรือให้ผู้ใช้เรียกใช้คำสั่งเอง

  • อย่าเดาเวิร์กสเปซ โดยเป็นส่วนที่อยู่ถัดจาก comet.com/opik/ (หรือ /opik/ สำหรับ Comet แบบโฮสต์เอง) ใน URL ของ Opik ของผู้ใช้

  • อย่าพิมพ์ ~/.claude.json หรือ ~/.opik.config: ทั้งสองค่าอาจมี API key อยู่ uvx opik@latest mcp status และ claude mcp list จะแสดงข้อมูลที่จำเป็น และตัวติดตั้งจะอ่านการตั้งค่าเอง

  • หากการตรวจสอบสิทธิ์ขัดขวางคำสั่ง อย่าหาทางเลี่ยง ให้คำสั่งแก่ผู้ใช้เพื่อเรียกใช้เอง (ใน Claude Code ให้ใช้ ! ก่อนเรียกใช้จากพรอมป์ต์) สำหรับไคลเอนต์ที่ตัวติดตั้งไม่รู้จัก ให้ลงทะเบียนด้วยตนเองโดยใช้คำสั่งใน ตั้งค่าด้วยตนเอง: ใช้เซิร์ฟเวอร์โฮสต์สำหรับ Opik Cloud และ เซิร์ฟเวอร์ภายในเครื่องสำหรับกรณีอื่น

  • ก่อนลงทะเบียนเซิร์ฟเวอร์ภายในเครื่อง ให้เรียกใช้ด้วย env ที่จะส่งให้และ --check โดย export OPIK_API_KEY ใน shell แทนการเขียนไว้ใน คำสั่ง: OPIK_URL=http://localhost:5173/api uvx opik-mcp@latest --check คำสั่งนี้จะออกด้วยรหัส 0 และระบุ workspace ที่ตรวจพบ หรือแจ้งสิ่งที่ต้องแก้ไข เมื่อลงทะเบียนแล้ว Claude Code จะแสดง Connected แม้ใช้คีย์ผิด ส่วน Codex ไม่มีการตรวจสอบ

  • Claude Code ไม่ยอมเพิ่มทับรายการ opik-mcp ที่มีอยู่แล้ว จึงต้องลบออก ก่อนด้วย claude mcp remove opik-mcp --scope user; ส่วน add ของ Codex จะแทนที่ รายการเดิม

  • หลังลงทะเบียนแล้ว ใน Claude Code ให้อ่านเฉพาะบรรทัดสถานะ: claude mcp get opik-mcp | grep Status ผลลัพธ์ฉบับเต็มจะแสดงบล็อก env ซึ่งมี API key รวมอยู่ด้วย เซิร์ฟเวอร์โฮสต์จะแสดง ! Needs authentication จนกว่าจะเรียกใช้ claude mcp login opik-mcp ส่วน Codex ไม่มีคำสั่งที่เริ่ม เซิร์ฟเวอร์ก่อนเริ่มเซสชัน; codex mcp get opik-mcp แสดงสิ่งที่บันทึกไว้ โดยปกปิดค่า env


ตั้งค่าด้วยตนเอง (ไม่ตรวจสอบ Opik และไม่มี skill pack)

คำสั่ง เริ่มต้นอย่างรวดเร็ว ทำทุกอย่างนี้ให้กับ Claude Code, Codex, Cursor, VS Code Copilot และ opencode รวมถึงตรวจสอบว่าคุณใช้ Opik แบบใดและ ติดตั้ง skill pack ด้วย ให้ลงทะเบียนด้วยตนเองเฉพาะเมื่อใช้ไคลเอนต์อื่น หรือต้องการดูว่าตัวติดตั้งเขียนอะไรไว้ เอเจนต์เขียนโค้ดที่ติดตั้งให้ผู้ใช้ ให้เรียกใช้ตัวติดตั้ง: ดู ติดตั้งด้วยเอเจนต์เขียนโค้ด

เซิร์ฟเวอร์โฮสต์ (Opik Cloud)

Claude Code ด้วยตนเอง

claude mcp add --scope user --transport http opik-mcp https://www.comet.com/opik/api/v1/mcp

จากนั้นลงชื่อเข้าใช้จาก /mcp → Authenticate ในเซสชัน Claude Code ระบบจะเปิด เบราว์เซอร์ให้ผู้ที่อยู่หน้าแป้นพิมพ์ดำเนินการเอง; หากใช้เทอร์มินัลของตนเอง claude mcp login opik-mcp จะทำแบบเดียวกัน --scope user ทำให้เซิร์ฟเวอร์พร้อมใช้งานในทุกโปรเจกต์; หากไม่มี ตัวเลือกนี้ Claude Code จะลงทะเบียนเซิร์ฟเวอร์ไว้เฉพาะไดเรกทอรีปัจจุบัน เมื่อใช้ SSH claude mcp login opik-mcp --no-browser จะแสดง URL สำหรับลงชื่อเข้าใช้เพื่อเปิดบน เครื่องของคุณเอง; ขั้นตอนสุดท้ายต้องใช้เทอร์มินัลแบบโต้ตอบ (ssh -t)

Codex ด้วยตนเอง

codex mcp add opik-mcp --url https://www.comet.com/opik/api/v1/mcp

add เปิดหน้าลงชื่อเข้าใช้; codex mcp login opik-mcp เปิดหน้าเดิมอีกครั้ง ใน ~/.codex/config.toml เซิร์ฟเวอร์เดียวกันมีรูปแบบดังนี้:

[mcp_servers.opik-mcp]
url = "https://www.comet.com/opik/api/v1/mcp"

Cursor ด้วยตนเอง

ใช้ปุ่มใต้ เซิร์ฟเวอร์โฮสต์ หรือเพิ่มลงใน ~/.cursor/mcp.json:

{
  "mcpServers": {
    "opik-mcp": {
      "url": "https://www.comet.com/opik/api/v1/mcp"
    }
  }
}

VS Code Copilot ด้วยตนเอง

ใช้ปุ่มใต้ เซิร์ฟเวอร์โฮสต์ หรือเพิ่มลงใน .vscode/mcp.json ใน workspace หรือใน mcp.json ของผู้ใช้ (MCP: Open User Configuration):

{
  "servers": {
    "opik-mcp": {
      "type": "http",
      "url": "https://www.comet.com/opik/api/v1/mcp"
    }
  }
}

ไคลเอนต์อื่น

ไคลเอนต์ใดก็ตามที่รับ URL ได้ สามารถใช้เซิร์ฟเวอร์โฮสต์ได้:

npx add-mcp https://www.comet.com/opik/api/v1/mcp --name opik-mcp

ไคลเอนต์ที่เริ่มได้เฉพาะคำสั่งภายในเครื่องสามารถเชื่อมต่อผ่าน npx -y mcp-remote https://www.comet.com/opik/api/v1/mcp

Opik Cloud ด้วย API key

ในกรณีที่ไม่มีใครดำเนินการลงชื่อเข้าใช้ผ่านเบราว์เซอร์ได้ เช่น เมื่อเอเจนต์ ทำงานโดยไม่มีผู้ดูแลจากสคริปต์ หรือไคลเอนต์ไม่รองรับ MCP OAuth ให้ใช้ API key จาก comet.com/api/my/settings/ แทน โดยกำหนดให้ เซิร์ฟเวอร์ภายในเครื่อง เชื่อมต่อกับ Opik Cloud:

claude mcp add --scope user opik-mcp \
  --env OPIK_API_KEY="$OPIK_API_KEY" \
  --env OPIK_WORKSPACE=<workspace> \
  -- uvx opik-mcp

ไคลเอนต์อื่นใช้ตัวแปรสองตัวเดียวกันในบล็อก env ของตน ตั้งค่า OPIK_WORKSPACE เป็นส่วนที่อยู่หลัง comet.com/opik/ ใน URL ของ Opik (https://www.comet.com/opik/acme-ai/projects → acme-ai) หากไม่ระบุ เซิร์ฟเวอร์จะส่ง default ซึ่ง Comet จะจับคู่กับ workspace เริ่มต้น ของบัญชีคุณ ทำให้การอ่านข้อมูลอาจมาจาก workspace ผิดโดยไม่มีข้อผิดพลาด

เซิร์ฟเวอร์ภายในเครื่อง (Opik แบบ self-hosted และโอเพนซอร์ส)

ตัวอย่างใช้ Opik โอเพนซอร์สที่ทำงานในเครื่อง หากใช้ Comet แบบ self-hosted ให้แทนที่ ด้วยตัวแปรสามตัวจาก ตาราง หลังเพิ่มเซิร์ฟเวอร์แล้ว ให้เริ่มเซสชันใหม่ และถามว่า: "list my Opik projects"

Claude Code ด้วยตนเอง

claude mcp add --scope user opik-mcp --env OPIK_URL=http://localhost:5173/api -- uvx opik-mcp

หากใช้ Comet แบบ self-hosted โดยมีคีย์อยู่ใน OPIK_API_KEY ของ shell:

claude mcp add --scope user opik-mcp \
  --env COMET_URL_OVERRIDE=https://<host> \
  --env OPIK_WORKSPACE=<workspace> \
  --env OPIK_API_KEY="$OPIK_API_KEY" \
  -- uvx opik-mcp

หรือแก้ไข ~/.claude.json โดยตรง:

{
  "mcpServers": {
    "opik-mcp": {
      "type": "stdio",
      "command": "uvx",
      "args": ["opik-mcp"],
      "env": {
        "OPIK_URL": "http://localhost:5173/api"
      }
    }
  }
}

claude mcp get opik-mcp แสดง ✔ Connected เมื่อเซิร์ฟเวอร์เริ่มทำงานแล้ว แต่ ไม่ได้ยืนยันว่า URL หรือคีย์ถูกต้อง เพราะมีเพียงการเรียกใช้เครื่องมือเท่านั้นที่เชื่อมต่อกับ Opik; --check (เซิร์ฟเวอร์ภายในเครื่อง) ทำเช่นนั้น นอกจากนี้ยังพิมพ์บล็อก env ซึ่งมี API key รวมอยู่ด้วย

Codex ด้วยตนเอง

codex mcp add opik-mcp --env OPIK_URL=http://localhost:5173/api -- uvx opik-mcp

หรือแก้ไข ~/.codex/config.toml:

[mcp_servers.opik-mcp]
command = "uvx"
args = ["opik-mcp"]
env = { OPIK_URL = "http://localhost:5173/api" }
# On a self-hosted Comet, forward the key from the environment Codex starts in,
# so it stays out of this file:
# env_vars = ["OPIK_API_KEY"]
# Time allowed for the server to start (default 10 s); the first start
# downloads the package.
startup_timeout_sec = 30

Codex ส่งให้เซิร์ฟเวอร์ภายในเครื่องเฉพาะตัวแปรใน env และชื่อใน env_vars เท่านั้น ดังนั้นคีย์ที่ export ไว้ใน shell จะไม่ถูกส่งไปถึงเซิร์ฟเวอร์

Cursor ด้วยตนเอง

เพิ่มลงใน ~/.cursor/mcp.json (ส่วนกลาง) หรือ .cursor/mcp.json (โปรเจกต์) หรือใช้ Cmd+Shift+J → Features → Model Context Protocol:

{
  "mcpServers": {
    "opik-mcp": {
      "type": "stdio",
      "command": "uvx",
      "args": ["opik-mcp"],
      "env": {
        "OPIK_URL": "http://localhost:5173/api"
      }
    }
  }
}

Cursor หมดเวลาใน 60 วินาที Cursor กำหนดเวลาสูงสุดสำหรับการเรียกใช้เครื่องมือ และจะไม่เริ่มนับใหม่เมื่อมีการแจ้งความคืบหน้า ดู ข้อจำกัดที่ทราบของโฮสต์

VS Code Copilot ด้วยตนเอง

เพิ่มลงใน .vscode/mcp.json ใน workspace หรือใน mcp.json ของผู้ใช้ (MCP: Open User Configuration):

{
  "servers": {
    "opik-mcp": {
      "type": "stdio",
      "command": "uvx",
      "args": ["opik-mcp"],
      "env": {
        "OPIK_URL": "http://localhost:5173/api"
      }
    }
  }
}

MCP Inspector (การทดสอบด้วยตนเอง)

OPIK_URL=http://localhost:5173/api npx @modelcontextprotocol/inspector uvx opik-mcp

ย้ายมาจาก npx opik-mcp?

เซิร์ฟเวอร์ TypeScript (npm opik-mcp@2) เลิกใช้งานแล้ว และจะหยุดให้บริการ คำขอในวันที่ 2026-11-15 หากติดตั้งใหม่ ให้เรียกใช้คำสั่ง เริ่มต้นอย่างรวดเร็ว; uvx opik-mcp คือคำสั่งที่ไคลเอนต์ใช้ เพื่อเริ่มเซิร์ฟเวอร์ ไม่ใช่ตัวติดตั้ง หากต้องการย้ายการตั้งค่าที่มีอยู่บน Opik Cloud ให้เปลี่ยนไปใช้เซิร์ฟเวอร์โฮสต์และนำ API key ออก มิฉะนั้น ในการตั้งค่าไคลเอนต์ MCP ให้แทนที่ npx -y opik-mcp ด้วย uvx opik-mcp ตัวแปร env บางตัวเปลี่ยนชื่อ และจะไม่มีการอ่านแฟล็กบรรทัดคำสั่งอีกต่อไป ดูคู่มือ การย้ายระบบ นโยบายการสนับสนุน: DEPRECATED.md ซอร์ส TypeScript อยู่ที่ git tag legacy-typescript-final


เครื่องมือ

opik-mcp มีชุดเครื่องมือขนาดเล็กที่เน้นผลลัพธ์ ครอบคลุมวงจรการทำงานทั้งหมด (อ่าน → ใส่คำอธิบายประกอบ → คัดสรร → สร้าง → ปรับปรุง)

เครื่องมือวัตถุประสงค์
readอ่านข้อมูลทั่วไปด้วย id / name / URI ของ opik://
listแสดงรายการข้อมูลทั่วไป พร้อมตัวกรองชื่อและการแบ่งหน้า (เลือกใช้ได้)
writeเขียนข้อมูลทั่วไป — บันทึก traces/spans, ให้คะแนน, แสดงความคิดเห็น, บันทึก prompts, จัดการ datasets และ experiments
schemaตรวจสอบ schema ของการดำเนินการเขียน (LLM ใช้สร้าง payload ที่ถูกต้อง)
read_skillอ่านหนึ่งในทักษะเอเจนต์ Opik ที่มาพร้อมเซิร์ฟเวอร์นี้

read

เครื่องมือเดียวสำหรับคำถามประเภท "แสดง X ให้ฉันดู" รับ entity_type พร้อมกับ id (UUID หรือชื่อสำหรับประเภทที่ตั้งชื่อได้) หรือ URI opik:// แบบเต็ม การอ่านข้อมูลแบบประกอบ (trace, prompt, thread, agent_insights_issue) จะแสดงข้อมูลย่อยในบรรทัดเดียวกัน เพื่อให้การเรียกใช้ครั้งเดียวแสดงภาพรวมทั้งหมด

ระเบียนที่คุณระบุจะแสดงมาทั้งหมด แต่ข้อมูลย่อยที่แสดงในบรรทัดเดียวกันจะไม่ครบ: เนื้อหาของข้อมูลเหล่านั้นดึงมาด้วย truncate=true ของ backend ดังนั้นฟิลด์ที่มีขนาดเกิน ~10 KB จะถูกตัดใน ClickHouse และรูปภาพ base64 จะถูกแทนที่ด้วย "[image]" — มิฉะนั้นไฟล์แนบเดียวที่แสดงซ้ำใน 200 spans จะมีต้นทุนมากกว่าข้อมูลอื่นทั้งหมดในการอ่าน คำตอบจะแจ้งเรื่องนี้ใน spanBodies / messageBodies และข้อมูลย่อยใด ๆ จะกลับมาแสดงครบได้เมื่อเรียกผ่าน read("span", id) หรือ read("trace", trace_id) ของตัวเอง ซึ่งเรียกใช้ endpoint ที่ไม่มีพารามิเตอร์ truncate เลย

จำนวนข้อมูลในคอลเลกชันที่แสดงในบรรทัดเดียวกันก็มีขีดจำกัดเช่นกัน: 200 spans, 200 turns, 100 prompt versions หากเกินกว่านี้ spansTruncated / messagesTruncated / versionsTruncated จะเป็น true และบรรทัด moreSpans / moreMessages / moreVersions ที่อยู่ข้างกันจะแสดงจำนวนและคำสั่ง list(...) ที่แน่นอน สำหรับดึงข้อมูลต่อจากจุดที่หยุดแสดงในบรรทัดเดียวกัน

เอนทิตีที่รองรับ: project, trace, span, dataset, dataset_item, experiment, prompt, thread, agent_insights_issue การค้นหาด้วยชื่อ รองรับสำหรับ project, experiment, prompt, dataset (ช้ากว่า — ใช้ API สองครั้ง — และอาจพบหลายรายการ) thread และ agent_insights_issue ต้องระบุโปรเจกต์: ส่ง project_id หรือ project_name หรือส่งลิงก์/URI ที่มีโปรเจกต์อยู่ด้วย เดิม dataset และ dataset_item เรียกว่า test_suite และ test_suite_item; ชื่อเดิมยังใช้ได้ แต่จะไม่แสดงเป็นตัวเลือก และโค้ดใหม่ควรใช้ชื่อใหม่

read(entity_type="trace", id="7f2e3c8a-…")
read(entity_type="project", id="demo")  # name lookup
read(entity_type="trace", id="opik://traces/7f2e3c8a-…")
read(entity_type="agent_insights_issue", id="<issue-uuid>", project_id="<project-uuid>")
read(
    entity_type="agent_insights_issue",
    id="https://www.comet.com/opik/<ws>/projects/<pid>/diagnostics?issue=<id>",
)

ลิงก์ที่คัดลอกจาก UI ของ Opik ใช้เป็น id ได้: ลิงก์ thread หรือลิงก์หน้า Diagnostics มีโปรเจกต์อยู่ด้วย จึงไม่ต้องระบุ project_id และระบบจะอ่านประเภทเอนทิตีจากลิงก์

การอ่าน project จะตอบคำถามว่า "โปรเจกต์ของฉันเป็นอย่างไรบ้าง" ได้ในการเรียกครั้งเดียว โดยส่งคืน {project, summary, vocabulary, contains, url}: ระเบียน ตามด้วยตัวเลขสี่รายการที่หน้า Logs แสดงเป็นการ์ด (จำนวน traces, อัตราข้อผิดพลาด, ระยะเวลาเฉลี่ย, ค่าใช้จ่ายรวม) สำหรับ 7 วันล่าสุดเทียบกับ 7 วันก่อนหน้า โดยนับเฉพาะทราฟฟิกจาก SDK เช่นเดียวกับที่แสดงบนหน้าจอ since / until ใช้เลื่อนช่วงเวลา; since="30d" คือช่วงที่ UI เปิดไว้ หากไม่มี traces ในช่วงเวลานั้น อัตราหรือค่าเฉลี่ยจะเป็น null เพราะอัตราข้อผิดพลาด 0% ในสัปดาห์ที่ไม่มีทราฟฟิกไม่ได้หมายความว่าสัปดาห์นั้นมีสุขภาพดี

vocabulary คือแผนผังที่ต้องใช้ก่อนถามเรื่องอื่น: ชื่อ feedback score ของโปรเจกต์, คีย์การใช้โทเค็น และกฎอัตโนมัติที่ให้คะแนน traces ชื่อเหล่านี้ใช้ในตัวกรองหรือใน series= ด้านล่าง หากเดาชื่อเองจะได้หน้าว่างที่ดูเหมือนเป็นข่าวดี จำนวน score และกฎที่แสดงมีขีดจำกัด แต่จะแจ้งจำนวนจริงและระบุคำสั่งสำหรับดึงส่วนที่เหลือ ส่วนคีย์การใช้โทเค็นจะแสดงครบทั้งหมด เพราะไม่มีวิธีอื่นในการไล่ดูรายการเหล่านี้ contains ระบุ experiment, dataset, prompt version และ optimization run ล่าสุด เพื่อให้คำถามว่า "ช่วงนี้เกิดอะไรขึ้นบ้าง" ไม่ต้องเรียกใช้อีกสี่ครั้ง หากโหลดส่วนใดไม่สำเร็จ ระบบจะแจ้งให้ทราบแทนการแสดงเป็นรายการว่าง และจะไม่แสดงส่วนที่ว่าง

การอ่าน agent_insights_issue จะส่งคืน {issue, example_trace_ids, details}: ระเบียนปัญหา Diagnostics (ชื่อ คำอธิบาย สาเหตุ วิธีแก้ที่แนะนำ ความรุนแรง สถานะ), id ของ traces ที่พบปัญหานั้นโดยตัดรายการซ้ำออก (ตัวอย่างเดียวกับที่หน้า Diagnostics แสดง — เปิดรายการหนึ่งด้วย read("trace", id)) และรายละเอียดแยกตามวัน เนื้อหาของ traces จะไม่แสดงในบรรทัดเดียวกัน ดังนั้นการอ่านนี้จึงใช้การเรียก backend เพียงครั้งเดียว since / until ใช้จำกัดแถวรายวัน; ค่าเริ่มต้นคือข้อมูลทั้งหมดตั้งแต่เริ่มต้น เมื่อเซิร์ฟเวอร์ทราบ URL ของ Opik และ workspace ของเซสชัน การอ่านนี้จะแนบ url (หน้า Diagnostics ของปัญหา) และ trace_url_template (ลิงก์โดยตรงไปยัง traces ตัวอย่างรายการใดก็ได้) เพื่อให้ผู้ช่วยส่งลิงก์ที่คลิกได้ให้คุณได้; ในเซสชัน OAuth ที่ไม่สามารถระบุ workspace ได้ ระบบจะไม่แสดงลิงก์แทนการเดา

ตัว traces เองไม่มี URL — ไม่สามารถสร้างลิงก์จากฟิลด์ที่ read หรือ list ส่งคืนได้ และหากเดารูปแบบ URL ก็จะได้ข้อผิดพลาด 404 คำแนะนำของเซสชันจึงระบุเทมเพลตไว้แทน คือ .../v1/session/redirect/projects/?trace_id={trace_id}&path=... เพื่อให้ผู้ช่วยใส่ id แล้วส่งลิงก์ให้คุณ ลิงก์นี้จะผ่าน redirect ของ opik-backend ซึ่งค้นหาโปรเจกต์และ workspace จาก trace จึงใช้ได้ในกรณีที่ URL ของโปรเจกต์โดยตรงใช้ไม่ได้ รวมถึงเซสชัน OAuth ที่ระบุ workspace ไม่ได้ด้วย เป็นลิงก์เดียวกับที่ Python SDK พิมพ์สำหรับ trace

list

เรียกดูหรือค้นหาในคอลเลกชันพร้อมแบ่งหน้า ประเภทที่ต้องระบุโปรเจกต์ (trace, span, thread, agent_insights_issue, dataset_item, prompt_version) ต้องระบุรายการหลักด้วย: UUID หรือชื่อโปรเจกต์, UUID ของ dataset หรือ UUID ของ prompt

list(entity_type="experiment", page=1, size=25)
list(entity_type="experiment", name="rerank")  # name substring filter
list(entity_type="agent_insights_issue", project_name="demo")  # open Diagnostics issues
list(entity_type="agent_insights_issue", project_id="<uuid>", status="resolved")
list(entity_type="trace", project_name="demo")  # latest traces of one project
list(
    entity_type="trace", project_name="demo", filters="error_info is_not_empty AND duration > 5000"
)
list(
    entity_type="span",
    project_name="demo",  # spans across the whole project
    filters='type = "llm" AND usage.total_tokens > 10000',
)
list(
    entity_type="thread",
    project_name="demo",
    filters="number_of_messages > 20 AND feedback_scores.helpfulness < 0.5",
)
list(entity_type="experiment", filters='dataset_id = "<dataset-uuid>" AND tags contains "baseline"')

ตัวกรอง trace, span, thread, experiment และ dataset_item รับ สตริง OQL ซึ่งใช้ไวยากรณ์เดียวกับ search_traces(filter_string=…) ของ SDK:

<field>[.<key>] <op> <value> [AND ...]
ops: = != > >= < <= contains not_contains starts_with ends_with is_empty is_not_empty in not_in

สตริงต้องอยู่ในเครื่องหมายอัญประกาศคู่ ตัวเลขไม่ต้องใส่เครื่องหมาย และ duration มีหน่วยเป็นมิลลิวินาที วันที่เป็นเวลาแบบ ISO-8601 พร้อมเขตเวลา ("2026-09-08T10:00:00Z") คะแนนและพจนานุกรมใช้คีย์: feedback_scores.accuracy < 0.5, metadata.environment = "prod" AND เป็นตัวเชื่อมเพียงตัวเดียว

เช่นเดียวกับหน้า Logs ของ UI รายการ trace, span และ thread จะเพิ่ม source = "sdk" เพื่อไม่ให้ trace จาก evaluator, playground และ experiment รบกวนการดูข้อมูล หากต้องการดู ให้ระบุชื่อ source ด้วยตนเอง บรรทัดแรกของผลลัพธ์จะแสดงตัวกรองที่ใช้

ตัวกรองที่ไม่ถูกต้องจะล้มเหลวก่อนส่งถึง backend พร้อมข้อมูลที่จำเป็นสำหรับแก้ไข: ตำแหน่งของข้อผิดพลาดทางไวยากรณ์ ชื่อฟิลด์ที่ใกล้เคียงที่สุด ตัวดำเนินการที่ใช้ได้สำหรับชนิดของฟิลด์ หรือรูปแบบค่าที่คาดไว้ ฟิลด์ที่มีชุดค่าปิด (source, span type, thread status, visibility_mode) จะถูกตรวจสอบ เทียบกับชุดค่านั้นด้วย รวมถึงทุกองค์ประกอบในรายการ in ด้วย source เป็นรายการเดียวที่ backend ตรวจสอบเอง และเมื่อตอบค่าที่ไม่รู้จัก จะส่ง 500 แทน 400 ดังนั้น source = "SDK" หากใช้ตัวอักษรพิมพ์ใหญ่ ก็จะกลายเป็นข้อผิดพลาดของเซิร์ฟเวอร์ที่ไม่ชัดเจน ส่วนที่เหลือจะเปรียบเทียบเป็นสตริงและตอบกลับด้วยหน้าเปล่า ซึ่งดูเหมือน "ไม่พบรายการที่ตรงกัน" ทั้งที่จริงหมายถึง "ไม่มีค่านี้" ขอข้อมูลอ้างอิงฟิลด์ฉบับเต็มได้จาก schema("list.trace") (หรือ list.span, list.thread, list.experiment) ซึ่งรวมค่าที่ยอมรับได้ด้วย

ค้นหารายการเดียวในชุดข้อมูล list(entity_type="dataset_item", dataset_id=…) filters on the case itself: data.<key> สำหรับคีย์ที่ใช้สร้าง ชุดข้อมูล, full_data สำหรับค้นหาข้อความบางส่วนใน payload ทั้งหมด (สแกนเต็ม — ระบุคีย์เมื่อทำได้), รวมถึง id, tags, source, trace_id, span_id และเวลา data.<key> รองรับเฉพาะตัวดำเนินการสตริงทั้งหกตัว (=, !=, contains, not_contains, starts_with, ends_with); backend จะตอบกลับ การเปรียบเทียบด้วย 400 ดังนั้นระบบจึงปฏิเสธตัวกรองนี้ก่อนเรียกใช้งาน endpoint นี้ไม่มีการเรียงลำดับและไม่มีการค้นหาข้อความอิสระ — sort จะถูกปฏิเสธ แทนที่จะถูกละทิ้ง read(entity_type="dataset_item", id=…) ส่งคืนรายการทั้งหมด ซึ่งเป็นวิธีอ่านค่าที่ถูกตัดออกจากตาราง

list(entity_type="dataset_item", dataset_id="<uuid>", filters='data.question contains "install"')
list(
    entity_type="dataset_item", dataset_id="<uuid>", filters='trace_id = "<trace-uuid>"'
)  # the case made from that trace
read(entity_type="dataset_item", id="<item-uuid>")  # the case, uncut

เมื่อใช้ experiment_ids รายการเดียวกันนี้จะเป็นการเปรียบเทียบแทน — รายการที่แนบแต่ละ run มาด้วย — และจะกรองตาม run (feedback_scores.<name>, output, duration) ทั้งสองรายการใช้ชุดฟิลด์คนละชุดบน endpoint ของ backend คนละตัว: schema("list.dataset_item_case") คือรายการของชุดข้อมูลเอง ส่วน schema("list.dataset_item") คือการเปรียบเทียบ

การเรียงลำดับ trace, span, thread และ experiment รองรับ sort="<field> [asc|desc]", desc เป็นค่าเริ่มต้น และรับได้เพียงฟิลด์เดียว: sort="duration desc", sort="total_estimated_cost", sort="feedback_scores.accuracy asc", sort="usage.total_tokens" ระบบจะตรวจสอบฟิลด์ กับรายการฟิลด์ที่เรียงลำดับได้ของ entity ก่อนเรียกใช้งาน เนื่องจาก backend จะละเว้นฟิลด์ที่เรียงลำดับไม่ได้โดยไม่แจ้งให้ทราบ ใน workspace ขนาดใหญ่มาก backend อาจยกเลิกการเรียงลำดับทั้งหมด ซึ่งส่วนหัวจะแจ้งให้ทราบเมื่อเกิดกรณีนี้

dataset_item เรียงลำดับได้เฉพาะเมื่อเป็นการเปรียบเทียบ (ร่วมกับ experiment_ids): endpoint ของ items ไม่รับพารามิเตอร์การเรียงลำดับ ดังนั้นระบบจะปฏิเสธการเรียงลำดับในรายการทั่วไปแทนที่จะละทิ้ง

ช่วงเวลาและการค้นหา trace, span และ thread รองรับ since และ until โดยแต่ละค่าเป็นช่วงเวลาแบบสัมพัทธ์ ("30m", "1h", "7d") หรือเวลาแบบ ISO-8601 พร้อมเขตเวลา จึงระบุ "ชั่วโมงที่ผ่านมา" ได้โดยไม่ต้องคำนวณเวลาเอง ช่วงเวลาจะอิงตามเวลาที่สร้างระเบียน ซึ่ง backend ประมวลผลได้รวดเร็วและตรงกับ start_time ภายในไม่กี่วินาทีสำหรับข้อมูลที่กำลังเข้ามา หากต้องการกำหนดขอบเขตเวลาอย่างแม่นยำ ให้ใส่ start_time ใน filters ทั้งสามชนิดนี้รองรับ search ด้วย ซึ่งเป็นข้อความอิสระที่ค้นหาได้ทุกที่ใน id, name, input, output, metadata, tags และ thread id การค้นหาจะสแกนทั้งโปรเจกต์บน backend ดังนั้นการเรียกครั้งแรกในโปรเจกต์ขนาดใหญ่อาจใช้เวลาหลายสิบวินาที การเรียกเหล่านี้มี timeout 60 วินาที การเพิ่ม since จะทำให้กลับมาทำงานได้รวดเร็วอีกครั้ง

การอ่านตาราง ระยะเวลาจะแสดงป้ายกำกับเป็น duration_ms / ttft_ms และแสดงเป็นมิลลิวินาทีจำนวนเต็ม ส่วนฟิลด์ยังคงเป็น duration ใน filters และ sort เวลาจะแสดงถึงระดับวินาที และค่าใช้จ่ายจะแสดงเป็นทศนิยมทั่วไป แถวของโปรเจกต์มี last_updated_trace_at เพื่อให้เห็นว่าโปรเจกต์ใดมี ข้อมูลที่กำลังเข้ามา ส่วนแถวของ thread จะแสดงข้อความแรก หากหน้าไม่มีข้อมูลภายใต้ช่วงเวลา จะแจ้งว่า trace ล่าสุดของโปรเจกต์เข้ามาเมื่อใด และหากหน้าไม่มีข้อมูลภายใต้ค่าเริ่มต้น source = "sdk" จะแจ้งวิธีดูแหล่งข้อมูลอื่น หากสะกด project_name ผิด ระบบจะแสดงชื่อที่มีอยู่ซึ่งใกล้เคียงที่สุด

list(
    entity_type="trace",
    project_name="demo",
    since="1h",
    filters="error_info is_not_empty",
    sort="duration desc",
)
list(entity_type="trace", project_name="demo", search="order-42")

ปัญหา Diagnostics agent_insights_issue คือหน้า Diagnostics ที่เข้าถึงผ่าน MCP: ข้อผิดพลาดที่เกิดซ้ำซึ่งงาน Diagnostics ของ Opik จัดกลุ่มไว้สำหรับโปรเจกต์ โดยเรียงตามลำดับเดียวกับ UI (พบล่าสุดก่อน) คอลัมน์ประกอบด้วย severity, status, total_occurrences (ผลรวมตลอดเวลา), latest_count (วันที่รายงานล่าสุด ซึ่งเป็นตัวเลขที่คำอธิบายของปัญหาอ้างถึง) และ last_seen โดยค่าเริ่มต้นจะแสดงปัญหาที่ยังเปิดอยู่ หากต้องการดูรายการอื่น ให้ส่ง status="resolved" หรือ "closed" read และ list ยังใช้ชื่อ issue ได้ด้วย ซึ่งเป็นชื่อที่ UI ใช้เรียกรายการเหล่านี้ ส่วนชื่อแบบยาวเป็นชื่อใน enum entity_type ดังนั้น entity นี้จึงไม่ปรากฏซ้ำสองครั้ง จำนวนเป็นยอดรวมตลอดเวลาเพื่อให้ตรงกับ UI; ใช้ since / until แบบเดียวกับ trace เพื่อจำกัดช่วงเวลา โดยจะตัดช่วงให้ตรงกับวันรายงานใน UTC เพราะ Diagnostics รวบรวมข้อมูลรายวัน

หากรายการว่าง ระบบจะแจ้งสาเหตุ เพราะ "ไม่มีอะไรผิดปกติ" กับ "ยังไม่ได้เปิดใช้ Diagnostics" อาจดูเหมือนกันหากไม่แจ้งเหตุผล มีสถานะอยู่ห้าแบบ: Diagnostics ใช้ไม่ได้ในการติดตั้งนี้, ยังไม่ได้เปิดใช้สำหรับโปรเจกต์นี้, ปิดอยู่, เปิดใช้แล้วแต่ไม่ได้สแกนเมื่อไม่นานมานี้ หรือเปิดใช้แล้วและไม่พบปัญหา พร้อมเวลาที่สแกนล่าสุด สถานะที่ดำเนินการต่อได้จะระบุว่าต้องเรียกใช้อะไร และทุกสถานะมีลิงก์ไปยังหน้า Diagnostics ของโปรเจกต์

รายการที่ไม่ว่างจะระบุวันที่กำกับไว้ ปัญหาคือสิ่งที่การสแกนครั้งล่าสุดจัดกลุ่มไว้ ดังนั้นคำตอบจึงลงท้ายด้วย Report covers data through <time> และหากช่วงเวลาที่คุณขอเลยช่วงนั้นไป ระบบจะแจ้งส่วนท้ายที่ยังไม่ครอบคลุมและวิธีปิดช่องว่างดังกล่าว: ใช้ trigger เมื่อการสแกนใหม่ย้อนกลับไปได้ไกลพอ มิฉะนั้นให้ใช้ raw traces พร้อม since ที่ระบบระบุให้ หากขอข้อมูลหนึ่งสัปดาห์จากโปรเจกต์ที่สแกนทุกคืน วันสุดท้ายจะหายไปจากผลลัพธ์ที่จัดกลุ่มไว้ ข้อความนี้จะแจ้งให้ทราบ

write("agent_insights_job.enable", {"project_name": "demo"}) เปิดใช้ Diagnostics หลังจากนั้นระบบจะสแกนทุกวัน และเรียกซ้ำได้อย่างปลอดภัย write("agent_insights_job.trigger", …) สแกนข้อมูลย้อนหลัง 24 ชั่วโมงทันที โดยไม่ต้องรอการสแกนตอนกลางคืน ทั้งสองคำสั่งใช้สิทธิ์เดียวกับการอ่านปัญหา และทั้งคู่จะถูกปฏิเสธหากการติดตั้งนี้ไม่มี Diagnostics

เปลี่ยนสถานะปัญหาตามวงจรการทำงานได้ด้วย write("agent_insights_issue.resolve", {"issue_id": "<uuid>", "project_name": "demo"}) — จัดการแล้ว — หรือ …close สำหรับปัญหาที่ไม่ควรดำเนินการ และใช้ …reopen เพื่อย้ายทั้งสองสถานะกลับไปยังรายการที่เปิดอยู่ ทั้งสามคำสั่งใช้สิทธิ์เดียวกันและตอบกลับด้วยลิงก์ไปยังมุมมองที่ย้ายปัญหาไป เนื่องจากปัญหาที่แก้ไขแล้วจะไม่อยู่ในหน้าเริ่มต้น การตัดสินว่าข้อผิดพลาดได้รับการแก้ไขแล้วหรือไม่ขึ้นอยู่กับดุลยพินิจ ดังนั้นให้ใช้คำสั่งเหล่านี้เมื่อคุณร้องขอเท่านั้น: ผู้ช่วยไม่ควรจัดระเบียบรายการเองระหว่างการตรวจสอบปัญหา

เมตริกตามช่วงเวลา project_metric สร้างตารางช่วงเวลาสำหรับเมตริกหนึ่งรายการของโปรเจกต์ ได้แก่ จำนวน trace, span และ thread, ระยะเวลา, อัตราข้อผิดพลาด, ค่าใช้จ่าย, การใช้โทเค็น และคะแนน feedback ซึ่งตอบคำถามต่อจากภาพรวมว่าเกิดการเปลี่ยนแปลงขึ้นเมื่อใด

list(entity_type="project_metric", project_name="demo", metric_type="trace_count")
list(
    entity_type="project_metric",
    project_name="demo",
    metric_type="trace_error_rate",
    since="14d",
    interval="daily",
)
list(
    entity_type="project_metric", project_name="demo", metric_type="span_count", breakdown="model"
)  # one column per model
list(
    entity_type="project_metric",
    project_name="demo",
    metric_type="span_duration",
    breakdown="model",
    series="p99",
)  # the p99 of each model

แต่ละแถวคือช่วงเวลา ไม่ใช่ระเบียน ดังนั้น page, size และ sort จึงถูกปฏิเสธแทนที่จะถูกละเว้น interval คือ hourly, daily, weekly หรือ total; หากไม่ระบุ ระบบจะเลือกตามช่วงเวลาเหมือนแท็บ Metrics — รายชั่วโมงเมื่อไม่เกิน 3 วัน รายวันเมื่อไม่เกิน 30 วัน และรายสัปดาห์เมื่อมากกว่านั้น — ดังนั้นกราฟเริ่มต้นจึงมีเพียงไม่กี่สิบแถวไม่ว่าช่วงเวลาจะยาวเท่าใด ส่วนกราฟรายชั่วโมงตลอดหนึ่งเดือน (721 แถว) เป็นสิ่งที่ต้องร้องขอโดยเฉพาะ since / until ใช้รูปแบบเดียวกับที่อื่นและมีค่าเริ่มต้นเป็น 7 วันที่ผ่านมา filters ใช้ฟิลด์ของ entity ที่เมตริกนั้นเกี่ยวข้อง ดังนั้นเมตริกของ span จะกรองด้วยฟิลด์ของ span

breakdown แบ่งแต่ละช่วงเวลาตาม tags, name, error_info, error_type, model, provider, span_type, guardrail_name หรือ metadata.<key> เมตริกแต่ละรายการไม่ได้รองรับทุกตัวเลือก และมีเจ็ดรายการที่ไม่รองรับเลย เครื่องมือจะทราบว่ารายการใดใช้ได้และแจ้งก่อนเรียก backend พร้อมระบุเมตริกที่ตอบคำถามเดียวกันได้ หากมี เมตริกสามกลุ่มจะแสดงผลเป็นหลายชุดข้อมูลพร้อมกัน (ระยะเวลาเป็น p50/p90/p99, คะแนน feedback แยกตามชื่อ และการใช้โทเค็นแยกตามคีย์) และเมื่อจัดกลุ่ม backend จะแสดงกราฟได้ครั้งละชุดเดียว ดังนั้น series= จึงใช้เลือกชุดนั้น ได้แก่ เปอร์เซ็นไทล์ ชื่อคะแนน หรือคีย์การใช้งาน ค่าเริ่มต้นของระยะเวลาคือ p50 และของการใช้โทเค็นคือ total_tokens โดยค่าที่ใช้จะแสดงในบรรทัดแรก

ช่วงเวลาที่ไม่มีข้อมูลจะไม่แสดง และจะนับจำนวนไว้ด้านล่าง ดังนั้นเดือนที่เงียบสงบจึงมีเพียงไม่กี่แถวแทนที่จะเป็นคอลัมน์ศูนย์ และอัตราในช่วงเวลาที่ไม่มี trace จะไม่แสดง แทนที่จะรายงานเป็นศูนย์

ขอ schema("list.project_metric") เพื่อดูตารางเมตริก ช่วงเวลา และตารางการจัดกลุ่มแยกตามเมตริก

ชื่อของโปรเจกต์ score_name แสดงชื่อคะแนน feedback ที่บันทึกไว้ในโปรเจกต์ และ online_rule แสดง evaluator ของกฎอัตโนมัติที่กำหนดค่าไว้ ซึ่งเป็นแหล่งที่มาหลักของชื่อเหล่านั้น ทั้งสองรายการเป็นชุดข้อมูลเดียวกับที่ read("project", …) แสดง โดยแสดงครบถ้วนและแบ่งหน้า สำหรับกรณีที่เวอร์ชันจำกัดจำนวนในภาพรวมไม่เพียงพอ

list(entity_type="score_name", project_name="demo")
list(entity_type="online_rule", project_name="demo")

write

ตัวกระจายคำสั่งเขียนแบบครอบคลุม ส่ง operation + data แล้วตัวกระจายจะตรวจสอบ payload ใช้ REST verb ที่ถูกต้อง และส่งคืนคำตอบจาก backend

การดำเนินการ:

การดำเนินการสิ่งที่ทำ
trace.createบันทึก trace รายการเดียว (หรือเป็นชุด) ใช้เป็น parent สำหรับ spans / scores / comments
trace.updateปิดงานหรือแก้ไข trace ที่มีอยู่
span.createบันทึก span ใน trace ที่มีอยู่ (หรือเป็นชุด)
score.createแนบคะแนน feedback แบบตัวเลขกับ trace, span หรือ thread
comment.createแนบความคิดเห็นแบบข้อความอิสระกับ trace, span หรือ thread
prompt_version.saveบันทึก prompt เวอร์ชันใหม่ (สร้าง prompt ตามชื่อหากยังไม่มี)
dataset.createสร้างชุดข้อมูล — type: "test_suite" จะทำให้เป็นชุดทดสอบสำหรับ evaluation
dataset_item.upsertเพิ่มหรืออัปเดตรายการในชุดข้อมูล (ใช้รูปแบบ envelope เสมอ)
experiment.createสร้าง experiment ที่กำหนดขอบเขตไว้กับชุดข้อมูล
experiment_item.createแนบแถว trace + dataset_item ไปยัง experiment
thread.closeปิด thread (ทำเครื่องหมายว่าไม่ทำงาน) ส่ง thread_id และโปรเจกต์
thread.openเปิด thread ที่ปิดแล้วอีกครั้ง ส่ง thread_id และโปรเจกต์
agent_insights_job.enableเปิดใช้ Diagnostics สำหรับโปรเจกต์ (สแกนรายวัน เรียกซ้ำได้อย่างปลอดภัย)
agent_insights_job.triggerเรียกใช้การสแกน Diagnostics ทันที โดยสแกนย้อนหลัง 24 ชั่วโมง
agent_insights_issue.resolveทำเครื่องหมายว่าจัดการปัญหา Diagnostics แล้ว (ถามผู้ใช้ก่อน)
agent_insights_issue.closeทำเครื่องหมายว่าปัญหา Diagnostics ไม่ควรดำเนินการ (ถามผู้ใช้ก่อน)
agent_insights_issue.reopenย้ายปัญหา Diagnostics ที่แก้ไขแล้วหรือปิดแล้วกลับไปยังรายการที่เปิดอยู่
annotation_queue.createสร้างคิว annotation ของโปรเจกต์ โดยเลือกใช้มุมมอง annotator แบบกำหนดเองได้
annotation_queue.updateเปลี่ยนคิว annotation โดยตั้งค่า แทนที่ หรือล้างมุมมอง annotator
write(
    operation="score.create",
    data={
        "target": "trace",
        "target_id": "7f2e3c8a-…",
        "name": "helpfulness",
        "value": 0.9,
        "reason": "great recovery",
    },
)

schema

ตรวจสอบรูปแบบ JSON ที่แน่นอนและฟิลด์ที่จำเป็นของการดำเนินการเขียนก่อนเรียกใช้ ซึ่งมีประโยชน์เมื่อไม่แน่ใจว่า data ควรมีรูปแบบอย่างไร ระบบจะแสดง schema, OAuth scope และตัวอย่างที่ผ่านการตรวจสอบแล้ว เป็นการค้นหาข้อมูลเท่านั้น ไม่มีการเรียก backend

schema(operation="score.create")
schema(operation="prompt_version.save")

เครื่องมือเดียวกันตอบ list.trace, list.span, list.thread และ list.experiment ด้วยข้อมูลอ้างอิงของเครื่องมือ list สำหรับเอนทิตีนั้น: ฟิลด์ที่กรองได้ทั้งหมดพร้อมชนิดและตัวดำเนินการที่ใช้ได้ ฟิลด์ที่จัดเรียงได้ ระบุว่ารองรับช่วงเวลาหรือการค้นหาข้อความอิสระหรือไม่ และตัวกรองตัวอย่างสองรายการ

schema(operation="list.trace")

การกำหนดค่า

การตั้งค่าเหล่านี้ใช้กำหนดค่าเซิร์ฟเวอร์ภายในเครื่อง โดยทุกการตั้งค่าเป็นตัวแปรสภาพแวดล้อม เซิร์ฟเวอร์ที่โฮสต์บน Opik Cloud ไม่ใช้การตั้งค่าเหล่านี้

ข้อมูลระบุตัวตน / ปลายทาง

ตัวแปรค่าเริ่มต้นหมายเหตุ
OPIK_API_KEY—คีย์ API สำหรับ Comet ที่โฮสต์เอง หรือสำหรับ Opik Cloud ที่ไม่ได้ใช้เซิร์ฟเวอร์ที่โฮสต์ไว้ Opik แบบโอเพนซอร์สไม่ต้องใช้ เว้นแต่การติดตั้งใช้งานจะเพิ่มการยืนยันตัวตน
OPIK_WORKSPACEunsetชื่อเวิร์กสเปซ บนคลาวด์ที่ใช้คีย์ API หากไม่ได้กำหนด ระบบจะส่ง default ซึ่งจะชี้ไปยังเวิร์กสเปซ เริ่มต้น ของบัญชีคุณ — กำหนดค่านี้อย่างชัดเจนหากคุณทำงานในเวิร์กสเปซอื่น มิฉะนั้นการอ่านข้อมูลจะมาจากเวิร์กสเปซที่ไม่ถูกต้องโดยไม่มีการแจ้งเตือน ปล่อยว่างไว้เมื่อใช้ OAuth (โทเค็นจะระบุค่านี้) และบนระบบภายในเครื่อง/OSS (default เป็นเวิร์กสเปซเดียวที่มี)
COMET_WORKSPACE—ชื่อแทนที่เลิกใช้แล้วสำหรับ OPIK_WORKSPACE (เพื่อความเข้ากันได้ย้อนหลัง) หากกำหนดทั้งสองค่า OPIK_WORKSPACE จะมีลำดับความสำคัญสูงกว่า
COMET_WORKSPACE_IDunsetUUID ของเวิร์กสเปซ (ไม่บังคับ) เมื่อกำหนดค่านี้ ระบบจะใส่ค่าไว้ในเหตุการณ์การวิเคราะห์ และจะมีลำดับความสำคัญเหนือค่าที่แก้ไขได้ตามปกติ โดยทั่วไปไม่จำเป็น — การติดตั้งผ่าน OAuth จะรับ UUID จากโทเค็นโดยอัตโนมัติ
COMET_URL_OVERRIDEhttps://www.comet.comกำหนดเป็นโฮสต์ Comet ที่คุณโฮสต์เอง หรือ https://dev.comet.com สำหรับสภาพแวดล้อม staging
OPIK_URLได้มาจาก COMET_URL_OVERRIDE + /opik/apiกำหนดค่านี้สำหรับ Opik แบบโอเพนซอร์ส ซึ่งให้บริการ API ที่ /api (ภายในเครื่องคือ http://localhost:5173/api) บนแพลตฟอร์ม Comet ให้เปลี่ยนค่านี้เฉพาะเมื่อ Opik อยู่บนโฮสต์/พาธอื่นจาก UI ของ Comet
OPIK_DEFAULT_PROJECT_NAMEunsetเมื่อกำหนดค่านี้ บล็อบ instructions ประจำเซสชันจะบอก LLM ให้ส่งค่านี้เป็น project_name ในทุกการเรียกใช้เครื่องมือ เว้นแต่ผู้ใช้จะระบุโปรเจกต์อื่น

เซิร์ฟเวอร์ / การขนส่ง

ตัวแปรค่าเริ่มต้นหมายเหตุ
OPIK_MCP_TRANSPORTstdiostdio สำหรับการเปิดใช้งานโดยโฮสต์, streamable-http สำหรับรับฟังบนพอร์ต
OPIK_MCP_HOST127.0.0.1โฮสต์ที่ uvicorn ใช้ bind (streamable-http เท่านั้น)
OPIK_MCP_PORT8080พอร์ตที่ uvicorn ใช้ bind (streamable-http เท่านั้น)
OPIK_MCP_RELOADfalsetrue เพื่อเปิดใช้ uvicorn --reload (สำหรับ dev เท่านั้น)
OPIK_MCP_AS_URLunsetURL ของ OAuth Authorization Server ซึ่งประกาศไว้ใน /.well-known/oauth-protected-resource (RFC 9728) และใช้เป็นเป้าหมายพร็อกซีสำหรับการตรวจสอบ AS-discovery จำเป็นสำหรับโฮสต์ MCP เพื่อเริ่มขั้นตอน OAuth ผ่าน HTTP
OPIK_MCP_RESOURCE_URIunsetURI สาธารณะแบบ canonical ของเซิร์ฟเวอร์นี้ ซึ่งประกาศเป็น resource ในข้อมูลเมตาของ protected resource และใช้สร้างคำใบ้ WWW-Authenticate
OPIK_MCP_OAUTH_VALIDATION_CACHE_TTL_S30ระยะเวลาที่เชื่อถือคำตอบ "valid" จากการตรวจสอบโทเค็นของ opik-backend ก่อนที่คำขอถัดไปซึ่งใช้ OAuth token เดิมจะตรวจสอบอีกครั้ง ค่านี้จำกัดภาระที่เพิ่มให้ backend จากการตรวจสอบทุกคำขอ และช่วงเวลาที่โทเค็นหมดอายุแล้วยังถูกส่งต่อได้ (ช่วงเวลาดังกล่าวจะสิ้นสุดเมื่อ backend ตอบกลับ 401 ครั้งแรกด้วย) จำกัดค่าสูงสุดตาม expires_at ของโทเค็น หาก backend รายงานค่านี้
OPIK_MCP_LOG_LEVELINFOระดับเกณฑ์ของตัวบันทึก stderr

การเลือก transport

รูปแบบ bearer สองแบบมีสัญญาการทำงานบน HTTP ต่างกัน โทเค็น OAuth สำหรับ opik_mcp_at_… จะถูก ตรวจสอบทุกคำขอ กับ endpoint ตรวจสอบโทเค็นของ opik-backend (มีการแคช ดู OPIK_MCP_OAUTH_VALIDATION_CACHE_TTL_S); โทเค็นที่หมดอายุหรือถูกเพิกถอนจะได้รับ HTTP 401 พร้อม WWW-Authenticate: Bearer error="invalid_token" ซึ่งเป็นสิ่งที่โฮสต์ MCP ใช้เป็นเงื่อนไขสำหรับการให้สิทธิ์แบบเงียบ refresh_token ส่วน Opik API key จะ ไม่ถูกตรวจสอบภายในเครื่อง แต่จะถูกส่งต่อไปยัง opik-backend ตามเดิม ซึ่งเป็นจุดบังคับใช้นโยบายเพียงจุดเดียว เลือก transport ตามรูปแบบการติดตั้งใช้งาน:

สถานการณ์Transport
Opik Cloudไม่ต้องเปิดใช้งานอะไร: เซิร์ฟเวอร์ที่โฮสต์ไว้ คือเซิร์ฟเวอร์นี้ผ่าน HTTP ซึ่ง Comet เป็นผู้เรียกใช้
ไคลเอนต์ MCP และ Opik อยู่ในเครื่องเดียวกัน (ติดตั้ง OSS ภายในเครื่อง)stdio (แนะนำ — ง่ายที่สุด ไม่ต้องใช้พอร์ตหรือกำหนดค่า OAuth)
ไคลเอนต์ MCP ภายในเครื่อง → Opik ที่โฮสต์เองstdio พร้อมตัวแปรสภาพแวดล้อมสำหรับการติดตั้งใช้งาน หรือ HTTP พร้อม OAuth (OPIK_MCP_AS_URL ชี้ไปยัง backend)
opik-mcp ให้บริการอยู่หลัง edge เดียวกับ opik-backendHTTP — backend จะตรวจสอบ bearer ในทุกคำขอ

หมายเหตุสำหรับการติดตั้ง OSS ภายในเครื่อง: backend ของ OSS ไม่ตรวจสอบสิทธิ์คำขอ ดังนั้น opik-mcp ที่ใช้ HTTP อยู่ด้านหน้าจึงเปิดให้เข้าถึงได้เช่นเดียวกับ REST API ของ OSS เอง ให้คงค่า bind เริ่มต้น 127.0.0.1 ไว้ (และเลือกใช้ stdio หากทำได้) บนเครือข่ายที่ใช้ร่วมกัน

Telemetry

ตัวแปรค่าเริ่มต้นหมายเหตุ
OPIK_MCP_ANALYTICS_ENABLEDtrueกำหนดเป็น false เพื่อปิด telemetry ทั้งหมดที่ไม่ใช่ Sentry
`OPIK_MCP_SENTRY_ENABLEDtrueSet to false เพื่อปิด telemetry ของ Sentry ทั้งหมด
=======

ข้อจำกัดที่ทราบของโฮสต์

โฮสต์แต่ละรายกำหนดระยะเวลาที่อนุญาตให้การเรียกใช้เครื่องมือหนึ่งครั้งทำงานได้แตกต่างกัน:

  • Claude Code — ไม่มีการระบุ timeout ของการเรียกใช้เครื่องมือไว้ แนะนำให้ใช้
  • Cursor — timeout แบบตายตัว 60 วินาที ซึ่งจะ ไม่ เริ่มนับใหม่เมื่อมีความคืบหน้า (บั๊กต้นทาง)
  • MCP Inspector — MAX_TOTAL_TIMEOUT จำกัดระยะเวลารวม (ค่าเริ่มต้น 60 วินาที) เพิ่มค่านี้ใน UI ของ Inspector สำหรับการทำงานที่ใช้เวลานาน

หากการเรียกใช้ค้าง ให้กำหนด OPIK_MCP_LOG_LEVEL=DEBUG เพื่อบันทึกคำขอทั้งหมด


การแก้ไขปัญหา

การตั้งค่าใช้งานได้หรือไม่? เรียกใช้เซิร์ฟเวอร์ด้วย env จากการกำหนดค่าไคลเอนต์ แล้วใช้ --check: OPIK_URL=http://localhost:5173/api uvx opik-mcp@latest --check คำสั่งนี้ จะแสดงชื่อเวิร์กสเปซและโปรเจกต์ที่มองเห็น หรือแจ้งสิ่งที่ต้องแก้ไข ข้อผิดพลาดของเซิร์ฟเวอร์เองก็จะระบุสิ่งที่ต้องเปลี่ยนและลิงก์ไปยังหน้าเอกสารที่เกี่ยวข้อง

ไม่พบ OPIK_API_KEY — ตัวแปรนี้ไม่ได้ถูกส่งไปยังโปรเซสเซิร์ฟเวอร์ ใน Claude Code / Cursor / VS Code ตัวแปรสภาพแวดล้อมจะมีผลเฉพาะเมื่ออยู่ภายในบล็อก env ของการกำหนดค่าเซิร์ฟเวอร์ MCP ไม่ใช่ใน shell ของคุณ ส่วน Codex จะส่งต่อเฉพาะชื่อที่ระบุไว้ใน env_vars เริ่มเซสชันใหม่หลังแก้ไข เนื่องจากไคลเอนต์จะอ่านการกำหนดค่าเมื่อเริ่มเซสชัน

คำขอไปที่ /opik/api บน Opik แบบโอเพนซอร์ส — COMET_URL_OVERRIDE ใช้สำหรับแพลตฟอร์ม Comet ที่โฮสต์เอง ส่วนเวอร์ชันโอเพนซอร์สให้บริการ API ที่ /api: ให้กำหนด OPIK_URL=http://localhost:5173/api (หรือ https://<host>/api) แทน เซิร์ฟเวอร์จะแสดงคำเตือนเมื่อเริ่มทำงานหากโฮสต์เป็นเครื่องนี้ และ --check จะตอบว่า "No Opik API at …"

การเรียกใช้ใน Cursor หมดเวลาเมื่อครบ 60 วินาที — เป็นบั๊กที่ทราบของ Cursor ไม่ใช่ opik-mcp ให้จำกัดขอบเขตการเรียกใช้ (ลด size หรือกำหนดช่วงเวลาให้แคบลง) หรือเรียกใช้การทำงานเดียวกันบน Claude Code ซึ่งไม่มีขีดจำกัดแบบตายตัว

ไม่พบเซิร์ฟเวอร์, หน้าลงชื่อเข้าใช้ไม่เปิด, เวิร์กสเปซไม่ถูกต้อง, ไม่พบ uvx ปัญหาเหล่านี้อธิบายไว้ใน ส่วนการแก้ไขปัญหาของเอกสาร uvx opik@latest mcp status แสดงไคลเอนต์ทั้งหมดที่กำหนดค่าเซิร์ฟเวอร์ไว้ พร้อมระบุว่าการกำหนดค่าของแต่ละไคลเอนต์คลาดเคลื่อนหรือไม่


การพัฒนา

git clone git@github.com:comet-ml/opik-mcp.git
cd opik-mcp
make install        # uv sync --locked --extra dev
make check          # lint + typecheck + test
make run-dev        # uvicorn with --reload + DEBUG logs
make inspect        # MCP Inspector against the running server

เป้าหมายที่ใช้บ่อย:

เป้าหมายการทำงาน
make installuv sync --locked --extra dev
make runเรียกใช้เซิร์ฟเวอร์ MCP (ค่าเริ่มต้นคือ stdio)
make run-devเรียกใช้พร้อม DEBUG logging + uvicorn --reload
make devเรียกใช้ผ่าน mcp dev (ตัวครอบ Inspector dev-mode)
make inspectเปิด MCP Inspector โดยเชื่อมต่อกับเซิร์ฟเวอร์ที่กำลังทำงาน
make testuv run pytest -q
make lintruff check + ตรวจสอบรูปแบบ
make formatruff format + ruff check --fix
make typecheckmypy
make checklint + typecheck + test

โครงสร้าง repo:

opik-mcp/
├── src/opik_mcp/        ← server, tools, analytics
├── tests/               ← pytest suites
├── scripts/             ← live-BE smoke + MCP-session smoke
├── legacy/typescript/   ← migration guide for the deprecated v2 TS server (source: tag `legacy-typescript-final`)
├── pyproject.toml
└── Makefile

ขอความช่วยเหลือ


ใบอนุญาต

Apache-2.0.