MCP Server

Canonical is a verified company graph for the long tail — the companies others miss. Unlike a web search that returns links to crawl and rank, describe what you want (or pass structured filters) and get a precise, LLM-verified, domain-keyed shortlist your agent can act on directly. Connect via the Model Context Protocol with Claude Desktop, Claude Code, ChatGPT, Cursor, or Windsurf.

What is MCP?

The Model Context Protocol (MCP) is an open standard that lets AI assistants use external tools. When you connect the Canonical MCP server, your AI assistant can search for companies directly during a conversation — no manual API calls needed.

Connect with One Click

No package install needed. No API key needed. Just add the remote server URL — OAuth handles authentication automatically.

Claude Desktop Recommended

Add Canonical as a Connector — no config files needed:

  1. Open Claude Desktop → SettingsConnectors
  2. Click Add Connector
  3. Enter the URL: https://trycanonical.ai/mcp/
  4. Sign in to your Canonical account when prompted
Alternative: config file method

Edit your config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "canonical": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://trycanonical.ai/mcp/"]
    }
  }
}

Requires Node.js installed. Fully quit and restart Claude Desktop after saving.

Claude Code

claude mcp add canonical --transport http https://trycanonical.ai/mcp/

ChatGPT

Add as a remote tool in ChatGPT settings with the following URL:

https://trycanonical.ai/mcp/

Cursor

Add to .cursor/mcp.json in your project or ~/.cursor/mcp.json globally:

{
  "mcpServers": {
    "canonical": {
      "type": "streamable-http",
      "url": "https://trycanonical.ai/mcp/"
    }
  }
}

Windsurf

Same JSON format as Cursor — add to your Windsurf MCP config:

{
  "mcpServers": {
    "canonical": {
      "type": "streamable-http",
      "url": "https://trycanonical.ai/mcp/"
    }
  }
}

Smithery

Canonical is listed on Smithery, the developer MCP registry. Install it from your Smithery dashboard, or via the CLI:

npx -y @smithery/cli install canonical-ai/company-search

View Canonical on Smithery →

First use: When you first use the tool, you'll be prompted to sign in to your Canonical account. Don't have one? Sign up for free — you'll get 250 credits to start.

Authentication & Permissions

Canonical uses OAuth 2.0 with Dynamic Client Registration — there are no manual API keys or client credentials to manage. Your MCP client (Claude, Cursor, ChatGPT, etc.) handles the OAuth handshake automatically on the first call.

What happens on first connection

  1. Your client opens trycanonical.ai in your browser.
  2. You sign in to your Canonical account (or create one).
  3. You authorize the client for the search scope.
  4. The client receives an access token and is ready to call tools. No further sign-ins are needed unless the token expires or you revoke it.

Permissions

The connector is read-only. With the search scope it can:

  • Run searches and similarity lookups against Canonical's company catalogue.
  • Fetch the structured profile of a company by domain.
  • Surface your remaining credit balance in tool responses so the model can warn you when you're running low.

It cannot:

  • Modify, delete, or create any data in your Canonical account.
  • Access saved searches, payment methods, team members, or other account data.
  • Reach files, browser data, or anything outside Canonical.

Disconnecting

Remove the connector from your client to revoke its access — in Claude Desktop: SettingsConnectorsCanonicalRemove. The client calls Canonical's OAuth revocation endpoint and the token is invalidated immediately.

See our Privacy Policy for how Canonical handles queries and tool calls made through the MCP server.

Limits & Pricing

MCP tool calls share the same credit balance and rate limits as the REST API. See pricing for plan tiers.

Credit cost per tool

  • search_companies / find_similar_companies: 1 credit per strong-match result returned. Partials are never charged.
  • get_company_details: 1 credit per call, charged only when the domain resolves to a real company (a not-found lookup is free).
  • lookup_companies: 1 credit per call when at least one candidate is returned, regardless of how many names or candidates (a no-match lookup is free).
  • get_account_status: free (read-only).

Rate limits

Applied per organization across every MCP tool call:

  • Free: 20 calls / minute · 1,000 / day
  • Starter: 30 calls / minute · 5,000 / day
  • Pro: 100 calls / minute · 50,000 / day

When a limit is hit the tool returns a structured error with retry_after_seconds, so the model can back off and retry rather than fail the user's turn.

Tool Reference

The MCP server exposes five tools: search_companies, find_similar_companies, get_company_details, lookup_companies, and get_account_status. Domains (not internal numeric ids) are the public handle — pass a domain from any search result to get_company_details, find_similar_companies, or exclude_company_domains.

search_companies

Search the catalogue using structured parameters. Pass a free-text description for the semantic core (the only fuzzy field) plus typed filters for everything else. Constraints the engine can't enforce are reported in warnings — never silently dropped. Returns LLM-verified strong matches by default.

Parameter Type Default Description
description string | null null Free-text semantic description of what the company does (e.g. "B2B fintech companies in the payments space"). The only fuzzy field — drives ColBERT retrieval and LLM verification. Omit when searching by filters only.
cities list[string] | null null HQ city names (e.g. ["New York", "San Francisco"]). Most-granular filter wins.
states list[string] | null null HQ state/province names (e.g. ["California", "New York"]).
countries list[string] | null null HQ country names (e.g. ["United States", "India"]).
employee_size string | null null Headcount bucket. One of: 1-10, 11-50, 51-100, 101-500, 501-1000, 1001-5000, 5001+.
founding_year_min integer | null null Lowest founding year to include (inclusive). E.g. 2015 means "founded in 2015 or later".
founding_year_max integer | null null Highest founding year to include (inclusive). For an exact year, set founding_year_min == founding_year_max.
founding_year_exclude_min integer | null null Lowest year of a contiguous range to exclude (inclusive). Both exclude_min and exclude_max must be set together. For a single-year exclusion ("not founded in 2020"), set both to the same year. Companies with unknown founding_year are kept when excluding (NULL-inclusive), dropped when including (NULL-exclusive).
founding_year_exclude_max integer | null null Highest year of the exclude range (inclusive).
funding_series list[string] | null null Funding stages. Values: pre_seed, seed, series_aseries_g_plus, growth, late, bridge, venture, angel, other.
funding_min_usd integer | null null Minimum latest-round funding in USD.
funding_post_money_min_usd integer | null null Minimum post-money valuation in USD.
funded_after string | null null ISO date string (e.g. "2024-01-01"). Only companies funded on or after this date are returned.
funding_investor list[string] | null null Investor firm name variants (e.g. ["Sequoia", "Sequoia Capital"]). Any matching variant satisfies the filter.
has_repeat_founder boolean | null null When true, restrict to companies with at least one repeat founder.
has_technical_cofounder boolean | null null When true, restrict to companies with a technical cofounder.
requires_role_types list[string] | null null Require companies with leadership in these role categories (e.g. ["cto", "exec_other"]). Valid values: founder, cofounder, ceo, cto, cfo, coo, chief_other, exec_other.
founder_prior_categories list[string] | null null Prior-employer tier of at least one founder. Values: faang, big_tech, unicorn, top_startup, mbb.
founder_prior_companies list[string] | null null Specific prior-employer company names (e.g. ["Google", "Stripe"]). At least one founder must have worked there.
exclude_company_domains list[string] | null null Domains to exclude from results (e.g. ["stripe.com"]). Unresolvable domains appear in warnings.
exclude_description string | null null Semantic exclusion: exclude companies whose description matches this text (e.g. "consulting").
intent string | null null Optional ranking profile. Allowed slugs: sales_prospecting, sales_timing, sales_expansion, competitive_tracking, emerging_competitor_scan, talent_source, recruiter_employer_vet, jobseeker_stability, jobseeker_growth.
top_k integer 20 Number of results (1–1000). Strictly honored — never over-delivers.
include_partials boolean false When true, also returns LLM-evaluated partial matches (close but not strong). Off by default because partials aren't billed; opt in for exploratory context.

find_similar_companies

Given a seed company's domain, return canonically similar companies.

Parameter Type Default Description
company_domain string required Seed company domain (e.g. "stripe.com"). Case- and scheme-insensitive — "https://Stripe.com" works too.
top_k integer 20 Number of similar companies (1–1000).
intent string | null null Optional ranking profile that reorders the similar set after relevance (same slugs as search_companies, e.g. sales_timing). Omit for relevance-only ordering.
include_partials boolean false Same as search_companies — opt in to receive partials.
exclude_company_domains list[string] | null null Optional list of domains to exclude from similar results.

get_company_details

Drill into one company. Returns full canonical fields (name, description, hq, employees, funding, dimensions) plus a people list (founders + C-suite/execs) when leadership data is available. Response includes credits_used and credits_remaining. Costs 1 credit when the company is found (a not-found lookup is free), rate-limited.

Parameter Type Default Description
company_domain string required Domain of the company (the same handle returned in search results). Returns an error when the domain doesn't match any canonical company.

Response also includes a leadership_data flag: "available" (people populated), "not_available" (company is in our DB but not in the leadership subset — most companies fall here), or "error" (transient lookup failure).

lookup_companies

Look up companies by name to disambiguate before passing a domain to other tools (e.g. as an exclusion or seed). Each input name returns ranked candidates plus a recommendation: when auto_resolve_recommended is true the match is unambiguous (use primary_candidate_domain); when false the name is a genuine toss-up — present the candidates and let the user pick. Costs 1 credit when at least one candidate is returned (a no-match lookup is free), rate-limited. Response includes credits_used and credits_remaining.

Parameter Type Default Description
names list[string] required One or more free-text company names. Max 20 per call.
k integer 5 Candidates to return per name (1–25).
disambiguation_mode string auto_when_confident Override the recommendation for non-interactive callers: auto_when_confident (default), always_auto (never ask), or always_ask.

Per name: {confidence, auto_resolve_recommended, primary_candidate_domain, candidates: [{name, domain, headquarters, description, is_primary, payload_richness}]}. Follow auto_resolve_recommended — proceed silently when true, ask the user when false.

confidence: high = one candidate or all candidates are alias domains of one entity; medium = distinct entities but the top one dominates (≥5× the next entity's headcount and ≥100 employees, or the only candidate with a description); low = comparable distinct entities. Under auto_when_confident, high+medium auto-resolve and low asks. primary_candidate_domain is set and one candidate is is_primary: true only when auto-resolving; when asking, primary_candidate_domain is null and all candidates are is_primary: false (still ranked best-guess-first, but none authoritative).

get_account_status

Returns the org's credit balance, current plan, and search rate limits. Takes no parameters. Read-only, free — charges no credits. Use it to check remaining credits or pace requests before a large batch of searches.

Response field Type Description
credits.total integer Total credits currently available (subscription + extra).
credits.subscription integer Credits from the current billing-period subscription allowance.
credits.extra integer Credits purchased as top-ups (don't expire with the billing period).
credits.subscription_resets_at string | null ISO timestamp when the subscription credit allowance next resets, or null for free-tier orgs.
plan string Current plan slug: free, starter, or pro.
rate_limits.per_minute integer Max search calls allowed per minute for the org's plan.
rate_limits.per_day integer Max search calls allowed per day for the org's plan.
billing_url string URL to the Canonical billing page to top up credits or upgrade your plan.

Example Call & Response (search_companies)

Tool responses are structured JSON, not prose — the model can branch on fields directly:

# Example structured call
{
  "description": "AI diagnostic platforms for hospitals",
  "countries": ["United States"],
  "employee_size": "51-100",
  "founding_year_min": 2018,
  "funding_series": ["series_a", "series_b"],
  "top_k": 5,
  "intent": "sales_prospecting"
}

# Response
{
  "count": 2,
  "credits_used": 2,
  "credits_remaining": 980,
  "warnings": [],
  "results": [
    {
      "name": "Acme Health AI",
      "domain": "acmehealthai.com",
      "description": "AI-powered diagnostic platform...",
      "headquarters": "San Francisco, CA, United States",
      "employee_count": 75,
      "founding_year": 2019,
      "funding": { "latest_series": "series_b", "latest_amount_usd": 45000000 },
      "dimensions": { "industry": ["Healthcare"], "offering_type": ["Software"] },
      "verdict": "relevant",
      "verdict_reason": "1. Products...: AI diagnostic platform matches..."
    }
  ]
}

Note: the domain field is the public handle for a company — pass it to get_company_details, find_similar_companies, or exclude_company_domains. Internal numeric ids aren't exposed.

Troubleshooting

Client can't reach the server

Confirm the URL is exactly https://trycanonical.ai/mcp/ — the trailing slash matters. The transport is streamable HTTP (stateless); older MCP URL shapes won't connect.

Stuck in a sign-in loop or seeing "Authentication required"

Remove the connector from your client and re-add it. The OAuth handshake will run again from scratch and a fresh token will be issued.

"Insufficient credits"

Check your balance at billing. Top up, upgrade, or wait for your daily refresh.

Still stuck?

Email support@trycanonical.ai with the client you're using, the exact error message, and the server URL you configured.