[{"data":1,"prerenderedAt":500},["ShallowReactive",2],{"content-/kindle-screenshot-extension-yomitoku-pipeline":3,"all-pages-for-dir":498,"og-image-/kindle-screenshot-extension-yomitoku-pipeline":499},{"id":4,"title":5,"body":6,"category":480,"description":481,"extension":482,"meta":483,"navigation":424,"ogImage":484,"path":485,"project_name":442,"published":486,"publishedAt":487,"seo":488,"stem":489,"tags":490,"todo":484,"unpublished":486,"updatedAt":484,"__hash__":497},"pages/2026-06/2026-06-17/kindle-screenshot-extension-yomitoku-pipeline.md","KindleをyomitokuパイプラインにつなぐChrome拡張の設計と試行錯誤",{"type":7,"value":8,"toc":460},"minimark",[9,14,23,34,37,41,44,69,76,80,87,109,120,142,156,159,163,166,169,172,175,179,197,207,214,218,221,226,241,245,254,257,261,268,283,286,290,293,297,308,327,345,349,360,363,366,410,413],[10,11,13],"h2",{"id":12},"出発点裁断できない本をどう取り込むか","出発点：裁断できない本をどう取り込むか",[15,16,17,18,22],"p",{},"book-knowledge-base には既に「読み解く」スラッシュコマンド（",[19,20,21],"code",{},"/yomitoku","）がある。裁断本をスキャンしたPDFを yomitoku に投げ、章節単位に分割して Turso に格納する流れだ。問題は、最近 Kindle で買った本がこのパイプラインに乗らないこと。Amazon の DRM がかかっていてPDFに落ちないから、裁断本と同じ前処理を踏めない。",[15,24,25,26,30,31,33],{},"そこで「",[27,28,29],"strong",{},"read.amazon.co.jp の Kindle Cloud Reader をスクショで巡回して、画像群を既存パイプラインに流せばいい","」という発想に切り替えた。OCRから先は ",[19,32,21],{}," がそのまま使える。前段の「画像を集めるところ」だけを新規で組めばよい。",[15,35,36],{},"朝のうちはこのアイデアを温めるだけのつもりだったが、気がついたら半日溶けていた。",[10,38,40],{"id":39},"採用方針c案ハイブリッドスラッシュコマンド-chrome拡張","採用方針：C案ハイブリッド（スラッシュコマンド × Chrome拡張）",[15,42,43],{},"最初に「スラッシュコマンド単体 vs Chrome拡張機能単体 vs ハイブリッド」の3案を並べた。比較した結果、ハイブリッドのC案で進めることにした。",[45,46,47,54,60],"ul",{},[48,49,50,53],"li",{},[27,51,52],{},"スラッシュコマンド単体",": Chrome DevTools MCP を使えばページめくり・スクショ・OCR 委譲まで一気通貫で書ける。会話で「○ページまで」「OCR込み/抜き」を毎回指示変更できる柔軟さがある。一方で、長時間のページ送りループを MCP セッションに張り付けて回すのは不安定になりがち。",[48,55,56,59],{},[27,57,58],{},"Chrome拡張機能単体",": アイコンクリックで起動、ブラウザ内のDOM操作とスクショに強い。ただし、保存先ディレクトリやページ数の指定をUIに毎回作り込まないと変更できない。",[48,61,62,65,66,68],{},[27,63,64],{},"C案ハイブリッド（採用）",": ① スラッシュコマンドで起動 → ② Chrome拡張機能が Kindle Reader のページめくりとスクショを担当 → ③ ダウンロードされた画像群を ",[19,67,21],{}," パイプラインに流して OCR/章節分割/Turso 登録。",[15,70,71,72,75],{},"C案を選んだのは、",[27,73,74],{},"動的な指示性（スラッシュコマンド側）とページ操作の安定性（拡張機能側）を両取りできる","から。Kindle のページめくりは拡張機能のバックグラウンドに任せて、スラッシュコマンドは前後の段取りだけ見る、という分業にした。",[10,77,79],{"id":78},"準備chrome-devtools-mcp-が朝から壊れていた","準備：Chrome DevTools MCP が朝から壊れていた",[15,81,82,83,86],{},"実装に入る前に Chrome DevTools MCP が動かない。",[19,84,85],{},"mcp__chrome-devtools__*"," のツールが一切ロードされない。ツール検索しても空振りする。",[15,88,89,92,93,96,97,100,101,104,105,108],{},[19,90,91],{},"~/.claude/rules/windows.md"," の「",[27,94,95],{},"最頻の詰まり","」に該当していた。9222 ポートで ",[19,98,99],{},"curl -s http://localhost:9222/json/version"," を叩くと壊れた残骸が返ってくる。壊れた残骸の9222リスナーが居座っているのが真因。本来は ",[19,102,103],{},"chrome.exe"," を全部落として temp profile + 9222 で起動し直し、",[19,106,107],{},"/mcp"," で chrome-devtools を reconnect すれば復活するはずだった。",[15,110,111,112,115,116,119],{},"ところがこの日は別の問題も重なっていた。",[19,113,114],{},".claude.json"," から ",[19,117,118],{},"chrome-devtools"," MCP の登録そのものが消えていた。バックアップ（3/21時点）を覗くと24箇所に書かれていたものが、現在は0件。3/21〜6/17 のどこかで設定ファイルが書き換えられて消えた、というのが正体だった。",[15,121,122,123,126,127,130,131,134,135,137,138,141],{},"仕方ないので ",[19,124,125],{},"claude mcp add"," で user スコープに再登録。Git Bash の MSYS パス変換で ",[19,128,129],{},"/c"," が ",[19,132,133],{},"C:/"," に化けて起動失敗するトラップにも引っかかったが、修正してリトライ。さらにこの先 ",[19,136,114],{}," が消えても気づけるよう、MCP サーバー設定だけ抽出して ",[19,139,140],{},"~/.claude/mcp-servers-snapshot.json"," として git 管理に入れた。",[15,143,144,145,148,149,152,153,155],{},"Chrome 149 stable で remote debugging を許可する方法も、ログイン済み Chrome に繋ぐために必要だった。",[19,146,147],{},"chrome://inspect/#remote-debugging"," で incoming debugging connections を Allow に切り替え、",[19,150,151],{},"--autoConnect"," 方式に変更。Claude Code を再起動してようやく ",[19,154,85],{}," が見えるようになった。",[15,157,158],{},"ここまでで午前中が終わった。",[10,160,162],{"id":161},"プローブkindle-cloud-reader-の-dom-を覗く","プローブ：Kindle Cloud Reader の DOM を覗く",[15,164,165],{},"復活した MCP で Kindle のタブに切り替えてスクショを撮ったところ、ちゃんと撮れた。ASIN/タイトル/Location/「Back to 309」（しおり）が DOM から取れることまで確認。",[15,167,168],{},"ArrowRight で 20→22 へ進む（+2/ページ）、ArrowLeft で 22→8→2 まで戻せる。先頭 Location 2 まで到達できたので、巡回の最小単位は動くことが分かった。",[15,170,171],{},"そこから先で UI ノイズ（「Back to 309」表示、下部スクロールバー）を CSS で隠してテスト撮影。クリーンな状態が取れたので、ここで「5ページ分連続で進めるループ」に入ろうとした矢先、設計議論に戻すことにした。",[15,173,174],{},"「ループは MCP セッションで回し続けるより、Chrome 拡張機能のバックグラウンドに任せた方が安定する」と判断したから。C案の本気の実装に切り替えた。",[10,176,178],{"id":177},"実装chrome-extension-kindle-を新規ディレクトリで切る","実装：chrome-extension-kindle を新規ディレクトリで切る",[15,180,181,184,185,188,189,192,193,196],{},[19,182,183],{},"C:\\Users\\numbe\\Git_repo\\chrome-extension-kindle"," を新規作成して git init。既存の ",[19,186,187],{},"chrome-extension-MF","（クラウド会計）や ",[19,190,191],{},"chrome-extension-x","（X/Twitter）と同じ命名規則に揃えた。Chrome 拡張機能は ",[27,194,195],{},"全て別々のリポジトリで管理"," している慣習に乗る形だ。",[15,198,199,200,203,204,206],{},"並列でファイル群を生成させた。manifest.json、popup.html、popup.js、content.js、background.js、offscreen.html/js、アイコン群。スラッシュコマンドは book-knowledge-base 側に ",[19,201,202],{},"/yomitoku-kindle"," として追加。既存 ",[19,205,21],{}," に画像群を渡すだけのアダプタに留めた。",[15,208,209,210,213],{},"popup.js の ",[19,211,212],{},"innerHTML"," を安全な DOM 構築に置き換える等の細かい修正は途中で挟んだが、骨格は数回のターンで揃った。",[10,215,217],{"id":216},"試行錯誤のフェーズ5つの壁にぶつかった","試行錯誤のフェーズ：5つの壁にぶつかった",[15,219,220],{},"ここからが本番で、E2E で動かそうとするたびに別の問題が顔を出した。",[222,223,225],"h3",{"id":224},"壁1-文字化けと位置-不明","壁1: 文字化けと「位置: 不明」",[15,227,228,229,232,233,236,237,240],{},"最初に動かした拡張機能は、ページ情報が「位置: 不明」になり、書名も文字化けしていた。原因を Chrome DevTools 経由で直接調査したら、",[27,230,231],{},"Kindle Cloud Reader 側で UTF-8 → Latin-1 の mojibake"," が起きていた。",[19,234,235],{},"TextDecoder"," で復元できることを確認し、",[19,238,239],{},"content.js"," に組み込んで「明治維新とは何だったのか――世界史から考える」相当のタイトルが綺麗に取れるようになった。",[222,242,244],{"id":243},"壁2-拡張機能がリストに出てこない","壁2: 拡張機能がリストに出てこない",[15,246,247,249,250,253],{},[19,248,239],{}," を直してリロードしてもらったが、",[19,251,252],{},"chrome://extensions/"," の拡張機能リストに「Kindle Cloud Reader Capturer」が出てこない。ユーザーが「リロードしたよ」と言ってくれたタイミングと、こちら側で MCP から状態を覗くタイミングがずれていた可能性が高い。",[15,255,256],{},"何度もスクショを撮ってもらいながら、最終的にロードできた。「リロード」が拡張機能のリロードなのか Kindle タブのリロードなのか、口頭で曖昧になりやすいことを学んだ。",[222,258,260],{"id":259},"壁3-reader-did-not-become-ready-slider-not-found-in-60s","壁3: Reader did not become ready (slider not found) in 60s",[15,262,263,264,267],{},"巡回ループに入ると、60秒経って ",[19,265,266],{},"Reader did not become ready (slider not found) in 60s"," のエラーで止まる。「進んでないんで、ページの画面が多分止まってます」というユーザーの観察が正しかった。",[15,269,270,271,274,275,278,279,282],{},"調査したら、対象書籍が ",[27,272,273],{},"固定レイアウト（fixed layout）書籍"," だった。本文が ",[19,276,277],{},".kg-full-page-img"," という画像要素として配信されていて、Kindle が \"Learning reading speed...\" モードに居る間 ",[19,280,281],{},"reader-footer-title"," が空のまま。slider が出てくる前提のロジックが破綻していた。",[15,284,285],{},"ページ送りは「Next/Previous page ボタンを直接クリック」する方式に切り替え、終端判定は画像の fingerprint（同じページが連続したら終端）で組み直した。",[222,287,289],{"id":288},"壁4-進捗が見えない","壁4: 進捗が見えない",[15,291,292],{},"popup を開いても「実行中」とだけ出て、動いているのか止まっているのか分からない。「動いてるのか止まってんのかよくわかりません」という指摘を受けて、popup.js にリアルタイム進捗表示を入れた。ページ番号と取得済み枚数が刻々と更新されるようにして、ユーザーが「進んでない」を画面で判定できるようにした。",[222,294,296],{"id":295},"壁5-ファイル名が-uuid-になる-3枚で落ちる","壁5: ファイル名が UUID になる + 3枚で落ちる",[15,298,299,300,303,304,307],{},"「3枚今落ちたんすかね」と聞かれて Downloads フォルダを覗いたら、",[19,301,302],{},"ダウンロード.png"," という名前のファイルが UUID 付きでばらまかれていた。",[19,305,306],{},"kindle-captures/\u003CASIN>/page_NNNN.png"," の指定が完全に無視されていた。",[15,309,310,311,314,315,322,323,326],{},"さらに進めたら今度は ",[19,312,313],{},"URL.createObjectURL is not a function"," のエラーが popup に一瞬出る。",[27,316,317,318,321],{},"MV3 の service worker から ",[19,319,320],{},"URL.createObjectURL"," が削除されている","仕様にぶつかっていた。専用の ",[27,324,325],{},"Offscreen Document"," を立てて、そこで blob URL を作る回避策に書き換えた。",[15,328,329,330,333,334,337,338,341,342,344],{},"ファイル名の方は、blob URL を ",[19,331,332],{},"chrome.downloads.download"," に渡すと ",[19,335,336],{},"filename"," 引数が無視される仕様だったので、",[19,339,340],{},"chrome.downloads.onDeterminingFilename"," リスナーで強制上書きするように変更。UUID 名で散らばっていた 69 個の PNG を掃除してから、ようやく ",[19,343,306],{}," の形でサブフォルダに連番保存されるようになった。",[10,346,348],{"id":347},"着地v02-で一応うまくいってる状態","着地：v0.2 で「一応うまくいってる」状態",[15,350,351,352,355,356,359],{},"夕方になって、ようやく popup から実行ボタンを押すと、Kindle のページが順番に送られて、Downloads の ",[19,353,354],{},"kindle-captures/\u003CASIN>/"," 配下に ",[19,357,358],{},"page_0001.png"," から連番で溜まる状態になった。OCR とTurso 登録は明日に持ち越し。",[15,361,362],{},"「OK。一応うまくいってるみたいなんで、ここまでの進捗ちょっとドキュメンタリー残しておいてください。また明日やりましょう」で締めて、計画書に今日の格闘記録（5つの壁と解決方法）と拡張機能 v0.2 の最終構成、残課題、明日の復帰プロンプトをまとめて書き残してもらった。",[10,364,365],{"id":365},"学びメモ",[45,367,368,374,380,393,399],{},[48,369,370,373],{},[27,371,372],{},"「MCPで一気通貫」より「拡張機能に逃がす」が正解だった瞬間が確かにあった","。MCP セッションで長時間ループを回し続けると不安定になる。バックグラウンドに任せられる仕事は拡張機能側に分離した方が、観察と再開がしやすい。",[48,375,376,379],{},[27,377,378],{},"進捗の可視化を後回しにすると、進んでいるか止まっているかが分からなくなる","。popup に進捗表示を入れた瞬間、デバッグの解像度が一段上がった。最初から組むべきだった。",[48,381,382,385,386,388,389,392],{},[27,383,384],{},"MV3 の制約は service worker の制約","。",[19,387,320],{}," が使えない、",[19,390,391],{},"localStorage"," が使えない、等の罠が随所にある。Offscreen Document はその回避策として覚えておく。",[48,394,395,398],{},[27,396,397],{},"Kindle の本には固定レイアウトとリフロー型がある","。固定レイアウトは本文が画像として配信されるので、テキスト抽出ではなく OCR 一択になる。今回の対象書籍はたまたま固定レイアウトだったが、リフロー型は別の DOM 取得経路が要る。",[48,400,401,406,407,409],{},[27,402,403,405],{},[19,404,114],{}," のMCP 設定はバージョン管理されていない","ので、消えても気づきにくい。今日抽出した ",[19,408,140],{}," を git に入れたので、次に何か消えても git log で追える。",[10,411,412],{"id":412},"明日やること",[45,414,417,434,444,450],{"className":415},[416],"contains-task-list",[48,418,421,426,427,430,431,433],{"className":419},[420],"task-list-item",[422,423],"input",{"disabled":424,"type":425},true,"checkbox"," OCR連携: 拡張機能が保存した ",[19,428,429],{},"kindle-captures/\u003CASIN>/page_*.png"," を ",[19,432,21],{}," に渡して章節分割まで通す",[48,435,437,439,440,443],{"className":436},[420],[422,438],{"disabled":424,"type":425}," Turso 登録: ",[19,441,442],{},"book-knowledge-base"," の既存スキーマに乗せて、Kindle由来かPDF由来かを区別するフラグを追加する",[48,445,447,449],{"className":446},[420],[422,448],{"disabled":424,"type":425}," リフロー型書籍での挙動を別の本で1冊試す（固定レイアウトしかテストできていない）",[48,451,453,455,456,459],{"className":452},[420],[422,454],{"disabled":424,"type":425}," スラッシュコマンド ",[19,457,458],{},"/yomitoku-kindle \u003CURL>"," から拡張機能起動 → 完了通知 → OCR まで自律的に連結する部分の検証",{"title":461,"searchDepth":462,"depth":462,"links":463},"",2,[464,465,466,467,468,469,477,478,479],{"id":12,"depth":462,"text":13},{"id":39,"depth":462,"text":40},{"id":78,"depth":462,"text":79},{"id":161,"depth":462,"text":162},{"id":177,"depth":462,"text":178},{"id":216,"depth":462,"text":217,"children":470},[471,473,474,475,476],{"id":224,"depth":472,"text":225},3,{"id":243,"depth":472,"text":244},{"id":259,"depth":472,"text":260},{"id":288,"depth":472,"text":289},{"id":295,"depth":472,"text":296},{"id":347,"depth":462,"text":348},{"id":365,"depth":462,"text":365},{"id":412,"depth":462,"text":412},"dev","裁断本PDF用のOCR/章節分割パイプラインに、Kindle電子書籍をスクショ経由で乗せる。スラッシュコマンド+Chrome拡張機能のハイブリッド構成で半日格闘した記録。","md",{},null,"/kindle-screenshot-extension-yomitoku-pipeline",false,"2026-06-17T00:00:00.000Z",{"title":5,"description":481},"2026-06/2026-06-17/kindle-screenshot-extension-yomitoku-pipeline",[491,492,493,494,495,496,442],"Kindle","Chrome拡張機能","yomitoku","OCR","ChromeDevTools MCP","スラッシュコマンド","70h8rZDVN71EQW6dldOi3Qp-6zs7IPAaXWwtr-mGals",[],"https://log.eurekapu.com/og/blog/kindle-screenshot-extension-yomitoku-pipeline.png?v=2026-06-17T00%3A00%3A00.000Z&title=Kindle%E3%82%92yomitoku%E3%83%91%E3%82%A4%E3%83%97%E3%83%A9%E3%82%A4%E3%83%B3%E3%81%AB%E3%81%A4%E3%81%AA%E3%81%90Chrome%E6%8B%A1%E5%BC%B5%E3%81%AE%E8%A8%AD%E8%A8%88%E3%81%A8%E8%A9%A6%E8%A1%8C%E9%8C%AF%E8%AA%A4&author=Kei%20Komatsu&sig=c9756723c5cc182a",1782176329808]