Skip to content

jasonLaster/notion-cli

Repository files navigation

Notion Upload CLI Wrapper

A simple wrapper around the md-to-notion tool that provides a cleaner API for uploading markdown files to Notion.

Installation

Option 1: Install as Binary (Recommended)

Run the installation script to add notion to your PATH:

./install.sh

This will:

  • Create a symlink in ~/.local/bin/notion
  • Add ~/.local/bin to your PATH (if not already there)
  • Allow you to use notion from anywhere

After installation, you can use:

notion <page-id> ./docs
notion <page-id> ./document.md
notion <page-id> ./docs --dry-run
notion --help

Option 2: Manual Installation

pnpm add @vrerv/md-to-notion
pnpm add -D typescript @types/node

Usage

Single File Upload

# If installed as binary
notion <page-id> <path-to-md-file>

# Or using bun directly
bun run notion-upload.ts <page-id> <path-to-md-file>

Example:

notion 242a334e22908019a500f348e03a4a31 ./document.md

Directory Upload

# If installed as binary
notion <page-id> <path-to-directory>

# Or using bun directly
bun run notion-upload.ts <page-id> <path-to-directory>

Example:

notion 242a334e22908019a500f348e03a4a31 ./docs

This will upload all .md files in the directory (including subdirectories).

Folder Hierarchy Support

The CLI automatically creates folder hierarchy in Notion using relative paths only. For example, if you upload tests/fixtures/project/docs/README.md:

  1. Creates a page called "tests" under your target page
  2. Creates a page called "fixtures" under the "tests" page
  3. Creates a page called "project" under the "fixtures" page
  4. Creates a page called "docs" under the "project" page
  5. Uploads the content to the "docs" page

Smart Page Reuse: The CLI checks if folder pages already exist and reuses them, preventing duplicate pages.

Relative Paths Only: The folder hierarchy is created based on the relative path from your current working directory, not the full absolute path.

This maintains your folder structure in Notion:

Your Target Page
├── tests/
│   └── fixtures/
│       └── project/
│           ├── docs/
│           │   ├── README.md
│           │   └── api.md
│           └── overview.md

Glob Pattern Upload

Upload files matching a pattern:

# Upload all markdown files in current directory
notion <page-id> "./*.md"

# Upload all markdown files recursively
notion <page-id> "./**/*.md"

# Upload files matching a specific pattern
notion <page-id> "./mattermost-tasks*.md"

# Upload files in a specific directory
notion <page-id> "./docs/*.md"

Examples:

notion 242a334e22908019a500f348e03a4a31 "./*.md"
notion 242a334e22908019a500f348e03a4a31 "./mattermost-tasks*.md"
notion 242a334e22908019a500f348e03a4a31 "./**/*.md"

Important: Always quote glob patterns to prevent shell expansion:

  • notion <page-id> "*.md" - Correct (script handles glob)
  • notion <page-id> *.md - Shell expands first (may only pass one file)

Dry Run

Test what would be uploaded without actually uploading:

notion <page-id> <path-to-md-files> --dry-run

Replace Existing Pages

Replace existing pages instead of creating new ones:

notion <page-id> <path-to-md-files> --replace

Help

Show help information:

notion --help

Features

  • Single File Upload: Upload individual markdown files
  • Directory Upload: Upload all markdown files in a directory
  • Glob Pattern Upload: Upload files matching patterns like *.md, mattermost-tasks*.md
  • Folder Hierarchy: Automatically creates folder structure in Notion
  • Recursive Search: Finds markdown files in subdirectories
  • Smart Filtering: Excludes node_modules, .git, and other common directories
  • Dry Run Mode: Preview what would be uploaded without actually uploading
  • Replace Mode: Replace existing pages instead of creating new ones
  • Page ID Validation: Validates Notion page ID format
  • Clean Output: Only shows upload status, not verbose md-to-notion output
  • Error Handling: Clear error messages for failed uploads
  • Summary: Shows total uploaded/failed count
  • TypeScript Support: Full TypeScript support with proper types
  • Binary Installation: Install as notion command for global use

Output

Found 2 markdown file(s) to upload

Uploading: test-docs/page2.md
✅ test-docs/page2.md
Uploading: test-docs/page1.md
✅ test-docs/page1.md

📊 Summary: 2 uploaded, 0 failed

Configuration

The wrapper uses the NOTION_TOKEN environment variable from your shell. Make sure it's set in your .zshrc:

export NOTION_TOKEN="your-notion-token-here"

Or export it for the current session:

export NOTION_TOKEN="your-notion-token-here"

Development

Available Scripts

# Run the upload script
pnpm run upload <page-id> <path>

# Run in development mode with file watching
pnpm run dev

# Type check the TypeScript code
pnpm run type-check

# Run tests (file discovery and validation)
pnpm run test

# Build the binary
pnpm run build

Testing

The project includes a test suite that validates:

  • File discovery functionality
  • Directory traversal
  • Markdown file detection
  • Specific file existence checks

Run tests with:

pnpm run test

Requirements

  • Node.js with Bun
  • @vrerv/md-to-notion package installed
  • Valid Notion page ID (32 characters)
  • Valid Notion token

Troubleshooting

Invalid Page ID Error

If you get an "Invalid page ID format" error, make sure your page ID is:

  • 32 characters long
  • Contains only letters and numbers
  • Example: 242a334e22908019a500f348e03a4a31

No Files Found

If no markdown files are found:

  • Check that the path exists
  • Ensure files have .md extension
  • Verify the directory contains markdown files

Token Issues

If you get a token error:

  • Set the NOTION_TOKEN environment variable
  • Ensure the token has write permissions to the target page
  • Check that the page ID is correct

Binary Not Found

If the notion command is not found:

  1. Make sure you ran ./install.sh
  2. Restart your terminal or run source ~/.zshrc
  3. Check that ~/.local/bin is in your PATH: echo $PATH | grep local

Uninstallation

To remove the binary:

./uninstall.sh

About

Upload MD docs to notion

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published