OneNote MCP Server
A local MCP server that lets AI assistants read and edit OneNote pages on Windows via COM automation, without cloud authentication.
README
OneNote MCP Server
A local MCP (Model Context Protocol) server that lets Claude Desktop — or any MCP client — read and edit pages in the OneNote desktop app on Windows through OneNote's COM automation API.
No Azure app registration, no Microsoft Graph, no cloud authentication: the server talks directly to the OneNote application running on your machine.
Foreword
I'm a software developer but built this MCP server by heavily relying an AI Coding Agent since I'm not a python developer. I needed a reliable MCP server to edit and build OneNote pages and couldn't find a proper existing solution, therefore I built it myself. Other solutions seemed to focus on pulling out page content to leverage search and summarization with an LLM.
I tried to keep Token usage as low as possible and built in some bare minimum security by restricting notebook access. I still recommend using regular backups before allowing an LLM to access your Notebooks.
I hope this helps someone in a similar situation like me! Feel free to use the content of this Repo in any way you like.
Requirements
- Windows 10/11
- OneNote desktop (2013, 2016, or Microsoft 365)
- Python 3.10+
Installation
py -m venv .venv
.venv\Scripts\python.exe -m pip install -e .
Claude Desktop configuration
Add this to %APPDATA%\Claude\claude_desktop_config.json (adjust the path to
where you cloned the repo):
{
"mcpServers": {
"onenote": {
"command": "C:\\Projects\\onenote-mcp\\.venv\\Scripts\\python.exe",
"args": ["-m", "onenote_mcp.server"]
}
}
}
Alternatively, installation creates a console script, so command can simply be the absolute path to ".venv\\Scripts\\onenote-mcp.exe" inside the repo, with no args at all (relative paths won't work — Claude Desktop does not launch servers from the repo directory).
Restart Claude Desktop; the OneNote tools should appear in the tools list. OneNote desktop must be running (or startable) with at least one notebook open.
Installing as an executable
Install straight from GitHub into a fresh venv:
py -m venv %USERPROFILE%\onenote-mcp
%USERPROFILE%\onenote-mcp\Scripts\python.exe -m pip install git+https://github.com/noelroehrig/onenote-mcp
(cmd syntax — in PowerShell write $env:USERPROFILE instead of %USERPROFILE%.)
Then point Claude Desktop at the installed console script. On a machine with production onenote notebooks, restrict the server to a dedicated notebook right away:
{
"mcpServers": {
"onenote": {
"command": "C:\\Users\\<name>\\onenote-mcp\\Scripts\\onenote-mcp.exe",
"env": { "ONENOTE_ALLOWED_NOTEBOOKS": "SharedNotebook" }
}
}
}
Verify the whole chain: restart Claude Desktop and ask Claude to call the
ping tool — {"server": "ok", "onenote_responsive": true} means the server,
COM bridge, and OneNote are all talking to each other.
Note: the Microsoft Store "OneNote for Windows 10" app has no COM interface; the desktop edition (2016 or Microsoft 365) is required.
Tools
Navigation
| Tool | What it does |
|---|---|
get_notebooks |
Open notebooks with their sections (no pages) — the small navigation skeleton. |
list_pages |
The pages of one section as {id, name} pairs. |
The intended flow: get_notebooks → pick a section → list_pages(section_id) →
pick a page → read/write tools below.
Reading
| Tool | What it does |
|---|---|
get_page |
A page as structured JSON: paragraphs, headings, lists, inline and floating images. Image bytes are not included — images carry compact mcpref: handles instead. |
get_image_data |
The base64 bytes for a single image handle, fetched on demand. |
validate_handles |
Check whether image handles are still writable, without writing anything. |
Writing
| Tool | What it does |
|---|---|
create_page |
Create a page in a section; optionally as a sub-page of an existing page. Returns the new page id. |
replace_page |
Replace a page's entire content from structured JSON (outlines + floating images). |
append_page |
Append one structured content block to an existing page, preserving current content. |
Health
| Tool | What it does |
|---|---|
ping |
Fast health check: is the server alive, and is OneNote responding? Works even while another call is stuck on a wedged OneNote. |
Raw-XML escape hatches
Prefer the structured tools above; these exist for direct schema control and debugging. Token usage is significantly higher with the whole XML-overhead.
| Tool | What it does |
|---|---|
list_hierarchy_xml |
The entire notebook → section → page tree as raw OneNote XML (can be very large). |
get_page_xml |
The full <one:Page> XML of a page, with images as mcpref: handles. |
replace_page_xml |
Replace a page from a caller-supplied <one:Page> document. |
append_page_xml |
Append a single raw XML element (e.g. <one:Outline>) to a page. |
Image handles (mcpref:)
Reading a page never ships image bytes to the client. Each image is represented
by a short opaque handle such as mcpref:a1b2c3d4e5f6, together with its size and
position. This keeps reads of image-heavy pages small and fast.
- To preserve images when rewriting a page, copy the handles (or the whole
imageslist fromget_page) verbatim intoreplace_page/append_page. The server resolves handles back to real bytes just before writing to OneNote. - To inspect an image's pixels, call
get_image_datawith its handle. - Handles live for the lifetime of the server process. If a handle has gone
stale (e.g. after a restart), re-read the source page with
get_pageto mint fresh ones.
Error codes
Tool errors start with a machine-readable code so clients can react without parsing prose:
| Code | Meaning |
|---|---|
timeout |
OneNote did not respond within the per-operation deadline — it is likely showing a modal dialog or syncing. Dismiss any dialog and retry; ping tells you when it has recovered. |
backend_error |
OneNote returned a COM failure (bad id, locked content, …). |
bad_request |
The request itself was invalid (unknown image handle, malformed content, …). |
Configuration
All configuration is via environment variables (set them in the env block of
the Claude Desktop server entry if needed):
| Variable | Default | Meaning |
|---|---|---|
ONENOTE_ALLOWED_NOTEBOOKS |
(unset — no restriction) | Comma-separated notebook names, e.g. ClaudeSpike, Mathe 5a. When set, all other notebooks are invisible and untouchable: they are hidden from notebook listings and every read/write against their sections or pages is rejected. |
ONENOTE_READ_TIMEOUT |
20 |
Timeout (s) for page/hierarchy reads and image fetches |
ONENOTE_WRITE_TIMEOUT |
25 |
Timeout (s) for page creates and writes |
ONENOTE_PING_TIMEOUT |
8 |
Timeout (s) for the ping health probe |
ONENOTE_IMAGE_CACHE_MB |
200 |
In-memory cap for cached image bytes; least-recently-used entries are evicted beyond it |
Development
Source layout:
src/onenote_mcp/
server.py MCP tool definitions (FastMCP, stdio transport)
com.py COM wrapper: threading, timeouts, image-handle cache
builders.py model <-> OneNote XML conversion
models.py Pydantic models = the JSON schema of the structured tools
Run the server manually:
.venv\Scripts\python.exe -m onenote_mcp.server
Tests
Unit tests (no OneNote required):
.venv\Scripts\python.exe -m pytest tests/unit/ -q
End-to-end tests — these drive the real MCP server against the real OneNote desktop app and create pages in a test notebook. Open the ClaudeSpike notebook in OneNote first (they fall back to the first open notebook otherwise):
.venv\Scripts\python.exe -m pytest -m e2e tests/e2e/ -v
License
MIT — see LICENSE.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.