A native LM Studio plugin for reading and managing local Microsoft OneNote. It talks to
the OneNote desktop app directly through the OneNote COM API (via a fixed PowerShell
bridge) — there is no MCP server and no Python involved. Large reads are returned in
model-controlled pages so nothing gets silently truncated.
Credits
This plugin is a native reimplementation based on the excellent
local-onenote-mcp by
Peteroooooooo. All of the OneNote COM techniques —
the PowerShell COM bridge, the hierarchy/XML handling, and the content pipeline — come
from that project. Full credit and thanks to Peteroooooooo for the original work.
Additional functionality exists beyond what was available originally in
local-onenote-mcp.
This LM Studio plugin was created by Morxeton in collaboration with Claude Opus 4.8, and
continued development is done by Morxeton in collaboration with Qwen 3.6
via the LM Studio Code
Visual Studio Code extension.
How it works
Every tool drives OneNote through a small, fixed PowerShell program that uses the
OneNote.Application COM object. User data is passed only via JSON temp files (no string
interpolation), and the COM object is released after each call.
No background server, no MCP transport, no Python runtime. The only external requirement
beyond OneNote is Windows PowerShell (always present on Windows).
Requirements
Windows 10 / 11 with the Microsoft OneNote desktop app (the traditional Office
app, not the Store/UWP "OneNote for Windows 10").
LM Studio with the lms CLI available ( once if it isn't on PATH).
If you'd like to work on the development of this plugin for yourself or to contribute, execute these commands in the folder where you saved the source files (onenote-manager):
Run non-elevated. Launch LM Studio (and lms dev, if you use it) without
administrator rights, at the same privilege level as OneNote. A privilege mismatch makes
the OneNote COM object fail to start (0x80080005).
Then, in a chat, enable the onenote-manager plugin and ask it to work with OneNote.
Tools
All tools list alphabetically in LM Studio. Reads marked (paged) accept
offset/max_chars (text/XML) or offset/limit (lists).
Tool
Purpose
add_content_to_page_outline
Add content (plain/html/markdown) to an existing outline
add_image_to_page
Add a local image to a page (native size inferred)
add_outline_to_page
Add a new outline block to a page (plain/html/markdown)
add_todo_items_to_page_outline
Add one or more To Do items to an outline (plain/html/markdown text, auto TagDef, per-item indentation)
close_notebook
Close a notebook
create_notebook
Create and open a local notebook
create_page
Create a page (plain / html / markdown)
create_section
Create a section
create_section_group
Create a section group
delete_hierarchy
Delete a notebook / group / section / page (destructive)
delete_page_content
Delete one content object by id (destructive)
delete_row_from_table
Delete a table row by index or by first-column text
duplicate_page
Duplicate a page (template → new page); optional target section + title
duplicate_page_outline
Duplicate an Outline (by id/index) to the far bottom or right
Write, structural, and app-control tools can create, modify, delete, and export your
OneNote content. Enable the plugin only in chats where you want the model to have that access.
Highlighted commands
Tables
Every table tool identifies a table the same way: by its objectID (from
get_page_objects or the page XML — either the table's own objectID or the objectID of the
outline element that contains it) or by its 1-based position on the page ("1" =
first table).
Row and column numbers are 1-based (row 1 is the first/top row, which is often a header).
Outlines
OneNote lays out content in floating Outline boxes positioned by x/y. Identify an
outline by its objectID or 1-based index ("1" = first outline).
These generate XML only (they don't modify a page); insert the result with another
command.
duplicate_page
Copies a page (for example a template) into a new page. By default the copy lands in the
source page's own section; you may pass target_section_identifier and/or new_title.
OneNote assigns fresh object IDs to the copy.
save_page_xml_to_file writes one page's raw XML; the file is named after the page title
(.xml) unless you pass .
save_all_notebook_pages_xml_to_file reads every page via GetPageContent, which loads
them into OneNote. For very large notebooks this can make OneNote sluggish — restart
OneNote afterward if needed.
Configuration
Setting
Default
Meaning
OneNote operation timeout (s)
90
Max time for one COM operation
Markdown conversion timeout (s)
30
Only used when writing Markdown
Default page size (characters)
8000
Text/XML chars per read when max_chars omitted
Default item page size
50
List items per read when limit omitted
Default export directory
(empty)
Where save_*_to_file writes when output_dir omitted
Troubleshooting
Project layout
License
MIT (this plugin). See local-onenote-mcp
for the original project's license and terms.
Reads that can be large (page text, raw XML, hierarchies, search results, binary content)
are paginated: text/XML use offset + max_chars; lists use offset + limit. Each
response returns next_offset / has_more, and full documents are cached so paging does
not re-hit OneNote.
lms bootstrap
OneMore add-in for OneNote(optional) — only required if you write content with
content_format: "markdown". Set ONENOTE_MANAGER_MARKDIG_DLL if OneMore is installed in
a non-standard location.
find_meta
Find objects by OneNote meta name (paged)
find_references_to_hyperlink
Scan pages for all references to a given hyperlink URL (returns path + object IDs)
generate_onenote_hyperlink_xml
Generate hyperlink XML to another page (for later insertion)
generate_todo_tag_xml
Generate OneNote "To Do" checkbox tag XML (for later insertion)
get_binary_content
Read binary content (base64) by callback id (paged)
get_hyperlink
Client or web link for an object
get_page
Page text (+ title/objects on first slice) (paged)
Get one Outline's XML by objectID or 1-based index
get_page_table_xml
Get one table's XML by objectID or 1-based index
get_page_text
Page plain text (paged)
get_page_xml
Raw OneNote page XML (paged)
get_parent
Parent object id
get_special_locations
Backup / unfiled / default notebook folder
health_check
Verify the OneNote connection + counts
insert_page_outline_xml
Insert an Outline into a page at the far bottom or right
insert_page_outline_xml_from_file
Read an Outline XML from a file and insert it into a page
insert_row_into_table
Insert a table row (text per column); preserves formatting
list_hierarchy
List hierarchy from a start point (paged)
list_notebooks
List notebooks (paged)
list_pages
List pages in a section (paged)
list_sections
List sections (optionally in one notebook) (paged)
merge_sections
Merge one section into another (destructive)
navigate_to
Focus an object in the OneNote UI
navigate_to_url
Open a onenote: URL
open_hierarchy
Open or create a notebook / group / section by path
publish_object
Export to PDF / Word / XPS / HTML / .one, etc.
replace_entire_page_body
Replace a page's entire body content (destructive)
replace_page_table_xml
Replace one table's XML by objectID or 1-based index
replace_page_text
Find and replace all occurrences of text on a page (preserves formatting by default)
replace_table_cell_text
Replace one table cell's text by row/column
resolve_identifier
Resolve GUID / path / name to one object
save_all_notebook_pages_xml_to_file
Save a whole notebook's page XML to <notebook>.xml
save_page_xml_to_file
Save one page's XML to a file
search_pages
Indexed text search with snippets (paged)
save_page_outline_xml_to_file
Save one Outline's XML to a file
set_filing_location
Filing location for email / clips / printouts
sync_hierarchy
Sync a notebook hierarchy object
update_hierarchy_xml
Advanced: submit raw hierarchy XML
update_page_title
Rename a page
update_page_xml
Advanced: submit raw page XML
get_page_table_xml / replace_page_table_xml — read a table's raw
<one:Table>…</one:Table>, or replace it wholesale. To hand-edit, fetch, modify the
returned XML, and pass it back.
insert_row_into_table — add a row with values (text per column). Existing
formatting is preserved by cloning an existing row's cell styles (choose which with
template_row_index, default = last row). index sets the 1-based position (default:
append).
replace_table_cell_text — replace one cell's text by 1-based row/column; the cell's
formatting is kept.
delete_row_from_table — remove a row by 1-based row_index, or by matching
first_column_text (case-insensitive; wins if both are given).
get_page_outline_xml — read one outline's raw <one:Outline> XML.
insert_page_outline_xml — insert a <one:Outline> (or loose one:OE content, which
is auto-wrapped) into a page, positioned automatically after all existing outlines at the
far bottom (default) or far right. Fresh object IDs are assigned.
duplicate_page_outline — clone an existing outline and place the copy at the far
bottom or right.
save_page_outline_xml_to_file — extract one outline's raw <one:Outline> XML and write it to a file. The file is named after the page title with _outline_<index>.xml unless you pass file_name. Optional output_dir, overwrite. Defaults its directory to the plugin's Default export directory setting.
insert_page_outline_xml_from_file — read an Outline XML from a local .xml file and insert it into a page, positioned automatically at the far bottom (default) or far right. Fresh object IDs are assigned.
add_outline_to_page — create a new floating outline on the page from content
(plain / html / markdown). (This is the command formerly named append_to_page.)
add_content_to_page_outline — add content (plain / html / markdown) to an outline
identified by objectID or 1-based index. If outline_id is omitted the first outline is
used, and if the page has no outline, one is created automatically.
add_todo_items_to_page_outline — add one or more To Do (checkbox) items to an
outline in a single call. It creates the page's To Do TagDef if the page has none (and
reuses it otherwise). If outline_id is omitted the first outline is used, and if the
page has no outline, one is created. Each item's text is interpreted per
content_format (plain, html, or markdown), so items can carry hyperlinks or inline
formatting — e.g. a onenote: link from generate_onenote_hyperlink_xml, or markdown
[text](url) (block structure collapses to line breaks). Each entry in items has its own
text, optional completed, and optional indent_level (0 = top level, 1 = indented
under the previous item, …; an item can go at most one level deeper than the one before it,
and deeper values are clamped). By default the batch is appended (continuing the list); pass
position (1-based) to insert the batch between existing items at the first item's
indent level.
generate_onenote_hyperlink_xml resolves the target page's link and returns
inline_html (for add_outline_to_page / add_content_to_page_outline with
content_format: "html") plus one_t_xml /
one_oe_xml for raw insertion (e.g. inside insert_page_outline_xml). Supports
bold/italic/underline/strikethrough and web (https link vs onenote: link).
generate_todo_tag_xml returns a To Do checkbox tag: tag_def_xml (a page-level
one:TagDef — add once via update_page_xml if the page has none), tag_xml (the
one:Tag that goes first inside a one:OE), and, if you pass text, a ready one_oe_xml.
file_name
save_all_notebook_pages_xml_to_file reads an entire notebook by name and writes one XML
file (named <notebook>.xml) that mirrors the section-group / section / page structure,
with each page's raw OneNote XML embedded inline. Optional output_dir, page_info,
overwrite.
Both default their directory to the plugin's Default export directory setting, or the
plugin working directory if unset. Files are written on the machine running OneNote.
0x80080005 / focus flips to OneNote then times out — a privilege-level mismatch.
Run LM Studio non-elevated, at the same level as OneNote. Make sure OneNote isn't running
elevated either.
First call is slow / times out — OneNote is starting up. Raise OneNote operation
timeout and retry.
Reads look cut off — lower Default page size (characters); the model pages the
rest via next_offset.
Markdown content fails — install the OneMore add-in, or set
ONENOTE_MANAGER_MARKDIG_DLL to its Markdig.Signed.dll. Plain and HTML content need no
add-in.
OneNote gets sluggish after many reads — reads are cached and page GUIDs skip a
full-store scan, but reading many distinct pages still loads them into OneNote; restart
OneNote periodically for long sessions.
npm install # installs dependencies and creates package-lock.json (required by LM Studio)lms dev # loads the plugin into LM Studio and hot-reloads on changes