Connect your agent

Avail serves a remote MCP endpoint over Streamable HTTP. Your agent adds that URL, then signs in with Avail's OAuth and consent screens. You need an Avail account first, or you can create one when the sign-in page appears.

MCP server URL

Use this public URL. It is the resource advertised by Avail's OAuth metadata.

https://avail-cal.com/mcp

Unauthenticated requests return 401 and start the sign-in flow. GET is not used; the server answers GET with 405 and Allow: POST.

Claude (desktop or web)

Claude's custom connectors are the path for this remote server, on claude.ai and Claude Desktop. Remote connectors are added on your Claude account (Customize → Connectors), not as a local command in claude_desktop_config.json.

  1. Open Customize → Connectors.
  2. Add a custom connector. Name it Avail.
  3. Paste https://avail-cal.com/mcp and continue.
  4. Keep the detected authentication (OAuth). Sign in when Claude asks.

Claude also has a prefilled add-connector link: Add Avail in Claude. Exact menu labels can differ by plan; if you do not see custom connectors, use the Connectors settings Claude shows for your account.

ChatGPT

ChatGPT's screens for a custom MCP server have been moving (Plugins, connectors, or Developer mode, depending on your plan). The stable part is: add a custom MCP server or connector, paste the Avail URL above, choose OAuth if asked, then complete Avail sign-in and Allow.

We have not verified every ChatGPT plan's current menu names in this app. If your account cannot add a custom MCP URL, that is a ChatGPT limitation, not a missing Avail setting.

Cursor

Add a remote server in Cursor MCP settings, or put this in mcp.json (project .cursor/mcp.json or your user MCP config):

{
  "mcpServers": {
    "avail": {
      "url": "https://avail-cal.com/mcp"
    }
  }
}

Cursor should open a browser for Avail sign-in and consent. Enable the Avail server in the MCP list after it connects.

Any MCP client

Point the client at the URL as a Streamable HTTP (POST) server. Avail supports OAuth with dynamic client registration. The client should follow the 401 WWW-Authenticate challenge to Avail's authorization server, then open a browser for you to sign in and allow access. If your client only supports local stdio servers, it cannot use this endpoint.

Sign-in and consent

Unauthenticated authorize requests go to /sign-in with copy that you are connecting an MCP client. Sign in or sign up, then Avail continues the authorize request.

Next you see Authorize MCP client at /consent. It shows the email you are signed in as, the client id (or “an MCP client”), and the requested scopes (often openid profile email). Choose Allow or Deny. Allow sends you back to the client with an authorization code. Deny rejects the client. Cancel goes to /app without finishing.

Tools the agent gets

These are the tools registered on the Avail MCP server today. They run as the signed-in user after you Allow.

  • whoami

    Who am I

    Return the signed-in user's id, email, and name.

    Inputs: None.

  • create_intent

    Create intent

    Create a scheduling intent for the signed-in user and save their availability windows. Use this when they want to plan something (coffee, dinner, a call) and get a shareable link. Required: title, timezone (IANA, e.g. America/Los_Angeles), and availability: [{ start, end }] as ISO 8601 datetimes. Prefer offsets (2026-10-21T14:00:00-07:00); datetimes without an offset are interpreted in timezone. end must be after start; at least one window is required. Optional: description, type (free text such as coffee or call), duration_minutes, max_plans. max_plans=1 is a one-off (first booked slot closes it); omit max_plans for an open-ended intent. Before calling, use list_my_free_busy for the same windows and avoid overlapping busy times. To change those windows later, use set_intent_availability — do not create a second intent. Returns the intent id, the public URL (/intent/{id}), max_plans, saved windows, and any busy conflicts from Google Calendar / Avail calendars (conflicts do not block creation).

    Inputs: Required: title, timezone, availability[{ start, end }]. Optional: description, type, duration_minutes, max_plans.

  • list_my_intents

    List my intents

    List intents the signed-in user owns or participates in, newest first. Returns id, title, status, type, availability_type (specific_dates or days_of_week), respondent_count (including guests), max_plans, public URL, booked plans, and remaining open windows for each. No input required.

    Inputs: None.

  • get_intent

    Get intent

    Fetch one intent by id if the signed-in user is a participant (owner or invitee). Returns the intent (including type, duration_minutes, max_plans, status, and public URL), participants (user_id, name, role — no emails), each person's availability blocks (user_id is null for named guests; guest_name is set instead), booked plans, and remaining open windows. To update the signed-in user's own availability, use set_intent_availability. Required: id (UUID).

    Inputs: Required: id (UUID).

  • set_intent_availability

    Set intent availability

    Update the signed-in user's own availability on an existing intent they own or participate in. Never edits other users' or guests' rows. Creates the user's intent_availability row if they do not have one. Required: intent_id (UUID or public URL such as https://avail-cal.com/intent/{id}) and timezone (IANA). windows are [{ start, end }] ISO 8601 datetimes; prefer offsets. Naive datetimes use timezone. Default: replace only the local dates (specific_dates) or weekdays (days_of_week) that windows or clear touch, so setting Sunday 5-9pm leaves Saturday and Monday alone. Set replace_all=true to replace every existing window. clear is YYYY-MM-DD for specific_dates, or a weekday name/number (sunday or 0) for days_of_week, to remove that day. Pass replace_all=true with empty windows to clear everything. Uses the same save path as the share page (jsonb blocks + intent_availability_blocks UTC rows). The intent's availability type (specific_dates or days_of_week) is taken from the owner row. Returns the saved blocks, UTC windows, group overlap_windows, remaining open_windows, and everyone's availability like get_intent.

    Inputs: Required: intent_id (UUID or /intent/{id} URL), timezone. Optional: windows[{ start, end }], replace_all, clear.

  • book_plan

    Book plan

    Book a plan (one slot) on an intent for the signed-in user. The slot must fall inside the owner's remaining availability, last duration_minutes when that is set, and not overlap an existing non-cancelled plan. Creates plan participants for the booker and the intent owner. A one-off intent (max_plans=1) becomes scheduled once booked; an open-ended intent stays gathering. After the booking commits, writes a Google Calendar event for each participant who turned on writing (send_updates none — no invitation emails). A Google failure does not undo the booking. Required: intent_id (UUID) and start (ISO 8601). end is required when the intent has no duration_minutes; otherwise it is inferred. Optional timezone (IANA) is used for naive datetimes; defaults to the owner's availability timezone. Optional rrule is a validated RFC 5545 RRULE (timezone required when rrule is set).

    Inputs: Required: intent_id, start. end is required when the intent has no duration_minutes. Optional: timezone, rrule.

  • cancel_plan

    Cancel plan

    Cancel a booked plan the signed-in user participates in. Sets the plan status to cancelled so the slot is free again. If the intent had closed because max_plans was reached, it reopens. Deletes the Google Calendar event for participants who turned on writing (send_updates none — no cancellation emails unless they opted in separately). Required: plan_id (UUID).

    Inputs: Required: plan_id (UUID).

  • update_plan

    Update plan

    Update a booked plan the signed-in user participates in. Optional: start, end, timezone (IANA), rrule (validated RFC 5545). timezone is required when rrule is set. Required: plan_id (UUID).

    Inputs: Required: plan_id. Optional: start, end, timezone, rrule.

  • create_calendar_event

    Create calendar event

    Create an event on the signed-in user's Avail calendar. Required: title, start, end. Optional: timezone (IANA), rrule (validated RFC 5545). timezone is required when rrule is set. Returns the stored event, including rrule.

    Inputs: Required: title, start, end. Optional: timezone, rrule.

  • update_calendar_event

    Update calendar event

    Update an Avail calendar event the signed-in user owns. Required: event_id (UUID, or seriesId:originalStartAt for an occurrence). Optional: title, start, end, timezone, rrule, original_start_at, scope. scope is this (exception), following (split series), or all (update the series). Use this/following/all when the event repeats.

    Inputs: Required: event_id. Optional: title, start, end, timezone, rrule, original_start_at, scope (this | following | all).

  • delete_calendar_event

    Delete calendar event

    Delete an Avail calendar event the signed-in user owns. Required: event_id. Optional: original_start_at, scope. scope this writes a cancelled exception; following truncates the series; all deletes the series and its exceptions.

    Inputs: Required: event_id. Optional: original_start_at, scope (this | following | all).

  • list_my_events

    List my events

    List the signed-in user's Avail calendar events in a time range, including events synced from Google Calendar calendars they selected. Recurring series are expanded; each occurrence includes rrule, recurringEventId (series id), and originalStartAt so you can edit or delete it with scope this/following/all. Required: from, to (ISO 8601). Syncs Google events for that window when connected. Use this (or list_my_free_busy) before create_intent so availability avoids conflicts.

    Inputs: Required: from, to (ISO 8601).

  • list_my_free_busy

    List my free/busy

    Return busy intervals for the signed-in user in a time range. Uses Google Calendar freeBusy when connected, plus local Avail calendar events marked busy. Required: from, to (ISO 8601). Call this before create_intent and do not propose times that overlap busy periods.

    Inputs: Required: from, to (ISO 8601).

  • create_my_event

    Create my Google event

    Create an event on the signed-in user's chosen Google write calendar. Required: title, start, end, timezone (IANA). Optional: description, attendee_emails, send_updates. send_updates defaults to none — do not send Google invitations unless the user explicitly asked. The user must have turned on writing and chosen a write calendar. Returns the Google event id, times, and htmlLink.

    Inputs: Required: title, start, end, timezone. Optional: description, attendee_emails, send_updates (none | all | externalOnly).

  • update_my_event

    Update my Google event

    Update an event Avail created on the signed-in user's write calendar. Required: google_event_id. Optional: title, start, end, timezone, description, attendee_emails, send_updates. When changing the time, pass start, end, and timezone together. send_updates defaults to none.

    Inputs: Required: google_event_id. Optional: title, start, end, timezone, description, attendee_emails, send_updates.

  • delete_my_event

    Delete my Google event

    Delete an event on the signed-in user's write calendar. Required: google_event_id. send_updates defaults to none (do not email guests unless the user asked).

    Inputs: Required: google_event_id. Optional: send_updates.