Ms Graph Calendar

v1.0.2

Find available meeting times and free/busy slots for company employees using Microsoft Graph API. Use when user asks to schedule a meeting, find a free slot,...

0· 361·1 current·1 all-time

Install

OpenClaw Prompt Flow

Install with OpenClaw

Best for remote or guided setup. Copy the exact prompt, then paste it into OpenClaw for artisong/ms-graph-calendar.

Previewing Install & Setup.
Prompt PreviewInstall & Setup
Install the skill "Ms Graph Calendar" (artisong/ms-graph-calendar) from ClawHub.
Skill page: https://clawhub.ai/artisong/ms-graph-calendar
Keep the work scoped to this skill only.
After install, inspect the skill metadata and help me finish setup.
Required env vars: AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET
Required binaries: node, curl
Use only the metadata you can verify from ClawHub; do not invent missing requirements.
Ask before making any broader environment changes.

Command Line

CLI Commands

Use the direct CLI path if you want to install manually and keep every step visible.

OpenClaw CLI

Bare skill slug

openclaw skills install ms-graph-calendar

ClawHub CLI

Package manager switcher

npx clawhub@latest install ms-graph-calendar
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Suspicious
medium confidence
Purpose & Capability
The name/description (Microsoft Graph calendar free/busy lookup) matches the required env vars (AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET) and the included Node.js scripts which call Microsoft Graph. Required binaries include node (used by scripts); curl is listed but not used by the shipped scripts (minor mismatch).
!
Instruction Scope
SKILL.md instructs the agent and operator to collect Azure credentials and run the included scripts; the instructions are concrete and limited to resolving names and calling Graph endpoints. However the docs state "Credentials are read from env vars only — never log or echo them", while get-token.js both prints the access token to stdout and writes it to /tmp/openclaw-graph-token.json. That contradicts the stated 'never log' guidance and creates an accidental disclosure risk if console output is captured.
Install Mechanism
This is an instruction-only skill with Node.js scripts included; there is no external download or installer. No risky install URLs or extracted archives are present. The only runtime requirement is Node (and curl is listed but unused).
!
Credentials
Requested environment variables are appropriate for an app-only Microsoft Graph integration. However: (1) the skill caches and reuses an app access token by writing it to a temp file in the system temp directory without setting secure file permissions, which can expose the token to other local users; (2) get-token.js prints the access token to stdout (contradicting the README). These behaviours are not justified by the stated purpose and increase the blast radius of leaked credentials.
Persistence & Privilege
The skill writes persistent credentials to ~/.openclaw/ms-graph-calendar.json (setup sets file mode 600) and writes the access token to the system temp directory (no explicit mode). It does not request always: true and does not attempt to modify other skills. Persisting the client secret in the home config is expected for convenience, but the unsecured token in /tmp is a risk and should be hardened or removed after use.
Scan Findings in Context
[prints-access-token-to-stdout] unexpected: get-token.js calls console.log(json.access_token) and therefore prints the access token. Printing tokens to stdout contradicts the SKILL.md security note and increases chance of accidental leakage (logs, CI capture, screen scraping). Not expected for this purpose.
[writes-token-to-tempdir-without-permissions] unexpected: get-token.js writes the token file to os.tmpdir()/openclaw-graph-token.json without explicitly setting restrictive file permissions. While caching tokens is reasonable, writing them to a world-readable tmp file is not necessary for the described functionality and increases exposure to other local users or processes.
[stores-client-secret-in-home-config] expected: setup.js stores AZURE_CLIENT_SECRET in ~/.openclaw/ms-graph-calendar.json with file mode 600. Storing the client secret locally for convenience is expected; the file mode used mitigates some risk. This is expected given the skill's design.
What to consider before installing
This skill appears to implement what it claims (find free/busy via Microsoft Graph) but contains a few security inconsistencies you should address before use: - Do not run this on a shared machine without changes: get-token.js prints the raw access token to stdout and writes it to a temp file in the system temp directory. That token could be captured by logs or read by other local users/processes. Consider editing get-token.js to remove the console.log of the access token and to write the token file with restrictive permissions (e.g., fs.writeFileSync(path, data, { mode: 0o600 })). - If you prefer not to store credentials on disk, set AZURE_* env vars in a secure runtime (CI secret store, environment with restricted access) and avoid running setup.js. - Ensure the Azure App has least privilege: only grant Calendars.Read and User.Read.All as needed, and follow the README's recommendation to apply an App Access Policy in Exchange Online so the app cannot read all mailboxes unless required. Have an admin grant consent rather than using broader rights. - After testing, rotate the client secret if you accidentally exposed it (e.g., pasted it into chat or console logs). Remove the token file from /tmp if it exists. - Minor doc/code mismatches: curl is listed as required but not used by the scripts; SKILL.md mentions a device code flow though the code uses client credentials flow. If you do not control the registry/source, prefer reviewing the code and running it in an isolated environment (container or VM) before giving it production credentials. If you cannot or will not make these changes, treat the skill as risky and avoid installing it on multi-user systems or where console output is logged/collected.

Like a lobster shell, security has layers — review code before you run it.

Runtime requirements

📅 Clawdis
Binsnode, curl
EnvAZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET
Primary envAZURE_CLIENT_SECRET
latestvk979r6wk7awwnk2w07fht916p582306g
361downloads
0stars
3versions
Updated 1mo ago
v1.0.2
MIT-0

Microsoft Graph Calendar — Find Free Slots

Use this skill when the user wants to:

  • Find a time when multiple employees are all free
  • Check if a specific person is available at a given time
  • List upcoming meetings / busy blocks for one or more people
  • Suggest meeting slots across the company

Setup (ทำครั้งแรกครั้งเดียว)

ถ้าผู้ใช้ยังไม่เคย setup หรือระบบแจ้งว่าขาด credentials ให้ทำดังนี้:

  1. ถามผู้ใช้ 3 ค่านี้ทีละค่า:

    • AZURE_TENANT_ID (Azure Portal → Azure Active Directory → Overview)
    • AZURE_CLIENT_ID (App registrations → your app → Application (client) ID)
    • AZURE_CLIENT_SECRET (App registrations → your app → Certificates & secrets)
  2. เมื่อได้ครบแล้ว รันคำสั่ง:

node skills/ms-graph-calendar/scripts/setup.js \
  --tenant-id <AZURE_TENANT_ID> \
  --client-id <AZURE_CLIENT_ID> \
  --client-secret <AZURE_CLIENT_SECRET>

ค่าจะถูกบันทึกไว้ที่ ~/.openclaw/ms-graph-calendar.json (permission 600) และจะถูกโหลดอัตโนมัติทุกครั้งที่ใช้ skill

  1. ทดสอบด้วย:
node skills/ms-graph-calendar/scripts/get-token.js

ถ้าได้ "✅ Token acquired" แปลว่าพร้อมใช้งานแล้ว

App Registration ต้องมี Application Permissions:

  • Calendars.Read — read all users' calendars
  • User.Read.All — list employees
  • Admin ต้อง Grant consent ก่อน

Configuration

Authentication is cached after first login. No environment variables required for device code flow.

For headless/automated operation, set these environment variables:

  • AZURE_CLIENT_ID - Azure AD app client ID
  • AZURE_CLIENT_SECRET - Azure AD app secret
  • AZURE_TENANT_ID - Tenant ID (use "consumers" for personal accounts)

Tools

This skill runs Node.js scripts via bash. Files:

  • scripts/ — Node.js scripts
  • nicknames.md — ตาราง mapping ชื่อเล่น → email (แก้ไขได้เลย)

Instructions

Step 1 — Get Access Token

Before any Graph API call, get an app-only token:

node skills/ms-graph-calendar/scripts/get-token.js

Store the token in a temp variable for subsequent calls.

Step 2 — Parse the User's Request

Extract from the user's message:

  • Who: names or emails of attendees (e.g. "Alice and Bob", "the marketing team")
  • When: date range to search (e.g. "this week", "next Monday", "March 5–7")
  • Duration: how long the meeting should be (default 60 minutes)
  • Timezone: default to Asia/Bangkok if not specified

If any info is missing, ask the user before proceeding.

Step 3 — Resolve Employee Emails

3a. ลองแปลงชื่อเล่นก่อน (เร็วกว่า ไม่ต้องเรียก API):

node skills/ms-graph-calendar/scripts/resolve-nicknames.js --names "แบงค์,มิ้ว,โบ้"

อ่านจาก nicknames.md ในโฟลเดอร์ skill — แก้ไขได้ตรงนั้นเลย

3b. ถ้าหาไม่เจอใน nicknames.md ให้ fallback ไปค้น Graph API:

node skills/ms-graph-calendar/scripts/list-users.js --search "ชื่อ"

Confirm กับ user ถ้ามีคนชื่อเดียวกันหลายคน

Step 4 — Find Free Slots (choose one method)

Method A — findMeetingTimes (best for small groups, ≤10 people):

node skills/ms-graph-calendar/scripts/find-meeting-times.js \
  --attendees "alice@company.com,bob@company.com" \
  --start "2025-03-01T08:00:00" \
  --end "2025-03-01T18:00:00" \
  --duration 60 \
  --timezone "Asia/Bangkok" \
  --max 5

Method B — getSchedule (best for large groups or viewing free/busy blocks):

node skills/ms-graph-calendar/scripts/get-schedule.js \
  --emails "alice@company.com,bob@company.com,carol@company.com" \
  --start "2025-03-01T00:00:00" \
  --end "2025-03-07T00:00:00" \
  --timezone "Asia/Bangkok" \
  --interval 30

Step 5 — Present Results

Format the available slots clearly:

📅 Available slots where everyone is free:

1. Monday 3 Mar · 10:00–11:00
2. Tuesday 4 Mar · 14:00–15:00
3. Wednesday 5 Mar · 09:00–10:00

Which slot works best?

If no slots are found, widen the search window and try again, or report that no common availability exists in that period.


Example Conversations

User: "Find a 1-hour slot this week where Alice, Bob, and Carol are all free" Agent:

  1. Resolves emails for Alice, Bob, Carol
  2. Runs find-meeting-times.js with date range = this Mon–Fri
  3. Returns top 3 available slots

User: "Is John free tomorrow afternoon?" Agent:

  1. Resolves John's email
  2. Runs get-schedule.js for tomorrow 12:00–18:00
  3. Reports free/busy blocks

User: "Show me everyone in the marketing team's availability next week" Agent:

  1. Lists users in the Marketing group via list-users.js --group "Marketing"
  2. Runs get-schedule.js for all their emails
  3. Presents a visual free/busy summary

Error Handling

ErrorCauseFix
401 UnauthorizedToken expired or wrong credentialsRe-run get-token.js, check env vars
403 ForbiddenMissing Admin ConsentAsk IT admin to grant consent in Azure Portal
404 Not FoundUser email doesn't existVerify email via list-users.js
No slots foundEveryone is busyWiden time range or reduce attendees

Security Notes

  • Credentials are read from env vars only — never log or echo them
  • This skill has read-only access to calendars (Calendars.Read)
  • It cannot create, edit, or delete any events
  • To restrict which mailboxes the app can read, ask your IT admin to set an App Access Policy in Exchange Online:
    New-ApplicationAccessPolicy -AppId <ClientId> -PolicyScopeGroupId <GroupId> -AccessRight RestrictAccess
    

Comments

Loading comments...