Comet Opik

chính thức

Truy vấn và phân tích nhật ký Opik, dấu vết, lời nhắc và tất cả dữ liệu đo từ xa khác từ các LLM của bạn bằng ngôn ngữ tự nhiên.

Bạn có thể làm gì với Comet Opik MCP?

  • Truy vấn trace và dự án — Hỏi "liệt kê các dự án Opik của tôi" hoặc "trace nào trong dự án 'demo' đã thất bại hôm nay?" để duyệt dữ liệu không gian làm việc qua list và read.

  • Chấm điểm và nhận xét trace — Đính kèm điểm phản hồi dạng số kèm lý do, hoặc thêm bình luận dạng văn bản tự do vào trace, span hoặc luồng.

  • Quản lý phiên bản prompt — Lưu phiên bản prompt mới, tạo prompt theo tên nếu chúng chưa tồn tại.

  • Kiểm tra lược đồ ghi — Dùng schema để kiểm tra cấu trúc JSON chính xác, trường bắt buộc và ví dụ đã xác thực trước khi xây dựng bất kỳ thao tác ghi nào.

  • Theo dõi tình trạng dự án — Nhận tổng quan 7 ngày với số lượng trace, tỷ lệ lỗi, thời lượng và chi phí, hoặc vẽ biểu đồ số liệu theo thời gian.

  • Phân loại sự cố Diagnostics — Liệt kê các vấn đề insight của agent đang mở, giải quyết hoặc đóng chúng, đồng thời bật hoặc kích hoạt quét.

Tài liệu

Máy chủ MCP Opik

Máy chủ Giao thức Ngữ cảnh Mô hình (MCP) chính thức cho Opik, nền tảng đánh giá và quan sát LLM mã nguồn mở, được xây dựng bởi Comet. Kết nối máy chủ AI của bạn (Claude Code, Cursor, VS Code Copilot, Codex, opencode, hoặc bất kỳ máy khách MCP nào) trực tiếp vào không gian làm việc Opik của bạn: đọc trace, ghi điểm, và lưu các phiên bản prompt, tất cả từ trong chat.

Được xây dựng cho các kỹ sư LLM đã chạy Opik và muốn điều khiển nó từ chính trợ lý AI mà họ dùng để viết mã.

Đang nâng cấp từ npx opik-mcp cũ? Máy chủ TypeScript đã không còn được hỗ trợ và sẽ ngừng hoạt động vào 2026-11-15. Thay npx -y opik-mcp bằng uvx opik-mcp@latest trong cấu hình máy khách MCP của bạn. Hướng dẫn đầy đủ: legacy/typescript/MIGRATION.md.

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

Bắt đầu nhanh

Một lệnh duy nhất đăng ký máy chủ với các máy khách AI trên máy của bạn, cài đặt bộ kỹ năng Opik, và xác minh kết nối. Lệnh này cần uv và không cần Opik SDK:

uvx opik mcp configure

Lệnh này tự động phát hiện Claude Code, Cursor, VS Code Copilot, Codex và opencode, và sử dụng máy chủ lưu trữ trên Opik Cloud (đăng nhập qua trình duyệt, không lưu khóa API) hoặc máy chủ cục bộ này ở nơi khác. Bất kỳ máy khách MCP nào khác có thể lấy URL lưu trữ trực tiếp:

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

Add to Cursor Install in VS Code

Hướng dẫn thiết lập, khắc phục sự cố và FAQ: comet.com/docs/opik/mcp-server. Phần còn lại của README này bao gồm máy chủ cục bộ, mà lệnh trên thiết lập cho Opik tự lưu trữ và mã nguồn mở, và bạn cũng có thể cấu hình thủ công.


Cài đặt thủ công

opik-mcp là một gói Python (yêu cầu Python 3.13+). Cách được khuyến nghị để chạy nó là uvx, lệnh này tìm nạp và chạy phiên bản mới nhất đã phát hành theo yêu cầu — không cần cài đặt toàn cục, không cần xử lý virtualenv.

Cài đặt uv một lần:

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

Bạn sẽ cần hai thứ từ không gian làm việc Opik của mình:

  • OPIK_API_KEY — lấy từ comet.com/api/my/settings/.
  • OPIK_WORKSPACE — tên không gian làm việc của bạn (chữ thường, như xuất hiện trong URL). Ví dụ: https://www.comet.com/acme-ai/... → OPIK_WORKSPACE=acme-ai. COMET_WORKSPACE được chấp nhận như một bí danh không còn dùng.

Cloud, với khóa API: hãy đặt nó trừ khi mặc định tài khoản của bạn là cái bạn muốn. Nếu bỏ trống, máy chủ sẽ gửi default, mà Comet phân giải thành không gian làm việc mặc định của tài khoản bạn. Điều đó hoạt động, nhưng nếu bạn thực sự làm việc trong một không gian làm việc có tên, bạn sẽ bị trỏ đến một không gian khác mà không có gì báo cho bạn — các lần đọc của bạn trả về từ sai nơi thay vì báo lỗi.

Cloud, qua OAuth: để trống. Không gian làm việc đến từ token bạn đã ủy quyền, và máy chủ bỏ qua cài đặt này hoàn toàn.

Cục bộ / mã nguồn mở: để trống. Opik mã nguồn mở có một không gian làm việc duy nhất tên default và không có cách tạo không gian khác, đó chính xác là những gì dự phòng cung cấp cho bạn.

Comet tự lưu trữ: hãy đặt nó. Không giống mã nguồn mở, các triển khai này có các không gian làm việc có tên thực sự, và rủi ro sai không gian làm việc thầm lặng tương tự cũng áp dụng.

Dù trường hợp nào, hãy đảm bảo giá trị thực sự được thay thế. Các đoạn mã ngoài kia thường chứa các placeholder như <your-workspace> hoặc ${input:OPIK_WORKSPACE}; nếu dán nguyên trạng, những thứ đó không phải tên không gian làm việc. Máy chủ hiện từ chối chúng thẳng thừng thay vì để backend trả lời bằng lỗi xác thực mà không giải thích gì.

Claude Code

Thêm máy chủ bằng một lệnh:

claude mcp add --transport stdio opik-mcp \
  --env OPIK_API_KEY=<your-key> \
  --env OPIK_WORKSPACE=<your-workspace> \
  -- uvx opik-mcp

Hoặc chỉnh sửa ~/.claude.json trực tiếp:

{
  "mcpServers": {
    "opik-mcp": {
      "type": "stdio",
      "command": "uvx",
      "args": ["opik-mcp"],
      "env": {
        "OPIK_API_KEY": "<your-key>",
        "OPIK_WORKSPACE": "<your-workspace>"
      }
    }
  }
}

Khởi động lại Claude Code. Xác minh bằng /mcp — opik-mcp sẽ xuất hiện như đã kết nối. Sau đó, trong chat, hãy hỏi: "liệt kê các dự án Opik của tôi" — Claude sẽ gọi công cụ list và bạn sẽ thấy các dự án trong không gian làm việc của mình.

Cursor

Chỉnh sửa ~/.cursor/mcp.json (toàn cục) hoặc .cursor/mcp.json (dự án), hoặc mở Cmd+Shift+J → Features → Model Context Protocol:

{
  "mcpServers": {
    "opik-mcp": {
      "type": "stdio",
      "command": "uvx",
      "args": ["opik-mcp"],
      "env": {
        "OPIK_API_KEY": "<your-key>",
        "OPIK_WORKSPACE": "<your-workspace>"
      }
    }
  }
}

Tải lại Cursor; chấm xanh bên cạnh opik-mcp trong bảng MCP xác nhận kết nối. Hỏi trong chat: "liệt kê các dự án Opik của tôi".

Cursor hết thời gian 60 giây. Cursor áp đặt thời gian chờ gọi công cụ cứng mà không đặt lại khi có thông báo tiến trình. Xem Giới hạn máy chủ đã biết.

VS Code Copilot

.vscode/mcp.json trong không gian làm việc của bạn (hoặc User Settings JSON):

{
  "servers": {
    "opik-mcp": {
      "type": "stdio",
      "command": "uvx",
      "args": ["opik-mcp"],
      "env": {
        "OPIK_API_KEY": "<your-key>",
        "OPIK_WORKSPACE": "<your-workspace>"
      }
    }
  }
}

Tải lại cửa sổ; chỉ báo MCP của Copilot Chat hiển thị opik-mcp khi máy chủ có thể truy cập. Hỏi trong chat: "liệt kê các dự án Opik của tôi".

MCP Inspector (kiểm thử thủ công)

OPIK_API_KEY=<your-key> OPIK_WORKSPACE=<your-workspace> \
  npx @modelcontextprotocol/inspector uvx opik-mcp

Opik tự lưu trữ

Thêm COMET_URL_OVERRIDE (và OPIK_URL nếu Opik nằm ở đường dẫn không mặc định) vào cùng khối env trong cấu hình máy chủ của bạn:

{
  "mcpServers": {
    "opik-mcp": {
      "type": "stdio",
      "command": "uvx",
      "args": ["opik-mcp"],
      "env": {
        "OPIK_API_KEY": "<your-key>",
        "OPIK_WORKSPACE": "<your-workspace>",
        "COMET_URL_OVERRIDE": "https://opik.your-company.com",
        "OPIK_MCP_ANALYTICS_SOURCE": ""
      }
    }
  }
}

Bỏ qua OPIK_WORKSPACE trên triển khai mã nguồn mở, nơi default là không gian làm việc duy nhất; giữ nó trên Comet tự lưu trữ, nơi có các không gian làm việc có tên thực sự.

Đặt OPIK_MCP_ANALYTICS_SOURCE="" sẽ loại bỏ bản cài đặt của bạn khỏi nhãn nguồn cloud-Comet trên các sự kiện telemetry.


Công cụ

opik-mcp cung cấp một bề mặt nhỏ, hướng kết quả bao phủ toàn bộ vòng đời (đọc → chú thích → quản lý → soạn thảo → lặp lại).

Công cụMục đích
readĐọc phổ quát theo id / tên / URI opik://
listLiệt kê phổ quát với bộ lọc tên tùy chọn + phân trang
writeGhi phổ quát — ghi trace/span, chấm điểm, bình luận, lưu prompt, quản lý dataset & thí nghiệm
schemaKiểm tra nội bộ các lược đồ thao tác ghi (được LLM dùng để xây dựng payload hợp lệ)
read_skillĐọc một trong các kỹ năng agent Opik đi kèm với máy chủ này

read

Một công cụ cho bất kỳ câu hỏi "cho tôi xem X" nào. Nhận một entity_type cùng với một id (UUID hoặc, đối với các loại có tên, một tên) hoặc một URI opik:// đầy đủ. Các lần đọc tổng hợp (trace, prompt, thread, agent_insights_issue) nhúng các phần tử con của chúng để một lần gọi duy nhất trả về bức tranh đầy đủ.

Bản ghi bạn đặt tên trả về nguyên vẹn. Các phần tử con được nhúng thì không: phần thân của chúng được tìm nạp bằng truncate=true của backend, vì vậy một trường trên ~10 KB bị cắt trong ClickHouse và các hình ảnh base64 được thay thế bằng "[image]" — một tệp đính kèm được lặp lại qua 200 span sẽ tốn kém hơn mọi thứ khác trong lần đọc. Câu trả lời nói rõ điều đó trong spanBodies / messageBodies, và bất kỳ phần tử con nào lại nguyên vẹn thông qua read("span", id) hoặc read("trace", trace_id) của chính nó, các lệnh này truy cập các endpoint không có tham số truncate nào cả.

Một bộ sưu tập được nhúng cũng bị giới hạn độ dài: 200 span, 200 lượt, 100 phiên bản prompt. Vượt quá giới hạn đó, spansTruncated / messagesTruncated / versionsTruncated là true và một dòng moreSpans / moreMessages / moreVersions bên cạnh nó mang số lượng và lệnh gọi list(...) chính xác tiếp tục từ nơi phần được nhúng dừng lại.

Các thực thể được hỗ trợ: project, trace, span, dataset, dataset_item, experiment, prompt, thread, agent_insights_issue. Tra cứu theo tên có sẵn cho project, experiment, prompt, dataset (chậm hơn — hai lần gọi API — và có thể trả về nhiều kết quả khớp). thread và agent_insights_issue có phạm vi dự án: truyền project_id hoặc project_name, hoặc một liên kết/URI mang dự án. dataset và dataset_item trước đây được gọi là test_suite và test_suite_item; các tên cũ vẫn phân giải được, nhưng chúng không được quảng bá và mã mới nên dùng các tên mới.

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>",
)

Một liên kết sao chép từ giao diện Opik hoạt động như id: một liên kết thread hoặc một liên kết trang Chẩn đoán mang dự án, vì vậy không cần project_id và loại thực thể được lấy từ liên kết.

Một lần đọc project trả lời "dự án của tôi đang hoạt động thế nào" trong một lần gọi. Nó trả về {project, summary, vocabulary, contains, url}: bản ghi, sau đó là bốn con số mà trang Nhật ký hiển thị dưới dạng thẻ (số trace, tỷ lệ lỗi, thời lượng trung bình, tổng chi phí) trong 7 ngày qua so với 7 ngày trước đó, chỉ lưu lượng SDK, như trên màn hình. since / until di chuyển cửa sổ đó; since="30d" là những gì giao diện mở. Một tỷ lệ hoặc trung bình trong khoảng thời gian không có trace trả về dưới dạng null, vì 0% lỗi trong một tuần không có lưu lượng đọc như một tuần khỏe mạnh.

vocabulary là bản đồ bạn cần trước khi có thể hỏi bất cứ điều gì khác: tên điểm phản hồi của dự án, các khóa sử dụng token của nó, và các quy tắc tự động hóa chấm điểm các trace của nó. Đây là những tên đi vào bộ lọc hoặc vào series= bên dưới, và đoán chúng trả về một trang trống trông như tin tốt. Tên điểm và quy tắc bị giới hạn, luôn báo cáo tổng thực sự, và đặt tên cho lệnh gọi trả về phần còn lại; các khóa sử dụng được liệt kê đầy đủ, vì không có gì khác liệt kê chúng. contains đặt tên cho thí nghiệm, dataset, phiên bản prompt và lần chạy tối ưu hóa mới nhất, vì vậy "chuyện gì đang xảy ra ở đây" không cần thêm bốn lần gọi nữa. Một phần không tải được sẽ nói rõ điều đó thay vì trông trống rỗng, và một phần trống bị bỏ qua.

Một lần đọc agent_insights_issue trả về {issue, example_trace_ids, details}: bản ghi vấn đề Chẩn đoán (tên, mô tả, nguyên nhân, đề xuất sửa chữa, mức độ nghiêm trọng, trạng thái), các id đã khử trùng lặp của các trace thể hiện nó (cùng mẫu mà trang Chẩn đoán hiển thị — mở một cái bằng read("trace", id)), và phân tích theo ngày. Phần thân trace không được nhúng, vì vậy lần đọc vẫn là một lần gọi backend. since / until thu hẹp các hàng theo ngày; mặc định là toàn thời gian. Khi máy chủ biết URL Opik và không gian làm việc của phiên, lần đọc cũng mang url (trang Chẩn đoán của vấn đề) và trace_url_template (một liên kết sâu cho bất kỳ trace ví dụ nào), vì vậy trợ lý có thể đưa cho bạn thứ gì đó có thể nhấp được; trong phiên OAuth có không gian làm việc không thể phân giải, các liên kết bị bỏ qua thay vì đoán.

Bản thân các trace không mang URL — một liên kết cho một trace không thể suy ra từ các trường mà read hoặc list trả về, và một hình dạng đoán sẽ 404. Các hướng dẫn phiên đặt tên một mẫu cho nó thay vào đó, .../v1/session/redirect/projects/?trace_id={trace_id}&path=..., vì vậy trợ lý điền một id và đưa cho bạn một liên kết. Nó đi qua chuyển hướng của opik-backend, nơi phân giải dự án và không gian làm việc từ trace, vì vậy nó hoạt động ở nơi URL dự án trực tiếp không thể, bao gồm cả phiên OAuth với không gian làm việc chưa phân giải. Đó là cùng một liên kết mà Python SDK in cho một trace.

list

Duyệt hoặc tìm kiếm một bộ sưu tập với phân trang. Các loại có phạm vi dự án (trace, span, thread, agent_insights_issue, dataset_item, prompt_version) cần phần tử cha của chúng: một UUID hoặc tên dự án, một UUID dataset, hoặc một 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"')

Bộ lọc. trace, span, thread, experiment và dataset_item nhận một chuỗi OQL, cùng cú pháp với search_traces(filter_string=…) của SDK:

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

Chuỗi nằm trong dấu ngoặc kép, số để trần, duration tính bằng mili giây, ngày là các thời điểm ISO-8601 có múi giờ ("2026-09-08T10:00:00Z"). Điểm và từ điển nhận một khóa: feedback_scores.accuracy < 0.5, metadata.environment = "prod". AND là bộ nối duy nhất.

Giống trang Nhật ký của giao diện, danh sách trace, span và thread thêm source = "sdk" để các trace của bộ đánh giá, playground và thí nghiệm tránh xa; tự đặt tên source để xem chúng. Dòng đầu ra đầu tiên lặp lại bộ lọc đã được áp dụng. Bộ lọc lỗi sẽ thất bại trước khi đến được backend mà không có thông tin cần thiết để sửa: vị trí của lỗi cú pháp, tên trường gần nhất, các toán tử hợp lệ cho kiểu của trường, hoặc định dạng giá trị mong đợi. Các trường có tập giá trị đóng (source, span type, thread status, visibility_mode) cũng được kiểm tra với tập đó, bao gồm mọi phần tử của danh sách in. source là trường mà backend tự xác thực, và nó trả lời một giá trị không xác định với mã 500 thay vì 400, vì vậy source = "SDK" nếu không sẽ là một lỗi máy chủ mơ hồ cho một chữ cái viết hoa. Phần còn lại được so sánh dưới dạng chuỗi và trả về một trang trống, trông giống như "không có kết quả khớp" trong khi thực ra nghĩa là "không có giá trị như vậy". Hãy hỏi schema("list.trace") (hoặc list.span, list.thread, list.experiment) để tham chiếu đầy đủ các trường, bao gồm cả các giá trị được chấp nhận.

Tìm một trường hợp cụ thể trong tập dữ liệu. list(entity_type="dataset_item", dataset_id=…) filters on the case itself: data.<key> để lấy các khóa mà tập dữ liệu được xây dựng, full_data để tìm một chuỗi con của toàn bộ payload (một quét toàn bộ — hãy chỉ định tên khóa khi có thể), cùng với id, tags, source, trace_id, span_id và các mốc thời gian. data.<key> chỉ chấp nhận sáu toán tử chuỗi (=, !=, contains, not_contains, starts_with, ends_with); backend trả lời một phép so sánh với mã 400, vì vậy trường hợp này bị từ chối trước khi gọi. Endpoint không có sắp xếp và không có tìm kiếm văn bản tự do — sort bị từ chối thay vì bị bỏ qua. read(entity_type="dataset_item", id=…) trả về một trường hợp nguyên vẹn, đó là cách một giá trị mà bảng đã cắt được đọc lại.

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

Với experiment_ids, cùng một danh sách được dùng để so sánh — các trường hợp có mỗi lần chạy được gắn kèm — và nó lọc trên các lần chạy (feedback_scores.<name>, output, duration). Hai cái này là hai tập trường khác nhau trên hai endpoint backend: schema("list.dataset_item_case") là các trường hợp của riêng tập dữ liệu, schema("list.dataset_item") là so sánh.

Sắp xếp. trace, span, thread và experiment nhận sort="<field> [asc|desc]", desc theo mặc định và chỉ một trường: sort="duration desc", sort="total_estimated_cost", sort="feedback_scores.accuracy asc", sort="usage.total_tokens". Trường được kiểm tra với danh sách có thể sắp xếp của thực thể trước khi gọi, vì backend âm thầm bỏ qua các trường mà nó không thể sắp xếp. Trên các workspace rất lớn, backend bỏ hoàn toàn việc sắp xếp; tiêu đề sẽ nói rõ điều đó khi xảy ra.

dataset_item chỉ sắp xếp như một phép so sánh (với experiment_ids): endpoint items không nhận tham số sắp xếp, vì vậy một sắp xếp trên danh sách thông thường bị từ chối thay vì bị bỏ qua.

Khoảng thời gian và tìm kiếm. trace, span và thread nhận since và until, mỗi cái là một khoảng tương đối ("30m", "1h", "7d") hoặc một thời điểm ISO-8601 có múi giờ, vì vậy "giờ qua" không cần tính toán đồng hồ. Khoảng thời gian được tính theo thời gian tạo bản ghi, điều này rẻ cho backend và khớp với start_time trong vài giây đối với lưu lượng trực tiếp. Để có một ranh giới chính xác, hãy đặt start_time trong filters. Ba loại tương tự nhận search, văn bản tự do khớp ở bất kỳ đâu trong id, name, input, output, metadata, tags và thread id. Tìm kiếm quét toàn bộ dự án trên backend, vì vậy lần gọi đầu tiên trên một dự án lớn có thể mất hàng chục giây. Những lần gọi đó có thời gian chờ 60 giây. Thêm since giúp chúng nhanh trở lại.

Đọc bảng. Thời lượng được gắn nhãn duration_ms / ttft_ms và hiển thị dưới dạng mili giây nguyên; trường vẫn là duration trong filters và sort. Dấu thời gian được hiển thị đến giây và chi phí dưới dạng số thập phân đơn giản. Các hàng dự án mang last_updated_trace_at để bạn có thể thấy dự án nào có lưu lượng trực tiếp; các hàng thread mang tin nhắn đầu tiên. Một trang trống dưới một khoảng thời gian cho biết khi nào trace cuối cùng của dự án được ghi, và một trang trống dưới source = "sdk" mặc định cho biết cách xem các nguồn khác. Một project_name viết sai chính tả sẽ trả về tên hiện có gần nhất.

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")

Các vấn đề chẩn đoán. agent_insights_issue là trang Diagnostics qua MCP: các lỗi lặp lại mà công việc Diagnostics của Opik đã nhóm cho một dự án, được xếp hạng theo cách UI xếp hạng chúng (gần đây nhất được thấy trước). Các cột là severity, status, total_occurrences (tổng mọi thời điểm), latest_count (ngày báo cáo gần nhất, con số mà mô tả của chính vấn đề đề cập đến) và last_seen. Các vấn đề đang mở được liệt kê theo mặc định; truyền status="resolved" hoặc "closed" để xem phần còn lại. read và list cũng trả lời cho issue, đây là những gì UI gọi chúng; tên dài là tên trong enum entity_type, vì vậy thực thể đó không xuất hiện hai lần ở đó. Số đếm là mọi thời điểm để khớp với UI; cùng since / until như cho traces thu hẹp khoảng thời gian, được cắt xuống các ngày báo cáo UTC vì Diagnostics tổng hợp theo ngày.

Một danh sách trống cho biết lý do tại sao nó trống, vì "không có gì hỏng" và "không ai bật Diagnostics" trông giống nhau nếu không. Có năm trạng thái: Diagnostics không khả dụng trên bản triển khai này, chưa được bật cho dự án này, đã tắt, đã bật nhưng chưa được quét gần đây, hoặc đã bật và sạch với thời gian của lần quét cuối. Các trạng thái bạn có thể hành động sẽ nêu tên lệnh gọi cần thực hiện, và mọi trạng thái đều liên kết đến trang Diagnostics của dự án.

Một danh sách không trống tự ghi ngày tháng. Các vấn đề là bất cứ điều gì lần quét cuối đã nhóm, vì vậy câu trả lời kết thúc bằng Report covers data through <time>, và khi khoảng thời gian bạn hỏi chạy qua đó, nó nêu tên phần đuôi chưa được bao phủ và cách đóng nó: một trình kích hoạt khi một lần quét lại đủ xa, nếu không thì các trace thô với since mà nó cung cấp cho bạn. Hãy hỏi một tuần trên một dự án được quét hàng đêm và ngày cuối cùng bị thiếu trong câu trả lời được nhóm; đây là điều nói rõ điều đó.

write("agent_insights_job.enable", {"project_name": "demo"}) bật Diagnostics lên. Nó quét hàng ngày từ đó, và gọi lại là an toàn. write("agent_insights_job.trigger", …) quét 24 giờ qua ngay bây giờ, mà không cần chờ lần chạy hàng đêm. Cả hai đều yêu cầu quyền mà việc đọc các vấn đề yêu cầu, và cả hai đều từ chối nơi bản triển khai không có Diagnostics.

Một vấn đề di chuyển qua vòng đời của nó với write("agent_insights_issue.resolve", {"issue_id": "<uuid>", "project_name": "demo"}) — đã xử lý — hoặc …close cho một vấn đề không đáng hành động, và …reopen để đưa một trong hai trở lại danh sách mở. Cả ba đều yêu cầu cùng một quyền và trả lời bằng một liên kết đến chế độ xem mà vấn đề đã chuyển đến, vì một vấn đề đã giải quyết không còn trên trang mặc định. Việc một lỗi đã được sửa hay chưa là một phán đoán, vì vậy những thao tác này dành cho khi bạn hỏi: trợ lý không có nhiệm vụ dọn dẹp danh sách trong khi phân loại nó.

Số liệu theo thời gian. project_metric vẽ biểu đồ một số liệu cho một dự án dưới dạng một bảng các khoảng thời gian: số lượng trace, span và thread, thời lượng, tỷ lệ lỗi, chi phí, mức sử dụng token và điểm phản hồi. Nó trả lời câu hỏi theo sau phần tổng quan, đó là khi nào một thứ gì đó đã thay đổi.

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

Các hàng là các khoảng thời gian, không phải bản ghi, vì vậy page, size và sort bị từ chối thay vì bị bỏ qua. interval là hourly, daily, weekly hoặc total; nếu bỏ qua, nó theo khoảng thời gian giống như tab Metrics — theo giờ lên đến 3 ngày, theo ngày lên đến 30, theo tuần xa hơn — vì vậy một biểu đồ mặc định là vài chục hàng bất kể phạm vi, và một tháng theo giờ (721 hàng) là điều bạn phải yêu cầu. since / until nhận các dạng giống như mọi nơi khác và mặc định là 7 ngày qua. filters sử dụng các trường của thực thể mà số liệu đang nói đến, vì vậy một số liệu span được lọc bởi các trường span.

breakdown chia mỗi khoảng theo tags, name, error_info, error_type, model, provider, span_type, guardrail_name hoặc metadata.<key>. Không phải mọi số liệu đều chấp nhận mọi thứ trong số đó, và bảy số liệu không chấp nhận gì cả; công cụ biết cái nào và nói rõ trước khi gọi backend, nêu tên một số liệu trả lời cùng một câu hỏi nếu có. Ba nhóm trả về nhiều chuỗi cùng một lúc (một thời lượng dưới dạng p50/p90/p99, một điểm phản hồi theo tên, mức sử dụng token theo khóa), và backend vẽ biểu đồ một trong số chúng tại một thời điểm khi nhóm, vì vậy series= chọn nó: một phần trăm, một tên điểm, hoặc một khóa sử dụng. Thời lượng mặc định là p50 và mức sử dụng token là total_tokens, và cái nào được sử dụng sẽ được lặp lại trên dòng đầu tiên.

Các khoảng trống được bỏ qua và đếm bên dưới, vì vậy một tháng yên tĩnh là vài hàng thay vì một cột số không, và một tỷ lệ trên một khoảng không có trace là vắng mặt thay vì được báo cáo là không.

Hãy hỏi schema("list.project_metric") để biết bảng số liệu, các khoảng thời gian và ma trận nhóm theo từng số liệu.

Tên của một dự án. score_name liệt kê các tên điểm phản hồi được ghi trong một dự án và online_rule các bộ đánh giá quy tắc tự động hóa được cấu hình trên đó, đây là nơi hầu hết các tên đó đến từ. Cả hai đều là cùng một danh sách mà read("project", …) mang, đầy đủ và được phân trang, cho khi phiên bản giới hạn trong phần tổng quan là không đủ.

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

write

Bộ điều phối ghi phổ quát. Truyền operation + data và bộ điều phối xác thực payload, áp dụng động từ REST phù hợp, và trả về phản hồi của backend.

Các thao tác:

Thao tácChức năng
trace.createGhi một trace đơn lẻ (hoặc một lô). Cha cho spans / scores / comments.
trace.updateHoàn tất hoặc sửa đổi một trace hiện có.
span.createGhi một span trên một trace hiện có (hoặc một lô).
score.createGắn một điểm phản hồi số vào một trace, span, hoặc thread.
comment.createGắn một bình luận văn bản tự do vào một trace, span, hoặc thread.
prompt_version.saveLưu một phiên bản prompt mới (tạo prompt theo tên nếu thiếu).
dataset.createTạo một tập dữ liệu — type: "test_suite" biến nó thành một bộ kiểm thử đánh giá.
dataset_item.upsertUpsert các mục vào một tập dữ liệu (luôn ở dạng envelope).
experiment.createTạo một thử nghiệm có phạm vi trong một tập dữ liệu.
experiment_item.createGắn các hàng trace + dataset_item vào một thử nghiệm.
thread.closeĐóng một thread (đánh dấu nó không hoạt động). Truyền thread_id và dự án.
thread.openMở lại một thread đã đóng. Truyền thread_id và dự án.
agent_insights_job.enableBật Diagnostics cho một dự án (quét hàng ngày, an toàn để lặp lại).
agent_insights_job.triggerChạy một lần quét Diagnostics ngay bây giờ, trong 24 giờ qua.
agent_insights_issue.resolveĐánh dấu một vấn đề Diagnostics là đã xử lý (hỏi người dùng trước).
agent_insights_issue.closeĐánh dấu một vấn đề Diagnostics là không đáng hành động (hỏi người dùng trước).
agent_insights_issue.reopenĐưa một vấn đề Diagnostics đã giải quyết hoặc đã đóng trở lại danh sách mở.
write(
    operation="score.create",
    data={
        "target": "trace",
        "target_id": "7f2e3c8a-…",
        "name": "helpfulness",
        "value": 0.9,
        "reason": "great recovery",
    },
)

schema

Kiểm tra hình dạng JSON chính xác và các trường bắt buộc của bất kỳ thao tác ghi nào trước khi bạn gọi nó — hữu ích khi bạn không chắc data nên trông như thế nào. Trả về schema, phạm vi OAuth, và một ví dụ đã được xác thực. Tra cứu thuần túy, không gọi backend.

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

Cùng một công cụ trả lời list.trace, list.span, list.thread và list.experiment với tham chiếu của công cụ list cho thực thể đó: mọi trường có thể lọc với kiểu và toán tử hợp lệ của nó, các trường có thể sắp xếp, liệu một khoảng thời gian và tìm kiếm văn bản tự do có áp dụng, và hai ví dụ về bộ lọc.

schema(operation="list.trace")

Cấu hình

Mọi cài đặt là một biến môi trường. Các biến bắt buộc được in đậm.

Danh tính / endpoint

BiếnMặc địnhGhi chú
OPIK_API_KEY—Bắt buộc cho mọi thao tác đọc/ghi có xác thực.
OPIK_WORKSPACEchưa đặtTên không gian làm việc. Trên cloud với API key, nếu không đặt sẽ gửi default, giá trị này phân giải thành không gian làm việc mặc định của tài khoản bạn — hãy đặt tường minh nếu bạn làm việc ở không gian khác, nếu không các thao tác đọc sẽ âm thầm lấy từ sai không gian làm việc. Để trống khi dùng OAuth (token đã mang sẵn thông tin này) và trên bản local/OSS (default là không gian làm việc duy nhất ở đó).
COMET_WORKSPACE—Bí danh không còn dùng cho OPIK_WORKSPACE (tương thích ngược). OPIK_WORKSPACE được ưu tiên nếu cả hai đều được đặt.
COMET_WORKSPACE_IDchưa đặtUUID không gian làm việc tùy chọn. Được ghi vào sự kiện phân tích khi được đặt và có quyền ưu tiên hơn giá trị đã phân giải. Hiếm khi cần — các bản cài qua OAuth tự lấy UUID từ token.
COMET_URL_OVERRIDEhttps://www.comet.comĐặt thành máy chủ Comet tự lưu trữ của bạn, hoặc https://dev.comet.com cho môi trường staging.
OPIK_URLsuy ra từ COMET_URL_OVERRIDE + /opik/apiChỉ ghi đè nếu Opik nằm trên máy chủ/đường dẫn khác với giao diện Comet.
OPIK_DEFAULT_PROJECT_NAMEchưa đặtKhi được đặt, khối instructions theo phiên sẽ yêu cầu LLM truyền giá trị này làm project_name trong mọi lệnh gọi công cụ trừ khi người dùng chỉ định một dự án khác.

Máy chủ / giao thức vận chuyển

BiếnMặc địnhGhi chú
OPIK_MCP_TRANSPORTstdiostdio cho máy chủ khởi chạy từ host, streamable-http để lắng nghe trên một cổng.
OPIK_MCP_HOST127.0.0.1Máy chủ bind của uvicorn (chỉ dành cho streamable-http).
OPIK_MCP_PORT8080Cổng bind của uvicorn (chỉ dành cho streamable-http).
OPIK_MCP_RELOADfalsetrue để bật --reload của uvicorn (chỉ dành cho phát triển).
OPIK_MCP_AS_URLchưa đặtURL Máy chủ Ủy quyền OAuth, được quảng bá trong /.well-known/oauth-protected-resource (RFC 9728) và được dùng làm mục tiêu proxy cho các truy vấn khám phá AS. Bắt buộc để các máy chủ MCP khởi động quy trình OAuth qua HTTP.
OPIK_MCP_RESOURCE_URIchưa đặtURI công khai chuẩn của máy chủ này, được quảng bá làm resource trong siêu dữ liệu tài nguyên được bảo vệ và được dùng để suy ra gợi ý WWW-Authenticate.
OPIK_MCP_OAUTH_VALIDATION_CACHE_TTL_S30Khoảng thời gian một câu trả lời "hợp lệ" từ điểm nội quan token của opik-backend được tin cậy trước khi yêu cầu tiếp theo trên cùng token OAuth hỏi lại. Giới hạn tải backend do xác thực từng yêu cầu và khoảng thời gian token hết hạn vẫn được chuyển tiếp (khoảng thời gian đó cũng kết thúc ở mã 401 đầu tiên backend trả về). Bị giới hạn bởi expires_at của chính token khi backend báo cáo.
OPIK_MCP_LOG_LEVELINFONgưỡng ghi log stderr.

Chọn giao thức vận chuyển

Hai dạng bearer, hai hợp đồng trên giao thức HTTP. Một token truy cập OAuth opik_mcp_at_… được xác thực trên mọi yêu cầu với điểm nội quan token của opik-backend (có bộ nhớ đệm, xem OPIK_MCP_OAUTH_VALIDATION_CACHE_TTL_S); token hết hạn hoặc bị thu hồi sẽ nhận HTTP 401 kèm WWW-Authenticate: Bearer error="invalid_token", đây là điều các máy chủ MCP dựa vào để thực hiện cấp quyền refresh_token âm thầm. API key của Opik không được xác thực cục bộ: nó được chuyển tiếp nguyên văn đến opik-backend, nơi duy nhất thực thi. Chọn giao thức vận chuyển theo hình thức triển khai:

Tình huốngGiao thức vận chuyển
Máy khách MCP và Opik trên cùng một máy (bản OSS cục bộ)stdio (khuyến nghị — đơn giản nhất, không cần cổng, không cần thiết lập OAuth)
Máy khách MCP cục bộ → Opik từ xa (Comet cloud / tự lưu trữ)stdio với OPIK_API_KEY, hoặc HTTP với OAuth (OPIK_MCP_AS_URL trỏ đến backend)
opik-mcp được lưu trữ sau cùng một biên với opik-backendHTTP — bearer được backend xác thực theo từng yêu cầu

Lưu ý cho bản OSS cục bộ: backend OSS không xác thực yêu cầu, vì vậy opik-mcp HTTP đứng trước nó cũng mở như chính REST API OSS. Giữ bind 127.0.0.1 mặc định (và ưu tiên stdio) trên các mạng dùng chung.

Đo lường từ xa

Sự kiện sử dụng ẩn danh (chỉ loại sự kiện + thời gian — không có nội dung truy vấn). Bản băm SHA-256 của API key được bao gồm để bộ phận hỗ trợ có thể tìm tài khoản của bạn; khóa thô không bao giờ rời khỏi tiến trình. Từ chối: OPIK_MCP_ANALYTICS_ENABLED=false.

BiếnMặc địnhGhi chú
OPIK_MCP_ANALYTICS_ENABLEDtrueĐặt thành false để tắt mọi đo lường từ xa.
OPIK_MCP_ANALYTICS_URLhttps://stats.comet.com/notify/event/Ghi đè cho staging.
OPIK_MCP_ANALYTICS_ENVIRONMENTprodThẻ trên mọi sự kiện (prod / staging / dev).
OPIK_MCP_ANALYTICS_SOURCEcomet.comBộ thu dùng giá trị này để đánh dấu on_prem=False. Bản cài tại chỗ nên ghi đè thành "" hoặc tên miền riêng của họ.
OPIK_MCP_ANALYTICS_CONNECT_TIMEOUT_S5.0Thời gian chờ kết nối HTTP.
OPIK_MCP_ANALYTICS_TOTAL_TIMEOUT_S10.0Thời gian chờ tổng yêu cầu HTTP.

Giới hạn máy chủ đã biết

Các máy chủ khác nhau về thời gian cho phép một lệnh gọi công cụ chạy:

  • Claude Code — không có thời gian chờ lệnh gọi công cụ được ghi nhận. Khuyến nghị.
  • Cursor — thời gian chờ 60s cố định không được đặt lại khi có tiến trình (lỗi upstream).
  • MCP Inspector — MAX_TOTAL_TIMEOUT giới hạn tổng thời lượng (mặc định 60s). Tăng giá trị này trong giao diện Inspector cho các thao tác dài.

Nếu một lệnh gọi bị kẹt, hãy đặt OPIK_MCP_LOG_LEVEL=DEBUG để có nhật ký yêu cầu đầy đủ.


Xử lý sự cố

OPIK_API_KEY không được nhận — biến không đến được tiến trình máy chủ. Trong Claude Code / Cursor / VS Code, biến môi trường chỉ áp dụng khi nằm trong khối env của cấu hình máy chủ MCP, không phải trong shell của bạn. Khởi động lại máy chủ sau khi chỉnh sửa.

Lệnh gọi Cursor hết thời gian ở 60s — lỗi đã biết của Cursor, không phải opik-mcp. Hoặc thu hẹp lệnh gọi (size nhỏ hơn, cửa sổ thời gian chặt hơn), hoặc chạy cùng thao tác trên Claude Code vốn không có giới hạn cứng.

Máy chủ không hiển thị, đăng nhập không mở, sai không gian làm việc, uvx không tìm thấy. Những vấn đề này được đề cập trong phần xử lý sự cố của tài liệu. opik mcp status (từ cùng CLI uvx opik) liệt kê mọi máy khách đã cấu hình máy chủ và liệu cấu hình của nó có bị lệch hay không.


Phát triển

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

Các mục tiêu phổ biến:

Mục tiêuChức năng
make installuv sync --locked --extra dev
make runChạy máy chủ MCP (stdio theo mặc định).
make run-devChạy với ghi log DEBUG + uvicorn --reload.
make devChạy qua mcp dev (trình bao bọc chế độ dev của Inspector).
make inspectKhởi chạy MCP Inspector với một máy chủ đang chạy.
make testuv run pytest -q.
make lintruff check + kiểm tra định dạng.
make formatruff format + ruff check --fix.
make typecheckmypy.
make checklint + typecheck + test.

Cấu trúc kho lưu trữ:

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

Nhận trợ giúp


Nâng cấp từ v2? Máy chủ TypeScript cũ vẫn được phát hành trên npm dưới tên opik-mcp@^2 (npx -y opik-mcp); mã nguồn của nó nằm ở thẻ git legacy-typescript-final. Xem legacy/typescript/DEPRECATED.md để biết chính sách hỗ trợ.


Giấy phép

Apache-2.0.