MCP setup | OpsBlu Docs

MCP: OpsBlu for agents

One streamable-HTTP MCP server at https://opsblu.com/mcp, authenticated with the same API key as REST. Six tools that mirror the REST endpoints. Aggregates and search are free; the agent pays credits only when it opens a record.

Transport: streamable HTTP (JSON-RPC 2.0, stateless, no SSE). Free tools work without a key; billed tools return an error asking for one. If your client insists on OAuth rather than a static header, use the REST API for now.

Connect

Pick your client. Sign in to see your key filled in.

{
  "mcpServers": {
    "opsblu": {
      "type": "http",
      "url": "https://opsblu.com/mcp",
      "headers": {
        "Authorization": "Bearer ob_live_YOUR_KEY"
      }
    }
  }
}

Claude Desktop → Settings → Developer → Edit Config. Claude Code: `claude mcp add --transport http opsblu https://opsblu.com/mcp --header "Authorization: Bearer ob_live_YOUR_KEY"`

Sign in to see your key filled in. Connecting adds 750 free credits.

Claude Desktop

  1. Settings → Developer → Edit Config. This opens claude_desktop_config.json.
  2. Add the opsblu entry from the Claude tab above under mcpServers.
  3. Restart Claude Desktop. The hammer icon lists the six tools.

Claude Code

one commandbash
claude mcp add --transport http opsblu https://opsblu.com/mcp \
  --header "Authorization: Bearer ob_live_YOUR_KEY"

Add --scope project to share it via .mcp.json (keep the key in an env var: --header "Authorization: Bearer $OPSBLU_KEY").

ChatGPT

  1. Settings → Connectors → Advanced → enable Developer mode.
  2. Create a connector: name OpsBlu, MCP server URL https://opsblu.com/mcp, authentication: API key in header, header Authorization: Bearer ob_live_….
  3. In a chat, open the + menu and enable the OpsBlu connector.

Cursor

Cursor Settings → MCP → Add new server, or drop the Cursor tab's JSON into .cursor/mcp.json in your project.

Any MCP client

  • Transport: streamable HTTP (POST JSON-RPC to /mcp; SSE for server-initiated messages).
  • Header: Authorization: Bearer ob_live_… (or X-API-Key).
  • Protocol: MCP 2025-06-18. tools/list returns the six tools with JSON Schemas identical to the REST query/body shapes.

Tools

ToolCostInputOutputREST twin
territory_stats Free state, city?, category? — or geojson polygon, categories? Stats: total, depth (phones, websites, emails, ads, cwv_fail, no_website, new_90d), categories, platforms, tracking, new_by_month. Never names or coordinates. Counts <5 suppressed. GET /v1/stats · POST /v1/stats/polygon
search_businesses Free Filters: state, city, zip, category, q, no_website, cwv_fail, platform, has_ads, has_analytics, server_side, new_days, changed_days, has_phone, has_email, hot, cursor, limit items[] of {id, name, category, city, state, signals, has_phone, has_email, has_website, platform, revealed}, total, next_cursor, estimate {records, hot_records, credits, usd} GET /v1/businesses
get_business 3 credits · 10 if hot id Full record (address, phone, emails, website, web.cwv/seo, marketing, signals) + credits_used + balance_remaining GET /v1/businesses/{id}
get_changes_since Free list since (RFC 3339), territory_id? or state/city/category, types? events[] of {type, at, business summary}. Opening a record is a get_business call. GET /v1/changes
enrich_domain Free (report card) url or domain Report card: cwv_mobile, cwv_desktop, seo, platform, tech_stack, marketing, tracking_health, peer comparison POST /v1/report-card → GET /v1/report-card/{id}
watch_territory Free name, kind (city|zip|polygon), state/city/zip or geojson, alerts {email, slack_webhook, webhook, types, cadence} Territory {id, …}. Use its id in get_changes_since. POST /v1/territories

Full field definitions are in the REST schemas. Tool outputs are the REST JSON, verbatim.

Auth, limits, caps

  • Keys come from /app/api-keys. Creating your first key grants the +750 connect bonus (business email accounts).
  • Per-key spend cap: set it when you create the key. The agent cannot spend past it; it gets 402 spend_cap and a message it can read.
  • Account spend cap: /app/billing. Applies on top of any key cap. "Your agent can't run away with your card."
  • Rate limits: ~120 calls/min per key for free tools; paid tools are naturally limited by credits. On 429 the response includes retry_after seconds.
  • Revoke a key any time; in-flight sessions fail with 401 auth_invalid.

How credits surface to the agent

Every paid tool result carries credits_used and balance_remaining, and every search result carries an estimate. A well-prompted agent reads them before spending:

search_businesses result (excerpt)json
{
  "total": 91,
  "items": [ { "id": "ob_por_lan_0012", "name": "…", "signals": { "no_website": true, "hot": false }, "has_phone": true, "revealed": false } ],
  "estimate": { "records": 91, "hot_records": 7, "already_revealed": 0, "credits": 322, "usd": 3.22 }
}
get_business result (excerpt)json
{ "record": { "id": "ob_por_lan_0012", "phone": "(503) 555-0199", "emails": [], "website": "", "signals": {…} },
  "credits_used": 3, "balance_remaining": 925, "already_revealed": false }

Opening the same record again in the same calendar month returns credits_used: 0 and already_revealed: true.

Prompting tips

  • Aggregates first. "Run territory_stats before searching, and tell me the count before you open anything."
  • Reveal only what you will contact. "Open at most 10 records, prefer ones with has_email = true."
  • Make the budget explicit. "Stop if balance_remaining would drop below 500."
  • Use the signals as the pitch. cwv_fail, no_website and ads_no_tracking are the first sentence of the outreach email.
  • Use territories for recurring work. One watch_territory call, then get_changes_since every morning. See the morning check recipe.