mcp server
tiingo-mcp
Tiingo MCP server in Rust with 38 tools for stock market data, forex, crypto, financial news, fundamentals, and corporate actions.
Set up
Runs on your computer. Pick your agent and operating system.
This project does not publish an install method we can turn into a config. Follow the README instead.
README
synced Oct 17, 2026Tiingo MCP server for stock market data
tiingo-mcp is a Rust Model Context Protocol (MCP) server for stock market data from Tiingo. Use it with Claude Code, Claude Desktop, or another MCP client to request stock prices, forex rates, crypto prices, fund data, financial news, and company fundamentals.
The server exposes 38 tools, and it also provides three fixed resources, one resource template, and five prompts. The tools cover these areas:
- End of day (EOD) stock prices, intraday IEX prices, and consolidated and overnight (BOATS) equity prices
- Forex, crypto, Crypto Yield, and mutual fund and ETF fees
- Search, news, fundamentals, and corporate actions such as dividends and splits
- Short, bounded subscriptions to Tiingo's live market data feeds
Prebuilt binaries are available for macOS, Linux, and Windows, so you can install the server without Rust. You need a Tiingo API key, and access to each dataset depends on the features enabled for your key.
Install Tiingo MCP
The release installers, MCPB bundles, and the crates.io package all install the same server with the 38 tools documented below. Choose one installation method, then configure your MCP client. The desktop bundle includes the client configuration.
| System or use | Installation method |
|---|---|
| macOS | Homebrew, or the install script |
| Linux | Install script |
| Windows | Windows installer, or the PowerShell script |
| Claude Desktop | Desktop bundle |
| Rust developers | Cargo |
| Custom installation | Download and install a binary |
Homebrew on macOS
Install with:
brew tap major7apps/tiingo-mcp https://github.com/major7apps/tiingo-mcp
brew install major7apps/tiingo-mcp/tiingo-mcp
tiingo-mcp --version
The first command adds this repository to Homebrew. You only need to run it once. Homebrew downloads the binary for your Mac.
To update, run brew update followed by brew upgrade major7apps/tiingo-mcp/tiingo-mcp. To remove the server, run brew uninstall major7apps/tiingo-mcp/tiingo-mcp.
The formula is maintained in this repository. It is not yet available from Homebrew's central homebrew/core repository. The source formula and submission guide describe the path to an official formula.
Windows installer
Download tiingo-mcp-x86_64-pc-windows-msvc.msi from the latest GitHub release. Open the installer and follow the installation steps. The installer adds the binary directory to PATH by default.
Open a new terminal after installation and run:
tiingo-mcp --version
Install a newer MSI to update the server. You can remove it through Windows Settings under Installed apps.
Install script
The install script detects your platform and downloads the matching prebuilt binary from the latest GitHub release. It installs into Cargo's binary directory, which is ~/.cargo/bin unless you set CARGO_HOME. You don't need Rust installed to use it.
On macOS or Linux, run:
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/major7apps/tiingo-mcp/releases/latest/download/tiingo-mcp-installer.sh | sh
On Windows, run this in PowerShell:
powershell -ExecutionPolicy ByPass -c "irm https://github.com/major7apps/tiingo-mcp/releases/latest/download/tiingo-mcp-installer.ps1 | iex"
Follow the installer's instructions to update your PATH, or open a new terminal. Run tiingo-mcp --version to check the installation, then configure your MCP client. To update a script installation, run the same install command again.
Prebuilt binary
You can download a prebuilt binary yourself if you'd rather not pipe a script into your shell. Each GitHub release has one archive per platform, and each archive holds the tiingo-mcp binary with the README, changelog, and license.
| Platform | Archive |
|---|---|
| macOS on Apple silicon | tiingo-mcp-aarch64-apple-darwin.tar.xz |
| macOS on Intel | tiingo-mcp-x86_64-apple-darwin.tar.xz |
| Linux on x86_64 | tiingo-mcp-x86_64-unknown-linux-musl.tar.xz |
| Linux on ARM64 | tiingo-mcp-aarch64-unknown-linux-musl.tar.xz |
| Windows on x86_64 | tiingo-mcp-x86_64-pc-windows-msvc.zip |
The Linux binaries use static linking with musl.
On macOS or Linux, set TARGET to the name from the table and run these commands. They download the archive and its checksum, check the archive against the checksum, and copy the binary to ~/.local/bin.
TARGET=aarch64-apple-darwin
BASE=https://github.com/major7apps/tiingo-mcp/releases/latest/download
curl -LO "$BASE/tiingo-mcp-$TARGET.tar.xz"
curl -LO "$BASE/tiingo-mcp-$TARGET.tar.xz.sha256"
shasum -a 256 -c "tiingo-mcp-$TARGET.tar.xz.sha256"
tar -xJf "tiingo-mcp-$TARGET.tar.xz"
mkdir -p ~/.local/bin
install -m 755 "tiingo-mcp-$TARGET/tiingo-mcp" ~/.local/bin/
~/.local/bin/tiingo-mcp --version
You can use sha256sum -c in place of shasum -a 256 -c on Linux. If ~/.local/bin isn't on your PATH, add it, or copy the binary to another directory that is. If you download the archive with a web browser on macOS, macOS may block the binary the first time it runs. You can clear the block with xattr -d com.apple.quarantine ~/.local/bin/tiingo-mcp.
On Windows, download tiingo-mcp-x86_64-pc-windows-msvc.zip and extract tiingo-mcp.exe to a folder such as %LOCALAPPDATA%\Programs\tiingo-mcp. Then add that folder to your user PATH, or put the full path to tiingo-mcp.exe in your MCP client's configuration. To check the download, compare the output of Get-FileHash tiingo-mcp-x86_64-pc-windows-msvc.zip with the value in the matching .sha256 file.
The release workflow also publishes GitHub build attestations. If you have the GitHub CLI, you can confirm that an archive was built by this repository's release workflow:
gh attestation verify "tiingo-mcp-$TARGET.tar.xz" -R major7apps/tiingo-mcp
Claude Desktop bundle (MCPB)
An MCPB bundle is a single file that a desktop MCP host, such as Claude Desktop, can install as an extension. Each release has one bundle per platform, named tiingo-mcp-<target>.mcpb, where <target> is one of the platform names in the table above. Download the bundle for your system, open it with your host's extension installer, and enter your Tiingo API key when the host asks for it. The bundle includes the binary and its MCP configuration, so you don't need to install the binary or set a path separately.
Install from crates.io with Cargo
If you have Rust 1.88 or newer, you can build and install the latest release from crates.io:
cargo install tiingo-mcp --locked
To install the current development version from a local checkout, run:
cargo install --path . --locked
Configure your MCP client
You need a Tiingo API key, which you can create at api.tiingo.com. The data you can access depends on the features enabled for your key, as described in Access and quota.
Homebrew, MSI, Cargo, and the install scripts install the server executable. You choose which MCP clients can use it and supply the API key in each client's settings. If you installed a desktop bundle, use the host's extension settings instead.
Add the server to your MCP client's configuration:
{
"mcpServers": {
"tiingo": {
"command": "tiingo-mcp",
"args": [],
"env": { "TIINGO_API_KEY": "your-api-key-here" }
}
}
}
If tiingo-mcp isn't on the PATH that your client sees, set command to the full path of the binary.
You can also use a full path to keep separate installations for different clients. The server reads TIINGO_API_KEY and RUST_LOG from the environment supplied by the client.
In Claude Code, you can add the server with one command:
claude mcp add tiingo --env TIINGO_API_KEY=your-api-key-here -- tiingo-mcp
You can also start the server directly to check that it runs:
TIINGO_API_KEY=your-api-key-here tiingo-mcp
The server talks to its MCP client over stdio, which means the client starts it as a child process and exchanges messages through standard input and output. The subscription tools open WebSocket connections to Tiingo, but the server itself does not offer an MCP WebSocket or Streamable HTTP transport.
The server writes only MCP protocol messages to stdout, and it writes diagnostic logs to stderr. It exits when stdin closes. You can control the log level with the RUST_LOG environment variable, e.g., RUST_LOG=debug.
Tools
The server keeps the 17 tools from releases before 2.1.0 compatible. Their names, required inputs, default behavior, and results are unchanged. Optional filters and ordering controls extend those inputs; API_SURFACE.md lists the precise compatibility changes.
Stocks (EOD and security metadata)
| Tool | Description |
|---|---|
get_stock_metadata | Name, exchange, description, and EOD date range for one ticker |
get_stock_prices | Historical raw and adjusted EOD prices and volume, with dividends, splits, optional columns and sorting |
get_bulk_eod_prices | The latest EOD prices for all tickers, with a list of tickers whose history needs a refresh |
get_ticker_metadata | Listing and security details supplied by Tiingo's data vendor |
IEX prices
| Tool | Description |
|---|---|
get_realtime_price | Current IEX top of book price for one ticker, with optional after hours data |
get_intraday_prices | Intraday IEX price history for one ticker, with columns, after hours and gap filling options |
get_iex_market_snapshot | Current IEX snapshot for 1–100 selected tickers, or every ticker when the filter is omitted |
Consolidated equity prices (beta, 4am to 8pm ET)
| Tool | Description |
|---|---|
get_equity_realtime_snapshot | Current consolidated snapshot for one ticker, 1–100 selected tickers, or every ticker |
get_equity_intraday_prices | Consolidated intraday history, with options for interval, after hours data, gap filling, and columns |
Overnight BOATS prices (beta add-on, 8pm to 3:59am ET)
| Tool | Description |
|---|---|
get_boats_snapshot | Current BOATS snapshot for one ticker, 1–100 selected tickers, or every ticker |
get_boats_prices | BOATS overnight history, with interval, gap filling and columns; after hours flag preserves the overnight window |
Mutual fund and ETF data
| Tool | Description |
|---|---|
get_fund_metadata | Fee metadata for a mutual fund or ETF |
get_fund_fee_metrics | Current and historical fee metrics for a mutual fund or ETF |
Search (early beta)
| Tool | Description |
|---|---|
search_tiingo_assets | Search by ticker or name, with exact matches, delisted assets and a result limit of 1–100 |
Crypto Yield
| Tool | Description |
|---|---|
get_crypto_yield_platforms | List of crypto lending platforms, with optional filters |
get_crypto_yield_pools | Metadata for lending pools, filtered by pool or platform |
get_crypto_yield_ticks | Latest metric values for lending pools |
get_crypto_yield_metrics | Historical Crypto Yield rate metrics for one lending pool |
Forex (beta)
| Tool | Description |
|---|---|
get_forex_quote | Current best bid and ask for one currency pair |
get_forex_quotes | Current best bid and ask for 1 to 100 currency pairs |
get_forex_prices | Historical forex prices |
Crypto
| Tool | Description |
|---|---|
get_crypto_quote | Current prices for one or more crypto tickers, with exchange and interval filters |
get_crypto_prices | Historical crypto prices, with exchange and interval filters |
get_crypto_metadata | Ticker metadata and supported exchanges |
Financial news
| Tool | Description |
|---|---|
get_news | Search financial news articles by ticker, tag, source, or date |
Company fundamentals
| Tool | Description |
|---|---|
get_fundamentals_definitions | Definitions of Tiingo's fundamental metrics |
get_financial_statements | Income statements, balance sheets and cash flow statements, with as-reported filings and date sorting |
get_daily_fundamentals | Daily market and valuation metrics, with optional columns and sorting |
get_company_meta | Company sector, industry, and location, with optional columns |
Corporate actions
| Tool | Description |
|---|---|
get_distributions_by_ex_date | Distributions across all tickers, optionally for one ex-date, including announced events |
get_dividends | Dividend and distribution history for one ticker |
get_dividend_yield | Dividend yield history for one ticker |
get_splits | Split history for one ticker |
get_splits_by_ex_date | Splits across all tickers, optionally for one ex-date, including announced and cancelled events |
Live market data subscriptions
The subscription tools let a client read live IEX or consolidated equity data for a limited time. First, the client starts a subscription. Second, it polls for new events, and it can add or remove symbols while the subscription is active. Third, it stops the subscription.
Each subscription keeps every event it receives, and polling doesn't remove events, so one subscription can receive at most 2,048 events or 8 MiB in total. When the next event would pass either limit, the subscription closes with the state data_gap, so the client never loses events without knowing. To keep reading after that, start a new subscription. A subscription also closes after 30 minutes, or after five minutes with no calls from the client. The start result reports the state at publication; check it before proceeding. A successful upstream acknowledgement does not prove that market events were delivered.
| Tool | Description |
|---|---|
start_market_data_subscription | Start one IEX or consolidated equity subscription with a size and time limit |
poll_market_data_subscription | Read new events after a sequence number, with a limit on count and wait time; the result's state shows whether the subscription is still open |
update_market_data_subscription | Add or remove symbols on an active subscription; if part of the update fails, the result lists the symbols that are active in appliedSymbols |
stop_market_data_subscription | Close the subscription and release its resources, and it's safe to call more than once |
REST request options
Optional controls are omitted from the Tiingo request unless you supply them, so existing defaults remain unchanged. Use columns to narrow EOD output and sort to order EOD or daily fundamental rows; prefix a field with - for descending order. Financial statements accept only sort="date" or sort="-date". Set as_reported=true to request filings as released with publication dates; omitted or false requests return the latest revisions with fiscal-period dates.
Snapshot tickers accepts an array of 1–100 symbols. For consolidated equity and BOATS, choose either the existing single ticker or the new tickers array. Omitting both keeps the all-market behavior. Crypto exchanges accepts an array of exchange identifiers for current or historical prices. Search supports exact_ticker_match, include_delisted, and limit from 1 to 100.
Intraday intervals accept positive whole-number minutes or hours, such as 45min and 4hour. IEX history uses those units only. Consolidated equity, BOATS and forex retain the existing 1day input; Crypto and Crypto Yield also accept day multiples such as 2day. EOD intervals remain daily, weekly, monthly, and annually.
IEX history accepts after_hours and force_fill; BOATS history also accepts force_fill. Tiingo’s BOATS after_hours flag does not extend its 8pm–3:59am ET history window. See the full request contract for query names, validation and exclusions.
Keeping a local EOD price cache
You can keep a local copy of EOD price history with two tools. First, load each ticker's full history once with get_stock_prices. Second, call get_bulk_eod_prices each day to get the latest prices for all tickers. The bulk result keeps raw and adjusted prices in separate fields, with splitFactor and divCash for each row.
A split or dividend changes a ticker's adjusted history. So if a row has splitFactor other than 1 or divCash greater than 0, reload that ticker's full history with get_stock_prices.
Access and quota
Tiingo decides which data your key can reach, based on the features enabled for your account, and this project can't promise access based on a plan name. An HTTP 401 error means Tiingo rejected your API key. An HTTP 403 error means the key is valid, but your account doesn't include the data you asked for.
The access guidance below was reviewed against official documentation on 2026-10-04 (sources_as_of); it does not guarantee the features enabled for a particular account.
Some data has extra rules:
- IEX subscriptions use data level 6 by default, which gives reference prices. You can request levels 0 or 5 only if you confirm that you have a direct market data agreement with IEX.
- Consolidated equity data is in beta and covers 4am to 8pm ET. It supports reference ticks at level 6 or top of book data at level 4.
- BOATS data is a separate beta add-on that covers 8pm to 3:59am ET. Tiingo doesn't combine it with consolidated equity data into one 24 hour feed.
- Fund fee data needs enterprise or institutional access. Fundamentals, corporate actions, and Crypto Yield depend on your account's features, and Search is in early beta. The ticker metadata from
get_ticker_metadatacomes from a data vendor and may be missing, so a 404 error from it doesn't mean you should try a different endpoint.
Every REST call uses API quota and bandwidth, and every live subscription uses bandwidth. To reduce use, request only the tickers and dates you need. The bulk and all ticker tools return large responses, so call them only when you need all of that data.
Resources
The server includes reference documents that clients can read without calling the Tiingo API.
| Resource | Description |
|---|---|
tiingo://capabilities | Server capabilities and dated notes on which Tiingo features each tool needs |
tiingo://fundamentals/definitions | Definitions of common fundamental metrics |
tiingo://guide/date-formats | Date formats, resample intervals, sort options, and other parameters |
tiingo://guide/{asset_class} | A guide for one data area, e.g., stocks, forex, crypto, funds, news, or fundamentals |
Prompts
| Prompt | Arguments | Description |
|---|---|---|
analyze-stock | ticker, include_news | Full analysis of one stock |
compare-stocks | ticker1, ticker2, period | Comparison of two stocks |
crypto-market-overview | tickers | Crypto market summary with seven day trends |
earnings-report-analysis | ticker, earnings_date | Review of an earnings report, the price reaction, and related news |
forex-pair-analysis | pair, period | Trend and volatility review for a currency pair |
Results and errors
Each successful tool call returns the result twice, once as JSON text for older clients and once as MCP structured content. When a call fails in a way the client can handle, the server returns an MCP tool error with a short JSON message, and it removes the API key and any sensitive details from that message.
When a subscription fails, poll_market_data_subscription returns the state failed and reports one of four reasons in terminalError, which are authentication, entitlement, transport, or protocol. The server doesn't pass along Tiingo's original error text. A subscription that closes for another reason, such as data_gap, expired, or stopped, reports that state and has no terminalError.
The server retries a request only when the failure is temporary and a retry is safe, and it rejects responses larger than 8 MiB. Malformed WebSocket frames and invalid UTF-8 terminate the subscription as a protocol failure; abrupt transport loss can reconnect. Error-body reading stops once its bounded diagnostic prefix is full. It never includes the API key or the authorization header in errors that the client can see.
Development
To build and check the project, clone the repository and run the same checks that CI runs:
git clone https://github.com/major7apps/tiingo-mcp.git
cd tiingo-mcp
cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-targets --locked
cargo llvm-cov --all-targets --all-features --locked --fail-under-lines 93 --summary-only
cargo build --release --locked
cargo deny check all
The normal test suite runs against local mock servers, so it doesn't need a Tiingo key. The live tests are marked as ignored, because they call the real Tiingo API and use quota or bandwidth. Run them only with explicit approval and a TIINGO_API_KEY. Record data delivery, acknowledgement without data, entitlement denial, skipped operations and terminal failure separately. A passing entitlement-aware test does not mean every represented tool returned data. The live inventory includes actual stdio cases for bounded REST and subscription updates; their presence does not establish live success.
For more detail on how the project is built and tested, see ARCHITECTURE.md, API_SURFACE.md, and QUALITY.md.