@pan-sec/notebooklm-mcp 1.4.0
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 +21 -0
- package/README.md +289 -0
- package/SECURITY.md +539 -0
- package/dist/auth/auth-manager.d.ts +137 -0
- package/dist/auth/auth-manager.d.ts.map +1 -0
- package/dist/auth/auth-manager.js +984 -0
- package/dist/auth/auth-manager.js.map +1 -0
- package/dist/auth/mcp-auth.d.ts +102 -0
- package/dist/auth/mcp-auth.d.ts.map +1 -0
- package/dist/auth/mcp-auth.js +286 -0
- package/dist/auth/mcp-auth.js.map +1 -0
- package/dist/config.d.ts +89 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +216 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +26 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +41 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +371 -0
- package/dist/index.js.map +1 -0
- package/dist/library/notebook-library.d.ts +70 -0
- package/dist/library/notebook-library.d.ts.map +1 -0
- package/dist/library/notebook-library.js +279 -0
- package/dist/library/notebook-library.js.map +1 -0
- package/dist/library/types.d.ts +67 -0
- package/dist/library/types.d.ts.map +1 -0
- package/dist/library/types.js +8 -0
- package/dist/library/types.js.map +1 -0
- package/dist/resources/resource-handlers.d.ts +22 -0
- package/dist/resources/resource-handlers.d.ts.map +1 -0
- package/dist/resources/resource-handlers.js +216 -0
- package/dist/resources/resource-handlers.js.map +1 -0
- package/dist/session/browser-session.d.ts +108 -0
- package/dist/session/browser-session.d.ts.map +1 -0
- package/dist/session/browser-session.js +621 -0
- package/dist/session/browser-session.js.map +1 -0
- package/dist/session/session-manager.d.ts +77 -0
- package/dist/session/session-manager.d.ts.map +1 -0
- package/dist/session/session-manager.js +314 -0
- package/dist/session/session-manager.js.map +1 -0
- package/dist/session/session-timeout.d.ts +122 -0
- package/dist/session/session-timeout.d.ts.map +1 -0
- package/dist/session/session-timeout.js +281 -0
- package/dist/session/session-timeout.js.map +1 -0
- package/dist/session/shared-context-manager.d.ts +107 -0
- package/dist/session/shared-context-manager.d.ts.map +1 -0
- package/dist/session/shared-context-manager.js +447 -0
- package/dist/session/shared-context-manager.js.map +1 -0
- package/dist/tools/definitions/ask-question.d.ts +8 -0
- package/dist/tools/definitions/ask-question.d.ts.map +1 -0
- package/dist/tools/definitions/ask-question.js +211 -0
- package/dist/tools/definitions/ask-question.js.map +1 -0
- package/dist/tools/definitions/notebook-management.d.ts +3 -0
- package/dist/tools/definitions/notebook-management.d.ts.map +1 -0
- package/dist/tools/definitions/notebook-management.js +243 -0
- package/dist/tools/definitions/notebook-management.js.map +1 -0
- package/dist/tools/definitions/session-management.d.ts +3 -0
- package/dist/tools/definitions/session-management.d.ts.map +1 -0
- package/dist/tools/definitions/session-management.js +41 -0
- package/dist/tools/definitions/session-management.js.map +1 -0
- package/dist/tools/definitions/system.d.ts +3 -0
- package/dist/tools/definitions/system.d.ts.map +1 -0
- package/dist/tools/definitions/system.js +143 -0
- package/dist/tools/definitions/system.js.map +1 -0
- package/dist/tools/definitions.d.ts +12 -0
- package/dist/tools/definitions.d.ts.map +1 -0
- package/dist/tools/definitions.js +26 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/handlers.d.ts +213 -0
- package/dist/tools/handlers.d.ts.map +1 -0
- package/dist/tools/handlers.js +813 -0
- package/dist/tools/handlers.js.map +1 -0
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +8 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types.d.ts +82 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/audit-logger.d.ts +140 -0
- package/dist/utils/audit-logger.d.ts.map +1 -0
- package/dist/utils/audit-logger.js +361 -0
- package/dist/utils/audit-logger.js.map +1 -0
- package/dist/utils/cert-pinning.d.ts +97 -0
- package/dist/utils/cert-pinning.d.ts.map +1 -0
- package/dist/utils/cert-pinning.js +328 -0
- package/dist/utils/cert-pinning.js.map +1 -0
- package/dist/utils/cleanup-manager.d.ts +133 -0
- package/dist/utils/cleanup-manager.d.ts.map +1 -0
- package/dist/utils/cleanup-manager.js +673 -0
- package/dist/utils/cleanup-manager.js.map +1 -0
- package/dist/utils/cli-handler.d.ts +16 -0
- package/dist/utils/cli-handler.d.ts.map +1 -0
- package/dist/utils/cli-handler.js +102 -0
- package/dist/utils/cli-handler.js.map +1 -0
- package/dist/utils/crypto.d.ts +175 -0
- package/dist/utils/crypto.d.ts.map +1 -0
- package/dist/utils/crypto.js +612 -0
- package/dist/utils/crypto.js.map +1 -0
- package/dist/utils/logger.d.ts +61 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +92 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/page-utils.d.ts +54 -0
- package/dist/utils/page-utils.d.ts.map +1 -0
- package/dist/utils/page-utils.js +405 -0
- package/dist/utils/page-utils.js.map +1 -0
- package/dist/utils/response-validator.d.ts +98 -0
- package/dist/utils/response-validator.d.ts.map +1 -0
- package/dist/utils/response-validator.js +352 -0
- package/dist/utils/response-validator.js.map +1 -0
- package/dist/utils/secrets-scanner.d.ts +126 -0
- package/dist/utils/secrets-scanner.d.ts.map +1 -0
- package/dist/utils/secrets-scanner.js +443 -0
- package/dist/utils/secrets-scanner.js.map +1 -0
- package/dist/utils/secure-memory.d.ts +130 -0
- package/dist/utils/secure-memory.d.ts.map +1 -0
- package/dist/utils/secure-memory.js +279 -0
- package/dist/utils/secure-memory.js.map +1 -0
- package/dist/utils/security.d.ts +83 -0
- package/dist/utils/security.d.ts.map +1 -0
- package/dist/utils/security.js +272 -0
- package/dist/utils/security.js.map +1 -0
- package/dist/utils/settings-manager.d.ts +37 -0
- package/dist/utils/settings-manager.d.ts.map +1 -0
- package/dist/utils/settings-manager.js +125 -0
- package/dist/utils/settings-manager.js.map +1 -0
- package/dist/utils/stealth-utils.d.ts +135 -0
- package/dist/utils/stealth-utils.d.ts.map +1 -0
- package/dist/utils/stealth-utils.js +398 -0
- package/dist/utils/stealth-utils.js.map +1 -0
- package/dist/utils/tool-validation.d.ts +93 -0
- package/dist/utils/tool-validation.d.ts.map +1 -0
- package/dist/utils/tool-validation.js +277 -0
- package/dist/utils/tool-validation.js.map +1 -0
- package/docs/SECURITY_IMPLEMENTATION_PLAN.md +437 -0
- package/docs/configuration.md +94 -0
- package/docs/tools.md +34 -0
- package/docs/troubleshooting.md +59 -0
- package/docs/usage-guide.md +245 -0
- package/package.json +82 -0
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
# Security Implementation Plan - High Priority Features
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This plan outlines the implementation of 5 high-priority security features for the notebooklm-mcp-secure fork.
|
|
6
|
+
|
|
7
|
+
**Target Version**: 1.3.0-secure
|
|
8
|
+
**Status**: ✅ ALL PHASES COMPLETE
|
|
9
|
+
**Estimated Files**: 8 new, 6 modified
|
|
10
|
+
|
|
11
|
+
### Implementation Status
|
|
12
|
+
|
|
13
|
+
| Phase | Feature | Status |
|
|
14
|
+
|-------|---------|--------|
|
|
15
|
+
| 1 | Audit Logging | ✅ Complete |
|
|
16
|
+
| 2 | Session Timeout | ✅ Complete |
|
|
17
|
+
| 3 | MCP Authentication | ✅ Complete |
|
|
18
|
+
| 4 | Response Validation | ✅ Complete |
|
|
19
|
+
| 5 | Post-Quantum Encrypted Storage | ✅ Complete |
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Feature 1: Post-Quantum Encrypted Credential Storage ✅
|
|
24
|
+
|
|
25
|
+
### Problem
|
|
26
|
+
Chrome profile stores session cookies and auth state in plaintext on disk at:
|
|
27
|
+
- `~/.local/share/notebooklm-mcp/chrome_profile/`
|
|
28
|
+
- `~/.local/share/notebooklm-mcp/browser_state/state.json`
|
|
29
|
+
|
|
30
|
+
Anyone with disk access can steal the Google session. Additionally, classical encryption may be vulnerable to future quantum computer attacks.
|
|
31
|
+
|
|
32
|
+
### Solution
|
|
33
|
+
Encrypt sensitive files at rest using **hybrid post-quantum encryption**:
|
|
34
|
+
- **ML-KEM-768 (Kyber)** for quantum-resistant key encapsulation
|
|
35
|
+
- **AES-256-GCM** for symmetric encryption
|
|
36
|
+
- **PBKDF2** for classical key derivation from passwords
|
|
37
|
+
|
|
38
|
+
This hybrid approach provides both current security and future quantum resistance.
|
|
39
|
+
|
|
40
|
+
### Implementation (COMPLETE)
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
src/utils/crypto.ts (NEW) ✅
|
|
44
|
+
├── deriveKey(passphrase, salt) → Key derivation using PBKDF2
|
|
45
|
+
├── getMachineKey() → Derive key from machine ID (fallback)
|
|
46
|
+
├── generatePQKeyPair() → Generate ML-KEM-768 key pair
|
|
47
|
+
├── encryptPQ(data, publicKey) → Hybrid PQ+AES-256-GCM encryption
|
|
48
|
+
├── decryptPQ(ciphertext, secretKey) → Hybrid PQ decryption
|
|
49
|
+
├── encryptClassical(data, key) → AES-256-GCM encryption (fallback)
|
|
50
|
+
├── decryptClassical(ciphertext, key) → AES-256-GCM decryption
|
|
51
|
+
└── SecureStorage class
|
|
52
|
+
├── initialize() → Load/generate PQ keys
|
|
53
|
+
├── save(filename, data) → Encrypt with ML-KEM-768 + AES-256-GCM
|
|
54
|
+
├── load(filename) → Decrypt and return data
|
|
55
|
+
├── loadJSON<T>(filename) → Parse JSON after decryption
|
|
56
|
+
├── delete(filename) → Remove all encrypted versions
|
|
57
|
+
├── exists(filename) → Check any version exists
|
|
58
|
+
├── getStatus() → Return encryption status
|
|
59
|
+
└── getPublicKey() → Export PQ public key
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Encrypted File Format
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"version": 2,
|
|
66
|
+
"algorithm": "aes-256-gcm",
|
|
67
|
+
"pqAlgorithm": "ML-KEM-768",
|
|
68
|
+
"encapsulatedKey": "<base64>",
|
|
69
|
+
"iv": "<base64>",
|
|
70
|
+
"salt": "<base64>",
|
|
71
|
+
"tag": "<base64>",
|
|
72
|
+
"ciphertext": "<base64>"
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Files Modified
|
|
77
|
+
- `src/auth/auth-manager.ts` ✅ - Use SecureStorage for state.json, session.json
|
|
78
|
+
- `package.json` ✅ - Added `@noble/post-quantum` dependency
|
|
79
|
+
|
|
80
|
+
### Environment Variables
|
|
81
|
+
```
|
|
82
|
+
NLMCP_ENCRYPTION_ENABLED=true # Default: true
|
|
83
|
+
NLMCP_ENCRYPTION_KEY=<base64-key> # Optional: User-provided classical key
|
|
84
|
+
NLMCP_USE_POST_QUANTUM=true # Default: true
|
|
85
|
+
NLMCP_USE_MACHINE_KEY=true # Default: true (fallback)
|
|
86
|
+
NLMCP_PBKDF2_ITERATIONS=100000 # Default: 100000
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Dependencies
|
|
90
|
+
- Node.js `crypto` module (built-in)
|
|
91
|
+
- `@noble/post-quantum` v0.2.1 - ML-KEM (Kyber) implementation
|
|
92
|
+
|
|
93
|
+
### Security Properties
|
|
94
|
+
1. **Quantum Resistance**: ML-KEM-768 provides ~192-bit post-quantum security
|
|
95
|
+
2. **Hybrid Security**: Even if PQ crypto is broken, AES-256-GCM remains secure
|
|
96
|
+
3. **Forward Secrecy**: New encapsulated key per file save
|
|
97
|
+
4. **Automatic Migration**: Unencrypted files are automatically encrypted on load
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Feature 2: Session Timeout Enforcement
|
|
102
|
+
|
|
103
|
+
### Problem
|
|
104
|
+
Sessions can remain active indefinitely. Stale sessions with valid cookies pose security risk.
|
|
105
|
+
|
|
106
|
+
### Solution
|
|
107
|
+
Implement configurable hard timeout that:
|
|
108
|
+
1. Forces session closure after max lifetime (e.g., 8 hours)
|
|
109
|
+
2. Forces re-authentication after inactivity (e.g., 30 minutes)
|
|
110
|
+
3. Clears sensitive memory on timeout
|
|
111
|
+
|
|
112
|
+
### Implementation
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
src/session/session-timeout.ts (NEW)
|
|
116
|
+
├── SessionTimeoutManager class
|
|
117
|
+
│ ├── startSession(sessionId)
|
|
118
|
+
│ ├── touchSession(sessionId) → Reset inactivity timer
|
|
119
|
+
│ ├── isExpired(sessionId) → boolean
|
|
120
|
+
│ ├── getTimeRemaining(sessionId) → { lifetime, inactivity }
|
|
121
|
+
│ └── onTimeout callback → Cleanup handler
|
|
122
|
+
└── TimeoutConfig interface
|
|
123
|
+
├── maxLifetimeMs: number (default: 8 hours)
|
|
124
|
+
├── inactivityTimeoutMs: number (default: 30 min)
|
|
125
|
+
└── warningBeforeMs: number (default: 5 min)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Files Modified
|
|
129
|
+
- `src/session/session-manager.ts` - Integrate timeout checks
|
|
130
|
+
- `src/session/browser-session.ts` - Call touchSession on activity
|
|
131
|
+
- `src/tools/handlers.ts` - Return timeout warnings in responses
|
|
132
|
+
- `src/config.ts` - Add timeout config options
|
|
133
|
+
|
|
134
|
+
### Environment Variables
|
|
135
|
+
```
|
|
136
|
+
NLMCP_SESSION_MAX_LIFETIME=28800 # 8 hours in seconds
|
|
137
|
+
NLMCP_SESSION_INACTIVITY_TIMEOUT=1800 # 30 minutes in seconds
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Feature 3: Audit Logging
|
|
143
|
+
|
|
144
|
+
### Problem
|
|
145
|
+
No record of what operations were performed, when, or by whom. Critical for:
|
|
146
|
+
- Security incident investigation
|
|
147
|
+
- Compliance requirements
|
|
148
|
+
- Debugging production issues
|
|
149
|
+
|
|
150
|
+
### Solution
|
|
151
|
+
Comprehensive audit log with:
|
|
152
|
+
- All tool invocations with sanitized parameters
|
|
153
|
+
- Authentication events (login, logout, failures)
|
|
154
|
+
- Session lifecycle events
|
|
155
|
+
- Security events (validation failures, rate limits)
|
|
156
|
+
|
|
157
|
+
### Implementation
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
src/utils/audit-logger.ts (NEW)
|
|
161
|
+
├── AuditLogger class
|
|
162
|
+
│ ├── logToolCall(tool, args, result, duration)
|
|
163
|
+
│ ├── logAuthEvent(event, success, details)
|
|
164
|
+
│ ├── logSessionEvent(event, sessionId, details)
|
|
165
|
+
│ ├── logSecurityEvent(event, severity, details)
|
|
166
|
+
│ └── flush() → Force write to disk
|
|
167
|
+
├── AuditEvent interface
|
|
168
|
+
│ ├── timestamp: ISO8601 string
|
|
169
|
+
│ ├── eventType: 'tool' | 'auth' | 'session' | 'security'
|
|
170
|
+
│ ├── eventName: string
|
|
171
|
+
│ ├── success: boolean
|
|
172
|
+
│ ├── duration_ms?: number
|
|
173
|
+
│ ├── details: Record<string, any> (sanitized)
|
|
174
|
+
│ └── hash: SHA256 of previous entry (tamper detection)
|
|
175
|
+
└── Log rotation and retention config
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Log Format (JSONL)
|
|
179
|
+
```json
|
|
180
|
+
{"timestamp":"2025-11-28T10:30:00Z","eventType":"tool","eventName":"ask_question","success":true,"duration_ms":3420,"details":{"question_length":150,"session_id":"abc123"},"hash":"a1b2c3..."}
|
|
181
|
+
{"timestamp":"2025-11-28T10:30:05Z","eventType":"security","eventName":"rate_limit_exceeded","success":false,"details":{"session_id":"abc123","remaining":0},"hash":"d4e5f6..."}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Files Modified
|
|
185
|
+
- `src/tools/handlers.ts` - Add audit logging to all handlers
|
|
186
|
+
- `src/auth/auth-manager.ts` - Log auth events
|
|
187
|
+
- `src/session/session-manager.ts` - Log session events
|
|
188
|
+
- `src/index.ts` - Initialize audit logger on startup
|
|
189
|
+
|
|
190
|
+
### Log Location
|
|
191
|
+
```
|
|
192
|
+
~/.local/share/notebooklm-mcp/audit/
|
|
193
|
+
├── audit-2025-11-28.jsonl
|
|
194
|
+
├── audit-2025-11-27.jsonl
|
|
195
|
+
└── ...
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Environment Variables
|
|
199
|
+
```
|
|
200
|
+
NLMCP_AUDIT_ENABLED=true
|
|
201
|
+
NLMCP_AUDIT_DIR=~/.local/share/notebooklm-mcp/audit
|
|
202
|
+
NLMCP_AUDIT_RETENTION_DAYS=30
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Feature 4: Content Security Policy (Response Validation)
|
|
208
|
+
|
|
209
|
+
### Problem
|
|
210
|
+
NotebookLM responses could potentially contain:
|
|
211
|
+
- Malicious links
|
|
212
|
+
- Prompt injection attempts targeting Claude
|
|
213
|
+
- Encoded payloads
|
|
214
|
+
- Exfiltration URLs
|
|
215
|
+
|
|
216
|
+
### Solution
|
|
217
|
+
Validate and sanitize all responses before returning to the MCP client.
|
|
218
|
+
|
|
219
|
+
### Implementation
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
src/utils/response-validator.ts (NEW)
|
|
223
|
+
├── ResponseValidator class
|
|
224
|
+
│ ├── validate(response) → { safe: boolean, warnings: string[], sanitized: string }
|
|
225
|
+
│ ├── detectMaliciousUrls(text) → URLs to untrusted domains
|
|
226
|
+
│ ├── detectPromptInjection(text) → Injection patterns
|
|
227
|
+
│ ├── detectEncodedPayloads(text) → Base64, hex, etc.
|
|
228
|
+
│ ├── sanitizeResponse(text) → Cleaned text
|
|
229
|
+
│ └── getStats() → { blocked, warned, passed }
|
|
230
|
+
└── ValidationConfig
|
|
231
|
+
├── blockMaliciousUrls: boolean
|
|
232
|
+
├── blockPromptInjection: boolean
|
|
233
|
+
├── warnOnSuspicious: boolean
|
|
234
|
+
└── allowedDomains: string[]
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Detection Patterns
|
|
238
|
+
```typescript
|
|
239
|
+
// Prompt injection patterns (from MEDUSA AI security scanner)
|
|
240
|
+
const PROMPT_INJECTION_PATTERNS = [
|
|
241
|
+
/ignore\s+(all\s+)?(previous|prior|above)\s+(instructions?|prompts?)/i,
|
|
242
|
+
/disregard\s+(all\s+)?(previous|prior|above)/i,
|
|
243
|
+
/you\s+are\s+now\s+in\s+(\w+)\s+mode/i,
|
|
244
|
+
/forget\s+(everything|all|your)\s+(you|instructions)/i,
|
|
245
|
+
/new\s+instructions?:/i,
|
|
246
|
+
/system\s*:\s*/i,
|
|
247
|
+
/\[INST\]/i,
|
|
248
|
+
/<\|im_start\|>/i,
|
|
249
|
+
];
|
|
250
|
+
|
|
251
|
+
// Suspicious URL patterns
|
|
252
|
+
const SUSPICIOUS_URL_PATTERNS = [
|
|
253
|
+
/bit\.ly|tinyurl|t\.co/i, // URL shorteners
|
|
254
|
+
/pastebin|hastebin/i, // Paste services
|
|
255
|
+
/file:\/\//i, // File protocol
|
|
256
|
+
/javascript:/i, // JS protocol
|
|
257
|
+
];
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Files Modified
|
|
261
|
+
- `src/tools/handlers.ts` - Validate responses before returning
|
|
262
|
+
- `src/session/browser-session.ts` - Optional: validate at capture time
|
|
263
|
+
|
|
264
|
+
### Environment Variables
|
|
265
|
+
```
|
|
266
|
+
NLMCP_RESPONSE_VALIDATION=true
|
|
267
|
+
NLMCP_BLOCK_PROMPT_INJECTION=true
|
|
268
|
+
NLMCP_BLOCK_SUSPICIOUS_URLS=true
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Feature 5: MCP Authentication
|
|
274
|
+
|
|
275
|
+
### Problem
|
|
276
|
+
Any process on the local machine can connect to the MCP server via stdio. No authentication means:
|
|
277
|
+
- Malicious processes can use your Google session
|
|
278
|
+
- No accountability for requests
|
|
279
|
+
- Shared machines are especially vulnerable
|
|
280
|
+
|
|
281
|
+
### Solution
|
|
282
|
+
Require authentication token for MCP requests.
|
|
283
|
+
|
|
284
|
+
### Implementation Options
|
|
285
|
+
|
|
286
|
+
#### Option A: Environment Token (Simple)
|
|
287
|
+
```
|
|
288
|
+
NLMCP_AUTH_TOKEN=<random-32-char-token>
|
|
289
|
+
```
|
|
290
|
+
Client must include in request metadata.
|
|
291
|
+
|
|
292
|
+
#### Option B: Unix Socket Permissions (Linux/Mac)
|
|
293
|
+
Instead of stdio, use Unix socket with file permissions.
|
|
294
|
+
|
|
295
|
+
#### Option C: Challenge-Response (Most Secure)
|
|
296
|
+
1. Server generates challenge on connect
|
|
297
|
+
2. Client signs challenge with shared secret
|
|
298
|
+
3. Server validates signature
|
|
299
|
+
|
|
300
|
+
### Chosen: Option A (Environment Token) + Option B (Unix Socket)
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
src/auth/mcp-auth.ts (NEW)
|
|
304
|
+
├── MCPAuthenticator class
|
|
305
|
+
│ ├── validateToken(token) → boolean
|
|
306
|
+
│ ├── generateToken() → string (for initial setup)
|
|
307
|
+
│ ├── hashToken(token) → string (stored hash, not plaintext)
|
|
308
|
+
│ └── isEnabled() → boolean
|
|
309
|
+
└── Token storage in encrypted config
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Files Modified
|
|
313
|
+
- `src/index.ts` - Add auth middleware to MCP server
|
|
314
|
+
- `src/config.ts` - Add auth config options
|
|
315
|
+
|
|
316
|
+
### Environment Variables
|
|
317
|
+
```
|
|
318
|
+
NLMCP_AUTH_ENABLED=true
|
|
319
|
+
NLMCP_AUTH_TOKEN=<token> # Or auto-generated on first run
|
|
320
|
+
NLMCP_AUTH_TOKEN_FILE=~/.config/notebooklm-mcp/token
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Client Configuration (Claude Code)
|
|
324
|
+
```json
|
|
325
|
+
{
|
|
326
|
+
"mcpServers": {
|
|
327
|
+
"notebooklm": {
|
|
328
|
+
"command": "npx",
|
|
329
|
+
"args": ["notebooklm-mcp-secure"],
|
|
330
|
+
"env": {
|
|
331
|
+
"NLMCP_AUTH_TOKEN": "<your-token>"
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Implementation Order
|
|
341
|
+
|
|
342
|
+
| Phase | Feature | Complexity | Dependencies |
|
|
343
|
+
|-------|---------|------------|--------------|
|
|
344
|
+
| 1 | Audit Logging | Medium | None |
|
|
345
|
+
| 2 | Session Timeout | Low | None |
|
|
346
|
+
| 3 | MCP Authentication | Medium | None |
|
|
347
|
+
| 4 | Response Validation | Medium | MEDUSA patterns |
|
|
348
|
+
| 5 | Encrypted Storage | High | Phase 1 (for key storage) |
|
|
349
|
+
|
|
350
|
+
### Rationale
|
|
351
|
+
1. **Audit Logging first** - Enables monitoring of all subsequent changes
|
|
352
|
+
2. **Session Timeout second** - Quick win, low risk
|
|
353
|
+
3. **MCP Auth third** - Critical for shared environments
|
|
354
|
+
4. **Response Validation fourth** - Leverages MEDUSA patterns
|
|
355
|
+
5. **Encrypted Storage last** - Most complex, benefits from audit logs
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Testing Plan
|
|
360
|
+
|
|
361
|
+
### Unit Tests
|
|
362
|
+
```
|
|
363
|
+
tests/
|
|
364
|
+
├── crypto.test.ts
|
|
365
|
+
├── session-timeout.test.ts
|
|
366
|
+
├── audit-logger.test.ts
|
|
367
|
+
├── response-validator.test.ts
|
|
368
|
+
└── mcp-auth.test.ts
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Integration Tests
|
|
372
|
+
- Full flow with all security features enabled
|
|
373
|
+
- Timeout behavior under load
|
|
374
|
+
- Audit log integrity verification
|
|
375
|
+
- Auth token rotation
|
|
376
|
+
|
|
377
|
+
### Security Tests
|
|
378
|
+
- Attempt to bypass auth
|
|
379
|
+
- Inject malicious responses
|
|
380
|
+
- Tamper with audit logs
|
|
381
|
+
- Access encrypted data without key
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
## Rollout
|
|
386
|
+
|
|
387
|
+
### Version 1.3.0-secure.1
|
|
388
|
+
- Audit Logging
|
|
389
|
+
- Session Timeout
|
|
390
|
+
|
|
391
|
+
### Version 1.3.0-secure.2
|
|
392
|
+
- MCP Authentication
|
|
393
|
+
- Response Validation
|
|
394
|
+
|
|
395
|
+
### Version 1.3.0-secure.3
|
|
396
|
+
- Encrypted Storage
|
|
397
|
+
- Full integration testing
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## Success Metrics
|
|
402
|
+
|
|
403
|
+
| Feature | Metric |
|
|
404
|
+
|---------|--------|
|
|
405
|
+
| Encrypted Storage | 0 plaintext credentials on disk |
|
|
406
|
+
| Session Timeout | 100% sessions expire correctly |
|
|
407
|
+
| Audit Logging | All events logged with <1ms overhead |
|
|
408
|
+
| Response Validation | 0 prompt injections passed through |
|
|
409
|
+
| MCP Auth | 0 unauthorized requests processed |
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
## Appendix: File Structure After Implementation
|
|
414
|
+
|
|
415
|
+
```
|
|
416
|
+
src/
|
|
417
|
+
├── auth/
|
|
418
|
+
│ ├── auth-manager.ts (modified)
|
|
419
|
+
│ └── mcp-auth.ts (NEW)
|
|
420
|
+
├── session/
|
|
421
|
+
│ ├── browser-session.ts (modified)
|
|
422
|
+
│ ├── session-manager.ts (modified)
|
|
423
|
+
│ └── session-timeout.ts (NEW)
|
|
424
|
+
├── utils/
|
|
425
|
+
│ ├── security.ts (existing)
|
|
426
|
+
│ ├── crypto.ts (NEW)
|
|
427
|
+
│ ├── audit-logger.ts (NEW)
|
|
428
|
+
│ └── response-validator.ts (NEW)
|
|
429
|
+
├── config.ts (modified)
|
|
430
|
+
└── index.ts (modified)
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
**Document Version**: 1.0
|
|
436
|
+
**Created**: 2025-11-28
|
|
437
|
+
**Author**: Pantheon Security
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
## Configuration
|
|
2
|
+
|
|
3
|
+
**No config files needed!** The server works out of the box with sensible defaults.
|
|
4
|
+
|
|
5
|
+
### Configuration Priority (highest to lowest):
|
|
6
|
+
1. **Tool Parameters** - Claude passes settings like `browser_options` at runtime
|
|
7
|
+
2. **Environment Variables** - Optional overrides for advanced users
|
|
8
|
+
3. **Hardcoded Defaults** - Sensible defaults that work for most users
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Tool Parameters (Runtime Configuration)
|
|
13
|
+
|
|
14
|
+
Claude can control browser behavior via the `browser_options` parameter in tools like `ask_question`, `setup_auth`, and `re_auth`:
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
browser_options: {
|
|
18
|
+
show: boolean, // Show browser window (overrides headless)
|
|
19
|
+
headless: boolean, // Run in headless mode (default: true)
|
|
20
|
+
timeout_ms: number, // Browser timeout in ms (default: 30000)
|
|
21
|
+
|
|
22
|
+
stealth: {
|
|
23
|
+
enabled: boolean, // Master switch (default: true)
|
|
24
|
+
random_delays: boolean, // Random delays between actions (default: true)
|
|
25
|
+
human_typing: boolean, // Human-like typing (default: true)
|
|
26
|
+
mouse_movements: boolean, // Realistic mouse movements (default: true)
|
|
27
|
+
typing_wpm_min: number, // Min typing speed (default: 160)
|
|
28
|
+
typing_wpm_max: number, // Max typing speed (default: 240)
|
|
29
|
+
delay_min_ms: number, // Min delay between actions (default: 100)
|
|
30
|
+
delay_max_ms: number, // Max delay between actions (default: 400)
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
viewport: {
|
|
34
|
+
width: number, // Viewport width (default: 1024)
|
|
35
|
+
height: number, // Viewport height (default: 768)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Example usage:**
|
|
41
|
+
- "Research this and show me the browser" → Sets `show: true`
|
|
42
|
+
- "Use slow typing for this query" → Adjusts typing WPM via stealth settings
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Environment Variables (Optional)
|
|
47
|
+
|
|
48
|
+
For advanced users who want to set global defaults:
|
|
49
|
+
- Auth
|
|
50
|
+
- `AUTO_LOGIN_ENABLED` — `true|false` (default `false`)
|
|
51
|
+
- `LOGIN_EMAIL`, `LOGIN_PASSWORD` — for auto‑login if enabled
|
|
52
|
+
- `AUTO_LOGIN_TIMEOUT_MS` (default `120000`)
|
|
53
|
+
- Stealth / Human-like behavior
|
|
54
|
+
- `STEALTH_ENABLED` — `true|false` (default `true`) — Master switch for all stealth features
|
|
55
|
+
- `STEALTH_RANDOM_DELAYS` — `true|false` (default `true`)
|
|
56
|
+
- `STEALTH_HUMAN_TYPING` — `true|false` (default `true`)
|
|
57
|
+
- `STEALTH_MOUSE_MOVEMENTS` — `true|false` (default `true`)
|
|
58
|
+
- Typing speed (human‑like)
|
|
59
|
+
- `TYPING_WPM_MIN` (default 160), `TYPING_WPM_MAX` (default 240)
|
|
60
|
+
- Delays (human‑like)
|
|
61
|
+
- `MIN_DELAY_MS` (default 100), `MAX_DELAY_MS` (default 400)
|
|
62
|
+
- Browser
|
|
63
|
+
- `HEADLESS` (default `true`), `BROWSER_TIMEOUT` (ms, default `30000`)
|
|
64
|
+
- Sessions
|
|
65
|
+
- `MAX_SESSIONS` (default 10), `SESSION_TIMEOUT` (s, default 900)
|
|
66
|
+
- Multi‑instance profile strategy
|
|
67
|
+
- `NOTEBOOK_PROFILE_STRATEGY` — `auto|single|isolated` (default `auto`)
|
|
68
|
+
- `NOTEBOOK_CLONE_PROFILE` — clone base profile into isolated dir (default `false`)
|
|
69
|
+
- Cleanup (to prevent disk bloat)
|
|
70
|
+
- `NOTEBOOK_CLEANUP_ON_STARTUP` (default `true`)
|
|
71
|
+
- `NOTEBOOK_CLEANUP_ON_SHUTDOWN` (default `true`)
|
|
72
|
+
- `NOTEBOOK_INSTANCE_TTL_HOURS` (default `72`)
|
|
73
|
+
- `NOTEBOOK_INSTANCE_MAX_COUNT` (default `20`)
|
|
74
|
+
- Library metadata (optional hints)
|
|
75
|
+
- `NOTEBOOK_DESCRIPTION`, `NOTEBOOK_TOPICS`, `NOTEBOOK_CONTENT_TYPES`, `NOTEBOOK_USE_CASES`
|
|
76
|
+
- `NOTEBOOK_URL` — optional; leave empty and manage notebooks via the library
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Storage Paths
|
|
81
|
+
|
|
82
|
+
The server uses platform-specific paths via [env-paths](https://github.com/sindresorhus/env-paths)
|
|
83
|
+
- **Linux**: `~/.local/share/notebooklm-mcp/`
|
|
84
|
+
- **macOS**: `~/Library/Application Support/notebooklm-mcp/`
|
|
85
|
+
- **Windows**: `%LOCALAPPDATA%\notebooklm-mcp\`
|
|
86
|
+
|
|
87
|
+
**What's stored:**
|
|
88
|
+
- `chrome_profile/` - Persistent Chrome browser profile with login session
|
|
89
|
+
- `browser_state/` - Browser context state and cookies
|
|
90
|
+
- `library.json` - Your notebook library with metadata
|
|
91
|
+
- `chrome_profile_instances/` - Isolated Chrome profiles for concurrent sessions
|
|
92
|
+
|
|
93
|
+
**No config.json file** - Configuration is purely via environment variables or tool parameters!
|
|
94
|
+
|
package/docs/tools.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
## Tools
|
|
2
|
+
|
|
3
|
+
### Core
|
|
4
|
+
- `ask_question`
|
|
5
|
+
- Parameters: `question` (string, required), optional `session_id`, `notebook_id`, `notebook_url`, `show_browser`.
|
|
6
|
+
- Returns NotebookLM's answer plus the follow-up reminder.
|
|
7
|
+
- `list_sessions`, `close_session`, `reset_session`
|
|
8
|
+
- Inspect or manage active browser sessions.
|
|
9
|
+
- `get_health`
|
|
10
|
+
- Summaries auth status, active sessions, and configuration.
|
|
11
|
+
- `setup_auth`
|
|
12
|
+
- Opens the persistent Chrome profile so you can log in manually.
|
|
13
|
+
- `re_auth`
|
|
14
|
+
- Switch to a different Google account or re-authenticate.
|
|
15
|
+
- Use when NotebookLM rate limit is reached (50 queries/day for free accounts).
|
|
16
|
+
- Closes all sessions, clears auth data, and opens browser for fresh login.
|
|
17
|
+
|
|
18
|
+
### Notebook library
|
|
19
|
+
- `add_notebook` – Safe conversational add; expects confirmation before writing.
|
|
20
|
+
- `list_notebooks` – Returns id, name, topics, URL, metadata for every entry.
|
|
21
|
+
- `get_notebook` – Fetch a single notebook by id.
|
|
22
|
+
- `select_notebook` – Set the active default notebook.
|
|
23
|
+
- `update_notebook` – Modify metadata fields.
|
|
24
|
+
- `remove_notebook` – Removes entries from the library (not the original NotebookLM notebook).
|
|
25
|
+
- `search_notebooks` – Simple query across name/description/topics/tags.
|
|
26
|
+
- `get_library_stats` – Aggregate statistics (total notebooks, usage counts, etc.).
|
|
27
|
+
|
|
28
|
+
### Resources
|
|
29
|
+
- `notebooklm://library`
|
|
30
|
+
- JSON representation of the full library: active notebook, stats, individual notebooks.
|
|
31
|
+
- `notebooklm://library/{id}`
|
|
32
|
+
- Fetch metadata for a specific notebook. The `{id}` completion pulls from the library automatically.
|
|
33
|
+
|
|
34
|
+
**Remember:** Every `ask_question` response ends with a reminder that nudges your agent to keep asking until the user’s task is fully addressed.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
## Troubleshooting
|
|
2
|
+
|
|
3
|
+
### Fresh start / Deep cleanup
|
|
4
|
+
If you're experiencing persistent issues, corrupted data, or want to start completely fresh:
|
|
5
|
+
|
|
6
|
+
**⚠️ CRITICAL: Close ALL Chrome/Chromium instances before cleanup!** Open browsers can prevent cleanup and cause issues.
|
|
7
|
+
|
|
8
|
+
**Recommended workflow:**
|
|
9
|
+
1. Close all Chrome/Chromium windows and instances
|
|
10
|
+
2. Ask: "Run NotebookLM cleanup and preserve my library"
|
|
11
|
+
3. Review the preview - you'll see exactly what will be deleted
|
|
12
|
+
4. Confirm deletion
|
|
13
|
+
5. Re-authenticate: "Open NotebookLM auth setup"
|
|
14
|
+
|
|
15
|
+
**What gets cleaned:**
|
|
16
|
+
- Browser data, cache, Chrome profiles
|
|
17
|
+
- Temporary files and logs
|
|
18
|
+
- Old installation data
|
|
19
|
+
- **Preserved:** Your notebook library (when using preserve option)
|
|
20
|
+
|
|
21
|
+
**Useful for:**
|
|
22
|
+
- Authentication problems
|
|
23
|
+
- Browser session conflicts
|
|
24
|
+
- Corrupted browser profiles
|
|
25
|
+
- Clean reinstalls
|
|
26
|
+
- Switching between accounts
|
|
27
|
+
|
|
28
|
+
### Browser closed / `newPage` errors
|
|
29
|
+
- Symptom: `browserContext.newPage: Target page/context/browser has been closed`.
|
|
30
|
+
- Fix: The server auto‑recovers (recreates context and page). Re‑run the tool.
|
|
31
|
+
|
|
32
|
+
### Profile lock / `ProcessSingleton` errors
|
|
33
|
+
- Cause: Another Chrome is using the base profile.
|
|
34
|
+
- Fix: `NOTEBOOK_PROFILE_STRATEGY=auto` (default) falls back to isolated per‑instance profiles; or set `isolated`.
|
|
35
|
+
|
|
36
|
+
### Authentication issues
|
|
37
|
+
**Quick fix:** Ask the agent to repair authentication; it will run `get_health` → `setup_auth` → `get_health`.
|
|
38
|
+
|
|
39
|
+
**For persistent auth failures:**
|
|
40
|
+
1. Close ALL Chrome/Chromium instances
|
|
41
|
+
2. Ask: "Run NotebookLM cleanup with library preservation"
|
|
42
|
+
3. After cleanup completes, ask: "Open NotebookLM auth setup"
|
|
43
|
+
4. This creates a completely fresh browser session while keeping your notebooks
|
|
44
|
+
|
|
45
|
+
**Auto-login (optional):**
|
|
46
|
+
- Set `AUTO_LOGIN_ENABLED=true` with `LOGIN_EMAIL`, `LOGIN_PASSWORD` environment variables
|
|
47
|
+
- For automation workflows only
|
|
48
|
+
|
|
49
|
+
### Typing speed too slow/fast
|
|
50
|
+
- Adjust `TYPING_WPM_MIN`/`MAX`; or disable stealth typing by setting `STEALTH_ENABLED=false`.
|
|
51
|
+
|
|
52
|
+
### Rate limit reached
|
|
53
|
+
- Symptom: "NotebookLM rate limit reached (50 queries/day for free accounts)".
|
|
54
|
+
- Fix: Use `re_auth` tool to switch to a different Google account, or wait until tomorrow.
|
|
55
|
+
- Upgrade: Google AI Pro/Ultra gives 5x higher limits.
|
|
56
|
+
|
|
57
|
+
### No notebooks found
|
|
58
|
+
- Ask to add the NotebookLM link you need.
|
|
59
|
+
- Ask to list the stored notebooks, then choose the one to activate.
|