msloop-mcp
OfficialClick 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., "@msloop-mcpList my Loop workspaces"
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.
msloop-mcp
MCP server for Microsoft Loop: enumerate, read, and edit your Loop workspaces and pages from any MCP client (Claude Desktop, Cursor, or anything else that speaks stdio).
No app registration required. Two auth modes: browser-session (reuses your signed-in Loop web app session — works even on tenants that block user consent) and device-code (Microsoft's first-party Graph PowerShell app). Tokens are cached locally and refresh automatically. See Authentication.
┌────────────┐ stdio ┌──────────────────────────────────────────────────┐
│ MCP client │ ◄──────► │ msloop-mcp │
└────────────┘ │ ├─ Graph search .loop files, HTML render │
│ ├─ Substrate workspaces + page discovery │
│ └─ LWS page read/create/edit (markdown) │
└──────────────────────────────────────────────────┘Setup
bun install && bun run build # produces the standalone binary dist/msloop-mcpInstall it on your PATH (no npm/node_modules needed at runtime — it's a self-contained executable):
ln -sf "$PWD/dist/msloop-mcp" ~/.local/bin/msloop-mcpThen register it with your MCP client as a stdio server. Most clients take the same JSON shape — for Claude Desktop it goes in claude_desktop_config.json, for Cursor in ~/.cursor/mcp.json:
{
"mcpServers": {
"msloop": {
"type": "stdio",
"command": "msloop-mcp"
}
}
}If the binary isn't on your PATH, use the full path in command instead.
First run: in browser-session mode there is no in-server login — capture the session once via scripts/save-session.mjs (see Authentication). In device-code mode, call the loop_login tool: it returns a URL (https://login.microsoft.com/device) and a code — open the URL, sign in with your work/school Microsoft account, enter the code, approve. One approval covers all API planes; everything else is silent afterwards. Cache lives in ~/.msloop-mcp/ (mode 0600); loop_logout wipes it.
Requires a work/school account (Loop needs M365). Bun >= 1.1 to build and run tests.
Related MCP server: msloop-mcp
Authentication
Two modes, selected by MSLOOP_AUTH_MODE (browser | device). Auto-detected by default: browser when ~/.msloop-mcp/session-tokens.json exists, device otherwise.
Browser-session mode (default once a session is captured)
Reuses the signed-in Loop web app session — no app registration, no admin consent, so it works on tenants that block user consent (e.g. university tenants).
Open https://loop.cloud.microsoft in a dedicated browser profile and sign in with your work/school account, e.g.:
chromium --user-data-dir=~/.msloop-mcp/chromium-profile https://loop.cloud.microsoftDump the localStorage + sessionStorage entries whose keys match
/token/ifrom the loop.cloud.microsoft tab into a JSON file — either an array of{name, value}or{localStorage: {…}, sessionStorage: {…}}.Import it:
bun scripts/save-session.mjs entries.json
Tokens auto-refresh via the Loop SPA refresh token (client a187e399-0c36-4b98-8f04-1edc167a0996; the refresh grant sends Origin: https://loop.cloud.microsoft, which Entra requires for SPA clients), so reads keep working indefinitely after the one-time capture. If the session fully expires, redo the capture — loop_auth_status tells you when.
Device-code mode (default otherwise, or MSLOOP_AUTH_MODE=device)
Signs in through Microsoft's first-party Graph PowerShell app, so no app registration is needed — but it requires user consent for the Graph scopes. Tenants with consent disabled (AADSTS65005-type admin-approval walls) cannot use this mode; use browser-session mode there.
Call loop_login, open the returned URL, enter the code, approve (details under Setup).
Tools
Tool | What it does |
| Device-code sign-in (returns URL + code); in browser mode, returns capture instructions |
| Account + per-plane token state |
| Clear cached tokens |
| All workspaces (personal "My workspace" + shared), with ids |
| Keyword search over every accessible Loop page/component; returns |
| Pages inside one workspace (by id or title substring) |
| Page content as markdown (pageId, Loop URL, or title substring) |
| New page with markdown content in a workspace |
|
|
| Move page to recycle bin (requires |
Page references accepted everywhere: pageId (base64 host,driveId,itemId), a Loop share URL (https://…/:fl:/…), or a title substring (unambiguous matches auto-resolve; ambiguous ones error with the candidates).
How editing works
Loop has no public content API, so this server uses the same internal planes the Loop web app uses:
Read: Loop Web Service markdown render, with fallback to Graph's
?format=htmlrender converted to markdown.Write (
create/edit): LWSPATCH /pages/{id}withlocationsemantics —after(append),REPLACE_ALL, orTargetLabel(section replace). Writes take markdown natively;appendnever touches existing content.
Editing a page while it is open in someone's browser is safe (Fluid merges text), but treat replace_all as destructive: embedded images/components in the replaced range are dropped.
Configuration
Env var | Default | Purpose |
| auto: | Force |
|
| Use your own app registration |
|
| Pin a tenant (recommended for own registrations) |
|
| Token cache location |
| unset | Graph Search |
| production | API endpoints (overridable for testing) |
If your tenant blocks the shared first-party app: browser-session mode usually avoids the problem entirely (it uses Loop's own SPA client and needs no consent). If you must stay on device mode, register an app in Entra ID (public client, "Allow public client flows: Yes"), add delegated Files.ReadWrite.All, Sites.ReadWrite.All, User.Read, then set MSLOOP_CLIENT_ID/MSLOOP_TENANT_ID.
Known limits
LWS pages/lists are a moving internal API; unexpected responses surface as descriptive errors, and the Graph fallback path keeps reads working regardless.
loop_create_page/loop_edit_pageuse the Loop internal write API (LWS), which some tenants reject (EDU tenants are a common case) — the error says so explicitly. On those tenants pages can only be written from the Loop app; reads are unaffected.Advanced components (code canvases, Copilot notes) read as best-effort text.
Tests
bun run typecheck && bun test/integration.mjs # stubbed-API end-to-end over InMemoryTransport
bun test/smoke.mjs # real compiled binary over stdio
bun test/e2e-live.mjs # live reads against your tenant (requires a captured session)This server cannot be deployed
Maintenance
Related MCP Connectors
MCP-native collaborative markdown editor with real-time AI document editing
MCP-native open-source Notion alternative: read & write pages, databases and kanban boards.
Public read-only MCP for products, frameworks, guides, methodology, and blog metadata.
Publish and share access-controlled Markdown documents from any MCP-enabled AI tool.
Related MCP Servers
- FlicenseNot gradedqualityFmaintenanceEnables users to view and edit Microsoft Loop pages as interactive markdown widgets directly within the chat interface. It supports inline rendering and provides tools for requesting page updates through a host's Loop MCP server.-
- AlicenseAqualityFmaintenanceMCP server that provides read access to Microsoft Loop workspaces and pages by reusing your Loop web session, enabling listing, reading, and searching across Loop content without app registration.820 npm2MIT
- AlicenseNot gradedqualityCmaintenanceA read-only MCP server that enables AI assistants to search and read Microsoft Loop content through the Microsoft Graph API, with per-user permission trimming ensuring each user only sees pages they already have access to.MIT
- AlicenseAqualityCmaintenanceEnables reading, listing, creating, and editing Microsoft Loop pages as Markdown through browser automation.4MIT