Copilot Workspace MCP
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Copilot Workspace MCP v1.4
MCP server that lets Microsoft 365 Copilot and Copilot Studio (incl. Teams) list, read and
write files in named code workspaces. Each chat keeps its own workspace, and the choice
survives server restarts (SQLite state via the built-in node:sqlite).
Quick start
npm install
Copy-Item .env.example .env # then set WORKSPACES, ALLOWED_ROOTS
npm run new-key # generates MCP_API_KEY in .env
npm run dev # http://localhost:8790/mcp
npm test # unit + end-to-end testsRequires Node.js >= 22.13. Expose port 8790 with a dev tunnel and register
https://<tunnel-host>/mcp in the client (the /mcp suffix is required).
Related MCP server: ChatGPT Codex CLI Bridge
Standalone executable (download, run, done)
A single-file app that sets everything up for you: no clone, no npm install, no build, no manual tunnel.
Download and run
Get the archive for your system from the latest release,
unpack it and run the executable inside. Each archive also contains a short README.txt; SHA256SUMS.txt is on the release page.
System | Archive | Run |
Windows (x64) |
| double-click |
macOS (Apple silicon / Intel) |
|
|
Linux (x64 / arm64) |
|
|
On first run it:
asks for the workspace folder to expose (default: current folder) and generates an API key, saved in
%APPDATA%\copilot-workspace-mcp\config.env(Windows) or~/.config/copilot-workspace-mcp/config.envdownloads the
devtunnelCLI into that folder if it is not on PATH, and signs you in if neededcreates a persistent tunnel (same public URL on every run), starts the server and hosts the tunnel
prints the public
https://.../mcpURL and the API key (key shown on first run or with--show-key)
A local web UI (default http://localhost:8791, loopback only) opens automatically in its own app-style window using the
installed Edge/Chrome, or the default browser if there is none (--no-ui / --no-open). It shows colour-coded live logs with
level/source/text filters, pause, clear and download, tunnel status with a restart button, Settings for every variable in
config.env (saving validates and restarts the server in place), and a Stop button. Ctrl+C, closing the console or Stop shuts
down the tunnel first, then the server, cleanly. The browser tools (browser_*) are on by default; set ENABLE_BROWSER=false to disable them.
Native window (Windows). On Windows the UI opens in a small frameless WebView2 window instead of a browser window. It has no
title bar and no close button (only minimize and maximize), Alt+F4 and the taskbar's "Close window" are ignored, and the window
exits only when the app stops, so the server and tunnel cannot be left running by accident: Stop is the one way out. It needs
the Edge WebView2 runtime (preinstalled on Windows 11 and current Windows 10); without it, or on macOS and Linux, the UI falls back
to the browser app window described above. The host (shell/, .NET Framework 4.8, ~1 MB) is compiled by npm run build:shell
and embedded in the executable by npm run build:standalone when the .NET SDK is installed (the Windows CI job has it).
The tunnel allows anonymous clients by default (Copilot Studio / M365 Copilot cannot sign in to a dev tunnel; the API key still
protects /mcp). Set TUNNEL_ALLOW_ANONYMOUS=false to restrict it to your own Microsoft account.
The console shows only errors and important lines (add --verbose for all dev tunnel output). Other flags:
--reconfigure, --new-key, --show-key, --no-tunnel, --no-ui, --no-open, --help. Any variable from .env.example can be
set in a .env in the folder you start it from, in the environment, or in config.env (later wins; settings saved
from the web UI go to config.env, so they override the other two).
Build it yourself
Needs Node.js >= 24 and npm install once. The executable embeds the Node runtime of the machine (or target) it is built for.
Goal | Command | Output in |
This machine's OS/arch |
|
|
Linux x64 + arm64 |
|
|
macOS Intel + Apple silicon |
|
|
Every target |
| all of the above plus |
Any mix |
| |
Download-ready archives |
|
|
Set OUT_DIR=some/folder to write somewhere other than release/.
Building on each OS. Run npm install then npm run build:standalone on that machine. On macOS this also ad-hoc signs the binary
(codesign, built into macOS), so it can run immediately on Apple silicon.
Cross-building from one machine. Targets for another OS/arch download that platform's official Node runtime
(same version as yours, cached in .cache/node/) and inject the app into it, so you can produce Linux and macOS binaries from Windows.
Cross-built Linux and Windows binaries run as they are. Cross-built macOS binaries cannot be code-signed off a Mac, so on the Mac run
once codesign --sign - ./copilot-workspace-mcp (the release archives avoid this because CI builds them on macOS runners).
Run it as a service (starts with the machine)
copilot-workspace-mcp service install # first-time setup, then register + start the service
copilot-workspace-mcp service url # print the public tunnel address
copilot-workspace-mcp service logs [-f] # show (or follow) the log
copilot-workspace-mcp service status | start | stop | restart | uninstallFrom a clone use npm run service -- install --exe release/copilot-workspace-mcp-<platform>-<arch>.
install runs the interactive setup once (workspace folder, API key, dev tunnel sign-in), then registers the program with --service:
no prompts, no window. The web UI stays at http://localhost:8791 in any browser.
System | Mechanism | Starts |
Windows | Scheduled Task | when you log on; restarted if it stops |
Linux | systemd user service ( | at boot ( |
macOS | LaunchAgent | when you log in; |
It runs as your user, not SYSTEM/root, because the dev tunnel sign-in is stored in your account. The tunnel address is written to the
log (search for TUNNEL URL:) and to tunnel-url.txt, both in the config folder (Windows %APPDATA%copilot-workspace-mcp, others ~/.config/copilot-workspace-mcp):
logs/service.log (5 MB, then rotated to .1) and tunnel-url.txt. Move the executable before installing, not after: the service points at its path.
Releases. Pushing a tag such as v1.4.0 runs .github/workflows/release.yml: it builds on Windows, Linux (x64 and arm64) and macOS
(Intel and Apple silicon) runners, packages the archives with scripts/package-release.mjs, and attaches them and SHA256SUMS.txt to a GitHub release.
The same workflow can be started by hand (Actions > Release executables) to get the archives as a build artifact without a release.
Configure a Copilot Studio agent
Step-by-step guide: Set up a Copilot Studio agent with this MCP server
(view it rendered,
since GitHub shows .html files as source; or download the repo file and open it in a browser).
It covers adding the MCP tool, the api-key header authentication, the per-chat workspace input, the optional browser and
command tools, and troubleshooting. The quick version: add an MCP tool with your public https://.../mcp URL, authentication
API key, type Header, name api-key, value = your key.
How a chat's workspace is chosen
For every tool call the server resolves the workspace in this order:
workspacetool argument (alias) - used by Microsoft 365 Copilot declarative agentsthe chat's saved binding, keyed by conversation id - Copilot Studio / Teams (
conversation-idheader, orconversationIdargument set toSystem.Conversation.Id)the default workspace (
DEFAULT_WORKSPACE, orswitch_workspacewithmakeDefault)
Every file tool reply starts with [workspace: <alias>].
Client | Setup |
Copilot Studio / Teams | Import |
M365 Copilot declarative agent | Add |
Any agent | Add the tool-usage blocks from |
MCP tools
Tool | Purpose |
| Registered workspaces, default and this chat's current one |
| Bind this chat to a workspace ( |
| Which workspace this chat uses and why |
| Register/unregister a folder (only under |
| Glob within the workspace (skips |
| Read a text file (size-capped) |
| Atomic create/overwrite; blocked in |
| Delete a file or an empty folder; a folder with content needs |
| Exact-string replacement (one edit or an atomic list of |
| Regex search of file contents ( |
| Replace, insert or delete one cell of a Jupyter |
| Per-chat task list that survives restarts |
ws_read_file also takes offset, limit and lineNumbers, and list_files takes sortBy: "modified".
Optional: web tools
Tool | Enabled by | Purpose |
|
| Read a public web page as text (HTML becomes markdown-style text; long pages are paged with |
|
| Top web results (title, URL, snippet) from the Brave Search API. |
Optional: headless browser and command runner
Both are off by default (see .env.example).
Tool | Enabled by | Purpose |
|
| Drive a headless Edge/Chrome (one tab per chat). Screenshots are returned as images and saved under |
| on by default; | Send an HTTP request (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, with headers and a text/JSON body) and get back the status, headers and body. Only |
| on by default; | Run git in a workspace. No shell, never prompts for credentials, remotes must be configured names, pull is fast-forward only, and force-push is not available. |
| on by default ( | Run allowlisted commands in a workspace root, optionally in the background (dev servers), with output capture. |
Typical flow: run_command npm run dev (background, readyText) -> browser_open the printed URL -> browser_screenshot -> browser_logs -> process_stop.
Safety: the browser only loads hosts in BROWSER_ALLOWED_HOSTS (default localhost; every sub-request and redirect is checked, file: is refused).
run_command only starts commands that begin with an allowlist entry, rejects quotes, pipes, &, ;, $, % and redirects, runs without MCP_API_KEY in its environment,
and each chat can only see and stop its own processes. By default it accepts dotnet, npm, npx, pnpm, yarn, node, python, python3, pip, cargo, go, make and curl;
set RUN_ALLOWED_COMMANDS to a narrower list (e.g. dotnet build;dotnet test;npm test), or to an empty value to switch the tools off. Never allowlist a shell (powershell, cmd, bash).
Programs like dotnet, node and python can run arbitrary code, and curl run this way is not limited by CURL_ALLOWED_HOSTS, so anyone holding the API key can do what those programs can do in your
workspaces. Keep the key private. Because quotes are rejected, arguments with spaces (such as curl -H "A: b") cannot be passed; use the curl tool for those. Uses playwright-core against an installed browser; no browser download.
HTTP endpoints
All except /health require the API key (api-key header, Authorization: Bearer, or ?api_key=).
Method | Path | Purpose |
GET |
| Liveness (no paths revealed) |
POST |
| MCP Streamable HTTP (stateless) |
GET / POST |
| List / register |
DELETE |
| Unregister |
GET / POST |
| Get / set default |
GET |
| Source file count |
GET |
| Recent tool calls |
API key (MCP_API_KEY)
Every request except GET /health must carry the key; without it the server returns 401.
The server refuses to start when MCP_API_KEY is empty (unless MCP_ALLOW_ANONYMOUS=true).
Generate (writes/rotates the key in
.env, prints it once):npm run new-key- or only print one:npm run new-key -- --printRestart the server (
npm run dev);.envis read at startup.Send it in one of these ways (checked in this order):
Where
Example
api-keyheader (recommended)api-key: <key>Bearer token
Authorization: Bearer <key>Query string (avoid: ends up in logs)
https://<host>/mcp?api_key=<key>Configure the clients
Copilot Studio: MCP wizard > Authentication API key > Type Header > name
api-key(or usedocs/copilot-studio-connector.yaml, which already declares it). Paste the key when creating the connection.M365 Copilot declarative agent: API key auth registered in the Teams developer portal / Agents Toolkit; the key is stored by Microsoft, not in the app package.
curl / scripts:
curl -H "api-key: $env:MCP_API_KEY" http://localhost:8790/workspaces
Rotate: npm run new-key, restart, then update the connection in each client. Never commit .env
(it is git-ignored) and never paste the key into chat prompts.
Dependencies
Versions are pinned exactly in package.json (and .npmrc sets save-exact=true). Update deliberately:
npm install <pkg>@<version>, then npm run typecheck && npm test. Check with npm run audit.
Known advisory: braces <= 3.0.3 (via fast-glob -> micromatch), CVE-2026-93687 / GHSA-vfj7-8cjw-p6xm,
has no patched release. list_files mitigates it by capping glob patterns at 512 characters and
8 nesting levels; remove this note when a fixed braces ships.
Safety
Paths are resolved inside the workspace (also through symlinks/junctions);
..and absolute paths are rejected.Writes into
.git,node_modulesor the state DB are refused; writes are atomic and size-limited.Every tool call is recorded in the audit log (no file contents). Chat bindings expire after
BINDING_TTL_DAYS(30) of inactivity; audit rows after 90 days.
Configuration
See .env.example. State DB default: %LOCALAPPDATA%\copilot-mcp\state.db.
License
MIT, see LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Persistent cloud workspaces for AI agents: run commands, edit files, use git and a browser.
Cross-agent artifact workspace with provenance across Claude Code, Codex, Cursor, LangGraph.
Securely search and manage workspace context files for AI agents and teams.
User-owned files and explicit AI Memories for authorized assistants with scoped access.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceProvides Copilot Studio with six tools for secure workspace file operations and one-time execution of pre-approved Python jobs in isolated, network-less Docker containers, with strict access controls and audit logging.-
- AlicenseNot gradedqualityCmaintenanceEnables conversations to delegate natural-language engineering tasks to a local CLI coding agent in operator-approved workspaces via MCP, with sandbox modes, write gating, bounded execution, and redacted results.MIT
- AlicenseNot gradedqualityAmaintenanceEnables ChatGPT on supported surfaces to inspect and edit local projects, run bounded commands, control Chrome or Edge, and work with connected Excel workbooks, while invoking the Codex model only when needed.MIT
- AlicenseNot gradedqualityBmaintenanceEnables an AI to open a workspace, list files, read and write files within a configured workspace directory, and render an embedded workspace UI inside ChatGPT. File access is restricted to that workspace, with hidden folders and symlinks skipped.Apache 2.0