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.