notebooklm-mcp-server 3.0.1 → 3.0.3
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/dist/auth.js +20 -3
- package/dist/client.d.ts +10 -0
- package/dist/client.js +54 -1
- package/dist/server.js +1 -1
- package/package.json +1 -1
package/dist/auth.js
CHANGED
|
@@ -77,10 +77,27 @@ export class AuthManager {
|
|
|
77
77
|
}
|
|
78
78
|
if (onStatus)
|
|
79
79
|
onStatus('Extracting secure session cookies...');
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
// CRITICAL: Filter cookies to only those that match notebooklm.google.com
|
|
81
|
+
// Playwright's context.cookies() without URL returns ALL cookies from ALL domains
|
|
82
|
+
// (including accounts.google.com, youtube.com, etc.), causing duplicate cookie names
|
|
83
|
+
// and conflicting session values. CDP's Network.getCookies (used by Python) only
|
|
84
|
+
// returns cookies for the current page URL. We match that behavior here.
|
|
85
|
+
const allCookies = await context.cookies('https://notebooklm.google.com');
|
|
86
|
+
// Deduplicate by name (keep last value, like browsers do)
|
|
87
|
+
const cookieMap = new Map();
|
|
88
|
+
for (const c of allCookies) {
|
|
89
|
+
cookieMap.set(c.name, c.value);
|
|
90
|
+
}
|
|
91
|
+
const cookieString = Array.from(cookieMap.entries())
|
|
92
|
+
.map(([name, value]) => `${name}=${value}`)
|
|
83
93
|
.join('; ');
|
|
94
|
+
// Validate that required session cookies are present
|
|
95
|
+
const REQUIRED_COOKIES = ['SID', 'HSID', 'SSID', 'APISID', 'SAPISID'];
|
|
96
|
+
const missingCookies = REQUIRED_COOKIES.filter(name => !cookieMap.has(name));
|
|
97
|
+
if (missingCookies.length > 0) {
|
|
98
|
+
console.error(`Warning: Missing required cookies: ${missingCookies.join(', ')}`);
|
|
99
|
+
}
|
|
100
|
+
console.error(`Extracted ${cookieMap.size} unique cookies for notebooklm.google.com`);
|
|
84
101
|
const authData = {
|
|
85
102
|
cookies: cookieString,
|
|
86
103
|
updatedAt: new Date().toISOString()
|
package/dist/client.d.ts
CHANGED
|
@@ -68,6 +68,16 @@ export declare class NotebookLMClient {
|
|
|
68
68
|
*/
|
|
69
69
|
private extractRpcResult;
|
|
70
70
|
listNotebooks(): Promise<Notebook[]>;
|
|
71
|
+
/**
|
|
72
|
+
* Get a single notebook's data including all source IDs.
|
|
73
|
+
* Uses the GET_NOTEBOOK RPC (rLM1Ne).
|
|
74
|
+
*/
|
|
75
|
+
getNotebook(notebookId: string): Promise<any>;
|
|
76
|
+
/**
|
|
77
|
+
* Extract source IDs from raw notebook data returned by getNotebook().
|
|
78
|
+
* Matches Python _extract_source_ids_from_notebook().
|
|
79
|
+
*/
|
|
80
|
+
private extractSourceIdsFromNotebook;
|
|
71
81
|
createNotebook(title: string): Promise<string>;
|
|
72
82
|
deleteNotebook(notebookId: string): Promise<boolean>;
|
|
73
83
|
renameNotebook(notebookId: string, newTitle: string): Promise<boolean>;
|
package/dist/client.js
CHANGED
|
@@ -340,6 +340,47 @@ export class NotebookLMClient {
|
|
|
340
340
|
}
|
|
341
341
|
return notebooks;
|
|
342
342
|
}
|
|
343
|
+
/**
|
|
344
|
+
* Get a single notebook's data including all source IDs.
|
|
345
|
+
* Uses the GET_NOTEBOOK RPC (rLM1Ne).
|
|
346
|
+
*/
|
|
347
|
+
async getNotebook(notebookId) {
|
|
348
|
+
// Python: params = [notebook_id, None, [2], None, 0]
|
|
349
|
+
const result = await this.callRpc(RPC_IDS.GET_NOTEBOOK, [notebookId, null, [2], null, 0], `/notebook/${notebookId}`);
|
|
350
|
+
return result;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Extract source IDs from raw notebook data returned by getNotebook().
|
|
354
|
+
* Matches Python _extract_source_ids_from_notebook().
|
|
355
|
+
*/
|
|
356
|
+
extractSourceIdsFromNotebook(notebookData) {
|
|
357
|
+
const sourceIds = [];
|
|
358
|
+
if (!notebookData || !Array.isArray(notebookData))
|
|
359
|
+
return sourceIds;
|
|
360
|
+
try {
|
|
361
|
+
// Structure: notebookData[0] = [title, sources_array, notebook_id, ...]
|
|
362
|
+
const notebookInfo = Array.isArray(notebookData[0]) ? notebookData[0] : notebookData;
|
|
363
|
+
if (notebookInfo.length > 1 && Array.isArray(notebookInfo[1])) {
|
|
364
|
+
const sources = notebookInfo[1];
|
|
365
|
+
for (const source of sources) {
|
|
366
|
+
// Each source: [[source_id], title, metadata, ...]
|
|
367
|
+
if (Array.isArray(source) && source.length > 0) {
|
|
368
|
+
const sourceIdWrapper = source[0];
|
|
369
|
+
if (Array.isArray(sourceIdWrapper) && sourceIdWrapper.length > 0) {
|
|
370
|
+
const sourceId = sourceIdWrapper[0];
|
|
371
|
+
if (typeof sourceId === 'string') {
|
|
372
|
+
sourceIds.push(sourceId);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
catch {
|
|
380
|
+
// ignore parse errors
|
|
381
|
+
}
|
|
382
|
+
return sourceIds;
|
|
383
|
+
}
|
|
343
384
|
async createNotebook(title) {
|
|
344
385
|
// Python: params = [title, None, None, [2], [1, None, None, None, None, None, None, None, None, None, [1]]]
|
|
345
386
|
const params = [title, null, null, [2], [1, null, null, null, null, null, null, null, null, null, [1]]];
|
|
@@ -973,9 +1014,21 @@ export class NotebookLMClient {
|
|
|
973
1014
|
// =========================================================================
|
|
974
1015
|
async query(notebookId, queryText, sourceIds, conversationId, _retryCount = 0) {
|
|
975
1016
|
await this.init();
|
|
1017
|
+
// Auto-fetch source_ids from notebook if not provided (matches Python behavior)
|
|
1018
|
+
if (!sourceIds || sourceIds.length === 0) {
|
|
1019
|
+
try {
|
|
1020
|
+
const notebookData = await this.getNotebook(notebookId);
|
|
1021
|
+
sourceIds = this.extractSourceIdsFromNotebook(notebookData);
|
|
1022
|
+
console.error(`[NotebookLM] Auto-fetched ${sourceIds.length} source IDs from notebook`);
|
|
1023
|
+
}
|
|
1024
|
+
catch (e) {
|
|
1025
|
+
console.error(`[NotebookLM] Warning: Could not auto-fetch source IDs: ${e.message}`);
|
|
1026
|
+
sourceIds = [];
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
976
1029
|
const cid = conversationId || uuidv4();
|
|
977
1030
|
// Python: sources_array = [[[sid]] for sid in source_ids] (triple nested)
|
|
978
|
-
const sources = sourceIds ? sourceIds.map(id => [[id]]) : [];
|
|
1031
|
+
const sources = sourceIds.length > 0 ? sourceIds.map(id => [[id]]) : [];
|
|
979
1032
|
// Python: params = [sources_array, query_text, None, [2, null, [1]], conversation_id]
|
|
980
1033
|
const params = [
|
|
981
1034
|
sources,
|
package/dist/server.js
CHANGED
|
@@ -4,7 +4,7 @@ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextpro
|
|
|
4
4
|
import { NotebookLMClient } from "./client.js";
|
|
5
5
|
import { AuthManager } from "./auth.js";
|
|
6
6
|
import chalk from "chalk";
|
|
7
|
-
const VERSION = "3.0.
|
|
7
|
+
const VERSION = "3.0.3";
|
|
8
8
|
const server = new Server({
|
|
9
9
|
name: "notebooklm-mcp-server",
|
|
10
10
|
version: VERSION,
|