Skip to main content

Export OneNote notebooks to Obsidian-compatible Markdown via Microsoft Graph API

Project description

OneNote → Obsidian Exporter

Tests Lint Python 3.10+ MIT License PyPI Version Downloads GitHub Release Docs

Export your Microsoft OneNote notebooks to Obsidian-compatible Markdown files via Microsoft Graph API.

Why This Tool?

  • Zero setup — no Azure AD app registration needed, works out of the box
  • Full fidelity — images, file attachments, checkboxes, tables, embedded content
  • Smart resume — re-running skips unchanged pages, exports only what's new
  • Preserves structure — Notebook / Section / Section Group hierarchy mapped to folders
  • Open source — MIT licensed, community-driven, 98% test coverage

Features

  • No Azure AD registration required — uses a public Microsoft client ID out of the box
  • Full notebook export — text, images, file attachments, checkboxes, embedded content
  • Preserves structure — Notebook / Section / Page hierarchy mapped to folders
  • Resume support — re-running skips unchanged pages (tracks by modification time)
  • Recursive section groups — nested section groups are fully supported
  • YAML frontmatter — each page includes created, modified, source, onenote_id

Requirements

  • Python 3.10+
  • A personal Microsoft account with OneNote data

Installation

From PyPI (recommended)

pip install onenote-to-obsidian

From source

git clone https://github.com/Lenivvenil/onenote-to-obsidian.git
cd onenote-to-obsidian
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e .

Docker

docker run -it --rm \
  -v ~/.onenote_exporter:/home/appuser/.onenote_exporter \
  -v ~/ObsidianVault:/home/appuser/ObsidianVault \
  ghcr.io/lenivvenil/onenote-to-obsidian

Quick Start

# Export all notebooks (first run creates config automatically)
onenote-to-obsidian

# Or run as a module
python -m onenote_to_obsidian

# List your notebooks
onenote-to-obsidian --list

# Export a specific notebook
onenote-to-obsidian --notebook "My Notebook"

# Export to a custom vault path
onenote-to-obsidian --vault /path/to/obsidian/vault

On the first run, you'll see a device code prompt:

===========================================================
  To authorize:
  1. Open: https://microsoft.com/devicelogin
  2. Enter code: XXXXXXXXX
===========================================================

Open the link in your browser, enter the code, and sign in with your Microsoft account.

CLI Options

Option Description
--vault PATH Path to Obsidian vault (default: ~/ObsidianVault)
--notebook NAME Export only the specified notebook
--list List available notebooks and exit
--reset-state Force re-export of all pages
--setup Configure a custom client ID
-v, --verbose Enable debug logging

Output Structure

vault/
├── Notebook Name/
│   ├── Section Name/
│   │   ├── attachments/
│   │   │   ├── 0-resourceid.png
│   │   │   └── document.pdf
│   │   ├── Page Title.md
│   │   └── Another Page.md
│   └── Section Group/
│       └── Nested Section/
│           └── ...
└── Another Notebook/
    └── ...

Each .md file includes YAML frontmatter:

---
created: "2023-01-15T10:30:00Z"
modified: "2024-06-20T14:22:00Z"
source: onenote
onenote_id: "page-guid"
---

What Gets Converted

OneNote element Markdown result
Images ![alt](attachments/id.png)
File attachments [file.pdf](attachments/file.pdf)
Checkboxes (unchecked) - [ ] text
Checkboxes (checked) - [x] text
Embedded content (iframes) [Embedded content](url)
Headers, bold, italic, tables, links Standard Markdown
Absolute positioning CSS Removed

Authentication

The tool uses OAuth2 device code flow. No app registration is needed — it ships with the public Microsoft Office client ID.

Token storage: OAuth tokens are cached in ~/.onenote_exporter/token_cache.json (permissions: owner-only, chmod 600). Re-authentication is only needed when refresh tokens expire.

Custom client ID: If the default client ID doesn't work for your account type, run --setup and provide your own (see Azure AD app registration guide).

Configuration

All configuration is stored in ~/.onenote_exporter/:

File Purpose
config.json Client ID, vault path, OAuth scopes
token_cache.json Cached OAuth2 tokens (chmod 600)
export_state.json Which pages have been exported

Troubleshooting

"Invalid client_id" error

Try the fallback client ID:

onenote-to-obsidian --setup
# Enter: 1fec8e78-bce4-4aaf-ab1b-5451cc387264

Pages not exporting

  1. Verify you're signed in: onenote-to-obsidian --list
  2. Check logs: onenote-to-obsidian --verbose
  3. Reset state: onenote-to-obsidian --reset-state

"Account not supported" error

Your Microsoft account type may not be compatible with the default client ID. Run --setup and try the fallback, or register your own app in Azure AD.

FAQ

Does this work with work/school Microsoft accounts?

It works with personal Microsoft accounts out of the box. Work/school accounts may require a custom client ID — run --setup and register your own app in Azure AD.

Can I re-export without re-downloading everything?

Yes. The tool tracks exported pages by ID and modification time. Re-running exports only new or changed pages. Use --reset-state to force a full re-export.

What happens if the export crashes mid-way?

Progress is saved in ~/.onenote_exporter/export_state.json. Re-running picks up where it left off. File deduplication also survives crashes.

Is my data sent anywhere besides Microsoft?

No. The tool only communicates with Microsoft Graph API and writes to your local filesystem. OAuth tokens are cached locally with owner-only permissions.

How do I use a different Obsidian vault location?

onenote-to-obsidian --vault /path/to/your/vault

The default location is ~/ObsidianVault.

Comparison with Alternatives

Feature onenote-to-obsidian Manual copy-paste OneNote export (OOXML)
No registration needed Yes N/A N/A
Images & attachments Yes Manual Partial
Resume / incremental Yes No No
Checkboxes Yes No No
Section groups Yes N/A Yes
YAML frontmatter Yes No No
Automation-friendly Yes No Partial

Development

# Install with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run tests with coverage
pytest --cov=onenote_to_obsidian

# Lint and format
ruff check onenote_to_obsidian/
ruff format onenote_to_obsidian/

See CONTRIBUTING.md for full contributor guidelines.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

onenote_to_obsidian-1.1.0.tar.gz (56.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

onenote_to_obsidian-1.1.0-py3-none-any.whl (23.1 kB view details)

Uploaded Python 3

File details

Details for the file onenote_to_obsidian-1.1.0.tar.gz.

File metadata

  • Download URL: onenote_to_obsidian-1.1.0.tar.gz
  • Upload date:
  • Size: 56.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for onenote_to_obsidian-1.1.0.tar.gz
Algorithm Hash digest
SHA256 56b6428bb17a47525962d050c3f5f48ab70ddd48ad74b950585e6d4543a45da2
MD5 03b0e1051757fa5bc133ee71902f716e
BLAKE2b-256 9186b7d773c3d015a0db7f0233946554a405be1686b651affbd71ffe69129fef

See more details on using hashes here.

Provenance

The following attestation bundles were made for onenote_to_obsidian-1.1.0.tar.gz:

Publisher: publish.yml on Lenivvenil/onenote-to-obsidian

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file onenote_to_obsidian-1.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for onenote_to_obsidian-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e87a797033c22d863acf4a0d00c1a5745acc992ec68f9bd4d499ad652d8c8006
MD5 f96aaa9a4a67d5c125ccf7535fe62b2d
BLAKE2b-256 420a6257cf23f4b578c77284cc659ac82baf3e1fa1ddba3ed1d4d7d5008bf2cb

See more details on using hashes here.

Provenance

The following attestation bundles were made for onenote_to_obsidian-1.1.0-py3-none-any.whl:

Publisher: publish.yml on Lenivvenil/onenote-to-obsidian

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page