notebooklm-mcp-server 1.1.6 → 1.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -54,6 +54,9 @@ npm install -g notebooklm-mcp-server
54
54
  npx playwright install chromium
55
55
  ```
56
56
 
57
+ > [!NOTE]
58
+ > **Auto-punto-actualización**: El servidor comprueba automáticamente si hay nuevas versiones al arrancar. Si existe una actualización, se instalará sola y te pedirá reiniciar para asegurar que siempre tengas las últimas correcciones de Google.
59
+
57
60
  ### 2. Direct usage with NPX (Zero-Config)
58
61
 
59
62
  If you don't want to install it globally, you can run it directly:
@@ -76,6 +79,9 @@ Before using the server, you must link it to your Google Account. This version u
76
79
  2. A browser window will open. Log in with your Google account.
77
80
  3. Close the browser once you see your notebooks. Your session is now securely saved locally.
78
81
 
82
+ > [!TIP]
83
+ > **Sesión Expirada?** Si tu agente recibe errores de autenticación, simplemente pídele que ejecute la herramienta `refresh_auth`. Abrirá el navegador automáticamente para que renueves la sesión sin salir de tu chat.
84
+
79
85
  ---
80
86
 
81
87
  ## ⚡ Quick Start
@@ -170,17 +176,45 @@ claude skill add notebooklm -- "npx -y notebooklm-mcp-server start"
170
176
 
171
177
  ## 📖 Documentation
172
178
 
173
- | Tool | Description |
174
- | :------------------------ | :---------------------------------------------------- |
175
- | `list_notebooks` | Lists all notebooks available in your account. |
176
- | `create_notebook` | Creates a new notebook with an optional title. |
177
- | `get_notebook` | Retrieves the details and sources of a notebook. |
178
- | `query_notebook` | Asks a grounded question to a specific notebook. |
179
- | `add_source_url` | Adds a website or YouTube video as a source. |
180
- | `add_source_text` | Adds pasted text content as a source. |
181
- | `generate_audio_overview` | Triggers the generation of an Audio Overview podcast. |
182
- | `rename_notebook` | Renames an existing notebook. |
183
- | `delete_notebook` | Deletes a notebook (Warning: Destructive). |
179
+ The following tools are available through this MCP server:
180
+
181
+ ### 📒 Notebook Management
182
+ | Tool | Description |
183
+ | :----------------- | :---------------------------------------------------- |
184
+ | `notebook_list` | Lists all notebooks in your account. |
185
+ | `notebook_create` | Creates a new notebook with a title. |
186
+ | `notebook_rename` | Renames an existing notebook. |
187
+ | `notebook_delete` | Deletes a notebook (Warning: Destructive). |
188
+
189
+ ### 🖇️ Source Management
190
+ | Tool | Description |
191
+ | :----------------------- | :----------------------------------------------------- |
192
+ | `notebook_add_url` | Adds a website or YouTube video as a source. |
193
+ | `notebook_add_text` | Adds custom text content as a source. |
194
+ | `notebook_add_local_file` | Uploads a local PDF, Markdown or Text file. |
195
+ | `notebook_add_drive` | Adds a file from Google Drive (Docs, Slides, etc). |
196
+ | `source_delete` | Removes a source from a notebook. |
197
+ | `source_sync` | Syncs a Drive source to get the latest version. |
198
+
199
+ ### 🔍 Research & Query
200
+ | Tool | Description |
201
+ | :----------------- | :---------------------------------------------------- |
202
+ | `notebook_query` | Asks a grounded question to a specific notebook. |
203
+ | `research_start` | Starts a web/drive research task. |
204
+ | `research_poll` | Polls for research status and results. |
205
+ | `research_import` | Imports research results as permanent sources. |
206
+
207
+ ### 🎨 Studio & Generation
208
+ | Tool | Description |
209
+ | :---------------------- | :---------------------------------------------------- |
210
+ | `audio_overview_create` | Generates an Audio Overview (podcast). |
211
+ | `studio_poll` | Checks status of generated audio/video artifacts. |
212
+ | `mind_map_generate` | Generates a Mind Map JSON from sources. |
213
+
214
+ ### ⚙️ System
215
+ | Tool | Description |
216
+ | :------------- | :----------------------------------------------------------------- |
217
+ | `refresh_auth` | **Interactive**: Opens a browser to renew your Google session. Use this if tools start failing. |
184
218
 
185
219
  ---
186
220
 
package/dist/auth-cli.js CHANGED
@@ -1,23 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
  import { AuthManager } from './auth.js';
3
3
  import chalk from 'chalk';
4
- import ora from 'ora';
5
4
  export async function runAuthCli() {
6
5
  const auth = new AuthManager();
7
- console.log('\n' + chalk.cyan.bold('╔═══════════════════════════════════════════╗'));
8
- console.log(chalk.cyan.bold('║ NotebookLM MCP Authentication ║'));
9
- console.log(chalk.cyan.bold('╚═══════════════════════════════════════════╝\n'));
10
- const spinner = ora('Initializing browser...').start();
6
+ // Use stderr for ALL logs to avoid breaking MCP stdout
7
+ console.error('\n' + chalk.cyan.bold('╔═══════════════════════════════════════════╗'));
8
+ console.error(chalk.cyan.bold('║ NotebookLM MCP Authentication ║'));
9
+ console.error(chalk.cyan.bold('╚═══════════════════════════════════════════╝\n'));
11
10
  try {
12
11
  await auth.runAuthentication((status) => {
13
- spinner.text = status;
12
+ console.error(chalk.blue(`[Status] ${status}`));
14
13
  });
15
- spinner.succeed(chalk.green.bold('Authentication successful!'));
16
- console.log('\n' + chalk.white('Your session is now active. You can use the server with your favorite MCP client.'));
14
+ console.error('\n' + chalk.green.bold('Authentication successful!'));
15
+ console.error(chalk.white('Your session is now active. You can close any leftovers and return to your chat.'));
17
16
  }
18
17
  catch (error) {
19
- spinner.fail(chalk.red.bold('Authentication failed'));
20
- console.error('\n' + chalk.red('Error: ') + error.message);
18
+ console.error('\n' + chalk.red.bold('Authentication failed'));
19
+ console.error(chalk.red('Error: ') + error.message);
21
20
  process.exit(1);
22
21
  }
23
22
  }
package/dist/auth.js CHANGED
@@ -89,7 +89,7 @@ export class AuthManager {
89
89
  fs.mkdirSync(path.dirname(this.authPath), { recursive: true });
90
90
  }
91
91
  fs.writeFileSync(this.authPath, JSON.stringify(authData, null, 2));
92
- console.log(`Authentication successful! Cookies saved to ${this.authPath}`);
92
+ console.error(`Authentication successful! Cookies saved to ${this.authPath}`);
93
93
  await browser.close();
94
94
  }
95
95
  getSavedCookies() {
package/dist/client.js CHANGED
@@ -30,8 +30,8 @@ export class NotebookLMClient {
30
30
  * Internal RPC executor with correct batchexecute envelope format.
31
31
  */
32
32
  async callRpc(rpcId, params, _retryCount = 0) {
33
- // Current Google batchexecute envelope format
34
- const fReq = JSON.stringify([[[rpcId, JSON.stringify(params), null, "1"]]]);
33
+ // Use the 'generic' identifier which is more robust across Google services
34
+ const fReq = JSON.stringify([[[rpcId, JSON.stringify(params), null, "generic"]]]);
35
35
  const body = new URLSearchParams();
36
36
  body.append('f.req', fReq);
37
37
  if (this.csrfToken) {
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ const program = new Command();
5
5
  program
6
6
  .name('notebooklm-mcp-server')
7
7
  .description('NotebookLM MCP Server (Node.js)')
8
- .version('1.1.6');
8
+ .version('1.1.7');
9
9
  program
10
10
  .command('server')
11
11
  .description('Start the MCP server (default)')
package/dist/server.js CHANGED
@@ -6,7 +6,7 @@ import { AuthManager } from "./auth.js";
6
6
  import chalk from "chalk";
7
7
  const server = new Server({
8
8
  name: "notebooklm-mcp-server",
9
- version: "1.1.6",
9
+ version: "1.1.7",
10
10
  }, {
11
11
  capabilities: {
12
12
  tools: {},
@@ -276,20 +276,27 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
276
276
  switch (name) {
277
277
  case "notebook_list":
278
278
  const notebooks = await client.listNotebooks();
279
- if (!notebooks || notebooks.length === 0) {
280
- return { content: [{ type: "text", text: "No se encontraron cuadernos. Si crees que esto es un error, intenta ejecutar 'refresh_auth' para renovar la sesión." }] };
281
- }
282
- const listText = notebooks.map(n => `- ${n.title} (ID: ${n.id})`).join('\n');
283
- return { content: [{ type: "text", text: `Has encontrado ${notebooks.length} cuadernos:\n\n${listText}` }] };
279
+ return {
280
+ content: [
281
+ {
282
+ type: "text",
283
+ text: JSON.stringify({
284
+ status: "success",
285
+ notebooks: notebooks || [],
286
+ count: notebooks?.length || 0
287
+ }, null, 2)
288
+ }
289
+ ]
290
+ };
284
291
  case "notebook_create":
285
292
  const newId = await client.createNotebook(args?.title);
286
- return { content: [{ type: "text", text: `Cuaderno creado exitosamente con ID: ${newId}` }] };
293
+ return { content: [{ type: "text", text: JSON.stringify({ status: "success", notebook_id: newId }) }] };
287
294
  case "notebook_delete":
288
295
  await client.deleteNotebook(args?.notebook_id);
289
- return { content: [{ type: "text", text: `Cuaderno eliminado exitosamente.` }] };
296
+ return { content: [{ type: "text", text: JSON.stringify({ status: "success", message: `Deleted notebook ${args?.notebook_id}` }) }] };
290
297
  case "notebook_rename":
291
298
  await client.renameNotebook(args?.notebook_id, args?.title);
292
- return { content: [{ type: "text", text: `Cuaderno renombrado correctamente a: ${args?.title}` }] };
299
+ return { content: [{ type: "text", text: JSON.stringify({ status: "success", message: `Renamed notebook to ${args?.title}` }) }] };
293
300
  case "notebook_add_url":
294
301
  const sourceIdUrl = await client.addUrlSource(args?.notebook_id, args?.url);
295
302
  return { content: [{ type: "text", text: JSON.stringify({ status: "success", source_id: sourceIdUrl }) }] };
@@ -356,15 +363,22 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
356
363
  catch (error) {
357
364
  console.error(chalk.red(`Tool execution error [${name}]:`), error);
358
365
  return {
359
- content: [{ type: "text", text: `Error de ejecución: ${error.message || String(error)}` }],
360
- isError: true,
366
+ content: [
367
+ {
368
+ type: "text",
369
+ text: JSON.stringify({
370
+ status: "error",
371
+ error: error.message || String(error)
372
+ }, null, 2)
373
+ }
374
+ ]
361
375
  };
362
376
  }
363
377
  });
364
378
  async function main() {
365
379
  const transport = new StdioServerTransport();
366
380
  await server.connect(transport);
367
- console.error("NotebookLM MCP Server v1.1.6 running on stdio");
381
+ console.error("NotebookLM MCP Server v1.1.7 running on stdio");
368
382
  }
369
383
  main().catch((error) => {
370
384
  console.error("Fatal error:", error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "notebooklm-mcp-server",
3
- "version": "1.1.6",
3
+ "version": "1.1.7",
4
4
  "description": "Node.js Model Context Protocol server for Google NotebookLM",
5
5
  "type": "module",
6
6
  "repository": {