Stock & Options Data for AI Agents
Use your AI agent to explore our datasets and work with your downloaded CSVs. MCP (Model Context Protocol) connects your agent to tools for checking coverage, reading data and calculating summaries. Every dataset schema links to independent source reconciliation: sample values checked against Cboe official index closes and public quote records, and a fixed panel checked against Cboe Global Markets quotes after every US trading session.
Two ways to use MCP
Explore our datasets
Connect to our public MCP server. No purchase or API key is needed.
- Check stock symbols and the latest options session.
- Read CSV field definitions and inspect real sample rows.
- Compare products, prices and license options.
Analyze files on your computer
Use mcp.py with downloaded data or our free samples. The same tool works with stocks and options.
- Find files and select the rows and columns you need.
- Filter by date, symbol, contract fields or session.
- Calculate summaries with a record of the source file.
Connect your AI agent
In an AI client that supports remote MCP, add this server URL and select Streamable HTTP:
https://historicaldata.net/mcp
Your agent discovers the available tools automatically. It can query up to 10 symbols at once, read the stock or options schema and preview a few fixed rows from the public samples. Options coverage queries check the latest published session; they do not establish full historical coverage. Use the local tool below to read your own downloaded files.
Tool reference and connection details
The server supports protocol 2025-06-18 with structured results and retains 2025-03-26 for older clients. It is stateless and returns JSON to POST requests, with no Mcp-Session-Id. GET returns 405 because no SSE stream is offered. Send the negotiated MCP-Protocol-Version header on subsequent requests; requests without it use the older version. The newer version does not accept JSON-RPC batches; use search_symbols for several symbols.
| Tool | Purpose and input |
|---|---|
search_symbol | Required symbol string; optional product is all, stocks or options. Returns the REST symbol-response structure. |
get_status | Arguments {}. Returns the REST status structure, including product availability and separate source dates. |
get_catalog | Arguments {}. Returns the REST catalog structure, including public offers, samples and status. |
get_pricing | Arguments {}. Returns the catalog's offers structure directly, including products, prices, licenses, archiveDownloadDays, archiveRefundRequestDays and refund terms. No offers wrapper. |
get_free_sample | Arguments {}. Returns the catalog's samples structure directly: ZIP URLs, July–December 2022 scope, symbols and field counts. The tool returns links without downloading files. |
search_symbols | Required symbols: 1–10 distinct strings; optional product. Each entry in results has its query, data and error status. Symbol queries count individually toward the request limit. |
get_dataset_schema | Required dataset: stocks-daily, stocks-minute or options-eod. Optional layout: symbol or date; options support date only. Returns ordered fields, types, units in descriptions, missing-value rules and limitations. |
preview_sample | Required dataset; optional columns and limit (1–10). Returns 3 daily stock rows, 3 minute stock rows or 4 options rows, with exact CSV strings and source hashes. These fixed examples are not a historical query or a complete event window. |
Initialize, then discover tools
MCP clients normally handle initialization automatically. For a manual connection, POST an initialize request first. Continue only if the client supports the returned result.protocolVersion.
curl 'https://historicaldata.net/mcp' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{
"protocolVersion":"2025-06-18","capabilities":{},
"clientInfo":{"name":"coverage-client","version":"1.0"}}}'
After initialization, POST {"jsonrpc":"2.0","method":"notifications/initialized"} to the same URL with the same content headers. The notification has no ID and returns HTTP 202 with an empty body. Then POST {"jsonrpc":"2.0","id":2,"method":"tools/list"} to discover the current tool descriptions and input schemas.
Call a tool and read its result
curl 'https://historicaldata.net/mcp' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-06-18' \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{
"name":"search_symbol","arguments":{"symbol":"SPXW","product":"options"}}}'
First check for a top-level JSON-RPC error, then result.isError. With protocol 2025-06-18, each tool declares an outputSchema and returns result.structuredContent. The same object is serialized in result.content[0].text for text-based clients. Older clients receive the text form. Check product availability inside the data before interpreting a result.
A tool can return isError: true with usable metadata for one product and an unavailable flag for the other. Keep the healthy product's result separate from the failed check. A completed no-match result is not itself a tool error.
Explore before buying
Once connected, ask your agent a question in plain language:
- Check coverage
- “Check stock coverage for TSLA, KO and SPY. Show each matching file and its dates, and keep any unavailable results separate.”
- Understand the format
- “Explain the options CSV fields, the units of theta and vega, and how to interpret empty IV values.”
- Try real rows
- “Show the stock minute sample with timestamp, close, adj_close and split. Keep empty values empty and identify the source files.”
The previews are small, verified selections from the public samples. For broader analysis, download the full free sample and use the local tool below.
Work with your downloaded data
mcp.py gives your agent tools to work with stock daily bars, stock 1-minute bars and options end-of-day CSVs. It reads files in the folder you choose and runs calculations locally. Python 3.10 or later is required; no additional packages are needed.
What can your agent do?
- Find your files
list_files - List CSV filenames and sizes in your data folder. Original case and separate listing filenames are preserved.
- Select the data you need
read_csv - Read one file at a time. Choose columns, an inclusive date range and exact text filters, such as an options underlying, expiration or call/put type. Read up to 100 matching rows per page.
- Calculate summaries
summarize_csv - Calculate counts, missing values, minimums, maximums, sums and arithmetic means for numeric columns. Group by a text field, observation day or month. Empty numeric cells are excluded rather than filled with zero.
- Keep the result traceable
- Each data analysis returns the source filename, SHA256, filters and row counts. The agent can cite the exact file it used; later pages must match the same file hash.
Examples to ask your agent
- Stock daily data
- “In this TSLA daily file, show the raw close, adjusted close and recorded split for 24–26 August 2022. Include the file hash and keep missing values visible.”
- Stock minute data
- “For 25 August 2022 in this TSLA minute file, summarize volume by pre-market, regular and post-market session. Show the number of populated and missing values.”
- Options data
- “In this options CSV, select SPY calls expiring on 16 September 2022. Show contract, strike, bid, ask, IV and IV flag, and report how many rows match.”
Set up the local MCP
- Save
mcp.pyand extract your data into a dedicated folder. - In a client that supports local MCP over stdio, set the command to your Python executable and use the arguments below. Replace both paths with your own.
- Ask your agent to list the files, select a specific security file, then filter rows or calculate a summary.
python /path/to/mcp.py --root /path/to/downloaded-data
Once configured, the AI client starts the MCP process for you. It communicates through standard input and output (stdio), so you do not need to open a network port or keep a separate terminal running. Your client must support local MCP servers.
Example client configuration and analysis limits
Configuration keys vary by client. A common local-server format is:
{
"mcpServers": {
"historicaldata-local": {
"command": "python",
"args": ["C:/tools/mcp.py", "--root", "C:/data/historicaldata"]
}
}
}
Analysis scans one complete CSV file. Defaults are a 512 MiB file limit and a 30-second scan limit; an exceeded limit returns an error without a partial summary. For larger files, explicitly configure --max-file-mb (up to 4096) and --max-seconds (up to 300), subject to your client's timeout. Results allow at most 100 groups and 1 MiB of output. All-empty numeric aggregates return null.
Use python mcp.py --version to check the tool version. The tool reads your files without modifying them. Cross-file joins, charts and large-scale analysis require additional tools or a separate workflow; this MCP does not perform them automatically.
Calculations run on your computer. Requested rows and results return to your AI client and may be sent to its model provider; use an environment permitted by your license and data policies.
Start with files you have already downloaded through your purchase or from the free samples. The local tool does not sign into your account or provide remote access to paid data. Keep different securities and listing lifecycles separate; a matching file hash does not establish that its data is complete or that reported defects have been repaired.
Downloads, manifests and verification
HistoricalData.net delivers paid CSV data through the purchased product's download links. After successful payment, the download link is available immediately on the purchase confirmation page and is also sent by email. The supplied README explains the delivery index, manifests and download commands for that product.
Use the included verify.py for its documented checks and update.py for supported download or update workflows. Download access depends on the order and its update entitlement; the public coverage API cannot retrieve private order contents.
Files can be corrected. Follow the current manifest and its checksums rather than assuming files are immutable or that an ETag is always an MD5 digest. Stock manifests list filenames, sizes and SHA-256 values; do not assume they contain per-file row counts or date ranges.
See using the files, validation scope and the data license.
What does the coverage lookup establish?
The homepage lookup, REST symbol endpoint and MCP search_symbol tool check one ticker, options underlying or option root, such as AAPL, LEH or SPXW. MCP search_symbols checks up to 10 distinct symbols in one call. Company-name searches and full option-contract searches are not supported.
- Stock file coverage
- The stock lookup returns matching published daily files, first and last dated rows, available security identity and CSV sizes. A reused ticker can match multiple listing files. File boundaries can include corporate-action rows without trading; they are not necessarily the first and last trading dates.
- Latest options session
- The options lookup counts contract rows for the resolved underlying on one published trading day. The result does not establish historical start/end dates, a root-only count or coverage throughout a requested period. A root mapping applies to the checked session, not automatically to earlier files.
- No match versus failure
- A completed lookup can return
found: false. For stocks, no published daily file matched the symbol; for options, no match was found in the latest published session.unavailable: truemeans the product could not be checked. Neither an options no-match nor a failed query establishes that earlier options history is absent.
Stock file boundaries do not establish complete daily coverage, and the lookup does not report minute-file date ranges. Archive-wide start dates cannot establish a particular security's history. For period-specific research, check the stock coverage notes, options coverage notes and relevant files; contact HistoricalData.net when the public lookup cannot answer the coverage question.
Cite data quality evidence
Read the data quality reports with their machine-readable claims, results and source hashes. Preserve the sample date, field and numerator/denominator when citing a finding. Sample agreement is not archive-wide accuracy; these supplier-authored comparisons are not exchange certification.
- Stock report: comparison with NYSE Daily TAQ — 1 July 2026 daily prices and 19-security minute scope, with quantity differences and a supplementary interval check. Claims JSON · Results JSON · Sources · Markdown.
- Options report: comparison with Cboe — sample-specific contract and field agreement; quote timing is not established. Claims JSON · Results JSON · Sources · Markdown.
How do you query the REST API?
View REST endpoints, examples and response fields
The HistoricalData.net REST API accepts public GET requests and returns JSON with apiVersion: "2" on successful metadata responses. REST supports cross-origin browser requests. The request examples use this site's API origin; the OpenAPI specification lists the same origin under servers.
| GET endpoint | Response and operation ID |
|---|---|
/api/symbol/{symbol} | Coverage for one symbol. OpenAPI operation: lookupSymbol. |
/api/status | Archive statistics, source dates and product availability. OpenAPI operation: getStatus. |
/api/catalog | Dataset definitions, public offers, sample links and status. OpenAPI operation: getCatalog. |
Check a symbol
curl 'https://historicaldata.net/api/symbol/AAPL'
curl 'https://historicaldata.net/api/symbol/SPXW?product=options'
curl 'https://historicaldata.net/api/symbol/LEH?product=stocks'
The symbol endpoint's optional product parameter accepts all, stocks or options; the default is all. Selecting one product omits the other product's block. Stock queries match exact case first, falling back to uppercase only when there is no exact match; options queries normalize to uppercase. Preserve the returned file identities. URL-encode the symbol as one path component, especially when it contains a slash.
| Returned field | How to read it |
|---|---|
symboloptions.underlying | symbol is the normalized query; options.underlying is the resolved CSV underlying when found. Preserve both names when they differ. |
stocks.records[] | One record per matching daily file. Each record contains file, name, type, active, delistDate, dates and sizes. The name, type and delisting date can be null. file identifies the published file; it is not a public download URL. |
stocks.records[].firstDatestocks.records[].lastDate | First and last dated rows in that daily file. Parse these separate fields instead of the display string coverage. delistDate is separate listing metadata and can differ from the last row date. |
stocks.records[].sizeDayBytesstocks.records[].sizeMinuteBytes | Uncompressed CSV bytes. A null minute size means no matching minute file is published; it does not mean zero volume. A minute size does not establish minute-file dates or completeness. |
stocks.lastDate | The stock statistics date for the lookup source. It is distinct from each file's stocks.records[].lastDate. |
options.latestDateoptions.contractsLatestDay | The checked session and contract-row count for options.underlying. latestDate is also returned for a completed no-match result; the underlying and count are absent when not found. |
stocks.source / stocks.scopeoptions.source / options.scope | Stocks use v2-published-stock-files and daily-file-boundaries. Options use v2-published-options-session and latest-published-session. These fields accompany completed checks; an unavailable product instead has unavailable: true. |
Read a dated response
Selected fields from a real SPXW?product=options response for the 2026-09-04 session follow. This is a fixed documentation example, not a live count; the response's explanatory options.note is omitted here.
{
"apiVersion": "2",
"symbol": "SPXW",
"options": {
"found": true,
"latestDate": "2026-09-04",
"underlying": "SPX",
"contractsLatestDay": 28650,
"source": "v2-published-options-session",
"scope": "latest-published-session"
}
}
The example reports 28,650 rows for the resolved SPX underlying on 2026-09-04. It does not report 28,650 SPXW-only contracts or establish SPXW's historical coverage. The omitted stock block reflects product=options, not missing stock coverage.
Read dates and archive statistics
curl 'https://historicaldata.net/api/status'
In /api/status, check stocks.available and options.available before using each product's values. HTTP 200 can contain a failed product. Stock statistics carry stocks.firstDate and stocks.lastDate; the options session has options.latestDate and options.underlyingCount.
Options archive-size statistics are separate under options.statistics. Their asOf date can precede options.latestDate, and the entire statistics block can be null even when the latest-session check is available. Null means unavailable statistics, not a zero-size archive. The session's underlying count is not the number of underlyings across all history.
Read product offers and sample links
curl 'https://historicaldata.net/api/catalog'
The catalog's datasets[] contains product definitions and documentation links; offers.products[] contains numeric amount values in USD for a single user, billing periods and includedUpdateMonths. License multipliers are in offers.licenses[]. Historical archives use one-time billing; update subscriptions use monthly billing.
The catalog's offers.archiveDownloadDays and offers.archiveRefundRequestDays are both 21, counted from purchase. These periods apply to historical archives; included updates and monthly subscriptions have separate access periods. offers.refunds summarizes the rules, and offers.refundPolicyUrl links to the complete terms. Replacing or extending an archive download link does not restart or extend the refund application period.
The catalog's samples object returns downloadable ZIP URLs and sample scope. status contains the same availability and source-date structure as /api/status. Reading the catalog does not download a file, create an order or subscribe to updates. Use the returned product links to inspect the data and license before purchase.
How should AI clients discover tools and cite results?
Import https://historicaldata.net/openapi.json into a tool that supports OpenAPI 3.1. It defines operation IDs, parameter validation, response schemas, nullable fields and error responses for the REST endpoints. Use its servers URL so the client calls the same API described by the specification.
The machine-readable site guide links products, documentation and coverage tools. OpenAPI describes REST operations; MCP clients discover tools through tools/list. A homepage example is a dated observation, so a question about another symbol requires a new lookup.
A standalone coverage answer should name HistoricalData.net, the queried symbol, the resolved security or underlying, the relevant data date and the scope of the check. Stock answers should retain each matching file's date boundaries and identity. Options answers should retain options.latestDate and identify the count as one session's rows for options.underlying.
- Example: resolved root
- HistoricalData.net's SPXW query resolved to SPX for the 2026-09-04 session and returned 28,650 contract rows for SPX. The result does not establish SPXW-only or historical coverage.
- Example: no current match
- HistoricalData.net's options lookup found no TWTR match in the 2026-09-04 session. The result does not rule out TWTR options data on earlier dates.
These are fixed examples from checked responses. For a fresh answer, use the returned dates and values and link to the queried endpoint. If a requested historical period cannot be established by the lookup, state that limitation and use the product documentation or request a period-specific check from HistoricalData.net.
How should clients handle caching and errors?
HistoricalData.net's metadata responses use Cache-Control: no-store. A coverage observation saved in a research log must retain its source date and scope; it is not a fresh check. Avoid repeated requests for the same question. Use the MCP batch tool for up to 10 symbols, not unbounded enumeration.
- 200 with no match
- For
/api/symbolresponses, inspect each returned product'sunavailableflag before interpretingfound. For/api/status, inspectstocks.availableandoptions.available; in/api/catalog, inspect those flags understatus. - 400 / 404 / 405
- Correct invalid input, an unknown endpoint or the HTTP method before retrying. The REST symbol route requires one symbol and a supported product value. MCP uses POST; GET on
/mcpnormally returns 405. - MCP 403 / 413 / 415
- MCP rejects an unapproved supplied
Originheader (403), a body larger than 64 KiB (413), or an unsupported content type (415). REST's cross-origin support does not mean every browser origin is accepted by MCP. UseContent-Type: application/jsonand the supported client connection. - 429
- Reduce the request rate and honor the
Retry-Afterheader. Clients should not depend on a fixed global quota. - 503 or unavailable
- A combined symbol query can return HTTP 200 with one product unavailable. If both products fail, or the requested single product fails, the symbol endpoint returns 503. Retry the failed check later; a service failure is not evidence of missing coverage.
- MCP errors
- Check both JSON-RPC errors and
isErrorinside tool results. A successful HTTP status alone does not establish a successful lookup.
If a result conflicts with a page or a file, compare the source dates and scope before choosing one as authoritative. Send the symbol, requested period and endpoint to info@historicaldata.net for a coverage check.