@roomi-fields/notebooklm-mcp 1.5.7 → 1.5.9
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/LICENSE +22 -22
- package/README.md +219 -219
- package/deployment/INDEX.md +0 -0
- package/deployment/PACKAGE-FILES.txt +180 -180
- package/deployment/QUICK-START.md +0 -0
- package/deployment/docs/01-INSTALL.md +21 -1
- package/deployment/docs/02-CONFIGURATION.md +0 -0
- package/deployment/docs/03-API.md +16 -10
- package/deployment/docs/04-N8N-INTEGRATION.md +0 -0
- package/deployment/docs/05-TROUBLESHOOTING.md +19 -1
- package/deployment/docs/06-NOTEBOOK-LIBRARY.md +9 -9
- package/deployment/docs/07-AUTO-DISCOVERY.md +6 -15
- package/deployment/docs/08-DOCKER.md +0 -0
- package/deployment/docs/08-WSL-USAGE.md +7 -7
- package/deployment/docs/09-MULTI-INTERFACE.md +6 -6
- package/deployment/docs/10-CONTENT-MANAGEMENT.md +15 -19
- package/deployment/docs/11-MULTI-ACCOUNT.md +1 -1
- package/deployment/docs/README.md +4 -50
- package/deployment/scripts/README.md +0 -0
- package/deployment/scripts/install.ps1 +114 -114
- package/deployment/scripts/setup-auth.ps1 +217 -217
- package/deployment/scripts/start-server.ps1 +72 -72
- package/deployment/scripts/stop-server.ps1 +51 -51
- package/deployment/scripts/test-api.ps1 +651 -651
- package/deployment/scripts/test-auth.ps1 +0 -0
- package/deployment/scripts/test-auto-discovery.ps1 +295 -295
- package/deployment/scripts/test-cors.ps1 +398 -398
- package/deployment/scripts/test-errors.ps1 +581 -581
- package/deployment/scripts/test-server.ps1 +140 -140
- package/deployment/scripts/test-sessions.ps1 +426 -426
- package/deployment/scripts/test-validation.ps1 +299 -299
- package/dist/accounts/account-manager.d.ts +0 -0
- package/dist/accounts/account-manager.d.ts.map +0 -0
- package/dist/accounts/account-manager.js +0 -0
- package/dist/accounts/account-manager.js.map +0 -0
- package/dist/accounts/auto-login-manager.d.ts +0 -0
- package/dist/accounts/auto-login-manager.d.ts.map +0 -0
- package/dist/accounts/auto-login-manager.js +0 -0
- package/dist/accounts/auto-login-manager.js.map +0 -0
- package/dist/accounts/crypto.d.ts +0 -0
- package/dist/accounts/crypto.d.ts.map +0 -0
- package/dist/accounts/crypto.js +0 -0
- package/dist/accounts/crypto.js.map +0 -0
- package/dist/accounts/index.d.ts +0 -0
- package/dist/accounts/index.d.ts.map +0 -0
- package/dist/accounts/index.js +0 -0
- package/dist/accounts/index.js.map +0 -0
- package/dist/accounts/types.d.ts +0 -0
- package/dist/accounts/types.d.ts.map +0 -0
- package/dist/accounts/types.js +0 -0
- package/dist/accounts/types.js.map +0 -0
- package/dist/auth/auth-manager.d.ts +0 -0
- package/dist/auth/auth-manager.d.ts.map +0 -0
- package/dist/auth/auth-manager.js +0 -0
- package/dist/auth/auth-manager.js.map +0 -0
- package/dist/auto-discovery/auto-discovery.d.ts +0 -0
- package/dist/auto-discovery/auto-discovery.d.ts.map +0 -0
- package/dist/auto-discovery/auto-discovery.js +0 -0
- package/dist/auto-discovery/auto-discovery.js.map +0 -0
- package/dist/cli/accounts.d.ts +0 -0
- package/dist/cli/accounts.d.ts.map +0 -0
- package/dist/cli/accounts.js +0 -0
- package/dist/cli/accounts.js.map +0 -0
- package/dist/cli/de-auth.d.ts +0 -0
- package/dist/cli/de-auth.d.ts.map +0 -0
- package/dist/cli/de-auth.js +0 -0
- package/dist/cli/de-auth.js.map +0 -0
- package/dist/cli/help.d.ts +0 -0
- package/dist/cli/help.d.ts.map +0 -0
- package/dist/cli/help.js +5 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/setup-auth.d.ts +0 -0
- package/dist/cli/setup-auth.d.ts.map +0 -0
- package/dist/cli/setup-auth.js +0 -0
- package/dist/cli/setup-auth.js.map +0 -0
- package/dist/config.d.ts +0 -0
- package/dist/config.d.ts.map +0 -0
- package/dist/config.js +0 -0
- package/dist/config.js.map +0 -0
- package/dist/content/content-generator.d.ts +0 -0
- package/dist/content/content-generator.d.ts.map +0 -0
- package/dist/content/content-generator.js +0 -0
- package/dist/content/content-generator.js.map +0 -0
- package/dist/content/content-manager.d.ts +8 -0
- package/dist/content/content-manager.d.ts.map +1 -1
- package/dist/content/content-manager.js +411 -67
- package/dist/content/content-manager.js.map +1 -1
- package/dist/content/content-templates.d.ts +0 -0
- package/dist/content/content-templates.d.ts.map +0 -0
- package/dist/content/content-templates.js +0 -0
- package/dist/content/content-templates.js.map +0 -0
- package/dist/content/index.d.ts +0 -0
- package/dist/content/index.d.ts.map +0 -0
- package/dist/content/index.js +0 -0
- package/dist/content/index.js.map +0 -0
- package/dist/content/types.d.ts +0 -0
- package/dist/content/types.d.ts.map +0 -0
- package/dist/content/types.js +0 -0
- package/dist/content/types.js.map +0 -0
- package/dist/errors.d.ts +0 -0
- package/dist/errors.d.ts.map +0 -0
- package/dist/errors.js +0 -0
- package/dist/errors.js.map +0 -0
- package/dist/http-wrapper.d.ts +0 -0
- package/dist/http-wrapper.d.ts.map +0 -0
- package/dist/http-wrapper.js +0 -0
- package/dist/http-wrapper.js.map +0 -0
- package/dist/i18n/en.json +0 -0
- package/dist/i18n/fr.json +0 -0
- package/dist/i18n/index.d.ts +0 -0
- package/dist/i18n/index.d.ts.map +0 -0
- package/dist/i18n/index.js +0 -0
- package/dist/i18n/index.js.map +0 -0
- package/dist/index.d.ts +0 -0
- package/dist/index.d.ts.map +0 -0
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/dist/library/notebook-library.d.ts +0 -0
- package/dist/library/notebook-library.d.ts.map +0 -0
- package/dist/library/notebook-library.js +0 -0
- package/dist/library/notebook-library.js.map +0 -0
- package/dist/library/types.d.ts +0 -0
- package/dist/library/types.d.ts.map +0 -0
- package/dist/library/types.js +0 -0
- package/dist/library/types.js.map +0 -0
- package/dist/session/browser-session.d.ts +12 -0
- package/dist/session/browser-session.d.ts.map +1 -1
- package/dist/session/browser-session.js +156 -32
- package/dist/session/browser-session.js.map +1 -1
- package/dist/session/session-manager.d.ts +0 -0
- package/dist/session/session-manager.d.ts.map +0 -0
- package/dist/session/session-manager.js +0 -0
- package/dist/session/session-manager.js.map +0 -0
- package/dist/session/shared-context-manager.d.ts +0 -0
- package/dist/session/shared-context-manager.d.ts.map +0 -0
- package/dist/session/shared-context-manager.js +0 -0
- package/dist/session/shared-context-manager.js.map +0 -0
- package/dist/startup/startup-manager.d.ts +0 -0
- package/dist/startup/startup-manager.d.ts.map +0 -0
- package/dist/startup/startup-manager.js +0 -0
- package/dist/startup/startup-manager.js.map +0 -0
- package/dist/stdio-http-proxy.d.ts +0 -0
- package/dist/stdio-http-proxy.d.ts.map +0 -0
- package/dist/stdio-http-proxy.js +7 -2
- package/dist/stdio-http-proxy.js.map +1 -1
- package/dist/tools/index.d.ts +0 -0
- package/dist/tools/index.d.ts.map +0 -0
- package/dist/tools/index.js +0 -0
- package/dist/tools/index.js.map +0 -0
- package/dist/types.d.ts +0 -0
- package/dist/types.d.ts.map +0 -0
- package/dist/types.js +0 -0
- package/dist/types.js.map +0 -0
- package/dist/utils/citation-extractor.d.ts +0 -0
- package/dist/utils/citation-extractor.d.ts.map +0 -0
- package/dist/utils/citation-extractor.js +67 -67
- package/dist/utils/citation-extractor.js.map +0 -0
- package/dist/utils/cleanup-manager.d.ts +0 -0
- package/dist/utils/cleanup-manager.d.ts.map +0 -0
- package/dist/utils/cleanup-manager.js +0 -0
- package/dist/utils/cleanup-manager.js.map +0 -0
- package/dist/utils/logger.d.ts +0 -0
- package/dist/utils/logger.d.ts.map +0 -0
- package/dist/utils/logger.js +0 -0
- package/dist/utils/logger.js.map +0 -0
- package/dist/utils/page-utils.d.ts +5 -0
- package/dist/utils/page-utils.d.ts.map +1 -1
- package/dist/utils/page-utils.js +73 -15
- package/dist/utils/page-utils.js.map +1 -1
- package/dist/utils/stealth-utils.d.ts +0 -0
- package/dist/utils/stealth-utils.d.ts.map +0 -0
- package/dist/utils/stealth-utils.js +0 -0
- package/dist/utils/stealth-utils.js.map +0 -0
- package/docs/ADDING_A_LANGUAGE.md +0 -0
- package/docs/ARCHITECTURE_MIGRATION_STUDY.md +0 -0
- package/docs/CHROME_PROFILE_LIMITATION.md +0 -0
- package/docs/MULTI_ACCOUNT_SYSTEM.md +0 -0
- package/package.json +5 -2
- package/scripts/archive/add-and-activate-notebook.ps1 +4 -4
- package/scripts/archive/add-new-notebook.ps1 +4 -4
- package/scripts/archive/add-rom1pey.ps1 +2 -2
- package/scripts/archive/add-rpmonster.ps1 +2 -2
- package/scripts/archive/add-source-debug.ps1 +1 -1
- package/scripts/archive/add-source-e2e.ps1 +1 -1
- package/scripts/archive/add-source-visible.ps1 +1 -1
- package/scripts/archive/add-test-notebook.ps1 +1 -1
- package/scripts/archive/add-test-source.ps1 +1 -1
- package/scripts/archive/capture-screen.ps1 +1 -1
- package/scripts/archive/change-language.mjs +4 -3
- package/scripts/archive/change-language.ts +5 -3
- package/scripts/archive/check-account.ps1 +0 -0
- package/scripts/archive/check-notebook-2.ps1 +0 -0
- package/scripts/archive/check-test-notebook.ps1 +0 -0
- package/scripts/archive/create-notebook-auto.ps1 +0 -0
- package/scripts/archive/create-notebook.ps1 +2 -2
- package/scripts/archive/create-rom1pey-notebook.ps1 +2 -2
- package/scripts/archive/create-rom1pey.ps1 +2 -2
- package/scripts/archive/create-test-notebook-fresh.ps1 +0 -0
- package/scripts/archive/create-test-notebook.ps1 +0 -0
- package/scripts/archive/debug-add-source-auto.ps1 +0 -0
- package/scripts/archive/debug-add-source.ps1 +0 -0
- package/scripts/archive/debug-add-text-source.ps1 +4 -4
- package/scripts/archive/debug-home.ps1 +0 -0
- package/scripts/archive/debug-selectors.ps1 +1 -1
- package/scripts/archive/debug-sources-panel.ps1 +0 -0
- package/scripts/archive/debug-ui.ps1 +0 -0
- package/scripts/archive/discover-home.ps1 +2 -2
- package/scripts/archive/kill-automation-chrome.ps1 +0 -0
- package/scripts/archive/list-my-notebooks.ps1 +0 -0
- package/scripts/archive/navigate-home-visible.ps1 +1 -1
- package/scripts/archive/navigate-home.ps1 +1 -1
- package/scripts/archive/run-e2e-english.ps1 +3 -3
- package/scripts/archive/run-e2e-rom1pey-v2.ps1 +4 -4
- package/scripts/archive/run-e2e-rom1pey.ps1 +4 -4
- package/scripts/archive/setup-english-test.ps1 +6 -6
- package/scripts/archive/setup-test-notebook.ps1 +1 -1
- package/scripts/archive/simple-add-source.ps1 +1 -1
- package/scripts/archive/t10.ps1 +1 -1
- package/scripts/archive/t20.ps1 +1 -1
- package/scripts/archive/t30.ps1 +1 -1
- package/scripts/archive/t31.ps1 +1 -1
- package/scripts/archive/t32.ps1 +1 -1
- package/scripts/archive/t39.ps1 +0 -0
- package/scripts/archive/t40.ps1 +0 -0
- package/scripts/archive/t53.ps1 +1 -1
- package/scripts/archive/t54.ps1 +0 -0
- package/scripts/archive/t55.ps1 +0 -0
- package/scripts/archive/t9.ps1 +0 -0
- package/scripts/archive/test-access.ps1 +1 -1
- package/scripts/archive/test-add-delete-source.ps1 +4 -4
- package/scripts/archive/test-add-source-visible.ps1 +1 -1
- package/scripts/archive/test-add-source.ps1 +1 -1
- package/scripts/archive/test-add-text-debug.ps1 +2 -2
- package/scripts/archive/test-add-text-source.ps1 +0 -0
- package/scripts/archive/test-add-url-source.ps1 +0 -0
- package/scripts/archive/test-ask-ascii.ps1 +0 -0
- package/scripts/archive/test-ask-cnv.ps1 +0 -0
- package/scripts/archive/test-ask-headed.ps1 +1 -1
- package/scripts/archive/test-ask-ifs.ps1 +0 -0
- package/scripts/archive/test-ask-now.ps1 +0 -0
- package/scripts/archive/test-ask-real.ps1 +0 -0
- package/scripts/archive/test-ask-visible.ps1 +0 -0
- package/scripts/archive/test-create-notebook.ps1 +0 -0
- package/scripts/archive/test-create-then-add.ps1 +0 -0
- package/scripts/archive/test-delete-source.ps1 +4 -4
- package/scripts/archive/test-e2e-notebook.ps1 +2 -2
- package/scripts/archive/test-english-notebook.ps1 +4 -4
- package/scripts/archive/test-english.ps1 +1 -1
- package/scripts/archive/test-full-custom-instructions.ps1 +1 -1
- package/scripts/archive/test-full-infographic.ps1 +1 -1
- package/scripts/archive/test-full-language.ps1 +1 -1
- package/scripts/archive/test-full-presentation.ps1 +1 -1
- package/scripts/archive/test-full-report.ps1 +1 -1
- package/scripts/archive/test-full-source-selection.ps1 +1 -1
- package/scripts/archive/test-full-video-brief.ps1 +1 -1
- package/scripts/archive/test-full-video-explainer.ps1 +1 -1
- package/scripts/archive/test-full-video-styles.ps1 +1 -1
- package/scripts/archive/test-generate-report.ps1 +0 -0
- package/scripts/archive/test-generate-study-guide.ps1 +0 -0
- package/scripts/archive/test-headed-ask.ps1 +1 -1
- package/scripts/archive/test-headed-now.ps1 +2 -2
- package/scripts/archive/test-headed.ps1 +2 -2
- package/scripts/archive/test-hello.ps1 +1 -1
- package/scripts/archive/test-i18n-studio.ps1 +0 -0
- package/scripts/archive/test-i18n.ps1 +0 -0
- package/scripts/archive/test-manual-headed.ps1 +1 -1
- package/scripts/archive/test-mathieu-quota.ps1 +1 -1
- package/scripts/archive/test-notebook-1.ps1 +0 -0
- package/scripts/archive/test-notebook-2-sources.ps1 +0 -0
- package/scripts/archive/test-notebook1.ps1 +0 -0
- package/scripts/archive/test-personal-notebook.ps1 +1 -1
- package/scripts/archive/test-rate-limit.ps1 +1 -1
- package/scripts/archive/test-real-ask.ps1 +1 -1
- package/scripts/archive/test-real-ask2.ps1 +1 -1
- package/scripts/archive/test-rom1pey.ps1 +1 -1
- package/scripts/archive/test-rotation-complete.ps1 +1 -1
- package/scripts/archive/test-rotation.ps1 +2 -2
- package/scripts/archive/test-show-browser.ps1 +1 -1
- package/scripts/archive/test-update-notebook.ps1 +1 -1
- package/scripts/archive/verify-language-slow.ps1 +1 -1
- package/scripts/archive/verify-language.ps1 +1 -1
- package/scripts/check-server.ps1 +0 -0
- package/scripts/docker-entrypoint.sh +25 -25
- package/scripts/doctor.mjs +257 -0
- package/scripts/mcp-proxy-hidden.ps1 +0 -0
- package/scripts/mcp-wsl-helper.sh +146 -146
- package/scripts/start-server-hidden.vbs +13 -10
- package/scripts/start-server.ps1 +1 -1
- package/scripts/start-vnc.sh +0 -0
- package/scripts/stop-server.bat +0 -0
- package/scripts/stop-server.ps1 +0 -0
- package/scripts/switch-account-language.sh +87 -128
- package/scripts/test-account.ps1 +0 -0
- package/docs/archive/auto-discovery-complet.md +0 -906
- package/scripts/add-totp.ts +0 -110
|
@@ -1,906 +0,0 @@
|
|
|
1
|
-
# Auto-Discovery Notebooks - Cahier des charges complet
|
|
2
|
-
|
|
3
|
-
## 0. Vision & Contexte stratégique
|
|
4
|
-
|
|
5
|
-
### 0.1 Problème actuel
|
|
6
|
-
|
|
7
|
-
Les utilisateurs de MCP NotebookLM doivent **manuellement** :
|
|
8
|
-
- Nommer chaque notebook
|
|
9
|
-
- Inventer des tags pertinents
|
|
10
|
-
- Écrire des descriptions
|
|
11
|
-
- Deviner quand interroger quel notebook
|
|
12
|
-
|
|
13
|
-
**Résultat** : Bibliothèque mal organisée, discovery impossible, friction maximale.
|
|
14
|
-
|
|
15
|
-
### 0.2 Solution : Progressive Disclosure autonome
|
|
16
|
-
|
|
17
|
-
Inspiré par **Claude Skills best practices** ([doc officielle](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices#progressive-disclosure-patterns)), ce système permet une **découverte progressive et autonome** des ressources documentaires.
|
|
18
|
-
|
|
19
|
-
**Architecture en 3 niveaux** :
|
|
20
|
-
|
|
21
|
-
**Niveau 0 - Startup (ultra-léger)** :
|
|
22
|
-
```
|
|
23
|
-
library.json chargé en mémoire
|
|
24
|
-
├── cnv-pratique-essentiels: "Manuel CNV couvrant 4 étapes..."
|
|
25
|
-
├── n8n-workflows-api: "Documentation complète API n8n..."
|
|
26
|
-
└── react-hooks-guide: "Guide React Hooks et state management..."
|
|
27
|
-
```
|
|
28
|
-
*Coût : ~500 tokens, instantané*
|
|
29
|
-
|
|
30
|
-
**Niveau 1 - Matching contextuel** :
|
|
31
|
-
```
|
|
32
|
-
User: "Je veux automatiser Gmail avec n8n"
|
|
33
|
-
→ Scan metadata (tags: ["n8n", "gmail", "automation"])
|
|
34
|
-
→ Match: "n8n-workflows-api" (score: 95%)
|
|
35
|
-
→ Décision : interroger ce notebook
|
|
36
|
-
```
|
|
37
|
-
*Coût : 0 query NotebookLM (juste matching local)*
|
|
38
|
-
|
|
39
|
-
**Niveau 2 - Query profonde** :
|
|
40
|
-
```
|
|
41
|
-
→ Query NotebookLM: "Comment utiliser le node Gmail dans n8n?"
|
|
42
|
-
→ Réponse précise depuis documentation
|
|
43
|
-
```
|
|
44
|
-
*Coût : 1 query NotebookLM (rate-limited mais ciblée)*
|
|
45
|
-
|
|
46
|
-
### 0.3 Bénéfice clé : Découverte autonome
|
|
47
|
-
|
|
48
|
-
**Avant (manuel)** :
|
|
49
|
-
```
|
|
50
|
-
User → "Utilise le notebook X" → Claude query X
|
|
51
|
-
```
|
|
52
|
-
*L'humain doit savoir quel notebook utiliser*
|
|
53
|
-
|
|
54
|
-
**Après (autonome)** :
|
|
55
|
-
```
|
|
56
|
-
User → "Automatise Gmail" → Système découvre automatiquement → Query notebook pertinent
|
|
57
|
-
```
|
|
58
|
-
*L'orchestrateur (Claude/n8n/Cursor) découvre seul les ressources pertinentes*
|
|
59
|
-
|
|
60
|
-
### 0.4 Cas d'usage orchestrateurs
|
|
61
|
-
|
|
62
|
-
#### Claude Code - Workflow autonome
|
|
63
|
-
|
|
64
|
-
```
|
|
65
|
-
1. User: "Build a Gmail spam filter workflow with n8n"
|
|
66
|
-
|
|
67
|
-
2. Claude (discovery interne):
|
|
68
|
-
- Scan library metadata
|
|
69
|
-
- Match tags: ["n8n", "gmail", "workflows"]
|
|
70
|
-
- Trouve: "n8n-workflows-api"
|
|
71
|
-
|
|
72
|
-
3. Claude (query ciblée):
|
|
73
|
-
- "How does Gmail integration work in n8n?"
|
|
74
|
-
- NotebookLM → réponse précise
|
|
75
|
-
|
|
76
|
-
4. Claude (implémentation):
|
|
77
|
-
- Code le workflow avec infos exactes
|
|
78
|
-
- Zéro hallucination
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
**Sans auto-discovery** : Claude devrait lire tous les notebooks (coûteux) ou demander à l'utilisateur (friction).
|
|
82
|
-
|
|
83
|
-
#### n8n - Automation intelligente
|
|
84
|
-
|
|
85
|
-
```yaml
|
|
86
|
-
HTTP Request: GET /notebooks/match?task=gmail automation
|
|
87
|
-
→ Retourne: notebook pertinent
|
|
88
|
-
|
|
89
|
-
HTTP Request: POST /notebooks/{id}/ask
|
|
90
|
-
→ Query: "What Gmail triggers are available?"
|
|
91
|
-
→ Response: documentation précise
|
|
92
|
-
|
|
93
|
-
Function Node:
|
|
94
|
-
→ Parse response → Configure Gmail node automatiquement
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
**Bénéfice** : n8n peut **auto-découvrir** la documentation nécessaire sans intervention humaine.
|
|
98
|
-
|
|
99
|
-
#### Cursor / IDEs - Contextual matching
|
|
100
|
-
|
|
101
|
-
```typescript
|
|
102
|
-
// Developer demande
|
|
103
|
-
"How do I use the n8n API to create a workflow?"
|
|
104
|
-
|
|
105
|
-
// IDE via MCP
|
|
106
|
-
find_relevant_notebook({ task: "n8n API workflow creation" })
|
|
107
|
-
→ Match: "n8n-workflows-api"
|
|
108
|
-
|
|
109
|
-
// Query automatique
|
|
110
|
-
ask_notebook({ question: "API endpoint for workflow creation?" })
|
|
111
|
-
→ Response avec citations sources
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### 0.5 Avantage compétitif
|
|
115
|
-
|
|
116
|
-
**Feature killer unique** :
|
|
117
|
-
- ❌ PleasePrompto : pas d'auto-discovery
|
|
118
|
-
- ❌ khengyun : pas d'auto-discovery
|
|
119
|
-
- ✅ **roomi-fields : SEUL avec auto-discovery autonome**
|
|
120
|
-
|
|
121
|
-
**Impact produit** :
|
|
122
|
-
- Friction = 0 (30 secondes vs 5 minutes par notebook)
|
|
123
|
-
- Discovery autonome (orchestrateurs self-serve)
|
|
124
|
-
- Library auto-organisée (scalable à 50+ notebooks)
|
|
125
|
-
|
|
126
|
-
### 0.6 Documentation publique à produire
|
|
127
|
-
|
|
128
|
-
**README.md** doit inclure :
|
|
129
|
-
```markdown
|
|
130
|
-
## 🔍 Auto-Discovery : Self-Organizing Documentation
|
|
131
|
-
|
|
132
|
-
The **only MCP NotebookLM server** with autonomous resource discovery.
|
|
133
|
-
|
|
134
|
-
Add notebook → System auto-generates metadata → Orchestrators discover resources autonomously.
|
|
135
|
-
|
|
136
|
-
Perfect for:
|
|
137
|
-
- ✅ Teams with 10+ documentation notebooks
|
|
138
|
-
- ✅ n8n workflows needing dynamic doc access
|
|
139
|
-
- ✅ Claude Code autonomous research
|
|
140
|
-
- ✅ Onboarding new developers
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
**API docs** doit expliquer :
|
|
144
|
-
- Progressive disclosure pattern (3 niveaux)
|
|
145
|
-
- Comment orchestrateurs utilisent le matching
|
|
146
|
-
- Économie de rate limits Google
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
## 1. Spécifications techniques
|
|
151
|
-
|
|
152
|
-
### 1.1 Modifications du schema
|
|
153
|
-
|
|
154
|
-
#### Fichier `src/types/notebook.ts`
|
|
155
|
-
|
|
156
|
-
```typescript
|
|
157
|
-
interface Notebook {
|
|
158
|
-
id: string;
|
|
159
|
-
url: string;
|
|
160
|
-
name: string; // 3 mots max, kebab-case
|
|
161
|
-
description: string; // 2 phrases, 150 chars max
|
|
162
|
-
tags: string[]; // 8-10 keywords
|
|
163
|
-
created_at: string;
|
|
164
|
-
last_queried?: string;
|
|
165
|
-
auto_generated: boolean; // NOUVEAU : indique si metadata auto-générée
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
#### Fichier `src/library/library-manager.ts`
|
|
170
|
-
|
|
171
|
-
**Ajouter méthode de validation :**
|
|
172
|
-
|
|
173
|
-
```typescript
|
|
174
|
-
validateMetadata(metadata: NotebookMetadata): void {
|
|
175
|
-
// Vérifie :
|
|
176
|
-
// - name: kebab-case, 3 mots max, pas de spaces, pas d'espaces
|
|
177
|
-
// - description: <= 150 chars
|
|
178
|
-
// - tags: 8-10 éléments
|
|
179
|
-
// Throw error avec message précis si invalide
|
|
180
|
-
}
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
---
|
|
184
|
-
|
|
185
|
-
### 1.2 Nouveau module Auto-Discovery
|
|
186
|
-
|
|
187
|
-
#### Créer `src/auto-discovery/auto-discovery.ts`
|
|
188
|
-
|
|
189
|
-
```typescript
|
|
190
|
-
class AutoDiscovery {
|
|
191
|
-
constructor(private notebookClient: NotebookLMClient) {}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Query le notebook pour obtenir ses métadonnées
|
|
195
|
-
* Retry automatique en cas d'échec (max 2 fois)
|
|
196
|
-
*/
|
|
197
|
-
async discoverMetadata(notebookUrl: string, maxRetries = 2): Promise<NotebookMetadata> {
|
|
198
|
-
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
199
|
-
try {
|
|
200
|
-
// 1. Ouvre le notebook via notebookClient
|
|
201
|
-
// 2. Envoie le prompt (voir generatePrompt())
|
|
202
|
-
// 3. Parse la réponse JSON (voir parseResponse())
|
|
203
|
-
// 4. Valide le format (voir validateMetadata())
|
|
204
|
-
// 5. Retourne metadata
|
|
205
|
-
return await this._discover(notebookUrl);
|
|
206
|
-
} catch (error) {
|
|
207
|
-
if (attempt === maxRetries) throw error;
|
|
208
|
-
await this.delay(2000); // Wait 2s before retry
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Parse et valide la réponse JSON de NotebookLM
|
|
215
|
-
*/
|
|
216
|
-
private parseResponse(response: string): NotebookMetadata {
|
|
217
|
-
// 1. Nettoie markdown code blocks si présents
|
|
218
|
-
let cleaned = response.replace(/```json\n?/g, '').replace(/```\n?/g, '').trim();
|
|
219
|
-
|
|
220
|
-
// 2. Parse JSON
|
|
221
|
-
const parsed = JSON.parse(cleaned);
|
|
222
|
-
|
|
223
|
-
// 3. Valide structure
|
|
224
|
-
this.validateMetadata(parsed);
|
|
225
|
-
|
|
226
|
-
return parsed;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Valide que la metadata respecte les règles
|
|
231
|
-
*/
|
|
232
|
-
private validateMetadata(metadata: NotebookMetadata): void {
|
|
233
|
-
// name: kebab-case, 3 mots max
|
|
234
|
-
const nameRegex = /^[a-z0-9]+(-[a-z0-9]+){0,2}$/;
|
|
235
|
-
if (!nameRegex.test(metadata.name)) {
|
|
236
|
-
throw new Error(`Invalid name format: "${metadata.name}". Must be kebab-case, 3 words max.`);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// description: <= 150 chars
|
|
240
|
-
if (metadata.description.length > 150) {
|
|
241
|
-
throw new Error(`Description too long: ${metadata.description.length} chars (max 150)`);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// tags: 8-10 éléments
|
|
245
|
-
if (metadata.tags.length < 8 || metadata.tags.length > 10) {
|
|
246
|
-
throw new Error(`Invalid tags count: ${metadata.tags.length} (must be 8-10)`);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Génère le prompt pour NotebookLM
|
|
252
|
-
*/
|
|
253
|
-
private generatePrompt(): string {
|
|
254
|
-
return `Analyze your complete content and respond ONLY in this JSON format:
|
|
255
|
-
|
|
256
|
-
{
|
|
257
|
-
"name": "example-notebook-name",
|
|
258
|
-
"description": "First sentence describes main topic. Second sentence adds key details.",
|
|
259
|
-
"tags": ["keyword1", "keyword2", "keyword3", "keyword4", "keyword5", "keyword6", "keyword7", "keyword8"]
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
Rules:
|
|
263
|
-
- name: 3 words maximum, kebab-case format (e.g., "react-hooks-guide", "n8n-api-docs")
|
|
264
|
-
- description: exactly 2 sentences, total length under 150 characters
|
|
265
|
-
- tags: between 8 and 10 keywords covering:
|
|
266
|
-
* Core concepts (3-4 tags like "react", "hooks", "state")
|
|
267
|
-
* Actions/verbs (2-3 tags like "debugging", "testing")
|
|
268
|
-
* Use contexts (2-3 tags like "frontend", "api", "automation")
|
|
269
|
-
|
|
270
|
-
OUTPUT ONLY VALID JSON. NO OTHER TEXT.`;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
private delay(ms: number): Promise<void> {
|
|
274
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
---
|
|
280
|
-
|
|
281
|
-
### 1.3 Nouvelle route HTTP
|
|
282
|
-
|
|
283
|
-
#### Modifier `src/http/routes/notebooks.ts`
|
|
284
|
-
|
|
285
|
-
```typescript
|
|
286
|
-
router.post('/notebooks/auto-discover', async (req, res) => {
|
|
287
|
-
try {
|
|
288
|
-
const { url } = req.body;
|
|
289
|
-
|
|
290
|
-
// Validation
|
|
291
|
-
if (!url || !url.includes('notebooklm.google.com')) {
|
|
292
|
-
return res.status(400).json({
|
|
293
|
-
error: 'Invalid NotebookLM URL',
|
|
294
|
-
expected: 'https://notebooklm.google.com/notebook/...'
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// 1. Auto-discover metadata
|
|
299
|
-
const autoDiscovery = new AutoDiscovery(notebookClient);
|
|
300
|
-
const metadata = await autoDiscovery.discoverMetadata(url);
|
|
301
|
-
|
|
302
|
-
// 2. Créer notebook avec metadata
|
|
303
|
-
const notebook = await libraryManager.addNotebook({
|
|
304
|
-
url,
|
|
305
|
-
...metadata,
|
|
306
|
-
auto_generated: true
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
// 3. Retourner résultat
|
|
310
|
-
res.json({
|
|
311
|
-
success: true,
|
|
312
|
-
notebook,
|
|
313
|
-
message: 'Notebook auto-discovered and added to library'
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
} catch (error) {
|
|
317
|
-
// Gestion erreurs détaillée
|
|
318
|
-
if (error.message.includes('Invalid name format')) {
|
|
319
|
-
return res.status(500).json({
|
|
320
|
-
error: 'NotebookLM returned invalid metadata format',
|
|
321
|
-
details: error.message
|
|
322
|
-
});
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
res.status(500).json({
|
|
326
|
-
error: error.message,
|
|
327
|
-
hint: 'NotebookLM might have returned invalid format. Try again.'
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
});
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
---
|
|
334
|
-
|
|
335
|
-
### 1.4 Gestion des erreurs
|
|
336
|
-
|
|
337
|
-
| Cas d'erreur | Code HTTP | Message |
|
|
338
|
-
|--------------|-----------|---------|
|
|
339
|
-
| URL invalide | 400 | "Invalid NotebookLM URL" |
|
|
340
|
-
| Notebook inaccessible | 404 | "Notebook not found or not accessible" |
|
|
341
|
-
| Réponse NotebookLM invalide | 500 | "NotebookLM returned invalid format" |
|
|
342
|
-
| Timeout NotebookLM | 504 | "NotebookLM query timeout (>30s)" |
|
|
343
|
-
| Format JSON invalide | 500 | "Could not parse NotebookLM response" |
|
|
344
|
-
| Validation metadata échouée | 500 | "Generated metadata is invalid: [details]" |
|
|
345
|
-
|
|
346
|
-
---
|
|
347
|
-
|
|
348
|
-
## 2. Tests
|
|
349
|
-
|
|
350
|
-
### 2.1 Tests unitaires
|
|
351
|
-
|
|
352
|
-
#### Créer `tests/auto-discovery.test.ts`
|
|
353
|
-
|
|
354
|
-
```typescript
|
|
355
|
-
describe('AutoDiscovery', () => {
|
|
356
|
-
let autoDiscovery: AutoDiscovery;
|
|
357
|
-
|
|
358
|
-
beforeEach(() => {
|
|
359
|
-
autoDiscovery = new AutoDiscovery(mockNotebookClient);
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
test('should parse valid JSON response', () => {
|
|
363
|
-
const response = `{
|
|
364
|
-
"name": "test-notebook-name",
|
|
365
|
-
"description": "Test description sentence one. Test description sentence two.",
|
|
366
|
-
"tags": ["tag1", "tag2", "tag3", "tag4", "tag5", "tag6", "tag7", "tag8"]
|
|
367
|
-
}`;
|
|
368
|
-
|
|
369
|
-
const metadata = autoDiscovery.parseResponse(response);
|
|
370
|
-
expect(metadata.name).toBe('test-notebook-name');
|
|
371
|
-
expect(metadata.tags).toHaveLength(8);
|
|
372
|
-
});
|
|
373
|
-
|
|
374
|
-
test('should reject invalid name format (spaces)', () => {
|
|
375
|
-
const response = `{"name": "Invalid Name With Spaces", "description": "...", "tags": [...]}`;
|
|
376
|
-
expect(() => autoDiscovery.parseResponse(response)).toThrow('Invalid name format');
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
test('should reject invalid name format (too many words)', () => {
|
|
380
|
-
const response = `{"name": "too-many-words-in-name", ...}`;
|
|
381
|
-
expect(() => autoDiscovery.parseResponse(response)).toThrow('Invalid name format');
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
test('should reject too few tags', () => {
|
|
385
|
-
const response = `{"name": "valid-name", "description": "...", "tags": ["tag1", "tag2"]}`;
|
|
386
|
-
expect(() => autoDiscovery.parseResponse(response)).toThrow('Invalid tags count');
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
test('should reject too many tags', () => {
|
|
390
|
-
const response = `{"tags": ["t1","t2","t3","t4","t5","t6","t7","t8","t9","t10","t11"], ...}`;
|
|
391
|
-
expect(() => autoDiscovery.parseResponse(response)).toThrow('Invalid tags count');
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
test('should clean markdown code blocks', () => {
|
|
395
|
-
const response = "```json\n{\"name\": \"test\", ...}\n```";
|
|
396
|
-
const metadata = autoDiscovery.parseResponse(response);
|
|
397
|
-
expect(metadata.name).toBe('test');
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
test('should retry on failure', async () => {
|
|
401
|
-
// Mock failure then success
|
|
402
|
-
mockNotebookClient.query
|
|
403
|
-
.mockRejectedValueOnce(new Error('Timeout'))
|
|
404
|
-
.mockResolvedValueOnce('{"name": "test", ...}');
|
|
405
|
-
|
|
406
|
-
const metadata = await autoDiscovery.discoverMetadata('url');
|
|
407
|
-
expect(metadata.name).toBe('test');
|
|
408
|
-
});
|
|
409
|
-
});
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
### 2.2 Test PowerShell
|
|
413
|
-
|
|
414
|
-
#### Créer `deployment/scripts/test-auto-discovery.ps1`
|
|
415
|
-
|
|
416
|
-
```powershell
|
|
417
|
-
# Test auto-discovery endpoint
|
|
418
|
-
$url = "http://localhost:3000/notebooks/auto-discover"
|
|
419
|
-
$body = @{
|
|
420
|
-
url = "https://notebooklm.google.com/notebook/test-123"
|
|
421
|
-
} | ConvertTo-Json
|
|
422
|
-
|
|
423
|
-
Write-Host "Testing auto-discovery endpoint..." -ForegroundColor Cyan
|
|
424
|
-
|
|
425
|
-
try {
|
|
426
|
-
$response = Invoke-RestMethod -Uri $url -Method POST -Body $body -ContentType "application/json"
|
|
427
|
-
|
|
428
|
-
Write-Host "✓ Auto-discovery successful" -ForegroundColor Green
|
|
429
|
-
Write-Host " Name: $($response.notebook.name)" -ForegroundColor White
|
|
430
|
-
Write-Host " Description: $($response.notebook.description)" -ForegroundColor White
|
|
431
|
-
Write-Host " Tags: $($response.notebook.tags -join ', ')" -ForegroundColor White
|
|
432
|
-
Write-Host " Auto-generated: $($response.notebook.auto_generated)" -ForegroundColor White
|
|
433
|
-
|
|
434
|
-
} catch {
|
|
435
|
-
Write-Host "✗ Test failed: $($_.Exception.Message)" -ForegroundColor Red
|
|
436
|
-
exit 1
|
|
437
|
-
}
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
---
|
|
441
|
-
|
|
442
|
-
## 3. Documentation
|
|
443
|
-
|
|
444
|
-
### 3.1 Mettre à jour `README.md`
|
|
445
|
-
|
|
446
|
-
**Ajouter section après "HTTP REST API" :**
|
|
447
|
-
|
|
448
|
-
```markdown
|
|
449
|
-
## 🔍 Auto-Discovery : Self-Organizing Documentation
|
|
450
|
-
|
|
451
|
-
NotebookLM MCP is the **only MCP server** with autonomous resource discovery.
|
|
452
|
-
|
|
453
|
-
### How it works
|
|
454
|
-
|
|
455
|
-
**1. Add notebook** (zero manual metadata):
|
|
456
|
-
```bash
|
|
457
|
-
curl -X POST http://localhost:3000/notebooks/auto-discover \
|
|
458
|
-
-H "Content-Type: application/json" \
|
|
459
|
-
-d '{"url": "https://notebooklm.google.com/notebook/YOUR_ID"}'
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
**2. System queries NotebookLM** to auto-generate:
|
|
463
|
-
- Kebab-case name (3 words max)
|
|
464
|
-
- Concise description (2 sentences)
|
|
465
|
-
- Relevant tags (8-10 keywords)
|
|
466
|
-
|
|
467
|
-
**3. Orchestrators discover autonomously**:
|
|
468
|
-
- Claude Code finds relevant docs without prompting
|
|
469
|
-
- n8n workflows auto-select documentation
|
|
470
|
-
- Cursor matches context to notebooks
|
|
471
|
-
|
|
472
|
-
### Progressive disclosure pattern
|
|
473
|
-
|
|
474
|
-
Inspired by [Claude Skills best practices](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices#progressive-disclosure-patterns):
|
|
475
|
-
|
|
476
|
-
- **Level 0** (startup): Lightweight metadata loaded (~500 tokens)
|
|
477
|
-
- **Level 1** (matching): Local tag/description search (0 NotebookLM queries)
|
|
478
|
-
- **Level 2** (deep query): Targeted NotebookLM query only when needed
|
|
479
|
-
|
|
480
|
-
### Why this matters
|
|
481
|
-
|
|
482
|
-
**Before**: Manual library management, orchestrators can't discover resources autonomously
|
|
483
|
-
|
|
484
|
-
**After**: Self-organizing library, autonomous documentation discovery
|
|
485
|
-
|
|
486
|
-
Perfect for:
|
|
487
|
-
- ✅ Teams with 10+ documentation notebooks
|
|
488
|
-
- ✅ n8n workflows needing dynamic doc access
|
|
489
|
-
- ✅ Claude Code autonomous research
|
|
490
|
-
- ✅ Onboarding new developers without manual setup
|
|
491
|
-
|
|
492
|
-
### Example workflow
|
|
493
|
-
|
|
494
|
-
```bash
|
|
495
|
-
# 1. Add documentation notebooks (auto-discover metadata)
|
|
496
|
-
curl -X POST /notebooks/auto-discover -d '{"url": "https://notebooklm.google.com/notebook/n8n-docs"}'
|
|
497
|
-
curl -X POST /notebooks/auto-discover -d '{"url": "https://notebooklm.google.com/notebook/react-guide"}'
|
|
498
|
-
|
|
499
|
-
# 2. Claude Code autonomously discovers relevant notebook
|
|
500
|
-
User: "Build Gmail automation with n8n"
|
|
501
|
-
→ System matches: "n8n-docs" (tags: ["n8n", "gmail", "automation"])
|
|
502
|
-
→ Query NotebookLM: "Gmail node configuration?"
|
|
503
|
-
→ Claude implements with accurate info
|
|
504
|
-
|
|
505
|
-
# 3. Zero hallucinations, zero manual intervention
|
|
506
|
-
```
|
|
507
|
-
```
|
|
508
|
-
|
|
509
|
-
### 3.2 Mettre à jour `deployment/docs/03-API.md`
|
|
510
|
-
|
|
511
|
-
**Ajouter section :**
|
|
512
|
-
|
|
513
|
-
```markdown
|
|
514
|
-
### POST `/notebooks/auto-discover`
|
|
515
|
-
|
|
516
|
-
Automatically generate notebook metadata by querying NotebookLM itself.
|
|
517
|
-
|
|
518
|
-
**Request:**
|
|
519
|
-
```json
|
|
520
|
-
{
|
|
521
|
-
"url": "https://notebooklm.google.com/notebook/abc123"
|
|
522
|
-
}
|
|
523
|
-
```
|
|
524
|
-
|
|
525
|
-
**Response (Success):**
|
|
526
|
-
```json
|
|
527
|
-
{
|
|
528
|
-
"success": true,
|
|
529
|
-
"notebook": {
|
|
530
|
-
"id": "generated-uuid",
|
|
531
|
-
"url": "https://notebooklm.google.com/notebook/abc123",
|
|
532
|
-
"name": "cnv-pratique-essentiels",
|
|
533
|
-
"description": "Manuel CNV couvrant 4 étapes fondamentales. Inclut exercices d'auto-empathie et écoute.",
|
|
534
|
-
"tags": [
|
|
535
|
-
"cnv",
|
|
536
|
-
"empathie",
|
|
537
|
-
"communication",
|
|
538
|
-
"besoins",
|
|
539
|
-
"sentiments",
|
|
540
|
-
"demandes",
|
|
541
|
-
"conflits",
|
|
542
|
-
"authenticité"
|
|
543
|
-
],
|
|
544
|
-
"auto_generated": true,
|
|
545
|
-
"created_at": "2025-01-23T10:00:00Z"
|
|
546
|
-
},
|
|
547
|
-
"message": "Notebook auto-discovered and added to library"
|
|
548
|
-
}
|
|
549
|
-
```
|
|
550
|
-
|
|
551
|
-
**Response (Error):**
|
|
552
|
-
```json
|
|
553
|
-
{
|
|
554
|
-
"error": "NotebookLM returned invalid metadata format",
|
|
555
|
-
"details": "Invalid name format: \"Invalid Name\". Must be kebab-case, 3 words max."
|
|
556
|
-
}
|
|
557
|
-
```
|
|
558
|
-
|
|
559
|
-
**Errors:**
|
|
560
|
-
- `400 Bad Request`: Invalid URL format
|
|
561
|
-
- `404 Not Found`: Notebook not accessible
|
|
562
|
-
- `500 Internal Server Error`: NotebookLM query failed or returned invalid format
|
|
563
|
-
- `504 Gateway Timeout`: NotebookLM query timeout (>30s)
|
|
564
|
-
|
|
565
|
-
**How it works:**
|
|
566
|
-
|
|
567
|
-
1. System opens the specified notebook
|
|
568
|
-
2. Sends prompt to NotebookLM asking it to analyze its own content
|
|
569
|
-
3. NotebookLM responds with JSON containing name, description, and tags
|
|
570
|
-
4. System validates the metadata format
|
|
571
|
-
5. Saves notebook to library with auto-generated metadata
|
|
572
|
-
|
|
573
|
-
**Progressive Disclosure Pattern:**
|
|
574
|
-
|
|
575
|
-
This endpoint enables the **Level 0** of progressive disclosure:
|
|
576
|
-
- Metadata stored locally (lightweight, ~100 bytes per notebook)
|
|
577
|
-
- Loaded at startup for instant matching
|
|
578
|
-
- Deep queries to NotebookLM only when notebook is selected
|
|
579
|
-
|
|
580
|
-
Orchestrators (Claude Code, n8n, Cursor) can scan all notebook metadata without rate limit concerns, then query NotebookLM only for the most relevant notebook.
|
|
581
|
-
```
|
|
582
|
-
|
|
583
|
-
### 3.3 Créer `deployment/docs/07-AUTO-DISCOVERY.md`
|
|
584
|
-
|
|
585
|
-
**Nouveau document dédié :**
|
|
586
|
-
|
|
587
|
-
```markdown
|
|
588
|
-
# Auto-Discovery Pattern
|
|
589
|
-
|
|
590
|
-
## Overview
|
|
591
|
-
|
|
592
|
-
Auto-Discovery enables autonomous resource discovery for AI orchestrators. Instead of manually cataloging notebooks, the system queries NotebookLM to generate its own metadata.
|
|
593
|
-
|
|
594
|
-
## Architecture
|
|
595
|
-
|
|
596
|
-
### Three-Level Progressive Disclosure
|
|
597
|
-
|
|
598
|
-
**Level 0 - Metadata Registry (Lightweight)**
|
|
599
|
-
```
|
|
600
|
-
library.json: 5KB for 50 notebooks
|
|
601
|
-
├── Loaded at startup
|
|
602
|
-
├── Cached in memory
|
|
603
|
-
└── Zero NotebookLM queries
|
|
604
|
-
```
|
|
605
|
-
|
|
606
|
-
**Level 1 - Contextual Matching (Local)**
|
|
607
|
-
```
|
|
608
|
-
User query → Tag/description matching → Relevant notebooks
|
|
609
|
-
Example: "gmail automation" → Match tags: ["gmail", "n8n", "automation"]
|
|
610
|
-
Cost: 0 NotebookLM queries (local only)
|
|
611
|
-
```
|
|
612
|
-
|
|
613
|
-
**Level 2 - Deep Query (Rate-Limited)**
|
|
614
|
-
```
|
|
615
|
-
Selected notebook → Query NotebookLM → Precise answer
|
|
616
|
-
Cost: 1 NotebookLM query (rate-limited by Google)
|
|
617
|
-
```
|
|
618
|
-
|
|
619
|
-
## For Orchestrators
|
|
620
|
-
|
|
621
|
-
### Claude Code
|
|
622
|
-
|
|
623
|
-
```typescript
|
|
624
|
-
// Autonomous workflow
|
|
625
|
-
User: "Build n8n Gmail workflow"
|
|
626
|
-
|
|
627
|
-
// Claude internally:
|
|
628
|
-
1. Scan library metadata (instant)
|
|
629
|
-
2. Match: "n8n-workflows-api" (tags: ["n8n", "gmail"])
|
|
630
|
-
3. Query NotebookLM: "Gmail node configuration?"
|
|
631
|
-
4. Implement with accurate info
|
|
632
|
-
```
|
|
633
|
-
|
|
634
|
-
### n8n
|
|
635
|
-
|
|
636
|
-
```yaml
|
|
637
|
-
# Workflow node
|
|
638
|
-
HTTP Request: GET /notebooks/match?task=gmail automation
|
|
639
|
-
→ Returns: relevant notebook
|
|
640
|
-
|
|
641
|
-
HTTP Request: POST /notebooks/{id}/ask
|
|
642
|
-
→ Query: "Available Gmail triggers?"
|
|
643
|
-
→ Response: precise documentation
|
|
644
|
-
```
|
|
645
|
-
|
|
646
|
-
### Cursor / IDEs
|
|
647
|
-
|
|
648
|
-
```typescript
|
|
649
|
-
// Context-aware matching
|
|
650
|
-
Developer: "How to use n8n API?"
|
|
651
|
-
→ MCP: find_relevant_notebook({ task: "n8n API" })
|
|
652
|
-
→ Match: "n8n-workflows-api"
|
|
653
|
-
→ Query notebook for details
|
|
654
|
-
```
|
|
655
|
-
|
|
656
|
-
## Metadata Generation
|
|
657
|
-
|
|
658
|
-
### Prompt to NotebookLM
|
|
659
|
-
|
|
660
|
-
The system sends this prompt to each notebook:
|
|
661
|
-
|
|
662
|
-
```
|
|
663
|
-
Analyze your complete content and respond ONLY in JSON format:
|
|
664
|
-
{
|
|
665
|
-
"name": "kebab-case-name",
|
|
666
|
-
"description": "Two sentences max.",
|
|
667
|
-
"tags": ["8-10", "keywords", "covering", "concepts", "actions", "contexts"]
|
|
668
|
-
}
|
|
669
|
-
```
|
|
670
|
-
|
|
671
|
-
### Validation Rules
|
|
672
|
-
|
|
673
|
-
- **name**: 3 words max, kebab-case, no spaces
|
|
674
|
-
- **description**: 2 sentences, under 150 chars
|
|
675
|
-
- **tags**: 8-10 keywords (concepts + actions + contexts)
|
|
676
|
-
|
|
677
|
-
### Example Generated Metadata
|
|
678
|
-
|
|
679
|
-
```json
|
|
680
|
-
{
|
|
681
|
-
"name": "n8n-workflows-api",
|
|
682
|
-
"description": "Complete n8n API documentation covering workflow creation and node configuration. Includes authentication, webhooks, and error handling.",
|
|
683
|
-
"tags": [
|
|
684
|
-
"n8n",
|
|
685
|
-
"api",
|
|
686
|
-
"workflows",
|
|
687
|
-
"automation",
|
|
688
|
-
"webhooks",
|
|
689
|
-
"nodes",
|
|
690
|
-
"integration",
|
|
691
|
-
"documentation"
|
|
692
|
-
]
|
|
693
|
-
}
|
|
694
|
-
```
|
|
695
|
-
|
|
696
|
-
## Benefits
|
|
697
|
-
|
|
698
|
-
### For Users
|
|
699
|
-
- **Zero friction**: 30 seconds to add notebook (vs 5 minutes manual)
|
|
700
|
-
- **No metadata expertise**: System generates relevant tags automatically
|
|
701
|
-
- **Scalable**: Works with 1 or 100 notebooks
|
|
702
|
-
|
|
703
|
-
### For Orchestrators
|
|
704
|
-
- **Autonomous discovery**: Find relevant docs without human guidance
|
|
705
|
-
- **Token efficient**: Metadata scan costs ~500 tokens (vs 50k+ full read)
|
|
706
|
-
- **Rate limit preservation**: 1 query per notebook add (vs N queries per research)
|
|
707
|
-
|
|
708
|
-
### For Product
|
|
709
|
-
- **Unique feature**: Only NotebookLM MCP with auto-discovery
|
|
710
|
-
- **Better UX**: Frictionless notebook management
|
|
711
|
-
- **Competitive advantage**: Clear differentiator vs other implementations
|
|
712
|
-
|
|
713
|
-
## Comparison with Claude Skills
|
|
714
|
-
|
|
715
|
-
| Aspect | Claude Skills | NotebookLM Auto-Discovery |
|
|
716
|
-
|--------|---------------|---------------------------|
|
|
717
|
-
| Metadata source | SKILL.md file | NotebookLM query |
|
|
718
|
-
| Access cost | Free (local files) | Rate-limited (Google API) |
|
|
719
|
-
| Content depth | Full docs bundled | Query on-demand |
|
|
720
|
-
| Discovery pattern | Read files progressively | Match → Query if needed |
|
|
721
|
-
| Update mechanism | Edit files | Re-query notebook |
|
|
722
|
-
|
|
723
|
-
**Key difference**: Skills are free/local, Notebooks are rate-limited/remote
|
|
724
|
-
→ **Auto-Discovery optimizes for minimal queries via smart metadata matching**
|
|
725
|
-
|
|
726
|
-
## Error Handling
|
|
727
|
-
|
|
728
|
-
### Common Issues
|
|
729
|
-
|
|
730
|
-
**Invalid metadata format**:
|
|
731
|
-
```json
|
|
732
|
-
{
|
|
733
|
-
"error": "Invalid name format",
|
|
734
|
-
"details": "Must be kebab-case, 3 words max"
|
|
735
|
-
}
|
|
736
|
-
```
|
|
737
|
-
→ System retries with same prompt (max 2 retries)
|
|
738
|
-
|
|
739
|
-
**NotebookLM timeout**:
|
|
740
|
-
```json
|
|
741
|
-
{
|
|
742
|
-
"error": "NotebookLM query timeout",
|
|
743
|
-
"hint": "Try again in a few seconds"
|
|
744
|
-
}
|
|
745
|
-
```
|
|
746
|
-
→ Rate limit hit, wait and retry
|
|
747
|
-
|
|
748
|
-
**Notebook not accessible**:
|
|
749
|
-
```json
|
|
750
|
-
{
|
|
751
|
-
"error": "Notebook not found",
|
|
752
|
-
"hint": "Check notebook URL and sharing settings"
|
|
753
|
-
}
|
|
754
|
-
```
|
|
755
|
-
→ Verify notebook is shared with "Anyone with link"
|
|
756
|
-
|
|
757
|
-
## Future Enhancements
|
|
758
|
-
|
|
759
|
-
### Phase 2: Smart Refresh
|
|
760
|
-
```typescript
|
|
761
|
-
PATCH /notebooks/:id/refresh
|
|
762
|
-
→ Re-query NotebookLM to update metadata if content changed
|
|
763
|
-
```
|
|
764
|
-
|
|
765
|
-
### Phase 3: Semantic Matching
|
|
766
|
-
```typescript
|
|
767
|
-
GET /notebooks/match?query=gmail&semantic=true
|
|
768
|
-
→ Use embeddings for advanced matching beyond tags
|
|
769
|
-
```
|
|
770
|
-
|
|
771
|
-
### Phase 4: Usage Analytics
|
|
772
|
-
```typescript
|
|
773
|
-
GET /notebooks/:id/related
|
|
774
|
-
→ "Notebooks often queried together"
|
|
775
|
-
```
|
|
776
|
-
```
|
|
777
|
-
|
|
778
|
-
---
|
|
779
|
-
|
|
780
|
-
## 4. Ordre d'implémentation
|
|
781
|
-
|
|
782
|
-
1. **Schema** : Modifier `src/types/notebook.ts` (5 min)
|
|
783
|
-
2. **Auto-discovery classe** : Créer `src/auto-discovery/auto-discovery.ts` avec prompt et validation (30 min)
|
|
784
|
-
3. **Route HTTP** : Ajouter endpoint `/auto-discover` dans `src/http/routes/notebooks.ts` (20 min)
|
|
785
|
-
4. **Validation** : Ajouter méthode `validateMetadata` dans library-manager (15 min)
|
|
786
|
-
5. **Tests unitaires** : Créer `tests/auto-discovery.test.ts` (20 min)
|
|
787
|
-
6. **Test PowerShell** : Créer script `test-auto-discovery.ps1` (10 min)
|
|
788
|
-
7. **Documentation** : Mettre à jour README, API docs, créer doc auto-discovery (25 min)
|
|
789
|
-
8. **Test manuel** : Valider avec vrai notebook NotebookLM (10 min)
|
|
790
|
-
|
|
791
|
-
**Durée totale estimée : ~2h15**
|
|
792
|
-
|
|
793
|
-
---
|
|
794
|
-
|
|
795
|
-
## 5. Livrables attendus
|
|
796
|
-
|
|
797
|
-
### Code
|
|
798
|
-
- [ ] `src/types/notebook.ts` modifié (ajout champ `auto_generated`)
|
|
799
|
-
- [ ] `src/auto-discovery/auto-discovery.ts` créé (classe complète avec prompt)
|
|
800
|
-
- [ ] `src/http/routes/notebooks.ts` modifié (nouveau endpoint POST `/auto-discover`)
|
|
801
|
-
- [ ] `src/library/library-manager.ts` modifié (méthode `validateMetadata`)
|
|
802
|
-
|
|
803
|
-
### Tests
|
|
804
|
-
- [ ] `tests/auto-discovery.test.ts` créé (tous les tests passent)
|
|
805
|
-
- [ ] `deployment/scripts/test-auto-discovery.ps1` créé (test manuel automatisé)
|
|
806
|
-
- [ ] Test manuel avec vrai notebook NotebookLM validé
|
|
807
|
-
|
|
808
|
-
### Documentation
|
|
809
|
-
- [ ] `README.md` section "Auto-Discovery" ajoutée
|
|
810
|
-
- [ ] `deployment/docs/03-API.md` endpoint `/auto-discover` documenté
|
|
811
|
-
- [ ] `deployment/docs/07-AUTO-DISCOVERY.md` créé (doc complète pattern)
|
|
812
|
-
- [ ] Exemples curl inclus dans documentation
|
|
813
|
-
|
|
814
|
-
### Validation
|
|
815
|
-
- [ ] Endpoint fonctionne avec notebook réel
|
|
816
|
-
- [ ] Format JSON validé (name kebab-case, description 150 chars, 8-10 tags)
|
|
817
|
-
- [ ] Erreurs bien gérées avec messages clairs
|
|
818
|
-
- [ ] Retry logic fonctionne (2 tentatives max)
|
|
819
|
-
- [ ] Tests PowerShell passent
|
|
820
|
-
|
|
821
|
-
---
|
|
822
|
-
|
|
823
|
-
## 6. Critères d'acceptation
|
|
824
|
-
|
|
825
|
-
✅ **Fonctionnel**
|
|
826
|
-
- L'endpoint `/notebooks/auto-discover` retourne metadata valide
|
|
827
|
-
- Le prompt NotebookLM génère JSON conforme aux règles
|
|
828
|
-
- Les metadata sont sauvegardées correctement dans library.json
|
|
829
|
-
- Les erreurs sont gérées avec messages explicites
|
|
830
|
-
- Le retry logic fonctionne (max 2 tentatives, wait 2s)
|
|
831
|
-
|
|
832
|
-
✅ **Qualité code**
|
|
833
|
-
- TypeScript avec types stricts (pas de `any`)
|
|
834
|
-
- Tests unitaires couvrent cas principaux (valid, invalid, retry)
|
|
835
|
-
- Validation stricte des metadata (throw errors précis)
|
|
836
|
-
- Code commenté pour parties critiques (prompt, validation)
|
|
837
|
-
|
|
838
|
-
✅ **Documentation**
|
|
839
|
-
- README explique clairement la feature et son avantage unique
|
|
840
|
-
- API doc complète avec exemples request/response
|
|
841
|
-
- Doc dédiée explique le pattern progressive disclosure
|
|
842
|
-
- Exemples curl testables fournis
|
|
843
|
-
|
|
844
|
-
✅ **User Experience**
|
|
845
|
-
- Message de succès clair avec metadata générée affichée
|
|
846
|
-
- Messages d'erreur explicites avec hints pour résoudre
|
|
847
|
-
- Temps de réponse acceptable (< 30 secondes typical)
|
|
848
|
-
|
|
849
|
-
---
|
|
850
|
-
|
|
851
|
-
## 7. Notes importantes
|
|
852
|
-
|
|
853
|
-
⚠️ **Rate limits Google** : NotebookLM a des limites quotidiennes par compte Google. Le retry logic (max 2 tentatives, wait 2s) aide mais ne résout pas le rate limit. Documenter clairement dans l'API.
|
|
854
|
-
|
|
855
|
-
⚠️ **Format JSON strict** : NotebookLM peut wrapper le JSON dans des code blocks markdown (```json\n...\n```). Le parser DOIT nettoyer avant parse, sinon échec garanti.
|
|
856
|
-
|
|
857
|
-
⚠️ **Validation stricte** : Mieux rejeter metadata invalide que d'accepter data corrompue. Throw errors avec messages précis pour aider au debug.
|
|
858
|
-
|
|
859
|
-
⚠️ **Prompt critique** : Le prompt est LA pièce maîtresse. Il doit être ultra-clair, pas d'ambiguïté. Tested avec un vrai notebook avant implémentation.
|
|
860
|
-
|
|
861
|
-
💡 **Feature unique** : Aucun autre MCP NotebookLM n'a l'auto-discovery → avantage compétitif majeur. À mettre en avant dans toute la communication (README, doc, réseaux sociaux).
|
|
862
|
-
|
|
863
|
-
💡 **Documentation = Produit** : La doc publique (README, API docs) doit expliquer le "pourquoi" (progressive disclosure, autonomous discovery) pas juste le "comment" (endpoint technique). C'est ce qui différencie d'une simple API.
|
|
864
|
-
|
|
865
|
-
---
|
|
866
|
-
|
|
867
|
-
## 8. Après l'implémentation
|
|
868
|
-
|
|
869
|
-
### Communication externe
|
|
870
|
-
|
|
871
|
-
**GitHub** :
|
|
872
|
-
- Release notes v1.3.0 : "Auto-Discovery feature"
|
|
873
|
-
- README badge : "🔍 Auto-Discovery"
|
|
874
|
-
|
|
875
|
-
**LinkedIn / X / Reddit** :
|
|
876
|
-
```
|
|
877
|
-
🚀 New feature: Auto-Discovery for NotebookLM MCP
|
|
878
|
-
|
|
879
|
-
Add a notebook URL → System auto-generates metadata → AI orchestrators discover resources autonomously.
|
|
880
|
-
|
|
881
|
-
The ONLY NotebookLM MCP with progressive disclosure pattern.
|
|
882
|
-
|
|
883
|
-
Perfect for teams with 10+ documentation notebooks.
|
|
884
|
-
|
|
885
|
-
[Link to repo]
|
|
886
|
-
```
|
|
887
|
-
|
|
888
|
-
**Dev.to article** :
|
|
889
|
-
"Building Self-Organizing Documentation Libraries with NotebookLM MCP"
|
|
890
|
-
|
|
891
|
-
### Metrics à suivre
|
|
892
|
-
|
|
893
|
-
- **Adoption** : % utilisateurs qui utilisent `/auto-discover` vs ajout manuel
|
|
894
|
-
- **Accuracy** : % metadata valides générées (target >95%)
|
|
895
|
-
- **Performance** : Temps moyen de discovery (target <20s)
|
|
896
|
-
- **Error rate** : % échecs (rate limit, invalid format, etc.)
|
|
897
|
-
|
|
898
|
-
### Next iterations
|
|
899
|
-
|
|
900
|
-
**Phase 2** : Smart refresh (PATCH `/notebooks/:id/refresh`)
|
|
901
|
-
**Phase 3** : Semantic matching (embeddings)
|
|
902
|
-
**Phase 4** : Usage analytics (notebooks related, popular tags)
|
|
903
|
-
|
|
904
|
-
---
|
|
905
|
-
|
|
906
|
-
**Ce cahier des charges est complet et prêt pour Claude Code.**
|