Endpoints: 28,729MCP servers: 18,413Payout addresses: 2,070Paid calls: 1,528Letters: 13Defects: 1,322counted just now
teppi

Server definition

Hash
sha256:818706f9f859185f9a4076d3bdbd62b5062c97affc9267a84a3dae044877df03
What it is
What a remote MCP server returned when asked what it offers: 12 tools

The blob, as servednamed by its sha256

{ "instructions": "Cobalt Capture stores visual product-review sessions — screenshots with notes and annotations — at shareable URLs that ANY MCP client can read or write: a coding agent (Claude Code, Cursor, Codex), a chat assistant (Claude chat, Cowork, ChatGPT), or a text-only agent. The person using you does not need to be a developer.\n\nWHICH SURFACE ARE YOU ON? Decide once, up front, and tell the user what that means:\n- You can DRIVE A BROWSER (Playwright, computer use, a browser tool that screenshots to a file): every study below runs in full.\n- You have NO BROWSER (a chat client): the public-page studies — pricing_teardown, positioning_pass, comparison_study — run in full, because add_screenshot(page_url=...) renders each page for you (desktop or mobile). Studies that must sign up or click through a product (usability_pass, flow_pass, investigation_pass) can only cover their public, logged-out screens from here — say so in one line before starting, offer the public-page part, and never present a text-only run as the full study.\n\nEDIT a review the human has already SAVED to their account (a follow-up: re-weight a comparison, retake a capture, add a section): the anonymous claim_token no longer works once a review is saved. Ask the human to open the review, choose Export & more → Hand to your agent, and paste you the token; pass it as claim_token to add_screenshot / add_note / update_review. Without it, make a new review rather than reporting changes in chat.\n\nREAD a review: call get_review with a review URL (/r/<slug> or /s/<slug>) or a bare slug. It returns the reviewer's notes as text plus each annotated screenshot as an image. Free reviews stay readable for 7 days; after that get_review reports the review as LOCKED because it is past its plan's editing window — relay that message in one line, don't retry, and don't pitch an upgrade.\n\nSEARCH Cobalt's own published studies (pricing teardowns, positioning audits, and comparisons it has run on well-known products): search(query) returns matching studies, fetch(id) returns one as text. It never searches other people's reviews, which are reachable only by their link.\n\nREADY-MADE STUDIES (playbooks). Before improvising a site review, check whether one of these is what the user asked for — they are maintained server-side and are more thorough than anything worth reconstructing. Tags: [public pages — runs anywhere, chat included] vs [needs a browser you control]:\n- pricing_teardown [public pages] — can a real buyer tell what they'd pay and which tier is theirs? Buyer math for three buyer sizes, tier names vs economics, the pushed tier, trial terms, feature table and fine print, trust at the CTA, desktop and phone.\n- website_teardown [public pages] — visual website teardown of the homepage and key marketing pages: what each page puts first (hierarchy, the main action, clutter, navigation, phone) and what it says (audience, claim, proof, jargon), judged cold and then through the site's likely visitors. Read-only, runs start to finish unattended. (positioning_pass is the old name for this study and still works.)\n- comparison_study [public pages] — two or three products, one buying decision: a thinking phase proposes weighted criteria (one approval stop), then a sourced matrix with an edge on every row, the critical differences, and an overall LEAN with what would flip it. Software or physical goods; uses web search for the independent sources.\n- usability_pass [needs a browser] — first-time-user usability audit. Signs up with a disposable inbox, works the real jobs cold, screenshots every point of friction, ranks findings by severity. Has one human approval stop (personas/jobs).\n- flow_pass [needs a browser] — the user names a flow (signup, checkout, inviting a teammate) and you walk it step by step, reporting what broke and what merely confused. Any email the flow sends is audited too.\n- investigation_pass [needs a browser, usually the repo] — the general product investigator ('Ace') for a product you OWN, run in its own environment; guardrails scale to owned-dev / owned-prod / external.\nFetch any of them with get_playbook(name, url) and follow it verbatim; clients that surface MCP prompts also expose them as slash commands. Match on what the user ASKED FOR, not on what is closest: a pricing question is pricing_teardown, not positioning_pass.\n\nWHEN NO STUDY FITS (an onboarding-email audit, an accessibility pass, a support-docs review — anything not listed): do NOT bend the request into the nearest playbook. Its lenses and severity labels are built for a different question and will mislabel what you find. Instead run the generic method, which is the same shape every study here uses: (1) restate the user's question as the single thing the review must answer, and the 2-4 lenses you'll judge it through; (2) open the review (create_review) with that scope as the summary; (3) capture every state you judge as a screenshot with a note quoting the exact thing at issue — desktop and phone where layout matters; (4) finalize with update_review: the one-sentence answer first, then findings ordered by severity anchored on OUTCOME for the person the study is about (would they misunderstand / be blocked / merely notice), then a keep-list of what works. Name the method you used in the summary so the reader knows it was a custom study, and tell the user in one line that no ready-made playbook covered it — that is useful feedback for us.\n\nWRITE a review (e.g. to compile a browser-testing or QA run into one shareable report):\n1. Call create_review(title, summary?) ONCE. It returns a `review` slug and a `claim_token` — keep both; the claim_token authorizes every write. At this point you don't yet know what you'll find, so keep the initial summary to the task/scope.\n2. For each screen, call add_screenshot(review, claim_token, image_url, comment?) as you capture it (see GETTING THE IMAGE IN below for where image_url comes from). Do this per-screen rather than batching at the end, so nothing is lost. Use add_note(review, claim_token, text) for standalone notes.\n3. When the run is DONE, call update_review(review, claim_token, summary) with the headline findings and outcome. This puts the verdict at the TOP of the review, above the step-by-step screenshots — do this instead of leaving conclusions in a trailing note, which forces every reader to scroll past the intermediate steps first.\n4. Share the returned review_url. No login is required: reviews are anonymous and auto-expire in 30 days unless the human opens the save_url to keep them.\n\nGETTING THE IMAGE IN. add_screenshot needs a real image, not a description. NO BROWSER OR SCREENSHOT TOOL (a chat client, a text-only agent)? Pass `page_url` and Cobalt renders the page itself — viewport 'desktop' or 'mobile', full_page for the whole scroll — and hands the image back to you. Do this for every screen you'd otherwise only describe; never ship a 'no screenshots' review when page_url is available. CHECK EVERY IMAGE THAT COMES BACK: consent banners are stripped automatically, but if the shot is still covered, blank, or the wrong page, retake it in place — replace_screenshot(item=<that item's number>, page_url=..., hide_selectors=[...]) — rather than leaving it or appending another. A capture that doesn't show the thing is worse than none. If you DO have a browser, it takes an `image_url` on Cobalt's own storage, which you get by POSTing the image to https://cobaltcapture.com/api/upload (multipart field `file`, no auth, returns {url, key}). Three paths, in order of preference:\n1. PREFERRED — upload from INSIDE the script that took the screenshot. If you are driving a browser (Playwright, Puppeteer, Selenium), you are already running a script with permission to run; do the POST in that same script, right after the capture. One process, no extra shell command, no second permission prompt, and the bytes never pass through you. In Python:\n page.screenshot(path='shot.png')\n url = requests.post('https://cobaltcapture.com/api/upload',\n files={'file': ('shot.png', open('shot.png','rb'), 'image/png')}\n ).json()['url']\n The 3-tuple matters: requests sends application/octet-stream without it and the\n upload is rejected with 'not an image'.\n Then pass `url` to add_screenshot as `image_url`. Print the urls (or collect them) so you have them for the tool calls. Node/Playwright equivalent: the built-in request context, `request.post(..., { multipart: { file: ... } })`. Do NOT shell out to curl as a separate step when a script is already running — that is a second permission surface for no gain.\n2. Live-browser screen share, when the shot must come from the HUMAN's own browser session, or when you can run page JavaScript but cannot execute scripts or shell commands: open a Cobalt editor page (/new) in that browser, have the human click Capture once and pick the window (a one-time gesture; browsers require it and no automation can drive that picker). Then call window.cobaltGrab() on that page via your javascript_tool for each screen — it grabs the current shared frame, uploads it, and returns {ok, url}. Pass that url as `image_url`.\n3. `curl -sS -F [email protected] https://cobaltcapture.com/api/upload` — the last resort, for when you have a file but no script running (and a shell you are allowed to use). It works, but in a sandboxed client it costs a permission prompt per call, which is why it is third.\nNOT A PATH: base64 via `image`. The server accepts it (PNG/JPEG/WebP up to 8 MB decoded), but tool-call arguments are text YOU generate, so a screenshot means emitting tens of thousands of base64 tokens perfectly — slow, expensive, and unreliable. Worse, if the screenshot reached you as an image rather than a file, you cannot transcribe it at all. Reserve `image` for genuinely small images you already hold as base64 text.\n\nTEST ACCOUNTS / EMAIL. If the product needs a signup to review, and create_inbox is in your tool list, use it — do NOT ask the human for an email account, an inbox API key, or any third-party service. There is nothing for them to set up. Steps:\n1. create_inbox() -> returns `address` and `inbox_token`. Use a FRESH inbox per test persona.\n2. Type `address` into the product's signup form and submit.\n3. check_inbox(address, inbox_token) -> reads what arrived. Mail normally lands within seconds; if it's empty, wait ~5s and call again (there is no blocking wait). Give it a few tries before concluding the product never sent anything — 'no verification email arrived' is a real finding, but only after you've actually waited.\n4. Pull the code or confirmation link out of the message and continue in the browser. Note that senders often rewrite links for click tracking, so the confirm URL may point at a tracking domain rather than the product's own — follow it anyway, it redirects correctly.\nInboxes expire, so don't reuse one across a long session. If create_inbox is NOT available, don't block the run: drive up to the verification wall, capture it, record 'signup requires email verification' as a finding, and continue with whatever is reachable without an account.\n\nThe claim_token from create_review is the handle for the whole session — pass it to every add_screenshot / add_note / update_review call for that review.\n\nOPTIONAL — EMAIL THE HUMAN A LINK. If the run was unattended and the human might forget to come back for it, offer to email them the review with email_review(review, claim_token, email). It only sends to a VERIFIED COBALT ACCOUNT address (a spam guard), so ask for their Cobalt account email; if they don't have an account it tells them to make a free one. The email is a link only — nothing you write reaches them.", "tools": [ { "description": "Append a free-standing text note (not tied to a screenshot) to a review created by create_review. Use for context, steps taken, or a summary of findings between screenshots.", "inputSchema": { "properties": { "claim_token": { "description": "The claim_token from create_review (authorizes the write). For a review the human has SAVED to their account, pass the agent token they generated on the review page (Export & more → Hand to your agent) here instead.", "type": "string" }, "review": { "description": "The review slug or URL from create_review.", "type": "string" }, "text": { "description": "The note text (plain text or markdown).", "type": "string" } }, "required": [ "review", "claim_token", "text" ], "type": "object" }, "name": "add_note", "outputSchema": null }, { "description": "Append one screenshot, with an optional title and note, to the end of a review. The image is stored in Cobalt and shown in the review. Three ways to supply it: `page_url`, a public page that Cobalt renders in a headless browser (`viewport` 'desktop' at 1280px or 'mobile' at 390px, `full_page` for the whole scroll, `hide_selectors` for elements to hide; common cookie banners are hidden automatically), which also returns the rendered image; `image_url`, an image already uploaded to https://cobaltcapture.com/api/upload; or `image`, a small base64 image. This tool only appends; it never changes an existing item (replace_screenshot does that).", "inputSchema": { "properties": { "claim_token": { "description": "The claim_token from create_review (authorizes the write). For a review the human has SAVED to their account, pass the agent token they generated on the review page (Export & more → Hand to your agent) here instead.", "type": "string" }, "comment": { "description": "Optional note describing what this screen shows or what's wrong with it.", "type": "string" }, "full_page": { "description": "With page_url: capture the entire scrollable page instead of the first viewport. Default false. Pages that scroll inside an inner container come back viewport-sized.", "type": "boolean" }, "hide_selectors": { "description": "With page_url: extra CSS selectors to hide before the shot, e.g. ['#newsletter-modal', '.chat-widget']. Common cookie and consent banners are hidden on every render.", "items": { "type": "string" }, "maxItems": 10, "type": "array" }, "image": { "description": "A small base64-encoded PNG, JPEG or WebP (data: URL prefix accepted). Intended for images under about 100 KB; larger screenshots are better uploaded and passed as image_url.", "type": "string" }, "image_url": { "description": "An image URL on Cobalt's own image host, as returned by https://cobaltcapture.com/api/upload (multipart field `file`, returns {url, key}) or by the editor's window.cobaltGrab(). External URLs are refused.", "type": "string" }, "page_url": { "description": "A public http(s) page for Cobalt to render and screenshot server-side. Pages behind a login can't be rendered. Becomes the item's source_url unless one is passed. Takes 10 to 30 seconds; a site that blocks automated browsers returns an error.", "type": "string" }, "review": { "description": "The review slug or URL from create_review.", "type": "string" }, "source_url": { "description": "Optional URL of the page the screenshot was taken on.", "type": "string" }, "title": { "description": "Optional short caption for the screenshot.", "type": "string" }, "viewport": { "description": "With page_url: 'desktop' (1280x800, default) or 'mobile' (390x844 phone, 2x, touch).", "enum": [ "desktop", "mobile" ], "type": "string" } }, "required": [ "review", "claim_token" ], "type": "object" }, "name": "add_screenshot", "outputSchema": null }, { "description": "Read mail delivered to an inbox from create_inbox, newest first, for example a verification code or confirmation link from a signup email. Returns immediately; mail usually arrives within seconds, so an empty result can be checked again shortly. format=\"html\" returns each message's HTML for reviewing the email's design.", "inputSchema": { "properties": { "address": { "description": "The inbox address from create_inbox.", "type": "string" }, "format": { "description": "\"text\" (default) returns each message flattened to readable text, with link targets kept. \"html\" returns the raw HTML part.", "enum": [ "text", "html" ], "type": "string" }, "inbox_token": { "description": "The inbox_token from create_inbox (authorizes reading).", "type": "string" } }, "required": [ "address", "inbox_token" ], "type": "object" }, "name": "check_inbox", "outputSchema": null }, { "description": "Create a temporary email inbox for signing up to a product under test. Returns an `address` to enter in the signup form and an `inbox_token` for reading it with check_inbox. Inboxes expire after a day.", "inputSchema": { "properties": { "review": { "description": "Optional review slug this inbox belongs to — a label for your own bookkeeping.", "type": "string" } }, "type": "object" }, "name": "create_inbox", "outputSchema": null }, { "description": "Start a new Cobalt Capture review and get a handle for filling it in. Use this to compile the findings of any site study — a usability pass, a pricing teardown, a positioning audit, a QA run — into one shareable, durable report with real screenshots. Works from any client, chat assistants included: with no browser, add_screenshot(page_url=...) renders the pages for you. Returns a `review` slug and a `claim_token` — pass BOTH back to add_screenshot / add_note to append content. Also returns a `review_url` to share and a `save_url` the human opens (while signed in) to save the review to their account permanently. The review is anonymous and auto-deletes after 30 days unless saved.", "inputSchema": { "properties": { "product_url": { "description": "Optional URL of the product/site under review.", "type": "string" }, "summary": { "description": "Optional overview shown at the top of the review (plain text or markdown). Good place for the overall task, outcome, and headline findings.", "type": "string" }, "title": { "description": "Title of the review, e.g. 'Onboarding walkthrough — Jupiter Invoice'.", "type": "string" } }, "required": [ "title" ], "type": "object" }, "name": "create_review", "outputSchema": null }, { "description": "Email a link to a review to the person who ran the study. Sends only to an address that belongs to a verified Cobalt account (other addresses are refused, which keeps the tool from being used to send unsolicited mail). The email contains only the review link, never text supplied in the call.", "inputSchema": { "properties": { "claim_token": { "description": "The claim_token from create_review (proves you created this review), or, for a saved review, the agent token its owner generated on the review page (Export & more → Hand to your agent).", "type": "string" }, "email": { "description": "The human's Cobalt account email. Must belong to a verified account, or the send is refused.", "type": "string" }, "review": { "description": "The review slug or URL from create_review.", "type": "string" } }, "required": [ "review", "claim_token", "email" ], "type": "object" }, "name": "email_review", "outputSchema": null }, { "description": "Fetch the full text of a Cobalt study by the id search returned, or of any Cobalt review by its URL (/r/<slug>) or slug. Returns text: findings, prices, the comparison matrix, and the underlying review's notes with links to its screenshots. Use get_review instead when you need to see the screenshots as images.", "inputSchema": { "properties": { "id": { "description": "An id from search (e.g. 'teardown:canva'), or a review URL or slug.", "type": "string" } }, "required": [ "id" ], "type": "object" }, "name": "fetch", "outputSchema": null }, { "description": "Return the full text of a Cobalt study playbook: a step-by-step method for a kind of product review that ends in a shareable Cobalt review. Available: 'pricing_teardown' (can a buyer tell what they would pay and which tier fits; public pages only); 'website_teardown' (what each key page leads with and says, judged as a first-time visitor; public pages only; 'positioning_pass' is its old name); 'comparison_study' (two or three products compared for one buying decision, with a sourced matrix; public pages plus web search); 'usability_pass' (a first-time-user audit that signs up and uses the product; needs a browser); 'flow_pass' (one named flow such as signup or checkout, including its emails; needs a browser); 'investigation_pass' (a product investigation of an app the user owns, run in its own environment; needs a browser and usually the code). The public-page studies work without a browser because add_screenshot(page_url) renders pages server-side.", "inputSchema": { "properties": { "name": { "description": "Playbook name, e.g. 'usability_pass'.", "type": "string" }, "url": { "description": "The site to run it against, if you already know it.", "type": "string" } }, "required": [ "name" ], "type": "object" }, "name": "get_playbook", "outputSchema": null }, { "description": "Fetch a Cobalt Capture review by its share link or slug. Returns the reviewer's notes as text AND each annotated screenshot as an image, so you can see exactly what was marked and what to change.", "inputSchema": { "properties": { "review": { "description": "A Cobalt review URL (https://cobaltcapture.com/r/<slug> or /s/<slug>) or just the slug.", "type": "string" } }, "required": [ "review" ], "type": "object" }, "name": "get_review", "outputSchema": null }, { "description": "Overwrite one existing screenshot in a review with a new capture, in the same position. Destructive: the old image and any pins or annotations on it are removed and cannot be recovered; the title and comment change only if new ones are passed. Works on screenshots only, not notes. Takes the same capture arguments as add_screenshot, plus `item`, the 1-based number of the screenshot to replace.", "inputSchema": { "properties": { "claim_token": { "description": "The claim_token from create_review (authorizes the write). For a review the human has SAVED to their account, pass the agent token they generated on the review page (Export & more → Hand to your agent) here instead.", "type": "string" }, "comment": { "description": "Optional note describing what this screen shows or what's wrong with it.", "type": "string" }, "full_page": { "description": "With page_url: capture the entire scrollable page instead of the first viewport. Default false. Pages that scroll inside an inner container come back viewport-sized.", "type": "boolean" }, "hide_selectors": { "description": "With page_url: extra CSS selectors to hide before the shot, e.g. ['#newsletter-modal', '.chat-widget']. Common cookie and consent banners are hidden on every render.", "items": { "type": "string" }, "maxItems": 10, "type": "array" }, "image": { "description": "A small base64-encoded PNG, JPEG or WebP (data: URL prefix accepted). Intended for images under about 100 KB; larger screenshots are better uploaded and passed as image_url.", "type": "string" }, "image_url": { "description": "An image URL on Cobalt's own image host, as returned by https://cobaltcapture.com/api/upload (multipart field `file`, returns {url, key}) or by the editor's window.cobaltGrab(). External URLs are refused.", "type": "string" }, "item": { "description": "The 1-based number of the existing screenshot item to overwrite (as it appears in the review, counting notes).", "minimum": 1, "type": "integer" }, "page_url": { "description": "A public http(s) page for Cobalt to render and screenshot server-side. Pages behind a login can't be rendered. Becomes the item's source_url unless one is passed. Takes 10 to 30 seconds; a site that blocks automated browsers returns an error.", "type": "string" }, "review": { "description": "The review slug or URL from create_review.", "type": "string" }, "source_url": { "description": "Optional URL of the page the screenshot was taken on.", "type": "string" }, "title": { "description": "Optional short caption for the screenshot.", "type": "string" }, "viewport": { "description": "With page_url: 'desktop' (1280x800, default) or 'mobile' (390x844 phone, 2x, touch).", "enum": [ "desktop", "mobile" ], "type": "string" } }, "required": [ "review", "claim_token", "item" ], "type": "object" }, "name": "replace_screenshot", "outputSchema": null }, { "description": "Search the studies Cobalt Capture has published on well-known products: pricing teardowns, positioning audits, and head-to-head comparisons (for example Canva pricing, Spotify vs Apple Music). Returns matching studies as {id, title, url}; pass an id to fetch for the full text. It does NOT search private reviews, which are reachable only by their link (use get_review, or fetch with the review URL).", "inputSchema": { "properties": { "query": { "description": "What to look for, e.g. 'canva pricing' or 'spotify'.", "type": "string" } }, "required": [ "query" ], "type": "object" }, "name": "search", "outputSchema": null }, { "description": "Set or replace a review's summary and/or title. The summary is shown at the top of the review, above every screenshot and note. Replaces any existing summary or title.", "inputSchema": { "properties": { "claim_token": { "description": "The claim_token from create_review (authorizes the write). For a review the human has SAVED to their account, pass the agent token they generated on the review page (Export & more → Hand to your agent) here instead.", "type": "string" }, "compared_to": { "description": "Optional: when this run repeats an earlier study, the earlier review's slug or URL. Recorded so re-runs can be compared over time.", "type": "string" }, "review": { "description": "The review slug or URL from create_review.", "type": "string" }, "summary": { "description": "The overview shown at the top of the review. Replaces any existing summary.", "type": "string" }, "title": { "description": "Optional replacement title.", "type": "string" } }, "required": [ "review", "claim_token" ], "type": "object" }, "name": "update_review", "outputSchema": null } ] }
Verify it yourselfcurl -s https://api.teppi.xyz/v1/evidence/sha256:818706f9f859185f9a4076d3bdbd62b5062c97affc9267a84a3dae044877df03 | sha256sum