โ† Back to skills
extension
Category: OtherAPI key required

M365 Planner

Manage Microsoft 365 Planner plans, buckets, and tasks via Microsoft Graph API. Use when creating, listing, updating, or deleting Planner resources. Supports...

personAuthor: felox63hubclawhub

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

| Operation | Script | |-----------|--------| | List all plans | node scripts/list_plans.js | | Create plan | node scripts/create_plan.js <name> <group-id> | | Delete plan | node scripts/delete_plan.js <plan-id> |

Buckets

| Operation | Script | |-----------|--------| | List buckets | Integrated in list_plans.js | | Create bucket | node scripts/create_bucket.js <plan-id> <name> | | Delete bucket | node scripts/delete_bucket.js <bucket-id> |

Tasks

| Operation | Script | |-----------|--------| | List tasks | Integrated in list_plans.js | | Create task | node scripts/create_task.js <plan-id> <bucket-id> <title> | | Update task | node scripts/update_task.js <task-id> --percent-complete 50 | | Delete task | node scripts/delete_task.js <task-id> | | Cleanup | node 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