@openavail/mcp
v1.3.0
Published
MCP server for [Openavail](https://openavail.com) — gives AI agents the ability to check availability, create bookings, and manage calendar events on behalf of calendar owners. Works with any MCP-compatible client: Claude Desktop, Claude Code, Cursor, Win
Readme
@openavail/mcp
MCP server for Openavail — gives AI agents the ability to check availability, create bookings, and manage calendar events on behalf of calendar owners. Works with any MCP-compatible client: Claude Desktop, Claude Code, Cursor, Windsurf, and others.
Quickstart
Hosted MCP with OAuth
Hosted MCP is the primary setup path for clients that support remote HTTP MCP and browser-based
OAuth login. Add a remote MCP server named openavail with this URL:
https://mcp.openavail.com/mcpWhen the client opens the browser, sign in to Openavail and approve the connection. Openavail creates
a client-specific backing agent such as Codex MCP or Claude Code MCP. The default OAuth grant is
approval-first: read_freebusy, read_events, and create_booking_proposals. It can read calendar
context and draft booking proposals for approval, but it cannot create holds, book directly, preempt,
or cancel events unless you later change the backing agent's permissions in the Openavail dashboard.
Codex
In Codex, add Openavail as a remote HTTP MCP server:
- Name:
openavail - URL:
https://mcp.openavail.com/mcp - Authentication: OAuth/browser login
After the OAuth approval completes, start with the get-agent-context tool. OAuth-created
user-scoped connections do not need OPENAVAIL_OWNER_EMAIL; Openavail resolves the connected calendar
owner from the signed-in dashboard user.
Claude Code
In Claude Code, add Openavail as a remote HTTP MCP server:
- Name:
openavail - URL:
https://mcp.openavail.com/mcp - Authentication: OAuth/browser login
If your Claude Code build does not support remote HTTP MCP with OAuth, use the stdio setup below with
an OPENAVAIL_API_KEY.
Permission changes and OAuth refresh
If you later grant additional permissions to the hosted MCP backing agent, refresh the OAuth session so the client receives the new grant. In Codex:
codex mcp logout openavail
codex mcp login openavailIf the server was added before OAuth metadata was available, re-add it:
codex mcp remove openavail
codex mcp add openavail --url https://mcp.openavail.com/mcp --oauth-client-id codex
codex mcp login openavailPermission downgrades and revoked credentials fail closed on the server. The refresh step is for newly granted tools becoming usable in the client.
Local stdio fallback
Claude Desktop
Add to your Claude Desktop config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"openavail": {
"command": "npx",
"args": ["-y", "@openavail/mcp"],
"env": {
"OPENAVAIL_API_KEY": "ak_01HX7QQM…",
"OPENAVAIL_REQUESTER_CREDENTIAL": "rc_12345678_…",
"OPENAVAIL_OWNER_EMAIL": "[email protected]"
}
}
}
}Restart Claude Desktop after saving.
Claude Code (CLI)
claude mcp add --transport stdio openavail \
--env OPENAVAIL_API_KEY=ak_01HX7QQM… \
--env [email protected] \
-- npx -y @openavail/mcpCursor / Windsurf / other clients
Add the same JSON block to your client's MCP config file. Config file locations:
| Client | Config file |
|---|---|
| Cursor | .cursor/mcp.json (project) or ~/.cursor/mcp.json (global) |
| Windsurf | .codeium/windsurf/mcp_config.json |
The npm package is scoped. Use @openavail/mcp; the unscoped openavail package is not published.
Environment variables
| Variable | Required | Description |
|---|---|---|
| OPENAVAIL_API_KEY | Required for private owner-scoped tools | Owner-agent API key from the Openavail dashboard. Go to Agents → Register agent, create an agent, then click Create API key. Keys are prefixed ak_. |
| OPENAVAIL_REQUESTER_CREDENTIAL | Optional | Requester credential for public scheduling tools. Keys are prefixed rc_. It proves external requester identity when asking another owner for time; it does not grant calendar access. |
| OPENAVAIL_OWNER_EMAIL | No | Default calendar owner email for private owner-scoped tools. When set, those tools omit the owner_email parameter. Override per-call by passing owner_email explicitly. |
No credential is required for anonymous public scheduling tools. If neither OPENAVAIL_API_KEY nor OPENAVAIL_REQUESTER_CREDENTIAL is set, the server registers public scheduling tools only and calls public scheduling anonymously. If only OPENAVAIL_REQUESTER_CREDENTIAL is set, the server registers public scheduling tools only with verified requester identity. If OPENAVAIL_API_KEY is set, private owner-scoped tools are also registered, and public scheduling tools still use anonymous or requester-credential identity rather than owner authority.
Getting an API key
- Log in to the Openavail dashboard.
- Go to Agents → Register agent and create an agent.
- Click Create API key under the agent.
- Copy the key immediately — it is not shown again.
For a new approval-mode agent using this MCP server, grant read_freebusy and
create_booking_proposals. For trusted auto-booking agents, grant read_freebusy,
create_holds, and create_bookings. Grant read_events only when the agent should see booking titles,
descriptions, and attendees in Openavail responses. Grant preempt only to trusted agents that may
displace lower-priority bookings when rules allow it.
Requester credentials
Requester credentials are different from owner-agent API keys:
OPENAVAIL_API_KEYacts inside the configured owner's account. Use it for private tools such assearch-availability,create-hold,confirm-hold,create-booking-proposal, and calendar-event compatibility tools.OPENAVAIL_REQUESTER_CREDENTIALproves external requester identity for public scheduling tools. It is used when asking another owner for time through their public scheduling boundary. The target owner's policy still decides visibility, review, and auto-book behavior.
Anonymous public scheduling does not need a requester credential. Set OPENAVAIL_REQUESTER_CREDENTIAL when a verified requester should see meeting types or behavior that the target owner has allowed for that requester identity, verified domain, or audience.
Available tools
Start here
For private owner-scoped tools, start by reading the owner context. Public scheduling tools can run
without owner-agent credentials and do not expose this tool unless OPENAVAIL_API_KEY is set.
| Tool | Description |
|---|---|
| get-agent-context | Call this first. Returns the owner's timezone, working hours, slot interval, and all valid meeting class names in one call. Everything you need to make a valid booking request. |
Native tools (Openavail-specific)
| Tool | Description |
|---|---|
| create-booking-proposal | Create an approval-first booking proposal with a curated review set, without creating a hold or calendar event. |
| get-booking-proposal | Fetch a private owner-scoped booking proposal by proposal_id, including owner decision, approval status, candidates, and final booking ID when booked. |
| search-availability | Find capped candidate slots without creating a hold. Pass earliest_start and latest_end — latest_end is when the meeting must end, not start. Use max_results up to 100. |
| create-hold | Reserve a selected candidate or short negotiation window. |
| confirm-hold | Confirm a hold, committing the booking to the calendar. |
| simulate | Preview the arbitration decision without creating anything (Pro plan). |
| get-schedule-rules | Get working hours and slot interval for an owner. |
| list-meeting-classes | List valid meeting class names and their priority/preempt policy. |
| get-pending-notifications | Fetch unread agent notifications (last 7 days). |
| ack-notifications | Acknowledge notifications by ID to mark them as read. |
Public scheduling tools
Use these when the agent is an external requester asking another owner for time. These tools never expose internal proposal IDs, private conflicts, hidden meeting types, raw owner availability, or owner audit history.
| Tool | Description |
|---|---|
| list-public-meeting-types | List public-safe meeting types visible on a public scheduling boundary. Uses anonymous identity or OPENAVAIL_REQUESTER_CREDENTIAL when set. Returns suggested times when the owner enabled them. |
| create-public-booking-proposal | Submit a structured or free-text public booking proposal. requester_contact is the submitter; attendees should include the requester. Returns a safe status and status URL. |
| confirm-public-requester-contact | Confirm the requester-contact email for an anonymous public proposal using the token from the contact verification URL. |
| get-public-booking-proposal-status | Poll safe public status by public proposal access token. |
| withdraw-public-booking-proposal | Withdraw a pending public proposal by public proposal access token. It does not cancel or reschedule booked meetings. |
list-public-meeting-types returns the display name, optional description,
duration, public_meeting_type identifier, and suggestedTimes when configured.
Suggested times are not holds. Use the identifier when calling
create-public-booking-proposal, and use the duration when choosing the request
window. If you choose a suggested time, submit it as the requested_window; Openavail
rechecks the window before the request continues. Owner/admin setup derives the
identifier from the meeting type name by default.
Compatibility tools (Google Calendar MCP-compatible names)
These use the same tool names as google-calendar-mcp so agents targeting that server work without prompt changes.
| Tool | Description |
|---|---|
| list-calendars | List connected calendars for an owner. |
| list-events | List committed bookings in a time window. |
| get-event | Fetch a single booking by ID. |
| create-event | Create a booking directly (no prior hold). |
| update-event | Update a booking's title, description, or attendees. |
| delete-event | Cancel a booking. |
| search-events | Search bookings by title keyword. |
Notes
Always call get-agent-context first. It returns the owner's IANA timezone, working hours, setup warnings, unavailable features, and all valid meeting class names in one call. Use the timezone to convert local times to UTC before any booking call.
latest_end is a deadline, not a start boundary. latest_end is the latest a meeting may end, not start. For a 60-min meeting at 2 pm, set latest_end to at least 3 pm.
Use expiresInSeconds for TTL checks. The create-hold response includes both expiresAt (absolute UTC timestamp) and expiresInSeconds (relative). Use expiresInSeconds for hold freshness and retry decisions; use expiresAt for logging, display, and correlation.
Calendar types: Openavail supports work, personal, and other calendar types per owner. calendar_type is a hint, not a hard requirement. If a user has only connected a personal calendar and you pass calendar_type: "work", the request falls back to the primary calendar and returns the resolved calendar type. Call list-calendars or get-agent-context first to know which types are connected.
Hold TTL: create-hold creates a 5-minute hold. Confirm promptly for human-in-the-loop flows, or the hold will expire.
All times are UTC: Pass start/end in ISO 8601 UTC format (2026-07-01T14:00:00Z). The timezone from get-agent-context tells you the owner's local timezone for conversion.
Rate limits: Per API key, independent of other keys. On a 429 response, read the Retry-After header and wait that many seconds.
| Tool | Limit |
|---|---|
| search-availability | 300 req/min |
| create-hold, confirm-hold, create-event | 120 req/min each |
| All other tools | 600 req/min (shared per server IP) |
