Skip to main content
Glama
taiki-yoshida

copilot-studio-code

README.md
# copilot-studio-code

A local MCP server that gives a Microsoft Copilot Studio agent Claude-Code-style tools against your local filesystem and shell — read, edit, search, and run commands from the Copilot Studio test canvas. Ships with an importable Copilot Studio solution so you can stand up a working agent in minutes.

## Tools exposed

| Tool         | Purpose |
|--------------|---------|
| `read_file`  | Read a UTF-8 text file. |
| `write_file` | Create or overwrite a file. |
| `edit_file`  | Exact-match string replace (unique-match required, or `replace_all=true`). |
| `list_dir`   | List entries in a directory. |
| `glob`       | Find files matching a glob pattern. |
| `grep`       | Regex search across files (skips `node_modules`, `.git`, `dist`). |
| `run_shell`  | Execute a shell command (PowerShell on Windows, bash elsewhere). Disabled in `strict` mode. |

## Safety modes (selected at startup)

| Mode | Path jail | `run_shell` |
|------|-----------|-------------|
| `strict`   | enforced | **disabled** |
| `moderate` (default) | enforced | enabled, audit-logged |
| `open`     | off      | enabled, audit-logged |

How the mode is chosen, in order of precedence:

1. `SAFETY` env var (`strict` / `moderate` / `open`)
2. `--safety <mode>` CLI flag
3. Interactive prompt at startup (10s timeout → `moderate`)

All `write_file`, `edit_file`, and `run_shell` calls are appended to `<root>/.copilotstudio-mcp/audit.log`.

## Run it

```powershell
npm install
npm start
```

The server prints something like:

```
copilot-studio-code MCP server
  workspace root : E:\Dev\projects\my-project
  safety mode    : moderate
  listening on   : http://localhost:8787/mcp
  health check   : http://localhost:8787/healthz
```

Override the workspace it operates on:

```powershell
$env:WORKSPACE_ROOT = "E:\Dev\some-other-project"; npm start
```

## Wiring it into Copilot Studio

Copilot Studio is cloud-hosted, so it cannot reach `localhost`. Use **Microsoft Dev Tunnels** to expose the server over HTTPS.

### 1. Install and log in to dev tunnels

```powershell
winget install Microsoft.devtunnel
devtunnel user login
```

### 2. Create a persistent tunnel for port 8787

```powershell
devtunnel create copilotstudio-mcp --allow-anonymous
devtunnel port create copilotstudio-mcp -p 8787 --protocol http
devtunnel host copilotstudio-mcp
```

`devtunnel host` prints a public URL like `https://<id>-8787.usw2.devtunnels.ms`. Leave it running.

> Drop `--allow-anonymous` and the tunnel will require an MS account on the Copilot Studio side. Recommended once you have it working.

### 3. Wire the MCP server into a Copilot Studio agent

Two ways: import the prebuilt solution (fastest), or configure an agent manually.

#### Path A — Import the prebuilt solution

The [`solution/`](./solution) folder ships an unmanaged Copilot Studio solution containing a pre-configured agent (generative orchestration on, content moderation low), a custom connector for the MCP server, and a `WorkspaceMCP` topic that surfaces the tools to the planner.

1. Open https://make.powerapps.com → your environment → **Solutions** → **Import solution**.
2. Upload `solution/CopilotStudioCode_1_0_0_0.zip`. Take the defaults through the wizard.
3. Once imported, open the **Workspace MCP** custom connector → **Edit** → on the **General** tab, replace the placeholder host `YOUR-TUNNEL-ID-PORT.YOUR-REGION.devtunnels.ms` with your real dev tunnel host (e.g. `abc123-8787.usw2.devtunnels.ms`). Save → **Update connector**.
4. Open the imported agent and skip to step 4 (test canvas).

> The solution does not include the MCP server itself — that runs locally from this repo. The connector just points at it.

#### Path B — Configure an agent manually

1. Open Copilot Studio → your agent → **Tools** → **+ Add a tool** → **Model Context Protocol**.
2. Server URL: `https://<your-tunnel-id>-8787.usw2.devtunnels.ms/mcp`
3. Authentication: **None** (for the anonymous tunnel) or **Microsoft Entra** (for an authenticated one).
4. Save. Copilot Studio fetches the tool list from `/mcp` and shows the seven tools. Ensure each is enabled on the agent.
5. Settings → **Generative AI** → Orchestration: **Generative**; content moderation: **Low**. Without generative orchestration the planner won't dispatch MCP tools.

### 4. Test it from the test canvas

Open the test canvas and try prompts like:

- "List the files in the workspace root."
- "Read package.json and tell me what scripts are defined."
- "Add a new script called `lint` that runs `tsc --noEmit`."
- "Run `git status` and summarize the result."

The agent picks tools by name from the descriptions in `src/tools.ts` — tighten those descriptions if the agent picks the wrong tool.

## Project layout

```
src/                                  the MCP server (TypeScript)
  index.ts                            entry: safety prompt + boot
  server.ts                           express + Streamable HTTP MCP transport
  tools.ts                            the seven tool registrations
  safety.ts                           mode definitions
  paths.ts                            workspace-root path jail
  audit.ts                            JSONL audit log
solution/                             importable Copilot Studio solution
  CopilotStudioCode_1_0_0_0.zip       agent + connector + topics (unmanaged)
```