API-318: Add nansen mcp verify — client-independent authenticated MCP setup verification - #508
API-318: Add nansen mcp verify — client-independent authenticated MCP setup verification#508gulshngill wants to merge 3 commits into
nansen mcp verify — client-independent authenticated MCP setup verification#508Conversation
The hosted Nansen MCP server answers tools/list (and free tools) without a valid API key, so a broken credential setup looks successful until the first paid data call. `nansen mcp verify` runs a real authenticated data-path check: key resolution, unauthenticated tools/list reachability, then a paid tools/call canary (~1 credit) with server error text mapped to actionable next steps. Non-zero exit through the unified error envelope on failure; --json returns the structured checks. Runnable with zero checkout via npx. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pr-reviewer Summary for #1b52831✅ No issues found The code review completed successfully with no findings. Review effort: 3/5 (Moderate) SummaryThis PR adds Overall assessment: The production code is correct, the error-handling paths are thorough, and the test suite covers every important branch (SSE vs JSON responses, all auth-failure mappings, timeout, network failure, malformed results, key-precedence, and the non-zero Specific things reviewed and confirmed correct:
Token usage: 18,732 input, 5,867 output, 867,800 cache read, 53,422 cache write | Usage Guide New pushes are reviewed automatically with a 10-minute cooldown between reviews. To request a review at any time, comment |
Both remediation strings sent users to https://app.nansen.ai/account?tab=api -- the URL API-390 removed today from the MCP server (nansen-ra#3452) and from the Kong 401 (nansen-api#1832). Merging this as-is would reintroduce it. Use https://app.nansen.ai/api?tab=api, the key management view, matching both. Deliberately NOT /auth/agent-setup: that page auto-fires POST /api-keys on load and mints a key. Right for onboarding, wrong in an error path -- the user here already has a key and needs to inspect or rotate it, and Free/Pioneer cap at 1 key so they would get a 403 on arrival. Adds a test pinning the URL and excluding both rejected alternatives; verified it fails if the URL regresses. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Problem
MCP clients can list the hosted Nansen MCP server's tools without a valid API key — the server serves
tools/list(and free tools) unauthenticated, and tool-argument validation also runs before auth. So a broken credential setup looks successful until the first paid data call fails. There was no user-facing way to verify an MCP setup end to end.Solution
New diagnostic command — client-independent, runnable with zero checkout:
It performs a real authenticated data-path check, not just discovery:
mcp-api-key— resolves the key (--api-key→NANSEN_API_KEY→~/.nansen/config.json) and reports the masked key + source.mcp-server— JSON-RPCtools/listfor reachability (explicitly labelled "unauthenticated; reachability only").mcp-auth—tools/callon the cheapest paid canary tool (nansen_score_top_tokens, ~1 credit). Server error text is mapped to actionable next steps: key rejected → check the client'sNANSEN-API-KEYheader / rotate at app.nansen.ai; insufficient credits → top up; rate limited → retry (and the setup is not reported verified).Verified ⟺ the paid canary call succeeds with a well-formed result. On failure the command exits non-zero through the CLI's unified error envelope (
code: MCP_VERIFY_FAILED);--jsonreturns the structured checks (failure carries them indetails). Success message is honest about scope: the CLI proves the key works against the server's paid data path and reminds the user to put that same key in their client's header; README documents an in-client canary prompt for that final hop.No new dependencies — the stateless streamable-HTTP server needs exactly two
fetchPOSTs (JSON or SSE-framed responses both handled).Changes
src/mcp-verify.js(new) — MCP JSON-RPC probe + checks + report formattingsrc/cli.js—mcp verifywiring, HELP entry; barenansen mcpprints usage only (never runs the paid probe implicitly)src/doctor.js— exportresolveAuthConfig, extract sharedformatChecks(doctor output unchanged, proven by existing tests)src/schema.json—mcp verifycommand schemaREADME.md— "Verify your MCP setup" section + troubleshooting rowsrc/__tests__/mcp-verify.test.js(new, 22 tests) — mocked-fetch coverage of SSE/JSON parsing, every auth-failure mapping, timeout/network/unparseable paths, key precedence, report format, and the non-zero--jsonexit contract.changeset/mcp-verify.md— minorTesting
npm test: 2310 passed, 2 skipped (57 files) — all fetch mocked. Re-run after mergingmain(2026-08-28).npm run lint: clean--jsonfailure → single machine-readable envelope; barenansen mcp→ usage, no network callNote for docs: the verify one-liner is worth adding to the MCP "Connecting" page on docs.nansen.ai (external repo, out of scope here).
🤖 Generated with Claude Code