跳到主要内容
知仓学习社ZHICANG

notebooklm

Install, authenticate, troubleshoot, and operate Gemini Notebook through the notebooklm-py CLI or typed async Python API. Use for notebook and sourc…

读凭据执行命令联网改身份文件写文件读文件严重 110 · 高危 579teng-lin/notebooklm-py

它会碰到什么

扫了多少1960 个文本文件,68085 KB
它会碰到什么读凭据执行命令联网改身份文件写文件读文件
命中总数7022 处
命中统计严重 110 · 高 579 · 中 2282 · 低 4032

这个仓库里自带 102 个测试样本文件(有些技能仓会放故意的恶意样本做演示),它们不计入上面的能力与命中。

逐条看命中(30 条严重或高危)
  • 严重 .env.example:2cred-paths
    # Copy this file to .env and fill in your values
  • 严重 .github/workflows/publish-mcpb.yml:138cred-paths
    cp deploy/.env.example env.example
  • 严重 deploy/docker-compose.yml:3cred-paths
    #   cp .env.example .env   # set NOTEBOOKLM_MCP_TOKEN, NOTEBOOKLM_MCP_VERSION, and/or OAuth
  • 严重 deploy/docker-compose.yml:3cred-paths
    #   cp .env.example .env   # set NOTEBOOKLM_MCP_TOKEN, NOTEBOOKLM_MCP_VERSION, and/or OAuth
  • 严重 deploy/docker-compose.yml:22cred-paths
    # NOTEBOOKLM_MCP_VERSION=X.Y.Z in .env (release-download users get a compose with
  • 严重 deploy/docker-compose.yml:31cred-paths
    # `id -u`/`id -g` automatically, or set them in .env.
  • 严重 deploy/docker-compose.yml:42cred-paths
    # together (partial → refuses to start). See .env.example. The OAuth state
  • 严重 deploy/docker-compose.yml:50cred-paths
    # container (compose `.env` is interpolation-source only, not container env).
  • 严重 deploy/docker-compose.yml:77cred-paths
    # in .env to point at a different profile dir (e.g. a dedicated/throwaway one).
  • 严重 deploy/docker-compose.yml:91cred-paths
    # Pinnable for reproducibility: set CLOUDFLARED_VERSION in .env to a release
  • 严重 deploy/Makefile:2cred-paths
    #   make setup                  — interactive first run: pick a tunnel + generate secrets → .env
  • 严重 deploy/Makefile:12cred-paths
    # TUNNEL: a CLI/env override wins; else the choice `make setup` saved in .env;
  • 严重 deploy/Makefile:13cred-paths
    # else cloudflare. Only TUNNEL is read from .env into make — it's make-only (not a
  • 严重 deploy/Makefile:14cred-paths
    # compose var), so it can't collide with compose's own reading of .env.
  • 严重 deploy/Makefile:15cred-paths
    _TUNNEL_DOTENV := $(shell [ -f .env ] && sed -n 's/^TUNNEL=//p' .env | tr -d '\r' | head -1)
  • 严重 deploy/Makefile:15cred-paths
    _TUNNEL_DOTENV := $(shell [ -f .env ] && sed -n 's/^TUNNEL=//p' .env | tr -d '\r' | head -1)
  • 严重 deploy/Makefile:19cred-paths
    # CLI/env override wins; else deploy/.env; else ./oauth-state (matches the compose
  • 严重 deploy/Makefile:21cred-paths
    _OAUTH_STATE_DOTENV := $(shell [ -f .env ] && sed -n 's/^NOTEBOOKLM_OAUTH_STATE_DIR=//p' .env | tr -d '\r' | head -1)
  • 严重 deploy/Makefile:21cred-paths
    _OAUTH_STATE_DOTENV := $(shell [ -f .env ] && sed -n 's/^NOTEBOOKLM_OAUTH_STATE_DIR=//p' .env | tr -d '\r' | head -1)
  • 严重 deploy/Makefile:23cred-paths
    # (which Compose reads directly) wins, then deploy/.env, then the default. Otherwise
  • 严重 deploy/Makefile:28cred-paths
    # override order: shell/CLI env, deploy/.env, this checkout's pyproject version,
  • 严重 deploy/Makefile:32cred-paths
    _VERSION_DOTENV := $(shell [ -f .env ] && sed -n 's/^NOTEBOOKLM_MCP_VERSION=//p' .env | tr -d '\r' | head -1)
  • 严重 deploy/Makefile:32cred-paths
    _VERSION_DOTENV := $(shell [ -f .env ] && sed -n 's/^NOTEBOOKLM_MCP_VERSION=//p' .env | tr -d '\r' | head -1)
  • 严重 deploy/Makefile:58cred-paths
    # NOTE: do NOT set/export NOTEBOOKLM_PROFILE_DIR here. make does not read .env, so a
  • 严重 deploy/Makefile:60cred-paths
    # env, where it OUTRANKS the .env value (shell env > .env) — silently ignoring the
  • 严重 deploy/Makefile:60cred-paths
    # env, where it OUTRANKS the .env value (shell env > .env) — silently ignoring the
  • 严重 deploy/Makefile:61cred-paths
    # user's `.env` setting. Compose reads NOTEBOOKLM_PROFILE_DIR from .env directly and
  • 严重 deploy/Makefile:61cred-paths
    # user's `.env` setting. Compose reads NOTEBOOKLM_PROFILE_DIR from .env directly and
  • 严重 deploy/Makefile:75cred-paths
    && ! grep -qsE '^NOTEBOOKLM_MCP_VERSION=.+' .env; then \
  • 严重 deploy/Makefile:76cred-paths
    echo "✗ NOTEBOOKLM_MCP_VERSION is unknown — run from a source checkout, pass VERSION=x.y.z, or set it in deploy/.env"; \

这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。

技能内容

Gemini Notebook Automation

Use the notebooklm CLI for agent workflows. Prefer --json and explicit IDs so every

operation is inspectable and safe under concurrency. Use the typed async Python API only when the

user requests application code or the CLI cannot express the workflow. The readiness, identity,

authorization, and credential-handling rules below apply to both interfaces.

Setup and Authentication

Requires Python 3.10+. Install the package in the user's existing environment; do not create a

separate environment unless requested:

pip install "notebooklm-py[browser]"
pip install "notebooklm-py[cookies]"  # optional browser-cookie extraction

If system pip reports externally-managed-environment, do not use --break-system-packages.

For CLI-only use, offer uv tool install "notebooklm-py[browser]" or the equivalent pipx

command; for application code, use the user's active project environment.

For unattended or headless work, prefer durable profile-backed master-token auth over a copied

cookie snapshot. Install pip install "notebooklm-py[headless]"; the one-time automatic OAuth

capture also needs [browser]. On a trusted workstation run

notebooklm login --master-token --account <email>, then deploy master_token.json, not

storage_state.json, to the selected profile. NOTEBOOKLM_HOME selects the private base directory

and NOTEBOOKLM_PROFILE selects its profile; defaults resolve to

~/.notebooklm/profiles/default/master_token.json.

In CI, NOTEBOOKLM_MASTER_TOKEN_JSON is a secret-transport convention, not an environment variable

the package reads directly. Write its exact value to the selected profile's master_token.json

with mode 0600, unset it, then run notebooklm auth refresh to mint storage_state.json. A

sibling master token can automatically re-mint expired file-backed cookies. Inline

NOTEBOOKLM_AUTH_JSON is only a short-lived fallback; it bypasses this recovery path.

Use PyPI or a release tag, not an unreleased main checkout. When available, consult the

installation guide.

Before a workflow, verify real authentication rather than merely parsing the cookie file:

notebooklm auth check --test --json

Require .status == "ok" and .checks.token_fetch == true. If validation fails:

  • With a display, run notebooklm login and validate again.
  • In a headless environment, install [cookies] and use

notebooklm login --browser-cookies <browser>. Use

notebooklm auth inspect --browser <browser> first when account selection is unclear.

  • If previously valid cookies became stale, try notebooklm auth refresh; use

notebooklm auth refresh --browser-cookies <browser> after signing back into the browser.

The normal --test preflight may heal and persist refreshed cookies. Add --passive when the

check must be strictly read-only, including the failure-diagnosis workflow below.

notebooklm status reports selected-notebook context, not authentication.

Treat both auth files as bearer credentials: never print, log, or commit them. A master token is a

durable full-account credential that survives password changes; use a dedicated account, protect

it in a secret store and as 0600 on disk, and explicitly revoke it if exposed.

Operating Invariants

  1. Use --json for discovery and mutations, then retain the returned full UUIDs. Important

envelopes are .notebook.id from create, .source.id from source add, and .task_id from

asynchronous generators. generate mind-map instead returns mind_map, note_id, and kind;

both kinds return a finished result with no task ID or separate artifact wait step.

  1. Pass -n/--notebook <id> on every notebook-scoped command in automation or concurrent work.

Do not rely on notebooklm use. For every concurrent run, also set a unique

NOTEBOOKLM_PROFILE=agent-<id> so context and profile writes are isolated. A new profile has no

credentials: put a master_token.json copy in that profile and mint its storage before use.

Never share one writable storage_state.json across agents.

  1. After adding sources, retain every .source.id, then run source wait for each before chat or

generation. The add envelope has no status. Require wait exit 0 and status == "ready"; let the

waiter handle media-specific transient error rows.

  1. After an asynchronous generator returns a task/artifact ID, pass it positionally to

artifact wait with -n <notebook_id>. Download that exact artifact with

-a <artifact_id> -n <notebook_id>; never select the latest visible artifact. Mind-map generation

returns its completed result directly and does not need artifact wait.

  1. For overlapping research runs, always pass --run-id <research_run_id>.
  2. Use a host's background facility only when it actually exists. Keep wait and dependent download

commands in one sequential job, and download only after the wait exits 0. Otherwise run in the

foreground or return exact ID-pinned commands to the user.

Authorization Boundaries

Safe inspection and explicitly requested creation, source addition, chat, and prompt suggestion can

run directly. Diagnose failures with read-only commands before attempting recovery.

Obtain confirmation immediately before an action when it was not already clearly authorized:

  • destructive commands such as notebook/source/note/artifact/label/profile deletion, sharing

removal, logout, clear, research cancellation, and ask --new;

  • language set, because the default mode changes the account-global output language (prefer a

generation command's --language override);

  • generation or long foreground waits, which can take minutes and be rate-limited;
  • downloads, which write files;
  • research wait --import-all, which imports sources;
  • ask --save-as-note and history --save, which create notes.

User intent, not the presence of a CLI prompt, is the authorization boundary. After authorization,

pass --yes/-y where supported. Most destructive JSON commands refuse to prompt without it, but

some, including ask --new --json and share remove --json, execute without prompting. Never

treat prompt absence as consent.

research cancel is fire-and-forget. After an authorized cancellation, verify the exact run with

notebooklm research status -n <notebook_id> --run-id <research_run_id> --json.

Command Discovery

Use the installed CLI's help as the version-matched source of truth instead of guessing flags:

notebooklm --help
notebooklm source --help
notebooklm research --help
notebooklm generate --help
notebooklm artifact --help
notebooklm download --help

Also inspect notebooklm --version and drill down to the exact command, such as

notebooklm generate audio --help, whenever its help differs from this skill.

Common operations:

| Goal | Command |

|---|---|

| Check compute usage | notebooklm usage --json; notebooklm usage --categories for category availability and estimated costs |

| List or create notebooks | notebooklm list --json; notebooklm create "Title" --json |

| Add and wait for a source | notebooklm source add <input> -n <nb> --json; notebooklm source wait <src> -n <nb> |

| Chat | notebooklm ask "question" -n <nb> --json |

| Research | notebooklm source add-research "query" -n <nb> --mode fast --json (deep is also supported) |

| List or wait for artifacts | notebooklm artifact list -n <nb> --json; notebooklm artifact wait <id> -n <nb> |

| Generate | notebooklm generate <type> ... -n <nb> --json |

| Download | notebooklm download <type> <path> -n <nb> -a <artifact> |

For the full surface, consult the installed command help or, when available, the

CLI reference.

For application code, use the baseline below and, when available, the

Python API guide.

Canonical Source-to-Artifact Workflow

Keep {notebook_id}, every {source_id}, and {artifact_id} from JSON output:

An explicit request for this completed workflow authorizes its normal prerequisite waits, requested

generation, and requested output file. Confirm only work not already authorized by that request.

  1. notebooklm create "Research: topic" --json
  2. notebooklm source add <input> -n {notebook_id} --json for each input.
  3. Once the foreground wait is authorized, run

notebooklm source wait {source_id} -n {notebook_id} --timeout 600 for every captured source.

  1. Once generation is authorized, generate the requested type. For audio:

notebooklm generate audio "instructions" -n {notebook_id} -s {source_id} --json.

Repeat -s for each selected source and capture .task_id as {artifact_id}.

  1. Once the foreground wait is authorized, run

notebooklm artifact wait {artifact_id} -n {notebook_id} --timeout 1200.

  1. Once the output write is authorized, run

notebooklm download audio ./podcast.m4a -a {artifact_id} -n {notebook_id}.

For analysis without generation, replace steps 4-6 with an ID-pinned chat command only after every

source is ready:

notebooklm ask "Summarize the key arguments" -n {notebook_id} --json

Deep Research

Deep research can take 15-30+ minutes. Start it non-blocking and retain

.poll_task_id // .task_id as {research_run_id}:

notebooklm source add-research "query" -n {notebook_id} --mode deep --no-wait --json

Import only after explicit authorization, pinning both IDs:

notebooklm research wait -n {notebook_id} --run-id {research_run_id} \
  --import-all --timeout 1800 --json

With --import-all, --timeout is a per-phase budget for polling and import retry, so this example

can consume roughly 3600 seconds of host wall time.

Retain newly created source IDs from .imported_sources[].id and wait for readiness before later

chat or generation.

Python API Baseline

When the full API guide is unavailable, use the installed typed API and its docstrings; do not guess

method names. Keep the same IDs and readiness gates as the CLI workflow:

import asyncio

from notebooklm import NotebookLMClient


async def main(url: str) -> None:
    async with NotebookLMClient.from_storage() as client:
        notebook = await client.notebooks.create("Research: topic")
        source = await client.sources.add_url(notebook.id, url)
        await client.sources.wait_until_ready(notebook.id, source.id, timeout=600)

        answer = await client.chat.ask(
            notebook.id, "Summarize the key arguments", source_ids=[source.id]
        )
        print(answer.answer)

        task = await client.artifacts.generate_audio(
            notebook.id,
            source_ids=[source.id],
            instructions="Focus on the key arguments",
        )
        final = await client.artifacts.wait_for_completion(notebook.id, task.task_id, timeout=1200)
        if not final.is_complete:
            raise RuntimeError(f"Generation ended with {final.status}: {final.error}")
        await client.artifacts.download_audio(
            notebook.id, "./podcast.m4a", artifact_id=task.task_id
        )


asyncio.run(main("https://example.com"))

NotebookLMClient.from_storage() is an async context manager and is not awaited. A client is

re-entrant on one event loop but is not thread-safe; create one client per loop. Public namespaces

include notebooks, sources, chat, research, artifacts, mind_maps, notes, settings,

sharing, labels, and collections. Apply the authorization boundaries above before running

state-changing, long-running, or file-writing calls.

Generation Notes

Available generators include audio, video, slide-deck, infographic, report, mind-map,

data-table, quiz, and flashcards. Inspect notebooklm generate <type> --help because formats,

styles, source selection, language, and retry support vary by type.

Keep these non-obvious distinctions:

  • Mind map (--kind interactive, default) is an asynchronous studio artifact internally, but the

CLI polls it to completion and returns {mind_map, note_id, kind}; do not run artifact wait.

  • Mind map (--kind note-backed) is server-synchronous. Both kinds accept --instructions;

interactive applies it reliably, while the server may ignore it for note-backed maps.

  • generate video --format cinematic ignores --style, requires Google AI Ultra, and can take

roughly 30-40 minutes.

  • Slide-deck has no orientation flag. Request portrait output in the description (for example,

9:16 portrait); slide revision cannot change the deck's orientation.

  • For a custom report, pass the prompt as the positional description with --format custom;

--append applies only to built-in report formats.

For prompts too long or awkward for shell quoting, use --prompt-file PATH on ask,

source add-research, and supported generators. It contains prompt text; upload source documents

with source add instead.

Output and Citations

Use JSON structurally rather than parsing human output. Common lifecycle values are:

  • sources: unknown/preparing/processing -> ready or error; proceed only on ready;
  • artifacts: pending/in_progress -> completed, failed, or removed; not_found may be a

brief listing lag. Proceed or download only on completed.

Chat JSON includes answer, conversation_id, and references[].source_id. A reference's

start_char/end_char are UTF-16 offsets into the structured source document, not flat

SourceFulltext.content. In Python, use

from notebooklm import resolve_chat_reference_passage, then call

await resolve_chat_reference_passage(client, notebook_id, reference); it uses the exact document

range and falls back to find_citation_context() when necessary.

Failure Handling

On failure, run safe read-only diagnosis first:

notebooklm auth check --test --passive --json
notebooklm list --json
notebooklm source list -n {notebook_id} --json
notebooklm artifact list -n {notebook_id} --json
notebooklm research status -n {notebook_id} --run-id {research_run_id} --json

Inspect only the commands relevant to the failed workflow. Do not mutate state during diagnosis.

  • Exit 0 means success. Expected command failures use exit 1. A source wait timeout uses exit 2;

artifact wait and research wait timeouts use exit 1.

  • Branch on exit code first. Ordinary handled JSON failures use {error, code, message}, while wait

commands return domain envelopes such as {"status": "timeout", "error": "..."}.

  • On auth failure, revalidate checks.token_fetch; log in only if it is not true.
  • On a wait timeout, report it and inspect the exact source, artifact, or research run.
  • Generation is rate-limited by Google. Preserve the task ID, inspect status, and retry only when the

user authorizes it; do not loop indefinitely. For an existing failed Studio artifact, inspect

notebooklm artifact retry <artifact_id> -n {notebook_id} --help before retrying in place.

  • On a protocol error, record the installed version, exact command, relevant IDs, and redacted

error. Check the project's issue tracker when network access exists; do not invent a workaround

when it does not.

Keep progress updates brief and include the relevant returned ID. Never expose credential contents.

Skill Installation

If this file is already inside an agent skill directory, the skill itself is installed. Otherwise:

  • notebooklm skill install installs or updates supported local skill targets.
  • notebooklm skill package builds an uploadable archive for sandboxed agent environments.
  • notebooklm skill status --json reports installed versions and content_mismatch.

想直接用这个技能?

本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。

它属于哪个仓库

星标★ 19,345
本站分层T2
该仓技能数1
原文件路径SKILL.md