Use blockchain RPC in LangChain agents with BlockVectra
Give a LangChain agent live blockchain data with one tool over BlockVectra's keyless public endpoint, then add the docs MCP server and an API key for the methods that need one.
A LangChain agent reads live blockchain data through one tool that POSTs JSON-RPC to https://api.blockvectra.com/v1/eth_mainnet/public. That endpoint needs no API key or sign-up for the methods in each chain's public.methods. A key adds the rest, and the Free Plan gives 30,000,000 CU per 30-day window. Checked .
import httpx
from langchain.agents import create_agent
from langchain.tools import tool
RPC = "https://api.blockvectra.com/v1/eth_mainnet/public"
@tool
def eth_block_number() -> str:
"""Return the latest Ethereum mainnet block number as a hex string."""
body = {"jsonrpc": "2.0", "id": 1, "method": "eth_blockNumber", "params": []}
return httpx.post(RPC, json=body, timeout=10).json()["result"]
agent = create_agent("claude-sonnet-5", tools=[eth_block_number])
result = agent.invoke({"messages": [{"role": "user", "content": "What is the latest block?"}]})
print(result["messages"][-1].content)Install with pip install langchain httpx; the model string and its provider key follow the LangChain quickstart. The tool uses LangChain's @tool decorator and create_agent.
The same tool in TypeScript
import * as z from "zod";
import { createAgent, tool } from "langchain";
const ethBlockNumber = tool(
async () => {
const res = await fetch("https://api.blockvectra.com/v1/eth_mainnet/public", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_blockNumber", params: [] }),
});
return (await res.json()).result as string;
},
{ name: "eth_block_number", description: "Latest Ethereum mainnet block number (hex).", schema: z.object({}) },
);
const agent = createAgent({ model: "claude-sonnet-5", tools: [ethBlockNumber] });See the LangChain JS tools guide for the tool() signature.
Call any method with an API key
Methods outside public.methods, such as eth_getLogs, need a key. Read it from the environment and send it in the x-api-key header; the chain slug (eth_mainnet, base_mainnet, and so on) comes from GET /v1/chains:
import os
import httpx
from langchain.tools import tool
@tool
def rpc_call(chain: str, method: str, params: list) -> dict:
"""Call a JSON-RPC method on a BlockVectra chain slug such as base_mainnet."""
headers = {"x-api-key": os.environ["BLOCKVECTRA_API_KEY"]}
body = {"jsonrpc": "2.0", "id": 1, "method": method, "params": params}
return httpx.post(f"https://api.blockvectra.com/v1/{chain}", json=body, headers=headers, timeout=15).json()Returning the whole JSON-RPC response lets the model read an error object and change its next call. To create the key without a browser, run the four-step flow in the programmatic sign-up guide: challenge, signature, login, then POST /keys. Developers can also create a key in the console.
Add the docs MCP server
LangChain agents connect to MCP servers through MCPAdapter. Point it at https://docs.blockvectra.com/mcp to give the agent list_chains, get_status, rpc_call, read_doc and the other tools listed on the MCP server page. Connecting needs no key.
from langchain.agents import create_agent
from langchain.mcp import MCPAdapter
async def main():
async with MCPAdapter("https://docs.blockvectra.com/mcp") as adapter:
tools = await adapter.list_tools()
agent = create_agent("claude-sonnet-5", tools)
return await agent.ainvoke({"messages": [{"role": "user", "content": "List the supported chains."}]})Install with pip install "langchain[mcp]" (langchain>=1.4.0, in beta). To use keyed tools, pass the key as a bearer token: MCPAdapter(Client(url, auth=os.environ["BLOCKVECTRA_API_KEY"])) with from fastmcp.client import Client, as in LangChain's MCP authentication guide.
In TypeScript, install @langchain/mcp-adapters@^2.0.0 and pass a headers map:
import { MCPAdapter } from "@langchain/mcp-adapters";
import { createAgent } from "langchain";
const adapter = new MCPAdapter({
servers: {
blockvectra: {
url: "https://docs.blockvectra.com/mcp",
headers: { "x-api-key": process.env.BLOCKVECTRA_API_KEY! },
},
},
});
try {
const agent = createAgent({ model: "claude-sonnet-5", tools: await adapter.listTools() });
// agent.invoke(...)
} finally {
await adapter.close();
}Drop the headers line to connect keyless. Official references: LangChain MCP (Python) and LangChain MCP (JavaScript).
Errors your tool will see
| Response | Meaning | What the agent should do |
|---|---|---|
HTTP 401, -32024, missing_api_key | Keyed URL called without a key | Send the key in x-api-key or the path |
HTTP 401, -32024, invalid_api_key | Key unknown, disabled or revoked | Check the key in the console; a new key takes a few seconds to activate |
-32601, method_not_public | Method is not in the chain's public.methods | Use a keyed URL instead of /public |
-32601, method not available | Method is not enabled on that chain | Check methods.allow in GET /v1/chains |
Each error carries data.reason and a docs_url; the full list is on the errors page.
Common questions
Does the public endpoint work for eth_getLogs? No. It serves only the methods in the chain's public.methods; eth_getLogs and the Data API need an API key.
Can the agent pass the API key as a tool argument? No. Keep it in the environment or the MCP client headers; the MCP server rejects keys in tool arguments.
Can the tool target another chain? Yes. Replace eth_mainnet with any chain slug that has a public.url in GET /v1/chains.
Next steps
- Agent framework overview for ElizaOS, viem, wagmi and Coinbase AgentKit.
- Connect an AI agent to discover endpoints with MCP, llms.txt and OpenAPI.
- Billing rules for CU metering, rate limits and non-billed errors.
Last updated:
Agent framework recipes
Configure blockchain RPC for LangChain, ElizaOS, viem, wagmi, and Coinbase AgentKit, with a page and runnable code for each, and discover capabilities via docs MCP.
ElizaOS
Point ElizaOS's plugin-evm at BlockVectra with two environment variables, start keyless on the public endpoint, and add the docs MCP server through plugin-mcp.