MeetBetr

MeetBetr for developers

MeetBetr finds the times a group of friends is actually free and turns them into plans they answer in one tap. The MeetBetr connector lets an AI assistant do the same for a person who connects their account.

It's an MCP server with three tools: find free times, propose a plan and check a plan. It is consent-first. An assistant sees only the free windows a person's friends already share with that person, never calendar entries, and nothing is sent until the person confirms.

Connecting

WhatValue
Server URLhttps://mcp.meetbetr.com (also answers at /mcp)
TransportStreamable HTTP. POST JSON-RPC; replies are application/json. Stateless: no session ID, no server-sent stream (GET returns 405).
Protocol versions2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05
AuthorizationOAuth 2.1, authorization code with PKCE (S256). Every request needs Authorization: Bearer ….
Who can connectAnyone with a free MeetBetr account (iPhone app, phone-number sign-in).

An unauthenticated request gets 401 with a WWW-Authenticate header pointing to the resource metadata, so MCP clients discover everything on their own.

Sign-in (OAuth)

EndpointURL
Protected resource metadata (RFC 9728)https://mcp.meetbetr.com/.well-known/oauth-protected-resource
Authorization server metadata (RFC 8414)https://mcp.meetbetr.com/.well-known/oauth-authorization-server
Authorizehttps://mcp.meetbetr.com/authorize
Tokenhttps://mcp.meetbetr.com/token
Dynamic client registration (RFC 7591)https://mcp.meetbetr.com/register
Revocation (RFC 7009)https://mcp.meetbetr.com/revoke

Scopes

ScopeWhat the person is toldTool
availability.readSee when you and your friends are freefind_free_times
plans.readSee your plans and who's repliedcheck_plan
plans.writeSend plans you confirmpropose_plan

People see and disconnect their connected assistants at meetbetr.com/connect. Access also ends if they delete their MeetBetr account.

Tools

Times come back in the person's own time zone as ISO 8601 with offsets, plus a readable when. Friends are named the way they appear in the person's MeetBetr ("Nate", "Lindsay K"), or by a saved crew ("soccer team"). Phone numbers are never accepted or returned.

find_free_times read-only

When the person and some of their friends are all free. It uses only the free windows those friends share with this person. Friends who don't share come back as not_sharing, and assistants must not guess for them. It returns up to 5 windows, spread across different days. If nothing works for everyone, it returns the best windows missing one person, marked missing. With days, it looks for whole free days in a row, up to a year out, for trips and weekends away.

ArgumentTypeNotes
friendsstring[]Up to 20 names or crews. Leave it out to ask who's free: every friend who shares, most people first
duration_minutesinteger15 to 720, default 120
daysinteger1 to 14 whole days in a row, instead of hours
from, toYYYY-MM-DDDefault: today through 2 weeks (2 months with days)
part_of_dayenumany (7am–11pm), morning, lunch, afternoon, evening
days_of_weekenumany, weekdays, weekends
// "When are Nate and Lindsay free for dinner next week?"
{ "friends": ["Nate", "Lindsay"], "part_of_day": "evening", "from": "2026-09-28", "to": "2026-10-04" }
→ { "time_zone": "America/Los_Angeles",
    "windows": [ { "start": "2026-09-29T18:30:00-07:00", "end": "2026-09-29T22:00:00-07:00",
                   "when": "Tue, Sep 29, 6:30 PM – 10:00 PM", "free": ["You", "Nate", "Lindsay"] }, … ],
    "friends": [ { "name": "Nate", "status": "shares_free_times" }, … ], "notes": [] }

propose_plan sends, after confirmation

Always two calls. The first, with the plan, returns a draft and sends nothing. The assistant shows the person exactly what will go out, and only after they say yes calls again with { "draft_id": "…", "confirm": true }. Invitees on MeetBetr get a notification. The result also carries a link and a ready-to-send text for anyone who isn't on MeetBetr, which the person sends themselves. Sending the same draft twice returns the same plan.

ArgumentTypeNotes
titlestringUp to 80 characters
times{ start, duration_minutes? }[]1 to 5 options. start is ISO 8601; without an offset it's read in the person's zone
inviteesstring[]MeetBetr friends or crews, up to 20 people
place, detailsstringOptional
draft_id + confirmstring, booleanThe second call; the draft is good for 30 minutes
{ "title": "Tacos at Guisados", "times": [{ "start": "2026-10-02T19:00", "duration_minutes": 120 }],
  "invitees": ["Nate", "Lindsay"], "place": "Guisados" }
→ { "status": "draft", "draft_id": "…", "summary": "\"Tacos at Guisados\" at Guisados, Fri, Oct 2, 7:00 PM – 9:00 PM. To Nate and Lindsay…",
    "warnings": [], "next_step": "Nothing has been sent. …" }

{ "draft_id": "…", "confirm": true }
→ { "status": "sent", "plan_id": "…", "link": "https://meetbetr.com/p/…", "share_text": "…" }

If a proposed time stopped working between the two calls (a calendar changed), the send is refused with conflict and the next best times. A plan for 8 or more people needs an Event Pass or MeetBetr Plus. Without one it returns needs_pass, and the person finishes it in the app. Assistants never buy anything.

check_plan read-only

How a plan is going: collecting, locked or cancelled, who's in, who can't make it, who hasn't replied (for the plan's host), votes per time, the leading time, and the locked time and place. Pass a plan link, its id, or words from its title. Without plan, it lists the person's current plans.

// "Did everyone reply to taco night?"
{ "plan": "taco night" }
→ { "title": "Taco night", "status": "collecting", "going": ["Marcus", "Tyler"], "cant_make_it": ["Sofia"],
    "waiting_on": ["Kevin"], "leading_time": "Sat, Oct 3, 7:00 PM – 9:00 PM", … }

Errors

Tool failures come back as a normal result with isError: true, a code, and a plain sentence the assistant can say out loud.

CodeMeaning
friend_not_foundNo friend by that name, or more than one; the result lists the closest matches
not_allowedThe person didn't allow this permission when connecting
needs_passA big plan: finish it in the MeetBetr app
conflictA proposed time stopped working; nothing was sent
draft_not_found, draft_expiredMake the draft again
plan_not_foundNo plan the person hosts or was invited to matches
rate_limitedToo many calls or plans; try later
bad_requestAn argument couldn't be read; the message says which

An expired or revoked access token gets HTTP 401; refresh it, or connect again.

Limits

Privacy

See the full privacy policy and terms.

Support

Questions, a pre-registered client, or a test account for review: support@meetbetr.com.