Your AI agent can draft emails, search the web, summarize a 40-page PDF, and write code. Then someone asks it to "find a time with Sarah and James next week" and it confidently books a slot during Sarah's all-hands meeting.
This isn't a reasoning failure. The LLM didn't get confused. It's an API design problem — calendar APIs were built for humans navigating UIs, not for agents making sequential tool calls. And the gap between what those APIs expose and what an agent needs to do reliable scheduling is wider than it looks.
The real reason: calendar APIs aren't built for agents
To find mutual availability for two people using raw Google Calendar or Outlook, an agent has to:
Authenticate with OAuth for each person (more on this in a moment)
Fetch each person's calendar events for the target week
Parse the free/busy data into usable windows
Cross-reference working hours per timezone
Apply buffer preferences (no back-to-back meetings, no 8am calls)
Rank the resulting slots by quality
Handle pagination if there are many events
Present options in a format the user can act on
That's 6–8 steps of stateful tool calls before a single time is suggested. Each step is a new opportunity to hallucinate or fail silently.
Most agents either skip steps and guess, or collapse under the complexity of multi-party coordination. Add a third person across a different timezone and the combinatorial complexity quickly exceeds what fits cleanly in a single agent loop.
There are four specific failure modes:
OAuth redirect flows — agents can't click "Allow." Every major calendar API requires a browser-based OAuth flow that's simply incompatible with agentic tool use.
Raw free/busy without scoring — the API gives you busy blocks, not ranked availability. The agent has to invent its own ranking logic or just pick the first open slot.
Timezone math — LLMs are notoriously unreliable at timezone arithmetic. A slot that looks available in UTC might be 11pm for one participant.
Multi-party coordination — four people across three timezones isn't just harder, it's categorically different. The intersection of constraints doesn't fit neatly into a prompt.
What a scheduling API for agents actually looks like
The fix isn't a smarter agent — it's an API designed around how agents actually work.
MeetSync is a scheduling API built on four principles:
API key auth, not OAuth. A single header: X-API-Key: your-key. No redirect flows, no token refresh, no browser required.
Explicit timezone offsets in every field. Every datetime in every response includes a full ISO 8601 offset — 2025-09-22T10:00:00-04:00, not 10:00:00. The agent never has to infer a timezone.
UUIDs as stable references. Participants, proposals, and bookings are identified by UUIDs throughout. The agent can reference the same entity across multiple tool calls without re-fetching or re-resolving names.
Scored slot output. Instead of raw free/busy data, findMutualAvailability returns ranked slots with a 0–1 score combining working hours fit (0.5), buffer preference fit (0.3), and daily meeting load (0.2). The agent picks from a ranked list — it doesn't compute one.
Error responses include a code, message, and details field that tells the agent exactly what failed and how to fix it — not a generic 400.
Five tool calls from "schedule a meeting" to confirmed booking
Here's what the full flow looks like when an agent receives: "Schedule a 30-minute call with Sarah and James next week."
Call 1 — Register participants (if not already registered)
createParticipant → { id: "sarah-uuid", name: "Sarah", email: "sarah@..." }
createParticipant → { id: "james-uuid", name: "James", email: "james@..." }
Call 2 — Find mutual availability
json// Tool call
{
"tool": "findMutualAvailability",
"input": {
"participantIds": ["sarah-uuid", "james-uuid"],
"durationMinutes": 30,
"startDate": "2025-09-22",
"endDate": "2025-09-26",
"limit": 5
}
}
// Response
{
"slots": [
{ "start": "2025-09-22T10:00:00-04:00", "end": "2025-09-22T10:30:00-04:00", "score": 0.91 },
{ "start": "2025-09-22T14:00:00-04:00", "end": "2025-09-22T14:30:00-04:00", "score": 0.84 },
{ "start": "2025-09-23T11:00:00-04:00", "end": "2025-09-23T11:30:00-04:00", "score": 0.79 }
]
}
One call. Ranked results. No availability reasoning required from the agent.
**Call 3 — Confirm with the user, then book**
createBooking → {
organizerParticipantId: "sarah-uuid",
participantIds: ["james-uuid"],
startTime: "2025-09-22T10:00:00-04:00",
endTime: "2025-09-22T10:30:00-04:00"
}
The agent's job throughout is orchestration — not reasoning about calendars. The API handles all the availability intelligence.
Setting it up: MCP server, Claude tool use, LangChain
There are three ways to connect MeetSync to your agent:
- MCP server (Claude Desktop and any MCP-compatible agent) bashnpx mcp-meetsync Set MEETSYNC_API_URL and MEETSYNC_API_KEY as environment variables and all 19 endpoints are immediately available as named tools. No code required.
- Claude tool use (TypeScript) Define the tools using the JSON schemas in docs/tool-definition.md and pass them to the Anthropic client. The full TypeScript agentic loop is in the tutorial.
- LangChain (Python) Three @tool functions wrapping the MeetSync endpoints, passed to create_tool_calling_agent. The full Python example with AgentExecutor is in the tutorial. Copy-paste definitions for all three are in docs/tool-definition.md.
The proposal workflow: let participants vote before booking
Sometimes the agent is acting on behalf of an organizer who can't commit for the invitees. In that case, use the proposal workflow instead of booking directly.
It's two extra tool calls: createProposal with a set of candidate slots, then respondToProposal once per participant to record their preference. Once all participants have accepted the same slot, the proposal moves to accepted and you call createBooking with the proposalId and acceptedSlotId.
This is useful for external meetings, cross-team scheduling, or any situation where the agent shouldn't make the final commitment unilaterally.
Conclusion
Scheduling fails in agents because the APIs were built for humans. The fix is an API that does the availability intelligence — auth, timezone normalization, slot scoring, error explanations — so the agent only has to orchestrate tool calls and talk to the user.
MeetSync is that API.
Install: npx mcp-meetsync
Full tutorial (worked example, Claude TypeScript + LangChain Python): github.com/nicholasemccormick/mcp-meetsync/docs/tutorial.md
API reference: github.com/nicholasemccormick/mcp-meetsync/docs/README.md
Questions or feedback? Drop them in the comments — happy to help if you're building something similar.
Top comments (2)
How i solved it:
Using 2 skills, predefined 1. Clock, 2. Plan
You need a system prompt like this:
and then sysprompt:
works flawless 🤫
In my experience, AI agents often falter at scheduling due to a lack of context awareness. The key isn't just integrating the latest NLP models but ensuring your agent understands organizational nuances like preferred meeting times, cultural holidays, and team roles. One approach is to supplement AI with human-in-the-loop systems, allowing for real-time adjustments and feedback. This hybrid method often bridges the gap between AI capabilities and human expectations effectively. - Ali Muwwakkil (ali-muwwakkil on LinkedIn)