Connect skdul to Claude and other AI assistants for natural-language scheduling.
The skdul MCP (Model Context Protocol) Server lets AI assistants like Claude manage your scheduling through natural language. Instead of clicking through a UI, just tell Claude what you need — "Book a 30-minute call with Jane tomorrow at 2pm" — and it handles the rest.
The server exposes 31 tools across 9 categories, 2 resources, and 42 example prompts. Tools cover everything from profile management to calendar intelligence, smart booking, and async scheduling negotiation. Resources let AI clients read structured data without invoking a tool call.
Authentication is handled automatically via OAuth 2.1 + PKCE when connecting from claude.ai or Claude Code. Session tokens are valid for 2 hours; the server prompts re-authentication when they expire.
Connect from claude.ai, Claude Code, or any MCP-compatible client. All three methods are shown below.
No local setup or API key required — authentication is handled via OAuth.
Enter the MCP server URL:
https://www.skdul.ai/api/mcpNo local setup required — authentication is handled via OAuth on first use.
{
"mcpServers": {
"skdul": {
"url": "https://www.skdul.ai/api/mcp"
}
}
}For any MCP client that supports remote servers via streamable HTTP. Use the URL below in your client's MCP configuration.
https://www.skdul.ai/api/mcp{
"url": "https://www.skdul.ai/api/mcp"
}The MCP server uses OAuth 2.1 + PKCE for authorization. When you first connect from claude.ai or Claude Code, the server redirects you to skdul's authorization page. After you approve, a session token is issued and stored by your MCP client.
| Property | Value |
|---|---|
| Auth flow | OAuth 2.1 with PKCE |
| Token lifetime | 2 hours |
| On token expiry | Claude shows an auth error; click to re-authorize |
| Alternative auth | API key via Authorization: Bearer sk_live_… |
For non-OAuth clients, generate an API key from Dashboard → MCP Server → API Keys and pass it as a Bearer token. The server accepts both OAuth access tokens and API keys.
| Property | Value |
|---|---|
| MCP spec version | 2025-03-26 |
| Transports | Streamable HTTP (primary), SSE (legacy fallback) |
| Server URL | https://www.skdul.ai/api/mcp |
| Local stdio | Not supported — server is cloud-hosted only |
Clients that only support the older SSE transport can still connect using the same URL — the server negotiates the transport automatically during the initialization handshake.
42 example prompts across 9 categories. Hover any prompt to reveal the copy button, then paste it into a Claude conversation with the skdul MCP server connected.
31 tools across 9 categories. Each tool can be invoked by any connected MCP client.
get_profileReturns the authenticated user's full profile including name, username, timezone, branding settings, and plan. No inputs required — always returns the profile of the connected account.
Returns Profile object with id, username, full_name, email, timezone, time_format, brand_color, bio, week_start, avatar_url, plan.
update_profile6 paramsUpdates one or more profile fields. Only include the fields to change — omitted fields stay untouched. Timezone changes affect future slot calculations but do not alter existing bookings.
Returns Updated Profile object.
| Name | Type | Required | Description |
|---|---|---|---|
fullName | string | No | Display name shown on the booking page. |
timezone | string | No | IANA timezone (e.g. America/New_York). |
timeFormat | "12h" | "24h" | No | Clock display format. |
brandColor | string | No | Hex color code (e.g. #E8634A). |
bio | string | No | Short bio for the public booking page. |
weekStart | "sunday" | "monday" | No | First day of the week on calendar views. |
list_event_types1 paramLists all event types (meeting templates) for the authenticated user. Active events are returned by default; pass includeInactive to also retrieve disabled ones.
Returns Array of EventType objects sorted by creation date.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
includeInactive | boolean | No | false | Include disabled event types in results. |
create_event_type10 paramsCreates a new event type. The slug must be unique per user and forms the booking URL path (/{username}/{slug}). Newly created event types are active by default.
Returns The created EventType object.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
title | string | Yes | — | Event title (e.g. '30 Minute Meeting'). |
slug | string | Yes | — | URL slug (e.g. '30min'). Must be lowercase, no spaces. |
durationMinutes | number | Yes | — | Duration in minutes. |
description | string | No | — | Description shown on the booking page. |
locationType | "video" | "phone" | "in_person" | "custom" | No | video | Meeting location type. |
bufferBefore | number | No | 0 | Minutes to block before the meeting. |
bufferAfter | number | No | 0 | Minutes to block after the meeting. |
minimumNotice | number | No | 60 | Minimum advance notice in minutes. |
maxPerDay | number | No | — | Maximum bookings of this type per day. Omit for unlimited. |
color | string | No | — | Display color hex code. |
update_event_type12 paramsUpdates any subset of fields on an existing event type. Use isActive to pause bookings without deleting. Slug changes take effect immediately.
Returns The updated EventType object.
| Name | Type | Required | Description |
|---|---|---|---|
eventTypeId | string | Yes | The event type ID to update. |
title | string | No | Event title. |
slug | string | No | URL slug. |
durationMinutes | number | No | Duration in minutes. |
description | string | No | Booking page description. |
locationType | "video" | "phone" | "in_person" | "custom" | No | Location type. |
bufferBefore | number | No | Buffer minutes before. |
bufferAfter | number | No | Buffer minutes after. |
minimumNotice | number | No | Minimum advance notice in minutes. |
maxPerDay | number | No | Maximum bookings per day. |
color | string | No | Display color hex code. |
isActive | boolean | No | Set to false to stop accepting new bookings. |
delete_event_type1 paramPermanently deletes an event type. Existing confirmed bookings are not affected. Use isActive: false instead if you want to preserve booking history.
Returns { success: true }
| Name | Type | Required | Description |
|---|---|---|---|
eventTypeId | string | Yes | The event type ID to delete. |
get_available_slots4 paramsReturns all open time slots for an event type within a date range. Slots account for working hours, buffer times, existing bookings, and synced external calendar events. Pass the guest's timezone for localised results.
Returns Array of { start: ISO 8601, end: ISO 8601 } objects.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
eventTypeId | string | Yes | — | The event type ID to check availability for. |
startDate | string | Yes | — | Start of date range (YYYY-MM-DD). |
endDate | string | Yes | — | End of date range (YYYY-MM-DD). Max 60-day range. |
timezone | string | No | UTC | IANA timezone for slot times. |
list_bookings4 paramsLists the authenticated user's bookings with optional filters. Returns upcoming confirmed bookings by default, sorted by start time.
Returns Array of Booking objects.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
status | string | No | — | Filter by status: confirmed, cancelled_by_host, cancelled_by_guest, rescheduled, completed, no_show. |
upcoming | boolean | No | true | When true, only return bookings with a future start time. |
guestEmail | string | No | — | Filter to bookings for a specific guest email. |
limit | number | No | 20 | Maximum results to return (max 100). |
get_booking1 paramRetrieves full details for a single booking including nested event type metadata. Use to display confirmation pages or sync to external systems.
Returns Booking object with nested event_types field.
| Name | Type | Required | Description |
|---|---|---|---|
bookingId | string | Yes | The booking ID. |
create_booking8 paramsCreates a confirmed booking for a guest. The slot must be within the event's availability window — call get_available_slots first. Returns an error if the slot is taken. Confirmation emails are sent automatically.
Returns The created Booking object with status: confirmed.
| Name | Type | Required | Description |
|---|---|---|---|
eventTypeId | string | Yes | Event type ID to book. |
startTime | string (ISO 8601) | Yes | Meeting start time in UTC. |
endTime | string (ISO 8601) | Yes | Meeting end time in UTC. |
guestName | string | Yes | Guest's full name. |
guestEmail | string | Yes | Guest's email for confirmations. |
durationMinutes | number | Yes | Duration in minutes — must match event type duration. |
guestTimezone | string | No | Guest's IANA timezone for email formatting. |
guestNotes | string | No | Optional notes from the guest. |
cancel_booking2 paramsCancels a confirmed booking, removes the calendar event, deletes the Zoom meeting if applicable, and sends a cancellation email to the guest. This action is irreversible.
Returns Updated Booking object with status: cancelled_by_host.
| Name | Type | Required | Description |
|---|---|---|---|
bookingId | string | Yes | The booking ID to cancel. |
reason | string | No | Cancellation reason included in the guest email. |
reschedule_booking3 paramsReschedules a booking to a new time. Creates a new confirmed booking, marks the original as rescheduled, and sends rescheduling emails. The new slot must be available.
Returns The new Booking object at the rescheduled time.
| Name | Type | Required | Description |
|---|---|---|---|
bookingId | string | Yes | The booking ID to reschedule. |
newStartTime | string (ISO 8601) | Yes | New start time in UTC. |
newEndTime | string (ISO 8601) | Yes | New end time in UTC. |
get_availability_scheduleReturns the host's weekly availability schedule — the days and hours during which bookings are accepted. Used alongside buffer times and external calendar data to compute open slots.
Returns Schedule object with name, timezone, and rules array (dayOfWeek, startTime, endTime, isEnabled).
update_availability_schedule5 paramsReplaces the weekly working hour schedule. This is a full replacement — send all rules you want active. Days not included will block all bookings.
Returns Updated Schedule object with new rules.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
rules | AvailabilityRule[] | Yes | — | Full set of availability rules. Replaces all existing rules. |
rules[].dayOfWeek | number (0–6) | Yes | — | Day of week. 0 = Sunday … 6 = Saturday. |
rules[].startTime | string (HH:MM) | Yes | — | Start of availability window in 24h format. |
rules[].endTime | string (HH:MM) | Yes | — | End of availability window in 24h format. |
rules[].isEnabled | boolean | No | true | Set to false to block this day without removing the rule. |
browse_booking_pages1 paramDiscovers a host's public event types by username before attempting a booking. Returns available meeting types, durations, and booking page URLs.
Returns Array of public EventType objects with booking page URLs.
| Name | Type | Required | Description |
|---|---|---|---|
username | string | Yes | The host's skdul username (e.g. 'janedoe'). |
find_and_book_best_slot15 paramsFinds the optimal time slot with a host using preference-aware scoring, then optionally creates the booking. Runs as a dry run by default — set dryRun: false to confirm the booking. Supports rich scheduling constraints for time-of-day and day-of-week preferences.
Returns Best slot with score, and Booking object if dryRun is false.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
bookingPageUrl | string | No | — | Full booking page URL. Use instead of username + eventSlug. |
username | string | No | — | Host username. Required if bookingPageUrl not provided. |
eventSlug | string | No | — | Event slug. Required if bookingPageUrl not provided. |
guestName | string | No | — | Guest name for the booking. |
guestEmail | string | No | — | Guest email for confirmation. |
guestNotes | string | No | — | Notes to include with the booking. |
guestTimezone | string | No | — | Guest IANA timezone. |
preferMorning | boolean | No | — | Score morning slots higher. |
preferAfternoon | boolean | No | — | Score afternoon slots higher. |
avoidDays | number[] | No | — | Days of week to avoid (0 = Sunday … 6 = Saturday). |
preferDays | number[] | No | — | Preferred days of week. |
earliestHour | number (0–23) | No | — | Earliest acceptable hour for a meeting start. |
latestHour | number (0–23) | No | — | Latest acceptable hour for a meeting start. |
withinDays | number | No | 14 | How many days ahead to search for slots. |
dryRun | boolean | No | true | If true, returns the best slot without booking. Set to false to confirm. |
get_scheduling_preferences3 paramsRetrieves active scheduling preference rules. Rules can be explicit (set manually) or learned (inferred by AI from booking history). These rules power the slot scoring engine.
Returns Array of Preference objects with rule_type, rule payload, priority, and is_learned flag.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
contactEmail | string | No | — | Filter to preferences scoped to a specific contact. |
ruleType | string | No | — | Filter by type: time_preference, day_preference, contact_rule, focus_block, max_meetings, buffer_rule, duration_rule, custom. |
includeLearnedRules | boolean | No | true | Whether to include AI-inferred rules alongside explicit ones. |
set_scheduling_preference7 paramsCreates a scheduling preference rule. Higher priority rules override lower ones when they conflict. Contact-scoped rules only apply when scheduling with that specific contact.
Returns The created Preference object.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
ruleType | string | Yes | — | Rule category: time_preference, day_preference, contact_rule, focus_block, max_meetings, buffer_rule, duration_rule, custom. |
rule | object | Yes | — | Rule payload. Structure varies by ruleType (e.g. { preferMorning: true } for time_preference). |
contactEmail | string | No | — | Scope this rule to a specific contact. |
contactCategory | string | No | — | Scope to a category of contacts (e.g. VIP, teammate). |
eventTypeId | string | No | — | Scope to a specific event type. |
priority | number (1–100) | No | 5 | Rule priority. Higher values take precedence. |
description | string | No | — | Human-readable label for this rule. |
delete_scheduling_preference1 paramDeletes a preference rule. Takes effect immediately — subsequent slot scoring calls will no longer apply this rule. Learned rules can also be deleted.
Returns { success: true }
| Name | Type | Required | Description |
|---|---|---|---|
preferenceId | string | Yes | The preference rule ID to delete. |
get_scheduling_insights2 paramsReturns AI-computed patterns from booking history: busiest days, peak hours, back-to-back frequency, and weekly load. Each insight includes a confidence score (0–1). Pass recompute: true to refresh stale data.
Returns Array of Insight objects with insightType, summary, data payload, and confidence score.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
insightType | string | No | — | Filter to a specific type: busiest_day, peak_hours, back_to_back, weekly_load, duration_pattern. |
recompute | boolean | No | false | Recompute from the last 90 days of bookings before returning. |
get_contact_context1 paramReturns the full scheduling history and learned context for a contact — past bookings, observed time preferences, and contact-scoped preference rules. Use before creating a scheduling request to find the most convenient times.
Returns ContactContext with email, totalMeetings, preferredDays, preferredHourRange, recentBookings, and rules.
| Name | Type | Required | Description |
|---|---|---|---|
contactEmail | string | Yes | The contact's email address. |
analyze_calendar_health3 paramsComputes a weighted health score (0–100) for your calendar over a date range. The score factors in meeting density, back-to-back sequences, missing buffers, and available focus time. Also returns actionable text recommendations.
Returns CalendarHealthResult with score, totalMeetings, totalHoursBooked, backToBackCount, focusTimeHours, overbookedDays, and recommendations array.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
startDate | string | No | 14 days ago | Start of analysis range (YYYY-MM-DD). |
endDate | string | No | 14 days ahead | End of analysis range (YYYY-MM-DD). |
timezone | string | No | UTC | IANA timezone for day boundary calculations. |
detect_conflicts2 paramsFinds double-booked or overlapping events within a date range. Returns each conflicting pair with the specific overlap duration in minutes.
Returns Object with conflicts array (eventA, eventB, overlapMinutes) and a total count.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
startDate | string | No | today | Start of detection range (YYYY-MM-DD). |
endDate | string | No | 7 days ahead | End of detection range (YYYY-MM-DD). |
get_week_summary2 paramsReturns a daily breakdown of a single week — meeting count, total hours, and back-to-back sequences per day. Includes warnings for overloaded days. Defaults to the current week.
Returns WeekSummary with totalMeetings, totalHours, and byDay array with per-day stats and warnings.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
weekOf | string | No | current week | Any date within the target week (YYYY-MM-DD). |
timezone | string | No | UTC | IANA timezone for day boundary calculations. |
find_focus_time6 paramsFinds uninterrupted blocks of free time suitable for deep work. Filters out blocks shorter than minBlockMinutes. Optionally restricts results to a preferred hour range.
Returns Object with focusBlocks array (start, end, durationMinutes, date) and totalFocusHours.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
minBlockMinutes | number | No | 90 | Minimum block duration in minutes. |
startDate | string | No | today | Start of search range (YYYY-MM-DD). |
endDate | string | No | 7 days ahead | End of search range (YYYY-MM-DD). |
preferredStartHour | number (0–23) | No | — | Only return blocks starting at or after this hour. |
preferredEndHour | number (0–23) | No | — | Only return blocks ending at or before this hour. |
timezone | string | No | UTC | IANA timezone for hour filtering. |
suggest_reschedules3 paramsIdentifies back-to-back meetings and overloaded days, then suggests which specific bookings to move and better alternative times. Powered by the same scoring engine as smart booking.
Returns Object with suggestions array — each has the booking to move, the reason, and up to 3 suggestedSlots.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
date | string | No | today | Focus suggestions around this date (YYYY-MM-DD). |
maxSuggestions | number | No | 5 | Maximum number of suggestions to return. |
timezone | string | No | UTC | IANA timezone for suggestion context. |
create_scheduling_request12 paramsSends an async scheduling request to another skdul user. The engine automatically finds mutual availability and proposes a matched slot. A notification email goes to the target. Returns 400 if no mutual slot is found.
Returns SchedulingRequest with requestId, status: pending, matchedSlotStart, matchedSlotEnd.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
targetUsername | string | Yes | — | The username of the person you want to schedule with. |
title | string | Yes | — | Meeting title shown to the recipient. |
durationMinutes | number | No | 30 | Desired meeting duration in minutes. |
locationType | "video" | "phone" | "in_person" | No | video | Preferred meeting format. |
notes | string | No | — | Optional context message to the recipient. |
preferMorning | boolean | No | — | Prefer morning slots for mutual availability search. |
preferAfternoon | boolean | No | — | Prefer afternoon slots. |
avoidDays | number[] | No | — | Days of week to avoid (0 = Sunday … 6 = Saturday). |
preferDays | number[] | No | — | Preferred days of week. |
earliestHour | number (0–23) | No | — | Earliest acceptable meeting hour. |
latestHour | number (0–23) | No | — | Latest acceptable meeting hour. |
withinDays | number | No | 14 | Days ahead to search for mutual availability. |
list_scheduling_requests3 paramsLists scheduling requests where you are the initiator or recipient. Use direction to filter to sent or received. Pending requests are awaiting a response.
Returns Array of SchedulingRequest objects sorted by creation date descending.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
direction | "sent" | "received" | "all" | No | all | Which requests to return. |
status | string | No | — | Filter by status: pending, accepted, rejected, cancelled, expired. |
limit | number | No | 20 | Maximum results to return. |
get_scheduling_request1 paramRetrieves full details for a specific scheduling request including the matched slot and current status.
Returns SchedulingRequest object with all fields.
| Name | Type | Required | Description |
|---|---|---|---|
requestId | string | Yes | The scheduling request ID. |
respond_to_scheduling_request3 paramsAccepts or rejects an incoming scheduling request. Accepting automatically creates a confirmed booking at the matched slot and notifies the initiator. Only the recipient can respond.
Returns If accepted: Booking object. If rejected: SchedulingRequest with status: rejected.
| Name | Type | Required | Description |
|---|---|---|---|
requestId | string | Yes | The scheduling request ID to respond to. |
action | "accept" | "reject" | Yes | Whether to accept or reject the request. |
rejectionReason | string | No | Optional reason sent to the initiator when rejecting. |
cancel_scheduling_request2 paramsCancels an outgoing scheduling request that has not yet been accepted. Only the initiator can cancel. If already accepted, cancel the resulting booking via cancel_booking instead.
Returns SchedulingRequest with status: cancelled.
| Name | Type | Required | Description |
|---|---|---|---|
requestId | string | Yes | The scheduling request ID to cancel. |
reason | string | No | Optional cancellation reason. |
Resources are read-only MCP primitives that AI clients can fetch without invoking a tool. Reference them to give Claude a quick snapshot of your scheduling context at the start of a conversation.
skdul://booking-pagetext/plainBooking Page URL
Returns the authenticated user's public booking page URL. Use this when an AI assistant needs to share the booking link in a conversation or email draft.
Example response
"https://skdul.ai/janedoe"skdul://dashboard-summaryapplication/jsonDashboard Summary
Returns a JSON snapshot of the user's current scheduling state: upcoming bookings (next 7 days), active event types, and the next scheduled meeting. Useful for briefing an AI assistant at the start of a session.
Example response
{
"upcomingBookings": [
{
"id": "bkg_uuid",
"guestName": "John Smith",
"startTime": "2026-05-28T14:00:00Z",
"eventTitle": "30 Minute Meeting"
}
],
"activeEventTypes": [
{ "id": "evt_uuid", "title": "30 Minute Meeting", "slug": "30min" }
],
"nextBooking": {
"guestName": "John Smith",
"startTime": "2026-05-28T14:00:00Z"
}
}Set up your booking page in two minutes. No credit card required.
Start scheduling with AI