-
Notifications
You must be signed in to change notification settings - Fork 12
Description
The Issue
Vapi's MCP integration creates a non-existent wrapper function instead of exposing actual MCP server tools, causing "Unknown tool" errors in production calls.
Expected vs Actual Behavior
MCP Server defines:
@mcp.tool
def get_appointment_timeslots(zip_code: str, address: str, city: str): pass
@mcp.tool
def create_appointment(correlation_id: str, first_name: str, ...): pass
Should expose: get_appointment_timeslots
and create_appointment
Vapi exposes: book_appointments
(doesn't exist in MCP server)
Production Failure
AI attempted book_appointments
3 times, all failed:
// Request
{"function": {"name": "book_appointments", "arguments": "{\"action\": \"get_appointment_timeslots\", ...}"}}
// Response
{"result": "[{\"type\": \"text\", \"text\": \"Unknown tool: book_appointments\"}]"}
Customer couldn't book appointment due to this bug.
Root Cause
Vapi incorrectly parses MCP tools/list
JSON-RPC responses. Instead of exposing individual tools per the MCP specification, it creates a wrapper that doesn't exist.
Vapi's tool config shows the mismatch:
{
"function": {"name": "book_appointments"}, // ❌ Fake wrapper
"metadata": {
"tools": [
{"function": {"name": "ngrokfree-get_appointment_timeslots"}}, // ✅ Real tools
{"function": {"name": "ngrokfree-create_appointment"}}
]
}
}
Comparison
Claude Desktop (works correctly):
front-desk-appointment:get_appointment_timeslots
✅front-desk-appointment:create_appointment
✅
Impact on MCP's Purpose
This bug defeats the entire point of MCP. The protocol exists to expose groups of related tools through a single server, but Vapi's implementation forces developers to create individual tools one-by-one instead of leveraging MCP's server-based tool discovery. This makes MCP integration pointless on Vapi.