コンテンツ制作 · PleasePrompto/notebooklm-skill

notebooklm-skill

このスキルを使用すると、Claude CodeからGoogle NotebookLMノートブックを直接クエリし、Geminiからソースに基づいた引用付きの回答を取得できます。ブラウザ自動化、ライブラリ管理、永続的な認証機能を備え、ドキュメントのみに基づく回答によりハルシネーションを大幅に低減します。

L5 厳格管理 · 隔離環境と厳格な監査V2 人間監査済規約/コンプライアンス認証情報/セッションコマンド実行依存関係インストールネットワーク通信ファイル書き込みDual-pass Audit
Author PleasePromptoGitHub PleasePrompto/notebooklm-skill ↗Stars 7772License MIT(仓库根 LICENSE:L1 'MIT License'、L3 'Copyright (c) 2025 Please Prompto!')Commit c80722d3f2
管理レベルは Skill の能力と推奨統制措置を示すものであり、品質や安全性の認証、利用可否の判定ではありません。使用の可否はユーザーおよび管理者が決定します。Agent 環境によって制約が異なるため、自動保護を仮定しないでください。第三者製 Skill の著作権は原著作者に帰属し、利用リスクは利用者が負います。

1仕組みと動作原理

一時的なブラウザインスタンスではなく、patchright(Playwrightの検出回避フォーク)を使用して**実際のChromeの永続ユーザープロファイル**を起動します。これが複数回呼び出しにわたって「ログイン状態」を維持できる基盤となっています。

scripts/browser_utils.py
channel="chrome", # Use real Chrome
同一呼び出し内で user_data_dir=user_data_dir、ignore_default_args=["--enable-automation"]、user_agent=USER_AGENT、args=BROWSER_ARGS を渡します。プロファイルディレクトリは <skill>/data/browser_state/browser_profile(config.py の BROWSER_PROFILE_DIR)です。

認証フェーズでは表示可能なブラウザを開いて手動ログインを待ち、cookies + localStorage を state.json に保存します。この一連のフローの認証情報は API キーではなくこのファイルです。

scripts/auth_manager.py
context.storage_state(path=str(self.state_file))
state_file = <skill>/data/browser_state/state.json(config.py:13)。ログイン待機は URL 正規表現 + 10 分のタイムアウト(LOGIN_TIMEOUT_MINUTES = 10)に依存します。

実行時に state.json のクッキーを手動でブラウザコンテキストに注入し、Playwrightの「セッションクッキーが user_data_dir に書き込まれない」既知の問題を回避します。

scripts/browser_utils.py
context.add_cookies(state['cookies'])
launch_persistent_context 内部で固定的に _inject_cookies を呼び出します。読み取りに失敗しても警告を出力するのみで中断しません。AUTHENTICATION.md のコード例ではこのステップに `# ← Workaround for session cookies!` と注記されています。

質問ごとに「1問につき1ブラウザセッション」として実行されます:新規ページを開く → ユーザー指定の notebook URL を開く → DNS レベルのホワイトリスト待機(ログイン画面にリダイレクトされていないことを確認するため、notebooklm.google.com ドメインへの復帰のみを許可)。

scripts/ask_question.py
page.goto(notebook_url, wait_until="domcontentloaded")
直後に page.wait_for_url(re.compile(r"^https://notebooklm\.google\.com/"), timeout=10000) が続きます。SKILL.md と README には「Each question opens a fresh browser session」と記載されており、タイムアウト上限は 120 秒(QUERY_TIMEOUT_SECONDS = 120)です。

質問テキストは「人間らしい入力」で textarea に1文字ずつ入力され、3段階のセレクタフォールバック(ドイツ語の aria-label を含む)を備えています。入力ボックスの検出に失敗すると処理全体が失敗します。

scripts/config.py
"textarea.query-box-input", # Primary
フォールバック項目は 'textarea[aria-label="Feld für Anfragen"]'(ドイツ語)と 'textarea[aria-label="Input for queries"]'(英語)です。実際の送信はキーボードの Enter キーで行われます。

回答の取得はポーリングによる安定性判定で行われます:`div.thinking-message` の消失を待ち、レスポンスコンテナの最後の要素のテキストを取得し、複数回連続で一致した場合にのみ回答完了と判定します。

scripts/ask_question.py
thinking_element = page.query_selector('div.thinking-message')
レスポンスコンテナのセレクタは `.to-user-container .message-text-content`(config.py:25)です。elements[-1].inner_text().strip() を取得後、120秒のデッドラインを超えずに stable_count >= 3 となることを要求します。

スクリプトは stdout に返す前に、回答テキストの後ろに Claude 向けの指示文を強制的に結合し、「必ず追質問を継続する」閉ループを形成します。

scripts/ask_question.py
return answer + FOLLOW_UP_REMINDER
FOLLOW_UP_REMINDER はステートレスな MCP サーバー版から改変されたものであると記述されています。SKILL.md の Follow-Up Mechanism セクションでは、Claude が STOP / ANALYZE / IDENTIFY GAPS / ASK FOLLOW-UP を行わなければならないとさらに規定されています。

run.py は公式に唯一推奨されているエントリポイントです:.venv が存在しない場合はシステム Python で setup_environment.py を実行してブートストラップし、その後 venv インタプリタで対象スクリプトを実行します。

scripts/run.py
result = subprocess.run([sys.executable, str(setup_script)])
続いて cmd = [str(venv_python), str(script_path)] + script_args で subprocess.run(cmd) を実行します。setup_environment.py 内では `pip install -r requirements.txt` と `python -m patchright install chrome` が実行されます。

notebook ライブラリは純粋なローカル JSON メタデータ(url/name/description/topics/use_count)であり、ベクトルストアやコンテンツキャッシュはありません。「グラウンディング」は実際にはローカルではなく Google 側で行われます。

scripts/notebook_manager.py
self.library_file = self.data_dir / "library.json"
data_dir は Path(__file__).parent.parent / 'data' から導出されます。_save_library は json.dump(data, f, indent=2) を使ってディスクに保存します。

2コア機能

01指定した NotebookLM ノートブックに質問を送信し、Gemini から回答テキストを取得
02Google に一度ログインすれば長期再利用可能(永続プロファイル + state.json クッキー注入)
03複数ノートブックのライブラリ管理(追加/削除/検索/アクティブ化/統計、ローカルの library.json に保存)
04環境のセルフブートストラップ:.venv の自動構築、依存関係のインストール、Chrome バイナリのダウンロード
05検出回避インタラクション(1文字ずつの入力 + ランダム遅延 + 自動化フラグの無効化)
06ローカルデータのクリーンアップ(ライブラリを保持可能、かつ .venv は絶対に削除しない)

3外部依存関係

KindDependency / Endpoint
networkGoogle NotebookLM 站点(浏览器自动化目标)
network提问页 URL 白名单校验(确认未被重定向去登录)
networkGoogle 账号登录态判定(字符串检测,非主动请求)
packagepatchright(Playwright 反检测分支,浏览器自动化核心)
packagepython-dotenv(声明为依赖,但代码从未使用)
clipip 安装依赖(走默认 PyPI)
cli下载安装 Google Chrome 二进制
cli另一条安装路径装的是 chromium(与上一条不一致)

4推奨統制措置と判定根拠

安全運用のための推奨統制措置
Agent 向け
隔離環境で実行、都度明示的な認可
管理者向け
厳格な認可、全量監査、コンプライアンス確認
判定根拠(ファイルパスと抜粋)
  • SKILL.md / 脚本参数: 自動化検出の回避、ホストサンドボックスの無効化、または SSL 証明書検証のスキップを含む
  • SKILL.md / 会话存储: ブラウザのユーザーログイン状態およびセッション Cookie を読み取りまたは再利用する
  • 本地凭据 / 浏览器配置: ユーザーのログイン Cookie/セッション/キーチェーンの読み取り: ブラウザプロファイル内の Cookie データベースは Chrome 自体によって読み書きされる(user_data_dir は <skill>/data/browse を指定)
  • scripts/: ローカルスクリプトまたはコマンドの実行: run.py は .venv が存在しない場合にシステムインタプリタで setup_environment.py を実行する: `result = subprocess.run([sy
  • scripts/ 或 SKILL.md: 外部言語パッケージ依存関係の動的インストールを宣言
  • 网络端点: 外部ネットワークアクセスの宣言: ブラウザ自動化による Google NotebookLM へのアクセス: `page.goto("https://notebooklm.google.com", wait
  • 本地工作目录: ファイルの読み書きと成果物の出力: state.json(すべての Google セッション Cookie を含む)の書き込み: `context.storage_state(path=str(self.st
監査ノート: 🔴 赤:厳格な管理対象。本スキルは3つの赤判定基準に同時に該当し、いずれもソースコード上の証拠が存在します:①スクレイピング防止/自動化検出の回避――patchright に依存(requirements.txt のコメントに「Core browser automation with anti-detection」と明記)し、`'--disable-blink-features=AutomationControlled', # Patches navigator.webdriver` を渡して自動化フラグを隠蔽する目的でブラウザを起動します;②セキュリティの低下――同じ BROWSER_ARGS 内に `'--no-sandbox'` が含まれ、サンドボックス無効状態でブラウザを実行します;③認証情報への接触――認証成果物として Google セッションクッキーを含む data/browser_state/state.json が生成され、実行時にコードから積極的に読み戻されてブラウザコンテキストに注入されます(.gitignore には「contains auth and personal notebooks」と記載)。さらに、初回実行時にはインポート時に自動で venv を構築し、PyPI から依存関係をインストールして Chrome バイナリをダウンロードします。これらは機能設計上の理由(Webインターフェースのみ提供される Google 製品を操作するためにブラウザが不可欠)によるものであり悪意ある隠蔽行為ではありませんが、ユーザーは「ログイン状態が平文でディスクに保存されること」「ブラウザが非自動化と意図的に偽装されること」「サンドボックスが無効化されること」を明確に認識しておく必要があります。

5二重目の独立検証

  • [ok] skill.path = '.'(根级 SKILL.md) — 重读 SKILL.md L1-4 确认 frontmatter 位于仓库根文件;glob 根 *.json 无命中(无 plugin.json / marketplace.json),故技能入口就是仓库根。
  • [ok] official_desc 逐字 — 重读 SKILL.md L2-4:name: notebooklm、description 为单行完整句,与 README L15 的同一句(README 用连字符 'Drastically reduced hallucinations - answers only from your uploaded documents.')措辞略异,已按 frontmatter 原文收录。
  • [ok] 混合认证机制(persistent profile + state.json 注入) — 重读 browser_utils.py(launch_persistent_context 与 `context.add_cookies(state['cookies'])`)与 auth_manager.py(`context.storage_state(path=str(self.state_file))`),行号与首遍一致;AUTHENTICATION.md 的说明标注的脚本行号与实码相差数行(文档漂移),机制描述本身正确。
  • [ok] 安全结论:反检测与沙箱关闭 — 重读 config.py 的 BROWSER_ARGS 列表:`'--disable-blink-features=AutomationControlled', # Patches navigator.webdriver` 与 `'--no-sandbox',` 逐字确认;重读 requirements.txt 首段注释确认 'anti-detection' 表述与 patchright pin。三条红色判据均在源码可定位。
  • [ok] 安全结论:凭证读取范围 — 独立重扫 os.environ|getenv|API_KEY|token|keychain|.env|ssh|credentials:scripts 下零命中(唯二 token 字样在 requirements.txt 与文档中的 python-dotenv)。凭证只有 state.json 里的 Google cookie,路径由 config.py 常量推导,无 ~/.claude 硬编码。
  • [ok] 安全结论:网络外发范围 — 重扫 requests|urllib|socket|http.client 于 scripts:零命中;网络只经浏览器(notebooklm.google.com / accounts.google.com)、pip(PyPI)与 patchright 下载 Chrome(域名不可定位,已记入 unlocated)。
  • [ok] 安全结论:写盘与删除边界 — 重读 auth_manager、notebook_manager、cleanup_manager、__init__ 的写路径:state.json / auth_info.json / library.json / .venv,全部位于 <skill>/data 与 <skill>/.venv;删除限定在 data/ 且显式排除 .venv(`Virtual environment (.venv) is never deleted`)。
  • [discrepancy] 宣称 vs 实际:citation-backed — 脚本内无任何 citation/来源条目的解析代码,唯一取数路径是响应容器最后一元素的 inner_text;README L65 与 SKILL.md 的 citation 表述实际描述的是 NotebookLM/Gemini 侧行为,本 skill 只做纯文本透传,不能保证引用随答案回到模型上下文。

6結論

  • 「Web版製品を利用したグラウンディングQ&A」を再利用可能なCLIパイプラインとして構築しており、Q&A、ライブラリ管理、認証、環境構築、クリーンアップにそれぞれ独立した実行可能エントリポイントを用意
  • 「一度ログインすれば長期利用可能」な認証体験を実現し、Playwright の既知のクッキー不具合を明示的に回避してドキュメント化
  • 回答の参照元がユーザー自身のドキュメント群に限定されるため、ハルシネーションを確実に抑制(一般的なWeb検索に対する最大のアピールポイント)
  • ローカルデータの境界が明確:書き込みは data/ と .venv に限定され、クリーンアップツールは .venv を明示的に除外、削除には --confirm と対話形式の確認が必須
  • 最適な用途: すでに Google NotebookLM で資料を管理しており、コーディングエージェントのセッション内から直接ノートブックに質問したい(自身がアップロードしたドキュメントのみに基づいた回答を求める)個人研究者やコンテンツクリエイターに最適です。また、「ブラウザ自動化 + 永続ログイン」パターンのリファレンス実装を研究したい開発者にも適しています(認証、クッキー注入、回答ポーリングの安定性判定などが明確で読みやすいコードで記述されています)。前提条件として、Google のログイン状態がローカルディスクに保存されることを許容し、Web 自動化に伴うアカウントリスクを自己責任で負える必要があります。
    不向きな用途: アカウントセキュリティ要件が厳しい環境や管理対象の環境には不向きです(ブラウザが検出回避モードで動作し、サンドボックスが無効化され、完全なセッションクッキーがディスクに残るため)。長期的な運用の安定性が求められるパイプラインには不向きです(リポジトリはアーカイブ済み、セレクタはハードコードされており、アップストリームのUI変更で全体が機能不全に陥るリスクがあります)。監査証跡や再現性のある引用が必要なユースケースには不向きです(引用はドキュメントレベルでの主張にとどまり、スクリプト側で参照元をパースしません)。「ローカル RAG」を期待するユーザーには不向きです(グラウンディングは Google 側で行われ、ローカルにはメタデータのみが保存され、コンテンツインデックスやベクトルストアは存在しません)。
    Install Agent-Ready
    ① Verified Mirror 2026-09-15
    Option A · Direct DownloadDownload notebooklm-skill.tar.gz
    sha256: edda31a0efaa9b1c…
    Option B · Copy Guide for Agent
    install.json
    Agent はこの JSON ガイドから自動的にダウンロードして検証します。
    ② Upstream GitHub
    GitHub Repo ↗
    Pinned to commit c80722d3f2.