Skip to main content
Glama

Exa Ultra MCP

A local stdio MCP server for the full Exa API, built for AI agents.

  • Covers every Exa surface on the free plan: search (all types), contents, find-similar, answer, Agent runs, Monitors.

  • Quality modes: fast, auto (Exa standard) and max (highest the free plan allows). Set one server-wide, or pass one per call.

  • Pool of API keys with failover. On 401/402/429/5xx, timeouts or a broken response, the call moves to the next key. Bad requests (400) are not retried.

  • Budget guard. Spend per key comes from costDollars. A key is skipped near its monthly budget ($10 on the free plan). Agent runs reserve their worst-case cost until Exa bills them.

  • Shared state. Every process on the machine (one per chat session is common) shares the same budget, cooldowns and mode.

  • Lean output. Short Markdown for the model, typed JSON in structuredContent, real errors flagged isError: true, and the cost on every call.

  • Keys stay private. Keys are read from a file or the environment. They are never logged or returned, and every error message is scrubbed of them.

Agents (OpenBot, Claude, Codex, …): read AGENTS.md for setup and usage rules.

Quick start

git clone https://github.com/chocowarsky/exa-ultra-mcp.git
cd exa-ultra-mcp
npm install            # also builds dist/
npm test               # mock tests, no keys, no credits

Put your keys in a private file, one per line or comma-separated. Keep it outside the repo:

install -m 600 /dev/null ~/.config/exa-ultra/keys
$EDITOR ~/.config/exa-ultra/keys

Register the server with your MCP client:

{
  "mcpServers": {
    "exa-ultra": {
      "command": "node",
      "args": ["/absolute/path/to/exa-ultra-mcp/dist/index.js", "--keys-file=/home/you/.config/exa-ultra/keys"]
    }
  }
}

More client configs (OpenBot, Claude Desktop/Code, Cursor, Codex, OpenCode) are in examples/.

Related MCP server: Exa MCP Server

Modes

Mode

exa_search / exa_find_similar

exa_agent_run

Typical use

fast

lite: under 1 s, $0.004

minimal: $0.012

Autocomplete, tight agent loops

auto

auto: about 2 s, $0.007

low: $0.025

Exa's standard defaults

max (default)

deep-reasoning: 7–20 s, $0.015

ultra: usage-based, capped at EXA_AGENT_MAX_COST ($1)

Best quality on the free plan

An earlier rule wins over a later one:

  1. An explicit type or effort in the call.

  2. mode in the call (fast / auto / max).

  3. The server mode saved with the exa_mode tool. It applies to every session on the machine and survives restarts.

  4. EXA_MODE, or --mode=, from the config.

A mode never breaks a call. If the mode's search type cannot handle the options you set, the server falls back to auto and adds a note. Two cases: lite with outputSchema or freshness options, and deep-* with Snapshot. An explicit invalid combination is rejected locally, before any credits are spent.

Tools

Tool

Exa endpoint

Notes

exa_search

POST /search

All types, filters, objective, systemPrompt, outputSchema, contents options, Snapshot

exa_contents

POST /contents

text, highlights or summary; live crawl, subpages, links/images, Snapshot

exa_find_similar

/contents + /search

Replaces the deprecated /findSimilar

exa_answer

POST /answer

Cited answer, optional schema

exa_agent_run / exa_agent_get / exa_agent_manage

/agent/runs

Create, wait, follow-up, list, events, cancel, delete

exa_monitor

/monitors

Off by default (EXA_ENABLE_MONITORS=1), needs a public webhook

exa_mode

local

Show or set the server mode

exa_keys_status

local

Key health, cooldowns, spend, reservations; action=reset

Resources: exa://keys/status, exa://modes. Prompt: exa_research.

Configuration

Every setting is optional except the keys.

Variable

Default

Meaning

EXA_API_KEYS_FILE / --keys-file=

—

File with keys: commas, spaces or newlines; # comments allowed

EXA_API_KEYS / EXA_API_KEY

—

Keys in the environment (comma-separated)

EXA_MODE / --mode=

max

fast, auto or max

EXA_AGENT_MAX_COST

1

Cap per auto/ultra agent run, in USD (1–100)

EXA_AGENT_WAIT_SECONDS

120

How long exa_agent_run waits before it returns the run id

EXA_MONTHLY_BUDGET_PER_KEY

10

USD per key per month

EXA_BUDGET_MARGIN

0.05

Stop using a key this many USD before its budget

EXA_KEY_STRATEGY

round-robin

round-robin, priority or least-used

EXA_QPS_PER_KEY

10

Requests per second per key (free plan: 10); 0 = no limit

EXA_TIMEOUT_MS

60000

Timeout of one HTTP attempt

EXA_MAX_ATTEMPTS

5

Keys tried per call

EXA_MAX_CHARS

8000

Default cap on the text returned to the model

EXA_CACHE_TTL_SECONDS / EXA_CACHE_MAX

600 / 200

In-memory cache of identical calls

EXA_ENABLE_AGENT / EXA_ENABLE_MONITORS

1 / 0

Turn tool groups on or off

EXA_STATE_DIR

~/.local/state/exa-ultra-mcp

Shared state: fingerprints, spend, mode. Never keys

EXA_BASE_URL

https://api.exa.ai

For proxies or tests

Invalid values fall back to the default, with a warning on stderr.

Failover rules

Exa answer

What happens to the key

Retried on another key

401 / 403

Disabled for 6 h

✓

403 "plan doesn't include …"

Nothing; the key is fine

— (every key on the plan would answer the same)

402, or 429 about credits

Disabled until next month

✓

429 rate limit

Cooldown (Retry-After or backoff, max 2 min)

✓

5xx, 408, timeout, network error, 200 with a non-JSON body

Cooldown with backoff

✓

400 / 404 / 422

Nothing

— (the request itself is wrong)

Agent runs and monitors stay on the key that created them. A run with an unknown owner is found by asking each key.

Project layout

src/
  index.ts         CLI entry: config → server → stdio
  server.ts        createServer(config): builds the MCP server (used by the CLI and tests)
  config.ts        env/argv → Config, with validation
  modes.ts         fast / auto / max presets, efforts, prices
  core/
    client.ts      HTTP client: failover, pacing, redaction, cancellation
    keypool.ts     key selection, budget, reservations, cooldowns
    state.ts       cross-process JSON state with a lock
    cache.ts       TTL cache
    format.ts      compact Markdown output
  tools/
    index.ts       list of tool modules (add yours here)
    shared.ts      Ctx, schemas, helpers, cache + in-flight dedupe
    search.ts      exa_search, exa_find_similar
    contents.ts    exa_contents, exa_answer
    agent.ts       exa_agent_run / get / manage
    monitors.ts    exa_monitor
    admin.ts       exa_mode, exa_keys_status
test/              mock Exa API, unit + end-to-end + stress tests
scripts/           check-secrets.mjs
examples/          client configs

To add a tool, write a ToolModule ((server, ctx) => void) in src/tools/ and add it to toolModules() in src/tools/index.ts. To add a mode, add an entry to MODES in src/modes.ts. Schemas, docs and exa_mode pick it up automatically.

You can also use the server as a library:

import { createServer } from "exa-ultra-mcp";
import { loadConfig } from "exa-ultra-mcp/config";
const { server } = createServer(loadConfig({ ...process.env, EXA_MODE: "auto" }));

Development

npm test                 # build + 38 mock tests (no credits)
npm run stress           # 1000 concurrent calls with injected failures + 4 processes sharing state
npm run check:secrets    # scan tracked files; add --history to scan every commit
EXA_API_KEYS_FILE=~/.config/exa-ultra/keys npm run smoke   # live test of every tool, about $0.10

Results on a laptop: 1000 concurrent calls with 19% injected failures (429, 5xx, timeouts, HTML) finished in about 3 s at an error rate of 0.4%. Across 4 processes, 400/400 requests and all spend were tracked. One process uses about 35 MB of RAM.

Security

  • Never commit keys. .gitignore blocks common key files, and npm run check:secrets (also run in CI) fails on anything that looks like a key, including UUIDs, the format Exa uses.

  • The state file stores sha256 fingerprints and the last 4 characters of each key, never the key itself, with mode 0600.

  • Monitor webhook secrets are written to monitor-secrets/ in the state dir (0600) and are never returned to the model.

License

MIT

Available Tools

9 tools
exa_agent_getExa Agent run status/resultA

Get an Exa Agent run by id; with wait=true, keep polling until it finishes or waitSeconds pass.

NameRequiredDescriptionDefault
idYes
rawNoAlso return the full Exa JSON in structuredContent. Costs many tokens.
waitNo
noCacheNoSkip the local cache.
maxCharsNoCap on the text returned to you (default 8000).
waitSecondsNo

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It usefully discloses that wait=true polls until completion or waitSeconds, but it omits other behavioral details such as cache behavior, token cost of raw output, and error conditions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single compact sentence with the core operation front-loaded and no wasted wording. It efficiently conveys the id lookup and the optional polling behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema and no annotations, the description is somewhat thin. It covers the core get-by-id and wait behavior, but it does not describe what the run result contains or how status/result data is returned.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%, and the description compensates by explaining the important wait and waitSeconds semantics. The remaining parameters are either self-explanatory or documented in the schema, though the description does not add meaning for raw, noCache, or maxChars.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: get an Exa Agent run by id. It is clearly a retrieval tool, but it does not explicitly distinguish itself from siblings like exa_agent_run or exa_agent_manage.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by saying to get a run by id and explains the wait=true polling behavior. It does not state when to use this versus exa_agent_run or exa_agent_manage, nor does it give exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

exa_agent_manageExa Agent runs: list, events, cancel, deleteC

list = recent runs on every key · events = lifecycle events of a run · cancel = stop a running run · delete = remove a run.

NameRequiredDescriptionDefault
idNoRun id (events, cancel, delete).
limitNo
actionYes
cursorNo

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations at all, the description carries the full behavioral burden and delivers almost none of it: it never says that delete is permanent or cancel is irreversible, whether either is idempotent, what permissions or key scope is needed, or what happens to a run's events after deletion. 'Remove a run' is the only hint of destructiveness, and it is euphemistic rather than explicit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, no filler, each clause maps to exactly one action — structurally clean and easy to scan. The terseness borders on under-specification rather than verbosity, so the compactness is only mildly a virtue.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A four-mode tool with two destructive operations, no annotations, no output schema, and 25% schema coverage needs far more than one line. Nothing is said about return shapes, pagination, error conditions, or irreversibility, leaving significant gaps for anything beyond the happy path.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 25% — the id parameter is documented in the schema, but limit and cursor have bare types with no description in either place. The description does not compensate: it says list returns 'recent runs on every key' but never explains what limit does, how cursor pagination works, or whether cursor/limit are ignored by events/cancel/delete.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Uses a compact glossary form to bind each of the four enum actions to a specific behavior ('cancel = stop a running run', 'delete = remove a run'), so the agent can tell what each branch of the tool does. It does not differentiate the tool from close siblings like exa_agent_get or exa_agent_run, which likely overlap on retrieving a single run.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The action glossary implies which action does what, but there is no explicit when-to-use guidance, no statement of which action to prefer over exa_agent_get/exa_agent_run, and no preconditions (e.g. that events/cancel/delete require an id, or that list is account-wide). The agent must infer selection rules from a single line.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

exa_agent_runExa Agent research runA

Async multi-step Exa Agent run (deep research): list-building, enrichment of rows, multi-hop research, structured JSON with citations. Not for simple lookups (use exa_search or exa_answer). Effort comes from the mode unless you set it: fast = minimal ($0.012) · auto = low ($0.025) · max = ultra (usage-based, capped at $1/run). Waits up to waitSeconds (default 120); if still running, returns the run id for exa_agent_get.

NameRequiredDescriptionDefault
rawNoAlso return the full Exa JSON in structuredContent. Costs many tokens.
modeNoQuality preset for this call: fast (lite search, cheapest agent) · auto (Exa standard) · max (highest free-plan quality). Default: the server mode (see exa_mode). An explicit type/effort wins.
waitNoWait for the result (default true).
queryYesThe research task in natural language.
effortNoOverrides the mode. ultra = exhaustive · auto = sized to the task (both usage-based, capped by maxCostDollars) · fixed: minimal $0.012 · low $0.025 · medium $0.10 · high $0.50 · xhigh $1.00.
excludeNoEntities the agent must not return again.
noCacheNoSkip the local cache.
maxCharsNoCap on the text returned to you (default 8000).
inputDataNoExisting rows to research or enrich.
waitSecondsNo
outputSchemaNoJSON Schema for output.structured. Bound arrays with maxItems.
previousRunIdNoContinue from a completed run (follow-up question).
maxCostDollarsNoSpend ceiling for auto/ultra (default 1). A free key has $10/month in total.
maxDurationSecondsNoultra only.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and does well: it discloses async behavior, the default waitSeconds wait of 120, that a still-running call returns a run id for exa_agent_get, cost tiers per mode/effort, and a usage-based cap of $1/run. It does not cover auth/permissions or rate-limit behavior, so it is strong but not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose and exclusions, then packs cost and wait behavior into two dense but purposeful sentences. Every clause adds decision-relevant information for an agent; there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a 14-parameter, no-annotation, no-output-schema tool, the description covers the essential operational picture: async execution, waiting, fallback run id, cost model, and sibling alternatives. It leaves detailed parameter semantics and output schema usage to the well-documented input schema, so it is complete enough for correct invocation, though a bit more on structured output behavior could help.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 93%, so the baseline is 3, but the description adds real meaning beyond the schema by mapping mode and effort to cost/quality tiers ('fast = minimal ($0.012) · auto = low ($0.025) · max = ultra ... capped at $1/run') and by stating the waitSeconds default and run-id fallback. Minor parameters like inputData and outputSchema are left to the schema, which is acceptable given coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource — async multi-step Exa Agent run for deep research — and enumerates concrete use cases like list-building, row enrichment, multi-hop research, and structured JSON with citations. It explicitly distinguishes itself from exa_search and exa_answer, so an agent can route correctly without inspecting schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use guidance via the deep research use cases and an explicit when-not-to-use clause: 'Not for simple lookups (use exa_search or exa_answer).' It also explains the wait/fallback path to exa_agent_get, covering alternatives and follow-up behavior.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

exa_answerExa grounded answerA

Ask a question; Exa searches and writes a short cited answer itself ($0.005). Good for quick facts. For research where you read the sources yourself, use exa_search.

NameRequiredDescriptionDefault
rawNoAlso return the full Exa JSON in structuredContent. Costs many tokens.
textNoInclude full source text in citations (large).
queryYes
noCacheNoSkip the local cache.
maxCharsNoCap on the text returned to you (default 8000).
outputSchemaNoJSON Schema for a structured answer.
systemPromptNo
userLocationNo

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does disclose two genuinely useful traits: the answer is model-synthesized with citations, and each call costs $0.005. However, it says nothing about the local cache that the noCache parameter implies, about latency/rate limits, or about how maxChars truncation affects the returned answer.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, zero waste, with the core behavior and the routing alternative both front-loaded. The parenthetical price is the only aside and it earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 8-param tool with a nested outputSchema object and no annotations, the description covers what the tool does and when to pick it, which is the main risk of misselection. It is thin on the behavioral envelope — caching, output size, and the customization parameters — but not inadequate for correct invocation of the required query.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Eight parameters at 63% schema description coverage, and the description mentions none of them. systemPrompt and userLocation are undocumented in both schema and description, and the cost/size tradeoffs of raw, text, and maxChars — the most decision-relevant knobs here — are left entirely to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource chain ('Ask a question; Exa searches and writes a short cited answer itself') and distinguishes the result shape from raw-source retrieval by naming exa_search. An agent knows immediately this returns a synthesized, cited answer rather than documents.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly gives the selection rule: 'Good for quick facts' here, and 'For research where you read the sources yourself, use exa_search' as the alternative with the condition that selects it. Cost is also disclosed, which is decision-relevant for an agent choosing between tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

exa_contentsExa get page contentsA

Get clean content of known URLs (no search). Default returns page text. Supports live crawl (maxAgeHours 0), subpage crawling, link/image extraction, and Exa Snapshot (paid plans). Failed URLs are listed; the call fails only when every URL failed.

NameRequiredDescriptionDefault
rawNoAlso return the full Exa JSON in structuredContent. Costs many tokens.
urlsYes
linksNoReturn up to N links found on each page.
contentNoPage content to return. Pick one. highlights = short query-relevant excerpts (fewest tokens).
noCacheNoSkip the local cache.
maxCharsNoCap on the text returned to you (default 8000).
subpagesNoAlso crawl up to N linked subpages per result.
imageLinksNoReturn up to N image URLs per page.
maxAgeHoursNoCache freshness: 0 = always live crawl, -1 = cache only, N = accept cache up to N hours. Not a publish-date filter.
snapshotAsOfNoExa Snapshot: the page as it was at this ISO date-time. Paid plans only. Not with maxAgeHours/livecrawlTimeout/subpages.
summaryQueryNoWhat the per-page summary should focus on (summary mode; one LLM call per page).
maxCharactersNoPer-page cap for text or highlights. Only for a hard budget.
subpageTargetNoKeywords that pick which subpages to crawl, e.g. 'pricing' or ['docs','api'].
summarySchemaNoJSON Schema for a structured per-page summary (summary mode).
highlightsQueryNoSteer which excerpts are picked (highlights mode).
livecrawlTimeoutNoLive crawl timeout in ms.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With zero annotations the description carries the full burden and does well: it discloses partial-failure semantics ("Failed URLs are listed; the call fails only when every URL failed"), a paid-plan restriction on Snapshot, and the default output mode. It omits auth/rate-limit behavior and per-URL cost expectations beyond the Snapshot note, which keeps it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight clauses, zero filler, front-loaded with the core purpose before capabilities and failure behavior. Every sentence carries distinct information an agent would otherwise have to infer.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 16-parameter tool with no annotations and no output schema, the description covers default behavior, failure semantics, plan gating, and capability modes. What it lacks is guidance on parameter interplay (e.g. content mode vs maxChars vs summaryQuery) and expected return shape, though the schema absorbs most of that.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 94%, so the schema already explains nearly every parameter, including maxAgeHours semantics and Snapshot exclusivity. The description only restates the maxAgeHours=0 → live crawl mapping and the Snapshot paid-plan caveat, adding little beyond what the schema supplies; baseline 3 is correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Get clean content of known URLs (no search)" states a specific verb and resource and explicitly carves out the boundary against exa_search. An agent can tell instantly that this is a fetch-by-URL tool, not a discovery tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The "(no search)" qualifier and the list of capability modes (live crawl, subpage crawl, link/image extraction, snapshot) give clear context for when this tool applies. It stops short of naming siblings like exa_search or exa_find_similar as explicit alternatives, and leaves the choice among modes to the schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

exa_find_similarExa find similar pagesA

Find pages similar to a seed URL (competitors, alternatives, related papers). Reads the seed page, then runs a semantic search built from it. Replaces Exa's deprecated /findSimilar. Search type follows the mode like exa_search.

NameRequiredDescriptionDefault
rawNoAlso return the full Exa JSON in structuredContent. Costs many tokens.
urlYes
modeNoQuality preset for this call: fast (lite search, cheapest agent) · auto (Exa standard) · max (highest free-plan quality). Default: the server mode (see exa_mode). An explicit type/effort wins.
typeNo
focusNoWhat 'similar' means here, e.g. 'competing products' or 'papers on the same method'.
contentNo
noCacheNoSkip the local cache.
maxCharsNoCap on the text returned to you (default 8000).
numResultsNo
excludeSourceDomainNoDrop results from the seed's own domain (default true).

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden; it does disclose the non-obvious side effect that the seed page is fetched/read before searching, plus the deprecated-endpoint lineage. It says nothing about cost, rate limits, permissions, or whether results are cached (cache behavior is only exposed as a parameter).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core purpose and mechanism before the deprecation and mode notes. The '/findSimilar' deprecation reference is useful for migration context but is the least load-bearing sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A 10-parameter tool with no annotations and no output schema: the description covers what it does and the mode/type interaction, but says nothing about what the results look like, cost of the call, or how to get full page content (e.g. via exa_contents). Adequate but with clear gaps for an agent deciding whether to call it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 60%, so the schema covers the well-documented params (mode, focus, maxChars, noCache, excludeSourceDomain). The description's real contribution is the non-obvious interaction that search type follows the mode the way exa_search does — which explains the otherwise undocumented 'type' enum. It adds little for content, numResults, or raw.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb and resource ('Find pages similar to a seed URL') and grounds it with concrete use cases (competitors, alternatives, related papers). It also explains the mechanism — read the seed page, run a semantic search from it — which distinguishes it from a plain query-based search like exa_search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the presence of a required seed URL tells the agent this is the tool for similarity-from-example, but the description never states when to prefer it over exa_search or exa_answer. The exa_search reference is about type-following behavior, not about tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

exa_keys_statusExa key pool statusA

Show health, cooldowns, requests and tracked spend of each Exa key (keys shown as last 4 chars only). action=reset clears cooldowns and disables.

NameRequiredDescriptionDefault
aliasNoKey alias like k2, for reset of one key.
actionNo

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It usefully discloses key masking and that reset clears cooldowns and disables something, but it leaves important behavior ambiguous: what exactly is disabled, whether reset is destructive or reversible, and whether reset applies to all keys or only the aliased key.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences with no filler. The key metrics and the reset side effect are front-loaded and easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the status metrics and reset effect, but for a mutation-capable tool with no annotations and no output schema, it should more completely specify reset scope, side effects, and default behavior. It is adequate but has clear gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 50%, and the schema already documents alias while action lacks a schema description. The description adds meaning for action=reset, but does not clarify status behavior when action is omitted or how alias interacts with reset beyond what the schema says.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb and resource: show health, cooldowns, requests, and tracked spend for each Exa key. It also distinguishes the reset mode, and the tool is obviously separate from the search/agent siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies status monitoring and describes what action=reset does, but it does not explicitly say when to use status versus reset, when reset is appropriate, or whether an alias is required when resetting a single key.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

exa_modeExa Ultra modeA

Show or set the server-wide quality mode used when a call sets no type/effort: fast = Lowest latency and cost: lite search (<1 s, $0.004), agent effort minimal ($0.012). auto = Exa's standard defaults: auto search (~2 s, $0.007), agent effort low ($0.025). max = Highest quality the free plan allows: deep-reasoning search (7-20 s, $0.015), agent effort ultra (capped by EXA_AGENT_MAX_COST, default $1/run). Setting it applies to every agent and session on this machine. Only set it when the user asks.

NameRequiredDescriptionDefault
setNoNew server mode. Omit to show the current one.
resetNoForget the saved mode and go back to EXA_MODE from the config.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations to lean on, the description carries the full burden and does so: it discloses the configuration is global ('applies to every agent and session on this machine'), quantifies latency and dollar cost per mode, and names the EXA_AGENT_MAX_COST cap (default $1/run) that bounds the max tier. That is exactly the blast-radius context an agent needs before mutating shared state.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the verb and resource, then the mode tiers, then the global-scope warning and the usage restriction. The cost/latency figures are dense but each is decision-relevant; the tier list reads as a single run-on block rather than scannable lines.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-param, zero-required configuration tool with no output schema, everything needed to call it safely is present: what the modes buy, what the setting affects globally, and when not to touch it. Return shape for the show case is the only minor omission and is inferable from the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3; the description exceeds it by unpacking each enum value into concrete latency, cost, and downstream effect (lite vs auto vs deep-reasoning search, agent effort minimal/low/ultra). The reset parameter is left entirely to the schema, which keeps this short of a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific pair of verbs and a precise resource: show or set the server-wide default quality mode applied when a call omits type/effort. None of the exa_* siblings touch server configuration, so an agent can place it immediately without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit scoping on both sides: the mode only takes effect when a call sets no type/effort, and the description closes with the constraint 'Only set it when the user asks'. Omission-as-read is spelled out in the schema, so both the when and the when-not are covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 9 tool updatesv0.2.0
    • First observedexa_agent_get
    • First observedexa_agent_manage
    • First observedexa_agent_run
    • First observedexa_answer
    • First observedexa_contents
    • First observedexa_find_similar
    • First observedexa_keys_status
    • First observedexa_mode
    • First observedexa_search

TDQS

A3.8/5.0

Scored across 9 tools

Disambiguation5/5

Each tool targets a clearly distinct capability: web search, cited answers, similarity search, URL content retrieval, agent-run lifecycle, mode configuration, and key status. Overlaps such as exa_search vs. exa_answer vs. exa_agent_run are explicitly differentiated by their descriptions.

Naming Consistency4/5

All tools use a consistent exa_ prefix and snake_case, making the set predictable. Most are action-oriented, though config/admin tools like exa_mode and exa_keys_status are noun-based rather than verb_noun.

Tool Count5/5

Nine tools is well-scoped for a search and research API with agent and admin functions. Each tool covers a meaningful operation without redundant surface area.

Completeness5/5

The set covers search, answer generation, similarity, content retrieval, asynchronous agent runs with get/manage lifecycle operations, mode configuration, and key health. No obvious dead ends remain for the stated Exa search/research domain.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to perform real-time web searches, company research, content crawling, LinkedIn searches, and deep research using the Exa AI Search API. Provides comprehensive web information retrieval capabilities in a safe and controlled manner.
    2
    33,632 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Connects AI assistants to Exa AI's search capabilities for web search, code context retrieval from GitHub repos and documentation, company research, LinkedIn search, and deep research tasks.
    6 npm
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Connects AI assistants to Exa's search capabilities, enabling web search, code search, and company research.
    33,632 npm
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables MCP clients to connect to Exa for web search, retrieving URL contents, deep cited-answer search, and research-agent runs. It provides Exa search, content, and research tools with filtering, structured output, and cost reporting.
    5
    MIT