TypeScript and Python examples for AI agents and automated scripts. Start with a keyless public RPC read: use Robinhood mainnet by default, or select an EVM chain by its chain ID. No wallet, account, or API key is required for this step. When you need the Data API or an account, continue to the full SIWE onboarding flow below.
Agents working from a clone can start with AGENTS.md to choose documentation, public-read or account examples.
| Task | Start here |
|---|---|
| Ask a setup question | Documentation skill or Python MCP client |
| Read documentation from your framework | LangChain · Google ADK · Pydantic AI · OpenAI Agents SDK · mcp-use / Node.js |
| Check a chain ID | Python without cloning or local Python |
| Check chain ID and read a block number | TypeScript public reader |
| Create or reuse an account/key, then call Data API | Full onboarding setup and run instructions |
Documentation and public-read examples need no BlockVectra account or key. npm start runs the full onboarding flow and can create a wallet, account and API key. Each entry below lists its prerequisites and request limits.
With uv installed, you can run the pinned script without cloning. This command selects Mode mainnet:
uv run --no-project --script --python 3.11 https://raw.githubusercontent.com/blockvectra/agent-quickstart/0df68765d6706a4df88aee469dfb4fd07beeef89/examples/public_chain.py 34443A successful check prints {"chain":"mode_mainnet","chainId":34443}. Replace the final argument with another chain ID from the live directory, or omit it for Robinhood mainnet. uv downloads the script and may provision Python 3.11 if needed; the script itself uses only the Python standard library.
The script makes at most two serial HTTP requests: it selects the chain from the public directory, then verifies eth_chainId against that selection. It checks chain identity, not the latest block or method coverage. It never retries automatically. Each socket operation has a 15-second timeout; this is a socket timeout, not a hard deadline for DNS or the full request.
Prefer a local Python installation? Use the standard-library entry below. To also read the latest block number, use the TypeScript reader.
For documentation help without running the TypeScript example, install the BlockVectra documentation skill in an Agent Skills-compatible client. The pinned installer requires Node.js >= 22.20.0. From your project directory (your configured workspace for OpenClaw), choose the command for your agent; each installs to the current project without confirmation prompts:
# Codex
npx --yes skills@1.7.4 add blockvectra/agent-quickstart --skill blockvectra-docs --agent codex --yes
# Claude Code
npx --yes skills@1.7.4 add blockvectra/agent-quickstart --skill blockvectra-docs --agent claude-code --yes
# GitHub Copilot
npx --yes skills@1.7.4 add blockvectra/agent-quickstart --skill blockvectra-docs --agent github-copilot --yes
# OpenClaw
npx --yes skills@1.7.4 add blockvectra/agent-quickstart --skill blockvectra-docs --agent openclaw --yesTry: "Use blockvectra-docs to explain Robinhood mainnet public RPC setup and cite the source." The skill uses configured MCP documentation tools or an available HTTP reader. It needs no BlockVectra account or key and does not run RPC or the SIWE onboarding example. It contains instructions, not a bundled model or MCP server.
For Copilot CLI, connect the hosted documentation tools before asking the question:
copilot mcp add --transport http blockvectra-docs https://docs.blockvectra.com/mcp/docsThis server route exposes only search_docs and read_doc and rejects other tools. No BlockVectra key or client-side tool filter is needed.
The installer collects anonymous installation telemetry by default; set DISABLE_TELEMETRY=1 to opt out. See the installer documentation.
With Node.js 22 (>= 22.18) or Node.js >= 24.12, and git, run the keyless reader directly without installing dependencies:
git clone https://github.com/blockvectra/agent-quickstart.git
cd agent-quickstart
node src/public-read-cli.tsTo select another EVM chain, pass its decimal chain ID:
node src/public-read-cli.ts 56 # BSC mainnet
node src/public-read-cli.ts 1 # Ethereum mainnet
node src/public-read-cli.ts 57073 # Ink
node src/public-read-cli.ts 130 # Unichain
node src/public-read-cli.ts 252 # Fraxtal
node src/public-read-cli.ts 747474 # Katana
# With the npm entry: npm run read:public -- 56Omitting the argument keeps Robinhood mainnet (4663). The selected chain must appear exactly once in the current directory and advertise both public read methods. The reader checks the returned chain ID against your argument before fetching a block number; it stops if the chain or keyless policy is unavailable.
Node's built-in TypeScript support runs this entry without a build or npm installation. For other Node.js versions, use the existing npm path after cloning:
npm ci --ignore-scripts
npm run read:publicThe command reads the public chain directory, confirms the selected chain’s exact public endpoint and required methods, then serially reads the chain ID and latest block number. The whole check uses at most three HTTP requests: the directory plus two JSON-RPC calls. No wallet, account sign-up, or API key is involved. If the directory stops advertising the public endpoint or the required methods, it stops before any RPC. Data API and account operations still need an API key, and the full onboarding flow below remains available.
If a request fails with an HTTP status or times out, the command identifies the directory or RPC method involved and exits with code 1. For HTTP 429, wait before trying again manually. The command does not retry automatically and does not print response bodies or raw exceptions. Other failures use a generic error message. Successful runs print the same JSON result.
Prefer Python? Python 3.10 or newer can run the same keyless identity check with no Node.js, npm, third-party packages, wallet, or API key:
git clone https://github.com/blockvectra/agent-quickstart.git
cd agent-quickstart
python3 examples/public_chain.py
python3 examples/public_chain.py 56 # Select a chain from the live directoryIf your Python project uses ApeWorX evmchains, its published 0.1.10 package already lists BlockVectra public RPCs for Robinhood mainnet and testnet. You can select them from its exported metadata without adding a provider adapter. For a reproducible metadata check, use evmchains==0.1.10 in your project's existing environment:
from evmchains import PUBLIC_CHAIN_META
for network, expected_id, endpoint in (
("mainnet", 4663, "https://api.blockvectra.com/v1/robinhood_mainnet/public"),
("testnet", 46630, "https://api.blockvectra.com/v1/robinhood_testnet/public"),
):
chain = PUBLIC_CHAIN_META["robinhood"][network]
if chain["chainId"] != expected_id or endpoint not in chain["rpc"]:
raise RuntimeError("Expected endpoint is absent from packaged chain metadata")
print(network, expected_id, endpoint)This reads installed metadata and prints two endpoints; it sends no HTTP or RPC requests and creates no wallet or account. A packaged URL is not a live availability check. Before making calls, check the selected endpoint's current public policy in the live chain directory, including required methods and history limits. The existing python3 examples/public_chain.py 4663 or 46630 command above selects from that directory and checks chain identity. It does not validate every method or establish archive coverage.
Beyond the keyless read, the full example covers:
- Wallet identity: Reads an Ethereum EOA private key from
AGENT_PRIVATE_KEYor from a local.agent-wallet.jsonfile. If neither is configured, generates a new wallet locally and saves it to.agent-wallet.json(permission0600) so subsequent runs reuse the same identity instead of creating new accounts. - Programmatic account sign-up: Authenticates via Sign-In with Ethereum (SIWE / EIP-191) against
https://console-api.blockvectra.com/v1in programmatic mode (omitting theOriginheader). First-time wallet sign-in automatically provisions an account. - API key provisioning: Reuses
.agent-key.jsonfor the same wallet, or creates and saves one key with private0600permissions.BLOCKVECTRA_API_KEYtakes precedence without reading or changing the saved key. - JSON-RPC execution: Reads the active chain directory from
GET https://api.blockvectra.com/v1/chains, selects the uniquerobinhood_mainnetentry with numeric chain ID4663, verifieseth_chainIdon that endpoint, then executeseth_blockNumberusing the API key. - Data API query: Calls the read-only dataset freshness endpoint (
GET /v1/data/{chain}/status/freshness) defined in the OpenAPI specification.
For a concrete event check, start with the pinned BSC receipt/log sample. Download its linked ZIP, extract it, and run with Node.js 22+:
node verify-sample.mjs observed-sample.jsonNo npm installation, account or key is needed. After the download, the checker runs offline. Expected output: PASS 1 receipt event matched among 4 returned logs.
The saved observation is from 2026-10-25, 13:26:17–13:26:21 UTC, BSC mainnet (56), block 129476271. It compares one receipt event with the fixed-block logs across eight fields. It checks consistency in that saved observation, not current availability, independent canonicality or complete history.
The same bundle includes bsc-compare-provider.mjs for an optional comparison using your own BSC endpoint. Follow its private environment setup; it makes at most three serial RPC requests with no retries or broadcasts and may consume provider quota. These diagnostic requests carry BlockVectraQA/1 and are separate from customer traffic. The comparison client was tested with synthetic transport; those tests are separate from the original saved live responses.
BlockVectra already supports JSON-RPC authentication with a key in the URL path. AgentOS can use it without a header-auth patch or a local proxy. Supply BLOCKVECTRA_API_KEY privately in the AgentOS process environment, then set:
export RPC_ROBINHOOD_URL="https://api.blockvectra.com/v1/robinhood_mainnet/${BLOCKVECTRA_API_KEY:?Set BLOCKVECTRA_API_KEY privately first}"Start AgentOS from that environment using your usual command. An existing 4663 or robinhood entry in [trading.rpc_urls] takes priority: remove that override, or update it privately to the same path-key URL. AgentOS's existing resolver checks explicit overrides before RPC_ROBINHOOD_URL and the public default. The shell command expands the variable; TOML does not perform this shell expansion.
Treat the full URL as a secret: keep it out of version control, shared logs, screenshots and browser code. Do not use shell tracing (set -x) while setting it. Header-capable clients can keep using x-api-key; existing eRPC users can use the configuration below to keep their local client URL free of credentials.
The configuration was checked against the linked AgentOS resolver using a synthetic key and the published path-key contract. No live authenticated RPC, AgentOS trading or LP workflow was executed. Its LP path can also use a separate public log fallback, so this override does not mean every external call uses BlockVectra.
Use createHeaderScopedRpcFetch with a server-side makeRpc client that accepts fetcher(stringUrl, requestInit). Choose the private endpoint from the public chain directory (GET https://api.blockvectra.com/v1/chains) and keep your existing chain choice; robinhood_mainnet and eth_mainnet are examples, not defaults. In your server module that already imports makeRpc, keep your existing network ('robinhood' for this example) and existingRpcEnv (including any fallback):
import { createHeaderScopedRpcFetch } from './examples/header-scoped-rpc-fetch.mjs';
const endpoint = 'https://api.blockvectra.com/v1/robinhood_mainnet';
const fetcher = createHeaderScopedRpcFetch({
endpoint, // Must equal your configured primary URL exactly.
apiKey: process.env.BLOCKVECTRA_API_KEY,
});
const rpc = makeRpc(network, {
fetcher,
env: { ...existingRpcEnv, RADAR_ROBINHOOD_RPC_URL: endpoint },
});Supply BLOCKVECTRA_API_KEY through your server's secret manager. A missing key fails when constructing the fetcher, without printing it. Never put it in URLs, logs, browser code or fallback configuration. Only the exact endpoint gets x-api-key. Other headers, method, body and AbortSignal survive; caller x-api-key or Authorization is rejected for Headers, tuples and objects. Redirects always fail, even with caller follow; there are no retries, body reads, response wrappers or added URL parameters, including on 429.
Configuration rejects credentials, explicit ports, query/fragment and public suffixes; the endpoint must be literal https://api.blockvectra.com/v1/<slug> (lowercase letters/digits, _ or - separators). Keys must be nonempty printable ASCII without surrounding whitespace; validation happens before requests, with fixed errors that omit the key. Strings match verbatim, so normalized path/query/fragment tricks gain no authorization. URL objects use a native normalized serialization snapshot; information already lost in new URL(...) cannot be recovered. Request is unsupported.
This only wires headers safely on the server; it is not a generic credential scrubber, browser helper or complete SDK. Other caller credentials remain your responsibility. A custom fetchImpl must be trusted and honor redirect: 'error'. Tests use synthetic keys and loopback HTTP with test-only URL mapping, not Prod DNS/TLS. Chain capability, chain ID, usage and actual scans (including a 24-hour scan) remain unverified.
Already run eRPC? The pinned configuration and offline reproduction pairs Robinhood mainnet (4663) and testnet (46630) with explicit upstream URLs and an x-api-key header. It uses ordinary eRPC upstream configuration; no BlockVectra-specific adapter is required.
Provide a nonempty BLOCKVECTRA_API_KEY in the server environment before startup: YAML can expand a missing variable to an empty header. Keep the expanded configuration and authentication headers out of shared logs. The example was checked with eRPC 0.5.0 and local fixtures, not live RPC. Public /public routes have different methods and limits; they are not drop-in replacements for this keyed setup.
After the keyless chain read, you can fetch a separate HEY builder card to see the project's latest reported ship and its sources. With curl available, this example uses the Ekubo token on Robinhood Chain:
hey_card_response="$(curl --silent --show-error --max-time 15 --max-filesize 131072 \
--header 'x-hey-integration: blockvectra-partner-example/0.1.0' \
--write-out '\n%{http_code}' \
'https://heyresearch.xyz/api/v1/builder?chain=4663&token=0x570c5aa79c798e7a418412cc8399ae5bcce570c5')" || exit
hey_card_status="${hey_card_response##*$'\n'}"
hey_card_body="${hey_card_response%$'\n'*}"
case "$hey_card_status" in
200) ;;
404) printf '%s\n' 'HEY returned 404; the separate chain read is unchanged.' >&2 ;;
*) printf 'HEY request returned HTTP %s\n' "$hey_card_status" >&2; exit 1 ;;
esac
printf '%s\n' "$hey_card_body"HTTP 404 with error: "not_found" means HEY has no published project for that contract. Follow its returned scan_url if needed; this does not invalidate the separate RPC result.
Keep HEY's as_of and activity timestamps separate from the time of your chain read. Use the returned project_link for the source context. When activity_applies_to_token is false, the activity is project-level; when activity_measured is false, activity is unmeasured, not zero. A block number does not verify the builder card.
+-------------------------------------------------------------+
| Local Agent Runtime |
| |
| 1. Generate / load Ethereum EOA wallet (viem) |
| 2. Sign SIWE challenge locally with EIP-191 personal_sign |
+------------------------------+------------------------------+
|
| (HTTP POST, no Origin header)
v
+-------------------------------------------------------------+
| BlockVectra Control Plane (console-api) |
| |
| - POST /auth/siwe/challenge -> Issues nonce & SIWE message |
| - POST /auth/siwe/login -> Verifies signature & issues |
| session token (rgs_...) |
| - POST /keys -> Generates API key (rgw_...) |
+------------------------------+------------------------------+
|
| (Authenticated with x-api-key)
v
+-------------------------------------------------------------+
| BlockVectra Data Plane (Gateway) |
| |
| - GET /v1/chains -> Public chain directory |
| - POST /v1/{chain} -> Chain-scoped JSON-RPC |
| - GET /v1/data/{chain}/... -> REST Data API endpoints |
+-------------------------------------------------------------+
- Local private keys: Private keys never leave the local environment and are never transmitted to any API endpoint or conversational context.
- Header-based key authentication: API keys are passed exclusively via request headers (
x-api-keyorAuthorization: Bearer). - No secret leakage in logs: Private keys, session tokens, and API keys are never printed in plaintext (only truncated prefixes such as
rgw_54dd...appear in diagnostic output). - Wallet-bound account recovery: An agent's account identity is bound to its Ethereum wallet address. If a session token or API key is lost, signing in again with the same wallet restores access to manage or revoke existing keys.
- Node.js >= 18.0.0
- npm
- git
-
Clone the repository and enter the directory:
git clone https://github.com/blockvectra/agent-quickstart.git cd agent-quickstart -
Install dependencies from the lockfile:
npm ci --ignore-scripts
-
(Optional) Configure an existing wallet by injecting
AGENT_PRIVATE_KEYinto the process environment through your runtime's secret manager..env.exampledocuments its format;npm startdoes not load a.envfile automatically.Without this override, the script reuses
.agent-wallet.json. It creates a wallet only when that file is absent, using an exclusive write and permission0600on POSIX filesystems. An unreadable, damaged or inconsistent wallet stops execution before sign-in and is never overwritten. Preserve the file and restore a trusted backup before retrying; deleting it creates a different identity on the next run. The private key is never printed to the console.
Execute the TypeScript entrypoint directly using tsx:
npx tsx src/index.tsOr run via npm script:
npm startThe block-number check requires HTTP success, a matching JSON-RPC response and a valid Ethereum block quantity. Rejected responses stop before the Data API step; valid explicitly retryable errors have at most five attempts per RPC method (up to ten across chain-ID and block-number verification). See JSON-RPC responses and Ethereum quantities.
Whole-request errors with id: null may be retried when explicitly marked retryable; a successful response must still match request ID 1.
This mainnet example does not select a network by display-name similarity or fall back to testnet. Missing, duplicate or inconsistent mainnet directory entries stop before RPC. A valid eth_chainId result must equal 4663 before the script requests a block number or Data API freshness. This adds one read-only RPC call on a successful run; chain verification may fail after wallet/account/key provisioning has already occurred.
Every HTTP request in the full onboarding flow has a 15-second deadline, including response-body reads. A timeout stops the run without retrying that request. It does not prove that the server did not perform a sign-in or key creation; if either request times out, check with the same wallet in Console before rerunning.
The Data API freshness request uses a 15-second timeout with no retry. A response is consumed only when HTTP succeeds, the JSON envelope is an object, meta.chain equals the selected robinhood_mainnet, data is an array, and every row has a string dataset with max_block_number and seconds_behind each an integer or null. Unexpected rows stop the run with a local error that preserves the HTTP status but not the upstream body. Empty lists, zero, negative, null and extra fields are accepted. This check only proves the request flow and the consumed fields; it does not establish that every dataset is fresh, stale-free or complete, and a null value is logged as unknown rather than zero.
Run npm test and npm run typecheck for offline regression checks. Tests replace network calls and do not provision accounts.
Pull requests and pushes to main run these checks on Node.js 24.21.0 through Offline checks, after installing the lockfile dependencies with npm ci --ignore-scripts.
The full onboarding run saves the API key and key ID in .agent-key.json, bound to the wallet address. Later runs in the same directory reuse it and skip sign-in and key creation. The key survives a later RPC/Data API failure, so rerunning does not silently create another one. Keep this git-ignored file private and load api_key through your server or Agent runtime's secret manager; never paste it into chat or client code.
A damaged, overly permissive or different-wallet file stops before sign-in and is not overwritten. An expired or revoked saved key is not automatically replaced: manage it using the same wallet, then deliberately replace the local file or inject BLOCKVECTRA_API_KEY. If saving a newly created key fails, the example attempts to revoke that key and reports only its ID and whether the revoke request was accepted. This is local persistence, not a remote key-status check.
src/wallet-balances.ts is an opt-in, read-only helper for GET /v1/data/{chain}/addresses/{address}/balances. collectBalancePages(readPage, expectedChain, maxPages = 20) follows next_cursor until it is omitted and rejects on malformed envelopes, chain mismatch, HTTP/read failures, repeated cursors, the page cap, duplicate tokens, or a changed known meta.refreshed_at. Balances stay exact decimal-integer strings; symbol/decimals stay null when unknown (decimals: 0 is a real value). readPage must reject HTTP errors before returning JSON. Run it server-side only; the API key must not reach browsers or logs.
import { collectBalancePages } from "./src/wallet-balances.js";
const chain = "robinhood_mainnet"; // check chain capability/coverage first
const address = "0x..."; // wallet to read
const result = await collectBalancePages(async (cursor) => {
const url = new URL(`https://api.blockvectra.com/v1/data/${chain}/addresses/${address}/balances`);
if (cursor !== undefined) url.searchParams.set("cursor", cursor); // opaque, unchanged
const res = await fetch(url, { headers: { "x-api-key": process.env.BLOCKVECTRA_API_KEY! } });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}, chain);Before real use, confirm the selected chain's capability and coverage for this endpoint; this repository makes no claim that Robinhood balances are currently available and has not run this against a live API. Balances come from a snapshot refreshed every 6 hours (plus up to 30 minutes of delay and the refresh run), so rows may be stale. meta.as_of_block is the indexed head, not the snapshot height; read meta.refreshed_at (null means unknown, treat as stale). Pages are not a transactionally consistent portfolio; pages keeps each page's original meta. The aggregate refreshedAt is the shared known time only when every page reported the same one; if any page has refreshed_at: null it is null (unknown), regardless of page order, and differing known times are still rejected even with a null page between them.
Illustrative output (addresses, keys, block heights and dataset counts vary; this revision was validated offline):
=== BlockVectra AI Agent Quickstart ===
[1/5] Generated agent wallet and saved to .agent-wallet.json (0600).
Tip: Set AGENT_PRIVATE_KEY in your environment to override.
Wallet Address: 0x...
[2/5] Requesting SIWE challenge...
Signing verbatim challenge message with EIP-191...
Submitting SIWE login...
Account Created: true
[3/5] Provisioning API key...
Key ID: k_xxxxxxxxxxxx
API Key saved to .agent-key.json (0600). Keep this file private.
[4/5] Reading chain directory from GET /v1/chains...
Selected: Robinhood Chain (robinhood_mainnet, Chain ID 4663)
Verifying eth_chainId via JSON-RPC...
Verified Chain ID: 4663
Calling eth_blockNumber via JSON-RPC...
Latest Block: 77213136 (0x49a2dd0)
[5/5] Querying Data API GET /{chain}/status/freshness...
Data Datasets Tracked: 15
Dataset 'blocks': block 77213095 (0s lag)
=== Quickstart Completed Successfully ===
Key ID: k_xxxxxxxxxxxx (Revoke anytime via POST https://console-api.blockvectra.com/v1/keys/k_xxxxxxxxxxxx/revoke)
BlockVectra provides two Streamable HTTP MCP endpoints. Use https://docs.blockvectra.com/mcp/docs for documentation only; the full endpoint below also includes RPC, Data and account tools:
https://docs.blockvectra.com/mcp
Python 3.11+ can connect directly with the official MCP Python SDK. With uv installed, run this from the cloned repository:
uv run examples/mcp_docs.py
uv run examples/mcp_docs.py --query "Robinhood mainnet RPC"
uv run examples/mcp_docs.py --query "Robinhood 主网 RPC" --lang zhThe example pins mcp==2.3.0 in its script metadata, lists the two documentation tools, then reads the English quickstart page by default. With --query, it searches by keyword and reads only the first matching document in the selected --lang; no matches cause an error instead of silently reading quickstart. Without --query, --lang selects the language of quickstart. It prints JSON containing the tool names, page path, language and complete Markdown text, so an agent can consume the result. It uses the documentation-only endpoint: no BlockVectra key, wallet, model API or chain RPC is involved. Errors exit non-zero; the example has a 40-second overall deadline. Dependency installation occurs before that deadline.
The separate standard-library RPC example above still needs no third-party Python packages.
For LangChain tools, use examples/langchain_docs.py. With Python 3.11+ and uv, run from the cloned repository:
LANGSMITH_TRACING=false uv run examples/langchain_docs.pyTo try the same example without cloning, run this fixed published version (Python 3.11+ and uv required):
LANGSMITH_TRACING=false uv run --script --python 3.11 \
https://raw.githubusercontent.com/blockvectra/agent-quickstart/f6199662a459abebccba5c3451d80bf5e9a199e4/examples/langchain_docs.pyuv downloads the script and manages its dependencies. The commit in the URL fixes the example's source version; it does not lock every transitive dependency.
The script declares langchain[mcp]==1.4.9, fastmcp==4.1.6 and mcp==2.3.0 in inline metadata; uv manages its environment separately from project dependencies. It uses the current langchain.mcp.MCPAdapter API, which is beta, rather than the deprecated adapters package. See the LangChain migration guide.
It verifies that only search_docs and read_doc are exposed, searches for English quickstart, then reads that page through LangChain tools. JSON output contains the protocol version, tool names and both tool messages with the document text. No LLM, model API key, BlockVectra key, wallet or chain RPC is needed. The command disables LangSmith tracing. Operation timeouts are 15 seconds, with a 60-second cooperative overall timeout; dependency installation happens before those timeouts. The existing call logic was checked with the pinned versions; this does not verify a model-driven agent workflow.
Use Python 3.11+ and uv from this checkout:
uv run examples/adk_docs.pyThe example pins google-adk[mcp]==2.14.0 and mcp==2.3.0. It connects McpToolset to the remote /mcp/docs endpoint, checks for exactly search_docs and read_doc, searches for quickstart, then reads that English page and prints its Markdown in JSON. It needs no BlockVectra account, wallet, API key, Google Cloud project or model API key; the in-memory ADK context runs no model.
The two-tool scope is enforced by the server. Keep this toolset open while using its tools, then call await toolset.close() in finally. For a model-backed agent, add this same toolset to your ADK agent's tools and configure your model provider separately. See the official ADK MCP guide.
The example sets 15-second HTTP/read timeouts and a 60-second overall timeout, follows no HTTP redirects, and adds no retry loop. ADK retains its own session-recovery behavior. A failed search, tool error, empty document or unexpected tool list stops the example. This reads documentation only; it does not execute the RPC or account steps described in the page.
Use Python 3.11+ and uv from this checkout:
uv run examples/pydantic_docs.pyThe example pins pydantic-ai-slim[mcp]==2.66.0, fastmcp==4.1.6 and mcp==2.3.0. It uses Pydantic AI's MCPToolset to discover the two documentation tools, search for quickstart, and read that English page. JSON output includes the Markdown. No model, model API key, BlockVectra account, wallet or API key is needed.
The async with toolset block keeps the connection open for both calls and closes it on success or failure. Tool errors, an unexpected tool list, a missing search match or empty document stop the example. HTTP and tool timeouts are 15 seconds, with a 60-second cooperative overall timeout; dependency installation happens before these timeouts. The HTTP client follows no redirects and the example adds no retry loop. It reads documentation without executing the RPC or account instructions in the page.
For a model-backed agent, configure your model separately and reuse the toolset in the agent's toolsets. Pydantic AI recommends its higher-level MCP capability for ordinary agent runs; this example uses MCPToolset directly so its connection and two calls are explicit. See the official client guide. This example does not test a model-driven agent workflow.
Use Python 3.12+ and uv from this checkout:
uv run examples/openai_agents_docs.pyThe example pins openai-agents==0.24.0 and mcp==2.3.0. It uses the SDK's MCPServerStreamableHttp to discover the two documentation tools, search for quickstart, and read that English page. JSON output includes the Markdown. No model, model API key, BlockVectra account, wallet or API key is needed, and tracing is disabled.
The async with server block keeps the connection open for both calls and closes it on success or failure. Tool errors, an unexpected tool list, an empty search or an empty document stop the example. HTTP and session timeouts are 15 seconds, with a 60-second cooperative overall timeout; dependency installation happens before these timeouts. The HTTP client follows no redirects and the example adds no retry loop. It reads documentation without executing the RPC or account instructions in the page.
This calls the SDK-managed MCP server directly; it does not run an Agent or Runner. For a model-backed agent, configure your model separately and pass the same server in the agent's mcp_servers. See the official OpenAI Agents SDK guide. This example does not test a model-driven agent workflow.
Use the standalone mcp-use example with Node.js 22.22.2+:
cd examples/mcp-use-docs
npm ci --ignore-scripts
npm startIt connects to the docs-only MCP endpoint, lists the tools, searches for quickstart in English and prints the page returned by the search. No local server, model, account or API key is needed. The client closes on success or failure; tool errors and empty results stop the script. Calls have 15-second timeouts. Dependency installation needs network access and happens before the script starts.
SDK anonymous telemetry is disabled before the client module loads.
The example pins @mcp-use/client to 2.4.5 and commits its dependency lockfile. Internal QA runs set BLOCKVECTRA_INTERNAL_QA=1; ordinary runs leave it unset. Reading the document does not execute its RPC or account instructions.
The documentation-only endpoint exposes search_docs and read_doc without an API key:
claude mcp add --transport http blockvectra-docs https://docs.blockvectra.com/mcp/docsRPC availability without a key follows the selected chain's public methods and limits. Calls outside that policy, indexed Data API and account tools require your own API key; keyed calls still have method and usage limits.
For the full tools, merge this separate blockvectra entry into your project's .mcp.json, preserving the documentation connection and any other servers:
{
"mcpServers": {
"blockvectra": {
"type": "http",
"url": "https://docs.blockvectra.com/mcp",
"headers": {
"x-api-key": "${BLOCKVECTRA_API_KEY}"
}
}
}
}Set BLOCKVECTRA_API_KEY privately before starting Claude Code. Keep the literal variable reference in the file; Claude Code expands it in the header. Do not put the key in CLI arguments or chat.
Add the server to .cursor/mcp.json or through Cursor Settings:
{
"mcpServers": {
"blockvectra-docs": {
"url": "https://docs.blockvectra.com/mcp/docs"
}
}
}Configure the headers object so the API key is passed securely in HTTP headers:
{
"mcpServers": {
"blockvectra": {
"url": "https://docs.blockvectra.com/mcp",
"headers": {
"x-api-key": "${env:BLOCKVECTRA_API_KEY}"
}
}
}
}Cursor resolves environment variables with ${env:NAME}. Make BLOCKVECTRA_API_KEY available to the Cursor process before starting it; this HTTP configuration does not read a project .env file. See Cursor MCP configuration.
- Headers only: API keys must be configured strictly in HTTP request headers (
x-api-keyorAuthorization: Bearer). - Never pass keys in chat: Do not pass API keys or wallet private keys as tool arguments or paste them into conversational prompts.
- Cache bypass: All keyed MCP requests carry
Cache-Control: no-storeto prevent caching of tenant data.
If an agent loses its API key or session token, it can regain access using the same Ethereum wallet:
- Re-authenticate: Submit a new SIWE challenge and signature to
POST /auth/siwe/login. The server returns a fresh session token (account_created: false). - List keys:
curl -s "https://console-api.blockvectra.com/v1/keys" \ -H "Authorization: Bearer <session_token>"
- Revoke a key:
curl -s -X POST "https://console-api.blockvectra.com/v1/keys/<key_id>/revoke" \ -H "Authorization: Bearer <session_token>"
- Provision a replacement key:
curl -s -X POST "https://console-api.blockvectra.com/v1/keys" \ -H "Authorization: Bearer <session_token>" \ -H "Content-Type: application/json" \ -d '{"label":"agent-replacement-key"}'
- Programmatic Sign-up Guide
- AI Agent Integration Guide
- Plans and Pricing
- Data API OpenAPI Specification
- JSON-RPC OpenAPI Specification