Documentation Index
Fetch the complete documentation index at: https://mintlify.com/jacob-bd/notebooklm-mcp-cli/llms.txt
Use this file to discover all available pages before exploring further.
The nlm CLI is built for end-to-end automation — from discovering sources and ingesting content through to generating polished audio, reports, and flashcards. Every step that the web UI exposes can be scripted, scheduled, or wired into an AI agent via MCP. The workflows below show the exact command sequences for the most common tasks, along with scripting patterns for unattended runs.
Set an alias for any notebook you use repeatedly — nlm alias set research <notebook-id> — so you can write research instead of a full UUID in every command.
Workflow 1: Research → Podcast
Discover sources with NotebookLM’s built-in web research, import the best ones, and generate a deep-dive audio overview.
Start deep research
nlm research start "AI trends 2026" --notebook-id <id> --mode deep
Deep mode searches broadly and takes roughly five minutes. The command prints a task_id you will need later.Poll until research completes
nlm research status <notebook> --max-wait 300
This polls every few seconds and exits once the research task finishes or the 300-second timeout is reached.Import cited sources
nlm research import <notebook> <task-id> --cited-only
--cited-only limits the import to sources that were actually referenced in the research summary, keeping your notebook focused.Generate the audio podcast
nlm audio create <notebook> --format deep_dive --confirm
Audio generation runs asynchronously on NotebookLM’s servers. The --confirm flag is required to proceed without an interactive prompt.Poll studio status
nlm studio status <notebook>
Repeat until the status shows completed. Audio typically takes two to five minutes.Download the finished podcast
nlm download audio <notebook> <artifact-id> --output podcast.mp3
The artifact-id appears in the nlm studio status output.
Workflow 2: Ingest Multiple Sources → Report
Build a notebook from several URLs and a local file, then generate a Briefing Doc.
Create the notebook and set an alias
nlm notebook create "Competitive Analysis Q3"
nlm alias set analysis <notebook-id>
Add URL sources and wait for readiness
nlm source add analysis --url "https://example.com/report-1" --wait
nlm source add analysis --url "https://example.com/report-2" --wait
--wait blocks until the source is fully processed and ready for querying.Add a local file source
nlm source add analysis --file ./internal-research.pdf --wait
Generate a Briefing Doc
nlm report create analysis --format "Briefing Doc" --confirm
Download the report
nlm studio status analysis
nlm download report analysis <artifact-id> --output briefing.md
Workflow 3: Batch Podcast Generation
Generate audio overviews across multiple notebooks in one pass.
Tag the notebooks you want to batch
nlm tag add <notebook-id-1> --tags "research"
nlm tag add <notebook-id-2> --tags "research"
nlm tag add <notebook-id-3> --tags "research"
Trigger batch audio generation
nlm batch studio --type audio --tags "research" --confirm
This queues audio generation for every notebook tagged research.Poll each notebook for completion
nlm studio status <notebook-id-1>
nlm studio status <notebook-id-2>
nlm studio status <notebook-id-3>
Or loop over tag results in a script — see the Bash scripting example below.
Workflow 4: Cross-Notebook Research Summary
Query across multiple notebooks simultaneously to synthesize a unified answer.
Run a cross-notebook query
nlm cross query "What are the recurring themes around AI governance?" \
--notebooks "id1,id2,id3"
You can also use tags to select notebooks dynamically:nlm cross query "Summarize the key findings" --tags "research,2026"
Export results to a file
nlm cross query "Compare approaches to RAG architectures" \
--tags "ai" --json > cross_results.json
Workflow 5: Multi-Format Content Generation
Generate audio, a report, and flashcards in one pipeline command.
Run the multi-format pipeline
nlm pipeline run <notebook> multi-format
This built-in pipeline produces three artifacts in sequence:
- Audio — a
deep_dive podcast overview
- Report — a Briefing Doc
- Flashcards — study cards with default settings
Check all generated artifacts
nlm studio status <notebook>
Download each artifact
nlm download audio <notebook> <audio-id> --output overview.mp3
nlm download report <notebook> <report-id> --output briefing.md
nlm download flashcards <notebook> <cards-id> --output cards.html --format html
Bash Automation Script
The following script automates the full Research → Podcast pipeline end-to-end. Save it, make it executable with chmod +x, and run it with a notebook ID as the first argument.
All generation commands require --confirm (or -y). Without this flag the CLI waits for an interactive prompt, which will cause the script to hang indefinitely.
#!/bin/bash
# research_podcast.sh — Automate Research → Podcast workflow
# Usage: ./research_podcast.sh <notebook-id> "research query"
set -euo pipefail
NOTEBOOK_ID="${1:?Usage: $0 <notebook-id> <query>}"
QUERY="${2:?Usage: $0 <notebook-id> <query>}"
echo "→ Checking authentication..."
nlm login --check || nlm login
echo "→ Starting deep research: '$QUERY'"
nlm research start "$QUERY" --notebook-id "$NOTEBOOK_ID" --mode deep
echo "→ Waiting for research to complete (up to 5 minutes)..."
nlm research status "$NOTEBOOK_ID" --max-wait 300
echo "→ Importing cited sources..."
TASK_ID=$(nlm research status "$NOTEBOOK_ID" --max-wait 0 --json 2>/dev/null \
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('task_id',''))")
if [ -n "$TASK_ID" ]; then
nlm research import "$NOTEBOOK_ID" "$TASK_ID" --cited-only
else
echo "Warning: could not determine task ID; skipping import"
fi
echo "→ Generating deep-dive podcast..."
nlm audio create "$NOTEBOOK_ID" --format deep_dive --confirm
echo "→ Polling for audio completion..."
for i in $(seq 1 30); do
STATUS=$(nlm studio status "$NOTEBOOK_ID" --json 2>/dev/null \
| python3 -c "import sys,json; arts=json.load(sys.stdin); \
audio=[a for a in arts if a.get('type')=='audio']; \
print(audio[-1].get('status','') if audio else '')")
echo " Status: $STATUS (attempt $i/30)"
[ "$STATUS" = "completed" ] && break
sleep 15
done
echo "✓ Done. Run 'nlm studio status $NOTEBOOK_ID' to get the artifact ID for download."
Python Scripting: Parsing --json Output
Use --json to get machine-readable output from any command. Always parse it with a proper JSON library rather than splitting strings.
import json
import subprocess
def list_notebooks() -> list[dict]:
result = subprocess.run(
["nlm", "notebook", "list", "--json"],
capture_output=True,
text=True,
check=True,
)
return json.loads(result.stdout)
def get_studio_artifacts(notebook_id: str) -> list[dict]:
result = subprocess.run(
["nlm", "studio", "status", notebook_id, "--json"],
capture_output=True,
text=True,
check=True,
)
return json.loads(result.stdout)
# Example: find the latest completed audio artifact
notebooks = list_notebooks()
for nb in notebooks:
artifacts = get_studio_artifacts(nb["id"])
audio = [a for a in artifacts if a.get("type") == "audio" and a.get("status") == "completed"]
if audio:
print(f"Notebook: {nb['title']}")
print(f" Audio artifact ID: {audio[-1]['id']}")