From d3c44e99bcfa824ba5627379aed3938cb14450fe Mon Sep 17 00:00:00 2001 From: cassius66 Date: Sun, 3 Aug 2025 14:50:08 -0400 Subject: [PATCH 1/3] `get_call_transcript`: Gets the full transcript and conversation data of a specific call --- README.md | 1 + src/schemas/index.ts | 15 +++++++++++++++ src/tools/call.ts | 13 ++++++++++++- src/transformers/index.ts | 19 +++++++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3460867..f6efb50 100644 --- a/README.md +++ b/README.md @@ -225,6 +225,7 @@ The Vapi MCP Server provides the following tools for integration: - Immediate or scheduled calls - Dynamic variable values through `assistantOverrides` - `get_call`: Gets details of a specific call +- `get_call_transcript`: Gets the full transcript and conversation data of a specific call > **Note:** The `create_call` action supports scheduling calls for immediate execution or for a future time. You can also pass dynamic variables using `assistantOverrides.variableValues` to personalize assistant messages. diff --git a/src/schemas/index.ts b/src/schemas/index.ts index 2638121..4d3e297 100644 --- a/src/schemas/index.ts +++ b/src/schemas/index.ts @@ -304,6 +304,21 @@ export const GetCallInputSchema = z.object({ callId: z.string().describe('ID of the call to get'), }); +export const CallTranscriptOutputSchema = BaseResponseSchema.extend({ + id: z.string(), + transcript: z.string().optional(), + messages: z.array(z.object({ + role: z.string(), + message: z.string(), + time: z.number().optional(), + duration: z.number().optional(), + })).optional(), + recordingUrl: z.string().optional(), + summary: z.string().optional(), +}); + +export const GetCallTranscriptInputSchema = GetCallInputSchema; + // ===== Phone Number Schemas ===== export const GetPhoneNumberInputSchema = z.object({ diff --git a/src/tools/call.ts b/src/tools/call.ts index 408e347..1160d20 100644 --- a/src/tools/call.ts +++ b/src/tools/call.ts @@ -1,10 +1,11 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { VapiClient, Vapi } from '@vapi-ai/server-sdk'; -import { CallInputSchema, GetCallInputSchema } from '../schemas/index.js'; +import { CallInputSchema, GetCallInputSchema, GetCallTranscriptInputSchema } from '../schemas/index.js'; import { transformCallInput, transformCallOutput, + transformCallTranscriptOutput, } from '../transformers/index.js'; import { createToolHandler } from './utils.js'; @@ -42,4 +43,14 @@ export const registerCallTools = ( return transformCallOutput(call); }) ); + + server.tool( + 'get_call_transcript', + 'Gets the full transcript and conversation data of a specific call', + GetCallTranscriptInputSchema.shape, + createToolHandler(async (data) => { + const call = await vapiClient.calls.get(data.callId); + return transformCallTranscriptOutput(call); + }) + ); }; diff --git a/src/transformers/index.ts b/src/transformers/index.ts index 53fa800..a73f344 100644 --- a/src/transformers/index.ts +++ b/src/transformers/index.ts @@ -228,6 +228,25 @@ export function transformCallOutput( }; } +export function transformCallTranscriptOutput( + call: Vapi.Call +): z.infer { + return { + id: call.id, + createdAt: call.createdAt, + updatedAt: call.updatedAt, + transcript: call.artifact?.transcript, + messages: call.artifact?.messages?.map(msg => ({ + role: msg.role, + message: msg.message, + time: msg.time, + duration: msg.duration, + })), + recordingUrl: call.artifact?.recordingUrl, + summary: call.analysis?.summary, + }; +} + // ===== Phone Number Transformers ===== export function transformPhoneNumberOutput( From b09afe558f2c2a5b51e62da195520776c566c0d0 Mon Sep 17 00:00:00 2001 From: RP Date: Mon, 4 Aug 2025 08:48:19 -0400 Subject: [PATCH 2/3] feat: enhance message transformation in CallTranscriptOutput to handle optional properties --- src/schemas/index.ts | 2 +- src/transformers/index.ts | 32 ++++++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/schemas/index.ts b/src/schemas/index.ts index 4d3e297..85db71e 100644 --- a/src/schemas/index.ts +++ b/src/schemas/index.ts @@ -309,7 +309,7 @@ export const CallTranscriptOutputSchema = BaseResponseSchema.extend({ transcript: z.string().optional(), messages: z.array(z.object({ role: z.string(), - message: z.string(), + message: z.string().optional(), time: z.number().optional(), duration: z.number().optional(), })).optional(), diff --git a/src/transformers/index.ts b/src/transformers/index.ts index a73f344..e89e9ad 100644 --- a/src/transformers/index.ts +++ b/src/transformers/index.ts @@ -5,6 +5,7 @@ import { CallInputSchema, AssistantOutputSchema, CallOutputSchema, + CallTranscriptOutputSchema, PhoneNumberOutputSchema, ToolOutputSchema, UpdateAssistantInputSchema, @@ -236,12 +237,31 @@ export function transformCallTranscriptOutput( createdAt: call.createdAt, updatedAt: call.updatedAt, transcript: call.artifact?.transcript, - messages: call.artifact?.messages?.map(msg => ({ - role: msg.role, - message: msg.message, - time: msg.time, - duration: msg.duration, - })), + messages: call.artifact?.messages?.map(msg => { + // Handle different message types safely + const transformedMessage: any = { + role: msg.role, + time: msg.time || 0, + }; + + // Check if message has a 'message' property (UserMessage, BotMessage, SystemMessage, ToolCallMessage) + if ('message' in msg && typeof msg.message === 'string') { + transformedMessage.message = msg.message; + } else if ('result' in msg && typeof msg.result === 'string') { + // For ToolCallResultMessage, use result as message + transformedMessage.message = msg.result; + } else { + // Fallback for unknown message types - set to undefined since schema allows optional + transformedMessage.message = undefined; + } + + // Check if message has a 'duration' property (UserMessage, BotMessage) + if ('duration' in msg && typeof msg.duration === 'number') { + transformedMessage.duration = msg.duration; + } + + return transformedMessage; + }), recordingUrl: call.artifact?.recordingUrl, summary: call.analysis?.summary, }; From 950f0c39701cce47960d0fb8fc84ca764000a0d1 Mon Sep 17 00:00:00 2001 From: cassius66 Date: Tue, 5 Aug 2025 20:46:18 -0400 Subject: [PATCH 3/3] docs: add changelog documenting recent enhancements Co-authored-by: RP --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..4939f76 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,6 @@ +# Changelog + +## [Unreleased] +### Enhanced +- Improved message transformation in CallTranscriptOutput to handle optional properties +- Enhanced type safety for message handling