This MCP server defines 3 phone call tools with basic schemas and descriptions, but falls short of production quality. All three tools have descriptions and input schemas visible in src/index.ts, but lack critical LLM-optimization details. Descriptions are functional but generic (avg ~110 chars), missing context about when to use each tool, prerequisites, or failure modes. Parameters have types but minimal guidance on valid values or constraints. Output schemas are undocumented, LLMs cannot plan downstream steps. Error handling returns raw exceptions rather than actionable recovery guidance. The tool set shows a single responsibility (phone calls) but lacks composition guidance, agents cannot determine order of operations or retry strategies. No parameter validation examples, no mention of idempotency, and no explicit handling of the stateful call_id threading model that the agent must maintain across three sequential calls.
Tools (3)
continue_callwriteauthsource verified62/100
Send a response to the user and wait for their next message.
end_callwriteauthsource verified64/100
End the phone call with a final message.
initiate_callwriteauthsource verified67/100
Start a phone call to the user. Returns the call ID and waits for the user to respond.
Output schema undocumented. initiate_call returns a call ID and waits for user response, but the response format is never documented. Agents cannot extract the call_id field or understand the blocking semantics. This forces agents to guess at the structure and blocks downstream continue_call invocations.
Error handling returns raw exception messages (e.g., 'Error: {e.message}') without recovery guidance. An LLM receiving 'Error: Call ID not found' has no way to know whether to retry, lookup a different call, or abort. Errors should indicate: is this retryable? user-fixable? fatal?
Descriptions lack 'WHEN to use' context. 'Start a phone call to the user' is descriptive but does not explain when this tool is appropriate vs. text-based communication, prerequisites (phone number configured?), or whether the agent should check availability first. Descriptions should guide LLM tool selection.
Recommendations
Document the complete output schema for initiate_call, including the structure of the call_id and any metadata returned (e.g., { "call_id": "string", "status": "active", "created_at": "ISO 8601 timestamp" }). This enables agents to extract the call_id and plan downstream steps.
Add WHEN-TO-USE context to each tool description: 'Initiates a synchronous phone call to the user. Use this instead of text-based communication when immediate voice interaction is needed. Requires CALLME_USER_PHONE_NUMBER to be configured. Returns a call_id that subsequent continue_call and end_call invocations require.'
Document the call_id lifetime and threading model: 'The call_id identifies a unique conversation. It remains valid until end_call is invoked. Do not reuse call_ids across different conversations. If you lose the call_id, the conversation is orphaned and cannot be resumed.'
Add idempotency declarations to continue_call and end_call: 'Idempotent. Sending the same message with the same call_id is safe and will not duplicate the message. Use this property to safely retry on network failures.'
Specify message format constraints in parameter descriptions: 'message (string, 1-1000 chars): The text to speak to the user. Avoid special characters; the TTS provider accepts alphanumerics, punctuation, and basic symbols. Newlines are ignored; provide single sentences or short paragraphs.'
Document continue_call response format: 'Returns the user\'s next spoken message as a plain text string. If the user did not respond within 30 seconds, returns an empty string and status "timeout". If the call was ended by the user, returns status "disconnected".'
Stateful call_id threading not documented. The three tools form a sequence: initiate_call returns call_id → continue_call uses it → end_call uses it. There is no description explaining this dependency chain, the lifetime of call_id, or what happens if an agent loses it. Agents need explicit guidance on composition.
No idempotency contract. If continue_call is retried with the same call_id and message, will the message be sent twice? This is critical for agent reliability but never documented. Tools should declare whether repeated invocation with identical input is safe.
Parameter 'message' is underspecified. Is there a length limit? Does the TTS provider reject certain characters? Can the agent pass multi-paragraph text or only single sentences? The description 'Initial message to speak to the user' provides no guidance on format, length, or constraints.
continue_call response format undocumented. Does it return the user's next message as a string? A JSON object? Metadata about the response (duration, transcription confidence)? Agents cannot parse the output or decide what to do next without this specification.
No documentation of timeout behavior. If the user does not respond, how long does initiate_call and continue_call wait? Do they timeout? What is the response if they do? Agents need to know expected latency and failure modes for long-running operations.
initiate_callcontinue_call
Add timeout behavior to tool descriptions: 'initiate_call and continue_call block for up to 60 seconds waiting for the user to respond. If no response is received, they return a timeout error. The error is retryable; the agent can invoke continue_call again with the same call_id to reconnect.'
Create a composition example in a tool annotation or top-level server description: 'Typical flow: (1) initiate_call(message="Hello") → returns call_id; (2) continue_call(call_id, message="...response...") → returns user_reply; repeat step 2 as needed; (3) end_call(call_id, message="Goodbye").'
Enhance error messages with recovery guidance. Instead of 'Error: Call ID not found', return 'Call ID "call_123" not found or expired. The call may have been ended by the user or timed out. Start a new call with initiate_call().'
Document prerequisites and failure modes: 'initiate_call requires CALLME_USER_PHONE_NUMBER and CALLME_PHONE_NUMBER environment variables to be set, and a phone provider (Vapi or Telnyx) to be configured. If these are missing, returns an error: "Phone provider not initialized." Ensure these variables are set before calling.'
Add a dry-run or verification step for destructive operations (end_call). Consider returning a confirmation prompt: 'end_call(call_id, message="Goodbye") will terminate the call. Add require_confirmation=true to prevent accidental termination. Omit this parameter to end immediately.'
Document rate limits and quota constraints: 'Each call incurs charges via the phone provider. There is no built-in rate limit; configure agent rate limits at the client level to prevent unexpected billing. Typical cost is $0.10 - $0.50 per call depending on duration and provider.'