AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified Apache-2.0 Self-run

Secedgar Mcp Server

mcp-cyanheads-secedgar-mcp-server · by cyanheads

Query SEC EDGAR filings, XBRL financials, and company data through MCP. STDIO & Streamable HTTP.

No reviews yet
0 installs
29 views
0.0% view→install

Install

$ agentstack add mcp-cyanheads-secedgar-mcp-server

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-cyanheads-secedgar-mcp-server)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Secedgar Mcp Server? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

@cyanheads/secedgar-mcp-server Query SEC EDGAR filings, XBRL financials, and company data through MCP. STDIO & Streamable HTTP. 10 Tools (+1 opt-in) • 2 Resources • 1 Prompt

[](https://www.npmjs.com/package/@cyanheads/secedgar-mcp-server) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/secedgar-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.typescriptlang.org/) [](https://bun.sh/)

[](https://github.com/cyanheads/secedgar-mcp-server/releases/latest/download/secedgar-mcp-server.mcpb) [](https://cursor.com/en/install-mcp?name=secedgar-mcp-server&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBjeWFuaGVhZHMvc2VjZWRnYXItbWNwLXNlcnZlciJdLCJlbnYiOnsiRURHQVJfVVNFUl9BR0VOVCI6IllvdXJOYW1lIHlvdXItZW1haWxAZXhhbXBsZS5jb20ifX0=) [](https://vscode.dev/redirect?url=vscode:mcp/install?%7B%22name%22%3A%22secedgar-mcp-server%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40cyanheads/secedgar-mcp-server%22%5D%2C%22env%22%3A%7B%22EDGARUSERAGENT%22%3A%22YourName%20your-email%40example.com%22%7D%7D)

[](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)

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 |

secedgar_company_search

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

  • Supports ticker symbols (AAPL, VOO), company names (Apple), or CIK numbers (320193)
  • ETFs and mutual funds resolve by ticker via company_tickers_mf.json; fund results include series_id and class_id for downstream scoping
  • Current and former company names both resolve (Facebook → Meta Platforms, Square → Block)
  • Near-match suggestions on zero-result name search (e.g. MicrosfotMICROSOFT CORP / MSFT)
  • 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) — scoped server-side by CIK, so filings made under a former company name (same CIK) are included
  • Date range filtering, form type filtering, pagination up to 10,000 results
  • Returns form distribution for narrowing follow-up searches
  • When the entity-scoped window exceeds the inline limit, the already-fetched EFTS window is materialized as a df_ 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
  • Offset paging for large documents (10-K, S-1/A can exceed 1M chars): pass next_offset from a truncated response as offset on the next call to continue reading; first-page truncated responses include a detected outline (headings with offsets) for targeted navigation
  • Section targeting via the section param: jumps directly to a named heading by case-insensitive substring match (e.g. "risk factors", "item 7", "certain relationships"); on a miss, the error carries the detected outline so you can pick the correct heading
  • Extracted text is cached per accession + document (bounded LRU, 8 entries), making subsequent paged calls cheap

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
  • Optional limit caps the inline series to the most-recent N periods; the full series stays queryable via the df_ dataframe
  • 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
  • The full set of transactions parsed from the scanned recent filings is materialized as a df_ dataframe (the inline list is a preview capped at limit) — query it with secedgar_dataframe_query to aggregate net buy/sell by insider

secedgar_get_institutional_holdings

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

  • Pass the institutional filer (CIK or full legal name, e.g. 0000102909 for Vanguard) to see what it holds — reverse lookup from a portfolio company to its holders is not supported (EDGAR has no issuer→13F index); use secedgar_search_filings with forms=["13F-HR"] for issuer-side questions
  • Each holding: issuer name, CUSIP, market value (whole USD), shares/principal, and put/call; raw rows also carry investment discretion
  • Sub-lines for the same security (one per manager/account) are consolidated into distinct positions sorted by value by default — pass consolidate: false for raw filing rows
  • 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 counts raw info-table rows; total_positions counts distinct positions after consolidation (both before limit)
  • The full parsed holdings set is materialized as a df_ dataframe (the inline list is a preview capped at limit) — query it with secedgar_dataframe_query for full-filing aggregation or cross-quarter joins on cusip + reporting_period

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_ dataframe — query it with secedgar_dataframe_query
  • related_tags flags alternate-definition tags some filers use as their primary line (e.g. cash → restricted-cash-inclusive total, equity → NCI-inclusive total), so a whole-universe screen on the base tag isn't silently under-inclusive — query those separately

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
  • Surfaces related_tags for concepts with a high-coverage alternate-definition tag (e.g. restricted-cash-inclusive cash) so callers can discover them before screening
  • 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, secedgar_get_financials, secedgar_get_insider_transactions, and secedgar_get_institutional_holdings 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 (including ETFs and mutual funds via company_tickers_mf.json), company names (current and former), or raw CIK numbers with local caching; near-match trigram suggestions on zero-result name queries; committed former-names.json asset for prior-name resolution (Facebook → Meta, Square → Block)
  • 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, secedgar_get_financials, secedgar_get_insider_transactions, and secedgar_get_institutional_holdings materialize their full result 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 | | EDGAR_MIRROR_ENABLED | Enable the local SQLite mirror of company_tickers + XBRL company-facts so CIK resolution and financials read from disk instead of the live API. Node/Bun only (skipped on Workers). Bootstrap once with bun run mirror:init. | false | | EDGAR_MIRROR_PATH | Directory holding the mirror SQLite databases. | ./data/edgar-mirror | | EDGAR_MIRROR_REFRESH_CRON | Cron for the in-process nightly refresh (HTTP transport only). Recommended 0 9 * * *. Omit to refresh out-of-band via bun run mirror:refresh. | — | | EDGAR_MIRROR_FALLBACK_LIVE | When the mirror misses (not yet synced, or a filing newer than the last refresh), fall back to the live SEC API. Set false for strict mirror-only reads. | true | | 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, o

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.