Local OneNote MCP
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Local OneNote MCPlist all notebooks"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Local OneNote MCP
A pure-local Microsoft OneNote MCP server for Windows. It controls the OneNote desktop app through the local OneNote COM API, so it does not need Azure, Microsoft Graph, API keys, or OAuth.
Design
Local only: every operation happens through the installed OneNote desktop app.
COM-first: no direct binary
.oneediting.Safe bridge: user input is passed through JSON temp files, never interpolated into PowerShell script text.
Rich surface: hierarchy, page XML/text, search, create, update, export, navigation, sync, and advanced raw XML tools.
PowerShell is used only as a fixed COM bridge because some Windows/Office installations expose OneNote COM to PowerShell while leaving the COM type library unavailable to Python automation libraries.
Related MCP server: OneNote MCP Server
Requirements
Windows
Microsoft OneNote desktop app
Python 3.11+
Node.js/npm for the recommended
npxsetupOptional: OneMore, for Markdown-to-HTML conversion through its bundled Markdig parser
Check the required commands:
node -v
npm -v
python --version
# or: py -3 --versionQuick Start
Add this server to your MCP client config:
Codex
[mcp_servers.local-onenote]
type = "stdio"
command = "npx"
args = ["-y", "github:Peteroooooooo/local-onenote-mcp"]
startup_timeout_ms = 120000
[mcp_servers.local-onenote.env]
LOCAL_ONENOTE_MCP_TIMEOUT = "90"
LOCAL_ONENOTE_MCP_MAX_TEXT_CHARS = "60000"Claude Desktop-style JSON
{
"mcpServers": {
"local-onenote": {
"command": "npx",
"args": [
"-y",
"github:Peteroooooooo/local-onenote-mcp"
],
"env": {
"LOCAL_ONENOTE_MCP_TIMEOUT": "90",
"LOCAL_ONENOTE_MCP_MAX_TEXT_CHARS": "60000"
}
}
}
}Restart the MCP client after changing the config. On first run, npx downloads
this package from GitHub, creates a cached Python virtual environment, installs
the bundled Python MCP server into that cache, and starts the stdio server.
Later runs reuse the cache.
Test it by asking your MCP client to run local-onenote health_check.
After the package is published to the npm registry, replace the GitHub argument with the shorter package name:
args = ["-y", "local-onenote-mcp"]Install Options
Option 1: run with npx
This is the recommended setup for most users. Use the Quick Start config above.
Set LOCAL_ONENOTE_MCP_PYTHON if Python is not on PATH:
[mcp_servers.local-onenote.env]
LOCAL_ONENOTE_MCP_PYTHON = "C:\\path\\to\\python.exe"
LOCAL_ONENOTE_MCP_TIMEOUT = "90"
LOCAL_ONENOTE_MCP_MAX_TEXT_CHARS = "60000"Option 2: run directly from GitHub with uvx
This does not require cloning the repository.
[mcp_servers.local-onenote]
type = "stdio"
command = "uvx"
args = [
"--from",
"git+https://github.com/Peteroooooooo/local-onenote-mcp",
"local-onenote-mcp"
]
startup_timeout_ms = 120000
[mcp_servers.local-onenote.env]
LOCAL_ONENOTE_MCP_TIMEOUT = "90"
LOCAL_ONENOTE_MCP_MAX_TEXT_CHARS = "60000"Option 3: install once with pipx
pipx install git+https://github.com/Peteroooooooo/local-onenote-mcpThen configure your MCP client to run the installed console script:
[mcp_servers.local-onenote]
type = "stdio"
command = "local-onenote-mcp"
startup_timeout_ms = 120000
[mcp_servers.local-onenote.env]
LOCAL_ONENOTE_MCP_TIMEOUT = "90"
LOCAL_ONENOTE_MCP_MAX_TEXT_CHARS = "60000"If Windows cannot find local-onenote-mcp, run pipx ensurepath, restart the
terminal/MCP client, or use the full path printed by pipx list.
Option 4: clone for development
git clone https://github.com/Peteroooooooo/local-onenote-mcp
cd local-onenote-mcp
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e .Codex MCP Config
MCP stdio servers are launched as local processes. This project is implemented
in Python and also ships an npm launcher, so the client can launch it with
npx, uvx, pipx, or a Python executable/console script from an environment
where the package is installed.
For a development checkout, either run the console script:
[mcp_servers.local-onenote]
type = "stdio"
command = "C:\\path\\to\\local-onenote-mcp\\.venv\\Scripts\\local-onenote-mcp.exe"
startup_timeout_ms = 120000or run the module with that environment's Python:
{
"mcpServers": {
"local-onenote": {
"command": "C:\\path\\to\\local-onenote-mcp\\.venv\\Scripts\\python.exe",
"args": [
"-m",
"local_onenote_mcp.server"
],
"env": {
"LOCAL_ONENOTE_MCP_TIMEOUT": "90",
"LOCAL_ONENOTE_MCP_MAX_TEXT_CHARS": "60000"
}
}
}
}Other MCP servers may appear not to need Python because they are launched via
npx, uvx, Docker, or a packaged executable. The requirement is the same:
the MCP client needs a command it can execute.
Restart the MCP client after changing its config. Make sure command points to
an executable available to the MCP client process. If the path is stale, the MCP
client will not expose the local-onenote tools.
Validate the Codex config from this checkout:
.\.venv\Scripts\python.exe scripts\check_codex_config.pyThe check fails if Codex points at a missing Python executable or imports
local_onenote_mcp from a different checkout.
If OneMore is installed, the server can use OneMore's bundled Markdig parser
for Markdown writes. The default path is detected from the OneMore registry
entry. Override it with LOCAL_ONENOTE_MARKDIG_DLL when needed.
Tools
Read and discovery:
health_checkresolve_identifierget_special_locationslist_hierarchylist_notebookslist_sectionslist_pagesget_pageget_page_xmlget_page_textget_page_objectsget_binary_contentsearch_pagesfind_metaget_hyperlinkget_parent
Hierarchy/list tools hide OneNote recycle-bin items by default. Pass
include_recycle_bin=true when you need to inspect deleted pages or sections.
Identifiers accepted by tools are resolved in this order:
exact OneNote object ID
exact hierarchy path, for example
Notebook/Section Group/Sectionunique display name
For automation, prefer IDs or exact paths from list_hierarchy,
list_sections, or list_pages. Display names can be ambiguous.
Call resolve_identifier before write or delete operations when you want to
verify that an ID, path, or name resolves to exactly one live object.
health_check returns the Python executable, module path, process directory,
identifier resolution order, and default search backend. Use it first when
debugging MCP startup or duplicate checkout issues.
health_check also reports supported content formats. The current write
formats are plain, html, and markdown.
Create and update:
open_hierarchycreate_notebookcreate_sectioncreate_section_groupcreate_pageupdate_page_titleappend_to_pageadd_image_to_pagereplace_page_bodydelete_page_contentdelete_hierarchyupdate_page_xmlupdate_hierarchy_xml
File/export/app control:
publish_objectnavigate_tonavigate_to_urlsync_hierarchyclose_notebookmerge_sectionsset_filing_location
search_pages uses a live local text scan when include_unindexed=true, which
is the default. This finds freshly-created pages without waiting for OneNote's
desktop search index. Pass include_unindexed=false when you specifically want
to use the OneNote index.
get_page_objects marks objects with delete_supported and, for child objects
such as table cells or paragraph OEs, returns delete_object_id when the parent
outline is the deletable OneNote COM object. Use that parent ID with
delete_page_content.
Smoke Test
Run a read-only MCP startup and discovery check:
.\.venv\Scripts\python.exe scripts\smoke_mcp.pyRun a write/read/search smoke test against a chosen section:
.\.venv\Scripts\python.exe scripts\smoke_mcp.py --notebook "Notebook" --section "Notebook/Section" --export-dir tmpThe script talks to the server through stdio MCP, so it verifies the same path used by MCP clients instead of importing server functions directly.
Examples
List all open notebooks:
Use local-onenote health_check, then list_notebooks.Create a page:
Create a page in section "Notebook/Projects/Report" titled "Today's Notes"
with this plain-text body: ...Export a page to PDF:
Publish page "Notebook/Projects/Report/Today's Notes" to
"C:\path\to\exports\today.pdf" as pdf.Use absolute export paths in automation. publish_object normalizes relative
paths against the server process directory, but absolute paths make the output
location unambiguous.
Replace a page body:
Use replace_page_body.Add an image:
Use add_image_to_page with image_path. Width and height are optional.
If only one dimension is provided, the server infers the other dimension from
the image's native aspect ratio for PNG, JPEG, GIF, and BMP files.Import Markdown notes:
Use create_page or replace_page_body with content_format="markdown".
The server converts Markdown to HTML through OneMore's Markdig parser, then
emits native OneNote tables where possible.Example Markdown body:
# 入学待办
Unique token: example
- 上传照片
- 确认住宿
| 事项 | 状态 |
| --- | --- |
| 体检预约 | **进行中** |
| 学费支付 | 待确认 |Limits
This server is intentionally local and depends on the OneNote desktop COM API. It can be stronger than Graph for offline/local notebooks, but Graph still has a more formal cloud permission model and better multi-user sync semantics.
The server does not directly edit .one binary files. That is deliberate:
OneNote's COM API is the stable local write surface.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Peteroooooooo/local-onenote-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server