Historical database MCP
The historical database MCP, Data MCP for short, opens our historical database to your AI agent: every trade on pump.fun, PumpSwap, Bonk and StonkFun (Raydium LaunchLab), Meteora DBC and the pools their coins move to, with pump.fun's bonding curve back to March 2025, and the live trades up to the last few seconds. Ask in plain words and the agent answers from the data:
- Which wallets made the most on this coin, and are they still holding?
- What did this wallet make this month, per coin?
- Show me this coin's 5-minute candles since launch and who bought in the first minute.
- Find the most traded coins called "pepe".
It is the quickest way to pump.fun historical data: nothing to download and no database to run. It is a Model Context Protocol server, the standard way AI apps plug into tools and data. Claude, Cursor, VS Code and any other MCP client connect to it with one URL and your API key. It is the same data that powers shrine.trade. Comes with the Developer plan.
https://mcp.shrine.trade/mcp
Try it first on the API page: 3 free questions a day, no key needed.
Connect
You need your Developer key from the dashboard. Send it as Authorization: Bearer sk_…. A client that cannot set headers can put it on the URL instead: https://mcp.shrine.trade/mcp?key=sk_….
- Claude Code
- Claude app
- Cursor
- VS Code
- Codex
- Any client
claude mcp add --transport http shrine-data https://mcp.shrine.trade/mcp \
--header "Authorization: Bearer sk_…"
In Settings → Connectors → Add custom connector, name it shrine-data and paste the URL with your key:
https://mcp.shrine.trade/mcp?key=sk_…
~/.cursor/mcp.json:
{
"mcpServers": {
"shrine-data": {
"url": "https://mcp.shrine.trade/mcp",
"headers": { "Authorization": "Bearer sk_…" }
}
}
}
.vscode/mcp.json:
{
"servers": {
"shrine-data": {
"type": "http",
"url": "https://mcp.shrine.trade/mcp",
"headers": { "Authorization": "Bearer sk_…" }
}
}
}
~/.codex/config.toml, with your key in an environment variable:
[mcp_servers.shrine-data]
url = "https://mcp.shrine.trade/mcp"
bearer_token_env_var = "SHRINE_API_KEY"
export SHRINE_API_KEY=sk_…
Any MCP client that speaks Streamable HTTP:
- URL:
https://mcp.shrine.trade/mcp - Header:
Authorization: Bearer sk_…(orx-api-key: sk_…, or?key=sk_…on the URL)
Then ask. The agent sees the tools below, picks the right one, and reads the answer.
What you can ask
This is the same database that powers shrine.trade: the charts, wallet pages, PnL and holder views traders use there every day. It holds every trade with its wallet, side, amounts, price and front-end; flags for dev buys, bundles, snipers and first buys; the realized profit of every sell; every wallet's positions and daily PnL; who funded each wallet and when it was made; launches by creator; candles; and live balances and holders. So a question can be as specific as you like.
Coins
- Who created this coin, what else have they launched, and how did those do?
- How much of the first minute's buying came from bundles and snipers?
- Which front-ends traded this coin most: Axiom, GMGN, Photon?
- How concentrated are the holders now, and how many of the top 20 bought in the first minute?
- How long did it take to migrate, and what did the price do in the hour after?
Wallets
- What is this wallet's win rate and average hold time over the last 30 days?
- Which coins does it still hold, at what cost, and what are they worth now?
- Who funded this wallet, how old is it, and which other wallets got their first SOL from the same funder?
- Is this wallet a sniper? How often does it buy in a coin's first seconds?
- Which front-end does it trade from, and how big are its usual buys?
Finding traders
- Which wallets bought early into three or more of this week's 20 most traded coins?
- List wallets with over 100 SOL realized this month and a win rate above 60%.
- Who are the most profitable wallets on coins less than 10 minutes old?
- Which wallets made the most on this coin, and are they still holding?
The market
- How many coins launched each day this month, and what share migrated?
- What share of volume did each front-end have this week?
- Which coins had the most volume yesterday, and who were their top traders?
- Did coins whose dev bought more than 5 SOL do better than the rest?
Your own trading
- Go through my wallet's trades last week and show where I sold too early.
- Compare my PnL per coin with the 10 best traders on the same coins.
The agent picks a tool, or writes SQL for the questions no tool answers on its own, and can chain several calls: find the coins, then their traders, then those traders' other wallets.
Tools
| Tool | What it answers |
|---|---|
token_overview | A coin at a glance: name, symbol, creator, when it launched and migrated, where it trades, market cap, volume, holders, its last 24 hours |
token_trades | A coin's trades, newest first, by time range, side or wallet |
token_candles | Candles at 1m, 5m, 15m, 30m, 1h, 4h or 1d |
top_traders | A coin's best traders by realized profit or volume: SOL in and out, tokens still held, first and last trade |
top_holders | A coin's largest holders now |
wallet_trades | A wallet's trades, newest first, with each coin's symbol |
wallet_pnl | A wallet's realized profit and loss over the last N days: per day, per coin and in total |
wallet_positions | What a wallet holds now (tokens, cost, realized so far), or every position it opened |
search_tokens | Coins by part of their name or symbol, most traded first |
data_coverage | Which days the history covers, and any known gaps |
list_tables, describe_table | The tables behind the tools, their columns, units and example queries |
query | Read-only SQL for anything the tools do not cover |
Times take 1h, 24h, 7d, a date (2026-10-31) or an ISO time. Amounts come back in SOL and whole tokens, addresses in base58.
SQL for everything else
When no tool fits, the agent writes SQL. It finds the tables with list_tables, reads their columns, units and example queries with describe_table, and runs one read-only statement with query. Addresses are written b58('<address>') and come back as base58:
SELECT wallet, min(ts) AS first_buy, sum(sol) / 1e9 AS sol_in
FROM trades
WHERE mint = b58('Gc6r…pump') AND buy = 1
GROUP BY wallet ORDER BY first_buy LIMIT 20
A wallet's win rate over its positions closed in the last 30 days:
SELECT countIf(realized > 0) / count() AS win_rate, count() AS positions, sum(realized) AS realized_sol
FROM (
SELECT mint, start, argMax(realized, ver) AS realized, argMax(open, ver) AS open, argMax(last, ver) AS last
FROM wallet_coins WHERE wallet = b58('5Ln2…Qe7d') GROUP BY mint, start
)
WHERE open = 0 AND last >= now() - INTERVAL 30 DAY
Each front-end's share of the last 7 days:
SELECT platform, count() AS trades, sum(sol) / 1e9 AS volume_sol
FROM trades WHERE ts >= now() - INTERVAL 7 DAY
GROUP BY platform ORDER BY volume_sol DESC
A creator's launches, newest first:
SELECT mint, created FROM token_launches
WHERE creator = b58('…') ORDER BY created DESC LIMIT 50
The tables cover trades by coin and by wallet, candles, coins and their names, launches, every wallet's positions and daily figures, funding and transfers, and live balances and holders. describe_table shows each one's columns, units and more examples.
Stream the history
Besides questions, the same history streams back in time order: every trade of some coins, some wallets or the whole market, from any moment since March 2025 (the oldest stretch is pump.fun's bonding curve only), as fast as you read or at a multiple of real time. It is the way to replay a day, a week or a coin's whole life through your bot or backtest. Same key, same plan.
wss://mcp.shrine.trade/stream?from=… WebSocket
https://mcp.shrine.trade/stream?from=… JSON lines over HTTP
| Parameter | |
|---|---|
from | Required. 7d, 24h, a date (2026-10-01), an ISO time or unix seconds/ms |
to | Until when, exclusive. Default: now |
mint | Up to 50 coins, comma-separated |
wallet | Up to 50 wallets, comma-separated |
side | buy or sell only |
speed | 0: as fast as you read (default for coins and wallets). N: N times real time, so 1 replays at the pace it happened |
Without mint or wallet you get the whole market. That stream runs at up to 60 times real time (a day in 24 minutes), one at a time across all users, so it can be busy; name coins or wallets and it runs as fast as you read.
- curl
- JavaScript
- Python
curl -N "https://mcp.shrine.trade/stream?from=2026-10-01&to=2026-10-02&mint=Gc6r…pump" \
-H "Authorization: Bearer sk_…" > day.jsonl
const url = "wss://mcp.shrine.trade/stream?key=sk_…&from=7d&wallet=5Ln2…Qe7d&speed=0";
const ws = new WebSocket(url);
ws.onmessage = (m) => {
const e = JSON.parse(m.data);
if (e.type === "trade") onTrade(e); // your strategy, in time order
if (e.type === "end") console.log(e.trades, "trades replayed");
if (e.type === "error") console.error(e.message);
};
import json, requests
url = "https://mcp.shrine.trade/stream"
params = {"from": "2026-10-01", "to": "2026-10-08", "mint": "Gc6r…pump"}
with requests.get(url, params=params, headers={"Authorization": "Bearer sk_…"}, stream=True) as r:
for line in r.iter_lines():
e = json.loads(line)
if e["type"] == "trade":
on_trade(e)
One JSON object per line or message:
{"type":"trade","t":1793448946787,"slot":463685046,"signature":"3iLB…AGu","wallet":"Dnho…xd5v","mint":"27tv…pump","side":"buy","sol":0.00501,"tokens":176596.387645,"price":2.796e-8,"quote":"SOL","platform":"none","tags":["dev","first"],"realized":null,"fee":0.00001,"tip":0}
{"type":"progress","t":1793449389695}
{"type":"end","trades":24227,"to":1793730514778}
| Field | |
|---|---|
t | When it traded, unix ms |
slot, signature | Where to find it on chain (signature is null on the oldest pump.fun trades) |
wallet, mint, side | Who, which coin, buy or sell. On the oldest pump.fun trades most wallets show as unknown: and an id |
sol | SOL in or out, fees included |
tokens | Whole tokens |
price | Per whole token, in quote (SOL, USD or token) |
platform | The front-end it came from (Axiom, GMGN, Photon, …), none when unknown |
tags | dev, bundle, sniper, first (the wallet's first buy of the coin) |
realized | On a sell, its realized profit in SOL (average cost); null on buys |
fee, tip | Network fee and tip, SOL |
progress comes while a paced stream waits for its next trade, with the replay's clock; end closes a finished stream with the number of trades sent; error has error and message. One stream at a time per key: close it, or let it end, before opening the next.
What it can and cannot do
- It only reads. Every tool and every SQL statement is read-only. There is nothing to trade, sign, send or change, and no wallet, private key or account of yours is anywhere near it.
- Your key opens it, and nothing else does. Each request is checked against your plan; a key from a lapsed plan or a replaced key is refused. The key is only used to let you in and count your use. Keep it secret: anyone with it uses your plan. Prefer the header over
?key=, since a URL can end up in a client's logs. - It sees only the public history. The tables are trades, coins, candles, wallets' positions and balances on chain. Nothing about other API users, their keys, wallets or requests is in them.
- Fenced by your plan. Every query runs with a time limit, a cap on what it reads and a row limit, and your key has a number of queries a minute and at once. A query past a limit stops and the agent is told how to narrow it.
Limits
| Developer | |
|---|---|
| Queries | 60 a minute, 2 at once |
| Streams | 1 at a time; the whole market up to 60 times real time |
| Time per query | 30 s |
| Rows per answer | 2,000 |
A query that runs out of time or reads too much gets an answer the agent can act on, such as "filter on the coin and a time range". Narrow tools (one coin, one wallet, a time range) answer in a fraction of a second; a scan over months takes longer.
Without an AI client
It is plain JSON-RPC over HTTP, so a script can call a tool directly:
curl -s https://mcp.shrine.trade/mcp \
-H "Authorization: Bearer sk_…" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"top_traders","arguments":{"mint":"Gc6r…pump","limit":5}}}'
The answer's text is JSON: columns, rows, row_count, and what the query read.
Errors
| Status | error | Why |
|---|---|---|
| 401 | api_key_required | No key sent |
| 401 | unknown_key / key_disabled | Not a key of ours, or a newer key replaced it |
| 403 | plan_required | The key's plan does not include the Data MCP; upgrade links to the plans |
Inside a tool call, a refused or failed query comes back as a tool error with a plain message (too many queries this minute, a time limit, a table that does not exist), so the agent can retry or change course.
The history starts on 14 March 2025 and grows with every trade. Its oldest stretch holds pump.fun's bonding curve only, decoded from the Solana ledger: no PumpSwap or other pool trades, no signatures, times to the block's second, and most wallets known by an id only (unknown:1975d9be85242671: the same id is the same wallet, and it works as a wallet filter). After it comes every launchpad trade, curve and pool, with candles and wallet PnL. Ask data_coverage which days it holds and what each stretch covers. Front-ends (Axiom, GMGN, Photon and the rest) are tagged on trades from July 2026 on.
LimitsDeveloper 60 a minuteSee plans →