MCP server

Harvv runs a hosted Model Context Protocol server so AI coding agents (GitHub Copilot, Cursor, Claude, Windsurf, Zed, Lovable) can read your behavioral findings and install the pixel without leaving the editor. One endpoint, one bearer token, scoped to your account.

Just want it connected? The one-click quick start for VS Code, Copilot, Cursor, Claude Desktop, Windsurf and Zed lives at harvv.com/install/copilot. On Lovable, use harvv.com/install/lovable. This page is the full reference: transport, tools, parameters, and troubleshooting.

Endpoint

https://harvv.com/mcp

The aliases /mcp/lovable and /mcp/harvv resolve to the same server. Point any MCP client at the base /mcp URL.

Connect your client

Claude and ChatGPT sign in with OAuth: you paste the server URL and sign in with your Harvv email, with no token to copy. Other clients use the standard MCP config, an HTTP server URL plus an Authorization: Bearer header. Only the file or UI you paste it into changes.

Claude (claude.ai, Claude Desktop, Claude mobile)

  1. In Claude, open Customize → Connectors and choose Add custom connector (or pick Harvv from the directory).
  2. Enter https://harvv.com/mcp, leave the OAuth fields blank, and click Add. No token is needed: Claude sends you to harvv.com to sign in (OAuth).
  3. Sign in to Harvv and approve. Claude gets a token for your account only, and renews it itself.
  4. Ask about your site in a new conversation, for example "What sites do I have in Harvv?" or "Why are sales down this week on mystore.com?"

Plans. The free Claude plan can add one custom connector; Pro and Max add their own. On Team and Enterprise an Owner adds Harvv once under Organization settings → Connectors (Add, then Custom), and each member finds it under Customize → Connectors and clicks Connect.

Pasting a token instead. Claude only takes a fixed token through the Request headers section of the Add custom connector dialog, a beta that only some organizations have. If you have it and want a token, set Authentication to No sign-in, create a token in Harvv under Settings → Integrations and enter Bearer, a space, and the token as the authorization header. Otherwise use the sign-in above.

To disconnect, remove the connector in Claude, or revoke it in Harvv under Settings. Plain-English setup with screenshots: harvv.com/claude.

Other clients

Authentication

Transport (custom clients)

The server speaks JSON-RPC 2.0 over Streamable HTTP (MCP spec 2025-03-26 and later). For a hand-rolled client:

curl -X POST https://harvv.com/mcp \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"list_my_sites","arguments":{}}}'

Tools

49 tools, listed from the same registry tools/list serves, so this page cannot drift from the server. Every tool is scoped to the account behind your token. Most only read. 7 save a setting you ask for (dismiss_issue, mark_issue_fixed, annotate_change, set_conversion_goal, set_brand_names, set_working_context, set_costs): each returns a preview and changes nothing unless called with confirm=true, is marked destructive so your client asks before it runs. Dismissals, fixes, goals, costs and brand names can be changed back in Harvv; a change note saved with annotate_change stays. Someone given a single site to view cannot change it. Tools that act on a site take site_id; on an account with more than one site it is required, and list_my_sites is how you get it. The setup tools and get_help are free; data tools count against the monthly credit allowance only when they answer (a timeout or a bad argument is not charged).

Setup and help

Free. Onboarding, verification, navigation, the product guide, and a self-check for a draft conclusion.

check_install

Checks whether the Harvv pixel is firing on a public URL by fetching the page.

check_slack_integration (no arguments)

Checks whether this account's Slack integration is wired up correctly by making live calls to Slack, so it reports what Slack actually returns rather than what Harvv's database records.

get_connect_link

Get a one-time link that connects Google Analytics (GA4) or Google Search Console to one site on this account.

get_dashboard_url

Returns a link that opens a site in the Harvv dashboard, where the full behavioral data, session lists and charts are.

get_help

Harvv product documentation and best practice, not site data.

install_pixel

Returns the Harvv pixel install snippet for a site on this account, with where to place it on each platform (Shopify, WordPress, Webflow, Squarespace, Wix, Google Tag Manager) and code framework.

list_my_sites (no arguments)

Lists every site on the Harvv account this connection is scoped to, with id, name, domain and pixel_key for each.

red_team

Returns Harvv's checklist of the ways its own numbers have been wrong in production (impossible counts, missing denominators, stale figures quoted as current, causes asserted but never measured, measurement gaps reported as zero, raw-count rankings that only f

red_team_report

Records the outcome of a Red Team pass (a red_team call whose checks were applied to a draft): one finding per claim checked, with the check_id that applied, the claim in a sentence, the verdict (survives, softened, retracted), why, and source_tool when known,

Data tools

Metered. Behavioral findings, page-level friction and behavior, traffic, conversion, speed, SEO and AI visibility for your sites. Every numeric response carries window, counted and sample blocks that say what was measured.

annotate_change

Saves a dated note about a change made to the site (a deploy, a theme edit, a campaign launch, a price change), so later comparisons covering that date show it beside a rise or drop.

dismiss_issue

Dismisses a finding on a site in this account, with a reason, the same as the dashboard's Dismiss button.

get_ad_spend

What a site's ads cost and what the ad platform reports they returned: spend, impressions, clicks, conversions and conversion value per campaign, a daily series, and the change history (who changed a budget, bid strategy, status, landing page, ad or keyword, a

get_ad_traffic_quality

How the traffic from each ad campaign behaves after it lands, compared with the site's own non-paid traffic: bounce, rage clicks, dead clicks, scroll depth and form interaction, over the last N days (default 30, max 90).

get_ai_bot_activity

AI crawler activity on a site over the last N days (default 30, max 90), including robots.txt violations (requests for paths robots.txt disallows).

get_ai_recommendations

Which pages AI assistants (ChatGPT, Perplexity, Gemini, Claude, Copilot) sent visitors to, and whether those pages carry structured data (JSON-LD) a model can quote.

get_audience_state

Who a site's visitors are, as categories, over the last N days (default 7, max 30): signed-in vs anonymous vs unknown, whether logged-in CMS staff are in the numbers, whether visitors arrived with a cart, and first-time vs returning.

get_commerce_funnel

The site's commerce funnel (browsed collection, viewed product, added to cart, viewed cart, began checkout, purchased) plus form starts and submits, over the last N days (default 7, max 30), with session and event counts and cart value where tagged, built from

get_conversion_path

Finds the interaction that gates conversion on a page and how many visitors never reach it, by grouping the page's sessions by what they clicked before converting and comparing each group with an engagement-matched control.

get_conversions

Conversions, and revenue where the site sells online, for questions like 'how are sales today' or 'are leads coming in'.

get_dismissed_findings

What this account has already dismissed on a site: findings marked dismissed with the reason given (false positive, noise, intentional, duplicate, fixed already, not useful) or auto-expired by housekeeping.

get_element_clicks

Which elements get clicked most, ranked by click volume, optionally narrowed to a page path or an element-name filter (element_contains 'footer' answers 'what do people click in the footer?').

get_fleet_benchmark

Compares a site with the Harvv fleet on five behaviour rates over the last 30 days: share of sessions on phones, sessions with a dead click, sessions with a rage click, sessions that never scroll past a quarter of the page, and dead clicks per 1,000 sessions.

get_forms

Every form visitors use on a site, one row per form: sessions that started it, progress through a multi-step form (sessions per step), what Continue/Submit clicks did (refused with errors, moved on, finished, left the page, closed the popup, or nothing visible

get_friction_findings

Alias of get_issues, kept for older clients; get_issues returns the same findings plus fix text and a status filter.

get_issue_sessions

Lists the visitor sessions affected by one issue (the issue_id from get_issues), plus a dashboard link showing all of them.

get_issues

The UX issues Harvv has detected on a site, each with what is broken, sessions affected, status, and a plain-English recommended fix.

get_js_errors

JavaScript exceptions and failed network requests on a site, grouped by message and file or by URL, over the last N days (default 3, max 30).

get_keyword_opportunities

Ranked SEO opportunities for a site: every search query Google Search Console reports the site appearing for, joined to Google Ads search volume, CPC and competition.

get_keyword_volume

Monthly Google search volume, CPC, competition and 12-month trend for keywords you name, for a country, state or city.

get_layout_changes

Estimates when a site's layout or theme last changed, and which open findings that change may have invalidated, from the pixel alone (no CMS access or plugin needed).

get_page_behavior

How visitors behave on a page (or the whole site) beyond clicks: the share who left mid-visit to check something elsewhere (tab-away), who hesitated (with the median pause), who copied text such as a price or SKU, who held the site open in several tabs, who re

get_page_friction

Per-page friction for a site over the last N days (default 7, max 30): dead clicks, rage clicks and affected sessions per page, plus the most-stuck elements.

get_page_ui

Renders one site page as a shopper sees it (phone by default), never typing or submitting: main buttons and how far down they sit, disabled controls and messages, popups and close size, small tap targets.

get_performance

Core Web Vitals for a site from real visitor sessions over the last N days (default 7, max 30): LCP, INP, CLS and TTFB at p50 and p75, plus the slowest pages by LCP.

get_profit

Profit per day and for the window: revenue, product revenue net of tax and shipping, estimated cost of goods, shipping cost, payment fees, ad spend (Meta and Google, the same import get_ad_spend reads), fixed costs, and what is left.

get_search_console

Google Search Console data Harvv has synced for a site: totals, top queries by clicks, CTR leaks (queries ranking well that get fewer clicks than their position predicts), almost-ranking queries and pages (average position 11 to 20), and how visitors arriving

get_seo_insights

Per-page SEO and GEO (AI-search readiness) findings for a site, built from what the pixel captured on the real rendered page of each URL visitors loaded, over the last N days (default 14, max 30).

get_setup_status

Where this Harvv account's setup stands, from what Harvv has observed rather than what anyone reports: for every site, whether the pixel has ever fired (and whether it is quiet), whether a Shopify store's Customer Events checkout pixel is delivering checkout s

get_site_stack

The site's technology stack as Harvv last observed it: platform, theme, and the active plugin list with the role of each.

get_stuck_points

Where shoppers get stuck between cart and order: per step, sessions that reached and passed it; per stuck element (dead, rage, disabled or repeated taps), who struggled and left, where they went, a range of extra sessions and orders a month (observational), wh

get_traffic_sources

Where a site's traffic comes from over the last N days (default 7, max 30), classified into channels (Organic search, Paid search, Paid social, Social, Email, Referral, Direct) with sessions and share for each.

get_traffic_summary

Traffic overview for a site over the last N days (default 7, max 30): sessions, unique visitors, top pages, referrer and source split, bounce-equivalent, the device split (`devices`: mobile, desktop, tablet) and the browser split (`browsers`: safari, chrome, e

mark_issue_fixed

Records that a finding has been fixed, the same as the dashboard's Mark fixed action.

report_page_walk

Records the steps an assistant walked for a browser_handoff run_id: element, size, disabled or unresponsive, nearby message, what stopped it.

set_brand_names

Saves the names a business is searched by besides its domain: a former name, a store name, or a domain it used to live on (e.g.

set_conversion_goal

Sets what counts as a conversion on a site: 'form' (a form submit, call or booking), 'add_to_cart' (a store's cart and checkout) or 'cv' (the site sends its own conversion event).

set_costs

Saves what a store's products, shipping and payments cost, so get_profit can say whether a change made or lost money (revenue and profit can move in opposite directions).

set_working_context

Saves notes about who a person works with, so later answers are framed for the right reader.

verify_finding

Re-checks one finding against recent data (default the last 3 days, max 14) to answer 'is this still happening now?'.

Example: get_friction_findings

Request:

{"jsonrpc":"2.0","id":4,"method":"tools/call",
 "params":{"name":"get_friction_findings","arguments":{"days":7}}}

The result is a content block whose text is JSON:

{
  "ok": true,
  "site": { "id": "c8d5fc24-...", "name": "Acme", "domain": "acme.com" },
  "window": { "days": 7, "requested_days": 7, "clamped": false,
              "min_days": 1, "max_days": 30 },
  "headline": { "sessions": 1840, "events": 41230,
                "dead_clicks": 212, "rage_clicks": 64,
                "unit": "count", "window_days": 7 },
  "findings": [
    { "id": "8231", "type": "dead_click",
      "title": "Dead clicks on pricing CTA",
      "element": "button.upgrade-cta", "priority": "high",
      "summary": "212 clicks on a button with no handler ...",
      "dashboard_url": "https://harvv.com/newdashboardui#/site/c8d5fc24-.../issue/8231" }
  ]
}

All headline counts are totals over the whole window, not per-day averages. Findings come sorted high priority first.

Troubleshooting

Every tool returns 401. The transport is fine (the auth check was reached); your token was rejected. The 401 body carries a reason code so you can tell which:
  • token_expired: the token reached the lifetime it was created with. An OAuth connector refreshes on its own; a pasted token is regenerated at Studio → Settings → Integrations.
  • token_revoked: regenerate at Studio → Settings → Integrations and reconnect.
  • token_not_found: mistyped, or from another account. Regenerate and reconnect.
  • wrong_scope: not a customer MCP token. Generate one from your dashboard.
The reason is in error.data.reason (JSON-RPC) and the WWW-Authenticate response header.
Tools show empty input schemas. If your client lists the tools but every inputSchema looks like {"properties":{}}, it cached an older catalog from before the site_id / url / days parameters shipped. Remove and re-add the Harvv connector (or refresh the connection) to re-fetch tools/list and pick up the current schemas. list_my_sites genuinely takes no arguments, so an empty schema there is correct.

check_install reports not-installed on a Lovable preview. Use the published URL, not the id-preview--*.lovable.app wrapper (see check_install above).

Signing in from Claude lands on the Harvv dashboard instead of returning to Claude. Start the connection again from Claude; the sign-in page returns you to the approval step. If your browser is signed in to a different Harvv account, the approval page offers to switch.

Data and privacy

Support

Email hello@harvv.com. Report a security issue to jordan@harvv.com (the contact on harvv.com/trust). Privacy requests: privacy@harvv.com.