api-patterns
3CX's native PBX MCP server: the per-PBX endpoint shape (every PBX is its own FQDN and its own OAuth authorization server — there is no shared mcp.3cx.com),…
Exchange Online calendars through Microsoft Graph: event retrieval and date-range queries, free/busy and availability lookup, meeting and Teams-meeting creation, room and equipment resource bookings, calendar permissions, and the Graph scopes and error causes involved.
$ npx -y skills add wyre-technology/msp-claude-plugins --skill calendar --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/calendarContext preview
The summary Claude sees to decide when to auto-load this skill.
Exchange Online calendars through Microsoft Graph: event retrieval and date-range queries, free/busy and availability lookup, meeting and Teams-meeting creation, room and equipment resource bookings, calendar permissions, and the Graph scopes and error causes involved.
name: "Microsoft 365 Calendar" description: > Exchange Online calendars through Microsoft Graph: event retrieval and date-range queries, free/busy and availability lookup, meeting and Teams-meeting creation, room and equipment resource bookings, calendar permissions, and the Graph scopes and error causes involved. when_to_use: >- When viewing events, finding free/busy times, creating meetings, managing room bookings, or checking a user's schedule. Use when: m365 calendar, outlook calendar, calendar events m365, meeting schedule m365, find availability m365, room booking m365, m365 free busy, teams meeting create, or calendar permissions.
Microsoft 365 calendar is powered by Exchange Online and surfaced through Microsoft Graph. For MSPs, calendar tasks include troubleshooting scheduling issues, creating meetings on behalf of users, managing room resources, and checking user availability during support incidents.
"Schedule a meeting" routes three different ways depending on who picks the time. Here, *you* pick it and write the event straight into a mailbox:
scheduling request tied to a PSA ticket is what TimeZest is for; use the `timezest` plugin (`timezest-scheduling`). Writing the event directly here bypasses the PSA workflow and the customer's choice.
window is a PSA service call, which carries the billing and dispatch record a calendar event does not; use the `autotask` plugin (`autotask-service-calls`) or the equivalent PSA plugin.
plugin.
Note also that a TimeZest "resource" is a technician or team, while a resource here is a room or equipment mailbox — they are not the same object.
GET /v1.0/users/{userId}/calendar/events?$select=id,subject,start,end,organizer,attendees,isOnlineMeeting,location&$orderby=start/dateTime&$top=10GET /v1.0/users/{userId}/calendarView?startDateTime=2024-01-15T00:00:00Z&endDateTime=2024-01-22T00:00:00Z&$select=subject,start,end,organizer,attendees,isOnlineMeeting> Use `calendarView` (not `/events`) for date-range queries — it correctly expands recurring events.
Get availability for a set of users:
POST /v1.0/users/{userId}/calendar/getSchedule
Content-Type: application/json
{
"schedules": ["user1@contoso.com", "user2@contoso.com"],
"startTime": { "dateTime": "2024-01-20T08:00:00", "timeZone": "Eastern Standard Time" },
"endTime": { "dateTime": "2024-01-20T17:00:00", "timeZone": "Eastern Standard Time" },
"availabilityViewInterval": 30
}**Response:**
{
"value": [
{
"scheduleId": "user1@contoso.com",
"availabilityView": "000022220000",
"scheduleItems": [
{
"status": "busy",
"start": { "dateTime": "2024-01-20T10:00:00" },
"end": { "dateTime": "2024-01-20T11:00:00" }
}
]
}
]
}`availabilityView` is a string where each character represents a 30-min slot: `0`=free, `1`=tentative, `2`=busy, `3`=out-of-office, `4`=working elsewhere.
POST /v1.0/users/{organizerId}/events
Content-Type: application/json
{
"subject": "IT Onboarding — Jane Smith",
"start": { "dateTime": "2024-01-20T10:00:00", "timeZone": "Eastern Standard Time" },
"end": { "dateTime": "2024-01-20T11:00:00", "timeZone": "Eastern Standard Time" },
"attendees": [
{ "emailAddress": { "address": "jsmith@contoso.com" }, "type": "required" },
{ "emailAddress": { "address": "itadmin@contoso.com" }, "type": "required" }
],
"isOnlineMeeting": true,
"onlineMeetingProvider": "teamsForBusiness",
"body": { "contentType": "HTML", "content": "<p>IT onboarding session agenda...</p>" }
}GET /v1.0/places/microsoft.graph.room?$select=id,displayName,emailAddress,capacity,building,floorNumber
Use `getSchedule` with the room's email address as a schedule ID (same as users above).
POST /v1.0/users/{userId}/events/{eventId}/cancel
Content-Type: application/json
{
"comment": "Meeting has been rescheduled. New invite to follow."
}PATCH /v1.0/users/{userId}/events/{eventId}
Content-Type: application/json
{
"subject": "Updated: IT Onboarding — Jane Smith",
"start": { "dateTime": "2024-01-21T14:00:00", "timeZone": "Eastern Standard Time" },
"end": { "dateTime": "2024-01-21T15:00:00", "timeZone": "Eastern Standard Time" }
}1. Get list of required attendees 2. Call `getSchedule` for all attendees + desired room 3. Parse `availabilityView` strings to find overlapping free slots 4. Return top 3 options within the user's working hours
When setting OOO (via mailbox settings), also check if the user has events during their absence:
1. Get events in the OOO date range 2. List events with other attendees — these may need cancellation or reassignment 3. Cancel/update events as needed 4. Set OOO via mailbox settings
Recurring events are expanded in `calendarView` results. Each instance has:
To update all future instances: `PATCH` the series master. To update only one instance: `PATCH` the specific occurrence.
| Error | Cause | Resolution | |-------|-------|------------| | `ErrorCalendarNotFound` | User has no calendar (no Exchange license) | Assign Excha
One command to supercharge Claude Code for MSP workflows. Then restart Claude Code. That's it. Documentation: mcp.wyre.ai
Repo: wyre-technology/msp-claude-plugins
3CX's native PBX MCP server: the per-PBX endpoint shape (every PBX is its own FQDN and its own OAuth authorization server — there is no shared mcp.3cx.com),…
3CX's live-operations surface: read-only visibility into active calls, recordings, voicemail, department and queue membership, and forwarding/presence…
3CX's read-only directory surface: resolving a caller by email or by exact extension, searching the PBX's own phonebooks, searching contacts synced from an…
3CX's system-and-configuration surface: server time, PBX event log and application log search, service status, database schema and the read-only SELECT-only…
Abnormal Security abuse mailbox cases: user-reported email submissions, case statuses and judgments, the case lifecycle, bulk and remediation actions, and…
Abnormal Security message analysis: message retrieval, email header inspection, attachments, sender reputation, delivery context, and SPF/DKIM/DMARC…