Skip to main content
Glama
OneNote MCP Server

OneNote MCP Server

by baibo3180

OneNote MCP Server — fork with truly persistent login

License: MIT Node

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 (tokenCachePersistenceOptions)

Upstream passed a wrong field name and never registered the cache plugin, so the refresh token died with the process

AuthenticationRecord persisted (AES-256-GCM) and reloaded on startup

A brand-new process can renew silently instead of prompting for a device code

createCredential() is async and awaited

It used to pass an unresolved Promise as the account record → silent renewal broke

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 (disableAutomaticAuthentication)

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

npm install no longer runs husky via prepare

npm install failed outright in a folder without .git (e.g. ZIP download)

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

git clone https://github.com/baibo3180/onenote-mcp-server.git
cd onenote-mcp-server
npm install

Recommended 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.

Option B — run straight from GitHub

npx -y github:baibo3180/onenote-mcp-server

Zero 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.

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

README.md

clone URL, npx github: example, the Windows cmd /c npx snippet

package.json

repository.url, bugs.url, homepage

CHANGELOG.md

the npx github: line (cosmetic)

git clone https://github.com/<your-user>/onenote-mcp-server.git
cd onenote-mcp-server
npm install

Two things stay per-machine, not per-repo, so a fork is not "shared login":

  • <repo>/.access-token.txt and <repo>/.auth-record.txt live inside the checkout — every clone/fork needs one authenticate on 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=production keeps structured logs on stderr (stdout stays clean for the MCP protocol).

  • On Windows some clients cannot spawn .cmd shims. If you use the npx route, 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)

  1. Restart your MCP client so it loads the new server.

  2. Call the authenticate tool.

  3. 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.

  4. 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

<repo>/.access-token.txt

Current access token + metadata

AES-256-GCM

<repo>/.auth-record.txt

Account record needed for silent renewal

AES-256-GCM

OS keychain (onenote-mcp)

AES key

Windows Credential Manager / Keychain / libsecret

MSAL token cache (OS-level)

Refresh token

Windows: DPAPI file · macOS: Keychain · Linux: libsecret

MSAL cache location per OS:

  • Windows — %LOCALAPPDATA%\.IdentityService\msal.cache.nocae (DPAPI, current user; a sibling .lockfile serialises cross-process access)

  • macOS — macOS Keychain, service Microsoft.Developer.IdentityService

  • Linux — libsecret / GNOME Keyring; a headless box without a Secret Service will fall back to a non-persistent in-memory cache (login once per run)

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:

  1. A crash left msal.cache.nocae.lockfile behind. This fork deletes locks older than 30 seconds automatically; if you are on a build without that fix, delete the file manually.

  2. The cache or the account record was deleted (msal.cache.nocae, .auth-record.txt), or you cleared Windows Credential Manager.

  3. More than 90 days without using the server (documented refresh-token lifetime), or you revoked the app at https://account.live.com/consent/Manage.

  4. You ran it through npx and 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.


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:

  1. App registrations → New registration

  2. Supported account types: Accounts in any organizational directory and personal Microsoft accounts

  3. Authentication → Allow public client flows: Yes

  4. Copy the Application (client) ID and set AZURE_CLIENT_ID in your MCP config's env block.

Delegated permissions used: Notes.Read, Notes.ReadWrite, Notes.Create, User.Read (offline_access is added implicitly).


Available tools (25)

  • Auth: authenticate, saveAccessToken

  • Read: listNotebooks, listSections, listSectionGroups, searchSections, listPagesInSection, searchPages, getRecentPages, getPageContent, getPageByTitle, getPageLink

  • Create: createNotebook, createSection, createSectionGroup, createPage, createPageInSection

  • Write: updatePageContent, appendToPage, updatePageTitle, replaceTextInPage, addNoteToPage, addTableToPage

  • Delete / 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 hooks

Tests 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.


中文快速开始

  1. 安装:git clone https://github.com/baibo3180/onenote-mcp-server.git → cd onenote-mcp-server → npm install (需要 Node ≥ 20)。

  2. 在你的 MCP 客户端里加配置,command 用 node,args 填 <仓库绝对路径>/src/server.mjs,env 里加 NODE_ENV=production。

  3. 重启客户端,调用 authenticate 工具,按返回的设备码到 https://microsoft.com/devicelogin 登录。

  4. 再调用 listNotebooks 验证。之后同一台机器上会自动静默续期,不用反复登录。

注意:npx github:... 每次重新拉取都会换目录,需要重新授权一次;想长期免登录请用上面的 clone 方式。

Related MCP Connectors

Related MCP Servers

  • A
    license
    D
    quality
    C
    maintenance
    Enables 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.
    20
    4
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables AI assistants to read, write, and manage Microsoft OneNote notebooks, sections, and pages through OAuth-authenticated MCP tools, resources, and prompts.
    16
    21 npm
    5
    MIT