mcpField
P
parsec-edgar: SEC EDGAR filings

parsec-edgar: SEC EDGAR filings

ローカル
github.com/ciscoriordan金融データ02 日前に更新

parsec-edgar: SEC EDGAR filings について

parsec-edgarは、Rust製のSEC EDGARクライアントで、Pythonバインディング、コマンドラインツール、MCPサーバーを備えています。SECのリクエスト制限を守りながら、項目別の閲覧、全文検索、一括取得を行えます。

主な機能

  1. 01ティッカーとCIKによる企業検索
  2. 02フォームと日付による提出書類一覧
  3. 03テキスト整形とItem別分割
  4. 04EDGAR全文検索
  5. 05再開可能な提出書類の一括取得

活用シーン

  1. 0110-K、10-Q、8-Kの必要な項目を読む
  2. 02提出書類を検索し、一致した添付書類を取得する
  3. 03フォームと日付別の提出書類データセットを作る

MCP 対応

MCPサーバーは、企業検索、提出書類一覧と概要、項目・文書の読み取り、全文検索のツールを提供します。stdioとStreamable HTTPに対応しています。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"ciscoriordan-parsec-edgar": {
"command": "uvx",
"args": [
"parsec-edgar"
],
"env": {
"PARSEC_EDGAR_USER_AGENT": "<PARSEC_EDGAR_USER_AGENT>"
}
}
}
}
起動コマンドuvx parsec-edgar
設定が必要な環境変数
PARSEC_EDGAR_USER_AGENTYour name and contact email, which the SEC requires with every request

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
pypiparsec-edgar0.1.1

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

parsec-edgar

Python バインディングとコマンドラインツールを備えた、Rust 製の高速な SEC EDGAR クライアントおよび提出書類パーサーです。

  • ティッカーまたは CIK で企業を検索します
  • フォームと日付で絞り込んで企業の提出書類一覧を表示します。1994 年まで遡る全履歴に対応しています
  • 提出書類の HTML(または古いプレーンテキストの提出データ)を、表の各行を 1 行に保ち、$ 記号を数字と結合した読みやすいテキストに変換します
  • 10-K、10-Q、8-K の提出書類を項目ごとのセクションに分割します(Item 1A Risk Factors、Item 7 MD&A、8-K Item 2.02 など)
  • SEC のフェアアクセス制限(デフォルトで毎秒 8 リクエスト、最大 10 リクエスト)を遵守し、アーカイブ文書をディスクにキャッシュします

ステータス:開発初期段階(0.1.1)。

インストール

pip install parsec-edgar          # Python library, plus the parsec-edgar command and MCP server
cargo install parsec-edgar-cli    # the parsec-edgar command, built from source (Rust 1.88 or newer)
cargo add parsec-edgar            # the Rust library

Python 3.10 以降向けに、Linux(x86-64 および ARM64)、macOS(Intel および Apple シリコン)、Windows(x86-64)用の Python ホイールを提供しています。各 GitHub リリースには、同じプラットフォーム向けのスタンドアロン parsec-edgar バイナリも含まれています。

SEC の User-Agent 要件

SEC は、すべてのリクエストで呼び出し元を名前と連絡先メールアドレスによって識別することを求めています。明示的に指定するか、PARSEC_EDGAR_USER_AGENT を設定してください(edgartools が使用する EDGAR_IDENTITY 変数も使用できます)。

export PARSEC_EDGAR_USER_AGENT="Example Corp [email protected]"

コマンドライン

parsec-edgar company AAPL
parsec-edgar filings AAPL --form 10-K --limit 5
parsec-edgar filings MSFT --form 10-K --since 1994 --until 2002   # reaches into older history pages
parsec-edgar text AAPL --form 10-K                                 # clean text of the latest 10-K
parsec-edgar sections AAPL --form 10-K --item 1A --item 7          # JSON
parsec-edgar sections MSFT --form 10-Q --no-text                   # ids, titles and offsets only
parsec-edgar sections AAPL --accession 0000320193-26-000026

アーカイブ文書(提出書類、そのインデックスページ、全インデックスの完了済み四半期)は ~/.cache/parsec-edgar にキャッシュされます(--cache-dir または PARSEC_EDGAR_CACHE で保存先を変更でき、--no-cache で無効にできます)。提出書類一覧、ティッカーファイル、全文検索の結果はディスクにキャッシュされないため、コマンドを実行するたびに最新のデータを取得します。MCP サーバーは、実行中にその一部をメモリに保持します(下記を参照)。

MCP サーバー

parsec-edgar mcp は Model Context Protocol サーバーを起動します。Claude やその他の LLM クライアントは、企業の検索、提出書類の一覧表示、EDGAR の全文検索、提出書類のセクションごとの閲覧を行えます。これはコマンドラインツールの一部であり、同じ User-Agent、キャッシュディレクトリ、レート設定を使用します。uv を使う場合は、事前に何もインストールせずに uvx parsec-edgar mcp で起動できます。それ以外の場合は、上記の手順に従ってコマンドをインストールしてください。このサーバーは、MCP registry に io.github.ciscoriordan/parsec-edgar として登録されています。

ツール戻り値
find_companyティッカー、CIK、または企業名の一部に一致する提出者を最大10件
list_filings簡潔な行(accession、フォーム、提出日、期間、8-K の Item)。フォームと提出日で絞り込みます
get_filing_outline提出書類のメタデータ、全体の長さ、Item セクションの ID、タイトル、文字数。本文は含まれません
read_sectionItem セクションをプレーンテキストで、一度に max_chars 文字(デフォルトは20,000文字)ずつ返します。続きがある場合は next_offset を返します
read_filing_textItem セクションのないフォーム(S-1、DEF 14A、20-F、...)の主文書全体を同じ方法で返すか、document で指定した添付資料を返します
search_full_text2001年以降の SEC 全文検索結果。企業、CIK、フォーム、提出日、accession、文書 URL に加え、一致箇所が添付資料内にある場合は添付資料の種類とファイル名(document)を返します

ツールの説明では、モデルに対して最初に get_filing_outline を呼び出し、必要なセクションだけを読み取るよう案内しています。Apple の2026年の10-Kでは、アウトラインは約2,200文字ですが、全文は230,000文字で、Risk Factors だけでも86,000文字あります。オフセットは文字数で数えます。上限付近に段落、行、単語の区切りがある場合、ページはその位置で終わります。失敗(不明なティッカーまたは CIK、セクションが見つからない、不正な日付など)は、存在するセクション ID の一覧など、次の手順を示すツールエラーとして返されます。

検索結果の多くは主文書ではなく添付資料内にあります。たとえば、8-K に添付された EX-99.1 のプレスリリースなどです。その場合、search_full_text は添付資料のファイル名を document として返し、検索結果の accession と document を指定すると、read_filing_text(または get_filing_outline)でその添付資料を読み取れます。.htm、.html、.txt、.xml で終わるプレーンなファイル名のみ受け付けます。

サーバーの実行中は、直近に読み取った6件の文書(ページを続けて読む際に文書を解析するのは一度だけです)、accession 番号で検索したすべての提出書類、各フォームの最新の提出書類を10分間メモリ内に保持します。同じ文書を同時に必要とする呼び出しでは、ダウンロードを共有します。SEC のティッカーファイルは一度だけ読み込まれるため、サーバーの起動後に追加または変更されたティッカーは、サーバーを再起動するまで CIK でのみ検索できます。

Claude Code
claude mcp add parsec-edgar -s user -e PARSEC_EDGAR_USER_AGENT="Example Corp [email protected]" -- uvx parsec-edgar mcp

コマンドをインストール済みの場合は、代わりに行末に -- parsec-edgar mcp を追加してください。

Claude Desktop

サーバーを claude_desktop_config.json に追加し(macOS では ~/Library/Application Support/Claude/、Windows では %APPDATA%\Claude\)、Claude Desktop を再起動してください。

{
  "mcpServers": {
    "parsec-edgar": {
      "command": "uvx",
      "args": ["parsec-edgar", "mcp"],
      "env": { "PARSEC_EDGAR_USER_AGENT": "Example Corp [email protected]" }
    }
  }
}

Claude Desktop はシェルの PATH を読み込みません。サーバーを起動できない場合は、which uvx が出力するフルパスを command として指定するか、インストール済みのコマンドを使用してください。その場合は、which parsec-edgar が出力するフルパスを command とし、"args": ["mcp"] を指定します。

その他の MCP クライアント

stdio では、コマンドは parsec-edgar mcp です。環境で PARSEC_EDGAR_USER_AGENT(または EDGAR_IDENTITY)を設定してください。通常どおりグローバルオプションを適用できます。たとえば、parsec-edgar --rps 5 --cache-dir /data/edgar mcp のように指定します。User-Agent が設定されていない場合、サーバーは明確なメッセージを表示して終了します。

HTTP 経由で接続するクライアントでは、Streamable HTTP トランスポートを実行します。

parsec-edgar mcp --http 127.0.0.1:8080        # endpoint http://127.0.0.1:8080/mcp
claude mcp add --transport http parsec-edgar http://127.0.0.1:8080/mcp

HTTP サーバーが受け付けるのは、localhost、127.0.0.1、::1、またはサーバーがリッスンするアドレス宛てのリクエストのみです。これにより、ウェブページからの DNS リバインディングをブロックします。--http 0.0.0.0:8080 を指定すると、すべてのインターフェースでリッスンしますが、引き続きループバック名宛てのリクエストのみを受け付けます。そのため、他のマシンから使用する名前は --allow-host で指定してください。リバースプロキシの背後に配置する場合は、公開名も同様に追加します(--allow-host mcp.example.com)。ウェブページからのリクエストには、ローカルの Origin(任意のポートの http://localhost または http://127.0.0.1)、または --allow-origin https://app.example.com で指定した Origin も必要です。ネイティブクライアントは Origin を送信しないため、影響を受けません。サーバーには独自の認証機能がないため、インターネットに直接公開しないでください。

テスト
cargo test -p parsec-edgar-cli    # paging and lookup unit tests, plus stdio and HTTP protocol tests that make no SEC requests
PARSEC_EDGAR_USER_AGENT="Example Corp [email protected]" \
    cargo test -p parsec-edgar-cli --test mcp -- --ignored --nocapture   # every tool against live SEC data, 3 requests per second

全文検索

SEC の EDGAR 全文検索(2001 年以降に提出された書類が対象)も、ライブラリから利用できます。1 回の呼び出しで、最も一致度の高いものから最大 100 件の結果を含むページが返されます。offset を指定すると、次のページを取得できます。

use parsec_edgar::{Client, FullTextQuery};

let client = Client::builder("Example Corp [email protected]").build()?;
let q = FullTextQuery::new("\"supply chain disruption\" OR tariffs").forms(&["10-K"]).since("2025").cik(320193);
let results = client.full_text_search(&q)?;
println!("{} matching documents", results.total);
for hit in &results.hits {
    println!("{} {} {} {}", hit.company, hit.form, hit.filing_date, hit.document_url);
}

すべての単語が含まれている必要があります。"double quotes" はフレーズに一致し、OR はいずれかの語に一致し、-word はその語を除外します。フォームのフィルターは、そのフォームの修正書類にも一致します。SEC が件数として返すのは最大 10,000 件であり、それを超えると total_is_exact は false になり、10,000 件目以降は提供されません。そのため、offset は 10,000 未満である必要があります。検索レコードに提出者名またはファイル名がない結果は hits から除外され、その位置が skipped に記載されます。そのため、次のページは offset + hits.len() + skipped.len() から始まります。

検索結果にはテキストの抜粋は含まれません。結果を読むには、hit.document_url を取得して document_to_text で変換するか、上記の MCP ツールを使用してください。hit.document は一致したファイルで、多くの場合、提出書類の主文書ではなく別紙(hit.document_type が EX-99.1 など)です。

Python

import parsec_edgar as pe

client = pe.Client("Example Corp [email protected]", cache_dir="~/.cache/parsec-edgar")
client.company("BRK.B")                     # {'cik': 1067983, 'ticker': 'BRK-B', ...}
filings = client.filings("MSFT", form=["10-K", "10-Q"], since="2024")
latest = client.latest("AAPL", "10-K")      # a filing dict
text = client.text(latest)                  # clean text
for s in client.sections(latest):
    print(s["id"], s["title"], len(s["text"]))

pe.html_to_text(html)                       # parse documents you already have
pe.extract_sections(text, "10-K")

検索に失敗すると LookupError、引数が不正な場合は ValueError、ネットワークまたは HTTP の失敗時には parsec_edgar.EdgarError が発生します。ネットワーク呼び出し中は GIL が解放されるため、1 つのクライアントを複数のスレッドで共有できます。レート制限は引き続き守られます。

Rust

use parsec_edgar::{Client, FilingQuery};

let client = Client::builder("Example Corp [email protected]")
    .cache_dir(Some("cache".into()))
    .build()?;
let filing = client.latest("AAPL", "10-K")?;
for s in client.filing_sections(&filing)? {
    println!("{} {} ({} bytes)", s.id, s.title, s.text.len());
}
let recent = client.filings("NVDA", &FilingQuery::forms(&["8-K"]).since("2026-01").limit(10))?;

一括クロール

parsec-edgar crawl はフォームの種類と日付で提出書類を検索してダウンロードし、メタデータと Item セクションを含む JSON としてそれぞれを書き出します。edgar-crawler の download_filings.py と extract_items.py が 2 段階で行う処理を、1 段階で実行します。

# Every 8-K filed on two days, across all companies
parsec-edgar crawl --form 8-K --since 2026-11-05 --until 2026-11-06 --out 8k

# Whole years, or some quarters of them
parsec-edgar crawl --form 10-K --form 10-K/A --year 2020-2024 --out 10k
parsec-edgar crawl --form 10-Q --year 2024 --quarter 2,3 --out 10q --jsonl

# A list of companies (tickers or CIKs), through the submissions API
parsec-edgar crawl --form 10-K --company AAPL --company 789019 --year 2015-2025 --out big-tech --raw
parsec-edgar crawl --form 10-K --companies-file sp500.txt --out sp500    # no dates: whole history

parsec-edgar crawl --form 10-K --year 2025 --out 10k --dry-run           # count only, download nothing

フォームの種類は完全一致するため、--form 10-K では 10-K/A と 10-K405 は含まれません。必要なフォームごとに --form を繰り返してください。--item 1A --item 7 はそのセクションだけを保持し、--limit N は最初の N 件の提出書類で停止し、--threads N(デフォルトは 8)はワーカー数を設定します。ワーカーは 1 つのクライアントを共有するため、全体で --rps の上限を守りながら、ドキュメントを並列に解析します。

--out ディレクトリへの出力:

  • 各提出書類の {cik}_{form}_{filing date}_{accession}.json。または --jsonl を指定した場合、filings.jsonl に提出書類ごとに 1 行
  • --raw を指定した場合、配信時の主要ドキュメントを raw/{same name}.htm(または .txt)として出力
  • failures.jsonl:最新の実行で失敗した提出書類ごとに、URL とエラーを 1 行で記録します(ダウンロードを開始する前に実行が失敗した場合、前回の一覧はそのまま残ります)

同じコマンドを再実行するとクロールが再開されます。すでに出力がある提出書類はスキップされ、失敗した提出書類は再試行されます。実行の強制終了、ディスク容量不足、電源障害が起きても、不完全なレコードが完了済みとして扱われることはありません。不完全な JSON ファイルは再クロールされ、filings.jsonl は最後の完全な行まで切り戻されます。進捗と最終サマリー(成功、失敗、スキップ、1 分あたりの提出書類数、提出書類あたりのリクエスト数)は stderr に出力され、何らかの失敗があった場合の終了ステータスは 1 です。1 件の提出書類の解析中にパニックが発生した場合、その提出書類の失敗として記録され、クロールは続行されます。

SEC はレート制限を超えたクライアントに 403 を返します。最初の 403 が返されると、すべてのワーカーが 1 分間停止し、その提出書類が再試行されます。同じタイミングで他のワーカーに返された 403 は、同じ事象として扱われます。成功したダウンロードがないまま、このような停止を 2 回行った後も 403 が返される場合、クロールは停止し、後で再開できるようになります。

各レコードには次のフィールドがあります。

フィールドedgar-crawler のフィールド内容
cik、company、filing_date同じ
formfiling_type
report_dateperiod_of_report
acceptance_datetimesubmissions API と同じ UTC
accession_number、itemsitems には 8-K の Item 番号が一覧表示されます
sic、sic_descriptionsic
state_of_incorporationstate_of_inc
state_locationstate_location事業所住所の州または国コード
fiscal_year_endfiscal_year_endMMDD
index_urlfiling_html_index提出書類の -index.htm ページ
primary_document、primary_document_urlhtm_filing_linksubmissions API と同じです。SEC が XML からレンダリングするフォーム(Forms 3、4、5、D、13F など)の場合は HTML レンダリングが含まれます。例:xslF345X05/wk-form4_1759530830.xml
full_submission_urlcomplete_text_filing_link
raw_filefilename--raw を指定した場合
sectionsitem_1、item_1A、...提出書類の順序で並べられた、セクション ID をキーとするセクションのテキスト
section_list各セクションの id、part、item、title、heading、start、end、chars
textItem セクションのないフォーム、および Item セクションが見つからなかった 10-K、10-Q、8-K の提出書類(たとえば、表紙のみを修正した 10-K/A)の全文
提出書類の検索方法

--company を指定しない場合、クロールでは EDGAR の全件インデックスを読み込みます。このインデックスには、各社のすべての提出書類が掲載され、四半期ごとに 1 ファイルあります。master.gz を読み込みます。これはパイプ区切り形式ですが、form.idx と company.idx は固定幅の列を使用しており、長い社名によって列が崩れることがあります。また、約 3 MB と最もダウンロードサイズが小さいファイルです(master.idx は 24 MB、form.idx は 42 MB)。複数の提出者がいる提出書類は、提出者ごとに 1 行ずつ掲載されますが、クロールは 1 回だけ行われます。完了した四半期はキャッシュされます。SEC は毎晩、前営業日の提出書類を追加するため、現在の四半期は実行のたびに再ダウンロードされます。新しい四半期のインデックスが公開されるのは、その最初の営業日を過ぎてからです。それまでは、クロールで未公開として報告され、その期間からは何も見つかりません。

インデックスに記載されているのは、各提出書類の完全な提出ファイル(すべての文書を 1 つの SGML ファイルにまとめたもので、10-K では 10 MB 以上になることもよくあります)のパスだけです。そのため、クロールでは各提出書類の -index.htm ページ(10~40 KB)を読み込みます。このページから、主要文書(リンク先から取得した、種類がフォームと一致する行)、報告期間、受理時刻、8-K の項目、提出日時点の提出者の SIC コード、設立州、事業所住所、会計年度末を取得できます。提出書類ごとに 2 回のリクエストが必要です。もう 1 つの方法として、会社ごとに 1 回、提出書類 API を呼び出す方法があります。しかし、8-K が多い日や 10-K の 1 年分のように、提出書類の大半が異なる会社からのものである場合は、節約になりません。また、会社ごとに 100 KB~1 MB のファイルに加え、最新の 1,000 件より古い提出書類については追加のページも必要です。

--company または --companies-file を指定した場合、提出書類は提出書類 API から取得します。会社ごとに 1 回のリクエストで、会社のプロフィール(SIC コード、設立州などの現在の値)も取得できます。日付範囲が最新の 1,000 件より前に遡る場合は古いページも読み込み、下限がない場合(--since または --year を指定しない場合)はすべてのページを読み込みます。その後、提出書類ごとに文書のリクエストが 1 回必要です。

2026 年 11 月に --rps 3、スレッド数 8 で、空のキャッシュディレクトリから各クロールを開始して計測しました。

クロール提出書類数所要時間1 分あたりの提出書類数提出書類あたりのリクエスト数失敗
2026-11-05 および 2026-11-06 に提出されたすべての 8-K(全件インデックス)1,00911.2 分90.02.00、インデックス分としてさらに 10
インデックス順で最初の 200 件の 2025 年の 10-K(全件インデックス)2002.3 分89.82.00、インデックス分としてさらに 40
7 社の 2016 年から 2025 年までの 10-K(--company)6044 秒1731.00、検索分としてさらに 700

どちらの全件インデックスのクロールも、リクエスト上限で実行されました(1 秒あたり 3 回の場合、リクエストが 2 回ずつなら 1 分あたり 90 件です)。解析速度には十分な余裕があります。すべての文書がキャッシュ済みの状態では、同じ 200 件の 10-K(HTML 788 MB)の解析と書き込みは 2 秒未満で完了しました。10-K のクロールを再実行すると、リクエストなしで 200 件すべてがスキップされました。会社単位のクロールでは 60 件すべてがスキップされましたが、提出書類を見つけるための 70 回のリクエストは繰り返されました。提出書類ファイルはキャッシュされないためです。会社単位のクロールでは、検索リクエスト 70 回のうち 58 回が JPMorgan の古い提出書類ページへのものでした。同社は年間約 26,000 件の文書を提出するため、最近のページ範囲には 1 年分しか含まれません。長期間にわたる大量提出企業の場合は、全件インデックスのほうが低コストです。

デフォルトの 1 秒あたり 8 回のリクエストで 10-K を 1 年分クロールする場合、2025 年には 10-K が 6,431 件(10-K/A を含めると 7,139 件)あるため、リクエストは約 12,900 回、所要時間は 27 分です。200 件のサンプルでは、主要文書の平均サイズは 3.9 MB でした。そのため、1 年分では約 25 GB となり、処理に追いつくには約 16 MB/s(125 Mbit/s)の帯域幅が必要です。接続速度がそれより遅い場合は、ダウンロード時間が処理速度を決めます。

8-K のクロールでは、すべてのレコードで主要文書、報告日、受理時刻を取得でき、97.5%で SIC コード、91%で設立州も取得できました。欠損値は SEC 側でも空欄であり、提出書類 API でも同様です。

Rust から
use parsec_edgar::{Client, CrawlQuery};

let client = Client::builder("Example Corp [email protected]").build()?;
let query = CrawlQuery::new(&["8-K"]).since("2026-11-05").until("2026-11-06");
for entry in client.crawl_index(&query)? {
    let (filing, index) = client.resolve_index_entry(&entry)?;  // reads the -index.htm page
    let profile = index.filer(filing.cik).map(|f| &f.profile);  // SIC code, state, fiscal year end
    let sections = client.filing_sections(&filing)?;
}
let tenks = CrawlQuery::new(&["10-K"]).years(2015, 2025);
let (filings, profile) = client.crawl_company_with_profile("AAPL", &tenks)?;  // one submissions request

Client::crawl_company は提出書類のみを返し、Client::company_profile(cik) は企業プロフィールのみを返します。Client::full_index(quarter) は1四半期分のインデックス行を返します(新しい四半期のインデックスがまだ公開されていない間は空です)。parse_master_index と parse_filing_index は、すでに手元にあるファイルを解析します。また、Client::requests_sent() はクライアントが送信した HTTP リクエストの数をカウントします。

クロールの制限事項
  • SEC は現在の四半期のインデックスを毎晩更新するため、提出書類は翌営業日にフルインデックスクロールに表示されます。
  • 完了した四半期のインデックスは、四半期終了から数日後以降はキャッシュされたままになります。そのため、SEC によるその後の修正は反映されません。再度読み込むには、キャッシュディレクトリから Archives/edgar/full-index/YYYY/QTRn/master.gz を削除するか、--no-cache を指定してクロールしてください。
  • クロールでダウンロードされたすべての文書もキャッシュに保存されます(--cache-dir または PARSEC_EDGAR_CACHE で別の場所を指定しない限り ~/.cache/parsec-edgar)。10-K を1年分クロールすると、出力に加えて約25 GB必要です。十分な空き容量のあるディスクを --cache-dir に指定するか、再度クロールする予定がない場合は --no-cache を使用してください。
  • --company を指定した場合、プロフィールの各項目には企業の現在の値が設定されます。フルインデックスクロールでは、各提出書類に記載された値が取得されます。
  • ティッカーは現在そのティッカーを保有している企業を指します。新しい持株会社への再編後も、過去の提出書類は旧 CIK のままです。2026年に XOM は ExxonMobil Holdings Corp(CIK 2115436)に移ったため、Exxon Mobil の過去の 10-K を取得するには --company 34088 が必要です。
  • 2001年頃より前の提出書類には独立した主文書がないため、クロールでは提出ファイル全体とその最初の文書を読み込みます。
  • edgar-crawler の remove_tables および include_signature オプションに相当する機能はまだなく、クロール用の Python バインディングもありません。

セクション ID

形式ID
10-K(および 10-K405、10-KSB、10-K/A)item_1、item_1a、item_1b、item_1c、item_2 ... item_16
10-Q(および 10-QSB、10-Q/A)part_1_item_1 ... part_1_item_4、part_2_item_1、part_2_item_1a ... part_2_item_6
8-K(および 8-K/A)item_1.01 ... item_9.01

各セクションには、id、part(10-Q のみ)、item、title(標準タイトル)、heading(提出書類に印刷された見出し)、start と end(提出書類のテキスト内のバイトオフセット)、および text が含まれます。

仕組み:Item の見出しに見える行はすべて候補になります。目次の項目やページ上部に繰り返し表示されるヘッダーも含まれます。見出しが本文中により長いテキストとして再登場する目次の項目、タイトル付きの Item 見出しの直前にある単独のページヘッダー、署名の後に再掲されている Item の一覧は、最初に除外されます。その後、抽出器は Item ごとに候補を 1 つ選び、選択した見出しが様式の Item 順に並び、最も長いテキスト範囲を開始するようにします。10-Q では、Item のすぐ上にある PART 行によって、Part I と Part II のどちらに属するかが決まります。PART 行がない場合、標準タイトルが一方の Part にのみ該当する Item は、その Part に分類されます(「Item 4. Controls and Procedures」は Part I です)。順序が前後して印刷された Item(Part II が Part I より前にある場合)は、PART 行で示され、署名より前にあるものに限り保持されます。最後の Item は、署名の位置、署名見出しがない場合は署名ブロックの冒頭文、またはページ番号付きの独自の目次を持つ添付文書(完全版の年次報告書など)の位置で終了します。

精度は、1997 年から 2026 年までの人手でラベル付けされた 129 件の提出書類(bench/)を基準に測定されています。調整をすべて終えた後にラベル付けされ、1 回だけ採点した 25 件では、抽出器はラベル付けされた Item の開始位置 349 件のうち 345 件を検出し、誤検出はなく、F1 は 0.994、範囲精度は 0.935 です。初回採点時点で、見落としを修正する前の 2 つの以前のテストセットでは、F1 は 0.989、範囲精度は 0.997(19 件)、および F1 は 0.955、範囲精度は 0.875(20 件)でした。調整に使用した 104 件では、F1 は 1.000、範囲精度は 0.993 ですが、これらは学習データ内の数値です。範囲精度は、各提出書類について、正しい Item に割り当てられた文字数を、ラベル付けまたは予測されたすべての Item 内の文字数で割って算出し、その後、提出書類ごとの平均を取ります。未使用の 25 件では、edgar-crawler の F1 は 0.961、範囲精度は 0.843、edgartools の F1 は 0.900、範囲精度は 0.705 です。bench/README.md に詳細、すべての見落とし、および各ルールの根拠となるベンチマーク提出書類数が記載されています。

既知の制限事項

  • Item 見出しのないテキストは、その直前の Item に含まれます。例:独自の目次がなく、最後の Item の後に印刷された財務諸表ページ(Netflix)、Item 8 の見出しがないまま Item 7A の後に続くテキスト(Kroger 2019)、Item 9 と Part III の間のテキスト(Allen Organ 1998)、最後の Item と署名の間に印刷された別紙索引(Patriot National Bancorp 2025)。
  • 順序が前後する Item が認識されるのは 10-Q のみで、Item のすぐ上に PART 行がある場合に限られます。Capital One の 2020 年の 10-Q では、1 つの PART I 行の下で Item 2 が Item 1 より前に印刷されているため、Item 1 は見落とされ、Item 2 の範囲に含まれます。
  • 独自の Item 番号がない役員セクションや、「Item 4(a)」のように番号が付けられた項目(Lockheed Martin 2006)は、Item 4 に含まれます。
  • 様式で定義されていない Item 番号は、いずれの Item にも割り当てられません。Item 5 が「Item 5A」と「Item 5B」としてのみ印刷されている場合(McDonald's 2003)、出力に Item 5 は含まれません。
  • 「Item 3. - Quantitative and Qualitative Disclosures」(Samsara Luggage 2023 10-Q)のように区切り記号が 2 つある見出しは認識されず、そのテキストは直前の Item に含まれます。
  • ページ番号を含み、5 ページ以上にわたって繰り返されるページ上部のヘッダーとフッターは削除されます。「2021 Form 10-K 100」のような短いものは残ります。
  • 表はタブ区切りの行として出力され、構造化データにはまだ変換されません。

構成

パス内容
crates/parsec-edgarコアライブラリ
crates/parsec-edgar-cliparsec-edgar コマンドラインツール
pythonPython バインディング(PyO3、maturin でビルド)
benchセクション分割の精度と速度のベンチマーク(手動ラベル付き)
server.jsonMCP レジストリのエントリー
.github/workflows継続的インテグレーションとリリースワークフロー

開発

cargo test                       # unit tests, no network
cargo fmt && cargo clippy --workspace --all-targets   # style (rustfmt.toml) and lints
cd python && maturin develop     # build the Python extension into the active virtualenv
python -m pytest python/tests    # Python package and command, no network
cargo run --release -p parsec-edgar-bench -- score   # section accuracy on the labeled filings (downloads them once)

GitHub Actions は、Linux、macOS、Windows でテストを実行し、最低 Rust バージョン(1.88)を確認して、Python パッケージをビルドおよびテストします。

リリース

Cargo.toml の workspace.package.version と server.json の 2 か所に新しいバージョンを設定してコミットし、v0.2.0 のようなタグをプッシュします。リリースワークフローはホイールとバイナリをビルドし、PyPI、crates.io、GitHub リリース、MCP レジストリに公開します。Actions タブからワークフローを手動で実行すると、公開せずにすべてをビルドしてテストします。

ライセンス

MIT

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。