The same free EOD stock data API — 15 years of daily OHLCV bars across U.S.-listed tickers — exposed as a Model Context Protocol (MCP) server, so Claude, OpenAI, ChatGPT, or any other MCP-capable agent can pull it directly.
* No credit card, ever — the free key is throttled under a fair-use policy of 300 requests/hour, 800/day, and 4,000/week, shared with the REST endpoint.
Sign up, then go to Profile → Developer API and click "Get free key". It works for both the REST endpoint and the MCP server below — same key, same rate-limit bucket.
The endpoint speaks Streamable HTTP (stateless, JSON responses, no SSE). Pick whichever client you use below — same key, same rate-limit bucket, in every case.
Both accept a url plus custom headers in their MCP server config — Claude Code's .mcp.json, Claude Desktop's remote-server settings:
{
"mcpServers": {
"stashgamma": {
"url": "https://www.stashgamma.com/api/dataapi/mcp",
"headers": {
"X-Api-Key": "YOUR_API_KEY"
}
}
}
}Ready-to-drop files: claude_code_mcp.json, claude_desktop_config.json. Restart the client after saving, then ask it about a symbol.
The Responses API supports remote MCP servers as a built-in tool type — pass the same URL and header, no separate integration to write:
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-4.1",
tools=[{
"type": "mcp",
"server_label": "stashgamma",
"server_url": "https://www.stashgamma.com/api/dataapi/mcp",
"headers": {"X-Api-Key": "YOUR_API_KEY"},
"require_approval": "never",
}],
input="Get QQQ's daily EOD bars for the last month.",
)Full runnable script: responses_mcp_example.py.
Many hosted AI assistants have an "add connector" or "add MCP server" form with a single URL field and no place for a header. Put your key in the URL and, if the form asks, choose "no authentication":
https://www.stashgamma.com/api/dataapi/mcp/YOUR_API_KEY
Click-by-click steps for the Claude and ChatGPT apps, with your own key filled in: Claude & ChatGPT setup guide.
?key=YOUR_API_KEY on the plain endpoint works the same way. Treat the full URL as a secret — if it leaks, rotate the key from Profile → Developer API and the old URL stops working.
A Custom GPT calls tools via an OpenAPI schema instead of MCP (a REST call, not the MCP endpoint above). Paste this schema into GPT Builder → Configure → Actions:
X-Api-Key, value = your key.Three read-only tools are exposed. Ask your agent about a symbol in plain language and it calls one of these underneath:
| Tool | Arguments | Returns |
|---|---|---|
| get_eod_data | symbol (required), from/to (optional, YYYY-MM-DD) | Same OHLCV bar shape as the REST API |
| get_latest_quote | symbol (required) | Most recent daily bar plus change vs the previous close |
| get_api_usage | none | Plan and remaining requests per hour/day/week — free, doesn't count against your quota |
Rate-limit and auth errors come back as a tool result with isError: true (e.g. "retry in Ns") instead of an opaque protocol error, so the agent can see and react to the reason directly.
No chat client involved — use an MCP SDK directly from a script or your own agent framework. Same endpoint, same tool, same key.
Python (official mcp SDK)
# pip install mcp
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def get_eod_data(symbol, api_key):
async with streamablehttp_client(
"https://www.stashgamma.com/api/dataapi/mcp",
headers={"X-Api-Key": api_key},
) as (read, write, _get_session_id):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool("get_eod_data", {"symbol": symbol})
if result.isError:
raise RuntimeError(result.content[0].text)
return result.content[0].text # JSON string, same shape as the REST responseNode.js (@modelcontextprotocol/sdk)
// npm install @modelcontextprotocol/sdk
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const transport = new StreamableHTTPClientTransport(
new URL("https://www.stashgamma.com/api/dataapi/mcp"),
{ requestInit: { headers: { "X-Api-Key": apiKey } } }
);
const client = new Client({ name: "my-agent", version: "1.0.0" });
await client.connect(transport);
const result = await client.callTool({
name: "get_eod_data",
arguments: { symbol: "QQQ" },
});Full runnable versions of both (plus ready-to-drop claude_desktop_config.json / .mcp.json snippets) — python_client.py, node_client.mjs.
The agent discovers and calls the tool directly — no hand-written fetch/parse wrapper to write or maintain.
It's the identical dataset and rate limit as the REST endpoint — switch between them, or use both, without a second key.
Full protocol-level reference (headers, error shapes, transport details) is in the API documentation's MCP section.
Free forever, no credit card — get a key and connect Claude or your own MCP client.
Get Started FreeFree Stock Data API
Start here — the free tier, no card required, 300 requests/hour.
EOD Data API Quickstart Guide
Get a key and pull your first end-of-day bars in under 5 minutes.
Historical Stock Data API
15 years of daily OHLCV across U.S.-listed tickers, for backtesting & research.
Free Stock Market APIs Compared
How the free tier stacks up against Alpha Vantage, IEX, and others.
OHLCV Data API
What OHLCV data is and exactly how the response is shaped.
Claude & ChatGPT Setup Guide
Click-by-click connector setup for Claude and ChatGPT, with your own key filled in.
Full API Documentation
Auth, endpoint reference, rate-limit headers, and error codes.
Ready to try it? Get your free API key — no card required.