Skip to main content
Glama
README.md
# NotebookLM MCP Server

MCP server for NotebookLM with hybrid metadata enforcement (API-native fields + Google Docs custom properties + local JSON storage).

## Features

- ✅ **Metadata Operations**: Validate, get, set, and query custom metadata
- ✅ **Notebook Operations**: List, get, create, delete, and share notebooks (via NotebookLM API)
- ✅ **Source Operations**: Add, get, and remove sources (Google Docs, PDFs, URLs, etc.)
- ✅ **Audio Overviews**: Generate and delete audio overviews
- ✅ **Hybrid Storage**: Three-layer metadata storage (API fields, Google Docs, local JSON)
- ✅ **OAuth2 Authentication**: Secure authentication with auto-refresh
- ✅ **Caching**: 30-second TTL for optimal performance
- ✅ **TDD**: 89+ tests with comprehensive coverage

## Architecture

```
MCP Server
    ↓
Metadata Manager (Orchestrator)
    ↓ ↓ ↓
[NotebookLM API] [Google Docs API] [Local JSON Store]
```

## Prerequisites

- Node.js 18+
- Google Cloud Project with:
  - NotebookLM Enterprise API enabled
  - Google Docs API enabled
  - Google Drive API enabled
- OAuth2 credentials (client ID and secret)

## Installation

```bash
# Clone or copy to your machine
cd /path/to/notebooklm-mcp

# Install dependencies
npm install

# Build
npm run build
```

## Configuration

### 1. Set up OAuth2 Credentials

Set environment variables:

```bash
export GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
export GOOGLE_CLIENT_SECRET="your-client-secret"
```

Or create `.env` file:

```
GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secret
```

### 2. Authenticate (First Time)

Run the setup flow:

```bash
npm run setup  # TODO: Implement OAuth web flow in future
```

This will:

1. Open your browser to Google OAuth consent screen
2. Request permissions for NotebookLM, Google Docs, and Drive
3. Save credentials to `~/.notebooklm-mcp/credentials.json`

## Manual Testing

**Before using the MCP server in production**, we recommend following the manual testing guide to verify everything works correctly.

👉 **[Complete Manual Testing Guide](docs/MANUAL_TESTING_GUIDE.md)**

The guide walks you through:
- **Phase 1:** No-auth metadata validation (5-10 min)
- **Phase 2:** OAuth setup and Claude Code integration (10-15 min)
- **Phase 3:** End-to-end workflow testing (15-20 min)

**Quick test** (after installation):

```bash
# Build the server
npm run build

# Run automated tests
npm test

# Expected: 89 tests passing (10 test suites)
```

For detailed testing including OAuth and Claude Code integration, see the [Manual Testing Guide](docs/MANUAL_TESTING_GUIDE.md).

## Usage

### Start MCP Server

```bash
npm start
```

The server runs on stdio and can be used with Claude Code.

### Configure in Claude Code

Add to your Claude Code MCP configuration:

**Desktop:** `~/.claude/desktop-config.json`

```json
{
  "mcpServers": {
    "notebooklm": {
      "command": "/path/to/notebooklm-mcp/bin/notebooklm-mcp",
      "env": {
        "GOOGLE_CLIENT_ID": "your-client-id",
        "GOOGLE_CLIENT_SECRET": "your-client-secret"
      }
    }
  }
}
```

## Available MCP Tools

### Metadata Operations

- `notebooklm_validate_metadata` - Validate metadata against schema
- `notebooklm_get_metadata` - Get metadata for notebook/source
- `notebooklm_set_metadata` - Set metadata
- `notebooklm_query_metadata` - Query by metadata filter

### Notebook Operations

- `notebooklm_list_notebooks` - List recently viewed notebooks
- `notebooklm_get_notebook` - Get notebook details with sources
- `notebooklm_create_notebook` - Create new notebook
- `notebooklm_delete_notebook` - Delete notebook(s)
- `notebooklm_share_notebook` - Share notebook with user

### Source Operations

- `notebooklm_add_sources` - Add sources to notebook
- `notebooklm_get_source` - Get source details
- `notebooklm_remove_sources` - Remove sources

### Audio Overview Operations

- `notebooklm_generate_audio` - Generate audio overview
- `notebooklm_delete_audio` - Delete audio overview

## Metadata Schema (v1.0)

### Required Fields

```typescript
{
  type: "notebook-source"  // Fixed value
  project: string          // Project name
  status: "active" | "archived" | "reference" | "in-progress"
}
```

### Optional Fields

```typescript
{
  area?: string           // PARA area (e.g., "vocation/spreetail")
  tags?: string[]         // Custom tags
  created?: string        // ISO date (YYYY-MM-DD)
  modified?: string       // ISO date (YYYY-MM-DD)
  customFields?: object   // Extensible custom metadata
}
```

### Example

```json
{
  "type": "notebook-source",
  "project": "palomino-nas",
  "status": "active",
  "area": "vocation/spreetail",
  "tags": ["infrastructure", "backup"],
  "created": "2026-02-17",
  "modified": "2026-02-17",
  "customFields": {
    "priority": "high",
    "owner": "brockbutler"
  }
}
```

## Development

### Run Tests

```bash
make test
# or
npm test
```

### Watch Mode (TDD)

```bash
make test-watch
# or
npm run test:watch
```

### Coverage Report

```bash
make test-coverage
```

### Build

```bash
make build
# or
npm run build
```

## Project Structure

```
/Users/brockstudio/Projects/notebooklm-mcp/
├── src/
│   ├── index.ts                    # Entry point
│   ├── server.ts                   # MCP server with 14 tools
│   ├── config.ts                   # Configuration
│   ├── validators/
│   │   └── schema.ts               # Metadata validation
│   ├── storage/
│   │   └── metadata-store.ts       # Local JSON store
│   ├── cache/
│   │   └── manager.ts              # TTL cache
│   ├── auth/
│   │   └── oauth.ts                # OAuth2 manager
│   ├── clients/
│   │   ├── notebooklm.ts          # NotebookLM API client
│   │   └── google-docs.ts         # Google Docs API client
│   └── managers/
│       └── metadata.ts             # Metadata orchestrator
├── tests/
│   ├── unit/                       # Unit tests
│   ├── integration/                # Integration tests
│   └── setup.ts                    # Test setup
├── bin/
│   └── notebooklm-mcp              # Executable wrapper
├── dist/                           # Compiled JavaScript
├── package.json
├── tsconfig.json
├── jest.config.js
├── Makefile
└── README.md
```

## Runtime Files

```
~/.notebooklm-mcp/
├── credentials.json                # OAuth tokens (chmod 600)
├── metadata.json                   # Local metadata store
└── metadata.json.backup            # Backup (on corruption)
```

## Implementation Status

### ✅ Completed (Tasks 1-14)

- Project scaffold and configuration
- Metadata validator with schema enforcement
- Local JSON store with atomic writes
- Cache manager with TTL
- OAuth2 credentials storage and token refresh
- Google Docs API client (stub)
- NotebookLM API client (stub)
- Metadata manager orchestration layer
- MCP server with 14 tools
- Comprehensive testing (89+ tests)
- Integration and end-to-end tests

### 🔲 Future Enhancements (Post-MVP)

- OAuth2 web flow setup wizard
- Real Google Docs API integration
- Real NotebookLM API integration
- Advanced querying (full-text search)
- Multi-device metadata sync
- Cloud backup for metadata

## Troubleshooting

### "No credentials found"

Run the setup flow to authenticate with Google:

```bash
npm run setup  # TODO: Implement OAuth web flow
```

### "Token refresh failed"

Your refresh token may have expired. Re-run setup:

```bash
rm ~/.notebooklm-mcp/credentials.json
npm run setup
```

### "NotebookLM API not yet implemented"

The NotebookLM API operations are currently stubs. They will be implemented in a future phase with real API integration.

## Contributing

This project follows TDD principles. All new features require tests.

## License

MIT

## Design Documents

- **Architecture**: `/Users/brockstudio/Projects/palomino-nas/docs/plans/2026-02-16-notebooklm-api-redesign.md`
- **Implementation Plan**: `/Users/brockstudio/Projects/palomino-nas/docs/plans/2026-02-16-notebooklm-api-implementation.md`

TDQS

A3.5/5.0

Scored across 14 tools

Disambiguation5/5

Each tool targets a distinct resource-action combination: metadata operations are clearly separated into validate/get/set/query, notebook operations into list/get/create/delete/share, and sources/audio each have their own dedicated tools. Even get_notebook and get_source are unambiguous because one returns notebook details with sources and the other returns a specific source's details.

Naming Consistency5/5

All tools follow a consistent snake_case verb_noun pattern with the notebooklm_ prefix. Action verbs such as get, set, list, create, delete, add, remove, generate, and share are used predictably across the tool set.

Tool Count5/5

14 tools is well within the ideal range for a domain-specific MCP server. The count covers notebooks, sources, metadata, sharing, and audio without feeling bloated or thin.

Completeness4/5

The tool surface provides strong lifecycle coverage for notebooks, sources, metadata, and audio overviews. Minor gaps exist such as no explicit notebook update/rename operation, no standalone list-sources tool, and no unshare or list-audio tools, but these are workable gaps rather than critical dead ends.

Maintenance

ActivityInactive
ResponsivenessNo issues