exa: fix verify.py rejecting every API key (v5 / 1.0.4)

Activating Exa always failed with "Exa API key is invalid or
unauthorized (HTTP 403)" — the key was never actually tested.

Two bugs stacked:

1. mcp.exa.ai is behind Cloudflare, which bans urllib's default
   Python-urllib/3.x agent with 403 / "error code: 1010" before Exa
   sees the request. verify.py sent no User-Agent and mapped any 403
   to "API key is invalid". Reproduced on the server with no key set
   at all — same "invalid key" message.

2. The probed endpoint cannot validate a key anyway: JSON-RPC
   initialize against the MCP endpoint returns 200 no matter what
   ?exaApiKey= carries (checked with a real key, a bogus key, and no
   key). Fixing only the headers would have flipped the bug to
   accepting every key, including garbage.

With a key, the probe is now a minimal POST to api.exa.ai/search with
the key in the x-api-key header — the only call that exercises the
credential (200 valid, 401/403 + Exa JSON error invalid, 402 out of
credits, 429 valid but throttled). With no key it probes MCP
initialize and reports reachability only, never validity. Both
requests send a User-Agent; the MCP one also sends
Accept: application/json, text/event-stream (else HTTP 406).

An opaque 401/403 with no Exa JSON error is now reported as "blocked
before reaching the API — the key was not tested", instead of blaming
the credential.

Also re-aligns manifest/fragment versions to 5 / 1.0.4 (were 2/1.0.1
vs 4/1.0.3; skald reads installed_version from the manifest, so the
update badge would never have appeared) and raises verify.timeout_secs
15 -> 20.
This commit is contained in:
Daniele
2026-08-20 23:02:30 +01:00
parent f02bb78ebd
commit 040a0b2320
5 changed files with 139 additions and 54 deletions
+6 -6
View File
@@ -259,9 +259,9 @@
"type": "api_key"
},
"folder": "exa",
"version": 4,
"version_string": "1.0.3",
"version_release_date": "2026-07-21",
"version": 5,
"version_string": "1.0.4",
"version_release_date": "2026-08-20",
"tools": [
{
"name": "web_search_exa",
@@ -275,7 +275,7 @@
"files": [
{
"path": "connector.json",
"sha256": "79e2fb2b125fd67c9cd5cbf5dbec481bab19b1e3891410336b4b9306ad323db7",
"sha256": "72f53af082e04e9dc90970f16f13889b19746f5e46d327017e25f1b759590740",
"size": 1655
},
{
@@ -290,8 +290,8 @@
},
{
"path": "verify.py",
"sha256": "8e77da3ca3eca8f733296da134aaa964e5db8d01d4bfb89aa5832296e9dc45a6",
"size": 2125
"sha256": "1928e52129931c542e624e9e964095bf6f601bca5330a039d9dd37be10d0be4b",
"size": 5083
}
]
},