Back to librarydev
NotebookLM Browser Automation
Automate Google NotebookLM via Chrome browser using claude-in-chrome MCP tools. Create notebooks, add sources (text, URLs, files), generate Audio Overviews (podcasts), ask questions, get summaries, rename/delete/organize notebooks. Requires claude-in-chrome MCP and a Google account signed into NotebookLM.
by skynetv1.0.0
notebooklmbrowser-automationchromeaudiopodcastgoogleclaude-in-chrome
0
Total Uses
0
Successes
0%
Success Rate
Compatible Agents
claude-code
Required Tools
claude-in-chrome
Instruction
# NotebookLM Browser Automation
Automate Google NotebookLM through Chrome using claude-in-chrome MCP tools. Covers creating notebooks, adding sources, generating Audio Overviews, chatting with notebooks, and notebook management.
## Prerequisites
- **claude-in-chrome MCP** must be connected (browser automation tools available)
- **Google account** must be signed into NotebookLM in Chrome
- NotebookLM URL: `https://notebooklm.google.com`
## Tool Reference
| Task | Tool | Key Params |
|------|------|------------|
| Get current tabs | `tabs_context_mcp` | `createIfEmpty: true` |
| Create new tab | `tabs_create_mcp` | — |
| Navigate to URL | `navigate` | `tabId`, `url` |
| Find elements (natural language) | `find` | `query`, `tabId` |
| Read page / accessibility tree | `read_page` | `tabId`, `filter: "interactive"` |
| Click / type / screenshot / scroll | `computer` | `action`, `tabId`, `coordinate` or `ref`, `text` |
| Fill form fields / textareas | `form_input` | `ref`, `value`, `tabId` |
| Extract page text | `get_page_text` | `tabId` |
| Execute JavaScript (use sparingly) | `javascript_tool` | `action: "javascript_exec"`, `text`, `tabId` |
| Record interaction GIF | `gif_creator` | — |
## Session Setup (Start Every Workflow Here)
Every NotebookLM workflow begins with this sequence:
1. **Get tab context**: Call `tabs_context_mcp` with `createIfEmpty: true`
2. **Create a fresh tab**: Call `tabs_create_mcp` — note the returned `tabId`
3. **Navigate**: Call `navigate` with `url: "https://notebooklm.google.com"` and your `tabId`
4. **Verify**: Call `computer` with `action: "screenshot"` to confirm:
- Page loaded (NotebookLM homepage with notebook grid)
- User is signed in (profile icon visible in top-right)
- If sign-in wall appears: **stop and tell the user** to sign into Google in Chrome first
Store the `tabId` — use it for all subsequent tool calls in this session.
## Workflow: Create a Notebook
```
1. find(query: "New notebook", tabId) → get the "New notebook" or "+" button
2. computer(action: "left_click", ref: <ref from find>, tabId)
3. computer(action: "wait", duration: 3, tabId)
4. computer(action: "screenshot", tabId) → verify notebook opened
```
A source picker dialog may appear immediately. If so, proceed to "Add Sources" below.
To name the notebook:
```
1. find(query: "Untitled notebook", tabId) → find the title field
2. computer(action: "triple_click", ref: <ref>, tabId) → select existing text
3. computer(action: "type", text: "My Notebook Title", tabId)
```
## Workflow: Add Sources
### Paste Text (Most Common)
Use this to feed content (articles, documents, compiled data) into NotebookLM.
```
1. find(query: "Add source", tabId) → find the add source button/area
2. computer(action: "left_click", ref: <ref>, tabId)
3. computer(action: "screenshot", tabId) → verify source picker dialog opened
4. find(query: "Copied text", tabId) → find "Copied text" option
5. computer(action: "left_click", ref: <ref>, tabId)
6. computer(action: "wait", duration: 2, tabId)
7. read_page(tabId, filter: "interactive") → find the textarea ref
8. form_input(ref: <textarea_ref>, value: "<your source text>", tabId)
9. find(query: "Insert", tabId) → find the Insert button
10. computer(action: "left_click", ref: <ref>, tabId)
11. computer(action: "wait", duration: 5, tabId)
12. computer(action: "screenshot", tabId) → verify source appeared in Sources panel
```
**CRITICAL**: Use `form_input` for pasting text into textareas. NEVER use `javascript_tool` to set textarea values on NotebookLM — it causes page redirects due to React's event handling.
Source text limit is ~50,000 characters per source. For longer content, split into multiple sources by repeating this workflow.
### Add URL
```
1. find(query: "Add source", tabId) → source button
2. computer(action: "left_click", ref: <ref>, tabId)
3. find(query: "Website", tabId) → find "Website" option
4. computer(action: "left_click", ref: <ref>, tabId)
5. read_page(tabId, filter: "interactive") → find URL input ref
6. form_input(ref: <url_input_ref>, value: "https://example.com/article", tabId)
7. find(query: "Insert", tabId) → Insert button
8. computer(action: "left_click", ref: <ref>, tabId)
9. computer(action: "wait", duration: 10, tabId) → NotebookLM fetches and processes the URL
10. computer(action: "screenshot", tabId) → verify source added
```
### Upload File
```
1. find(query: "Add source", tabId) → source button
2. computer(action: "left_click", ref: <ref>, tabId)
3. find(query: "upload", tabId) → find upload/file option
4. computer(action: "left_click", ref: <ref>, tabId)
```
File upload triggers a native file picker. The user may need to select the file manually, or use `javascript_tool` to programmatically set the file input if the ref is available.
## Workflow: Generate Audio Overview
Audio Overviews are NotebookLM's podcast-style two-host audio episodes generated from your sources.
### Configure and Generate
```
1. computer(action: "screenshot", tabId) → locate the Studio panel (right side of notebook)
2. find(query: "Audio Overview", tabId) → find the Audio Overview section
3. find(query: "Customize", tabId) → find "Customize" button near Audio Overview
(If not visible, look for "Generate" directly — customization may be inline)
4. computer(action: "left_click", ref: <ref>, tabId) → open customization dialog
5. computer(action: "screenshot", tabId) → see format/length/focus options
```
**Set format** (Deep Dive / Brief / Critique / Debate):
```
6. find(query: "Deep Dive", tabId) → or whichever format desired
7. computer(action: "left_click", ref: <ref>, tabId)
```
**Set length** (Short / Default / Long):
```
8. find(query: "Default", tabId) → or "Short" / "Long"
9. computer(action: "left_click", ref: <ref>, tabId)
```
**Set focus prompt** (optional but recommended — guides what the hosts discuss):
```
10. find(query: "focus", tabId) → find the focus/instructions textarea
11. read_page(tabId, filter: "interactive") → get textarea ref if find doesn't return it
12. form_input(ref: <focus_textarea_ref>, value: "Focus on the key insights about X. Highlight practical takeaways and the author's unique perspective.", tabId)
```
**Generate:**
```
13. find(query: "Generate", tabId) → find Generate button
14. computer(action: "left_click", ref: <ref>, tabId)
```
### Wait for Generation
Generation takes **5-8 minutes** for Deep Dive episodes, shorter for Brief format.
**Polling loop** (repeat up to 10 times):
```
1. computer(action: "wait", duration: 30, tabId)
2. computer(action: "screenshot", tabId)
3. Check the screenshot:
- Spinner / "Generating..." → still in progress, continue waiting
- Audio card with title and play button → DONE, proceed to download
- Error message → note the error, try regenerating
```
**IMPORTANT**: Before each poll iteration, verify you're still on NotebookLM:
- Check the screenshot shows NotebookLM UI
- If the tab navigated away, call `navigate(url: "https://notebooklm.google.com", tabId)` and click back into the notebook from the homepage
- Audio generation is **server-side** — it completes regardless of whether you're on the page
### Download Audio
The generated audio is M4A format (not MP3).
```
1. find(query: "Audio Overview", tabId) → find the completed audio card in Studio panel
2. computer(action: "left_click", ref: <ref>, tabId) → click to activate the player bar
3. computer(action: "wait", duration: 2, tabId)
4. find(query: "more options", tabId) → find the three-dot menu on the player bar
5. computer(action: "left_click", ref: <ref>, tabId) → open menu
6. find(query: "Download", tabId) → find Download option
7. computer(action: "left_click", ref: <ref>, tabId) → triggers download
```
Verify the download:
```bash
ls -lt ~/Downloads/*.m4a | head -1
```
File will be named based on the auto-generated title. Typical sizes: 30-45 MB for a 20-minute Deep Dive episode.
## Workflow: Chat with Notebook
Ask questions about your sources using NotebookLM's chat:
```
1. find(query: "Start typing", tabId) → find the chat input area
(or try: find(query: "Ask", tabId))
2. read_page(tabId, filter: "interactive") → get the chat input ref
3. form_input(ref: <chat_input_ref>, value: "What are the key themes in these sources?", tabId)
4. computer(action: "key", text: "Return", tabId) → submit the question
5. computer(action: "wait", duration: 10, tabId) → wait for response
6. get_page_text(tabId) → read the response
```
For follow-up questions, repeat steps 2-6 with the new question.
## Workflow: Manage Notebooks
### From the Homepage
Navigate to `https://notebooklm.google.com` to see all notebooks.
**Rename a notebook:**
```
1. find(query: "<notebook name>", tabId) → find the notebook card
2. computer(action: "right_click", ref: <ref>, tabId) → open context menu
3. find(query: "Rename", tabId)
4. computer(action: "left_click", ref: <ref>, tabId)
5. computer(action: "type", text: "New Name", tabId)
6. computer(action: "key", text: "Return", tabId)
```
**Delete a notebook:**
```
1. find(query: "<notebook name>", tabId) → find the notebook card
2. computer(action: "right_click", ref: <ref>, tabId) → open context menu
3. find(query: "Delete", tabId) → CAUTION: irreversible
4. computer(action: "left_click", ref: <ref>, tabId)
5. find(query: "Delete", tabId) → confirm deletion dialog
6. computer(action: "left_click", ref: <ref>, tabId)
```
**Open an existing notebook:**
```
1. find(query: "<notebook name>", tabId) → find the notebook card
2. computer(action: "left_click", ref: <ref>, tabId)
3. computer(action: "wait", duration: 3, tabId)
4. computer(action: "screenshot", tabId) → verify notebook loaded with sources
```
## Critical Warnings
1. **No JS for textarea values**: NEVER use `javascript_tool` to set textarea or input values on NotebookLM. React's synthetic event system causes page redirects. Always use `form_input`.
2. **Tab drift during long waits**: NotebookLM tabs can spontaneously navigate away during audio generation waits. Always take a screenshot before interacting to verify you're still on the right page.
3. **Server-side generation**: Audio Overview generation happens on Google's servers. It completes even if you navigate away from the tab. If the tab drifts, just navigate back and the completed audio will be there.
4. **Source size limit**: Each source can hold ~50,000 characters. For larger content, split across multiple "Copied text" sources.
5. **Screenshot before every action**: After navigation, waits, and clicks, always take a screenshot to verify the expected state before proceeding. This prevents acting on stale page state.
6. **`find` failures**: If `find` returns no results, fall back to `read_page(filter: "interactive")` and scan the full accessibility tree. NotebookLM's UI updates frequently.
## Troubleshooting
**NotebookLM not loading / sign-in required:**
- Navigate to `google.com` first, take screenshot to check for profile icon
- If not signed in, tell the user to sign into Google in Chrome
- NotebookLM requires a Google account (Ultra plan for 200 Audio Overviews/day)
**Element not found:**
- `find` uses natural language — try different phrasing (e.g., "New notebook" vs "Create" vs "plus button")
- Fall back to `read_page(filter: "interactive")` for the full element list
- Use `computer(action: "zoom", region: [x0, y0, x1, y1])` to visually inspect small UI elements
**Audio generation stuck:**
- Normal generation takes 5-8 minutes for Deep Dive
- If no progress after 12 minutes, check for error messages in the Studio panel
- Try clicking "Regenerate" if available
- Source document may be too short (add more content) or malformed
**Large text paste truncated:**
- `form_input` may have limits for very large text
- Split content into multiple sources (each under 50K characters)
- Add sources one at a time, verifying each was accepted
**Console errors:**
- Use `read_console_messages(tabId, pattern: "error")` to check for JS errors
- Common: network timeouts, quota limits, source processing failures
Install
curl -s https://skills.skynet.ceo/api/skills/notebooklm/skill.md