finra-mcp-server
MCP Server for Finra Public Data
Documentation
finra-mcp-server
A Model Context Protocol (MCP) server that exposes the FINRA Query API as a set of tools. It lets MCP-capable clients (Claude Desktop, Claude Code, and other MCP hosts) query FINRA's public regulatory and market datasets — TRACE corporate bond trades, OTC equity summaries, short interest, firm registration data, and more — in natural language.
The server handles OAuth2 authentication, token caching, request shaping, and pagination, and ships with a local catalog of datasets so a model can discover what's available before issuing a query.
What it does
FINRA publishes a large family of datasets through a single Query API surface:
/data/group/{group}/name/{dataset}Each dataset supports field projection, comparison filters, date-range filters, IN-list (domain) filters, sorting, and pagination. This server wraps that API with:
- OAuth2 client-credentials flow — fetches and caches a bearer token, refreshing automatically before expiry.
- A generic query tool (`finra_query`) that exposes the full filtering surface of the Query API.
- A local dataset catalog so the model can discover valid `group`/`dataset` combinations without guessing.
- Curated convenience tools for the most common datasets (TRACE bonds, short interest, OTC weekly summary, firm profile) that map friendly arguments (CUSIP, symbol, date range, CRD number) onto the underlying query shape.
Tools
| Tool | Description |
|---|---|
| `finra_query` | Generic Query API request. Supports `compareFilters`, `dateRangeFilters`, `domainFilters`, field projection, sorting, and pagination. Sync cap is 5,000 records. |
| `finra_list_datasets` | List datasets in the local catalog, optionally filtered by `category` or a `search` substring. Use this first to discover valid `group`/`dataset` names. |
| `finra_describe_dataset` | Look up catalog metadata for a specific `group`/`dataset`. |
| `finra_trace_corporate_bonds` | Curated wrapper for TRACE corporate-bond trade reports (`fixedIncomeMarket/trace`). Filter by `cusip`, `symbol`, or trade-date range. |
| `finra_short_interest` | Curated wrapper for consolidated short interest (`otcMarket/consolidatedShortInterest`). Filter by `symbol` and/or settlement-date range. |
| `finra_otc_weekly_summary` | Curated wrapper for OTC equity weekly trade summary (`otcMarket/weeklySummary`). Filter by `symbol` and/or week-ending date. |
| `finra_firm_profile` | Curated wrapper for firm profile lookup (`registration/firmProfile`). Provide a CRD number. |
`finra_query` arguments
| Argument | Type | Description |
|---|---|---|
| `group` | string (required) | Dataset group, e.g. `otcMarket`, `fixedIncomeMarket`, `registration`. |
| `dataset` | string (required) | Dataset name within the group, e.g. `weeklySummary`, `trace`. |
| `fields` | string[] | Subset of fields to return. Omit for all fields. |
| `compareFilters` | object[] | Field comparisons: `{ fieldName, fieldValue, compareType }` where `compareType` is one of `EQUAL`, `NOT_EQUAL`, `GREATER`, `LESSER`, `GREATER_EQUAL`, `LESSER_EQUAL`, `LIKE`. |
| `dateRangeFilters` | object[] | `{ fieldName, startDate, endDate }` with ISO `yyyy-MM-dd` dates. |
| `domainFilters` | object[] | IN-list filters: `{ fieldName, values: [...] }`. |
| `sortFields` | string[] | Sort fields; prefix with `-` for descending. |
| `limit` | number | Max records (1–5,000 for synchronous requests). Defaults to 100. |
| `offset` | number | Pagination offset (0–500,000). Defaults to 0. |
Dataset catalog
The server bundles a curated catalog (see `src/catalog.ts`) covering these categories:
- Equity / OTC Market — weekly/monthly summaries, ATS and non-ATS block summaries, daily OTC list, consolidated short interest, Reg SHO daily volume, threshold list, ADF data.
- Fixed Income — TRACE corporate bonds, Treasury daily/monthly aggregates, agency & corporate debt breadth/sentiment indicators, 144A debt indicators, capped-volume datasets.
- Registration — firm profiles, registrations, disclosures, status history, broker-dealer lists, branch and individual records, registration validation, and more.
- Firm — Rule 4530 customer complaint filings.
- FINRA Content — the FINRA rulebook and industry-snapshot datasets.
The catalog is for discovery only — the API may accept additional `group`/`dataset` combinations not listed here. If `finra_describe_dataset` returns no entry, you can still try `finra_query` directly.
Prerequisites
- Node.js ≥ 20
- FINRA API credentials — a client ID and client secret provisioned from the FINRA API Console. You will need a FINRA account with access to the API Platform, and you must accept the data-set agreements for any non-public datasets you intend to query.
Installation
git clone
cd finra-mcp-server
npm install
npm run buildThis compiles TypeScript from `src/` into `dist/`. The entry point is `dist/index.js`.
npm scripts
| Script | Purpose |
|---|---|
| `npm run build` | Compile TypeScript to `dist/`. |
| `npm run dev` | Compile in watch mode. |
| `npm start` | Run the compiled server (`node dist/index.js`). |
| `npm run typecheck` | Type-check without emitting output. |
Configuration
The server is configured entirely through environment variables.
| Variable | Required | Default | Description |
|---|---|---|---|
| `FINRA_CLIENT_ID` | ✅ | — | OAuth2 client ID from the FINRA API Console. |
| `FINRA_CLIENT_SECRET` | ✅ | — | OAuth2 client secret. |
| `FINRA_API_BASE` | `https://api.finra.org` | Base URL for the Query API. | |
| `FINRA_TOKEN_URL` | `https://ews.fip.finra.org/fip/rest/ews/oauth2/access_token?grant_type=client_credentials` | OAuth2 token endpoint. |
If `FINRA_CLIENT_ID` or `FINRA_CLIENT_SECRET` is missing, the server exits at startup with an error directing you to provision credentials.
Usage
The server speaks MCP over stdio. It is launched by an MCP client, which communicates with it over standard input/output — you do not run it as a long-lived HTTP service.
Claude Desktop / Claude Code
Add the server to your MCP client configuration. For Claude Desktop, edit `claude_desktop_config.json`; for Claude Code, use `claude mcp add` or edit `.mcp.json`.
{
"mcpServers": {
"finra": {
"command": "node",
"args": ["/absolute/path/to/finra-mcp-server/dist/index.js"],
"env": {
"FINRA_CLIENT_ID": "your-client-id",
"FINRA_CLIENT_SECRET": "your-client-secret"
}
}
}
}For Claude Code, the equivalent CLI command is:
claude mcp add finra \
--env FINRA_CLIENT_ID=your-client-id \
--env FINRA_CLIENT_SECRET=your-client-secret \
-- node /absolute/path/to/finra-mcp-server/dist/index.jsRestart the client after editing the configuration. The FINRA tools will then be available to the model.
Running directly
For local testing you can run the server directly. It will wait for an MCP client to connect over stdio:
export FINRA_CLIENT_ID=your-client-id
export FINRA_CLIENT_SECRET=your-client-secret
npm startTo exercise it interactively, use the MCP Inspector:
FINRA_CLIENT_ID=... FINRA_CLIENT_SECRET=... \
npx @modelcontextprotocol/inspector node dist/index.jsExamples
These show the arguments a model would pass to each tool.
Discover datasets in a category:
// finra_list_datasets
{ "category": "Fixed Income" }Recent TRACE trades for a bond by CUSIP:
// finra_trace_corporate_bonds
{ "cusip": "037833DX5", "startDate": "2026-01-01", "endDate": "2026-03-31", "limit": 200 }Short interest for a symbol:
// finra_short_interest
{ "symbol": "AAPL", "startDate": "2026-01-01", "endDate": "2026-06-01" }Look up a firm by CRD number:
// finra_firm_profile
{ "crdNumber": "7691" }Arbitrary query with the generic tool:
// finra_query
{
"group": "otcMarket",
"dataset": "weeklySummary",
"compareFilters": [
{ "fieldName": "issueSymbolIdentifier", "fieldValue": "TSLA", "compareType": "EQUAL" }
],
"dateRangeFilters": [
{ "fieldName": "weekStartDate", "startDate": "2026-01-01", "endDate": "2026-06-01" }
],
"sortFields": ["-weekStartDate"],
"limit": 50
}Each tool returns a JSON object containing the dataset identifiers, the total `recordCount` reported by the API, the number of records `returned`, and the `records` array.
How it works
- Authentication (`src/finra-client.ts`) — On the first request the client exchanges its base64-encoded `clientId:clientSecret` for a bearer token at `FINRA_TOKEN_URL`, then caches it. Tokens are reused until ~30 seconds before expiry (capped at 30 minutes) and refreshed automatically.
- Request shaping — Requests with filters, projections, or sorts are sent as `POST` with a JSON body; simple unfiltered requests use `GET` with query-string pagination. The total record count is read from the `record-count` response header.
- Tool layer (`src/tools.ts`) — Zod schemas validate every tool's arguments and are converted to JSON Schema for the MCP `tools/list` response. Curated tools translate friendly arguments into the underlying `compareFilters`/`dateRangeFilters` shape.
Project structure
src/
index.ts MCP server bootstrap (stdio transport, request handlers)
config.ts Environment-variable configuration loader
finra-client.ts OAuth2 token handling + Query API client
tools.ts Tool definitions, Zod schemas, and handlers
catalog.ts Local catalog of FINRA datasetsNotes & limitations
- Synchronous queries are capped at 5,000 records. For larger result sets, page with `limit`/`offset`. The Query API also supports an async mode for very large extracts; this server requests synchronous results.
- Data availability depends on your FINRA entitlements. Some datasets require accepting additional data agreements in the API Console.
- Field names (e.g. `issueSymbolIdentifier`, `tradeReportDate`, `firmCrdNumber`) follow FINRA's schema. Consult the FINRA developer catalog for the exact fields available in each dataset.
License
Released under the MIT License.
Frequently asked questions
What is finra-mcp-server?
finra-mcp-server is MCP Server for Finra Public Data
How do I install finra-mcp-server?
Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.
Is finra-mcp-server open source?
Yes — it is hosted on GitHub at https://github.com/cmaurer/finra-mcp-server and has 1 stars.
Related MCP tools
The go-to web for your AI coding agent — local-first search, fetch, crawl & research over MCP. No API keys, no cloud, $0/query. Public beta.
MCP server that enables AI assistants to interact with Google Gemini CLI, leveraging Gemini's massive token window for large file analysis and codebase understanding
A desktop MCP client designed as a tool unitary utility integration, accelerating AI adoption through the Model Context Protocol (MCP) and enabling cross-vendor LLM API orchestration.
Code research platform for AI agents; find, understand, and prove context across your code and all of GitHub, in a fraction of the tokens. One toolset, MCP or CLI
MCP server to provide Figma layout information to AI coding agents like Cursor
The world's best AI personal assistant for email. Open source app to help you reach inbox zero fast.
Run your own MCP server? See who uses it and what to fix.
Measure it with TrackMCP