Connect Your AI Agent in 3 Steps
Get your AI trading agent connected to Finlet via the hosted MCP server, the stdio bridge, or the REST API.
finlet CLI:
finlet manual quickstart— five-step copy-paste setupfinlet manual client-matrix— per-client config blocks (the same 8 clients below)finlet manual transports— hosted MCP-over-HTTP vsfinlet mcp servestdio vs RESTfinlet manual auth-model— OAuth 2.1 + PKCE, Bearer storage, api_key fallbackfinlet manual errors— every error envelope with a stable anchor for deep-linking
Register and Authenticate
Create your account, then sign in with OAuth so the CLI and MCP transport pick up your Bearer token automatically.
First, register an account. This issues an API key for REST clients:
finlet register
This returns an API key like:
API Key: a1b2c3d4e5f67890c8d4f6a2b9e7c5d3
Next, sign in via OAuth. This is the canonical credential path: it mints a Bearer JWT, writes it to ~/.finlet/credentials (mode 0600), and every subsequent CLI command and MCP dispatch picks it up automatically:
finlet auth login
finlet auth login opens your browser, walks you through the OAuth approval flow, and writes the Bearer token to ~/.finlet/credentials (mode 0600). All subsequent CLI commands pick it up automatically.
https://finlet.dev/mcp requires Authorization: Bearer <oauth_jwt> — obtain a JWT via finlet auth login. The fnlt_<api_key> form is not accepted on the MCP HTTP surface. For api_key clients without a browser, use either (a) the REST API at https://finlet.dev/v1/... with X-API-Key: fnlt_<key> or Authorization: Bearer fnlt_<key>, or (b) the bundled finlet mcp serve stdio bridge — set FINLET_API_KEY=fnlt_<key> in the subprocess env and the bridge translates internally.
CI / headless / non-interactive — export FINLET_API_KEY instead
If you can't run finlet auth login (CI workers, eval rigs, anything without a browser), export your api_key. The REST API accepts it on every route, and the finlet mcp serve stdio bridge translates it to OAuth Bearer internally before dispatching to the hosted service.
export FINLET_API_KEY=your_api_key_here
Configure Your Client
Pick your AI client. Each tab leads with hosted MCP-over-HTTP (OAuth Bearer, recommended) and follows with the local finlet mcp serve stdio bridge as a fallback.
https://finlet.dev/mcp is the recommended happy path — no install, no local process, just an OAuth Bearer in the Authorization header. The finlet mcp serve stdio bridge is the fallback for clients that don't speak HTTP transports yet. Both surfaces route through the same backend; you'll get the same tools and the same data.
Hosted (https://finlet.dev/mcp, OAuth Bearer)
Add this to claude_desktop_config.json. Replace $FINLET_OAUTH_BEARER with the JWT minted by finlet auth login (the value is stored at ~/.finlet/credentials; finlet auth status prints it).
{
"mcpServers": {
"finlet": {
"url": "https://finlet.dev/mcp",
"transport": "http",
"headers": {
"Authorization": "Bearer $FINLET_OAUTH_BEARER"
}
}
}
}
Local (finlet mcp serve stdio)
If your client can't speak HTTP transports, use the stdio bridge. FINLET_OAUTH_BEARER is primary; FINLET_API_KEY is the CI / headless fallback when no browser is available.
{
"mcpServers": {
"finlet": {
"command": "finlet",
"args": ["mcp", "serve"],
"env": {
"FINLET_OAUTH_BEARER": "your_jwt_here"
}
}
}
}
CI / headless variant — FINLET_API_KEY in env
Use this when the host can't run finlet auth login (CI workers, eval rigs). The stdio bridge translates the api_key to OAuth internally; the agent still sees the same tools.
{
"mcpServers": {
"finlet": {
"command": "finlet",
"args": ["mcp", "serve"],
"env": {
"FINLET_API_KEY": "your_api_key_here"
}
}
}
}
Hosted (https://finlet.dev/mcp, OAuth Bearer)
Register Finlet as a hosted MCP server from your terminal. Claude Code persists the entry under ~/.config/claude-code/mcp.json.
claude mcp add finlet --transport http --url https://finlet.dev/mcp --header "Authorization: Bearer $FINLET_OAUTH_BEARER"
Local (finlet mcp serve stdio)
Stdio fallback. FINLET_OAUTH_BEARER is primary; the CI / headless variant below uses FINLET_API_KEY.
claude mcp add finlet --command finlet --args "mcp,serve" --env "FINLET_OAUTH_BEARER=your_jwt_here"
CI / headless variant — FINLET_API_KEY in env
The MCP config block (equivalent to the claude mcp add command above, written directly):
{
"mcpServers": {
"finlet": {
"command": "finlet",
"args": ["mcp", "serve"],
"env": {
"FINLET_API_KEY": "your_api_key_here"
}
}
}
}
Hosted (https://finlet.dev/mcp, OAuth Bearer)
Cursor reads MCP servers from ~/.cursor/mcp.json. Add Finlet under mcpServers.
{
"mcpServers": {
"finlet": {
"url": "https://finlet.dev/mcp",
"transport": "http",
"headers": {
"Authorization": "Bearer $FINLET_OAUTH_BEARER"
}
}
}
}
Local (finlet mcp serve stdio)
Stdio fallback. Primary uses FINLET_OAUTH_BEARER; the CI / headless variant uses FINLET_API_KEY.
{
"mcpServers": {
"finlet": {
"command": "finlet",
"args": ["mcp", "serve"],
"env": {
"FINLET_OAUTH_BEARER": "your_jwt_here"
}
}
}
}
CI / headless variant — FINLET_API_KEY in env
{
"mcpServers": {
"finlet": {
"command": "finlet",
"args": ["mcp", "serve"],
"env": {
"FINLET_API_KEY": "your_api_key_here"
}
}
}
}
Hosted (https://finlet.dev/mcp, OAuth Bearer)
Codex CLI reads MCP servers from ~/.codex/config.toml. Add an [mcp_servers.finlet] entry pointing at the hosted endpoint.
[mcp_servers.finlet]
transport = "http"
url = "https://finlet.dev/mcp"
[mcp_servers.finlet.headers]
Authorization = "Bearer $FINLET_OAUTH_BEARER"
Local (finlet mcp serve stdio)
Stdio fallback. FINLET_OAUTH_BEARER is primary; the CI / headless variant uses FINLET_API_KEY.
[mcp_servers.finlet]
command = "finlet"
args = ["mcp", "serve"]
[mcp_servers.finlet.env]
FINLET_OAUTH_BEARER = "your_jwt_here"
CI / headless variant — FINLET_API_KEY in env
[mcp_servers.finlet]
command = "finlet"
args = ["mcp", "serve"]
[mcp_servers.finlet.env]
FINLET_API_KEY = "your_api_key_here"
Hosted (https://finlet.dev/mcp, OAuth Bearer)
Windsurf (Codeium) reads MCP servers from ~/.codeium/windsurf/mcp_config.json. Add Finlet under mcpServers.
{
"mcpServers": {
"finlet": {
"url": "https://finlet.dev/mcp",
"transport": "http",
"headers": {
"Authorization": "Bearer $FINLET_OAUTH_BEARER"
}
}
}
}
Local (finlet mcp serve stdio)
Stdio fallback. FINLET_OAUTH_BEARER is primary; the CI / headless variant uses FINLET_API_KEY.
{
"mcpServers": {
"finlet": {
"command": "finlet",
"args": ["mcp", "serve"],
"env": {
"FINLET_OAUTH_BEARER": "your_jwt_here"
}
}
}
}
CI / headless variant — FINLET_API_KEY in env
{
"mcpServers": {
"finlet": {
"command": "finlet",
"args": ["mcp", "serve"],
"env": {
"FINLET_API_KEY": "your_api_key_here"
}
}
}
}
Hosted (https://finlet.dev/mcp, OAuth Bearer)
VS Code's GitHub Copilot Chat extension (with MCP support) reads servers from ~/.config/Code/User/mcp.json (or the equivalent path for VS Code Insiders / Stable on your OS).
{
"mcpServers": {
"finlet": {
"url": "https://finlet.dev/mcp",
"transport": "http",
"headers": {
"Authorization": "Bearer $FINLET_OAUTH_BEARER"
}
}
}
}
Local (finlet mcp serve stdio)
Stdio fallback. FINLET_OAUTH_BEARER is primary; the CI / headless variant uses FINLET_API_KEY.
{
"mcpServers": {
"finlet": {
"command": "finlet",
"args": ["mcp", "serve"],
"env": {
"FINLET_OAUTH_BEARER": "your_jwt_here"
}
}
}
}
CI / headless variant — FINLET_API_KEY in env
{
"mcpServers": {
"finlet": {
"command": "finlet",
"args": ["mcp", "serve"],
"env": {
"FINLET_API_KEY": "your_api_key_here"
}
}
}
}
Hosted (https://finlet.dev/mcp, OAuth Bearer)
For any MCP-compatible client that speaks Streamable HTTP, configure an HTTP transport pointing at the hosted endpoint with the OAuth Bearer in the Authorization header.
{
"name": "finlet",
"transport": "http",
"url": "https://finlet.dev/mcp",
"headers": {
"Authorization": "Bearer $FINLET_OAUTH_BEARER"
}
}
Local (finlet mcp serve stdio)
Stdio fallback for clients without HTTP transport support. FINLET_OAUTH_BEARER is primary; the CI / headless variant uses FINLET_API_KEY.
{
"name": "finlet",
"transport": "stdio",
"command": "finlet",
"args": ["mcp", "serve"],
"env": {
"FINLET_OAUTH_BEARER": "your_jwt_here"
}
}
CI / headless variant — FINLET_API_KEY in env
{
"name": "finlet",
"transport": "stdio",
"command": "finlet",
"args": ["mcp", "serve"],
"env": {
"FINLET_API_KEY": "your_api_key_here"
}
}
pip install finlet). The finlet command must be available in your PATH for the stdio fallback. The hosted path needs only an HTTPS client.
REST (https://finlet.dev/v1/...)
If your agent does not speak MCP, call the hosted Finlet REST API directly. No install required. REST accepts either header form: X-API-Key: fnlt_<key> or Authorization: Bearer fnlt_<key>. OAuth Bearer (Authorization: Bearer <jwt>) is the preferred form when you can mint one via finlet auth login; the api_key form is the CI / headless equivalent.
# Verify the API is reachable
curl https://finlet.dev/v1/health
Primary auth — OAuth Bearer:
# Create a session (OAuth Bearer — preferred)
curl -X POST https://finlet.dev/v1/sessions \
-H "Authorization: Bearer $FINLET_OAUTH_BEARER" \
-H "Content-Type: application/json" \
-d '{"name": "test", "start_time": "2024-01-01", "initial_capital": 100000, "universe": ["AAPL", "GOOGL"]}'
# Get portfolio state
curl https://finlet.dev/v1/sessions/{session_id}/portfolio \
-H "Authorization: Bearer $FINLET_OAUTH_BEARER"
CI / headless variant — X-API-Key header
If you can't run finlet auth login (CI workers, eval rigs), pass your api_key in the X-API-Key header. Same routes, same response shapes — the auth header is the only thing that changes.
# Submit a market buy order against a session (CI / headless — api_key path)
curl -X POST https://finlet.dev/v1/sessions/$SESSION_ID/trade/order \
-H "X-API-Key: $FINLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ticker":"AAPL","side":"BUY","quantity":1,"order_type":"MARKET"}'
From the CLI, the equivalent command is:
finlet order --session $SID --ticker AAPL --side BUY --quantity 1
Run Your First Command
Create a session and query market data to verify everything works.
With finlet auth login complete from Step 1, create your first session:
finlet session create --name my-first-session --start 2024-01-01 --capital 100000 --universe AAPL,GOOGL,MSFT
Then ask your AI agent to call a Finlet MCP tool. Here is an example tool call your agent would make:
{
"tool": "get_price_data",
"arguments": {
"ticker": "AAPL",
"interval": "1d",
"period": "1mo"
}
}
Available MCP Tools
All 8 tools your AI agent can use via the Finlet MCP server. Run finlet manual plugin-matrix for the per-plugin reference with rate limits and error envelopes.
Market Data
get_price_data
Get historical OHLCV price data for a ticker. Supports intervals from 1m to 1w and lookback periods from 5d to 1y.
ticker
interval
period
search_news
Search for news articles about a company. Optionally filter by search text.
ticker
query
limit
get_fundamentals
Get fundamental metrics for a company: P/E ratio, market cap, revenue, and more.
ticker
Trading
submit_order
Submit a trade order (BUY/SELL). Supports MARKET, LIMIT, and STOP order types.
ticker
side
quantity
order_type
reasoning
get_portfolio
Get current portfolio state including cash balance, open positions, and total value.
session_id
Simulation Clock
get_sim_time
Get the current simulation time, clock mode, and speed.
session_id
advance_time
Advance the simulation clock by an interval: 1d, 1h, 5m, 1w, and more.
interval
session_id
freeze_time
Freeze the simulation clock. Time will not advance until you call advance_time.
session_id
Troubleshooting
Top 5 issues seen in the field. Each row deep-links to the canonical anchor in the finlet CLI's error catalog — run the command in your terminal for the full envelope, source code path, and recovery action.
-
Rate limit hit
An upstream plugin (Finnhub, FRED) or the per-tenant HTTP gate returned a 429. The envelope embeds the exact reset window — back off for that duration, then retry. Do not poll faster.
View in CLI:
finlet manual errors#rate-limit -
Expired or missing OAuth token
MCP-over-HTTP at
https://finlet.dev/mcprequiresAuthorization: Bearer <jwt>. If your token is past itsexpclaim, the CLI refreshes transparently on next dispatch. If it's missing entirely, runfinlet auth loginto mint a fresh one — or rebind the client to the stdio bridge.View in CLI:
finlet manual errors#expired-token·finlet manual errors#missing-bearer -
Missing API key for a plugin
Plugins that require credentials (Finnhub, FRED, EDGAR) fail with a specific envelope naming the missing key. Set the corresponding env var (
FINNHUB_API_KEY,FRED_API_KEY) in your shell or the stdio bridge'senvblock. Plugins without keys remain healthy on the free tier path.View in CLI:
finlet manual errors#missing-api-key -
MCP transport mismatch (api_key on MCP-over-HTTP returns 401)
The MCP HTTP surface at
/mcpdoes not accept thefnlt_<key>api_key form — that's a REST-only credential. If your hosted MCP call returns 401, switch to OAuth Bearer (finlet auth login), or rebind tofinlet mcp servestdio (which accepts api_key in env and translates internally).View in CLI:
finlet manual errors#transport-mismatch -
finlet serveport conflictIf
finlet serveorfinlet mcp servefails to bind, another process owns the port. Find it withlsof -i :<port>and either kill it or pass--port=<other>/FINLET_PORT=<other>to relocate Finlet.View in CLI:
finlet manual errors#port-conflict
#rate-limit, #expired-token, #missing-bearer, #missing-scope, #missing-api-key, #plugin-timeout, #plugin-malformed, #plugin-rate-limit, #transport-mismatch, #port-conflict, #date-ceiling-violation, #invalid-session, #order-rejected. Run finlet manual errors for the full catalog.