Skip to main content
Glama

ドキュメント変換API

PDF/Officeドキュメントと構造化JSONの間を双方向に変換します。NEXUS候補 #6 -- 手動ビルド、FORGE生成ではない。候補 #3 (agent-verification-api) と候補 #4 (url-metadata-api) と同じ手動Cloud Runアセットパターンに従います。

  • POST /extract-pdf-to-json -- テキスト、テーブル(ページごと)、ページ数、メタデータ。$0.02/呼び出し。

  • POST /extract-docx-to-json -- 段落(見出しレベル/スタイル付き)、テーブル、メタデータ。$0.01/呼び出し。

  • POST /extract-xlsx-to-json -- シートごとのセルグリッド、行/列の上限付き。$0.01/呼び出し。

  • POST /generate-pdf-from-json -- 構造化ブロック(見出し/段落/テーブル)-> PDFバイト。$0.02/呼び出し。

  • POST /generate-docx-from-json -- 構造化ブロック -> .docxバイト。$0.01/呼び出し。

  • /mcp のMCPツールは5つすべてをミラーリング -- 現在無料、「既知の制限」を参照。

  • GET /health、GET /.well-known/agent-card.json、GET /openapi.json(x-payment-info を含む)。

5つのエンドポイントはすべて、base64エンコードされたファイルバイトをリクエストボディに直接受け取ります -- 取得するURLは決してありません。これは意図的なスコープ境界です:このアセットのリスク面からSSRFを完全に排除します(url-metadata-api/agent-verification-api とは異なり、両者は呼び出し元が指定したURLを取得し、SSRFガードが必要です)。

なぜこれらのライブラリなのか、なぜ外部データソースがないのか

純粋なOSS、成熟済み、LLM呼び出しなし、実行時の外部ネットワーク呼び出しゼロ(完全にローカル計算):pdfplumber(PDF抽出、pdfminer.six をラップ)、python-docx(Word)、openpyxl(Excel)、reportlab(PDF生成)。このアセットには名前付きのサードパーティデータソースは一切ありません -- 意図的に、BuyWhereスタイルの幻覚リスク(skills/asset-lifecycle)を避けるためです:外部に間違えるものはなく、製品全体は「呼び出し元が送信したバイトに対して既知のライブラリを実行する」だけです。numpy/scipyは使用しません(既知のCloud Run Buildpacksの失敗を回避 -- scipyのソースビルド用のFortranコンパイラがないため -- skills/infra-deploy-ops を参照;これらのライブラリはどれも必要としません)。

Related MCP server: docxtpl MCP Server

なぜ $0.01-$0.02 なのか(agent-verification-api の $0.35、url-metadata-api の $0.01 と比較して)

ここには有料のサードパーティAPIコストはありません(live-entity-verification/agent-verification-api のWHOISとは異なります)-- 純粋なCPU/メモリコストなので、url-metadata-api の $0.01 シングルフェッチと同じ低い層に位置し、agent-verification-api の $0.35 には到底及びません。PDF操作(extract-pdf-to-json、generate-pdf-from-json)は、docx/xlsx($0.01)よりも一段高い価格($0.02)です:pdfplumber/reportlab は、python-docx/openpyxl(zipアーカイブの単純なXML解析)よりも呼び出しごとにはるかに多くの作業(ページレベルのレイアウト解析 / PDFレンダリング)を行います。このアセットは、3つの手動候補の中で最も予測可能であり、トップの収益源ではないと期待されています -- ドキュメント変換は一般的で低分散のエージェントニーズであり、差別化された/稀な能力ではありません -- そのため、価格設定は呼び出しごとのマージンよりも一貫した低摩擦の使用を優先します。

このアセットが他の3つの手動アセットにはない2つのリスク

  1. CPUバウンドであり、I/Oバウンドではない。 すべてのパーサー/ジェネレーター呼び出しは同期です(4つのライブラリのいずれにも非同期APIはありません)。他の3つのアセットは httpx.AsyncClient を介してI/Oバウンドであるのとは異なります。各ハンドラーは、asyncio.wait_for() タイムアウト(25秒)内で asyncio.to_thread() を介して実際の作業をオフロードするため、1つの呼び出し元の遅い解析がイベントループ全体/すべての同時リクエストをブロックすることはありません。 既知の残存制限: asyncio.wait_for() は 待機中の タスクをキャンセルしますが、基になるOSスレッドを強制終了することはできません -- Pythonには実行中のスレッドを強制終了するAPIがありません。pdfminer/openpyxl を内部的にハングさせる病的な入力は、呼び出し元が504を受け取った後でも、その1つのワーカースレッドを無期限に占有し続けます。緩和はされていますが、解決はされていません:制限付きセマフォ(NEXUS_MAX_CONCURRENT_JOBS、デフォルト4)は、そのような「リークした」スレッドが同時に蓄積できる数を制限します -- 新しいリクエストは無制限のスレッド増加ではなくクリーンな503を受け取りますが、すでにリークしたスレッドは決して回収されません。完全な修正には、CPUバウンドの作業をスレッドではなく、分離された強制終了可能なプロセス(ProcessPoolExecutor + ハードターミネート)で行う必要があります;7日間の試用候補には過大なため、ここでは行いません。

  2. 解凍爆弾 / リソース枯渇。 .docx/.xlsx はzipアーカイブです -- 圧縮サイズは小さいが非圧縮サイズが巨大な細工されたファイル(zip爆弾)は、他の3つのアセットが直面するものとは異なる実際のDoSベクトルです。_check_zip_bomb_safe() は、バイトを python-docx/openpyxl に渡す前に、zip中央ディレクトリ(zipfile.infolist()、安価で、エントリデータを解凍しない)を検査します:非圧縮サイズの合計が50MBを超える場合、または単一エントリの圧縮率が100倍を超える場合に拒否します。すべてのアップロードは、解析前に生/デコード済みバイトで8MBに制限されています(PDFも含まれます。zipベースではありませんが、形式に関係なく最悪の入力サイズを制限します)。

既知の制限(意図的に未修正 -- CLAUDE.md §3、必要という証拠なしにゲートを設けない)

  • MCPツール呼び出しは課金されません。 兄弟の手動アセットと同じインプロセス呼び出しパターン(および同じ理由):MCPツールは共有変換関数を直接呼び出し、ASGIアプリへのHTTP再エントリは行いません。

  • 呼び出し元ごとのレート制限はありません。 7日間の使い捨て測定には問題ありません;生き残るなら追加します。

  • 生成されたドキュメントは、ローカルでスモークテストされた範囲を超えてラウンドトリップの忠実性が検証されていません -- reportlab のテーブル/段落レンダリングと python-docx の見出しレベルマッピングはどちらも成熟した広く使用されているコードパスであり、ここで考えられるすべてのOffice/PDFリーダーに対して再検証されていません。

  • スレッドリークの残存制限については、上記の「CPUバウンド」リスクを参照してください。

NEXUS_X402_FREE_MODE

similarity-search-api/live-entity-verification(skills/x402-payments)と同じゲートパターン -- デフォルトは false(初日から課金、フリーミアム期間なし;エンジンには live-entity-verification のWHOISベースのエンジンが持っていたような外部検証依存関係がないため、有料に直接スキップするための同等の「本番で実証済み」という議論はありません -- それでも課金されます。セッションブリーフの「中程度で安定した」収益フレーミングによるもので、特定の前例によるものではありません)。実際のファシリテーターのラウンドトリップなしでテストするには、ローカルで true に設定します。

デプロイ先: Cloud Run、Railwayではない

候補 #3/#4 と同じパイプライン -- skills/infra-deploy-ops を参照。メモリを1Giに増量(共有 scripts/deploy_cloud_run.sh のハードコードされた512Miデフォルトと比較)-- これは3つの手動候補の中で最もメモリを消費します(PDF/Office解析ライブラリ、pdfplumber を介して推移的に pypdfium2/Pillow)。gcloud run deploy で直接デプロイされます(共有スクリプトは使用せず、1候補のメモリ増量のために共有インフラツールを編集しないようにするため):

# 1. First deploy -- PUBLIC_DOMAIN not known yet, every real request 421s until step 2.
gcloud run deploy document-conversion-api \
  --source manual_assets/document-conversion-api \
  --project nexus-505016 --region us-central1 \
  --allow-unauthenticated --min-instances=0 --max-instances=3 --memory=1Gi --quiet \
  --env-vars-file manual_assets/document-conversion-api/env-vars.deploy.yaml

# 2. Grab the printed *.run.app URL, then:
gcloud run services update document-conversion-api --region us-central1 --project nexus-505016 \
    --update-env-vars PUBLIC_DOMAIN=<the-real-domain>

測定(候補 #6、7日間ウィンドウ)

最初の本番デプロイから7日間のウィンドウ。真実のソース:traffic_events/revenue_events/mcp_call_events テーブル(asset_name = 'document-conversion-api')、Cloud Runログではありません。7日目:実際のトラフィックがゼロの場合(クローラーをフィルタリング)、Cloud Runサービスを一時停止/削除します。候補 #3/#4 と同じ決定ルールです。

Related MCP Connectors

Related MCP Servers