@roomi-fields/notebooklm-mcp 1.3.3 → 1.3.5
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 +764 -715
- package/dist/__tests__/cleanup-manager.test.d.ts +2 -0
- package/dist/__tests__/cleanup-manager.test.d.ts.map +1 -0
- package/dist/__tests__/cleanup-manager.test.js +341 -0
- package/dist/__tests__/cleanup-manager.test.js.map +1 -0
- package/dist/__tests__/config-parsing.test.d.ts +2 -0
- package/dist/__tests__/config-parsing.test.d.ts.map +1 -0
- package/dist/__tests__/config-parsing.test.js +338 -0
- package/dist/__tests__/config-parsing.test.js.map +1 -0
- package/dist/__tests__/config.test.d.ts +2 -0
- package/dist/__tests__/config.test.d.ts.map +1 -0
- package/dist/__tests__/config.test.js +267 -0
- package/dist/__tests__/config.test.js.map +1 -0
- package/dist/__tests__/errors.test.d.ts +2 -0
- package/dist/__tests__/errors.test.d.ts.map +1 -0
- package/dist/__tests__/errors.test.js +166 -0
- package/dist/__tests__/errors.test.js.map +1 -0
- package/dist/__tests__/logger.test.d.ts +2 -0
- package/dist/__tests__/logger.test.d.ts.map +1 -0
- package/dist/__tests__/logger.test.js +324 -0
- package/dist/__tests__/logger.test.js.map +1 -0
- package/dist/__tests__/page-utils.test.d.ts +2 -0
- package/dist/__tests__/page-utils.test.d.ts.map +1 -0
- package/dist/__tests__/page-utils.test.js +349 -0
- package/dist/__tests__/page-utils.test.js.map +1 -0
- package/dist/__tests__/setup-verification.test.d.ts +2 -0
- package/dist/__tests__/setup-verification.test.d.ts.map +1 -0
- package/dist/__tests__/setup-verification.test.js +15 -0
- package/dist/__tests__/setup-verification.test.js.map +1 -0
- package/dist/__tests__/stealth-utils.test.d.ts +2 -0
- package/dist/__tests__/stealth-utils.test.d.ts.map +1 -0
- package/dist/__tests__/stealth-utils.test.js +413 -0
- package/dist/__tests__/stealth-utils.test.js.map +1 -0
- package/dist/__tests__/types.test.d.ts +2 -0
- package/dist/__tests__/types.test.d.ts.map +1 -0
- package/dist/__tests__/types.test.js +461 -0
- package/dist/__tests__/types.test.js.map +1 -0
- package/dist/auth/auth-manager.d.ts +2 -2
- package/dist/auth/auth-manager.d.ts.map +1 -1
- package/dist/auth/auth-manager.js +187 -180
- package/dist/auth/auth-manager.js.map +1 -1
- package/dist/auto-discovery/auto-discovery.d.ts.map +1 -1
- package/dist/auto-discovery/auto-discovery.js +17 -17
- package/dist/auto-discovery/auto-discovery.js.map +1 -1
- package/dist/cli/de-auth.d.ts +10 -0
- package/dist/cli/de-auth.d.ts.map +1 -0
- package/dist/cli/de-auth.js +47 -0
- package/dist/cli/de-auth.js.map +1 -0
- package/dist/cli/help.d.ts +6 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +67 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/setup-auth.d.ts +11 -0
- package/dist/cli/setup-auth.d.ts.map +1 -0
- package/dist/cli/setup-auth.js +82 -0
- package/dist/cli/setup-auth.js.map +1 -0
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +49 -103
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +3 -3
- package/dist/errors.js.map +1 -1
- package/dist/http-wrapper.js +96 -172
- package/dist/http-wrapper.js.map +1 -1
- package/dist/index.js +110 -107
- package/dist/index.js.map +1 -1
- package/dist/library/notebook-library.d.ts +2 -2
- package/dist/library/notebook-library.d.ts.map +1 -1
- package/dist/library/notebook-library.js +24 -24
- package/dist/library/notebook-library.js.map +1 -1
- package/dist/session/browser-session.d.ts +4 -4
- package/dist/session/browser-session.d.ts.map +1 -1
- package/dist/session/browser-session.js +62 -58
- package/dist/session/browser-session.js.map +1 -1
- package/dist/session/session-manager.d.ts +3 -3
- package/dist/session/session-manager.d.ts.map +1 -1
- package/dist/session/session-manager.js +14 -14
- package/dist/session/session-manager.js.map +1 -1
- package/dist/session/shared-context-manager.d.ts +2 -2
- package/dist/session/shared-context-manager.d.ts.map +1 -1
- package/dist/session/shared-context-manager.js +62 -58
- package/dist/session/shared-context-manager.js.map +1 -1
- package/dist/tools/index.d.ts +14 -14
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +517 -530
- package/dist/tools/index.js.map +1 -1
- package/dist/types.d.ts +24 -67
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -12
- package/dist/types.js.map +1 -1
- package/dist/utils/cleanup-manager.d.ts +1 -1
- package/dist/utils/cleanup-manager.d.ts.map +1 -1
- package/dist/utils/cleanup-manager.js +90 -92
- package/dist/utils/cleanup-manager.js.map +1 -1
- package/dist/utils/logger.d.ts +1 -2
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +15 -15
- package/dist/utils/page-utils.d.ts +1 -1
- package/dist/utils/page-utils.d.ts.map +1 -1
- package/dist/utils/page-utils.js +39 -46
- package/dist/utils/page-utils.js.map +1 -1
- package/dist/utils/stealth-utils.d.ts +2 -2
- package/dist/utils/stealth-utils.d.ts.map +1 -1
- package/dist/utils/stealth-utils.js +13 -13
- package/dist/utils/stealth-utils.js.map +1 -1
- package/docs/CHROME_PROFILE_LIMITATION.md +229 -212
- package/package.json +107 -78
package/dist/tools/index.js
CHANGED
|
@@ -11,112 +11,112 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Based on the Python implementation from tools/*.py
|
|
13
13
|
*/
|
|
14
|
-
import { CONFIG, applyBrowserOptions } from
|
|
15
|
-
import { log } from
|
|
16
|
-
import { RateLimitError } from
|
|
17
|
-
import { CleanupManager } from
|
|
14
|
+
import { CONFIG, applyBrowserOptions } from '../config.js';
|
|
15
|
+
import { log } from '../utils/logger.js';
|
|
16
|
+
import { RateLimitError } from '../errors.js';
|
|
17
|
+
import { CleanupManager } from '../utils/cleanup-manager.js';
|
|
18
18
|
/**
|
|
19
19
|
* Build dynamic tool description for ask_question based on active notebook or library
|
|
20
20
|
*/
|
|
21
21
|
function buildAskQuestionDescription(library) {
|
|
22
22
|
const active = library.getActiveNotebook();
|
|
23
23
|
if (active) {
|
|
24
|
-
const topics = active.topics.join(
|
|
25
|
-
const useCases = active.use_cases.map((uc) => ` - ${uc}`).join(
|
|
26
|
-
return `# Conversational Research Partner (NotebookLM • Gemini 2.5 • Session RAG)
|
|
27
|
-
|
|
28
|
-
**Active Notebook:** ${active.name}
|
|
29
|
-
**Content:** ${active.description}
|
|
30
|
-
**Topics:** ${topics}
|
|
31
|
-
|
|
32
|
-
> Auth tip: If login is required, use the prompt 'notebooklm.auth-setup' and then verify with the 'get_health' tool. If authentication later fails (e.g., expired cookies), use the prompt 'notebooklm.auth-repair'.
|
|
33
|
-
|
|
34
|
-
## What This Tool Is
|
|
35
|
-
- Full conversational research with Gemini (LLM) grounded on your notebook sources
|
|
36
|
-
- Session-based: each follow-up uses prior context for deeper, more precise answers
|
|
37
|
-
- Source-cited responses designed to minimize hallucinations
|
|
38
|
-
|
|
39
|
-
## When To Use
|
|
40
|
-
${useCases}
|
|
41
|
-
|
|
42
|
-
## Rules (Important)
|
|
43
|
-
- Always prefer continuing an existing session for the same task
|
|
44
|
-
- If you start a new thread, create a new session and keep its session_id
|
|
45
|
-
- Ask clarifying questions before implementing; do not guess missing details
|
|
46
|
-
- If multiple notebooks could apply, propose the top 1–2 and ask which to use
|
|
47
|
-
- If task context changes, ask to reset the session or switch notebooks
|
|
48
|
-
- If authentication fails, use the prompts 'notebooklm.auth-repair' (or 'notebooklm.auth-setup') and verify with 'get_health'
|
|
49
|
-
- After every NotebookLM answer: pause, compare with the user's goal, and only respond if you are 100% sure the information is complete. Otherwise, plan the next NotebookLM question in the same session.
|
|
50
|
-
|
|
51
|
-
## Session Flow (Recommended)
|
|
52
|
-
\`\`\`javascript
|
|
53
|
-
// 1) Start broad (no session_id → creates one)
|
|
54
|
-
ask_question({ question: "Give me an overview of [topic]" })
|
|
55
|
-
// ← Save: result.session_id
|
|
56
|
-
|
|
57
|
-
// 2) Go specific (same session)
|
|
58
|
-
ask_question({ question: "Key APIs/methods?", session_id })
|
|
59
|
-
|
|
60
|
-
// 3) Cover pitfalls (same session)
|
|
61
|
-
ask_question({ question: "Common edge cases + gotchas?", session_id })
|
|
62
|
-
|
|
63
|
-
// 4) Ask for production example (same session)
|
|
64
|
-
ask_question({ question: "Show a production-ready example", session_id })
|
|
65
|
-
\`\`\`
|
|
66
|
-
|
|
67
|
-
## Automatic Multi-Pass Strategy (Host-driven)
|
|
68
|
-
- Simple prompts return once-and-done answers.
|
|
69
|
-
- For complex prompts, the host should issue follow-up calls:
|
|
70
|
-
1. Implementation plan (APIs, dependencies, configuration, authentication).
|
|
71
|
-
2. Pitfalls, gaps, validation steps, missing prerequisites.
|
|
72
|
-
- Keep the same session_id for all follow-ups, review NotebookLM's answer, and ask more questions until the problem is fully resolved.
|
|
73
|
-
- Before replying to the user, double-check: do you truly have everything? If not, queue another ask_question immediately.
|
|
74
|
-
|
|
75
|
-
## 🔥 REAL EXAMPLE
|
|
76
|
-
|
|
77
|
-
Task: "Implement error handling in n8n workflow"
|
|
78
|
-
|
|
79
|
-
Bad (shallow):
|
|
80
|
-
\`\`\`
|
|
81
|
-
Q: "How do I handle errors in n8n?"
|
|
82
|
-
A: [basic answer]
|
|
83
|
-
→ Implement → Probably missing edge cases!
|
|
84
|
-
\`\`\`
|
|
85
|
-
|
|
86
|
-
Good (deep):
|
|
87
|
-
\`\`\`
|
|
88
|
-
Q1: "What are n8n's error handling mechanisms?" (session created)
|
|
89
|
-
A1: [Overview of error handling]
|
|
90
|
-
|
|
91
|
-
Q2: "What's the recommended pattern for API errors?" (same session)
|
|
92
|
-
A2: [Specific patterns, uses context from Q1]
|
|
93
|
-
|
|
94
|
-
Q3: "How do I handle retry logic and timeouts?" (same session)
|
|
95
|
-
A3: [Detailed approach, builds on Q1+Q2]
|
|
96
|
-
|
|
97
|
-
Q4: "Show me a production example with all these patterns" (same session)
|
|
98
|
-
A4: [Complete example with full context]
|
|
99
|
-
|
|
100
|
-
→ NOW implement with confidence!
|
|
101
|
-
\`\`\`
|
|
102
|
-
|
|
103
|
-
## Notebook Selection
|
|
104
|
-
- Default: active notebook (${active.id})
|
|
105
|
-
- Or set notebook_id to use a library notebook
|
|
106
|
-
- Or set notebook_url for ad-hoc notebooks (not in library)
|
|
24
|
+
const topics = active.topics.join(', ');
|
|
25
|
+
const useCases = active.use_cases.map((uc) => ` - ${uc}`).join('\n');
|
|
26
|
+
return `# Conversational Research Partner (NotebookLM • Gemini 2.5 • Session RAG)
|
|
27
|
+
|
|
28
|
+
**Active Notebook:** ${active.name}
|
|
29
|
+
**Content:** ${active.description}
|
|
30
|
+
**Topics:** ${topics}
|
|
31
|
+
|
|
32
|
+
> Auth tip: If login is required, use the prompt 'notebooklm.auth-setup' and then verify with the 'get_health' tool. If authentication later fails (e.g., expired cookies), use the prompt 'notebooklm.auth-repair'.
|
|
33
|
+
|
|
34
|
+
## What This Tool Is
|
|
35
|
+
- Full conversational research with Gemini (LLM) grounded on your notebook sources
|
|
36
|
+
- Session-based: each follow-up uses prior context for deeper, more precise answers
|
|
37
|
+
- Source-cited responses designed to minimize hallucinations
|
|
38
|
+
|
|
39
|
+
## When To Use
|
|
40
|
+
${useCases}
|
|
41
|
+
|
|
42
|
+
## Rules (Important)
|
|
43
|
+
- Always prefer continuing an existing session for the same task
|
|
44
|
+
- If you start a new thread, create a new session and keep its session_id
|
|
45
|
+
- Ask clarifying questions before implementing; do not guess missing details
|
|
46
|
+
- If multiple notebooks could apply, propose the top 1–2 and ask which to use
|
|
47
|
+
- If task context changes, ask to reset the session or switch notebooks
|
|
48
|
+
- If authentication fails, use the prompts 'notebooklm.auth-repair' (or 'notebooklm.auth-setup') and verify with 'get_health'
|
|
49
|
+
- After every NotebookLM answer: pause, compare with the user's goal, and only respond if you are 100% sure the information is complete. Otherwise, plan the next NotebookLM question in the same session.
|
|
50
|
+
|
|
51
|
+
## Session Flow (Recommended)
|
|
52
|
+
\`\`\`javascript
|
|
53
|
+
// 1) Start broad (no session_id → creates one)
|
|
54
|
+
ask_question({ question: "Give me an overview of [topic]" })
|
|
55
|
+
// ← Save: result.session_id
|
|
56
|
+
|
|
57
|
+
// 2) Go specific (same session)
|
|
58
|
+
ask_question({ question: "Key APIs/methods?", session_id })
|
|
59
|
+
|
|
60
|
+
// 3) Cover pitfalls (same session)
|
|
61
|
+
ask_question({ question: "Common edge cases + gotchas?", session_id })
|
|
62
|
+
|
|
63
|
+
// 4) Ask for production example (same session)
|
|
64
|
+
ask_question({ question: "Show a production-ready example", session_id })
|
|
65
|
+
\`\`\`
|
|
66
|
+
|
|
67
|
+
## Automatic Multi-Pass Strategy (Host-driven)
|
|
68
|
+
- Simple prompts return once-and-done answers.
|
|
69
|
+
- For complex prompts, the host should issue follow-up calls:
|
|
70
|
+
1. Implementation plan (APIs, dependencies, configuration, authentication).
|
|
71
|
+
2. Pitfalls, gaps, validation steps, missing prerequisites.
|
|
72
|
+
- Keep the same session_id for all follow-ups, review NotebookLM's answer, and ask more questions until the problem is fully resolved.
|
|
73
|
+
- Before replying to the user, double-check: do you truly have everything? If not, queue another ask_question immediately.
|
|
74
|
+
|
|
75
|
+
## 🔥 REAL EXAMPLE
|
|
76
|
+
|
|
77
|
+
Task: "Implement error handling in n8n workflow"
|
|
78
|
+
|
|
79
|
+
Bad (shallow):
|
|
80
|
+
\`\`\`
|
|
81
|
+
Q: "How do I handle errors in n8n?"
|
|
82
|
+
A: [basic answer]
|
|
83
|
+
→ Implement → Probably missing edge cases!
|
|
84
|
+
\`\`\`
|
|
85
|
+
|
|
86
|
+
Good (deep):
|
|
87
|
+
\`\`\`
|
|
88
|
+
Q1: "What are n8n's error handling mechanisms?" (session created)
|
|
89
|
+
A1: [Overview of error handling]
|
|
90
|
+
|
|
91
|
+
Q2: "What's the recommended pattern for API errors?" (same session)
|
|
92
|
+
A2: [Specific patterns, uses context from Q1]
|
|
93
|
+
|
|
94
|
+
Q3: "How do I handle retry logic and timeouts?" (same session)
|
|
95
|
+
A3: [Detailed approach, builds on Q1+Q2]
|
|
96
|
+
|
|
97
|
+
Q4: "Show me a production example with all these patterns" (same session)
|
|
98
|
+
A4: [Complete example with full context]
|
|
99
|
+
|
|
100
|
+
→ NOW implement with confidence!
|
|
101
|
+
\`\`\`
|
|
102
|
+
|
|
103
|
+
## Notebook Selection
|
|
104
|
+
- Default: active notebook (${active.id})
|
|
105
|
+
- Or set notebook_id to use a library notebook
|
|
106
|
+
- Or set notebook_url for ad-hoc notebooks (not in library)
|
|
107
107
|
- If ambiguous which notebook fits, ASK the user which to use`;
|
|
108
108
|
}
|
|
109
109
|
else {
|
|
110
|
-
return `# Conversational Research Partner (NotebookLM • Gemini 2.5 • Session RAG)
|
|
111
|
-
|
|
112
|
-
## No Active Notebook
|
|
113
|
-
- Visit https://notebooklm.google to create a notebook and get a share link
|
|
114
|
-
- Use **add_notebook** to add it to your library (explains how to get the link)
|
|
115
|
-
- Use **list_notebooks** to show available sources
|
|
116
|
-
- Use **select_notebook** to set one active
|
|
117
|
-
|
|
118
|
-
> Auth tip: If login is required, use the prompt 'notebooklm.auth-setup' and then verify with the 'get_health' tool. If authentication later fails (e.g., expired cookies), use the prompt 'notebooklm.auth-repair'.
|
|
119
|
-
|
|
110
|
+
return `# Conversational Research Partner (NotebookLM • Gemini 2.5 • Session RAG)
|
|
111
|
+
|
|
112
|
+
## No Active Notebook
|
|
113
|
+
- Visit https://notebooklm.google to create a notebook and get a share link
|
|
114
|
+
- Use **add_notebook** to add it to your library (explains how to get the link)
|
|
115
|
+
- Use **list_notebooks** to show available sources
|
|
116
|
+
- Use **select_notebook** to set one active
|
|
117
|
+
|
|
118
|
+
> Auth tip: If login is required, use the prompt 'notebooklm.auth-setup' and then verify with the 'get_health' tool. If authentication later fails (e.g., expired cookies), use the prompt 'notebooklm.auth-repair'.
|
|
119
|
+
|
|
120
120
|
Tip: Tell the user you can manage NotebookLM library and ask which notebook to use for the current task.`;
|
|
121
121
|
}
|
|
122
122
|
}
|
|
@@ -126,495 +126,495 @@ Tip: Tell the user you can manage NotebookLM library and ask which notebook to u
|
|
|
126
126
|
export function buildToolDefinitions(library) {
|
|
127
127
|
return [
|
|
128
128
|
{
|
|
129
|
-
name:
|
|
129
|
+
name: 'ask_question',
|
|
130
130
|
description: buildAskQuestionDescription(library),
|
|
131
131
|
inputSchema: {
|
|
132
|
-
type:
|
|
132
|
+
type: 'object',
|
|
133
133
|
properties: {
|
|
134
134
|
question: {
|
|
135
|
-
type:
|
|
136
|
-
description:
|
|
135
|
+
type: 'string',
|
|
136
|
+
description: 'The question to ask NotebookLM',
|
|
137
137
|
},
|
|
138
138
|
session_id: {
|
|
139
|
-
type:
|
|
140
|
-
description:
|
|
139
|
+
type: 'string',
|
|
140
|
+
description: 'Optional session ID for contextual conversations. If omitted, a new session is created.',
|
|
141
141
|
},
|
|
142
142
|
notebook_id: {
|
|
143
|
-
type:
|
|
144
|
-
description:
|
|
145
|
-
|
|
143
|
+
type: 'string',
|
|
144
|
+
description: 'Optional notebook ID from your library. If omitted, uses the active notebook. ' +
|
|
145
|
+
'Use list_notebooks to see available notebooks.',
|
|
146
146
|
},
|
|
147
147
|
notebook_url: {
|
|
148
|
-
type:
|
|
149
|
-
description:
|
|
148
|
+
type: 'string',
|
|
149
|
+
description: 'Optional notebook URL (overrides notebook_id). Use this for ad-hoc queries to notebooks not in your library.',
|
|
150
150
|
},
|
|
151
151
|
show_browser: {
|
|
152
|
-
type:
|
|
153
|
-
description:
|
|
154
|
-
|
|
152
|
+
type: 'boolean',
|
|
153
|
+
description: 'Show browser window for debugging (simple version). ' +
|
|
154
|
+
'For advanced control (typing speed, stealth, etc.), use browser_options instead.',
|
|
155
155
|
},
|
|
156
156
|
browser_options: {
|
|
157
|
-
type:
|
|
158
|
-
description:
|
|
159
|
-
|
|
157
|
+
type: 'object',
|
|
158
|
+
description: 'Optional browser behavior settings. Claude can control everything: ' +
|
|
159
|
+
'visibility, typing speed, stealth mode, timeouts. Useful for debugging or fine-tuning.',
|
|
160
160
|
properties: {
|
|
161
161
|
show: {
|
|
162
|
-
type:
|
|
163
|
-
description:
|
|
162
|
+
type: 'boolean',
|
|
163
|
+
description: 'Show browser window (default: from ENV or false)',
|
|
164
164
|
},
|
|
165
165
|
headless: {
|
|
166
|
-
type:
|
|
167
|
-
description:
|
|
166
|
+
type: 'boolean',
|
|
167
|
+
description: 'Run browser in headless mode (default: true)',
|
|
168
168
|
},
|
|
169
169
|
timeout_ms: {
|
|
170
|
-
type:
|
|
171
|
-
description:
|
|
170
|
+
type: 'number',
|
|
171
|
+
description: 'Browser operation timeout in milliseconds (default: 30000)',
|
|
172
172
|
},
|
|
173
173
|
stealth: {
|
|
174
|
-
type:
|
|
175
|
-
description:
|
|
174
|
+
type: 'object',
|
|
175
|
+
description: 'Human-like behavior settings to avoid detection',
|
|
176
176
|
properties: {
|
|
177
177
|
enabled: {
|
|
178
|
-
type:
|
|
179
|
-
description:
|
|
178
|
+
type: 'boolean',
|
|
179
|
+
description: 'Master switch for all stealth features (default: true)',
|
|
180
180
|
},
|
|
181
181
|
random_delays: {
|
|
182
|
-
type:
|
|
183
|
-
description:
|
|
182
|
+
type: 'boolean',
|
|
183
|
+
description: 'Random delays between actions (default: true)',
|
|
184
184
|
},
|
|
185
185
|
human_typing: {
|
|
186
|
-
type:
|
|
187
|
-
description:
|
|
186
|
+
type: 'boolean',
|
|
187
|
+
description: 'Human-like typing patterns (default: true)',
|
|
188
188
|
},
|
|
189
189
|
mouse_movements: {
|
|
190
|
-
type:
|
|
191
|
-
description:
|
|
190
|
+
type: 'boolean',
|
|
191
|
+
description: 'Realistic mouse movements (default: true)',
|
|
192
192
|
},
|
|
193
193
|
typing_wpm_min: {
|
|
194
|
-
type:
|
|
195
|
-
description:
|
|
194
|
+
type: 'number',
|
|
195
|
+
description: 'Minimum typing speed in WPM (default: 160)',
|
|
196
196
|
},
|
|
197
197
|
typing_wpm_max: {
|
|
198
|
-
type:
|
|
199
|
-
description:
|
|
198
|
+
type: 'number',
|
|
199
|
+
description: 'Maximum typing speed in WPM (default: 240)',
|
|
200
200
|
},
|
|
201
201
|
delay_min_ms: {
|
|
202
|
-
type:
|
|
203
|
-
description:
|
|
202
|
+
type: 'number',
|
|
203
|
+
description: 'Minimum delay between actions in ms (default: 100)',
|
|
204
204
|
},
|
|
205
205
|
delay_max_ms: {
|
|
206
|
-
type:
|
|
207
|
-
description:
|
|
206
|
+
type: 'number',
|
|
207
|
+
description: 'Maximum delay between actions in ms (default: 400)',
|
|
208
208
|
},
|
|
209
209
|
},
|
|
210
210
|
},
|
|
211
211
|
viewport: {
|
|
212
|
-
type:
|
|
213
|
-
description:
|
|
212
|
+
type: 'object',
|
|
213
|
+
description: 'Browser viewport size',
|
|
214
214
|
properties: {
|
|
215
215
|
width: {
|
|
216
|
-
type:
|
|
217
|
-
description:
|
|
216
|
+
type: 'number',
|
|
217
|
+
description: 'Viewport width in pixels (default: 1920)',
|
|
218
218
|
},
|
|
219
219
|
height: {
|
|
220
|
-
type:
|
|
221
|
-
description:
|
|
220
|
+
type: 'number',
|
|
221
|
+
description: 'Viewport height in pixels (default: 1080)',
|
|
222
222
|
},
|
|
223
223
|
},
|
|
224
224
|
},
|
|
225
225
|
},
|
|
226
226
|
},
|
|
227
227
|
},
|
|
228
|
-
required: [
|
|
228
|
+
required: ['question'],
|
|
229
229
|
},
|
|
230
230
|
},
|
|
231
231
|
{
|
|
232
|
-
name:
|
|
233
|
-
description: `🚀 AUTO-DISCOVERY — Automatically generate notebook metadata via NotebookLM (RECOMMENDED)
|
|
234
|
-
|
|
235
|
-
## When to Use
|
|
236
|
-
- User provides NotebookLM URL and wants quick/automatic setup
|
|
237
|
-
- User prefers not to manually specify metadata
|
|
238
|
-
- Default choice for adding notebooks
|
|
239
|
-
|
|
240
|
-
## Workflow
|
|
241
|
-
1) User provides NotebookLM URL
|
|
242
|
-
2) Ask confirmation: "Add '[URL]' with auto-generated metadata?"
|
|
243
|
-
3) Call this tool → NotebookLM generates name, description, tags
|
|
244
|
-
4) Show generated metadata to user for review
|
|
245
|
-
|
|
246
|
-
## Benefits
|
|
247
|
-
- ✅ 30 seconds vs 5 minutes manual entry
|
|
248
|
-
- ✅ Zero-friction notebook addition
|
|
249
|
-
- ✅ Consistent metadata quality
|
|
250
|
-
- ✅ Discovers topics user might not think of
|
|
251
|
-
|
|
252
|
-
## Example
|
|
253
|
-
User: "Add this NotebookLM: https://notebooklm.google.com/notebook/abc123"
|
|
254
|
-
You: "Add this notebook with auto-generated metadata?"
|
|
255
|
-
User: "Yes"
|
|
256
|
-
You: Call auto_discover_notebook(url="https://...")
|
|
257
|
-
→ Returns: {name: "n8n-workflow-guide", description: "...", tags: [...]}
|
|
258
|
-
|
|
259
|
-
## Fallback
|
|
260
|
-
If auto-discovery fails (rare), use add_notebook tool for manual entry.
|
|
261
|
-
|
|
262
|
-
## How to Get a NotebookLM Share Link
|
|
263
|
-
|
|
264
|
-
Visit https://notebooklm.google/ → Login (free: 100 notebooks, 50 sources each, 500k words, 50 daily queries)
|
|
265
|
-
1) Click "+ New" (top right) → Upload sources (docs, knowledge)
|
|
266
|
-
2) Click "Share" (top right) → Select "Anyone with the link"
|
|
267
|
-
3) Click "Copy link" (bottom left) → Give this link to Claude
|
|
268
|
-
|
|
232
|
+
name: 'auto_discover_notebook',
|
|
233
|
+
description: `🚀 AUTO-DISCOVERY — Automatically generate notebook metadata via NotebookLM (RECOMMENDED)
|
|
234
|
+
|
|
235
|
+
## When to Use
|
|
236
|
+
- User provides NotebookLM URL and wants quick/automatic setup
|
|
237
|
+
- User prefers not to manually specify metadata
|
|
238
|
+
- Default choice for adding notebooks
|
|
239
|
+
|
|
240
|
+
## Workflow
|
|
241
|
+
1) User provides NotebookLM URL
|
|
242
|
+
2) Ask confirmation: "Add '[URL]' with auto-generated metadata?"
|
|
243
|
+
3) Call this tool → NotebookLM generates name, description, tags
|
|
244
|
+
4) Show generated metadata to user for review
|
|
245
|
+
|
|
246
|
+
## Benefits
|
|
247
|
+
- ✅ 30 seconds vs 5 minutes manual entry
|
|
248
|
+
- ✅ Zero-friction notebook addition
|
|
249
|
+
- ✅ Consistent metadata quality
|
|
250
|
+
- ✅ Discovers topics user might not think of
|
|
251
|
+
|
|
252
|
+
## Example
|
|
253
|
+
User: "Add this NotebookLM: https://notebooklm.google.com/notebook/abc123"
|
|
254
|
+
You: "Add this notebook with auto-generated metadata?"
|
|
255
|
+
User: "Yes"
|
|
256
|
+
You: Call auto_discover_notebook(url="https://...")
|
|
257
|
+
→ Returns: {name: "n8n-workflow-guide", description: "...", tags: [...]}
|
|
258
|
+
|
|
259
|
+
## Fallback
|
|
260
|
+
If auto-discovery fails (rare), use add_notebook tool for manual entry.
|
|
261
|
+
|
|
262
|
+
## How to Get a NotebookLM Share Link
|
|
263
|
+
|
|
264
|
+
Visit https://notebooklm.google/ → Login (free: 100 notebooks, 50 sources each, 500k words, 50 daily queries)
|
|
265
|
+
1) Click "+ New" (top right) → Upload sources (docs, knowledge)
|
|
266
|
+
2) Click "Share" (top right) → Select "Anyone with the link"
|
|
267
|
+
3) Click "Copy link" (bottom left) → Give this link to Claude
|
|
268
|
+
|
|
269
269
|
(Upgraded: Google AI Pro/Ultra gives 5x higher limits)`,
|
|
270
270
|
inputSchema: {
|
|
271
|
-
type:
|
|
271
|
+
type: 'object',
|
|
272
272
|
properties: {
|
|
273
273
|
url: {
|
|
274
|
-
type:
|
|
275
|
-
description:
|
|
274
|
+
type: 'string',
|
|
275
|
+
description: 'The NotebookLM notebook URL',
|
|
276
276
|
},
|
|
277
277
|
},
|
|
278
|
-
required: [
|
|
278
|
+
required: ['url'],
|
|
279
279
|
},
|
|
280
280
|
},
|
|
281
281
|
{
|
|
282
|
-
name:
|
|
283
|
-
description: `📝 MANUAL ENTRY — Add notebook with manually specified metadata (use auto_discover_notebook instead)
|
|
284
|
-
|
|
285
|
-
## When to Use
|
|
286
|
-
- Auto-discovery failed or unavailable
|
|
287
|
-
- User has specific metadata requirements
|
|
288
|
-
- User prefers manual control
|
|
289
|
-
|
|
290
|
-
## Conversation Workflow (Mandatory)
|
|
291
|
-
When the user says: "I have a NotebookLM with X"
|
|
292
|
-
|
|
293
|
-
**FIRST:** Try auto_discover_notebook for faster setup
|
|
294
|
-
**ONLY IF** user refuses auto-discovery or it fails:
|
|
295
|
-
|
|
296
|
-
1) Ask URL: "What is the NotebookLM URL?"
|
|
297
|
-
2) Ask content: "What knowledge is inside?" (1–2 sentences)
|
|
298
|
-
3) Ask topics: "Which topics does it cover?" (3–5)
|
|
299
|
-
4) Ask use cases: "When should we consult it?"
|
|
300
|
-
5) Propose metadata and confirm:
|
|
301
|
-
- Name: [suggested]
|
|
302
|
-
- Description: [from user]
|
|
303
|
-
- Topics: [list]
|
|
304
|
-
- Use cases: [list]
|
|
305
|
-
"Add it to your library now?"
|
|
306
|
-
6) Only after explicit "Yes" → call this tool
|
|
307
|
-
|
|
308
|
-
## Rules
|
|
309
|
-
- Do not add without user permission
|
|
310
|
-
- Prefer auto_discover_notebook when possible
|
|
311
|
-
- Do not guess metadata — ask concisely
|
|
312
|
-
- Confirm summary before calling the tool
|
|
313
|
-
|
|
314
|
-
## Example
|
|
315
|
-
User: "I have a notebook with n8n docs"
|
|
316
|
-
You: "Want me to auto-generate the metadata?" (offer auto_discover_notebook first)
|
|
317
|
-
User: "No, I'll specify it myself"
|
|
318
|
-
You: Ask URL → content → topics → use cases; propose summary
|
|
319
|
-
User: "Yes"
|
|
320
|
-
You: Call add_notebook
|
|
321
|
-
|
|
322
|
-
## How to Get a NotebookLM Share Link
|
|
323
|
-
|
|
324
|
-
Visit https://notebooklm.google/ → Login (free: 100 notebooks, 50 sources each, 500k words, 50 daily queries)
|
|
325
|
-
1) Click "+ New" (top right) → Upload sources (docs, knowledge)
|
|
326
|
-
2) Click "Share" (top right) → Select "Anyone with the link"
|
|
327
|
-
3) Click "Copy link" (bottom left) → Give this link to Claude
|
|
328
|
-
|
|
282
|
+
name: 'add_notebook',
|
|
283
|
+
description: `📝 MANUAL ENTRY — Add notebook with manually specified metadata (use auto_discover_notebook instead)
|
|
284
|
+
|
|
285
|
+
## When to Use
|
|
286
|
+
- Auto-discovery failed or unavailable
|
|
287
|
+
- User has specific metadata requirements
|
|
288
|
+
- User prefers manual control
|
|
289
|
+
|
|
290
|
+
## Conversation Workflow (Mandatory)
|
|
291
|
+
When the user says: "I have a NotebookLM with X"
|
|
292
|
+
|
|
293
|
+
**FIRST:** Try auto_discover_notebook for faster setup
|
|
294
|
+
**ONLY IF** user refuses auto-discovery or it fails:
|
|
295
|
+
|
|
296
|
+
1) Ask URL: "What is the NotebookLM URL?"
|
|
297
|
+
2) Ask content: "What knowledge is inside?" (1–2 sentences)
|
|
298
|
+
3) Ask topics: "Which topics does it cover?" (3–5)
|
|
299
|
+
4) Ask use cases: "When should we consult it?"
|
|
300
|
+
5) Propose metadata and confirm:
|
|
301
|
+
- Name: [suggested]
|
|
302
|
+
- Description: [from user]
|
|
303
|
+
- Topics: [list]
|
|
304
|
+
- Use cases: [list]
|
|
305
|
+
"Add it to your library now?"
|
|
306
|
+
6) Only after explicit "Yes" → call this tool
|
|
307
|
+
|
|
308
|
+
## Rules
|
|
309
|
+
- Do not add without user permission
|
|
310
|
+
- Prefer auto_discover_notebook when possible
|
|
311
|
+
- Do not guess metadata — ask concisely
|
|
312
|
+
- Confirm summary before calling the tool
|
|
313
|
+
|
|
314
|
+
## Example
|
|
315
|
+
User: "I have a notebook with n8n docs"
|
|
316
|
+
You: "Want me to auto-generate the metadata?" (offer auto_discover_notebook first)
|
|
317
|
+
User: "No, I'll specify it myself"
|
|
318
|
+
You: Ask URL → content → topics → use cases; propose summary
|
|
319
|
+
User: "Yes"
|
|
320
|
+
You: Call add_notebook
|
|
321
|
+
|
|
322
|
+
## How to Get a NotebookLM Share Link
|
|
323
|
+
|
|
324
|
+
Visit https://notebooklm.google/ → Login (free: 100 notebooks, 50 sources each, 500k words, 50 daily queries)
|
|
325
|
+
1) Click "+ New" (top right) → Upload sources (docs, knowledge)
|
|
326
|
+
2) Click "Share" (top right) → Select "Anyone with the link"
|
|
327
|
+
3) Click "Copy link" (bottom left) → Give this link to Claude
|
|
328
|
+
|
|
329
329
|
(Upgraded: Google AI Pro/Ultra gives 5x higher limits)`,
|
|
330
330
|
inputSchema: {
|
|
331
|
-
type:
|
|
331
|
+
type: 'object',
|
|
332
332
|
properties: {
|
|
333
333
|
url: {
|
|
334
|
-
type:
|
|
335
|
-
description:
|
|
334
|
+
type: 'string',
|
|
335
|
+
description: 'The NotebookLM notebook URL',
|
|
336
336
|
},
|
|
337
337
|
name: {
|
|
338
|
-
type:
|
|
338
|
+
type: 'string',
|
|
339
339
|
description: "Display name for the notebook (e.g., 'n8n Documentation')",
|
|
340
340
|
},
|
|
341
341
|
description: {
|
|
342
|
-
type:
|
|
343
|
-
description:
|
|
342
|
+
type: 'string',
|
|
343
|
+
description: 'What knowledge/content is in this notebook',
|
|
344
344
|
},
|
|
345
345
|
topics: {
|
|
346
|
-
type:
|
|
347
|
-
items: { type:
|
|
348
|
-
description:
|
|
346
|
+
type: 'array',
|
|
347
|
+
items: { type: 'string' },
|
|
348
|
+
description: 'Topics covered in this notebook',
|
|
349
349
|
},
|
|
350
350
|
content_types: {
|
|
351
|
-
type:
|
|
352
|
-
items: { type:
|
|
351
|
+
type: 'array',
|
|
352
|
+
items: { type: 'string' },
|
|
353
353
|
description: "Types of content (e.g., ['documentation', 'examples', 'best practices'])",
|
|
354
354
|
},
|
|
355
355
|
use_cases: {
|
|
356
|
-
type:
|
|
357
|
-
items: { type:
|
|
356
|
+
type: 'array',
|
|
357
|
+
items: { type: 'string' },
|
|
358
358
|
description: "When should Claude use this notebook (e.g., ['Implementing n8n workflows'])",
|
|
359
359
|
},
|
|
360
360
|
tags: {
|
|
361
|
-
type:
|
|
362
|
-
items: { type:
|
|
363
|
-
description:
|
|
361
|
+
type: 'array',
|
|
362
|
+
items: { type: 'string' },
|
|
363
|
+
description: 'Optional tags for organization',
|
|
364
364
|
},
|
|
365
365
|
},
|
|
366
|
-
required: [
|
|
366
|
+
required: ['url', 'name', 'description', 'topics'],
|
|
367
367
|
},
|
|
368
368
|
},
|
|
369
369
|
{
|
|
370
|
-
name:
|
|
371
|
-
description:
|
|
372
|
-
|
|
370
|
+
name: 'list_notebooks',
|
|
371
|
+
description: 'List all library notebooks with metadata (name, topics, use cases, URL). ' +
|
|
372
|
+
'Use this to present options, then ask which notebook to use for the task.',
|
|
373
373
|
inputSchema: {
|
|
374
|
-
type:
|
|
374
|
+
type: 'object',
|
|
375
375
|
properties: {},
|
|
376
376
|
},
|
|
377
377
|
},
|
|
378
378
|
{
|
|
379
|
-
name:
|
|
380
|
-
description:
|
|
379
|
+
name: 'get_notebook',
|
|
380
|
+
description: 'Get detailed information about a specific notebook by ID',
|
|
381
381
|
inputSchema: {
|
|
382
|
-
type:
|
|
382
|
+
type: 'object',
|
|
383
383
|
properties: {
|
|
384
384
|
id: {
|
|
385
|
-
type:
|
|
386
|
-
description:
|
|
385
|
+
type: 'string',
|
|
386
|
+
description: 'The notebook ID',
|
|
387
387
|
},
|
|
388
388
|
},
|
|
389
|
-
required: [
|
|
389
|
+
required: ['id'],
|
|
390
390
|
},
|
|
391
391
|
},
|
|
392
392
|
{
|
|
393
|
-
name:
|
|
394
|
-
description: `Set a notebook as the active default (used when ask_question has no notebook_id).
|
|
395
|
-
|
|
396
|
-
## When To Use
|
|
397
|
-
- User switches context: "Let's work on React now"
|
|
398
|
-
- User asks explicitly to activate a notebook
|
|
399
|
-
- Obvious task change requires another notebook
|
|
400
|
-
|
|
401
|
-
## Auto-Switching
|
|
402
|
-
- Safe to auto-switch if the context is clear and you announce it:
|
|
403
|
-
"Switching to React notebook for this task..."
|
|
404
|
-
- If ambiguous, ask: "Switch to [notebook] for this task?"
|
|
405
|
-
|
|
406
|
-
## Example
|
|
407
|
-
User: "Now let's build the React frontend"
|
|
393
|
+
name: 'select_notebook',
|
|
394
|
+
description: `Set a notebook as the active default (used when ask_question has no notebook_id).
|
|
395
|
+
|
|
396
|
+
## When To Use
|
|
397
|
+
- User switches context: "Let's work on React now"
|
|
398
|
+
- User asks explicitly to activate a notebook
|
|
399
|
+
- Obvious task change requires another notebook
|
|
400
|
+
|
|
401
|
+
## Auto-Switching
|
|
402
|
+
- Safe to auto-switch if the context is clear and you announce it:
|
|
403
|
+
"Switching to React notebook for this task..."
|
|
404
|
+
- If ambiguous, ask: "Switch to [notebook] for this task?"
|
|
405
|
+
|
|
406
|
+
## Example
|
|
407
|
+
User: "Now let's build the React frontend"
|
|
408
408
|
You: "Switching to React notebook..." (call select_notebook)`,
|
|
409
409
|
inputSchema: {
|
|
410
|
-
type:
|
|
410
|
+
type: 'object',
|
|
411
411
|
properties: {
|
|
412
412
|
id: {
|
|
413
|
-
type:
|
|
414
|
-
description:
|
|
413
|
+
type: 'string',
|
|
414
|
+
description: 'The notebook ID to activate',
|
|
415
415
|
},
|
|
416
416
|
},
|
|
417
|
-
required: [
|
|
417
|
+
required: ['id'],
|
|
418
418
|
},
|
|
419
419
|
},
|
|
420
420
|
{
|
|
421
|
-
name:
|
|
422
|
-
description: `Update notebook metadata based on user intent.
|
|
423
|
-
|
|
424
|
-
## Pattern
|
|
425
|
-
1) Identify target notebook and fields (topics, description, use_cases, tags, url)
|
|
426
|
-
2) Propose the exact change back to the user
|
|
427
|
-
3) After explicit confirmation, call this tool
|
|
428
|
-
|
|
429
|
-
## Examples
|
|
430
|
-
- User: "React notebook also covers Next.js 14"
|
|
431
|
-
You: "Add 'Next.js 14' to topics for React?"
|
|
432
|
-
User: "Yes" → call update_notebook
|
|
433
|
-
|
|
434
|
-
- User: "Include error handling in n8n description"
|
|
435
|
-
You: "Update the n8n description to mention error handling?"
|
|
436
|
-
User: "Yes" → call update_notebook
|
|
437
|
-
|
|
421
|
+
name: 'update_notebook',
|
|
422
|
+
description: `Update notebook metadata based on user intent.
|
|
423
|
+
|
|
424
|
+
## Pattern
|
|
425
|
+
1) Identify target notebook and fields (topics, description, use_cases, tags, url)
|
|
426
|
+
2) Propose the exact change back to the user
|
|
427
|
+
3) After explicit confirmation, call this tool
|
|
428
|
+
|
|
429
|
+
## Examples
|
|
430
|
+
- User: "React notebook also covers Next.js 14"
|
|
431
|
+
You: "Add 'Next.js 14' to topics for React?"
|
|
432
|
+
User: "Yes" → call update_notebook
|
|
433
|
+
|
|
434
|
+
- User: "Include error handling in n8n description"
|
|
435
|
+
You: "Update the n8n description to mention error handling?"
|
|
436
|
+
User: "Yes" → call update_notebook
|
|
437
|
+
|
|
438
438
|
Tip: You may update multiple fields at once if requested.`,
|
|
439
439
|
inputSchema: {
|
|
440
|
-
type:
|
|
440
|
+
type: 'object',
|
|
441
441
|
properties: {
|
|
442
442
|
id: {
|
|
443
|
-
type:
|
|
444
|
-
description:
|
|
443
|
+
type: 'string',
|
|
444
|
+
description: 'The notebook ID to update',
|
|
445
445
|
},
|
|
446
446
|
name: {
|
|
447
|
-
type:
|
|
448
|
-
description:
|
|
447
|
+
type: 'string',
|
|
448
|
+
description: 'New display name',
|
|
449
449
|
},
|
|
450
450
|
description: {
|
|
451
|
-
type:
|
|
452
|
-
description:
|
|
451
|
+
type: 'string',
|
|
452
|
+
description: 'New description',
|
|
453
453
|
},
|
|
454
454
|
topics: {
|
|
455
|
-
type:
|
|
456
|
-
items: { type:
|
|
457
|
-
description:
|
|
455
|
+
type: 'array',
|
|
456
|
+
items: { type: 'string' },
|
|
457
|
+
description: 'New topics list',
|
|
458
458
|
},
|
|
459
459
|
content_types: {
|
|
460
|
-
type:
|
|
461
|
-
items: { type:
|
|
462
|
-
description:
|
|
460
|
+
type: 'array',
|
|
461
|
+
items: { type: 'string' },
|
|
462
|
+
description: 'New content types',
|
|
463
463
|
},
|
|
464
464
|
use_cases: {
|
|
465
|
-
type:
|
|
466
|
-
items: { type:
|
|
467
|
-
description:
|
|
465
|
+
type: 'array',
|
|
466
|
+
items: { type: 'string' },
|
|
467
|
+
description: 'New use cases',
|
|
468
468
|
},
|
|
469
469
|
tags: {
|
|
470
|
-
type:
|
|
471
|
-
items: { type:
|
|
472
|
-
description:
|
|
470
|
+
type: 'array',
|
|
471
|
+
items: { type: 'string' },
|
|
472
|
+
description: 'New tags',
|
|
473
473
|
},
|
|
474
474
|
url: {
|
|
475
|
-
type:
|
|
476
|
-
description:
|
|
475
|
+
type: 'string',
|
|
476
|
+
description: 'New notebook URL',
|
|
477
477
|
},
|
|
478
478
|
},
|
|
479
|
-
required: [
|
|
479
|
+
required: ['id'],
|
|
480
480
|
},
|
|
481
481
|
},
|
|
482
482
|
{
|
|
483
|
-
name:
|
|
484
|
-
description: `Dangerous — requires explicit user confirmation.
|
|
485
|
-
|
|
486
|
-
## Confirmation Workflow
|
|
487
|
-
1) User requests removal ("Remove the React notebook")
|
|
488
|
-
2) Look up full name to confirm
|
|
489
|
-
3) Ask: "Remove '[notebook_name]' from your library? (Does not delete the actual NotebookLM notebook)"
|
|
490
|
-
4) Only on explicit "Yes" → call remove_notebook
|
|
491
|
-
|
|
492
|
-
Never remove without permission or based on assumptions.
|
|
493
|
-
|
|
494
|
-
Example:
|
|
495
|
-
User: "Delete the old React notebook"
|
|
496
|
-
You: "Remove 'React Best Practices' from your library?"
|
|
483
|
+
name: 'remove_notebook',
|
|
484
|
+
description: `Dangerous — requires explicit user confirmation.
|
|
485
|
+
|
|
486
|
+
## Confirmation Workflow
|
|
487
|
+
1) User requests removal ("Remove the React notebook")
|
|
488
|
+
2) Look up full name to confirm
|
|
489
|
+
3) Ask: "Remove '[notebook_name]' from your library? (Does not delete the actual NotebookLM notebook)"
|
|
490
|
+
4) Only on explicit "Yes" → call remove_notebook
|
|
491
|
+
|
|
492
|
+
Never remove without permission or based on assumptions.
|
|
493
|
+
|
|
494
|
+
Example:
|
|
495
|
+
User: "Delete the old React notebook"
|
|
496
|
+
You: "Remove 'React Best Practices' from your library?"
|
|
497
497
|
User: "Yes" → call remove_notebook`,
|
|
498
498
|
inputSchema: {
|
|
499
|
-
type:
|
|
499
|
+
type: 'object',
|
|
500
500
|
properties: {
|
|
501
501
|
id: {
|
|
502
|
-
type:
|
|
503
|
-
description:
|
|
502
|
+
type: 'string',
|
|
503
|
+
description: 'The notebook ID to remove',
|
|
504
504
|
},
|
|
505
505
|
},
|
|
506
|
-
required: [
|
|
506
|
+
required: ['id'],
|
|
507
507
|
},
|
|
508
508
|
},
|
|
509
509
|
{
|
|
510
|
-
name:
|
|
511
|
-
description:
|
|
512
|
-
|
|
510
|
+
name: 'search_notebooks',
|
|
511
|
+
description: 'Search library by query (name, description, topics, tags). ' +
|
|
512
|
+
'Use to propose relevant notebooks for the task and then ask which to use.',
|
|
513
513
|
inputSchema: {
|
|
514
|
-
type:
|
|
514
|
+
type: 'object',
|
|
515
515
|
properties: {
|
|
516
516
|
query: {
|
|
517
|
-
type:
|
|
518
|
-
description:
|
|
517
|
+
type: 'string',
|
|
518
|
+
description: 'Search query',
|
|
519
519
|
},
|
|
520
520
|
},
|
|
521
|
-
required: [
|
|
521
|
+
required: ['query'],
|
|
522
522
|
},
|
|
523
523
|
},
|
|
524
524
|
{
|
|
525
|
-
name:
|
|
526
|
-
description:
|
|
525
|
+
name: 'get_library_stats',
|
|
526
|
+
description: 'Get statistics about your notebook library (total notebooks, usage, etc.)',
|
|
527
527
|
inputSchema: {
|
|
528
|
-
type:
|
|
528
|
+
type: 'object',
|
|
529
529
|
properties: {},
|
|
530
530
|
},
|
|
531
531
|
},
|
|
532
532
|
{
|
|
533
|
-
name:
|
|
534
|
-
description:
|
|
535
|
-
|
|
533
|
+
name: 'list_sessions',
|
|
534
|
+
description: 'List all active sessions with stats (age, message count, last activity). ' +
|
|
535
|
+
'Use to continue the most relevant session instead of starting from scratch.',
|
|
536
536
|
inputSchema: {
|
|
537
|
-
type:
|
|
537
|
+
type: 'object',
|
|
538
538
|
properties: {},
|
|
539
539
|
},
|
|
540
540
|
},
|
|
541
541
|
{
|
|
542
|
-
name:
|
|
543
|
-
description:
|
|
542
|
+
name: 'close_session',
|
|
543
|
+
description: 'Close a specific session by session ID. Ask before closing if the user might still need it.',
|
|
544
544
|
inputSchema: {
|
|
545
|
-
type:
|
|
545
|
+
type: 'object',
|
|
546
546
|
properties: {
|
|
547
547
|
session_id: {
|
|
548
|
-
type:
|
|
549
|
-
description:
|
|
548
|
+
type: 'string',
|
|
549
|
+
description: 'The session ID to close',
|
|
550
550
|
},
|
|
551
551
|
},
|
|
552
|
-
required: [
|
|
552
|
+
required: ['session_id'],
|
|
553
553
|
},
|
|
554
554
|
},
|
|
555
555
|
{
|
|
556
|
-
name:
|
|
556
|
+
name: 'reset_session',
|
|
557
557
|
description: "Reset a session's chat history (keep same session ID). " +
|
|
558
|
-
|
|
558
|
+
'Use for a clean slate when the task changes; ask the user before resetting.',
|
|
559
559
|
inputSchema: {
|
|
560
|
-
type:
|
|
560
|
+
type: 'object',
|
|
561
561
|
properties: {
|
|
562
562
|
session_id: {
|
|
563
|
-
type:
|
|
564
|
-
description:
|
|
563
|
+
type: 'string',
|
|
564
|
+
description: 'The session ID to reset',
|
|
565
565
|
},
|
|
566
566
|
},
|
|
567
|
-
required: [
|
|
567
|
+
required: ['session_id'],
|
|
568
568
|
},
|
|
569
569
|
},
|
|
570
570
|
{
|
|
571
|
-
name:
|
|
572
|
-
description:
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
571
|
+
name: 'get_health',
|
|
572
|
+
description: 'Get server health status including authentication state, active sessions, and configuration. ' +
|
|
573
|
+
'Use this to verify the server is ready before starting research workflows.\n\n' +
|
|
574
|
+
'If authenticated=false and having persistent issues:\n' +
|
|
575
|
+
'Consider running cleanup_data(preserve_library=true) + setup_auth for fresh start with clean browser session.',
|
|
576
576
|
inputSchema: {
|
|
577
|
-
type:
|
|
577
|
+
type: 'object',
|
|
578
578
|
properties: {},
|
|
579
579
|
},
|
|
580
580
|
},
|
|
581
581
|
{
|
|
582
|
-
name:
|
|
583
|
-
description:
|
|
584
|
-
|
|
582
|
+
name: 'setup_auth',
|
|
583
|
+
description: 'Google authentication for NotebookLM access - opens a browser window for manual login to your Google account. ' +
|
|
584
|
+
'Returns immediately after opening the browser. You have up to 10 minutes to complete the login. ' +
|
|
585
585
|
"Use 'get_health' tool afterwards to verify authentication was saved successfully. " +
|
|
586
|
-
|
|
587
|
-
|
|
586
|
+
'Use this for first-time authentication or when auto-login credentials are not available. ' +
|
|
587
|
+
'IMPORTANT: If already authenticated, this tool will skip re-authentication. ' +
|
|
588
588
|
"For switching accounts or rate-limit workarounds, use 're_auth' tool instead.\n\n" +
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
589
|
+
'TROUBLESHOOTING for persistent auth issues:\n' +
|
|
590
|
+
'If setup_auth fails or you encounter browser/session issues:\n' +
|
|
591
|
+
'1. Ask user to close ALL Chrome/Chromium instances\n' +
|
|
592
|
+
'2. Run cleanup_data(confirm=true, preserve_library=true) to clean old data\n' +
|
|
593
|
+
'3. Run setup_auth again for fresh start\n' +
|
|
594
|
+
'This helps resolve conflicts from old browser sessions and installation data.',
|
|
595
595
|
inputSchema: {
|
|
596
|
-
type:
|
|
596
|
+
type: 'object',
|
|
597
597
|
properties: {
|
|
598
598
|
show_browser: {
|
|
599
|
-
type:
|
|
600
|
-
description:
|
|
601
|
-
|
|
599
|
+
type: 'boolean',
|
|
600
|
+
description: 'Show browser window (simple version). Default: true for setup. ' +
|
|
601
|
+
'For advanced control, use browser_options instead.',
|
|
602
602
|
},
|
|
603
603
|
browser_options: {
|
|
604
|
-
type:
|
|
605
|
-
description:
|
|
604
|
+
type: 'object',
|
|
605
|
+
description: 'Optional browser settings. Control visibility, timeouts, and stealth behavior.',
|
|
606
606
|
properties: {
|
|
607
607
|
show: {
|
|
608
|
-
type:
|
|
609
|
-
description:
|
|
608
|
+
type: 'boolean',
|
|
609
|
+
description: 'Show browser window (default: true for setup)',
|
|
610
610
|
},
|
|
611
611
|
headless: {
|
|
612
|
-
type:
|
|
613
|
-
description:
|
|
612
|
+
type: 'boolean',
|
|
613
|
+
description: 'Run browser in headless mode (default: false for setup)',
|
|
614
614
|
},
|
|
615
615
|
timeout_ms: {
|
|
616
|
-
type:
|
|
617
|
-
description:
|
|
616
|
+
type: 'number',
|
|
617
|
+
description: 'Browser operation timeout in milliseconds (default: 30000)',
|
|
618
618
|
},
|
|
619
619
|
},
|
|
620
620
|
},
|
|
@@ -622,65 +622,65 @@ User: "Yes" → call remove_notebook`,
|
|
|
622
622
|
},
|
|
623
623
|
},
|
|
624
624
|
{
|
|
625
|
-
name:
|
|
626
|
-
description:
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
625
|
+
name: 'de_auth',
|
|
626
|
+
description: 'De-authenticate (logout) - Clears all authentication data for security. ' +
|
|
627
|
+
'Use this when:\n' +
|
|
628
|
+
'- User wants to log out for security reasons\n' +
|
|
629
|
+
'- Removing credentials before shutting down\n' +
|
|
630
|
+
'- Clearing auth without immediately re-authenticating\n\n' +
|
|
631
|
+
'This will:\n' +
|
|
632
|
+
'1. Close all active browser sessions\n' +
|
|
633
|
+
'2. Delete all saved authentication data (cookies, Chrome profile)\n' +
|
|
634
|
+
'3. Preserve notebook library and other data\n\n' +
|
|
635
|
+
'IMPORTANT: After de_auth, the server will need re-authentication via setup_auth or re_auth before making queries.\n\n' +
|
|
636
636
|
"Use 'get_health' to verify de-authentication was successful (authenticated: false).",
|
|
637
637
|
inputSchema: {
|
|
638
|
-
type:
|
|
638
|
+
type: 'object',
|
|
639
639
|
properties: {},
|
|
640
640
|
},
|
|
641
641
|
},
|
|
642
642
|
{
|
|
643
|
-
name:
|
|
644
|
-
description:
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
643
|
+
name: 're_auth',
|
|
644
|
+
description: 'Switch to a different Google account or re-authenticate. ' +
|
|
645
|
+
'Use this when:\n' +
|
|
646
|
+
'- NotebookLM rate limit is reached (50 queries/day for free accounts)\n' +
|
|
647
|
+
'- You want to switch to a different Google account\n' +
|
|
648
|
+
'- Authentication is broken and needs a fresh start\n\n' +
|
|
649
|
+
'This will:\n' +
|
|
650
|
+
'1. Close all active browser sessions\n' +
|
|
651
|
+
'2. Delete all saved authentication data (cookies, Chrome profile)\n' +
|
|
652
|
+
'3. Open browser for fresh Google login\n\n' +
|
|
653
653
|
"After completion, use 'get_health' to verify authentication.\n\n" +
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
654
|
+
'TROUBLESHOOTING for persistent auth issues:\n' +
|
|
655
|
+
'If re_auth fails repeatedly:\n' +
|
|
656
|
+
'1. Ask user to close ALL Chrome/Chromium instances\n' +
|
|
657
|
+
'2. Run cleanup_data(confirm=false, preserve_library=true) to preview old files\n' +
|
|
658
|
+
'3. Run cleanup_data(confirm=true, preserve_library=true) to clean everything except library\n' +
|
|
659
|
+
'4. Run re_auth again for completely fresh start\n' +
|
|
660
|
+
'This removes old installation data and browser sessions that can cause conflicts.',
|
|
661
661
|
inputSchema: {
|
|
662
|
-
type:
|
|
662
|
+
type: 'object',
|
|
663
663
|
properties: {
|
|
664
664
|
show_browser: {
|
|
665
|
-
type:
|
|
666
|
-
description:
|
|
667
|
-
|
|
665
|
+
type: 'boolean',
|
|
666
|
+
description: 'Show browser window (simple version). Default: true for re-auth. ' +
|
|
667
|
+
'For advanced control, use browser_options instead.',
|
|
668
668
|
},
|
|
669
669
|
browser_options: {
|
|
670
|
-
type:
|
|
671
|
-
description:
|
|
670
|
+
type: 'object',
|
|
671
|
+
description: 'Optional browser settings. Control visibility, timeouts, and stealth behavior.',
|
|
672
672
|
properties: {
|
|
673
673
|
show: {
|
|
674
|
-
type:
|
|
675
|
-
description:
|
|
674
|
+
type: 'boolean',
|
|
675
|
+
description: 'Show browser window (default: true for re-auth)',
|
|
676
676
|
},
|
|
677
677
|
headless: {
|
|
678
|
-
type:
|
|
679
|
-
description:
|
|
678
|
+
type: 'boolean',
|
|
679
|
+
description: 'Run browser in headless mode (default: false for re-auth)',
|
|
680
680
|
},
|
|
681
681
|
timeout_ms: {
|
|
682
|
-
type:
|
|
683
|
-
description:
|
|
682
|
+
type: 'number',
|
|
683
|
+
description: 'Browser operation timeout in milliseconds (default: 30000)',
|
|
684
684
|
},
|
|
685
685
|
},
|
|
686
686
|
},
|
|
@@ -688,42 +688,42 @@ User: "Yes" → call remove_notebook`,
|
|
|
688
688
|
},
|
|
689
689
|
},
|
|
690
690
|
{
|
|
691
|
-
name:
|
|
692
|
-
description:
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
691
|
+
name: 'cleanup_data',
|
|
692
|
+
description: 'ULTRATHINK Deep Cleanup - Scans entire system for ALL NotebookLM MCP data files across 8 categories. Always runs in deep mode, shows categorized preview before deletion.\n\n' +
|
|
693
|
+
'⚠️ CRITICAL: Close ALL Chrome/Chromium instances BEFORE running this tool! Open browsers can prevent cleanup and cause issues.\n\n' +
|
|
694
|
+
'Categories scanned:\n' +
|
|
695
|
+
'1. Legacy Installation (notebooklm-mcp-nodejs) - Old paths with -nodejs suffix\n' +
|
|
696
|
+
'2. Current Installation (notebooklm-mcp) - Active data, browser profiles, library\n' +
|
|
697
|
+
'3. NPM/NPX Cache - Cached installations from npx\n' +
|
|
698
|
+
'4. Claude CLI MCP Logs - MCP server logs from Claude CLI\n' +
|
|
699
|
+
'5. Temporary Backups - Backup directories in system temp\n' +
|
|
700
|
+
'6. Claude Projects Cache - Project-specific cache (optional)\n' +
|
|
701
|
+
'7. Editor Logs (Cursor/VSCode) - MCP logs from code editors (optional)\n' +
|
|
702
|
+
'8. Trash Files - Deleted notebooklm files in system trash (optional)\n\n' +
|
|
703
|
+
'Works cross-platform (Linux, Windows, macOS). Safe by design: shows detailed preview before deletion, requires explicit confirmation.\n\n' +
|
|
704
|
+
'LIBRARY PRESERVATION: Set preserve_library=true to keep your notebook library.json file while cleaning everything else.\n\n' +
|
|
705
|
+
'RECOMMENDED WORKFLOW for fresh start:\n' +
|
|
706
|
+
'1. Ask user to close ALL Chrome/Chromium instances\n' +
|
|
707
|
+
'2. Run cleanup_data(confirm=false, preserve_library=true) to preview\n' +
|
|
708
|
+
'3. Run cleanup_data(confirm=true, preserve_library=true) to execute\n' +
|
|
709
|
+
'4. Run setup_auth or re_auth for fresh browser session\n\n' +
|
|
710
|
+
'Use cases: Clean reinstall, troubleshooting auth issues, removing all traces before uninstall, cleaning old browser sessions and installation data.',
|
|
711
711
|
inputSchema: {
|
|
712
|
-
type:
|
|
712
|
+
type: 'object',
|
|
713
713
|
properties: {
|
|
714
714
|
confirm: {
|
|
715
|
-
type:
|
|
716
|
-
description:
|
|
717
|
-
|
|
715
|
+
type: 'boolean',
|
|
716
|
+
description: 'Confirmation flag. Tool shows preview first, then user confirms deletion. ' +
|
|
717
|
+
'Set to true only after user has reviewed the preview and explicitly confirmed.',
|
|
718
718
|
},
|
|
719
719
|
preserve_library: {
|
|
720
|
-
type:
|
|
721
|
-
description:
|
|
722
|
-
|
|
720
|
+
type: 'boolean',
|
|
721
|
+
description: 'Preserve library.json file during cleanup. Default: false. ' +
|
|
722
|
+
'Set to true to keep your notebook library while deleting everything else (browser data, caches, logs).',
|
|
723
723
|
default: false,
|
|
724
724
|
},
|
|
725
725
|
},
|
|
726
|
-
required: [
|
|
726
|
+
required: ['confirm'],
|
|
727
727
|
},
|
|
728
728
|
},
|
|
729
729
|
];
|
|
@@ -772,7 +772,7 @@ export class ToolHandlers {
|
|
|
772
772
|
` { "question": "...", "notebook_url": "https://notebooklm.google.com/notebook/..." }`);
|
|
773
773
|
}
|
|
774
774
|
else {
|
|
775
|
-
const availableIds = allNotebooks.map(n => n.id).join(', ');
|
|
775
|
+
const availableIds = allNotebooks.map((n) => n.id).join(', ');
|
|
776
776
|
throw new Error(`Notebook not found: '${notebook_id}'\n\n` +
|
|
777
777
|
`Available notebooks: ${availableIds}\n\n` +
|
|
778
778
|
`To list all notebooks: GET /notebooks\n` +
|
|
@@ -806,7 +806,7 @@ export class ToolHandlers {
|
|
|
806
806
|
` GET /notebooks to list available notebooks`);
|
|
807
807
|
}
|
|
808
808
|
else {
|
|
809
|
-
const availableIds = allNotebooks.map(n => `${n.id} (${n.name})`).join('\n - ');
|
|
809
|
+
const availableIds = allNotebooks.map((n) => `${n.id} (${n.name})`).join('\n - ');
|
|
810
810
|
throw new Error(`❌ No notebook specified.\n\n` +
|
|
811
811
|
`Available notebooks:\n - ${availableIds}\n\n` +
|
|
812
812
|
`Please specify one of:\n` +
|
|
@@ -817,7 +817,7 @@ export class ToolHandlers {
|
|
|
817
817
|
}
|
|
818
818
|
}
|
|
819
819
|
// Progress: Getting or creating session
|
|
820
|
-
await sendProgress?.(
|
|
820
|
+
await sendProgress?.('Getting or creating browser session...', 1, 5);
|
|
821
821
|
// Apply browser options temporarily
|
|
822
822
|
const originalConfig = { ...CONFIG };
|
|
823
823
|
const effectiveConfig = applyBrowserOptions(browser_options, show_browser);
|
|
@@ -838,7 +838,7 @@ export class ToolHandlers {
|
|
|
838
838
|
// Get or create session (with headless override to handle mode changes)
|
|
839
839
|
const session = await this.sessionManager.getOrCreateSession(session_id, resolvedNotebookUrl, overrideHeadless);
|
|
840
840
|
// Progress: Asking question
|
|
841
|
-
await sendProgress?.(
|
|
841
|
+
await sendProgress?.('Asking question to NotebookLM...', 2, 5);
|
|
842
842
|
// Ask the question (pass progress callback)
|
|
843
843
|
const rawAnswer = await session.ask(question, sendProgress);
|
|
844
844
|
// Note: FOLLOW_UP_REMINDER removed for cleaner responses
|
|
@@ -846,7 +846,7 @@ export class ToolHandlers {
|
|
|
846
846
|
// Get session info
|
|
847
847
|
const sessionInfo = session.getInfo();
|
|
848
848
|
const result = {
|
|
849
|
-
status:
|
|
849
|
+
status: 'success',
|
|
850
850
|
question,
|
|
851
851
|
answer,
|
|
852
852
|
session_id: session.sessionId,
|
|
@@ -858,7 +858,7 @@ export class ToolHandlers {
|
|
|
858
858
|
},
|
|
859
859
|
};
|
|
860
860
|
// Progress: Complete
|
|
861
|
-
await sendProgress?.(
|
|
861
|
+
await sendProgress?.('Question answered successfully!', 5, 5);
|
|
862
862
|
log.success(`✅ [TOOL] ask_question completed successfully`);
|
|
863
863
|
return {
|
|
864
864
|
success: true,
|
|
@@ -873,15 +873,15 @@ export class ToolHandlers {
|
|
|
873
873
|
catch (error) {
|
|
874
874
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
875
875
|
// Special handling for rate limit errors
|
|
876
|
-
if (error instanceof RateLimitError || errorMessage.toLowerCase().includes(
|
|
876
|
+
if (error instanceof RateLimitError || errorMessage.toLowerCase().includes('rate limit')) {
|
|
877
877
|
log.error(`🚫 [TOOL] Rate limit detected`);
|
|
878
878
|
return {
|
|
879
879
|
success: false,
|
|
880
|
-
error:
|
|
881
|
-
|
|
880
|
+
error: 'NotebookLM rate limit reached (50 queries/day for free accounts).\n\n' +
|
|
881
|
+
'You can:\n' +
|
|
882
882
|
"1. Use the 're_auth' tool to login with a different Google account\n" +
|
|
883
|
-
|
|
884
|
-
|
|
883
|
+
'2. Wait until tomorrow for the quota to reset\n' +
|
|
884
|
+
'3. Upgrade to Google AI Pro/Ultra for 5x higher limits\n\n' +
|
|
885
885
|
`Original error: ${errorMessage}`,
|
|
886
886
|
};
|
|
887
887
|
}
|
|
@@ -945,7 +945,7 @@ export class ToolHandlers {
|
|
|
945
945
|
return {
|
|
946
946
|
success: true,
|
|
947
947
|
data: {
|
|
948
|
-
status:
|
|
948
|
+
status: 'success',
|
|
949
949
|
message: `Session ${session_id} closed successfully`,
|
|
950
950
|
session_id,
|
|
951
951
|
},
|
|
@@ -989,7 +989,7 @@ export class ToolHandlers {
|
|
|
989
989
|
return {
|
|
990
990
|
success: true,
|
|
991
991
|
data: {
|
|
992
|
-
status:
|
|
992
|
+
status: 'success',
|
|
993
993
|
message: `Session ${session_id} reset successfully`,
|
|
994
994
|
session_id,
|
|
995
995
|
},
|
|
@@ -1016,9 +1016,9 @@ export class ToolHandlers {
|
|
|
1016
1016
|
// Get session stats
|
|
1017
1017
|
const stats = this.sessionManager.getStats();
|
|
1018
1018
|
const result = {
|
|
1019
|
-
status:
|
|
1019
|
+
status: 'ok',
|
|
1020
1020
|
authenticated,
|
|
1021
|
-
notebook_url: CONFIG.notebookUrl ||
|
|
1021
|
+
notebook_url: CONFIG.notebookUrl || 'not configured',
|
|
1022
1022
|
active_sessions: stats.active_sessions,
|
|
1023
1023
|
max_sessions: stats.max_sessions,
|
|
1024
1024
|
session_timeout: stats.session_timeout,
|
|
@@ -1027,9 +1027,9 @@ export class ToolHandlers {
|
|
|
1027
1027
|
auto_login_enabled: CONFIG.autoLoginEnabled,
|
|
1028
1028
|
stealth_enabled: CONFIG.stealthEnabled,
|
|
1029
1029
|
// Add troubleshooting tip if not authenticated
|
|
1030
|
-
...(
|
|
1031
|
-
troubleshooting_tip:
|
|
1032
|
-
|
|
1030
|
+
...(!authenticated && {
|
|
1031
|
+
troubleshooting_tip: 'For fresh start with clean browser session: Close all Chrome instances → ' +
|
|
1032
|
+
'cleanup_data(confirm=true, preserve_library=true) → setup_auth',
|
|
1033
1033
|
}),
|
|
1034
1034
|
};
|
|
1035
1035
|
log.success(`✅ [TOOL] get_health completed`);
|
|
@@ -1056,7 +1056,7 @@ export class ToolHandlers {
|
|
|
1056
1056
|
async handleSetupAuth(args, sendProgress) {
|
|
1057
1057
|
const { show_browser, browser_options } = args;
|
|
1058
1058
|
// CRITICAL: Send immediate progress to reset timeout from the very start
|
|
1059
|
-
await sendProgress?.(
|
|
1059
|
+
await sendProgress?.('Initializing authentication setup...', 0, 10);
|
|
1060
1060
|
log.info(`🔧 [TOOL] setup_auth called`);
|
|
1061
1061
|
if (show_browser !== undefined) {
|
|
1062
1062
|
log.info(` Show browser: ${show_browser}`);
|
|
@@ -1068,22 +1068,22 @@ export class ToolHandlers {
|
|
|
1068
1068
|
Object.assign(CONFIG, effectiveConfig);
|
|
1069
1069
|
try {
|
|
1070
1070
|
// Progress: Starting
|
|
1071
|
-
await sendProgress?.(
|
|
1071
|
+
await sendProgress?.('Preparing authentication browser...', 1, 10);
|
|
1072
1072
|
log.info(` 🌐 Opening browser for interactive login...`);
|
|
1073
1073
|
// Progress: Opening browser
|
|
1074
|
-
await sendProgress?.(
|
|
1074
|
+
await sendProgress?.('Opening browser window...', 2, 10);
|
|
1075
1075
|
// Perform setup with progress updates (uses CONFIG internally)
|
|
1076
1076
|
const success = await this.authManager.performSetup(sendProgress);
|
|
1077
1077
|
const durationSeconds = (Date.now() - startTime) / 1000;
|
|
1078
1078
|
if (success) {
|
|
1079
1079
|
// Progress: Complete
|
|
1080
|
-
await sendProgress?.(
|
|
1080
|
+
await sendProgress?.('Authentication saved successfully!', 10, 10);
|
|
1081
1081
|
log.success(`✅ [TOOL] setup_auth completed (${durationSeconds.toFixed(1)}s)`);
|
|
1082
1082
|
return {
|
|
1083
1083
|
success: true,
|
|
1084
1084
|
data: {
|
|
1085
|
-
status:
|
|
1086
|
-
message:
|
|
1085
|
+
status: 'authenticated',
|
|
1086
|
+
message: 'Successfully authenticated and saved browser state',
|
|
1087
1087
|
authenticated: true,
|
|
1088
1088
|
duration_seconds: durationSeconds,
|
|
1089
1089
|
},
|
|
@@ -1093,7 +1093,7 @@ export class ToolHandlers {
|
|
|
1093
1093
|
log.error(`❌ [TOOL] setup_auth failed (${durationSeconds.toFixed(1)}s)`);
|
|
1094
1094
|
return {
|
|
1095
1095
|
success: false,
|
|
1096
|
-
error:
|
|
1096
|
+
error: 'Authentication failed or was cancelled',
|
|
1097
1097
|
};
|
|
1098
1098
|
}
|
|
1099
1099
|
}
|
|
@@ -1127,19 +1127,19 @@ export class ToolHandlers {
|
|
|
1127
1127
|
log.info(`🔧 [TOOL] de_auth called`);
|
|
1128
1128
|
try {
|
|
1129
1129
|
// 1. Close all active sessions
|
|
1130
|
-
log.info(
|
|
1130
|
+
log.info(' 🛑 Closing all sessions...');
|
|
1131
1131
|
await this.sessionManager.closeAllSessions();
|
|
1132
|
-
log.success(
|
|
1132
|
+
log.success(' ✅ All sessions closed');
|
|
1133
1133
|
// 2. Clear all auth data
|
|
1134
|
-
log.info(
|
|
1134
|
+
log.info(' 🗑️ Clearing all authentication data...');
|
|
1135
1135
|
await this.authManager.clearAllAuthData();
|
|
1136
|
-
log.success(
|
|
1136
|
+
log.success(' ✅ Authentication data cleared');
|
|
1137
1137
|
log.success(`✅ [TOOL] de_auth completed - Successfully logged out`);
|
|
1138
1138
|
return {
|
|
1139
1139
|
success: true,
|
|
1140
1140
|
data: {
|
|
1141
|
-
status:
|
|
1142
|
-
message:
|
|
1141
|
+
status: 'de-authenticated',
|
|
1142
|
+
message: 'Successfully logged out. Use setup_auth or re_auth to authenticate again.',
|
|
1143
1143
|
authenticated: false,
|
|
1144
1144
|
},
|
|
1145
1145
|
};
|
|
@@ -1164,7 +1164,7 @@ export class ToolHandlers {
|
|
|
1164
1164
|
*/
|
|
1165
1165
|
async handleReAuth(args, sendProgress) {
|
|
1166
1166
|
const { show_browser, browser_options } = args;
|
|
1167
|
-
await sendProgress?.(
|
|
1167
|
+
await sendProgress?.('Preparing re-authentication...', 0, 12);
|
|
1168
1168
|
log.info(`🔧 [TOOL] re_auth called`);
|
|
1169
1169
|
if (show_browser !== undefined) {
|
|
1170
1170
|
log.info(` Show browser: ${show_browser}`);
|
|
@@ -1176,26 +1176,26 @@ export class ToolHandlers {
|
|
|
1176
1176
|
Object.assign(CONFIG, effectiveConfig);
|
|
1177
1177
|
try {
|
|
1178
1178
|
// 1. De-authenticate first (logout)
|
|
1179
|
-
await sendProgress?.(
|
|
1180
|
-
log.info(
|
|
1179
|
+
await sendProgress?.('De-authenticating...', 1, 12);
|
|
1180
|
+
log.info(' 🔓 De-authenticating (logout)...');
|
|
1181
1181
|
const deAuthResult = await this.handleDeAuth();
|
|
1182
1182
|
if (!deAuthResult.success) {
|
|
1183
1183
|
throw new Error(`De-authentication failed: ${deAuthResult.error}`);
|
|
1184
1184
|
}
|
|
1185
|
-
log.success(
|
|
1185
|
+
log.success(' ✅ De-authentication complete');
|
|
1186
1186
|
// 2. Perform fresh setup
|
|
1187
|
-
await sendProgress?.(
|
|
1188
|
-
log.info(
|
|
1187
|
+
await sendProgress?.('Starting fresh authentication...', 3, 12);
|
|
1188
|
+
log.info(' 🌐 Starting fresh authentication setup...');
|
|
1189
1189
|
const success = await this.authManager.performSetup(sendProgress);
|
|
1190
1190
|
const durationSeconds = (Date.now() - startTime) / 1000;
|
|
1191
1191
|
if (success) {
|
|
1192
|
-
await sendProgress?.(
|
|
1192
|
+
await sendProgress?.('Re-authentication complete!', 12, 12);
|
|
1193
1193
|
log.success(`✅ [TOOL] re_auth completed (${durationSeconds.toFixed(1)}s)`);
|
|
1194
1194
|
return {
|
|
1195
1195
|
success: true,
|
|
1196
1196
|
data: {
|
|
1197
|
-
status:
|
|
1198
|
-
message:
|
|
1197
|
+
status: 'authenticated',
|
|
1198
|
+
message: 'Successfully re-authenticated with new account. All previous sessions have been closed.',
|
|
1199
1199
|
authenticated: true,
|
|
1200
1200
|
duration_seconds: durationSeconds,
|
|
1201
1201
|
},
|
|
@@ -1205,7 +1205,7 @@ export class ToolHandlers {
|
|
|
1205
1205
|
log.error(`❌ [TOOL] re_auth failed (${durationSeconds.toFixed(1)}s)`);
|
|
1206
1206
|
return {
|
|
1207
1207
|
success: false,
|
|
1208
|
-
error:
|
|
1208
|
+
error: 'Re-authentication failed or was cancelled',
|
|
1209
1209
|
};
|
|
1210
1210
|
}
|
|
1211
1211
|
}
|
|
@@ -1244,7 +1244,7 @@ export class ToolHandlers {
|
|
|
1244
1244
|
topics: metadata.tags, // tags → topics
|
|
1245
1245
|
content_types: ['documentation'],
|
|
1246
1246
|
use_cases: metadata.tags.slice(0, 3), // Use first 3 tags as use cases
|
|
1247
|
-
auto_generated: true
|
|
1247
|
+
auto_generated: true,
|
|
1248
1248
|
};
|
|
1249
1249
|
// Add notebook to library
|
|
1250
1250
|
const notebook = await this.library.addNotebook(notebookInput);
|
|
@@ -1492,7 +1492,7 @@ export class ToolHandlers {
|
|
|
1492
1492
|
const cleanupManager = new CleanupManager();
|
|
1493
1493
|
try {
|
|
1494
1494
|
// Always run in deep mode
|
|
1495
|
-
const mode =
|
|
1495
|
+
const mode = 'deep';
|
|
1496
1496
|
if (!confirm) {
|
|
1497
1497
|
// Preview mode - show what would be deleted
|
|
1498
1498
|
log.info(` 📋 Generating cleanup preview (mode: ${mode})...`);
|
|
@@ -1503,7 +1503,7 @@ export class ToolHandlers {
|
|
|
1503
1503
|
return {
|
|
1504
1504
|
success: true,
|
|
1505
1505
|
data: {
|
|
1506
|
-
status:
|
|
1506
|
+
status: 'preview',
|
|
1507
1507
|
mode,
|
|
1508
1508
|
preview: {
|
|
1509
1509
|
categories: preview.categories,
|
|
@@ -1519,36 +1519,23 @@ export class ToolHandlers {
|
|
|
1519
1519
|
const result = await cleanupManager.performCleanup(mode, preserve_library);
|
|
1520
1520
|
if (result.success) {
|
|
1521
1521
|
log.success(`✅ [TOOL] cleanup_data completed - deleted ${result.deletedPaths.length} items`);
|
|
1522
|
-
return {
|
|
1523
|
-
success: true,
|
|
1524
|
-
data: {
|
|
1525
|
-
status: "completed",
|
|
1526
|
-
mode,
|
|
1527
|
-
result: {
|
|
1528
|
-
deletedPaths: result.deletedPaths,
|
|
1529
|
-
failedPaths: result.failedPaths,
|
|
1530
|
-
totalSizeBytes: result.totalSizeBytes,
|
|
1531
|
-
categorySummary: result.categorySummary,
|
|
1532
|
-
},
|
|
1533
|
-
},
|
|
1534
|
-
};
|
|
1535
1522
|
}
|
|
1536
1523
|
else {
|
|
1537
1524
|
log.warning(`⚠️ [TOOL] cleanup_data completed with ${result.failedPaths.length} errors`);
|
|
1538
|
-
return {
|
|
1539
|
-
success: true,
|
|
1540
|
-
data: {
|
|
1541
|
-
status: "partial",
|
|
1542
|
-
mode,
|
|
1543
|
-
result: {
|
|
1544
|
-
deletedPaths: result.deletedPaths,
|
|
1545
|
-
failedPaths: result.failedPaths,
|
|
1546
|
-
totalSizeBytes: result.totalSizeBytes,
|
|
1547
|
-
categorySummary: result.categorySummary,
|
|
1548
|
-
},
|
|
1549
|
-
},
|
|
1550
|
-
};
|
|
1551
1525
|
}
|
|
1526
|
+
return {
|
|
1527
|
+
success: result.success,
|
|
1528
|
+
data: {
|
|
1529
|
+
status: result.success ? 'completed' : 'partial',
|
|
1530
|
+
mode,
|
|
1531
|
+
result: {
|
|
1532
|
+
deletedPaths: result.deletedPaths,
|
|
1533
|
+
failedPaths: result.failedPaths,
|
|
1534
|
+
totalSizeBytes: result.totalSizeBytes,
|
|
1535
|
+
categorySummary: result.categorySummary,
|
|
1536
|
+
},
|
|
1537
|
+
},
|
|
1538
|
+
};
|
|
1552
1539
|
}
|
|
1553
1540
|
}
|
|
1554
1541
|
catch (error) {
|