space ocr Claude スキルで、ドキュメントを構造化・検索可能なデータにする
Claude Code プラグインの space ocr スキルで、請求書などのドキュメント画像を位置情報付きの構造化データに変換し、シートに溜めてクエリするまでを解説します。
これは何か — ドキュメントを「構造化された位置付きデータ」に変える Claude スキル
space ocr は Claude スキルのひとつで、Claude Code プラグインとして配布されます。一度インストールすると、アシスタント(Claude Code)が請求書・領収書・名刺・身分証・各種フォームといったドキュメント画像を読み取り、構造化されたフィールド として取り出せるようになります。読み取りは space ocr の REST API(https://api.space-ocr.com)経由で行われます。
よくある「画像を貼り付けて、それらしい答えを期待する」やり方とは性質が違います。画像をそのままモデルに渡す方式では、値がどこから来たのか追跡できず、毎回プロンプトに画像を詰め直すことになります。一方で、自前で OCR エンジンとデータベースを立ち上げる方式は、抽出パイプライン・ストレージ・検索層をそれぞれ構築・運用する手間がかかります。space ocr はその中間を埋めます。抽出も保管もクエリも API 側が受け持ち、手元には標準ライブラリだけで動く Python スクリプトが 1 本あるだけです。
もうひとつの特徴は、返ってくる値がすべて、ページ上の正確な位置情報を伴う 点です。各フィールドには 4 点のバウンディングボックスが付きます。これは LLM の推測ではなく、Vision API が検出した実際のシンボルに再アンカーされ、0〜1000 に正規化されたグリッド上の座標として返されます。値を引用し、根拠を確認できる — Web ダッシュボードはこのボックスをドキュメント上に重ねて描画します。
インストール — Claude Code 上の 2 つのスラッシュコマンド
インストールは Claude Code の中で完結します。まずマーケットプレイスを登録し、続いてスキルをインストールします。この 2 行は一度だけ実行すればよく、以降は Claude Code がスキルを使えるようになります。
1 行目でスキルの配布元マーケットプレイスを Claude Code に追加し、2 行目で space-ocr スキルを実際にインストールします。pip での追加インストールや、別途サーバを起動する手順はありません。
/plugin marketplace add oisidonut/claude-space-ocr-skill
/plugin install space-ocr@space-ocrセットアップ — API キーと balance の 1 行確認
API キーは https://space-ocr.com の Settings → API Keys で発行します。新規アカウントには 100 スキャン分の無料枠 が付き、カード登録は不要です。発行したキー(spocr_ から始まる文字列)は、環境変数 SPACE_OCR_API_KEY で渡すか、.env ファイルに置きます。認証は HTTP ヘッダ Authorization: Bearer spocr_... で行われ、ベース URL は https://api.space-ocr.com です(必要なら SPACE_OCR_API_BASE で上書きできます)。
ランタイムは依存ゼロです。scripts/space_ocr.py という標準ライブラリのみの Python スクリプト 1 本で動き、必要なのは python3 だけです。SDK も MCP サーバもありません。すべてのコマンドは結果を JSON で標準出力に返します。
最初の確認は balance です。キーが正しく設定されているか、無料枠がどれだけ残っているかを 1 行で確かめられます。balance は無料枠の残り(free.remaining)、定額分(flatfee)、購入済み残高を表示します。読み取り系の操作なのでスキャンは消費しません。
export SPACE_OCR_API_KEY=spocr_xxx
python3 scripts/space_ocr.py balance1 枚のドキュメント — 組み込みテンプレートでフィールドを抽出
単一の画像から構造化フィールドを取り出すには ocr コマンドを使います。読み取りたいドキュメントの種類が分かっているなら、--template に組み込みテンプレートの ID を渡すのが最も確実です。たとえば請求書なら invoice を指定すると、その様式に合わせたフィールド一式が、それぞれの位置情報付きで返ります。
組み込みテンプレートには invoice、receipt、business_card、purchase_order、delivery、quote、bankbook、passport、driver_license、resident_card、my_number_card、residence_card などがあります。利用可能な一覧は templates コマンドで確認できます。
これら以外の様式を扱う場合は、2 通りの方法があります。ひとつは --fields <schema.json> で独自スキーマを与え、抜き出したいフィールドを自分で定義する方法。もうひとつは --auto で、エンジンに 4〜8 個のフィールドを推論させる方法です。--auto には拒否ゲートが設けられていて、構造のない画像・空の画像・横倒しの写真などはエラーを返し、フィールドをでっち上げません。失敗したスキャンは自動的に返金されます。
python3 scripts/space_ocr.py ocr invoice.jpg --template invoiceフォルダ単位のドキュメント → シート
ドキュメントが 1 枚を超えるなら、結果はシートに溜めるのが基本方針です。API 自体がストレージを兼ねており、フォルダ/シート/行という構造を持ちます。データベースもベクトルストアも構築せずに、処理済みドキュメントがそのままクエリ可能なワークスペースになります。
流れは 2 段階です。まず列を 1 度だけ定義してシートを作成し、次にそのシートへ画像を投入します。アップロードされた各画像はサーバ側で 非同期に OCR されるため、--wait を付けると全件の完了までブロックして待てます(待たずに job <JOB_ID> で進捗を追うこともできます)。1 回の OCR 呼び出し、または 1 枚のアップロードがそれぞれ 1 スキャンに相当します。
パスの扱いに 1 点だけ注意があります。 フォルダは表示名で指定できます(例: /invoices)。しかしシートやメモは、create が返す uniqueKey 形式のパス(例: /invoices/8G90wq...)で指定します。表示名ではありません。create の戻り値に出てくるこのパスを控えて、upload や query で再利用してください。
# 1) define the columns once, then create the sheet
python3 scripts/space_ocr.py create sheet /invoices "March" --columns columns.json
# -> returns a path like /invoices/8G90wq... (reuse this uniqueKey path)
# 2) drop every image in; OCR runs server-side (async), --wait blocks until done
python3 scripts/space_ocr.py upload /invoices/8G90wq... *.jpg --wait溜めた行から質問に答える
シートに行が入ったら、質問への回答は 保管済みの行から 行います。画像を OCR し直す必要はありません。query <SHEET> はサーバ側で --where/--sort/--limit を効かせられるため、絞り込み・並べ替え・件数制限をクライアントに全件取得してから処理するのではなく、API 側で済ませられます。
読み取り系の操作(view / query)はスキャンを消費しません。コストは 0 です。たとえば「合計が 40000 以上の請求書を、金額の降順で上位 20 件」といった問い合わせは、下のように 1 回のクエリで返ります。再 OCR せず、既存の行を答えにする — これがクォータと信頼性の両方を保つ要点です。
python3 scripts/space_ocr.py query /invoices/8G90wq... \
--where 'total>=40000' --sort total:desc --limit 20軽量さと信頼性を保つ 4 つのルール
このスキルの挙動は、次の 4 つのルールで定義されています。これに沿って使うことで、無駄なスキャン消費と根拠の追えない回答を避けられます。
- 溜める、垂れ流さない(Store, don't dump) — ドキュメントが 2 枚以上になったら、生の OCR JSON を貼り返すのではなく、シートに行として書き込む。
- スキャン前に確認(Check before you scan) — バッチ処理の前に
balanceを実行する。既に行があるなら再スキャンせず、その行を再利用する。 - 行から答える(Answer from stored rows) —
query <sheet>をサーバ側の--where/--sort/--limitとともに使う。読み取りは無料。再 OCR しない。 - 位置を引用し、不確かさを示す(Cite the location, flag uncertainty) — すべての値には
field_bboxesの位置情報がある。値はできるだけ印字どおりに逐語抽出する(正規化や計算をすると、ボックスがずれる)。
なお、冪等性も用意されています。/ocr/fields とアップロードは Idempotency-Key を受け付け、同じキーで再試行するとキャッシュ済みの結果が再生され、二重課金は発生しません。失敗したスキャンは自動返金されます。
検証可能性について(verified) — 返される各値には 4 点のバウンディングボックスが付きます。これは LLM の推測ではなく、Vision API が検出した実シンボルに再アンカーされ、0〜1000 に正規化されたグリッド上の座標として与えられます。そのため、値は引用でき、根拠をページ上で確認できます(Web ダッシュボードはこのボックスをドキュメント上に描画します)。値を逐語のまま抜き出す(正規化・計算しない)ことで、ボックスは正しい位置に留まります。
まとめ
インストールは Claude Code の 2 行、ランタイムは標準ライブラリのみの Python スクリプト 1 本、ストレージとクエリは API 側 — これだけで、ドキュメントを位置情報付きの構造化データに変え、データベースを別途構えることなく問い合わせられます。1 枚なら ocr、複数枚なら create sheet → upload --wait → query の流れを基本形として覚えておくと迷いません。