●2.1.283 — 週末の Claude Code リリースはなく、最新は 9月25日の 2.1.283 のまま。権限モード未設定時の既定が auto に変わった点は、許可ルールとの照合が要ります●PLANS — Pro と Team Standard の既定モデルが Sonnet から Opus へ。Claude Code 2.1.280 の変更で、プラン選びの前提が変わっています●10/07 — Claude Desktop / Cowork の管理構成キー旧綴りの受付終了まで残り9日。締切後は読み込みが fail-closed になります●AUTO — 「許可ルールに書いたコマンドが auto モードで拒否される」という問いが出ています。呼ぶ形を許可ルールに揃える話題です●NEW — 既定の Opus が 5.5 に変わった週、別名のまま残していた3箇所の確認●CURSOR — Cursor 経由で Claude を使うとクレジットがモデル原価に比例して減る構造。1日50件を超えるなら定額の Claude Code Pro が安定という整理が出ています●2.1.283 — 週末の Claude Code リリースはなく、最新は 9月25日の 2.1.283 のまま。権限モード未設定時の既定が auto に変わった点は、許可ルールとの照合が要ります●PLANS — Pro と Team Standard の既定モデルが Sonnet から Opus へ。Claude Code 2.1.280 の変更で、プラン選びの前提が変わっています●10/07 — Claude Desktop / Cowork の管理構成キー旧綴りの受付終了まで残り9日。締切後は読み込みが fail-closed になります●AUTO — 「許可ルールに書いたコマンドが auto モードで拒否される」という問いが出ています。呼ぶ形を許可ルールに揃える話題です●NEW — 既定の Opus が 5.5 に変わった週、別名のまま残していた3箇所の確認●CURSOR — Cursor 経由で Claude を使うとクレジットがモデル原価に比例して減る構造。1日50件を超えるなら定額の Claude Code Pro が安定という整理が出ています
def list_articles_tool(cursor: str | None = None, limit: int = 20): after_p, after_i = (decode_cursor(cursor) if cursor else (None, None)) rows = list_articles_cursor(after_p, after_i, limit) has_more = len(rows) > limit page = rows[:limit] next_cursor = ( encode_cursor(page[-1]["published_at"], page[-1]["id"]) if has_more and page else None ) total = db.scalar( "SELECT COUNT(*) FROM articles WHERE status = 'published'" ) return { "items": [ {"slug": r["slug"], "title": r["title"], "category": r["category"], "published_at": r["published_at"]} for r in page ], "page_size": len(page), "has_more": has_more, "next_cursor": next_cursor, "total_published": total, "hint": ( f"全{total}件中の最新{len(page)}件です。" "さらに古い記事が必要な場合のみ next_cursor を渡して再呼び出ししてください。" ), }
hint フィールドは地味ですが効きます。エージェントは「全400件中の最新20件」と明示されれば、たいていの場合そこで止まります。続きを取りに行くのは、本当に古い記事を探しているときだけになります。実際にこのヒントを入れてから、平均のページ取得回数は1呼び出しあたり2.1回から1.3回に下がりました。無駄なフェッチが減った分、コンテキストもさらに軽くなります。
MCPツールとして公開するときのスキーマ
Claude にツールとして見せるときは、入力スキーマを最小限にします。cursor は任意、limit には上限を設けて、エージェントが limit: 5000 のような無茶を投げてもサーバ側で頭打ちにします。
第二に、total を返すかどうかは慎重に決める価値があります。COUNT(*) は件数が増えると地味に重く、巨大テーブルではページ取得そのものより遅くなる場面があります。私は概算で構わない一覧では total を省き、has_more だけで運用しています。正確な総数が要る画面用APIとは、ツールを分けました。
第三に、カーソルの寿命です。署名付きカーソルは原理上いつまでも有効ですが、ソートキーのスキーマを変えた瞬間に k の不一致で全カーソルが無効になります。スケジュールタスクが古いカーソルを握ったまま再開すると、そこで例外が出ます。私は decode_cursor の失敗時に黙って先頭から取り直す挙動にして、エージェントが止まらないようにしました。例外を握りつぶすのは普段は避けたい判断ですが、ここは「止まらないこと」を優先しています。