doc-extract-api について
doc-extract-apiは、エージェントなどの呼び出し元向けの有料ドキュメント・JSON抽出APIです。4種類のドキュメントに検証済みスキーマを用いるほか、呼び出し元のJSON Schemaも受け付け、リクエストごとにx402でUSDCを支払います。
主な機能
- 01PDFや画像からのJSON抽出
- 024種類のドキュメント用スキーマ
- 03カスタムJSON Schemaによる抽出
- 04ドメイン別検証と警告
- 05x402によるリクエストごとのUSDC決済
活用シーン
- 01請求書やレシートから構造化フィールドを抽出
- 02契約書や履歴書をJSONに変換
- 03ドキュメントやテキストに独自スキーマを適用
MCP 対応
別途公開されているdoc-extract-api-mcpサーバーは、5つの抽出ツールを提供します。指定ウォレットで実際にx402決済して稼働中のAPIを呼び出し、ローカル抽出や無料利用には対応しません。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y doc-extract-apiWALLET_PRIVATE_KEYシークレットEVM private key for a wallet funded with real USDC on Base. Every tool call pays the live x402 API from this wallet — there is no free extraction path.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
doc-extract-api
ドキュメントを構造化 JSON に抽出する API です。PDF/PNG/JPEG を受け取り、整った JSON を返します。
固定された 4 種類のドキュメント(請求書、レシート、契約書、履歴書)には、それぞれ対応するスキーマと
ドメイン固有の検証が適用されます。/extract/custom では 任意の JSON Schema を受け付けるため、呼び出し元は
この 4 種類に限定されません。自律型 AI エージェント向けに構築されており、登録も API キーも人間による
決済手続きも不要です。エージェントは価格を確認し、x402 v2(USDC)を使って
HTTP 経由でリクエストごとに支払います。また、x402 Bazaar のディスカバリーカタログから
プログラムでこのサービスを見つけられます。MCP サーバーとしても公開されています(npm の
doc-extract-api-mcp、および
公式 MCP Registry)。ただし、これは同じ有料 API 用の
クライアントであり、無料の代替手段ではありません。MCP ツールを呼び出すたびに、ローカルで実行される
従量制限のない抽出ではなく、提供したウォレットから x402 で実際に支払われます。このサービスを
無料で利用する方法はありません。
Stripe ではなく x402 を使う理由
Stripe Checkout は人間向けに作られています。UI を介してカード情報を収集し、信頼されていない
プログラムによる(エージェント主導の)送信を決済ボタンが積極的に阻止します。x402 は
HTTP の 402 Payment Required ステータスコードを復活させます。支払いなしで有料エンドポイントに
アクセスすると、完全に機械可読なマニフェスト(価格、ネットワーク、受取アドレス、資産、さらに
Bazaar 拡張経由で実際の例を含む完全な入出力スキーマ)を PAYMENT-REQUIRED ヘッダーに格納した
402 が返されます。署名済み USDC 送金の承認情報を含む X-PAYMENT ヘッダーを付けて再試行すると、
リクエストが処理されます。アカウントもキーも不要で、人間が介在する必要もありません。
ディスカバリーと支払いの手順は、同じ HTTP の往復で完了します。
支払いが確定するのは、抽出が成功した後だけです。@x402/hono のミドルウェアはハンドラーの
実行前に支払い署名を検証しますが、実際のオンチェーン送金を実行するのは、ハンドラーが
エラーではないステータスを返した場合のみです(このプロジェクトの
paymentMiddlewareFromConfig の呼び出しでは、ラップされたルートが ≥400 を返すと確定処理が
スキップされることを確認済みです)。抽出に失敗しても、呼び出し元に費用は発生しません。
ディスカバリー:x402 Bazaar
Bazaar(GET {facilitator}/discovery/resources)は、エージェントクライアントから検索できる
x402 サービスのリアルタイムなクエリ可能カタログです(本稿執筆時点で約 15k 件の掲載があり、
client.extensions.bazaar.search({ query: "..." }) で検索できます)。掲載に申請フォームは不要です。
ファシリテーターは、ルートで宣言された bazaar 拡張を含む実際の支払いを初めて処理したときに、
リソースを自動でカタログに登録します。src/lib/discovery.ts では 4 つすべてのルートについて、
完全な入力スキーマ(multipart form-data、file フィールド)と、実際に検証済みの出力例を含む
その拡張を宣言しています。そのため、ルートで初回の実際のメインネット支払いが行われると、
エージェントがドキュメントを読まずに正しく統合できるだけの詳細情報とともに、カタログから
検索できるようになります。本稿執筆時点では、/extract/invoice のカタログ項目には、この詳細な
内容ではなく、移行前の古いレコードが表示されています。状況については git 履歴を確認するか、
問い合わせてください。/extract/receipt、/extract/contract、/extract/resume はまだ
メインネットでの支払いがないため、カタログに登録されていません。
位置付け(掲載文を書く前に実際の Bazaar を調査した結果):汎用 OCR の競合サービスは無料ですが、
未検証の生テキストを返します。汎用の構造化抽出サービスは 1 回あたり約 $0.10 で、呼び出し元が
生ファイルではなくプレーンテキストをすでに用意している必要があります。この両方を行うサービスは
見つかった中でこれだけです。生の PDF/画像を入力し、固定の検証済みスキーマを出力します。価格
(wrangler.toml を参照)は独自に設定したものではなく、各カテゴリの直接競合サービスについて
実際に確認できた最安の 402 対応価格に合わせています。請求書/レシート/履歴書/カスタムは
$0.02、契約書は $0.03 です(実際に比較可能なサービスの価格が 1 セント高いため)。正確な掲載文と
各ルートのタグ(serviceName/tags/description)については、src/lib/discovery.ts を
参照してください。
アーキテクチャ
schemas/—invoice、receipt、contract、resumeの抽出用 JSON Schema (Claude に送信するツールのinput_schemaでもあるため、モデルの出力はこの厳密な形式に限定されます)。src/lib/claude.ts— ドキュメントをネイティブのdocument/imageコンテンツブロックとして渡し、tool_choiceを強制して Anthropic Messages API を呼び出します。これにより、モデルはスキーマ以外の形式を返せなくなります。src/lib/validate.ts— 抽出後の妥当性チェックを行います。明細の合計が小計と一致すること、小計+税(+チップ)≒合計であること、日付が有効で未来の日付ではないこと、通貨が有効な ISO 4217 コードであることを確認し、信頼度の低いフィールドにフラグを付けます。src/lib/extract.ts— 1 回の抽出処理を統括して検証し、検証に失敗した場合は、計算が合わなかった箇所を具体的に説明する修正用プロンプトを使って 1 回だけ再試行します。失敗を黙って無視することはなく、いずれの場合もデータとともにvalidation_warningsを返します。src/lib/customSchema.ts/src/routes/customExtractHandler.ts—/extract/custom: Claude のツール使用を強制する同じエンジンを使いますが、ツールのinput_schemaには、4 つの固定スキーマのいずれかではなく、リクエスト時に呼び出し元が指定する JSON Schema を使用します。ドメイン固有のバリデーター(照合対象となる固定ドメインがないため)はないので、事実確認済みの出力ではなく、スキーマに準拠した出力を返します。validation_warningsは常に[]です。呼び出し元のスキーマには上限があり(6000 文字以下、深さ 4 以下、各階層のプロパティ 30 個以下、$refは不可)、モデル呼び出し前に 400 エラーとして拒否されます。x402 はエラー以外のレスポンスでのみ決済を確定するため、この時点では費用はかかりません。file(固定ルートと同じバイナリー PDF/画像)またはcontent(呼び出し元がすでに持っているプレーンテキスト/HTML。たとえば、すでに取得済みのウェブページ。100,000 文字以下)のどちらか一方を受け付けます。両方は指定できません。テキスト/HTML の経路では、Claude に送信するプロンプト内でコンテンツを指示ではなくデータとして明示的にラベル付けします。これは任意の呼び出し元提供コンテンツであり、そうしないとプロンプトインジェクションの原因になり得るためです。src/lib/facilitator.ts— テストネットでは無料のデフォルト facilitator を選択し、メインネット(X402_NETWORK = "base")では、認証済みの Coinbase CDP facilitator に加えて、Bazaar と同等の探索対象を広げるため Mogami と PayAI を選択します(CDP は引き続き最初の優先 facilitator です。先に指定した facilitator が検証/決済で優先されます)。このプロジェクトの人間が読みやすいネットワーク名を、x402 v2 で使用される CAIP-2 識別子(eip155:8453など)に対応付けます。重要:src/index.tsは構築済みの決済ミドルウェアをモジュールスコープでキャッシュし、リクエストごとには再構築しません。複数の facilitator を使う場合、応答しない facilitator があるとinitialize()にそのタイムアウト分が丸ごと追加されるため、リクエストごとに再構築すると、そのコストがリクエストのたびに発生してしまいます(複数 facilitator を初めて試した際、これにより API 全体が機能しなくなりました)。キャッシュすることで、そのコストがかかるのは、コールド状態の isolate の最初のリクエストだけになります。src/lib/discovery.ts— 4 つすべてのルートについて、Bazaar のリスティングコンテンツ(説明、タグ、探索用拡張(スキーマ+実例))を定義します。src/index.ts— Cloudflare Workers 上で動作する Hono アプリです。@x402/honoのpaymentMiddlewareFromConfigが/extract/*を保護します。Workers では環境変数はモジュールの読み込み時ではなくリクエスト内でのみ公開されるため、Envバインディングからリクエストごとに構築されます。src/routes/extractHandler.ts— 抽出処理のみを行います。この処理が実行される時点で、決済の検証はすでに完了しています。mcp/server.ts— stdio MCP サーバーです。extract_invoice、extract_receipt、extract_contract、extract_resume、extract_customツールを公開します。各ツール呼び出しでは、WALLET_PRIVATE_KEYで指定されたウォレットから、実際の x402 決済に署名して送信します(@x402/fetchのwrapFetchWithPaymentを使用。scripts/test-payment.mjsと同じ仕組みです)。その後、ネットワーク経由で稼働中の HTTP API を呼び出します。抽出をローカルで実行したり、Claude を直接呼び出したりすることはありません。無料での利用手段はありません。ウォレットがない場合や残高が不足している場合は、API を直接呼び出したときと同じように失敗します。
元の仕様から意図的に変更した点
仕様ではPDF→画像への変換処理(pdf2image/poppler)を想定していました。Cloudflare Workersではネイティブバイナリを実行できず、ClaudeのMessages APIはPDFをdocumentコンテンツブロックとしてネイティブに受け付けるため、PDFはそのままClaudeに送信します。これにより、パイプラインの工程全体と、いずれにせよWorkersでは実行できない依存関係を取り除けます。
セットアップ
cd "doc-extract-api"
npm install
1. シークレット
ローカル開発の場合は、.dev.vars.exampleを.dev.varsにコピーし、実際のキーを入力します(Gitの追跡対象外です)。
cp .dev.vars.example .dev.vars
本番環境:
npx wrangler secret put ANTHROPIC_API_KEY
2. ウォレット — 支払いの受取先
wrangler.tomlを編集します。実際の支払いを受け取るには、X402_PAY_TO_ADDRESSにご自身が管理する実際のウォレットアドレスを設定する必要があります。これは公開用の受取アドレス(銀行口座番号と同じように、安全にコミットできます)です。このプロジェクト内のどこにも秘密鍵を入れないでください。
X402_NETWORKのデフォルトはbase-sepolia(テストネットです。フォーセットから無料のテスト用USDCを取得できます。実際のお金を一切リスクにさらさずに、フロー全体を検証するのに適しています)です。
料金は共通ではなく、ルートごとに設定します:X402_INVOICE_PRICE、X402_RECEIPT_PRICE、X402_CONTRACT_PRICE、X402_RESUME_PRICE、X402_CUSTOM_PRICE。デフォルト値は、各カテゴリで確認済みの競合サービスのうち、現在最も低い料金に合わせています。上記のポジショニングに関する注記を参照してください。
2b. メインネットへの移行(X402_NETWORK = "base")
無料のデフォルトのファシリテーター(x402.org/facilitator。テストネットでは自動的に使用されます)はテストネットのみをサポートしています。メインネットでは、認証済みのファシリテーターが必要です。このプロジェクトでは、CoinbaseのCDPファシリテーター(src/lib/facilitator.ts)を利用できます。
- CDP Portalのアカウントを作成し、「Project → API Keys」でSecret API Keyを作成します。
npx wrangler secret put CDP_API_KEY_IDnpx wrangler secret put CDP_API_KEY_SECRETwrangler.tomlでX402_NETWORK = "base"を設定し、再デプロイします。
料金:決済済みトランザクションは月あたり約1,000件まで無料で、それ以降は1件あたり$0.001です。支払いの検証自体は常に無料です。X402_NETWORKが"base"に設定されていて、これらのシークレットが設定されていない場合、支払いが誤って設定されても気づかないままになるのではなく、ファシリテーターの設定時にリクエストが明確に失敗します。
Bazaarに掲載するには、メインネットで少なくとも1件の実際の支払いを完了させる必要があります。ファシリテーターは、bazaar拡張を含む支払いを初めて処理したときに、そのリソースをカタログに登録します。これを実行するには、実際に資金を入れたウォレットを使ってscripts/test-payment.mjsを一度実行します(下記参照)。その後、次のコマンドで確認します。
curl -s "https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources?limit=200" \
| grep -o 'doc-extract-api'
3. エンドツーエンドの支払いテスト(scripts/test-payment.mjs)
実際の自律型エージェントをシミュレートします。使い捨てウォレットを生成または使用し、x402 v2経由で支払い、稼働中のAPIを呼び出します。まずテストウォレットに資金を入れてください。無料で試す場合は、フォーセット(例:faucet.circle.com、Base Sepolia)からテストネット用USDCを取得します。X402_NETWORKが"base"の場合は、Base上の実際のUSDCを少額用意してください。
node scripts/gen-test-wallet.mjs # prints a fresh throwaway private key + address
TEST_WALLET_PRIVATE_KEY=0x... node scripts/test-payment.mjs
決済の詳細と、受取人のUSDC残高の支払い前後の値が表示されます。Base Sepolia(テストネット)とBaseメインネットの両方で、実際のUSDCを使ってエンドツーエンドでの動作を確認済みです。
4. ローカルで実行
npm run dev
curl -X POST http://localhost:8787/extract/invoice -F "file=@/path/to/invoice.pdf"
# → 402 Payment Required; full payment + discovery manifest in the PAYMENT-REQUIRED header
/extract/customは、schemaフィールド(type: "object"を指定したJSON Schema文字列)、任意のinstructionsフィールド、およびfile(バイナリ)またはcontent(生のテキスト/HTML)のいずれか一方を受け取ります。
curl -X POST http://localhost:8787/extract/custom \
-F "file=@/path/to/doc.pdf" \
-F 'schema={"type":"object","properties":{"order_id":{"type":"string"},"ship_date":{"type":"string"}}}' \
-F "instructions=Dates in YYYY-MM-DD"
すでにある生のテキスト/HTMLから処理する場合は、ファイルは不要です。
curl -X POST http://localhost:8787/extract/custom \
-F "content=<html><body><h1>Acme Corp</h1><p>Founded 1998, HQ in Austin, TX</p></body></html>" \
-F 'schema={"type":"object","properties":{"company":{"type":"string"},"founded":{"type":"number"},"hq":{"type":"string"}}}'
実際の呼び出し元では、x402対応のHTTPクライアント(エージェント側の@x402/fetchなど)を使用します。このクライアントが、402 → 支払いへの署名 → 再試行のループを自動的に処理します。
5. デプロイ
npm run deploy
6. MCP サーバー(有料、エージェントでの利用)
export WALLET_PRIVATE_KEY=0x... # a wallet funded with real USDC on Base — every call spends from it
npm run mcp
公開後は、MCPクライアントからこのリポジトリをクローンせずに直接実行できます。
npx doc-extract-api-mcp
MCP対応クライアントからこのstdioサーバーに接続すると、extract_invoice、extract_receipt、extract_contract、extract_resume、extract_customがツールとして公開されます。すべての呼び出しで、x402を介してネットワーク経由で稼働中のAPIに支払います。ローカルでの無料の抽出方法はありません。また、クライアント側でANTHROPIC_API_KEYを用意する必要もありません(キーはサーバー側で保持され、呼び出し元に必要なのは資金を入れたウォレットだけです)。
未対応
- 履歴書には実際の個人情報(氏名、連絡先、職歴)が含まれます。レスポンスが返された後にデータが保存されることはありません(ここにある他のすべてのドキュメントタイプと同様です)が、情報の機微性を考慮し、改めて記載しておく価値があります。
src/lib/discovery.tsの履歴書の説明を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。