Comet Opik

आधिकारिक

अपने Opik लॉग, ट्रेस, प्रॉम्प्ट और अपने LLMs से प्राप्त सभी अन्य टेलीमेट्री डेटा को प्राकृतिक भाषा में क्वेरी और विश्लेषण करें।

Comet Opik MCP के साथ आप क्या कर सकते हैं?

  • प्रोजेक्ट के अनुसार ट्रेस खोजें — पूछें कि आज किसी प्रोजेक्ट में कौन-से ट्रेस विफल हुए, और त्रुटि की जानकारी, अवधि या टोकन उपयोग के आधार पर फ़िल्टर करें।
  • कोई भी Opik इकाई पढ़ें — किसी प्रोजेक्ट, ट्रेस, स्पैन, डेटासेट, प्रयोग, प्रॉम्प्ट, थ्रेड या Diagnostics समस्या को आईडी, नाम या opik:// URI से प्राप्त करें।
  • स्कोर और टिप्पणियाँ लॉग करें — राइट टूल के ज़रिए किसी फ़ीडबैक मेट्रिक पर कारण सहित ट्रेस को स्कोर करें या टिप्पणियाँ जोड़ें।
  • प्रॉम्प्ट के संस्करण सहेजें — डेटासेट और प्रयोगों के साथ नए प्रॉम्प्ट संस्करण बनाएँ और संग्रहीत करें।
  • राइट स्कीमा देखें — भेजने से पहले मान्य पेलोड बनाने के लिए किसी राइट ऑपरेशन का स्कीमा पूछें।
  • प्रोजेक्ट की स्थिति जाँचें — पिछले 7 दिनों के ट्रेस की संख्या, त्रुटि दर, औसत अवधि और कुल लागत जानने के लिए प्रोजेक्ट पढ़ें।

दस्तावेज़

Opik MCP Server

Comet द्वारा निर्मित, ओपन-सोर्स LLM ऑब्ज़र्वेबिलिटी और मूल्यांकन प्लेटफ़ॉर्म Opik के लिए आधिकारिक Model Context Protocol (MCP) सर्वर। अपने AI होस्ट (Claude Code, Cursor, VS Code Copilot, Codex, opencode या किसी भी MCP क्लाइंट) को सीधे अपने Opik वर्कस्पेस से जोड़ें: ट्रेस पढ़ें, स्कोर लॉग करें और प्रॉम्प्ट के वर्शन सेव करें—सब कुछ चैट से।

उन 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

तुरंत शुरू करें

एक कमांड आपकी मशीन के AI क्लाइंट में Opik सेट अप करता है, जिसमें Claude Code भी शामिल है। यह आपका Opik ढूँढ़ता है (~/.opik.config में सेव किया हुआ, localhost पर चल रहा, या फिर आपसे पूछता है कि कौन-सा), MCP सर्वर रजिस्टर करता है, Opik स्किल पैक इंस्टॉल करता है और कनेक्शन जाँचता है। Opik Cloud पर संभालने के लिए कोई API key नहीं है: आपका क्लाइंट ब्राउज़र में साइन इन करता है। इसके लिए uv और किसी Opik SDK की ज़रूरत नहीं है:

uvx opik@latest mcp configure

टर्मिनल के बिना, जैसे किसी कोडिंग एजेंट या स्क्रिप्ट से, क्लाइंट का नाम दें:

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

--ai-client में codex, cursor, vscode और opencode भी लिए जा सकते हैं। इस तरह चलाने पर यह ~/.opik.config में सेव Opik का उपयोग करता है, जिसमें API key भी शामिल है, या localhost पर जवाब देने वाले Opik का; अन्यथा रुककर --deployment के लिए पूछता है।

"install opik mcp" करने के लिए कहे गए कोडिंग एजेंट को, उपयोगकर्ता से क्या पूछना है, इन चरणों सहित, uvx opik-mcp@latest --help से पूरी प्रक्रिया मिलती है। ये नीचे दिए गए कोडिंग एजेंट से इंस्टॉल करें वाले चरणों के समान हैं।

इसे हाथ से सेट अप करें में दिए गए क्लाइंट कमांड से सर्वर को हाथ से रजिस्टर करने पर, आप कौन-सा 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 नहीं और कोई वर्कस्पेस सेट करने की ज़रूरत नहीं: सर्वर उसी वर्कस्पेस में काम करता है जिसे आप साइन इन करते समय चुनते हैं। इसे जोड़ने के बाद नया सेशन शुरू करें और पूछें: "मेरे Opik प्रोजेक्ट की सूची दिखाएँ"।

तुरंत शुरू करें कमांड, स्किल पैक के साथ, Claude Code, Codex, Cursor, VS Code Copilot और opencode के लिए इसे सेट अप करता है। Claude Code में प्लगइन यही काम एक कमांड में करता है। नीचे दिए गए बटन इसे Cursor या VS Code में एक क्लिक से जोड़ते हैं; इसे हाथ से रजिस्टर करने के अन्य तरीके इसे हाथ से सेट अप करें में दिए गए हैं।

Add to Cursor Install in VS Code

Claude Code प्लगइन

opik प्लगइन Opik स्किल इंस्टॉल करता है और Opik Cloud के लिए होस्ट किया गया MCP सर्वर रजिस्टर करता है:

/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 से साइन इन करें। MCP OAuth सर्वर चलाने वाले सेल्फ-होस्टेड Comet के लिए, इसे claude mcp add --transport http opik-mcp https://<host>/opik/api/v1/mcp से जोड़ें; किसी अन्य सेल्फ-होस्टेड या ओपन-सोर्स Opik के लिए तुरंत शुरू करें कमांड इस्तेमाल करें। फिर /mcp में plugin:opik:opik-cloud को बंद करें। Claude Code इस मार्केटप्लेस से प्लगइन को अपने-आप अपडेट नहीं करता: /plugin marketplace update opik चलाएँ, फिर /plugin update opik@opik, या मार्केटप्लेस के लिए /plugin में ऑटो-अपडेट चालू करें। यह मार्केटप्लेस main उपलब्ध कराता है, जो नवीनतम रिलीज़ से आगे हो सकता है। अपडेट केवल हर रिलीज़ पर, प्लगइन का वर्शन बदलने पर ही आता है।

अगर आपने पहले इसी URL पर opik-mcp जोड़ा था, तो 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 की ओर निर्देशित करते हैं:

आपका OpikEnv vars
इस मशीन पर ओपन-सोर्स OpikOPIK_URL=http://localhost:5173/api
सर्वर पर ओपन-सोर्स OpikOPIK_URL=https://<host>/api, और केवल तभी OPIK_API_KEY जब डिप्लॉयमेंट में ऑथेंटिकेशन जोड़ा गया हो
सेल्फ-होस्टेड Comet प्लेटफ़ॉर्म (Opik UI यहाँ है: 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 URL में /opik/ के बाद वाले हिस्से को OPIK_WORKSPACE पर सेट करें; इसे छोड़ने पर रीड आपके खाते के डिफ़ॉल्ट वर्कस्पेस से होंगे, और कोई त्रुटि नहीं बताएगी कि ऐसा हुआ है।
  • MCP OAuth सर्वर चलाने वाला सेल्फ-होस्टेड Comet (डिफ़ॉल्ट रूप से बंद) होस्टेड फ़्लो का उपयोग कर सकता है, यहाँ: https://<host>/opik/api/v1/mcp।
  • हर मान की जगह अपना मान डालें। सर्वर <your-workspace> या ${input:OPIK_WORKSPACE} जैसे प्लेसहोल्डर वर्कस्पेस स्वीकार नहीं करता; प्लेसहोल्डर URL ज्यों का त्यों भेजा जाता है और कनेक्ट नहीं हो पाता।
  • env ब्लॉक में OPIK_MCP_ANALYTICS_SOURCE="" सेल्फ-होस्टेड इंस्टॉल को टेलीमेट्री इवेंट पर cloud-Comet स्रोत लेबल से बाहर रखता है।

किसी क्लाइंट में सर्वर जोड़ने से पहले सेटिंग जाँचें: इसे उसी env और --check के साथ चलाएँ। यह Opik को एक कॉल करता है और वर्कस्पेस तथा वहाँ दिखने वाले प्रोजेक्ट की संख्या प्रिंट करता है, या दस्तावेज़ों के लिंक के साथ बताता है कि क्या ठीक करना है, और 0 या 1 के साथ बाहर निकलता है। नया सेशन शुरू होने से पहले क्लाइंट यह नहीं बता सकता: गलत key होने पर भी Claude Code Connected दिखाता है, और Codex तब तक कुछ शुरू नहीं करता।

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

फिर इसे अपने क्लाइंट में रजिस्टर करें: लोकल सर्वर, हाथ से।


कोडिंग एजेंट से इंस्टॉल करें

किसी AI एजेंट को सर्वर इंस्टॉल करने के लिए कहे जाने पर, जैसे "install opik mcp"। लक्ष्य यह है कि सर्वर उपयोगकर्ता के Opik के लिए रजिस्टर हो, Opik स्किल पैक इंस्टॉल हो और उपयोगकर्ता साइन इन हो। इस मशीन से पता करें कि कौन-सा Opik है, और उपयोगकर्ता से केवल वही पूछें जो आप खुद नहीं जान सकते: हर संदेश में एक सवाल, और अगले सवाल से पहले हर जवाब। चरण 3 का इंस्टॉलर पूरा सेटअप एक बार में करता है, इसलिए उसे चलाने से पहले चरण 1 और 2 तय कर लें। uvx opik-mcp@latest --help ये चरण प्रिंट करता है।

  1. देखें कि क्या मौजूद है।

    uvx opik@latest mcp status
    

    यह ~/.opik.config में सेव Opik (URL और वर्कस्पेस, key कभी नहीं) और उन क्लाइंट को दिखाता है जिनमें सर्वर पहले से मौजूद है। 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 भी शामिल है, इसलिए key न पूछें।
    • ~/.opik.config नहीं है: curl -s http://localhost:5173/api/is-alive/ping। जवाब का मतलब है कि इस मशीन पर ओपन-सोर्स Opik है। सैंडबॉक्स वाले शेल में, जैसे Codex के शेल में, जवाब न मिलने का मतलब यह हो सकता है कि शेल में नेटवर्क नहीं है, न कि Opik मौजूद नहीं है।
    • दोनों में से कोई नहीं: पूछें, और खुद से कोई विकल्प न चुनें। प्रोजेक्ट में Opik URL, जैसे .env में OPIK_URL_OVERRIDE, इसे हाँ-या-नहीं वाला सवाल बना देता है। अन्यथा पूछें: "आप कौन-सा 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 सहित, अलग रखता है। अगर दोनों में से कोई नहीं है, तो चरण 2 में उपयोगकर्ता द्वारा बताए गए Opik के लिए फ़्लैग जोड़ें:

    उपयोगकर्ता का Opikजोड़ें
    Opik Cloud, www.comet.com--deployment cloud
    ओपन-सोर्स Opik--deployment local, और localhost पर न होने पर --url <url>
    सेल्फ-होस्टेड Comet प्लेटफ़ॉर्म, जिसके URL में /opik/ है--deployment self-hosted --url <url> --workspace <workspace>, और शेल में OPIK_API_KEY

    अगर यह विफल हो, जैसे Opik जवाब न दे, तो उपयोगकर्ता को बताएँ कि इसने क्या प्रिंट किया और क्या जाँचना है, जैसे VPN या URL। किसी दूसरे Opik पर स्विच न करें।

  4. Opik Cloud के लिए साइन-इन। अगर इंस्टॉलर बताए कि सर्वर ने अभी तक साइन इन नहीं किया है, तो उपयोगकर्ता को खुद चलाने के लिए claude mcp login opik-mcp दें, या Claude Code सेशन में /mcp दें; इसे खुद न चलाएँ, क्योंकि यह ब्राउज़र का इंतज़ार करता है। claude.ai कनेक्टर में /mcp से साइन इन करें। साइन-इन के दौरान वर्कस्पेस पूछा जाता है; अगर ~/.opik.config में कोई सेव है, तो उसका नाम बताएँ।

  5. पूरा करें। बताएँ कि क्या इंस्टॉल हुआ और क्या बाकी है। स्किल पैक का नाम बताएँ: Opik स्किल, जो हर प्रोजेक्ट के लिए इंस्टॉल किए गए हैं और एजेंट को Opik से इंस्ट्रूमेंट, मूल्यांकन और डीबग करना सिखाते हैं। क्लाइंट सेशन शुरू होने पर MCP सर्वर और स्किल लोड करते हैं: उपयोगकर्ता से नया सेशन शुरू करने को कहें, फिर आज़माएँ "मेरे Opik प्रोजेक्ट की सूची दिखाएँ"।

हर स्थिति में:

  • उपयोगकर्ता से चैट में API key पेस्ट करने को न कहें। होस्टेड सर्वर को इसकी ज़रूरत नहीं; अन्यथा इसे शेल एनवायरनमेंट ("$OPIK_API_KEY") से लें, या उपयोगकर्ता को कमांड चलाने दें।

  • वर्कस्पेस का अनुमान न लगाएँ। यह उपयोगकर्ता के Opik URL में comet.com/opik/ के बाद (या सेल्फ-होस्टेड Comet पर /opik/ के बाद) वाला हिस्सा है।

  • ~/.claude.json या ~/.opik.config प्रिंट न करें: दोनों में API key हो सकती है। uvx opik@latest mcp status और claude mcp list से ज़रूरी जानकारी मिलती है, और इंस्टॉलर कॉन्फ़िगरेशन खुद पढ़ता है।

  • अगर अनुमति जाँच किसी कमांड को रोकती है, तो उससे बचने का तरीका न निकालें। उपयोगकर्ता को कमांड चलाने के लिए दें (Claude Code में, प्रॉम्प्ट से चलाने से पहले !)। ऐसे क्लाइंट के लिए जिसे इंस्टॉलर नहीं पहचानता, इसे हाथ से सेट अप करें में दिए गए कमांड से हाथ से रजिस्टर करें: Opik Cloud के लिए होस्टेड सर्वर और बाकी के लिए लोकल सर्वर।

  • लोकल सर्वर रजिस्टर करने से पहले, उसे उस env और --check के साथ चलाएँ जिन्हें आप पास करेंगे, और OPIK_API_KEY को कमांड में लिखने के बजाय शेल में export करें: OPIK_URL=http://localhost:5173/api uvx opik-mcp@latest --check. यह 0 के साथ बाहर निकलता है और उस workspace का नाम बताता है जिसे वह देखता है, या बताता है कि क्या ठीक करना है। रजिस्टर करने के बाद, गलत key होने पर भी Claude Code Connected दिखाता है, और Codex कोई जाँच नहीं करता।

  • Claude Code किसी मौजूदा opik-mcp एंट्री के ऊपर जोड़ने से मना करता है, इसलिए पहले उसे claude mcp remove opik-mcp --scope user से हटाएँ; Codex का add उसे बदल देता है।

  • रजिस्टर करने के बाद, Claude Code में केवल status line पढ़ें: claude mcp get opik-mcp | grep Status. पूरा आउटपुट env ब्लॉक प्रिंट करता है, जिसमें API key भी शामिल है। होस्टेड सर्वर तब तक ! Needs authentication दिखाता है, जब तक claude mcp login opik-mcp नहीं चलाया जाता। Codex में ऐसा कुछ नहीं है जो session शुरू होने से पहले सर्वर चालू करे; codex mcp get opik-mcp दिखाता है कि क्या संग्रहीत किया गया था, और env मानों को छिपाकर दिखाता है।


इसे हाथ से सेट अप करें (Opik जाँच नहीं, skill pack नहीं)

Quick start कमांड Claude Code, Codex, Cursor, VS Code Copilot और opencode के लिए यह सब करता है, और यह भी जाँचता है कि आप कौन-सा Opik इस्तेमाल करते हैं तथा skill pack इंस्टॉल करता है। हाथ से रजिस्टर केवल किसी दूसरे क्लाइंट के लिए करें, या यह देखने के लिए कि इंस्टॉलर क्या लिखता है। उपयोगकर्ता के लिए इंस्टॉल करने वाला coding agent इंस्टॉलर चलाता है: coding agent से इंस्टॉल करें देखें।

होस्टेड सर्वर (Opik Cloud)

Claude Code, हाथ से

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

फिर Claude Code session में /mcp → Authenticate से साइन इन करें। इससे ब्राउज़र खुलता है, इसलिए कीबोर्ड पर मौजूद व्यक्ति यह करता है; अपने टर्मिनल से claude mcp login opik-mcp भी यही काम करता है। --scope user सर्वर को हर project में उपलब्ध कराता है; इसके बिना Claude Code इसे केवल मौजूदा directory के लिए रजिस्टर करता है। SSH पर, claude mcp login opik-mcp --no-browser साइन-इन URL प्रिंट करता है, जिसे अपनी मशीन पर खोलें; आखिरी चरण के लिए interactive terminal चाहिए (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, हाथ से

होस्टेड सर्वर के नीचे दिए गए बटन का इस्तेमाल करें, या अपने workspace के .vscode/mcp.json में अथवा अपने user 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 के ज़रिए इससे जुड़ सकता है।

API key के साथ Opik Cloud

जहाँ कोई ब्राउज़र साइन-इन पूरा नहीं कर सकता, जैसे जब कोई agent script से बिना निगरानी चलता हो या किसी क्लाइंट में MCP OAuth समर्थन न हो, वहाँ comet.com/api/my/settings/ से API key इस्तेमाल करें और लोकल सर्वर को Opik Cloud की ओर इंगित करें:

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

दूसरे क्लाइंट अपने env ब्लॉक में यही दो variables लेते हैं। OPIK_WORKSPACE को अपने Opik URL में comet.com/opik/ के बाद वाले segment पर सेट करें (https://www.comet.com/opik/acme-ai/projects → acme-ai)। इसे छोड़ देने पर, सर्वर default भेजता है, जिसे Comet आपके account के default workspace में बदल देता है; इसलिए बिना किसी error के गलत workspace से पढ़ा जा सकता है।

लोकल सर्वर (self-hosted और open-source Opik)

उदाहरणों में लोकल open-source Opik का इस्तेमाल किया गया है। self-hosted Comet के लिए, तालिका के तीन variables बदलें। सर्वर जोड़ने के बाद, नया session शुरू करें और पूछें: "मेरे Opik projects की सूची दिखाएँ"।

Claude Code, हाथ से

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

self-hosted Comet पर, key को अपने shell के OPIK_API_KEY में रखकर:

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 या key सही हैं, क्योंकि Opik तक केवल tool call पहुँचता है; यह काम --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 में दिए गए variables और env_vars में दिए गए नाम देता है, इसलिए आपके shell में export की गई key अन्यथा उस तक नहीं पहुँचती।

Cursor, हाथ से

~/.cursor/mcp.json (global) या .cursor/mcp.json (project) में जोड़ें, या 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 60s timeout. Cursor tool-call पर सख्त timeout लागू करता है, जो progress notifications से रीसेट नहीं होता। ज्ञात host सीमाएँ देखें।

VS Code Copilot, हाथ से

अपने workspace के .vscode/mcp.json में, या अपने user 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 server (npm opik-mcp@2) deprecated है और 2026-11-15 को requests देना बंद कर देगा। नए इंस्टॉल के लिए Quick start कमांड चलाएँ; uvx opik-mcp वह कमांड है जिसे क्लाइंट सर्वर शुरू करने के लिए चलाता है, इंस्टॉलर नहीं। Opik Cloud पर मौजूदा config को स्थानांतरित करने के लिए, होस्टेड सर्वर पर जाएँ और API key हटा दें। अन्यथा, अपने MCP client config में npx -y opik-mcp को uvx opik-mcp से बदलें। कुछ env vars के नाम बदल गए हैं और command-line flags अब पढ़े नहीं जाते: https://github.com/comet-ml/opik-mcp/blob/main/legacy/typescript/MIGRATION.md देखें। समर्थन नीति: DEPRECATED.md। TypeScript source git tag legacy-typescript-final पर है।


Tools

opik-mcp एक छोटा, परिणाम-केंद्रित इंटरफ़ेस देता है, जो पूरा lifecycle कवर करता है (पढ़ें → annotate करें → curate करें → बनाएँ → दोहराएँ)।

Toolउद्देश्य
readid / name / opik:// URI से सार्वभौमिक पढ़ना
listवैकल्पिक name filter + pagination के साथ सार्वभौमिक सूची
writeसार्वभौमिक लेखन — traces/spans लॉग करना, score देना, comment करना, prompts सहेजना, datasets और experiments प्रबंधित करना
schemawrite-operation schemas का निरीक्षण करना (LLM द्वारा मान्य payloads बनाने के लिए इस्तेमाल किया जाता है)
read_skillइस server के साथ बंडल की गई Opik agent skills में से एक पढ़ें

read

किसी भी "मुझे X दिखाएँ" सवाल के लिए एक tool। यह एक entity_type और एक id (UUID या, नाम वाले प्रकारों के लिए, name) अथवा पूरा opik:// URI लेता है। Composite reads (trace, prompt, thread, agent_insights_issue) अपने children को inline करते हैं, ताकि एक ही call पूरी तस्वीर लौटा दे।

आपके नाम से माँगा गया record पूरा लौटता है। Inline किए गए children पूरे नहीं होते: उनके bodies backend के truncate=true से लिए जाते हैं, इसलिए ClickHouse में ~10 KB से बड़ा field काट दिया जाता है और base64 images को "[image]" से बदल दिया जाता है — वरना 200 spans में एक ही attachment दोहराने की लागत बाकी सब से ज़्यादा होती। उत्तर spanBodies / messageBodies में इसकी जानकारी देता है, और कोई भी child अपने read("span", id) या read("trace", trace_id) के ज़रिए फिर से पूरा मिल जाता है; ये ऐसे endpoints पर जाते हैं जिनमें truncate parameter होता ही नहीं।

Inline की गई collection की लंबाई भी सीमित होती है: 200 spans, 200 turns, 100 prompt versions। इससे आगे, spansTruncated / messagesTruncated / versionsTruncated का मान true होता है और उसके साथ वाली moreSpans / moreMessages / moreVersions line count और वह सटीक list(...) call देती है, जो inline किए गए हिस्से के रुकने के स्थान से आगे जारी रहती है।

समर्थित entities: project, trace, span, dataset, dataset_item, experiment, prompt, thread, agent_insights_issue. project, experiment, prompt, dataset के लिए name-आधारित lookup उपलब्ध है (धीमा — दो API calls — और कई matches लौटा सकता है)। thread और agent_insights_issue project-scoped हैं: project_id या project_name, अथवा ऐसा link/URI पास करें जिसमें project शामिल हो। dataset और dataset_item को पहले test_suite और test_suite_item कहा जाता था; पुराने नाम अब भी काम करते हैं, लेकिन उनका प्रचार नहीं किया जाता और नए code में नए नाम इस्तेमाल करने चाहिए।

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

Opik UI से कॉपी किया गया link id के रूप में काम करता है: thread link या Diagnostics page link में project शामिल होता है, इसलिए project_id की ज़रूरत नहीं होती और entity type link से लिया जाता है।

project read एक ही call में "मेरा project कैसा चल रहा है" का जवाब देता है। यह {project, summary, vocabulary, contains, url} लौटाता है: record, फिर Logs page पर cards के रूप में दिखने वाले चार आँकड़े (trace count, error rate, average duration, total cost), पिछले 7 दिनों के लिए उससे पहले के 7 दिनों की तुलना में, केवल SDK traffic, जैसा स्क्रीन पर दिखता है। since / until उस अवधि को बदलते हैं; since="30d" वह है जिसे UI खोलता है। जिस अवधि में कोई trace न हो, उसकी rate या average null के रूप में लौटती है, क्योंकि बिना traffic वाले सप्ताह में 0% errors को स्वस्थ सप्ताह समझा जा सकता है।

vocabulary वह नक्शा है जिसकी ज़रूरत बाकी कुछ भी पूछने से पहले होती है: project के feedback score names, उसके token usage keys और उसके traces को score करने वाले automation rules। ये वे names हैं जो filter में या नीचे दिए गए series= में जाते हैं; इनका अनुमान लगाने पर खाली page मिलता है, जो अच्छी खबर जैसा लगता है। Score names और rules की सीमा है, लेकिन कुल संख्या हमेशा सही बताई जाती है और बाकी लौटाने वाली call का नाम दिया जाता है; usage keys पूरी सूची में दी जाती हैं, क्योंकि उन्हें गिनाने का कोई दूसरा तरीका नहीं है। contains सबसे नया experiment, dataset, prompt version और optimization run बताता है, ताकि "यहाँ क्या होता रहा है" के लिए चार और calls की ज़रूरत न पड़े। जो हिस्सा लोड नहीं हो पाता, वह खाली दिखने के बजाय इसकी जानकारी देता है; और खाली हिस्से को छोड़ दिया जाता है।

agent_insights_issue read {issue, example_trace_ids, details} लौटाता है: Diagnostics issue record (name, description, cause, suggested fix, severity, status), उससे जुड़े traces के deduplicated ids (वही sample जो Diagnostics page दिखाता है — किसी एक को read("trace", id) से खोलें), और प्रति-दिन का विवरण। Trace bodies inline नहीं किए जाते, इसलिए read एक backend call तक सीमित रहता है। since / until प्रति-दिन की rows को सीमित करते हैं; default में पूरा समय शामिल होता है। जब server को Opik URL और session का workspace पता होता है, तो read में url (issue का Diagnostics page) और trace_url_template (किसी भी उदाहरण trace का deep link) भी शामिल होते हैं, ताकि assistant आपको क्लिक करने योग्य चीज़ दे सके; ऐसे OAuth session में, जिसका workspace resolve नहीं हो सका, links का अनुमान लगाने के बजाय उन्हें छोड़ दिया जाता है।

Traces में स्वयं कोई URL नहीं होता — किसी trace का link उन fields से निकाला नहीं जा सकता जो read या list लौटाते हैं, और अनुमानित URL 404 देता है। इसके बजाय, session instructions में उसके लिए एक template दिया गया है, .../v1/session/redirect/projects/?trace_id={trace_id}&path=..., ताकि assistant उसमें id भरकर आपको link दे सके। यह opik-backend के redirect से होकर जाता है, जो trace से project और workspace resolve करता है; इसलिए यह वहाँ भी काम करता है जहाँ सीधा project URL काम नहीं कर सकता, जिसमें ऐसा OAuth session भी शामिल है जिसका workspace resolve नहीं हुआ हो। यह वही link है जिसे Python SDK किसी trace के लिए प्रिंट करता है।

list

Pagination के साथ collection ब्राउज़ करें या खोजें। Project-scoped प्रकारों (trace, span, thread, agent_insights_issue, dataset_item, prompt_version) के लिए parent चाहिए: project UUID या name, dataset UUID, या prompt UUID।

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

Filters. trace, span, thread, experiment और dataset_item OQL string लेते हैं, जो SDK के search_traces(filter_string=…) वाली ही grammar है:

<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 ही एकमात्र कनेक्टर है।

UI के Logs पेज की तरह, ट्रेस, स्पैन और थ्रेड सूचियों में source = "sdk" जोड़ा जाता है, ताकि इवैल्युएटर, प्लेग्राउंड और एक्सपेरिमेंट ट्रेस रास्ते में न आएँ; उन्हें देखने के लिए खुद source नाम दें। पहली आउटपुट लाइन लागू किए गए फ़िल्टर को दोहराती है।

गलत फ़िल्टर बैकएंड तक पहुँचने से पहले ही विफल हो जाता है और उसे ठीक करने के लिए ज़रूरी जानकारी देता है: सिंटैक्स त्रुटि की स्थिति, सबसे मिलता-जुलता फ़ील्ड नाम, फ़ील्ड के प्रकार के लिए मान्य ऑपरेटर, या अपेक्षित मान का फ़ॉर्मैट। सीमित मानों वाले फ़ील्ड (source, span type, thread status, visibility_mode) भी उनके विरुद्ध जाँचे जाते हैं, जिसमें in सूची का हर तत्व शामिल है। source वह एकमात्र फ़ील्ड है जिसे बैकएंड खुद वैलिडेट करता है, और अज्ञात मान पर 400 के बजाय 500 देता है, इसलिए बड़े अक्षर के लिए 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 पूरे पेलोड के किसी सबस्ट्रिंग के लिए (पूरा स्कैन — जहाँ संभव हो, कुंजी का नाम दें), साथ ही id, tags, source, trace_id, span_id और टाइमस्टैम्प के लिए। data.<key> केवल छह स्ट्रिंग ऑपरेटर लेता है (=, !=, contains, not_contains, starts_with, ends_with); बैकएंड तुलना पर 400 देता है, इसलिए कॉल से पहले ही इसे अस्वीकार कर दिया जाता है। एंडपॉइंट में सॉर्टिंग और फ़्री-टेक्स्ट खोज नहीं है — 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 के साथ यही सूची तुलना होती है — हर रन संलग्न वाले केस — और यह रन पर फ़िल्टर करती है (feedback_scores.<name>, output, duration)। ये दो अलग-अलग बैकएंड एंडपॉइंट के फ़ील्ड सेट हैं: 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"। कॉल से पहले फ़ील्ड को एंटिटी की सॉर्ट की जा सकने वाली सूची के विरुद्ध जाँचा जाता है, क्योंकि बैकएंड उन फ़ील्ड को चुपचाप अनदेखा करता है जिनके आधार पर वह सॉर्ट नहीं कर सकता। बहुत बड़े वर्कस्पेस में बैकएंड सॉर्टिंग पूरी तरह हटा देता है; ऐसा होने पर हेडर इसकी सूचना देता है।

dataset_item केवल तुलना के रूप में सॉर्ट करता है (experiment_ids के साथ): आइटम्स एंडपॉइंट कोई सॉर्टिंग पैरामीटर नहीं लेता, इसलिए साधारण सूची पर सॉर्ट को हटाने के बजाय अस्वीकार किया जाता है।

समयावधि और खोज। trace, span और thread में since और until होते हैं; हर एक सापेक्ष अवधि ("30m", "1h", "7d") या टाइमज़ोन वाला ISO-8601 इंस्टेंट हो सकता है, इसलिए "पिछले घंटे" के लिए घड़ी देखकर हिसाब लगाने की ज़रूरत नहीं। समयावधि रिकॉर्ड बनने के समय पर आधारित है, जो बैकएंड के लिए सस्ता है और लाइव ट्रैफ़िक के लिए कुछ सेकंड के भीतर start_time से मेल खाता है। सटीक सीमा के लिए, start_time को filters में रखें। यही तीन प्रकार search भी लेते हैं, जो ID, नाम, इनपुट, आउटपुट, मेटाडेटा, टैग और थ्रेड ID में कहीं भी मिलने वाला फ़्री टेक्स्ट है। खोज बैकएंड पर पूरे प्रोजेक्ट को स्कैन करती है, इसलिए बड़े प्रोजेक्ट पर पहली कॉल में दसियों सेकंड लग सकते हैं। इन कॉल्स का टाइमआउट 60 सेकंड है। since जोड़ने से ये फिर तेज़ हो जाती हैं।

टेबल पढ़ना। अवधि को duration_ms / ttft_ms के रूप में लेबल किया जाता है और पूर्ण मिलीसेकंड में दिखाया जाता है; फ़ील्ड filters और sort में duration ही रहता है। टाइमस्टैम्प सेकंड तक और लागत साधारण दशमलव के रूप में दिखाई जाती है। प्रोजेक्ट पंक्तियों में last_updated_trace_at होता है, जिससे पता चलता है कि किस प्रोजेक्ट में लाइव ट्रैफ़िक है; थ्रेड पंक्तियों में पहला संदेश होता है। समयावधि के दौरान खाली पेज बताता है कि प्रोजेक्ट में आख़िरी ट्रेस कब आया था, और डिफ़ॉल्ट 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 MCP के ज़रिए Diagnostics पेज है: किसी प्रोजेक्ट के लिए Opik के Diagnostics जॉब द्वारा समूहित बार-बार होने वाली विफलताएँ, UI की तरह क्रमबद्ध (सबसे हाल में देखी गई पहले)। कॉलम हैं severity, status, total_occurrences (अब तक का कुल योग), latest_count (सबसे हाल की रिपोर्ट का दिन, वह संख्या जिसका उल्लेख समस्या के अपने विवरण में है) और last_seen। डिफ़ॉल्ट रूप से खुली समस्याएँ दिखाई जाती हैं; बाकी के लिए status="resolved" या "closed" दें। read और list को issue नाम से भी जाना जाता है, जो UI में इनके लिए इस्तेमाल होता है; लंबा नाम entity_type enum में है, इसलिए वहाँ यह एंटिटी दो बार नहीं दिखती। गिनतियाँ अब तक की हैं, ताकि वे UI से मेल खाएँ; वही since / until जो ट्रेस के लिए हैं, समयावधि को सीमित करते हैं और UTC रिपोर्ट दिनों तक काटे जाते हैं, क्योंकि Diagnostics हर दिन के हिसाब से एग्रीगेट करता है।

खाली सूची बताती है कि वह खाली क्यों है, क्योंकि "कुछ भी खराब नहीं है" और "किसी ने Diagnostics चालू नहीं किया" अन्यथा एक जैसे दिखते हैं। पाँच स्थितियाँ हैं: इस डिप्लॉयमेंट पर Diagnostics उपलब्ध नहीं है, इस प्रोजेक्ट के लिए सक्षम नहीं है, बंद है, सक्षम है लेकिन हाल में स्कैन नहीं किया गया, या सक्षम और साफ़ है तथा आख़िरी स्कैन का समय दिया गया है। जिन स्थितियों पर आप कार्रवाई कर सकते हैं, वे करने के लिए कॉल का नाम बताती हैं, और हर स्थिति प्रोजेक्ट के Diagnostics पेज से लिंक करती है।

गैर-खाली सूची में तारीखें दी होती हैं। समस्याएँ आख़िरी स्कैन में समूहित की गई समस्याएँ हैं, इसलिए जवाब का अंत Report covers data through <time> से होता है, और जब माँगी गई समयावधि उससे आगे तक जाती है, तो जवाब छूटे हुए अंतिम हिस्से का नाम और उसे पूरा करने का तरीका बताता है: जब दोबारा स्कैन पर्याप्त पीछे तक पहुँचे तो ट्रिगर करें, अन्यथा दिए गए 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 किसी प्रोजेक्ट के एक मेट्रिक को समय के बकेट की टेबल के रूप में चार्ट करता है: ट्रेस, स्पैन और थ्रेड की गिनती, अवधि, त्रुटि दरें, लागत, टोकन उपयोग और फ़ीडबैक स्कोर। यह ओवरव्यू के बाद आने वाले सवाल का जवाब देता है: कुछ कब बदला।

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 उसी एंटिटी के फ़ील्ड इस्तेमाल करता है जिससे मेट्रिक संबंधित है, इसलिए स्पैन मेट्रिक को स्पैन फ़ील्ड से फ़िल्टर किया जाता है।

breakdown हर बकेट को tags, name, error_info, error_type, model, provider, span_type, guardrail_name या metadata.<key> के आधार पर बाँटता है। हर मेट्रिक इन सभी को स्वीकार नहीं करता, और सात मेट्रिक इनमें से किसी को भी स्वीकार नहीं करते; टूल जानता है कि कौन-से विकल्प मान्य हैं और बैकएंड को कॉल करने से पहले इसकी सूचना देता है, साथ ही जहाँ उपलब्ध हो, उसी सवाल का जवाब देने वाले मेट्रिक का नाम भी बताता है। तीन परिवार एक साथ कई सीरीज़ लौटाते हैं (अवधि के लिए p50/p90/p99, हर नाम के लिए फ़ीडबैक स्कोर, हर कुंजी के लिए टोकन उपयोग), और ग्रुपिंग के समय बैकएंड इनमें से एक को ही चार्ट करता है, इसलिए series= उसे चुनता है: एक पर्सेंटाइल, स्कोर का नाम, या उपयोग की कुंजी। अवधि का डिफ़ॉल्ट p50 और टोकन उपयोग का डिफ़ॉल्ट total_tokens है; इस्तेमाल किया गया विकल्प पहली लाइन में दोहराया जाता है।

खाली बकेट छोड़ दिए जाते हैं और नीचे उनकी गिनती दी जाती है, इसलिए शांत महीने में शून्य के कॉलम के बजाय कुछ पंक्तियाँ होती हैं, और बिना ट्रेस वाले बकेट की दर शून्य के रूप में दिखाने के बजाय अनुपस्थित रहती है।

मेट्रिक टेबल, अंतराल और हर मेट्रिक के लिए ग्रुपिंग मैट्रिक्स के लिए schema("list.project_metric") पूछें।

प्रोजेक्ट के नाम। score_name किसी प्रोजेक्ट में दर्ज फ़ीडबैक स्कोर के नामों की सूची देता है और online_rule उस पर कॉन्फ़िगर किए गए ऑटोमेशन नियम इवैल्युएटर की सूची देता है, जहाँ से इनमें से ज़्यादातर नाम आते हैं। दोनों वही सूचियाँ हैं जो read("project", …) देता है, पूरी और पेजिनेटेड, जब ओवरव्यू में सीमित संस्करण पर्याप्त न हो।

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

write

सार्वभौमिक राइट डिस्पैचर। operation + data दें और डिस्पैचर पेलोड को वैलिडेट करता है, सही REST verb लागू करता है और बैकएंड का जवाब लौटाता है।

ऑपरेशन:

ऑपरेशनयह क्या करता है
trace.createएक ट्रेस (या बैच) लॉग करता है। स्पैन / स्कोर / टिप्पणियों का पैरेंट।
trace.updateमौजूदा ट्रेस को अंतिम रूप देता है या उसमें संशोधन करता है।
span.createमौजूदा ट्रेस पर एक स्पैन (या बैच) लॉग करता है।
score.createट्रेस, स्पैन या थ्रेड से संख्यात्मक फ़ीडबैक स्कोर जोड़ता है।
comment.createट्रेस, स्पैन या थ्रेड से फ़्री-टेक्स्ट टिप्पणी जोड़ता है।
prompt_version.saveनया प्रॉम्प्ट संस्करण सहेजता है (नाम से प्रॉम्प्ट न मिलने पर उसे बनाता है)।
dataset.createडेटासेट बनाता है — type: "test_suite" इसे इवैल्युएशन टेस्ट सूट बनाता है।
dataset_item.upsertडेटासेट में आइटम अपसर्ट करता है (हमेशा envelope आकार)।
experiment.createडेटासेट के दायरे में एक्सपेरिमेंट बनाता है।
experiment_item.createएक्सपेरिमेंट में ट्रेस + dataset_item पंक्तियाँ जोड़ता है।
thread.closeथ्रेड बंद करता है (उसे निष्क्रिय चिह्नित करता है)। thread_id और प्रोजेक्ट दें।
thread.openबंद थ्रेड फिर खोलता है। thread_id और प्रोजेक्ट दें।
agent_insights_job.enableकिसी प्रोजेक्ट के लिए Diagnostics चालू करता है (रोज़ाना स्कैन, दोहराना सुरक्षित)।
agent_insights_job.triggerअभी पिछले 24 घंटों का Diagnostics स्कैन चलाता है।
agent_insights_issue.resolveDiagnostics समस्या को निपटाई गई चिह्नित करता है (पहले उपयोगकर्ता से पूछें)।
agent_insights_issue.closeDiagnostics समस्या को कार्रवाई के योग्य नहीं चिह्नित करता है (पहले उपयोगकर्ता से पूछें)।
agent_insights_issue.reopenहल की गई या बंद Diagnostics समस्या को फिर खुली सूची में रखता है।
annotation_queue.createकिसी प्रोजेक्ट की एनोटेशन कतार बनाता है, वैकल्पिक रूप से कस्टम एनोटेटर व्यू के साथ।
annotation_queue.updateएनोटेशन कतार बदलता है; उसका एनोटेटर व्यू सेट, बदलता या साफ़ करता है।
write(
    operation="score.create",
    data={
        "target": "trace",
        "target_id": "7f2e3c8a-…",
        "name": "helpfulness",
        "value": 0.9,
        "reason": "great recovery",
    },
)

schema

किसी भी राइट ऑपरेशन को कॉल करने से पहले उसका सटीक JSON आकार और आवश्यक फ़ील्ड देखें — यह तब उपयोगी है जब आपको पता न हो कि data कैसा दिखना चाहिए। यह स्कीमा, OAuth स्कोप और एक वैलिडेट किया हुआ उदाहरण लौटाता है। केवल लुकअप, बैकएंड कॉल नहीं।

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—सेल्फ-होस्ट किए गए Comet के लिए API key, या होस्ट किए गए सर्वर के बिना Opik Cloud के लिए। ओपन-सोर्स Opik को इसकी ज़रूरत नहीं होती, जब तक डिप्लॉयमेंट में ऑथेंटिकेशन न जोड़ा गया हो।
OPIK_WORKSPACEunsetवर्कस्पेस का नाम। API key के साथ क्लाउड पर, unset होने पर default भेजा जाता है, जो आपके खाते के डिफ़ॉल्ट वर्कस्पेस पर जाता है — अगर आप किसी दूसरे वर्कस्पेस में काम करते हैं, तो इसे स्पष्ट रूप से सेट करें, वरना रीड चुपचाप गलत वर्कस्पेस से होंगे। OAuth पर इसे unset छोड़ें (टोकन में वर्कस्पेस होता है) और स्थानीय/OSS पर (default वहाँ एकमात्र वर्कस्पेस है)।
COMET_WORKSPACE—OPIK_WORKSPACE का अप्रचलित उपनाम (पिछली संगतता के लिए)। अगर दोनों सेट हों, तो OPIK_WORKSPACE को प्राथमिकता मिलती है।
COMET_WORKSPACE_IDunsetवैकल्पिक वर्कस्पेस UUID। सेट होने पर एनालिटिक्स इवेंट में जोड़ा जाता है और हल किए गए UUID पर प्राथमिकता लेता है। इसकी ज़रूरत कम ही पड़ती है — OAuth इंस्टॉल में UUID टोकन से अपने-आप मिल जाता है।
COMET_URL_OVERRIDEhttps://www.comet.comइसे अपने सेल्फ-होस्ट किए गए Comet होस्ट पर, या स्टेजिंग के लिए https://dev.comet.com पर सेट करें।
OPIK_URLCOMET_URL_OVERRIDE + /opik/api से निकाला गयाओपन-सोर्स Opik के लिए इसे सेट करें, जो अपना API /api पर (http://localhost:5173/api स्थानीय रूप से) उपलब्ध कराता है। Comet प्लेटफ़ॉर्म पर इसे तभी बदलें, जब Opik, Comet UI से अलग होस्ट/पाथ पर हो।
OPIK_DEFAULT_PROJECT_NAMEunsetसेट होने पर, प्रति-सत्र instructions ब्लॉब LLM को निर्देश देता है कि हर टूल कॉल पर इसे project_name के रूप में भेजे, जब तक उपयोगकर्ता किसी दूसरे प्रोजेक्ट का नाम न बताए।

सर्वर / ट्रांसपोर्ट

वेरिएबलडिफ़ॉल्टनोट्स
OPIK_MCP_TRANSPORTstdioहोस्ट द्वारा लॉन्च किए जाने पर stdio, पोर्ट पर सुनने के लिए streamable-http।
OPIK_MCP_HOST127.0.0.1uvicorn का बाइंड होस्ट (streamable-http केवल)।
OPIK_MCP_PORT8080uvicorn का बाइंड पोर्ट (streamable-http केवल)।
OPIK_MCP_RELOADfalseuvicorn --reload सक्षम करने के लिए true (केवल डेवलपमेंट में)।
OPIK_MCP_AS_URLunsetOAuth Authorization Server URL, जिसे /.well-known/oauth-protected-resource (RFC 9728) में घोषित किया जाता है और AS-डिस्कवरी जाँचों के लिए प्रॉक्सी लक्ष्य के रूप में इस्तेमाल किया जाता है। MCP होस्ट को HTTP पर OAuth प्रक्रिया शुरू करने के लिए यह आवश्यक है।
OPIK_MCP_RESOURCE_URIunsetइस सर्वर का आधिकारिक सार्वजनिक URI, जिसे संरक्षित-संसाधन मेटाडेटा में resource के रूप में घोषित किया जाता है और WWW-Authenticate संकेत निकालने के लिए इस्तेमाल किया जाता है।
OPIK_MCP_OAUTH_VALIDATION_CACHE_TTL_S30opik-backend के टोकन इंट्रोस्पेक्शन से मिले "मान्य" उत्तर पर भरोसा करने की अवधि; इसके बाद उसी OAuth टोकन पर अगली रिक्वेस्ट फिर से जाँच करती है। इससे प्रति-रिक्वेस्ट वैलिडेशन के कारण backend पर पड़ने वाला लोड और वह अवधि सीमित होती है जिसमें एक्सपायर टोकन आगे भेजा जा सकता है (यह अवधि backend के पहले 401 उत्तर पर भी समाप्त हो जाती है)। अगर backend टोकन का अपना expires_at बताता है, तो यह अवधि उससे अधिक नहीं होगी।
OPIK_MCP_LOG_LEVELINFOstderr लॉगर का थ्रेशोल्ड।

ट्रांसपोर्ट चुनना

दो bearer प्रकार, HTTP ट्रांसपोर्ट के लिए दो अनुबंध। opik_mcp_at_… OAuth एक्सेस टोकन को opik-backend के टोकन इंट्रोस्पेक्शन एंडपॉइंट के विरुद्ध हर रिक्वेस्ट पर वैलिडेट किया जाता है (कैश किया जाता है, देखें OPIK_MCP_OAUTH_VALIDATION_CACHE_TTL_S); एक्सपायर या रद्द किए गए टोकन पर WWW-Authenticate: Bearer error="invalid_token" के साथ HTTP 401 मिलता है, जिस पर MCP होस्ट अपना साइलेंट refresh_token grant आधारित करते हैं। Opik API key को स्थानीय रूप से वैलिडेट नहीं किया जाता: इसे बिना बदलाव opik-backend को भेजा जाता है, जो इसे लागू करने का एकमात्र स्थान है। डिप्लॉयमेंट के स्वरूप के अनुसार ट्रांसपोर्ट चुनें:

परिदृश्यट्रांसपोर्ट
Opik Cloudचलाने के लिए कुछ नहीं: होस्ट किया गया सर्वर HTTP पर यही सर्वर है, जिसे Comet चलाता है
MCP क्लाइंट और Opik एक ही मशीन पर (स्थानीय OSS इंस्टॉल)stdio (अनुशंसित — सबसे आसान, न पोर्ट चाहिए, न OAuth सेटअप)
स्थानीय MCP क्लाइंट → सेल्फ-होस्ट किया गया Opikडिप्लॉयमेंट के env vars के साथ stdio, या OAuth के साथ HTTP (OPIK_MCP_AS_URL backend की ओर इंगित करता हुआ)
opik-mcp, opik-backend के साथ उसी edge के पीछे सर्व किया गया होHTTP — backend हर रिक्वेस्ट पर bearer को वैलिडेट करता है

स्थानीय OSS इंस्टॉल के लिए नोट: OSS backend रिक्वेस्ट को ऑथेंटिकेट नहीं करता, इसलिए उसके सामने चलने वाला HTTP opik-mcp, OSS REST API जितना ही खुला है। साझा नेटवर्क पर डिफ़ॉल्ट 127.0.0.1 बाइंड रखें (और stdio को प्राथमिकता दें)।

टेलीमेट्री

वेरिएबलडिफ़ॉल्टनोट्स
OPIK_MCP_ANALYTICS_ENABLEDtrueसभी गैर-Sentry टेलीमेट्री बंद करने के लिए इसे false पर सेट करें।
`OPIK_MCP_SENTRY_ENABLEDtrueSet to false सभी Sentry टेलीमेट्री बंद करने के लिए।
=======

ज्ञात होस्ट सीमाएँ

होस्ट इस बात में अलग-अलग होते हैं कि वे एक टूल कॉल को कितनी देर तक चलने देते हैं:

  • Claude Code — टूल कॉल के लिए कोई दस्तावेज़ित टाइमआउट नहीं। अनुशंसित।
  • Cursor — 60s की सख़्त टाइमआउट सीमा, जो प्रगति होने पर रीसेट नहीं होती (अपस्ट्रीम बग).
  • MCP Inspector — कुल अवधि को MAX_TOTAL_TIMEOUT सीमित करता है (डिफ़ॉल्ट 60s)। लंबे ऑपरेशन के लिए Inspector UI में इसे बढ़ाएँ।

अगर कोई कॉल अटक जाए, तो पूरा रिक्वेस्ट लॉग पाने के लिए 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 vars तभी लागू होते हैं जब वे MCP सर्वर कॉन्फ़िगरेशन के env ब्लॉक के अंदर हों, आपके shell में नहीं; Codex भी केवल env_vars में सूचीबद्ध नाम आगे भेजता है। बदलाव के बाद नया सेशन शुरू करें, क्योंकि क्लाइंट सेशन शुरू होने पर कॉन्फ़िगरेशन पढ़ते हैं।

ओपन-सोर्स Opik पर रिक्वेस्ट /opik/api को जा रही हैं — COMET_URL_OVERRIDE सेल्फ-होस्ट किए गए Comet प्लेटफ़ॉर्म के लिए है। ओपन सोर्स अपना API /api पर उपलब्ध कराता है: इसके बजाय OPIK_URL=http://localhost:5173/api (या https://<host>/api) सेट करें। जब होस्ट यह मशीन हो, तो सर्वर स्टार्टअप पर इस बारे में चेतावनी देता है, और --check का उत्तर होता है "No Opik API at …"।

Cursor कॉल 60s पर टाइमआउट हो जाती है — यह 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 runMCP सर्वर चलाएँ (डिफ़ॉल्ट रूप से stdio)।
make run-devDEBUG लॉगिंग + uvicorn --reload के साथ चलाएँ।
make devmcp dev के ज़रिए चलाएँ (Inspector dev-mode wrapper)।
make inspectचल रहे सर्वर के विरुद्ध MCP Inspector लॉन्च करें।
make testuv run pytest -q।
make lintruff check + फ़ॉर्मैट जाँच।
make formatruff format + ruff check --fix।
make typecheckmypy।
make checklint + typecheck + test।

रिपॉज़िटरी का लेआउट:

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.