Claude Codeでkintone取得をカーソルAPIに書き換える
kintoneの一括取得が500件・offset 1万件で止まるときの書き換え手順。カーソルの作成・取得・削除を実装し、Claude Codeへの依頼文とCLAUDE.mdの置き方まで示します。
kintoneのレコード一括取得は、GET /k/v1/records.json を limit と offset で回す書き方だと、数千件から先で行き詰まります。1回で取れるのは500件まで、offset の上限は10,000件です。この壁を越える公式の手段が「カーソル」で、カーソルを作り、next が false になるまで取得を繰り返す形に書き換えます。
この記事では、既存の取得ループをClaude Codeにカーソル方式へ書き換えさせる手順を、依頼文・実装例・検証・CLAUDE.mdの置き方の順に示します。
500件と1万件の壁はどこにあるか
レコード取得APIの仕様ページには、制限が2つ書かれています。
records.json の取得上限
1回の取得
500件
queryのlimitで指定。初期値は100件
offsetの上限
10,000件
これを超える位置は指定できない
limit 500 offset 9500 が最後の窓になり、10,000件目より後ろは offset では読めません。日付で期間を区切って複数回に分ける回避もありますが、区切りの設計が要り、更新が重なると取りこぼしも出ます。カーソルは、その区切り設計を不要にします。
Claude Code経由のMCP連携では、取得件数の上限がこの仕様に従うことをkintoneレコード検索・更新をClaudeで効率化する方法でも触れています。本記事は、MCPではなく自前のスクリプトで大量取得する側の話です。
カーソルAPIは3つで1組
カーソル関連のAPIは、作成・取得・削除の3つです。いずれもURLは /k/v1/records/cursor.json で、HTTPメソッドで役割が分かれます。
| 操作 | メソッド | 渡すもの | 返るもの |
|---|---|---|---|
| カーソルを作成 | メソッドPOST | 渡すものapp・fields・query・size | 返るものid・totalCount |
| カーソルから取得 | メソッドGET | 渡すものid | 返るものrecords・next |
| カーソルを削除 | メソッドDELETE | 渡すものid | 返るもの空のオブジェクト |
作成時の size は1回の取得件数で、1〜500を指定できます。省略すると100です。query には絞り込みと並び順を書けますが、limit と offset は指定できません。totalCount は取得対象の総件数なので、最後に件数照合へ使えます。
取得は next が true の間、同じカーソルIDで繰り返します。false になったら全件取得済みで、その時点でカーソルは自動的に削除されます。
書き換えで踏みやすい制限
仕様ページの制限事項から、実装に直結するものを拾います。
カーソルの制限
同時に10個まで
有効なカーソルは1ドメインあたり10個までです。上限に達すると、既存カーソルが全件取得を終える・削除される・期限切れになるまで新しいカーソルを作れません。
有効期限は10分
期限は、カーソルを作成した、またはカーソルから取得した最後の時刻から10分です。取得の合間に長い処理を挟むと、カーソルが切れます。
作成は直列、5分で打ち切り
カーソルを並行して作成することはできず、作成リクエストが実行中なら次のリクエストは待たされます。作成自体は5分でタイムアウトします。
取得結果の読み方にも注意点があります。カーソルから取れるレコードは、作成時点で対象だったレコードです。ただしフィールドの値は、取得APIを実行した時点の値が返ります。また、next が true でも次のリクエストの records が空になることがあるため、「空配列なら終了」という判定は使えません。終了は next だけで決めます。
Claude Codeに渡す依頼文
既存コードがある場合は、現状の取得ループを読ませたうえで、守る条件を先に並べると手戻りが減ります。
src/kintone/exportRecords.ts の取得処理を、records.json の
limit/offset ループから、カーソルAPI(作成→取得→削除)に書き換えてください。
条件:
- 終了判定は next のみ。空配列では終了しない
- 取得途中で例外が出たら、カーソルを DELETE で削除してから再スロー
- 取得件数と、作成時に返る totalCount が一致しなければエラーにする
- APIトークンは環境変数 KINTONE_API_TOKEN から読む。コードに書かない
- 既存のテストが通ることを確認し、ネットワークを使わない単体テストを足す「例外時にカーソルを消す」を明示するのは、10個の枠を使い切ると新しいカーソルが作れなくなるためです。落ちたスクリプトが残したカーソルは、期限の10分が過ぎるまで枠を占めます。
実装例
次の形が、公式のAPI仕様をそのまま3段に分けた骨格です。Claude Codeに書かせた結果も、構造はこれに近い形に収束させるのが目安になります。next の判定と、失敗時の削除がポイントです。
// src/kintone/exportRecords.ts
const BASE = process.env.KINTONE_BASE_URL; // 例: https://example.cybozu.com
const TOKEN = process.env.KINTONE_API_TOKEN;
const HEADERS = { "X-Cybozu-API-Token": TOKEN!, "Content-Type": "application/json" };
async function call(method: string, path: string, body?: object) {
const res = await fetch(`${BASE}/k/v1/${path}`, {
method, headers: HEADERS, body: body ? JSON.stringify(body) : undefined,
});
if (!res.ok) throw new Error(`${method} ${path}: ${res.status} ${await res.text()}`);
return res.json();
}
export async function exportAll(app: number, query: string) {
const cursor = await call("POST", "records/cursor.json", {
app, query, size: 500,
});
const records: unknown[] = [];
let finished = false;
try {
while (!finished) {
const id = encodeURIComponent(cursor.id);
const page = await call("GET", `records/cursor.json?id=${id}`);
records.push(...page.records);
finished = !page.next; // 空配列では終わらせない
}
} catch (e) {
await call("DELETE", "records/cursor.json", { id: cursor.id }).catch(() => {});
throw e;
}
if (records.length !== Number(cursor.totalCount)) {
throw new Error(`件数不一致: ${records.length} / ${cursor.totalCount}`);
}
return records;
}totalCount は文字列で返るため、Number() で比べています。全件取得後はカーソルが自動で消えるので、正常終了時に DELETE は呼びません。
並び順は query の order by レコード番号 asc のように明示しておくと、再実行時に結果の順序が揃います。fields で必要なフィールドコードだけに絞れば、転送量も減ります。
検証をClaude Codeに回させる
書き換えの正しさは、実APIに繋がなくても大半を確かめられます。fetch を差し替えたテストで、次の3つの挙動を固定します。
next: trueのあとに空のrecordsが返っても、続けて次を取りにいく- 2ページ目で例外を起こすと、
DELETEが1回呼ばれる - 取得合計が
totalCountと食い違うとエラーになる
そのうえで、検証用のアプリ(本番ではないもの)に対して一度実行させ、件数の照合結果を読ませます。
KINTONE_BASE_URL=https://example.cybozu.com \
KINTONE_API_TOKEN=xxxx \
npx tsx scripts/export-check.ts --app 12出力された取得件数と、kintone側のレコード一覧の件数が合うかを確かめます。1万件を超えるアプリで一度通っておくと、offset 方式では届かなかった範囲まで読めていることが分かります。
CLAUDE.mdに書く内容と置き場所
同じ指示を毎回依頼文に書くより、CLAUDE.mdに残すほうが安定します。公式のメモリのページは、CLAUDE.mdに書く指示を「検証できる具体さ」にするよう求めています。「正しく取得する」ではなく、条件を数値や手順で書きます。
# kintone連携の規約
- レコードの一括取得は records.json の offset を使わず、カーソルAPIを使う
- カーソルは1ドメインで同時に10個まで。例外時は必ず DELETE する
- 取得の終了判定は next のみ。空配列を終了条件にしない
- 作成時の totalCount と取得件数を照合する
- 取得テストは fetch を差し替えて実行し、本番アプリには接続しない
- APIトークンは KINTONE_API_TOKEN から読み、コードや出力に書かない置き場所は、全体の規約ならプロジェクトのCLAUDE.mdです。公式の目安は、1ファイル200行未満に収めることです。それ以上に長くなる場合や、特定のフォルダーだけに効かせたい場合は、.claude/rules/ にパス指定付きのルールとして分けます。
---
paths:
- "src/kintone/**/*.ts"
---
# kintone連携の規約
- 一括取得はカーソルAPIを使う(records.json の offset は使わない)
- 例外時はカーソルを DELETE するpaths を持つルールは、Claudeが該当パスのファイルを読む・書く・編集するときに読み込まれます。kintone連携のコードを触らない作業では文脈に入らないため、他の作業の邪魔になりません。
CLAUDE.mdはシステムプロンプトではなく、会話の先頭に渡される文脈です。厳密な強制ではないので、「必ず例外時に削除する」といった守らせたい点は、テストでも縛っておく二重の構えが向いています。
認証・権限・ゲストスペースの扱い
カーソルの3つのAPIは、パスワード認証・APIトークン認証・セッション認証のいずれでも呼べます。スクリプトからの定期取得ならAPIトークンが扱いやすい方法です。必要なアクセス権は、アプリのレコード閲覧権限、対象レコードの閲覧権限、取得するフィールドの閲覧権限の3つです。
ゲストスペース内のアプリを対象にする場合は、URLが /k/guest/GUEST_SPACE_ID/v1/records/cursor.json の形になります。通常の /k/v1/ のままでは届かないため、依頼文に「ゲストスペースのアプリか」を書いておくと、基底URLの組み立てを取り違えにくくなります。
APIトークンはコードや会話に貼らず、環境変数で渡します。
全件取得か、差分取得か
カーソルは全件を読む手段ですが、毎回全件を取り直す必要があるとは限りません。query には絞り込み条件を書けるので、更新日時で区切れば日次の差分取得にも使えます。
更新日時 > "2026-10-27T00:00:00+0900" order by 更新日時 asc差分にする場合も、カーソルの扱いは同じです。作成時の totalCount が前日までの取り込み済み件数と食い違わないかを見る、といった使い方もできます。全件を読む初回だけカーソルで取り込み、以降は差分条件で回す構成にしておくと、10個の枠や10分の期限に当たる機会も減ります。依頼文に「初回は全件、以降は更新日時の差分」と書けば、取得関数に条件を引数として渡す設計に誘導できます。
なお、取得途中でレコードが更新されても、カーソルの対象は作成時点のレコードのままです。差分取得の基準時刻は、カーソルを作った時刻で記録しておくと、次回の条件に重なりや抜けが出にくくなります。
よくあるつまずき
落とし穴
カーソルが残って新しく作れなくなる
途中で落ちたスクリプトのカーソルは、最後に触ってから10分間は枠を占めます。10個を超えるとカーソル作成が失敗するので、手元で再実行を繰り返すと詰まります。失敗時の DELETE と、少し待ってからの再実行を組み込みます。
- 取得の合間に重い処理を挟む: 1ページ取るたびに外部APIを呼ぶような処理は、10分の期限に当たりやすくなります。いったん全件をメモリやファイルに受けてから加工します。
- 権限の差で件数がずれる: カーソルの作成後にアクセス権の設定が変わると、変更後の条件では対象外のレコードが取れることがあります。閲覧権限のないフィールドの値は取れません。
- like検索を絞り込みに使う: キーワード検索(
like)は、該当が100,000件に達した時点で検索が打ち切られ、レスポンスヘッダーにX-Cybozu-Warningが付きます。件数照合で気づけるよう、totalCountの確認は残します。
書き換えの前に取得単位を整理する方法として、同じ「カーソルで読む」考え方を一般のAPI設計で扱ったClaude Codeでカーソルページネーションを実装する手順も参考になります。MCPサーバー側の仕様はMCPのページネーション仕様にあります。kintoneとClaude Codeの接続そのものはClaude Codeとkintoneの連携ガイドにまとめています。
まとめ
kintoneの大量取得は、offset を伸ばすのではなく、カーソルの作成・取得・削除の3段に分けるのが筋です。依頼文には「終了は next のみ」「例外時は DELETE」「totalCount と照合」の3条件を入れ、同じ内容をCLAUDE.mdか .claude/rules/ に残します。実APIでの検証は、1万件を超えるテスト用アプリで1回通せば足ります。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。