Skip to main content
Glama
cyanheads

@cyanheads/secedgar-mcp-server

npm License Docker MCP SDK TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework

Public Hosted Server: https://secedgar.caseyjhand.com/mcp


Tools

Eight tools for querying SEC EDGAR data, plus three for SQL analytics over the DuckDB-backed canvas dataframes those tools materialize:

Tool

Description

secedgar_company_search

Find companies and retrieve entity info with optional recent filings

secedgar_search_filings

Full-text search across all EDGAR filing documents since 1993

secedgar_get_filing

Fetch a specific filing's metadata and document content

secedgar_get_financials

Get historical XBRL financial data for a company

secedgar_get_insider_transactions

Form 3/4/5 insider transactions (buys, sells, grants, exercises) parsed from ownership XML

secedgar_get_institutional_holdings

13F-HR quarterly institutional holdings parsed from the information table

secedgar_fetch_frames

Fetch SEC XBRL frames for one concept × one period across all reporting companies

secedgar_search_concepts

Discover supported XBRL concept names or reverse-lookup a raw tag

secedgar_dataframe_describe

List canvas dataframes with provenance, TTL, and schema

secedgar_dataframe_query

Run a single-statement SELECT across dataframes

secedgar_dataframe_drop

Drop a canvas dataframe by name. Opt-in via EDGAR_DATAFRAME_DROP_ENABLED=true — off by default since TTL already handles cleanup

Entry point for most EDGAR workflows — resolve tickers, names, or CIKs to entity details.

  • Supports ticker symbols (AAPL), company names (Apple), or CIK numbers (320193)

  • Optionally includes recent filings with form type filtering

  • Returns entity metadata: SIC code, exchanges, fiscal year end, state of incorporation


secedgar_search_filings

Full-text search across all EDGAR filing documents since 1993.

  • Exact phrases ("material weakness"), boolean operators (revenue OR income), wildcards (account*)

  • Entity targeting within query string (cik:320193 or ticker:AAPL)

  • Date range filtering, form type filtering, pagination up to 10,000 results

  • Returns form distribution for narrowing follow-up searches

  • When post-filter hits exceed the inline limit, the already-fetched EFTS window (entity-filtered when ticker:/cik: is used) is materialized as a df_<id> dataframe — query it with secedgar_dataframe_query


secedgar_get_filing

Fetch a specific filing's metadata and document content by accession number.

  • Accepts accession numbers in dash or no-dash format

  • Converts HTML filings to readable plain text

  • Configurable content limit (1K–200K characters, default 50K)

  • Can fetch specific exhibits by document name


secedgar_get_financials

Get historical XBRL financial data for a company with friendly concept name resolution.

  • Friendly names like "revenue", "net_income", "eps_diluted" auto-resolve to correct XBRL tags

  • Handles historical tag changes (e.g., ASC 606 revenue recognition)

  • Automatic deduplication to one value per standard calendar period

  • Filter by annual, quarterly, or all periods

  • See secedgar://concepts resource for the full mapping


secedgar_get_insider_transactions

Surface Form 3/4/5 insider activity for a company by parsing ownership XML.

  • Reporting person, relationship to issuer (director, officer + title, 10% owner), and transaction date

  • Transaction code mapped to a readable type (purchase, sale, gift, award, exercise, …); shares signed by acquired/disposed

  • Price per share and shares owned after each transaction; covers non-derivative (open-market) and derivative (option/RSU) lines

  • Filter by transaction_type (purchase, sale, all); scans newest filings first


secedgar_get_institutional_holdings

Surface 13F-HR quarterly institutional holdings by parsing the information table.

  • Pass an institution (CIK or name) to see what it holds, or a company CIK to find its own 13F filings

  • Per position: issuer name, CUSIP, market value (thousands USD), shares/principal, put/call, and investment discretion

  • Resolves the filing-manager name and reporting quarter from the cover page; target a specific quarter with quarter (e.g. "2025-Q4")

  • total_holdings_in_filing reports the full position count before limit


secedgar_fetch_frames

Fetch SEC XBRL frames for one concept × one period across all reporting companies.

  • Same friendly concept names as secedgar_get_financials

  • Supports annual (CY2023), quarterly (CY2024Q2), and instant (CY2023Q4I) periods

  • Inline response returns the top N ranked companies (sort + limit), with ticker enrichment

  • The full frames response (all reporters, typically 2k–10k rows) is materialized as a df_<id> dataframe — query it with secedgar_dataframe_query


secedgar_search_concepts

Discover supported XBRL concept names before querying financials or cross-company comparisons.

  • Search by friendly name, label, or raw XBRL tag

  • Filter by statement group (income_statement, balance_sheet, cash_flow, per_share, entity_info) or taxonomy

  • Reverse-lookup raw tags like NetIncomeLoss to the supported friendly names

  • Returns the same catalog used by secedgar_get_financials, secedgar_fetch_frames, and secedgar://concepts


secedgar_dataframe_describe / secedgar_dataframe_query / secedgar_dataframe_drop

In-conversation SQL analytics over the dataframes that secedgar_fetch_frames, secedgar_search_filings, and secedgar_get_financials materialize on a shared DuckDB-backed canvas. Each data-returning call adds a dataset field with a df_XXXXX_XXXXX handle; pass that handle to secedgar_dataframe_query for joins, aggregates, window functions, percentiles — standard DuckDB SQL.

  • Read-only by default. Writes, DDL, DROP, COPY, PRAGMA, ATTACH, and external-file table functions are rejected by the framework SQL gate. System catalogs (information_schema, pg_catalog, sqlite_master, duckdb_*) are denied at the bridge layer so callers can't enumerate dataframes they don't already hold a handle for. secedgar_dataframe_drop is the only destructive tool and is opt-in (EDGAR_DATAFRAME_DROP_ENABLED=true); TTL handles cleanup otherwise.

  • Per-table TTL. Each dataframe ages on its own clock (default 24h, override with EDGAR_DATASET_TTL_SECONDS). The canvas itself uses the framework's sliding TTL.

  • register_as chaining. secedgar_dataframe_query can persist its result as a new dataframe (df_XXXXX_XXXXX) with a fresh TTL — pipe analyses without re-running the source query.

Resources

URI

Description

secedgar://concepts

Common XBRL financial concepts grouped by statement, mapping friendly names to XBRL tags

secedgar://filing-types

Common SEC filing types with descriptions, cadence, and use cases

Prompts

Prompt

Description

secedgar_company_analysis

Guides a structured analysis of a public company's SEC filings: identify recent filings, extract financial trends, surface risk factors, and note material events

Features

Built on @cyanheads/mcp-ts-core:

  • Declarative tool definitions — single file per tool, framework handles registration and validation

  • Structured output schemas with automatic formatting for human-readable display

  • Unified error handling across all tools

  • Pluggable auth (none, jwt, oauth)

  • Structured logging with request-scoped context

  • Runs locally (stdio/HTTP) from the same codebase

SEC EDGAR–specific:

  • Rate-limited HTTP client respecting SEC's 10 req/s limit with automatic inter-request delay

  • CIK resolution from tickers, company names, or raw CIK numbers with local caching

  • Friendly XBRL concept name mapping with historical tag change handling

  • Searchable concept catalog with statement-group metadata and reverse XBRL tag lookup

  • HTML-to-text conversion for filing documents via html-to-text

  • In-conversation SQL analytics: secedgar_fetch_frames, secedgar_search_filings, and secedgar_get_financials materialize their full upstream response as a DuckDB-backed canvas dataframe queryable via secedgar_dataframe_query

  • No API keys required — SEC EDGAR is a free, public API

Getting started

Public Hosted Instance

A public instance is available at https://secedgar.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:

{
  "mcpServers": {
    "secedgar-mcp-server": {
      "type": "streamable-http",
      "url": "https://secedgar.caseyjhand.com/mcp"
    }
  }
}

Self-Hosted / Local

Add the following to your MCP client configuration file.

{
  "mcpServers": {
    "secedgar-mcp-server": {
      "type": "stdio",
      "command": "bunx",
      "args": ["@cyanheads/secedgar-mcp-server@latest"],
      "env": {
        "EDGAR_USER_AGENT": "YourAppName your-email@example.com",
        "MCP_TRANSPORT_TYPE": "stdio"
      }
    }
  }
}

Or with npx (no Bun required):

{
  "mcpServers": {
    "secedgar-mcp-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cyanheads/secedgar-mcp-server@latest"],
      "env": {
        "EDGAR_USER_AGENT": "YourAppName your-email@example.com",
        "MCP_TRANSPORT_TYPE": "stdio"
      }
    }
  }
}

For Streamable HTTP, set the transport and start the server:

MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp

Prerequisites

Installation

  1. Clone the repository:

git clone https://github.com/cyanheads/secedgar-mcp-server.git
  1. Navigate into the directory:

cd secedgar-mcp-server
  1. Install dependencies:

bun install
  1. Build:

bun run build

Configuration

All configuration is validated at startup via Zod schemas in src/config/server-config.ts. Key environment variables:

Variable

Description

Default

EDGAR_USER_AGENT

Required. User-Agent header for SEC compliance. Format: "AppName contact@email.com". SEC blocks IPs without a valid User-Agent.

EDGAR_RATE_LIMIT_RPS

Max requests/second to SEC APIs. Do not exceed 10.

10

EDGAR_TICKER_CACHE_TTL

Seconds to cache the company tickers lookup file.

3600

EDGAR_DATASET_TTL_SECONDS

Per-table TTL for canvas-registered dataframes. Sliding window touched on every dataframe op.

86400

EDGAR_DATAFRAME_DROP_ENABLED

Set to true to expose secedgar_dataframe_drop — the only destructive tool on this server. Off by default; TTL handles cleanup.

false

CANVAS_PROVIDER_TYPE

Canvas engine. Defaults to duckdb; set to none to disable the canvas (e.g. when running on Cloudflare Workers, where DuckDB has no V8-isolate build).

duckdb

MCP_TRANSPORT_TYPE

Transport: stdio or http

stdio

MCP_HTTP_PORT

HTTP server port

3010

MCP_AUTH_MODE

Authentication: none, jwt, or oauth

none

MCP_LOG_LEVEL

Log level (debug, info, warning, error, etc.)

info

LOGS_DIR

Directory for log files (Node.js only).

<project-root>/logs

Running the server

Local development

  • Build and run the production version:

    bun run rebuild
    bun run start:http   # or start:stdio
  • Run checks and tests:

    bun run devcheck     # Lints, formats, type-checks
    bun run test         # Runs test suite

Docker

docker build -t secedgar-mcp-server .
docker run -e EDGAR_USER_AGENT="MyApp my@email.com" -p 3010:3010 secedgar-mcp-server

Project structure

Directory

Purpose

src/mcp-server/tools/definitions/

Tool definitions (*.tool.ts). Eight SEC EDGAR tools plus three dataframe_* tools for SQL analytics.

src/mcp-server/resources/definitions/

Resource definitions. XBRL concepts and filing types.

src/mcp-server/prompts/definitions/

Prompt definitions. Company analysis prompt.

src/services/edgar/

SEC EDGAR API client, XBRL concept mapping, HTML-to-text conversion.

src/services/canvas-bridge/

Adapter over the framework DataCanvas: df_<id> minting, all-nullable schema derivation, per-table TTL bookkeeping, bridge-layer system-catalog SQL deny.

src/config/

Server-specific environment variable parsing and validation with Zod.

tests/

Unit and integration tests, mirroring the src/ structure.

Development guide

See CLAUDE.md and AGENTS.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic

  • Use ctx.log for logging, ctx.state for storage

  • Register new tools and resources in the createApp() arrays

Contributing

Issues and pull requests are welcome. Run checks and tests before submitting:

bun run devcheck
bun run test

License

This project is licensed under the Apache 2.0 License. See the LICENSE file for details.

A
license - permissive license
-
quality - not tested
A
maintenance

Maintenance

Maintainers
13dResponse time
1dRelease cycle
7Releases (12mo)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cyanheads/secedgar-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server