Skip to content

Bring agent_run, web search, and the HTTP runtime up to hosted parity - #449

Merged
wlue merged 2 commits into
v4from
wlue/exa-mcp-functionality-audit
Oct 2, 2026
Merged

wlue merged 2 commits into
v4from
wlue/exa-mcp-functionality-audit

Conversation

@wlue

@wlue wlue commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

Brings the OSS tool surface and HTTP runtime up to parity with the hosted mcp.exa.ai server. agent_run advertises unicode-safe run ID patterns (strict providers rejected the old tool list), returns structuredContent against a declared outputSchema, accepts ultra effort plus the polymarket and macrobond providers, is marked openWorldHint with 402-aware errors and a description naming only registered tools, is on by default for callers with their own key, and hands back its run ID after a 45s call window, with the Exa Agent skill updated to match. web_search_exa gains an optional objective, web_search_advanced_exa is marked openWorldHint, and EXA_API_BASE_URL overrides the Exa API origin; the HTTP handler validates Accept media ranges, redacts ?exaApiKey= from debug logs, and prefers a URL key over a Bearer JWT with a one-time retry on the JWT when the key is rejected (McpConfig.apiKeyFallback). The container runtime adds SSE keepalives, a graceful SIGTERM/SIGINT drain, and 400s for malformed requests, and tests are split into unit and integration suites (the latter drives the runtime against a fake Exa API) that npm run ci runs together.

🤖 Generated with Claude Code

wlue and others added 2 commits September 30, 2026 14:12
agent_run advertises run ID patterns that compile as unicode-mode regexes
(strict providers rejected the old tool list), declares an MCP outputSchema
and returns structuredContent, accepts the ultra effort and the polymarket
and macrobond providers, is marked openWorldHint, names only registered
sibling tools in its description, explains 402 as not retryable, is on by
default for callers with their own key, and hands its run ID back after a
45s call window. The Exa Agent skill documents the new result shape.

web_search_exa takes an optional objective, forwarded to /search, and
web_search_advanced_exa is marked openWorldHint. EXA_API_BASE_URL overrides
the Exa API origin the tools call.

The HTTP handler validates Accept media ranges (406), redacts ?exaApiKey=
from debug logs, and prefers a ?exaApiKey= URL key over a Bearer JWT,
retrying a rejected key once on the JWT through McpConfig.apiKeyFallback.
The container runtime keeps idle SSE streams alive, drains in-flight
requests on SIGTERM/SIGINT without waiting out kept-alive connections,
survives unhandled rejections, and answers malformed requests with 400.

Tests are split into unit and integration suites; the integration suite
drives the runtime server against a fake Exa API and runs in npm run ci.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Models see objective in the tool schema's required list, so they state a
goal for every search, while calls that omit it (or send null or "") still
search without one. advertisedRequired decouples the advertised required
list from what the schema accepts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@wlue
wlue merged commit a5ac38c into v4 Oct 2, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant