How to Build an Appointment Confirmation Agent with Vapi and ChatBotKit
Missed appointments cost service businesses billions every year. Automated reminder calls help, but most are one-way - they play a recorded message and hang up. If the patient needs to reschedule, they still have to call the office back, wait on hold, and coordinate with a human.
In this tutorial you will build a two-way appointment confirmation agent that can actually solve the problem. The agent calls patients, confirms their appointment, and if they need to reschedule, checks live calendar availability, offers alternative slots, books the new appointment, sends a confirmation email, and updates the patient record - all in a single phone call.
Vapi handles the calling and speech. ChatBotKit handles every action the agent takes, exposed through a single MCP server endpoint.
What You'll Learn
- How to design a ChatBotKit blueprint where every tool serves a specific moment in the conversation
- How to expose appointment tools as an MCP server that Vapi can connect to
- How to configure a Vapi assistant with the MCP tool for outbound calls
- How to trigger confirmation calls for a full day's appointments using batch calling
- How to pass appointment context into each call so the agent knows why it is calling
Prerequisites
- A ChatBotKit account
- A Vapi account with a phone number provisioned
- A Google Calendar connected to ChatBotKit (for availability checking and booking)
- Basic familiarity with the ChatBotKit Blueprint Designer
- Approximately 30 minutes
Architecture Overview
The integration works in two layers:
- ChatBotKit - you build a skillset containing the abilities the agent needs during a call: checking calendar availability, booking slots, sending emails, notifying staff, and updating patient records. An MCPServer integration exposes that skillset as a single MCP endpoint.
- Vapi - you register that endpoint as an MCP tool and attach it to an assistant. When Vapi places an outbound call, the assistant discovers all available tools from the MCP server and can call them during the live conversation.
The agent does not need tools to look up who it is calling. The patient's name, appointment date, and phone number are injected into the Vapi assistant at call creation time via assistantOverrides.variableValues. The tools exist only for actions the agent takes in response to what the patient says.
How Vapi's MCP integration works: When a call starts, Vapi connects to your MCP server, fetches the list of available tools, and adds them to the assistant's context. Each time the LLM invokes a tool, Vapi creates a separate MCP connection with an
X-Call-Idheader identifying the specific call. This means each tool execution is isolated and reliable.
Step 1: Create the Blueprint in ChatBotKit
Build a blueprint with the five abilities the agent needs during a confirmation call. Each ability maps to a specific moment in the conversation:
| Moment | Ability | Template |
|---|---|---|
| Patient needs to reschedule | Check Available Slots | google/calendar/availability/list |
| Patient picks a new time | Book Appointment | google/calendar/availability/book |
| After confirming or rebooking | Send Confirmation Email | sendgrid/email/send |
| Patient cancels | Notify Front Desk | slack/message/send |
| After any outcome | Update Patient Record | hubspot/crm/contact/update |
- Navigate to Blueprints in your ChatBotKit dashboard
- Click Create and select Blueprint
- Name it "Appointment Confirmation Agent"
- Click Design to open the Blueprint Designer
Add a Bot, a Skillset, and the abilities shown below:
Notice what is not in this blueprint: there are no "look up contact" or "search leads" abilities. The agent already knows who it is calling because the patient context is injected at call creation time (see Step 5). Every tool here exists to take an action in response to the conversation, not to discover information the agent should already have.
(1) The Bot resource can be used independently of Vapi. Open it in the ChatBotKit Collabo chat interface to test your abilities and debug tool responses before connecting to a voice agent. This is the fastest way to verify that the availability check returns sensible slots and that booking works correctly.
(2) The MCPServer Integration is what Vapi connects to. After building the blueprint, open this integration in your dashboard and copy the Server URL and Access Token.
Save and build your blueprint.
Step 2: Copy the MCP Server URL and Access Token
Because the blueprint includes an mcpserverIntegration resource, the MCP server was created automatically when you built the blueprint.
- Go to Integrations in your ChatBotKit dashboard
- Find the Appointment Agent MCP Server integration created by the blueprint
- Click on it to open the details page
You will see two critical pieces of information:
- Server URL - the MCP endpoint URL (e.g.
https://api.chatbotkit.com/v1/integration/mcpserver/<id>/mcp) - Access Token - a bearer token for authenticating requests
Copy both values. You will need them in the next step.
Step 3: Create the MCP Tool in Vapi
Now switch to Vapi to register your ChatBotKit MCP server as a tool.
-
Log in to your Vapi dashboard
-
Navigate to Tools in the sidebar
-
Click Create Tool
-
Select MCP from the available tool types
-
Fill in the tool details:
- Name: "Appointment Tools"
- Description: "Calendar availability, booking, email confirmations, and CRM updates for appointment calls"
- Server URL: Paste the MCP endpoint URL from ChatBotKit
- Headers: Add an
Authorizationheader with the valueBearer <your-access-token>
-
Leave the protocol on the default Streamable HTTP setting (ChatBotKit supports both Streamable HTTP and SSE)
-
Click Save
Note: The MCP server URL should be treated as a credential. Vapi will connect to this URL when a call starts to discover available tools, and again each time the LLM invokes a tool during the conversation.
Step 4: Create the Assistant in Vapi
With the MCP tool created, set up a Vapi assistant for appointment confirmation calls.
-
In Vapi, go to Assistants and click Create Assistant
-
Choose a blank template
-
Configure the assistant:
- Name: "Appointment Confirmation Agent"
- Model: Select a model (e.g. GPT-4o or Claude)
- First Message: "Hi {{patientName}}, this is the appointment desk at Greenfield Clinic. I'm calling about your {{serviceType}} appointment scheduled for {{appointmentDate}} at {{appointmentTime}}. Can you confirm you'll be able to make it?"
-
Write a system prompt:
You are a friendly appointment coordinator for Greenfield Clinic. You are calling {{patientName}} about their {{serviceType}} appointment on {{appointmentDate}} at {{appointmentTime}}. Your job is to confirm the appointment, help reschedule if needed, or handle a cancellation. Keep responses short and natural. When checking availability, say "Let me check what we have open" before calling the tool. Always repeat back the chosen time to confirm before booking. End every call with a clear summary.
-
Under Tools, select the Appointment Tools MCP tool
-
Click Publish
The {{patientName}}, {{appointmentDate}}, {{appointmentTime}}, and {{serviceType}} placeholders are Vapi template variables. They get filled in at call creation time via assistantOverrides.variableValues, so every call is personalized without the agent needing to look anything up.
Step 5: Place Confirmation Calls
The typical workflow is to query your booking system for upcoming appointments and batch-call all patients who need confirmation.
Single Confirmation Call
Place one call with the patient's appointment context injected via assistantOverrides:
The agent will greet Jane by name and reference her specific appointment. No CRM lookup needed.
Batch Confirmation Calls
Confirm an entire day's appointments in one API request:
Each patient gets the same assistant and MCP tools. Vapi calls them sequentially.
Note: When using batch calling,
assistantOverrides.variableValuesapplies to all customers in the batch. If each patient has different appointment details, make individual calls or group patients by appointment time.
Scheduled Confirmation Calls
Restrict calls to morning hours so patients are not disturbed in the evening:
Step 6: Test the Agent
- Place a test call to your own phone number
- When you answer, the agent will greet you with your appointment details
- Walk through each scenario:
Confirm: Say "Yes, I'll be there." The agent should send you a confirmation email and update your record.
Reschedule: Say "I can't make Thursday, can we do next week instead?" The agent should:
- Say "Let me check what we have open"
- Call the Check Available Slots tool
- Read back 2-3 options
- After you pick one, call Book Appointment
- Send a confirmation email with the new details
- Update your patient record
Cancel: Say "I need to cancel." The agent should ask for a brief reason, notify the front desk on Slack, update your record, and let you know you can call back to rebook.
Going Further
Automating the Calling Workflow
In production, you would not trigger calls manually. A typical setup:
- A cron job or webhook queries your booking system for appointments in the next 48 hours
- It filters for patients who have not yet confirmed
- It builds the Vapi API request with each patient's details
- It POSTs to
/callto trigger the confirmation calls - After each call, the agent updates HubSpot, so the next cron run skips already-confirmed patients
You can also use a ChatBotKit trigger integration with a scheduled bot to orchestrate this - the bot queries HubSpot for upcoming appointments and uses the Vapi API (or Vapi's own MCP server) to place the calls.
Adding More Abilities
Add abilities to the skillset and they appear in the MCP server immediately - no Vapi-side changes needed:
google/calendar/event/updateto modify existing appointments (e.g. change duration or add notes)twilio/message/sendto send an SMS confirmation instead of or in addition to emailhubspot/crm/contact/fetchfor a receptionist bot variant that can look up patients manuallystripe/invoice/createto collect a cancellation fee or deposit for the new appointment
Using the Vapi MCP Server from ChatBotKit
The integration also works in reverse. Vapi provides its own MCP server at https://mcp.vapi.ai/mcp that exposes Vapi APIs as tools. You can connect this to a ChatBotKit bot so your front desk staff can say "Call Jane Smith at +15551234567 to confirm her Thursday appointment" in Slack or a web chat, and ChatBotKit orchestrates the Vapi API call through MCP.
Dynamic Tool Updates
Because Vapi fetches the tool list from your MCP server at the start of each call, any abilities you add or modify in ChatBotKit are immediately available to the next call. You can:
- Add new abilities and they appear in the next call
- Update ability descriptions to improve how the LLM uses them
- Remove abilities that are no longer needed
- Swap backend integrations without touching Vapi
Troubleshooting
Tools are not appearing in the Vapi assistant
- Verify the MCP Server URL is correct in the Vapi tool configuration
- Check that the
Authorization: Bearer <token>header is set correctly - Ensure the ChatBotKit MCPServer integration is pointing to the correct skillset
- Try removing and re-creating the MCP tool in Vapi to force a re-discovery
Tool calls fail during the call
- Test the abilities directly in ChatBotKit first using the Collabo chat interface
- For calendar abilities, verify the Google Calendar connection is active in your ChatBotKit secrets
- Check the ChatBotKit integration event log for error details
- Check the Vapi call log for error messages in the tool call results
Agent does not know the patient's name or appointment details
- Make sure you are passing
assistantOverrides.variableValueswhen creating the call - Verify the variable names match the
{{placeholders}}in your system prompt and first message - Check that the Vapi assistant is configured to use template variables
Voice agent responds slowly during tool calls
- The availability check queries Google Calendar in real time - ensure the calendar API is responding quickly
- Add a conversational filler in the system prompt (e.g. "Say 'Let me check what we have open' before calling the availability tool")
- Simplify ability responses to return only the data the LLM needs
Outbound calls not connecting
- Verify your Vapi phone number is provisioned and active
- Check that the patient phone number is in E.164 format (e.g. +15551234567)
- Review Vapi's call logs for carrier-level errors
- Ensure your Vapi account has sufficient credits for outbound calls
Next Steps
- Explore the full MCP Server Integration feature page for advanced configuration options
- Learn how to connect any MCP server to your AI agent for the reverse pattern - bringing external tools into ChatBotKit
- Read the Vapi MCP documentation for more details on protocol options and MCP provider examples
- Check the Vapi MCP Server documentation to learn how to use Vapi's own MCP server for programmatic call management