Google NotebookLM over MCP + a local HTTP REST API. Citation-backed Q&A, audio/video/content generation, multi-account rotation. For Claude Code, Codex, Cursor, n8n, Zapier, Make.
This MCP server automates Google NotebookLM by providing a REST API and MCP interface for citation-backed Q&A, content generation (audio, video, infog...
952app.get('/content/download', async (req: Request, res: Response) => {
953 try {
954 const { content_type, output_path, notebook_url, session_id } = req.query;
955 ...
956 const result = await toolHandlers.handleDownloadContent({
957 content_type: content_type as ...,
958 output_path: typeof output_path === 'string' ? output_path : undefined,
959 ...
960 });// Network-exposed MCP server; an attacker can send HTTP requests to this endpoint.
128app.post('/batch-to-vault', async (req: Request, res: Response) => {
129 ...
130 const { ..., vault_dir, ... } = req.body;
131 if (!vault_dir || typeof vault_dir !== 'string') {
132 return res.status(400).json({ ... });
133 }
134 ...
135 const result = await toolHandlers.handleBatchToVault({
136 ...,
137 vault_dir,
138 ...
139 });// Network-exposed MCP server; an attacker can send HTTP requests to this endpoint.
684app.post('/content/sources', async (req: Request, res: Response) => {
685 try {
686 const { source_type, file_path, url, text, title, notebook_url, session_id, show_browser } =
687 req.body;
688 ...
689 const result = await toolHandlers.handleAddSource({
690 source_type,
691 file_path,
692 ...
693 });// Network-exposed MCP server; an attacker can send HTTP requests to this endpoint.
231loginEmail: process.env.LOGIN_EMAIL || config.loginEmail,
232loginPassword: process.env.LOGIN_PASSWORD || config.loginPassword,// Network-exposed MCP server; environment variables may be leaked through various channels.
1153function tryKillPort(port: number): boolean {
1154 const isWindows = process.platform === 'win32';
1155 try {
1156 if (isWindows) {
1157 const output = execSync(`netstat -ano | findstr :${port} | findstr LISTENING`, {
1158 encoding: 'utf-8',
1159 timeout: 5000,
1160 });
1161 ...
1162 for (const pid of pids) {
1163 try {
1164 execSync(`taskkill /F /PID ${pid}`, { timeout: 5000 });
1165 ...
1166 } catch {}
1167 }
1168 } else {
1169 execSync(`fuser -k ${port}/tcp`, { timeout: 5000 });
1170 ...
1171 }
1172 } catch {
1173 return false;
1174 }
1175}// Network-exposed MCP server; exploitation requires control over port or PID values.
30const app = express();
31app.use(express.json({ limit: '10mb' }));
32...
33app.use((_req, res, next) => {
34 res.header('Access-Control-Allow-Origin', '*');
35 res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
36 res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
37 if (_req.method === 'OPTIONS') {
38 return res.sendStatus(200);
39 }
40 next();
41});// Network-exposed MCP server; no authentication on any endpoint.
243app.post('/cleanup-data', async (req: Request, res: Response) => {
244 try {
245 const { confirm, preserve_library } = req.body;
246 const result = await toolHandlers.handleCleanupData({ confirm, preserve_library });
247 res.json(result);
248 } catch (error) { ... }// Network-exposed MCP server; no authentication required.
684app.post('/content/sources', async (req: Request, res: Response) => {
685 try {
686 const { source_type, file_path, url, text, title, notebook_url, session_id, show_browser } =
687 req.body;
688 ...
689 const result = await toolHandlers.handleAddSource({
690 source_type,
691 url,
692 ...
693 });// Network-exposed MCP server; an attacker can send HTTP requests to this endpoint.
270app.post('/notebooks', async (req: Request, res: Response) => {
271 try {
272 const { url, name, description, topics, content_types, use_cases, tags } = req.body;
273 if (!url || !name || !description || !topics) {
274 return res.status(400).json({ ... });
275 }
276 const result = await toolHandlers.handleAddNotebook({
277 url,
278 name,
279 description,
280 topics,
281 content_types,
282 use_cases,
283 tags,
284 });// Network-exposed MCP server; an attacker can send HTTP requests to this endpoint.
527app.post('/notebooks/auto-discover', async (req: Request, res: Response) => {
528 try {
529 const { url } = req.body;
530 if (!url) { ... }
531 try {
532 const parsedUrl = new URL(url);
533 if (parsedUrl.hostname !== 'notebooklm.google.com') {
534 return res.status(400).json({ ... });
535 }
536 } catch { ... }
537 const autoDiscovery = new AutoDiscovery(sessionManager);
538 let metadata;
539 try {
540 metadata = await autoDiscovery.discoverMetadata(url);
541 } catch (error) { ... }// Network-exposed MCP server; an attacker can send HTTP requests to this endpoint.