notion2prompt
A high-performance Rust CLI tool that converts Notion pages and databases into structured prompts for AI models. Transform your Notion content into perfectly formatted AI inputs with recursive fetching, parallel processing, and smart child database embedding.
Quick Demo:
notion2prompt https://notion.so/your-page→ AI-ready structured prompt in seconds
Why notion2prompt?
Tired of manually copying and formatting Notion content for AI tools? This CLI automates the entire process, preserving structure, handling complex databases, and generating prompts optimized for AI models like Claude and GPT.
Features
- ⚡ High Performance: Parallel fetching with work-stealing queues and priority-based scheduling
- 🗃️ Complete Database Support: Automatically embeds child databases within parent pages
- = Recursive Fetching: Configurable depth limits with cycle detection
- 📝 Multiple Output Formats: Markdown with customizable Handlebars templates
- 📋 Flexible Output: File, clipboard, or pipe output options
- 🔒 Type Safety: Strong typing with domain-specific newtypes
- 🚀 Smart Caching: String interning and object pooling for efficiency
- 🛡️ Robust Error Handling: Automatic retries with exponential backoff
Quick Start
1. Install
2. Get Notion API Key
- Go to https://www.notion.so/my-integrations
- Click "New integration" → Name it → Copy the token
3. Share Your Page
- Open your Notion page → Click "Share" → Invite your integration
4. Convert!
Installation
Python (via uv)
The fastest way to install — pre-compiled wheels for Linux, macOS, and Windows:
# Install as a tool (adds `notion2prompt` to your PATH)
# Or run directly without installing
Python (via pip)
Python Library Usage
# One-shot: fetch and render
=
# Two-stage: fetch first, render later with different templates
=
=
Rust (via Cargo)
# Install directly from the repository
From Source
Requires Rust (latest stable) and Cargo:
# Binary at target/release/notion2prompt
Getting Started
1. Obtain a Notion API Key
- Go to https://www.notion.so/my-integrations
- Click "New integration"
- Give it a name and select the workspace
- Copy the "Internal Integration Token" (starts with
secret_)
2. Share Pages with Your Integration
- Open the Notion page you want to convert
- Click "Share" in the top right
- Invite your integration by name
- The integration needs read access
3. Set Your API Key
4. Run notion2prompt
# Using a Notion URL
# Using just the page ID
# With options
Usage
notion2prompt [OPTIONS] <NOTION_INPUT>
Arguments:
<NOTION_INPUT> Notion page/database ID or URL
Options:
-o, --output <FILE> Output file path
-t, --template <NAME> Template name [default: claude-xml]
-b, --clipboard Copy output to clipboard
-p, --pipe Output to stdout for piping
-d, --depth <N> Max recursion depth [default: 5]
-l, --limit <N> Max items to fetch [default: 1000]
-v, --verbose Enable verbose output
--content-dir <DIR> Content directory path
--instruction <TEXT> Additional instructions
--parse-child-pages Parse child pages recursively
--separate-child-page Keep child pages separate
--always-fetch-databases Always fetch database content
-h, --help Print help
-V, --version Print version
Examples
# Convert a page and save to file
# Copy to clipboard with custom depth
# Pipe to another command
|
# Use verbose mode for debugging
# Parse child pages with custom template
Templates
Templates use Handlebars syntax and are stored in the templates/ directory. The default template is claude-xml.hbs.
Available Templates
claude-xml.hbs- Optimized for Claude AI with XML-style sectionsdefault.hbs- Simple markdown output
Template Variables
Available variables in your templates:
{{absolute_content_path}}- Full path to content{{source_tree}}- File tree representation
Note: Check template files for the complete list of available variables
Architecture
notion2prompt uses a three-stage pipeline architecture optimized for performance and reliability:
1. Fetch Stage (Async)
Parallel content retrieval with intelligent work distribution:
- Work-stealing queues with priority scheduling
- Child database fetches get critical priority
- Atomic work tracking ensures completion
- Rate limiting and automatic retries
2. Transform Stage (Sync)
Pure data transformation without side effects:
- Visitor pattern for block processing
- Embedded database formatting
- Rich text and mention handling
- Property value formatting
3. Output Stage (Async)
Template rendering and output generation:
- Handlebars template rendering
- File writing, clipboard, or pipe output
- Path validation and sandboxing
Key Features Explained
Child Database Embedding
Child databases (inline databases in Notion) are automatically detected and embedded within their parent pages, ensuring complete content capture. This critical feature uses priority scheduling to guarantee child content is fetched before worker threads terminate.
Work-Stealing Concurrency
The parallel fetcher uses work-stealing to optimize CPU utilization. Multiple workers process API requests concurrently, automatically balancing load by stealing work from busy queues.
Type Safety
Every domain concept is wrapped in a newtype for compile-time validation:
let id = parse?; // Validates format
let key = parse?; // Ensures proper prefix
Performance
Performance characteristics (typical results may vary based on network conditions and content complexity):
- Network throughput: Limited by Notion API rate limits
- CPU processing: Optimized for high-throughput data transformation
- Memory efficiency: String interning and object pooling reduce memory usage
- Concurrency: Work-stealing parallelism improves utilization over sequential processing
Configuration
Environment Variables
NOTION_API_KEY- Your Notion API key (required)RUST_LOG- Log level (debug, info, warn, error)
Default Limits
- Default recursion depth: 5 levels
- Default item limit: 1000 items
- Maximum safe recursion depth: 50 levels
Development
Building
# Debug build
# Release build with optimizations
# Run tests
# Run with logging
RUST_LOG=debug
Code Quality
# Format code
# Run linter
# Type check
Testing
# Run all tests
# Run specific test module
# Run integration tests
# Run with output
Troubleshooting
Common Issues
-
"Invalid API key"
- Ensure your key starts with
secret_ - Verify the environment variable is set:
echo $NOTION_API_KEY
- Ensure your key starts with
-
"Object not found"
- Verify the page is shared with your integration
- Check the page/database ID is correct
- Ensure your integration has read access
-
"Rate limit exceeded"
- The tool automatically retries with exponential backoff
- Try reducing parallelism if issues persist
-
Missing child databases
- Ensure depth is greater than 0
- Use
--verboseto see fetch details - Check that child databases are properly linked in Notion
Debug Mode
# Enable debug logging
RUST_LOG=debug
# For development debugging, logs may be written to temporary files
# Check your system's temp directory if debug logging is enabled
Architecture Details
See ARCHITECTURE.md for detailed architecture documentation.
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Run tests (
cargo test) - Format code (
cargo fmt) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
This project is built on the shoulders of excellent open-source libraries. Thanks to all their maintainers and contributors:
Core Runtime & Networking
- tokio by the Tokio team — async runtime powering all concurrent operations
- reqwest by Sean McArthur (@seanmonstar) — ergonomic HTTP client
- hyper by Sean McArthur — the HTTP implementation beneath reqwest
Concurrency & Data Structures
- crossbeam by the Crossbeam team — work-stealing queues and concurrent primitives
- rayon by Niko Matsakis & Josh Stone — parallel iterators
- dashmap by Acrimon (@xacrimon) — concurrent hash map
- parking_lot by Amanieu d'Antras — fast mutex and RwLock
- im by Bodil Stokke (@bodil) — immutable data structures
Serialization & Templating
- serde by David Tolnay (@dtolnay) & Erick Tryzelaar — serialization framework
- serde_json by David Tolnay — JSON support
- handlebars-rust by Ning Sun (@sunng87) — template engine
CLI & Error Handling
- clap by the clap contributors — command-line argument parsing
- thiserror by David Tolnay — derive macro for error types
- anyhow by David Tolnay — flexible error handling
Notion API
- notion-client by jhamill34 — Notion API client for Rust
Python Bindings
- PyO3 by the PyO3 team — Rust ↔ Python FFI bindings
- maturin by the PyO3 team — build system for Rust Python extensions
- pyo3-async-runtimes — async/await bridge between Rust and Python
Utilities
- chrono by the Chronotope team — date and time handling
- regex by Andrew Gallant (@BurntSushi) — regular expressions
- indexmap by the indexmap contributors — insertion-ordered map
- lru by Jerome Froelich — LRU cache for API response caching
- arboard by 1Password — cross-platform clipboard access
- uuid by the uuid contributors — UUID generation and parsing
- url by the Servo project — URL parsing and validation