M365 Planner

Data & APIs

Manage Microsoft 365 Planner plans, buckets, and tasks via Microsoft Graph API. Use when creating, listing, updating, or deleting Planner resources. Supports group-based plan management, task assignment, progress tracking, and recurring tasks. Requires Azure AD app registration with Group.Read.All and Tasks.ReadWrite.All permissions.

Install

openclaw skills install m365-planner-v2

M365 Planner Skill

Manage Microsoft 365 Planner through Microsoft Graph API.

What's New in v1.2.3

  • 🌍 English Documentation – Complete translation for international ClawHub availability
  • 🔧 Portability – Env path now uses os.homedir() instead of hardcoded paths
  • 🧹 Security Cleanup – Full audit for sensitive data (no IDs, names, domains)
  • 📦 ClawHub-ready – Tarball created, node_modules excluded

What's New in v1.2.2

  • 🔧 Portability – Env path now uses os.homedir() instead of hardcoded /home/claw/.openclaw/.env
  • 🧹 Security Cleanup – Full audit for sensitive data (no IDs, names, domains)
  • 📦 ClawHub-ready – Tarball created, node_modules excluded

What's New in v1.2.1

  • Generic Scripts – No hardcoded Group-IDs or Plan names anymore
  • Command-Line Parameters – All scripts accept IDs as arguments
  • List Plans Improved – Shows all groups when no ID provided
  • Flexible Cleanup – Works with any plans/buckets
  • ClawHub-ready – No project-specific data included

What's New in v1.1.0

  • Node.js Scripts – Standalone scripts without mgc CLI
  • If-Match Header Support – Correct ETag handling for updates/deletes
  • Group-Based API – Direct access via M365 Group-ID
  • Recurring Tasks – Note about native Planner recurrence feature
  • Cleanup Scripts – Automated task cleanup

Prerequisites

  1. Azure AD App Registration (see Setup below)
  2. Node.js v18+ with @microsoft/microsoft-graph-client and axios
  3. M365 Group (not Security Group or Distribution List!)

Quick Start

# Test connection
node scripts/test-connection.js

# List all plans
node scripts/list_plans.js

# List plans for specific group
node scripts/list_plans.js <group-id>

# Create plan
node scripts/create_plan.js "Project Name" <group-id>

# Create task
node scripts/create_task.js <plan-id> <bucket-id> "Task Title"

# Delete completed tasks
node scripts/cleanup_verlaengerungen.js <group-id> "<plan-name>" "<bucket-name>"

Setup: Azure AD App Registration

Step 1: Create App Registration

Azure Portal:

  1. https://portal.azure.com → Azure Active Directory → App registrations
  2. "New registration"
  3. Name: M365-Planner-Integration
  4. Supported account types: Accounts in this organizational directory only
  5. Redirect URI: None (Client Credentials Flow)

Or via Azure CLI:

az login
az ad app create --display-name "M365-Planner-Integration" --sign-in-audience "AzureADMyOrg"

Note the Application (client) ID from the output.

Step 2: Add API Permissions

Important: Use Application Permissions (not Delegated)!

Azure Portal:

  1. App → API permissions → Add a permission
  2. Microsoft Graph → Application permissions
  3. Add:
    • Group.Read.All (not Group.ReadWrite.All – sufficient for Planner)
    • Tasks.ReadWrite.All
  4. Grant Admin Consent: Click "Grant admin consent for [Tenant]"!

Or via Azure CLI:

APP_ID="your-app-id"

# Group.Read.All
az ad app permission add \
  --id $APP_ID \
  --api 00000003-0000-0000-c000-000000000000 \
  --api-permissions 5b567253-7703-48e2-861c-caed61531407=Role

# Tasks.ReadWrite.All
az ad app permission add \
  --id $APP_ID \
  --api 00000003-0000-0000-c000-000000000000 \
  --api-permissions bdfbf15f-ee85-495a-99a9-ef9b2abb1dcb=Role

# Admin Consent
az ad app permission admin-consent --id $APP_ID

Step 3: Create Client Secret

Azure Portal:

  1. App → Certificates & secrets → Client secrets → New client secret
  2. Description: OpenClaw Integration
  3. Expires: 24 months (Maximum)
  4. Copy values immediately! – Only shown once

Or via Azure CLI:

az ad app credential reset \
  --id $APP_ID \
  --append \
  --display-name "OpenClaw Integration"

Step 4: Configure Environment

Store credentials in ~/.openclaw/.env:

# Microsoft 365 Planner Credentials
M365_CLIENT_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
M365_CLIENT_SECRET="your-secret-value"
M365_TENANT_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Secure permissions:

chmod 600 ~/.openclaw/.env

Step 5: Test Connection

node scripts/test-connection.js

Expected output:

✅ Access Token successfully received!
📋 Test: M365 Groups...
   3 groups found:
   - My Team ✅ M365/Planner-capable
✅ Connection successful!

Important Notes

M365 Groups vs. Security Groups

Planner ONLY works with M365 Groups!

  • M365 Group – Has Exchange mailbox, Teams, Planner (recognizable by mail attribute)
  • Security Group – Only for permissions, no Planner
  • Distribution List – Only for email distribution, no Planner

Check groups:

node scripts/test-connection.js

Shows all groups with status "✅ M365/Planner-capable".

Create M365 Group (if none exists):

  • Microsoft 365 Admin Center → Groups → Add a group
  • Or Teams: Create new team (automatically creates M365 Group)

If-Match Header (ETag)

All update and delete operations require the If-Match header!

Planner uses Optimistic Concurrency Control. Requests fail without ETag.

Delete Example:

// Wrong ❌
await client.api(`/planner/tasks/${taskId}`).delete();

// Correct ✅
const task = await client.api(`/planner/tasks/${taskId}`).get();
await client.api(`/planner/tasks/${taskId}`)
    .headers({ 'If-Match': task['@odata.etag'] })
    .delete();

Update Example:

const task = await client.api(`/planner/tasks/${taskId}`).get();
await client.api(`/planner/tasks/${taskId}`)
    .headers({ 'If-Match': task['@odata.etag'] })
    .update({ percentComplete: 50 });

Group-Based API Endpoints

Do NOT use:

GET /planner/plans  ❌ (requires complex filter)

Use:

GET /groups/{group-id}/planner/plans  ✅

Example:

const plans = await client.api(`/groups/${groupId}/planner/plans`).get();

Recurring Tasks

Microsoft Planner supports native recurring tasks!

In Planner Web UI or Mobile App:

  1. Open task
  2. Click "Repeat"
  3. Choose frequency: Daily, Weekly, Monthly, Yearly, Custom

Example:

  • "Domain renewal example.com" → Repeat yearly
  • "Check backup" → Repeat weekly

⚠️ API Limitation: The Graph API does not support creating recurring tasks directly. Recurring tasks must be set up via Planner UI.

Common Operations

Plans

OperationScript
List all plansnode scripts/list_plans.js
Create plannode scripts/create_plan.js <name> <group-id>
Delete plannode scripts/delete_plan.js <plan-id>

Buckets

OperationScript
List bucketsIntegrated in list_plans.js
Create bucketnode scripts/create_bucket.js <plan-id> <name>
Delete bucketnode scripts/delete_bucket.js <bucket-id>

Tasks

OperationScript
List tasksIntegrated in list_plans.js
Create tasknode scripts/create_task.js <plan-id> <bucket-id> <title>
Update tasknode scripts/update_task.js <task-id> --percent-complete 50
Delete tasknode scripts/delete_task.js <task-id>
Cleanupnode scripts/cleanup_verlaengerungen.js <group-id> "<plan-name>" "<bucket-name>"

Helper Scripts

test-connection.js

Tests connection to Microsoft Graph:

  • Request access token
  • Display tenant information
  • List available M365 Groups
  • Check Planner capability
node scripts/test-connection.js

list_plans.js

Shows all plans in an M365 Group with:

  • Buckets and their tasks
  • Task status (completed/in progress/open)
  • Percentage progress indicator
# Without argument: Shows all available groups
node scripts/list_plans.js

# With Group ID: Shows plans for specific group
node scripts/list_plans.js <group-id>

create_plan.js

Creates a new plan with default buckets:

  • To Do
  • In Progress
  • Done
node scripts/create_plan.js "Project Alpha" <group-id>

cleanup_verlaengerungen.js

Cleans up completed tasks from a bucket:

  • Deletes tasks with 100% progress
  • Keeps open tasks
  • Correct If-Match header handling
node scripts/cleanup_verlaengerungen.js <group-id> "<plan-name>" "<bucket-name>"

Example:

node scripts/cleanup_verlaengerungen.js abc-123 "My Project" "Completed"

Troubleshooting

Error: Insufficient privileges

Cause: Admin consent not granted

Solution:

az ad app permission admin-consent --id <app-id>

Or in Azure Portal: API permissions → Grant admin consent

Error: Group not found

Cause: Planner only works with M365 Groups

Solution:

  1. Check if it's an M365 Group (has mail attribute)
  2. Security Groups/Distribution Lists don't work
  3. Create new M365 Group (Teams or Admin Center)

Error: The If-Match header must be specified

Cause: Update/Delete without ETag

Solution:

// First get task for ETag
const task = await client.api(`/planner/tasks/${id}`).get();
// Then update/delete with If-Match header
await client.api(`/planner/tasks/${id}`)
    .headers({ 'If-Match': task['@odata.etag'] })
    .delete();

Error: This entity set must be queried with a filter

Cause: /planner/plans endpoint requires filter

Solution: Use group-based endpoint:

// Wrong ❌
const plans = await client.api('/planner/plans').get();

// Correct ✅
const plans = await client.api(`/groups/${groupId}/planner/plans`).get();

Error: Cannot find module '@microsoft/microsoft-graph-client'

Cause: Node.js packages not installed

Solution:

cd ~/.openclaw/workspace/skills/m365-planner
npm install

Dependencies

Install packages locally in skill directory:

cd ~/.openclaw/workspace/skills/m365-planner
npm install @microsoft/microsoft-graph-client axios

References

Changelog

v1.2.3 (2026-04-18)

  • 🌍 English Documentation – Complete translation for international ClawHub availability
  • 🔧 Portability – Env path uses os.homedir() for cross-system compatibility
  • 🧹 Security Audit – No hardcoded IDs, names, or domains

v1.2.2 (2026-04-18)

  • 🔧 Portability – Env path now uses os.homedir() instead of hardcoded /home/claw/.openclaw/.env
  • 🧹 Security Cleanup – Full audit for sensitive data (no IDs, names, domains)
  • 📦 ClawHub-ready – Tarball created, node_modules excluded

v1.2.1 (2026-04-18)

  • Generic Scripts – No hardcoded Group-IDs or Plan names anymore
  • Command-Line Parameters – All scripts accept IDs as arguments
  • List Plans Improved – Shows all groups when no ID provided
  • Flexible Cleanup – Works with any plans/buckets
  • ClawHub-ready – No project-specific data included

v1.1.0 (2026-04-17)

  • ✅ Node.js Scripts instead of mgc CLI
  • ✅ If-Match Header Support for updates/deletes
  • ✅ Group-based API Endpoints
  • ✅ Test-Connection Script with M365 Group Detection
  • ✅ List Plans Script with Bucket/Task overview
  • ✅ Cleanup Script for completed tasks
  • ✅ Documentation for recurring tasks (native Planner feature)
  • ✅ Troubleshooting Section expanded

v1.0.0 (2023-01-19)

  • Initial version with mgc CLI
  • Azure AD Setup Guide
  • Basic CRUD operations