# Bring your own RPC: run the API, SDK and MCP through your own node

> Canonical: https://blazephoenix.xyz/learn/bring-your-own-rpc
> License: CC BY 4.0 (attribution + link) · © 2026 BlazePhoenix
> Updated: 2026-07-27

Every endpoint now takes an optional rpc parameter, so heavy callers can route reads through their own node. The free keyless tier is unchanged — this only keeps automated volume off the shared pool.

Every quote is an eth_call, and node capacity is the one part of this stack that is not free to us. The free tier is not going anywhere — no key, no signup, open CORS, exactly as it has always been. But if you are running a bot that quotes every few seconds, you can now point our API at your own node and keep that volume off the shared pool entirely.

It is one parameter. Nothing else about the call changes, and nothing about the answer changes either — you are asking the same contract the same question. The only difference is whose node carries the read.

## Why we are asking, plainly

This project runs on a small budget. The shared RPC pool is what lets someone with no key, no account and no money get a real on-chain quote in one curl — and that is worth protecting. A single automated caller polling at a few seconds can consume more of that pool in a day than a thousand humans do, and every request it takes is one another person cannot have.

So this is not a paywall arriving by instalments. It is the opposite: a way for the callers who can carry their own weight to do so, so that the free path stays genuinely free for the people who cannot. If you are doing anything sustained and automated, bringing a node is the single most useful thing you can do for everyone else using this.

## Getting a node (free tiers are enough)

You do not need to run hardware. Every major provider has a free tier that comfortably covers a personal bot: Alchemy, Infura, QuickNode, Ankr and dRPC all issue an https endpoint per chain within a couple of minutes. Pick one, create an app for the chain you trade on, and copy the https URL.

One setting matters before you paste it anywhere: lock the key to your own domain or IP in the provider dashboard if you will use it from a browser. A key in front-end code is readable by anyone who opens the developer tools — that is true of ours too, and it is why ours are origin-locked. A key with no restriction is a key someone else can spend.

## The HTTP API

Append rpc= with your endpoint, URL-encoded. Your node is tried first; ours stay behind it as the fallback, so supplying a node can only make the call more reliable, never less. The response tells you which was used: meta.rpc reads "byo" when yours answered and "shared" when it did not.

If the parameter is malformed or points somewhere we refuse (see below), it is ignored silently and the request falls back to the normal free path. A typo in an optional parameter should never cost you a quote.

```
Quote through your own node:
  curl 'https://blazephoenix.xyz/api/quote?chain=base&in=WETH&out=USDC\
&amountIn=1000000000000000000&rpc=https%3A%2F%2Fyour-node.example.com%2Fv2%2FKEY'

Scan a token through your own node:
  curl 'https://blazephoenix.xyz/api/xray?chain=base&token=0x…\
&rpc=https%3A%2F%2Fyour-node.example.com%2Fv2%2FKEY'

Check which node answered:
  … | jq .meta.rpc      # "byo" or "shared"
```

## The SDK

The SDK has accepted your endpoint since before this change: give it one and it reads the chain directly, skipping our API altogether. That is the strongest form of this — you are not routing through us at all, you are talking to the contracts with our routing logic in your own process.

Give it nothing and it uses the public API exactly as before. Both paths return the same numbers, because both end at the same Quoter contract.

```
import { quote } from '@blazephoenix/sdk';

// Through your own node — nothing of yours touches our pool:
const q = await quote({
  chain: 'base', in: 'WETH', out: 'USDC', amountIn: 10n ** 18n,
  rpcUrl: process.env.MY_RPC,     // read straight from the chain
});

// Or through the free public API (no key, no setup):
const q2 = await quote({ chain: 'base', in: 'WETH', out: 'USDC', amountIn: 10n ** 18n });
```

## MCP (for AI agents)

Both MCP tools — get_quote and xray_scan — now take an optional rpc argument with the same meaning. An agent that runs continuously should be configured with one, so its background polling does not consume the pool that one-off human questions depend on.

The tool descriptions say this in the schema itself, so an agent reading the tool list learns the convention without a human explaining it.

```
MCP endpoint:
  https://blazephoenix.xyz/mcp

Tool call with your own node:
  {
    "name": "get_quote",
    "arguments": {
      "chain": "base", "in": "WETH", "out": "USDC",
      "amountIn": "1000000000000000000",
      "rpc": "https://your-node.example.com/v2/KEY"
    }
  }
```

## What we refuse, and why you should want us to

Accepting a URL from a stranger and fetching it server-side is the textbook shape of a server-side request forgery hole — the mechanism by which a public endpoint gets turned into a proxy for reaching things it should not reach. So the parameter passes a strict filter before we will send a single byte to it.

Refused: anything that is not https; any URL carrying credentials (user:pass@), because we will not forward secrets; any non-default port, since a node does not live on 22 or 6379; and any loopback, private, link-local or cloud-metadata address — 169.254.169.254 in particular, the classic target. Hostnames must look public; .local and .internal are refused by name.

We also do not send our own origin headers to your node. Ours exist only to satisfy the origin-lock on our keyed endpoints; a third-party host has no lock of ours to satisfy and gets no announcement from us.

## What does not change

The free tier: still free, still keyless, still open CORS, still no rate limit for human-scale use. The numbers: identical, because every path ends at the same on-chain call — you can verify that by running the same quote both ways and diffing the output.

And the fallback: if your node is slow or down, ours answer. Bringing your own endpoint is a contribution, not a dependency you have to babysit.

**Verify it yourself:** Run the same quote twice — once with rpc= pointing at your own node and once without — and diff the amountOut. They match, because both end at the same Quoter contract; only meta.rpc differs

Related: https://blazephoenix.xyz/learn/api-sdk-mcp · https://blazephoenix.xyz/learn/on-chain-quoting · https://blazephoenix.xyz/learn/integrated-dexes · https://blazephoenix.xyz/learn/phantom-liquidity
