Skip to content

Commit fb49dd2

Browse files
committed
feat: add get_call_details tool
The existing get_call tool returns a summary projection (id, status, endedReason, assistantId, phoneNumberId, customer.number, scheduledAt) which makes it impossible to fetch transcripts, recordings, messages, costs, or analysis without dropping out to the REST API. This adds a sibling get_call_details tool that returns the full call payload. It accepts an optional 'include' array so callers can scope the response to specific fields (transcript, recordingUrl, messages, costs, cost, analysis, summary, artifact) and keep LLM context windows in check on long calls. - New schemas: GetCallDetailsInputSchema, CallDetailsOutputSchema, CALL_DETAIL_FIELDS - New transformer: transformCallDetailsOutput - New tool registration in src/tools/call.ts - E2E test updated to assert tool is registered
1 parent c5daf98 commit fb49dd2

4 files changed

Lines changed: 73 additions & 1 deletion

File tree

src/__tests__/mcp-server-e2e.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ describe('MCP Server E2E Test', () => {
5959
expect(toolNames).toContain('list_calls');
6060
expect(toolNames).toContain('create_call');
6161
expect(toolNames).toContain('get_call');
62+
expect(toolNames).toContain('get_call_details');
6263
});
6364

6465
describe('Assistant Tools', () => {

src/schemas/index.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,38 @@ export const GetCallInputSchema = z.object({
304304
callId: z.string().describe('ID of the call to get'),
305305
});
306306

307+
export const CALL_DETAIL_FIELDS = [
308+
'transcript',
309+
'recordingUrl',
310+
'messages',
311+
'costs',
312+
'cost',
313+
'analysis',
314+
'summary',
315+
'artifact',
316+
] as const;
317+
318+
export const GetCallDetailsInputSchema = z.object({
319+
callId: z.string().describe('ID of the call to get full details for'),
320+
include: z
321+
.array(z.enum(CALL_DETAIL_FIELDS))
322+
.optional()
323+
.describe(
324+
'Subset of detail fields to return. Omit to return the full call object. Useful for keeping LLM context small on long calls.'
325+
),
326+
});
327+
328+
export const CallDetailsOutputSchema = CallOutputSchema.extend({
329+
transcript: z.string().optional(),
330+
recordingUrl: z.string().optional(),
331+
summary: z.string().optional(),
332+
messages: z.array(z.any()).optional(),
333+
costs: z.array(z.any()).optional(),
334+
cost: z.number().optional(),
335+
analysis: z.any().optional(),
336+
artifact: z.any().optional(),
337+
});
338+
307339
// ===== Phone Number Schemas =====
308340

309341
export const GetPhoneNumberInputSchema = z.object({

src/tools/call.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
22
import { VapiClient, Vapi } from '@vapi-ai/server-sdk';
33

4-
import { CallInputSchema, GetCallInputSchema } from '../schemas/index.js';
4+
import {
5+
CallInputSchema,
6+
GetCallInputSchema,
7+
GetCallDetailsInputSchema,
8+
} from '../schemas/index.js';
59
import {
610
transformCallInput,
711
transformCallOutput,
12+
transformCallDetailsOutput,
813
} from '../transformers/index.js';
914
import { createToolHandler } from './utils.js';
1015

@@ -42,4 +47,14 @@ export const registerCallTools = (
4247
return transformCallOutput(call);
4348
})
4449
);
50+
51+
server.tool(
52+
'get_call_details',
53+
'Gets full details of a specific call (transcript, recording URL, messages, costs, analysis, summary, artifact). Use after get_call when summary fields are not enough. Pass `include` to scope the response and avoid blowing past LLM context windows on long calls.',
54+
GetCallDetailsInputSchema.shape,
55+
createToolHandler(async (data) => {
56+
const call = await vapiClient.calls.get(data.callId);
57+
return transformCallDetailsOutput(call, data.include);
58+
})
59+
);
4560
};

src/transformers/index.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
UpdateAssistantInputSchema,
1111
CreateToolInputSchema,
1212
UpdateToolInputSchema,
13+
CALL_DETAIL_FIELDS,
1314
} from '../schemas/index.js';
1415

1516
// ===== Assistant Transformers =====
@@ -228,6 +229,29 @@ export function transformCallOutput(
228229
};
229230
}
230231

232+
export function transformCallDetailsOutput(
233+
call: Vapi.Call,
234+
include?: ReadonlyArray<(typeof CALL_DETAIL_FIELDS)[number]>
235+
): Record<string, unknown> {
236+
const summary = transformCallOutput(call);
237+
const callRecord = call as unknown as Record<string, unknown>;
238+
const artifact = (callRecord.artifact ?? {}) as Record<string, unknown>;
239+
240+
const fields = include ?? CALL_DETAIL_FIELDS;
241+
const details: Record<string, unknown> = {};
242+
for (const field of fields) {
243+
const value = callRecord[field] ?? artifact[field];
244+
if (value !== undefined) {
245+
details[field] = value;
246+
}
247+
}
248+
249+
if (include) {
250+
return { id: call.id, ...details };
251+
}
252+
return { ...summary, ...details };
253+
}
254+
231255
// ===== Phone Number Transformers =====
232256

233257
export function transformPhoneNumberOutput(

0 commit comments

Comments
 (0)