Looking for the full reference? This page is a quickstart shell — copy a config, paste it into your agent, you're done. The binary-portable, agent-readable version of the same content lives in the finlet CLI:

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:

Terminal
finlet register

This returns an API key like:

Output
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:

Terminal
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.

Auth path: MCP-over-HTTP at 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.

Terminal (CI / headless)
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.

Hosted first, local second. The hosted MCP server at 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).

JSON
{
  "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.

JSON
{
  "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.

JSON
{
  "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.

Terminal
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.

Terminal
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):

JSON
{
  "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.

JSON
{
  "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.

JSON
{
  "mcpServers": {
    "finlet": {
      "command": "finlet",
      "args": ["mcp", "serve"],
      "env": {
        "FINLET_OAUTH_BEARER": "your_jwt_here"
      }
    }
  }
}
CI / headless variant — FINLET_API_KEY in env
JSON
{
  "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.

TOML
[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.

TOML
[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
TOML
[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.

JSON
{
  "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.

JSON
{
  "mcpServers": {
    "finlet": {
      "command": "finlet",
      "args": ["mcp", "serve"],
      "env": {
        "FINLET_OAUTH_BEARER": "your_jwt_here"
      }
    }
  }
}
CI / headless variant — FINLET_API_KEY in env
JSON
{
  "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).

JSON
{
  "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.

JSON
{
  "mcpServers": {
    "finlet": {
      "command": "finlet",
      "args": ["mcp", "serve"],
      "env": {
        "FINLET_OAUTH_BEARER": "your_jwt_here"
      }
    }
  }
}
CI / headless variant — FINLET_API_KEY in env
JSON
{
  "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.

JSON
{
  "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.

JSON
{
  "name": "finlet",
  "transport": "stdio",
  "command": "finlet",
  "args": ["mcp", "serve"],
  "env": {
    "FINLET_OAUTH_BEARER": "your_jwt_here"
  }
}
CI / headless variant — FINLET_API_KEY in env
JSON
{
  "name": "finlet",
  "transport": "stdio",
  "command": "finlet",
  "args": ["mcp", "serve"],
  "env": {
    "FINLET_API_KEY": "your_api_key_here"
  }
}
Requirements: Python 3.12+ with Finlet installed (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.

cURL
# Verify the API is reachable
curl https://finlet.dev/v1/health

Primary auth — OAuth Bearer:

cURL
# 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.

cURL
# 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:

Terminal
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:

Terminal
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:

MCP Tool Call
{
  "tool": "get_price_data",
  "arguments": {
    "ticker": "AAPL",
    "interval": "1d",
    "period": "1mo"
  }
}
Success! If your agent receives OHLCV price data in response, your connection is working. You can now start building your trading strategy.

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/mcp requires Authorization: Bearer <jwt>. If your token is past its exp claim, the CLI refreshes transparently on next dispatch. If it's missing entirely, run finlet auth login to 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's env block. 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 /mcp does not accept the fnlt_<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 to finlet mcp serve stdio (which accepts api_key in env and translates internally).

    View in CLI: finlet manual errors#transport-mismatch

  • finlet serve port conflict

    If finlet serve or finlet mcp serve fails to bind, another process owns the port. Find it with lsof -i :<port> and either kill it or pass --port=<other> / FINLET_PORT=<other> to relocate Finlet.

    View in CLI: finlet manual errors#port-conflict

Need a different error? The CLI's error catalog ships 13 stable anchors: #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.