OneNote MCP Server
Click on "Deploy 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., "@OneNote MCP Server search my OneNote notebooks for notes about the Q3 budget"
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.
OneNote MCP Server — fork with truly persistent login
An MCP (Model Context Protocol) server that lets an AI assistant read, search, write and edit your Microsoft OneNote notebooks over Microsoft Graph — 25 tools covering notebooks, sections, section groups and pages.
This is a fork of IAmKSquared/onenotemcp (MIT). Upstream asks for a device-code login far too often; this fork fixes the token plumbing so you authenticate once per machine, not once per hour.
What this fork changes
Change | Why it matters |
Persistent MSAL cache actually enabled ( | Upstream passed a wrong field name and never registered the cache plugin, so the refresh token died with the process |
| A brand-new process can renew silently instead of prompting for a device code |
| It used to pass an unresolved |
Stale cache-lock cleanup (30s threshold) | A crash while holding MSAL's lock file used to degrade every later renewal into a device-code prompt |
Renewal credential is silent-only ( | On a fresh install the first tool call used to block for up to 15 minutes waiting for a login you never saw |
Device-code prompt is forced to stderr | The SDK printed it to stdout, which corrupts the MCP JSON-RPC stream and makes the client report a hung server |
|
|
Hardened Markdown→HTML conversion (attribute-escaped URLs, valid code blocks) | A crafted link URL could inject extra HTML attributes into a page; multi-line code fences produced |
Startup guards ( | An unhandled promise rejection used to kill the stdio server before it answered |
Startup tool banner derived from live registrations | The old hand-written list showed 22 tools while the server actually exposes 25 (2 auth + 10 read + 7 edit + 5 create + 1 delete) |
Troubleshooting docs for device-code loops and the OneNote freeze bug | Saves hours of debugging |
Measured on Windows 11 / Node 22: cold process, expired access token, 24 concurrent renewals — zero prompts, and the refresh token rotates on disk each time (rolling 90-day lifetime).
Related MCP server: OneNote MCP Server
Requirements
Node.js ≥ 20
A Microsoft account with OneNote (personal or work/school)
No Azure subscription needed for a quick test (see Client ID)
Installation
Option A — clone (recommended)
git clone https://github.com/baibo3180/onenote-mcp-server.git
cd onenote-mcp-server
npm installRecommended because the session files (.access-token.txt, .auth-record.txt)
live in the project folder. They survive restarts and git pull, so you stay
logged in.
If
git clonestalls or fails withConnection was reset, force HTTP/1.1 and retry — GitHub over HTTP/2 is throttled on some networks:git -c http.version=HTTP/1.1 clone https://github.com/baibo3180/onenote-mcp-server.gitSimply run it again if it fails once. The connection is intermittent, not broken.
Option B — run straight from GitHub
npx -y github:baibo3180/onenote-mcp-serverZero install, but every time npm re-fetches the repository (new commit, cleared
npx cache) it lands in a different folder, so .auth-record.txt is gone and
you will be asked for a device code again. The MSAL refresh token in the OS
token cache survives, but it is not enough on its own. Prefer Option A if you
dislike re-authenticating.
This needs npm itself to reach
github.com(it shells out to git and pulls a tarball). Behind a proxy that blocks GitHub you getE502 Bad Gatewayor a silent hang. Use Option A in that case — thegitclient can be forced onto HTTP/1.1 as shown above.
Forked this repo?
Everything is relative to the checkout, so a fork behaves exactly like the
original — no code references this repository's URL. Only the docs and
package.json names point at the original owner, so after forking, replace
baibo3180 with your username in:
File | What |
| clone URL, |
|
|
| the |
git clone https://github.com/<your-user>/onenote-mcp-server.git
cd onenote-mcp-server
npm installTwo things stay per-machine, not per-repo, so a fork is not "shared login":
<repo>/.access-token.txtand<repo>/.auth-record.txtlive inside the checkout — every clone/fork needs oneauthenticateon first run.The MSAL refresh token lives in the OS cache (Windows DPAPI, macOS Keychain, Linux libsecret). It is scoped to your OS user, so it never travels with a fork.
Both are already in .gitignore; a fork will not carry your credentials, and
your fork will not leak them either.
Connect your MCP client
Add this to your client's MCP configuration (Trae, Claude Desktop, Cursor, …):
{
"mcpServers": {
"onenote": {
"command": "node",
"args": ["/absolute/path/to/REPO/src/server.mjs"],
"env": {
"NODE_ENV": "production"
}
}
}
}Notes:
Use an absolute path to
src/server.mjs.NODE_ENV=productionkeeps structured logs on stderr (stdout stays clean for the MCP protocol).On Windows some clients cannot spawn
.cmdshims. If you use thenpxroute, set"command": "cmd"and"args": ["/c", "npx", "-y", "github:baibo3180/onenote-mcp-server"].Optional environment variables:
AZURE_CLIENT_ID,LOG_LEVEL.
First-time authentication (once per machine)
Restart your MCP client so it loads the new server.
Call the
authenticatetool.It returns a device code and a URL. Open https://microsoft.com/devicelogin, enter the code and sign in with the account that owns your OneNote notebooks.
Call
listNotebooks— you should see your notebooks.
From then on:
the access token (~1 hour) is renewed silently before it expires;
the refresh token is rotated and written back on every use, so its rolling 90-day window keeps moving as long as you use the server;
a new process (app restart, reboot, client switch) renews silently — no device code.
Where credentials live
File | Purpose | Protection |
| Current access token + metadata | AES-256-GCM |
| Account record needed for silent renewal | AES-256-GCM |
OS keychain ( | AES key | Windows Credential Manager / Keychain / libsecret |
MSAL token cache (OS-level) | Refresh token | Windows: DPAPI file · macOS: Keychain · Linux: libsecret |
If no OS keychain is available at all, the AES key falls back to a file
outside the project: %LOCALAPPDATA%\onenote-mcp\encryption.key on Windows,
~/.config/onenote-mcp/encryption.key elsewhere (override with
ONENOTE_MCP_KEY_FILE). It is never written into the checkout, so zipping or
copying the project does not hand over the key.
MSAL cache location per OS:
Windows —
%LOCALAPPDATA%\.IdentityService\msal.cache.nocae(DPAPI, current user; a sibling.lockfileserialises cross-process access)macOS — macOS Keychain, service
Microsoft.Developer.IdentityServiceLinux — libsecret / GNOME Keyring. The backend is loaded lazily: if
libsecret-1.so.0is missing (sudo apt install libsecret-1-0), the server still starts and works, but keeps tokens in memory only — so you log in once per process run instead of once per machine. SetONENOTE_MCP_DISABLE_CACHE_PERSISTENCE=1to skip the native backend on purpose (useful on headless hosts and in CI).
All of these are already in .gitignore. Never commit them — the token
cache is a credential that grants standing access to your notes.
Troubleshooting
The first tool call hangs, or the client says the server is unresponsive
Fixed in 1.1.1. On a fresh install with no saved login, the renewal credential
used to start an interactive device-code flow inside the tool call — blocking up
to 15 minutes and printing the prompt to stdout, which corrupts the MCP
stream. Renewal is now silent-only: you get an instant Authentication Required
message telling you to run authenticate.
If you are on 1.1.0 or earlier, call authenticate before any other tool, or
upgrade.
Asked for a device code again, even though I logged in before
In order of likelihood:
A crash left
msal.cache.nocae.lockfilebehind. This fork deletes locks older than 30 seconds automatically; if you are on a build without that fix, delete the file manually.The cache or the account record was deleted (
msal.cache.nocae,.auth-record.txt), or you cleared Windows Credential Manager.More than 90 days without using the server (documented refresh-token lifetime), or you revoked the app at https://account.live.com/consent/Manage.
You ran it through
npxand npm re-downloaded the repo (see Option B).
Re-running authenticate is the fix in every case.
No access token available. Please authenticate first...
Nothing to renew from. Call authenticate once.
OneNote desktop freezes when I click a code block on a page the server wrote
OneNote converts every newline inside <pre> / <code> into an object
placeholder character (U+FFFC). Pages containing them can make the desktop
client hang. When generating page HTML, write code as one <p> per line
with a monospace <span> (e.g. font-family:Consolas), and put inline code in
a monospace span instead of <code>.
Everything worked, then stopped after I moved the folder
The paths in your MCP config are absolute, and the account record is bound to
the old location. Update the config path and call authenticate once.
git clone hangs, or npx github: ends with E502 / never prints anything
Network, not code. Two different clients are involved:
npx github:...→ npm does the fetching, and npm honours the proxy environment. If that proxy cannot reach GitHub, you getE502or a silent hang. Do not fight it — clone first (Option A), thennpm installfrom the local folder and point your MCP client atsrc/server.mjs.git clone→ force HTTP/1.1 (git -c http.version=HTTP/1.1 clone ...) and retry on failure. If a proxy is set, unset it for the clone:env -u HTTPS_PROXY -u HTTP_PROXY git clone ...
Once the repo is on disk, nothing else needs GitHub access — authenticate
talks only to login.microsoft.com.
Client ID
Out of the box the server uses Microsoft Graph Explorer's public client ID. It is fine for trying things out, but it is shared by many apps and not something you should rely on long-term.
For regular use, register your own app in Microsoft Entra admin center:
App registrations → New registration
Supported account types: Accounts in any organizational directory and personal Microsoft accounts
Authentication → Allow public client flows: Yes
Copy the Application (client) ID and set
AZURE_CLIENT_IDin your MCP config'senvblock.
Delegated permissions used: Notes.Read, Notes.ReadWrite, Notes.Create,
User.Read (offline_access is added implicitly).
Available tools (25)
Auth:
authenticate,saveAccessTokenRead:
listNotebooks,listSections,listSectionGroups,searchSections,listPagesInSection,searchPages,getRecentPages,getPageContent,getPageByTitle,getPageLinkCreate:
createNotebook,createSection,createSectionGroup,createPage,createPageInSectionWrite:
updatePageContent,appendToPage,updatePageTitle,replaceTextInPage,addNoteToPage,addTableToPageDelete / copy:
deletePage,copyPage
Full parameter-level reference:
docs/UPSTREAM_README.md.
Development
npm install
npm run quality # eslint + prettier --check + all tests
npm run husky:init # optional: install git hooksTests do not need a Microsoft account; they mock Graph.
Security notes
The server runs locally over stdio and only talks to
graph.microsoft.com.Token files are encrypted with a key held in the OS keychain; the MSAL cache is protected by DPAPI (Windows) / Keychain (macOS) / libsecret (Linux).
Credentials are per-user and per-machine. Copying the project folder to another PC does not carry the login over.
Revoke access at https://account.live.com/consent/Manage (personal accounts) or in Entra ID (work accounts) if you ever suspect exposure.
Credits & license
MIT — see LICENSE.
Original project: IAmKSquared/onenotemcp by Kyle Klimek.
That project was in turn derived from eshlon/onenotemcp.
This fork adds persistent authentication, the stale-lock guard and the packaging fixes described above.
Not affiliated with or endorsed by Microsoft. OneNote and Microsoft Graph are trademarks of Microsoft Corporation.
中文快速开始
安装:
git clone https://github.com/baibo3180/onenote-mcp-server.git→cd onenote-mcp-server→npm install(需要 Node ≥ 20)。在你的 MCP 客户端里加配置,
command用node,args填<仓库绝对路径>/src/server.mjs,env里加NODE_ENV=production。重启客户端,调用
authenticate工具,按返回的设备码到 https://microsoft.com/devicelogin 登录。再调用
listNotebooks验证。之后同一台机器上会自动静默续期,不用反复登录。
注意:npx github:...
每次重新拉取都会换目录,需要重新授权一次;想长期免登录请用上面的 clone 方式。
Available Tools
25 toolsaddNoteToPageD
Inputs: note (required), pageId (required), noteType, position.
addTableToPageD
Inputs: pageId (required), tableData (required), title, position.
appendToPageD
Inputs: pageId (required), content (required), addSeparator, addTimestamp.
authenticateD
Inputs: no named parameters.
copyPageD
Inputs: pageId (required), targetSectionId (required).
createNotebookD
Inputs: displayName (required).
createPageD
Inputs: title (required), content (required).
createPageInSectionD
Inputs: title (required), content (required), sectionId (required).
createSectionD
Inputs: notebookId (required), displayName (required).
createSectionGroupD
Inputs: notebookId (required), displayName (required).
deletePageD
Inputs: pageId (required), confirmDelete (required).
getPageByTitleD
Inputs: title (required), format.
getPageContentD
Inputs: pageId (required), format.
getPageLinkD
Inputs: pageId (required).
getRecentPagesD
Inputs: notebookId (required), limit.
listNotebooksD
Inputs: no named parameters.
listPagesInSectionD
Inputs: sectionId (required).
listSectionGroupsD
Inputs: notebookId, sectionGroupId.
listSectionsD
Inputs: notebookId, sectionGroupId.
replaceTextInPageD
Inputs: pageId (required), findText (required), replaceText (required), caseSensitive.
saveAccessTokenD
Inputs: no named parameters.
searchPagesD
Inputs: query, notebookId, modifiedAfter, modifiedBefore.
searchSectionsD
Inputs: query (required).
updatePageContentD
Inputs: pageId (required), content (required), preserveTitle.
updatePageTitleD
Inputs: pageId (required), newTitle (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 25 tools
Tool names mostly indicate a resource and action, but without descriptions several tools overlap, especially page-content mutations like appendToPage, addNoteToPage, replaceTextInPage, and updatePageContent. createPage versus createPageInSection is also ambiguous about where the page is created.
Names consistently use camelCase and generally follow a verb+resource pattern such as listNotebooks, getPageContent, and createSection. Minor deviations like authenticate, updatePageTitle, and createPageInSection are still readable and predictable.
With 25 tools, the surface is heavy but plausibly covers OneNote's hierarchy, search, authentication, and page editing. Some content-editing tools appear redundant, so the count is borderline rather than tightly scoped.
Page operations are fairly complete, including create, get, update, copy, delete, append, replace, and table insertion. However, notebooks, sections, and section groups have creation and listing but no rename/update or delete operations, leaving notable lifecycle gaps for higher-level containers.
Related MCP Connectors
AI access to your aNotepad online notes: read, search, write, and organize via 22 tools.
Create, search, and update notes in an xNotepad AI notebook, with semantic search and AI Q&A.
Governed memory and workspace for any AI: tasks, calendar, mail and pages, with per-action consent.
Persistent memory and knowledge management for AI agents with semantic search and 50+ tools.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI language models to interact with Microsoft OneNote via a standardized interface, supporting notebook and page management through natural language.34 npm27MIT
- AlicenseDqualityCmaintenanceEnables AI assistants to securely interact with Microsoft OneNote data through the Microsoft Graph API. It supports comprehensive management tasks including searching page content, creating and editing notes, and automating productivity workflows like daily note creation.204MIT
- AlicenseAqualityDmaintenanceEnables AI assistants to read, write, and manage Microsoft OneNote notebooks, sections, and pages through OAuth-authenticated MCP tools, resources, and prompts.1646 npm5MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to read, search, write, and update Microsoft OneNote pages through the Model Context Protocol.46 npmMIT