# Microsoft Planner MCP server

> Manage Microsoft Planner tasks, buckets, and plans by interacting with the Microsoft Graph API.

- Repository: https://github.com/mspstack/mcp-planner
- Page: https://hostedmcp.org/servers/mspstack/mcp-planner
- Transport: stdio
- Stars: 4
- License: MIT
- Latest version: 0.4.0

## Install

### Claude Code

```sh
claude mcp add --env 'MS_CLIENT_SECRET=<YOUR_MS_CLIENT_SECRET>' --env 'MS_CLIENT_ID=<MS_CLIENT_ID>' --env 'MS_TENANT_ID=<MS_TENANT_ID>' mcp-planner -- npx -y mcp-planner
```

### Cursor (`~/.cursor/mcp.json`)

```json
{
  "mcpServers": {
    "mcp-planner": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-planner"
      ],
      "env": {
        "MS_CLIENT_SECRET": "<YOUR_MS_CLIENT_SECRET>",
        "MS_CLIENT_ID": "<MS_CLIENT_ID>",
        "MS_TENANT_ID": "<MS_TENANT_ID>"
      }
    }
  }
}
```

### VS Code (`.vscode/mcp.json`)

```json
{
  "servers": {
    "mcp-planner": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "mcp-planner"
      ],
      "env": {
        "MS_CLIENT_SECRET": "<YOUR_MS_CLIENT_SECRET>",
        "MS_CLIENT_ID": "<MS_CLIENT_ID>",
        "MS_TENANT_ID": "<MS_TENANT_ID>"
      }
    }
  }
}
```

### VS Code CLI

```sh
code --add-mcp '{"name":"mcp-planner","type":"stdio","command":"npx","args":["-y","mcp-planner"],"env":{"MS_CLIENT_SECRET":"<YOUR_MS_CLIENT_SECRET>","MS_CLIENT_ID":"<MS_CLIENT_ID>","MS_TENANT_ID":"<MS_TENANT_ID>"}}'
```

### Claude Desktop (`claude_desktop_config.json`)

```json
{
  "mcpServers": {
    "mcp-planner": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-planner"
      ],
      "env": {
        "MS_CLIENT_SECRET": "<YOUR_MS_CLIENT_SECRET>",
        "MS_CLIENT_ID": "<MS_CLIENT_ID>",
        "MS_TENANT_ID": "<MS_TENANT_ID>"
      }
    }
  }
}
```

### Codex

```sh
codex mcp add mcp-planner --env 'MS_CLIENT_SECRET=<YOUR_MS_CLIENT_SECRET>' --env 'MS_CLIENT_ID=<MS_CLIENT_ID>' --env 'MS_TENANT_ID=<MS_TENANT_ID>' -- npx -y mcp-planner
```

### Codex config.toml (`~/.codex/config.toml`)

```toml
[mcp_servers.mcp-planner]
command = "npx"
args = ["-y", "mcp-planner"]

[mcp_servers.mcp-planner.env]
MS_CLIENT_SECRET = "<YOUR_MS_CLIENT_SECRET>"
MS_CLIENT_ID = "<MS_CLIENT_ID>"
MS_TENANT_ID = "<MS_TENANT_ID>"
```

### Gemini CLI

```sh
gemini mcp add -s user -e 'MS_CLIENT_SECRET=<YOUR_MS_CLIENT_SECRET>' -e 'MS_CLIENT_ID=<MS_CLIENT_ID>' -e 'MS_TENANT_ID=<MS_TENANT_ID>' mcp-planner npx -- -y mcp-planner
```

### Gemini settings.json (`~/.gemini/settings.json`)

```json
{
  "mcpServers": {
    "mcp-planner": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-planner"
      ],
      "env": {
        "MS_CLIENT_SECRET": "<YOUR_MS_CLIENT_SECRET>",
        "MS_CLIENT_ID": "<MS_CLIENT_ID>",
        "MS_TENANT_ID": "<MS_TENANT_ID>"
      }
    }
  }
}
```

## Environment variables

| Name | Required | Secret | Description |
|---|---|---|---|
| `MS_CLIENT_SECRET` | yes | yes | Entra app registration client secret (app needs Tasks.ReadWrite.All, GroupMember.Read.All, User.Read.All application permissions) |
| `MS_CLIENT_ID` | yes | no | Entra app registration client id |
| `MS_TENANT_ID` | yes | no | Microsoft Entra ID tenant id (GUID or domain) |
| `PLANNER_ADVANCED_TOOLSET` | no | no | true/1 registers the advanced toolset (graph_get, graph_find_endpoint) — a read-only escape hatch limited to /planner, /groups, /users |

## Tools (12)

- `planner_search_groups`
- `planner_find_user`
- `planner_list_plans`
- `planner_get_plan`
- `planner_create_bucket`
- `planner_list_tasks`
- `planner_list_user_tasks`
- `planner_get_task`
- `planner_create_task`
- `planner_update_task`
- `planner_update_task_details`
- `planner_delete_task`

## FAQ

### How does the server handle concurrency in Microsoft Planner?

The server automatically handles Planner's ETag concurrency by fetching the current resource and passing its ETag during updates or deletions.

### What permissions are required for the Entra ID app registration?

You need to add Application permissions for Tasks.ReadWrite.All, GroupMember.Read.All, and User.Read.All, then grant admin consent.
