get_trace
Retrieve a full distributed trace as a hierarchical tree to debug requests end-to-end, analyze call chains, timing, and dependencies.
Instructions
Get all spans in a distributed trace as a hierarchical tree.
Use this tool to:
Debug a specific request end-to-end
See the full call chain from HTTP request to database queries
Understand timing and dependencies between spans
Identify bottlenecks in a request
First use query_spans to find spans, then use the traceId to get the full trace.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| observableServiceId | No | Service ID to query (required if multiple services available) | |
| traceId | Yes | Trace ID to fetch | |
| includePayloads | No | Include inputValue/outputValue | |
| maxPayloadLength | No | Truncate payload strings |
Implementation Reference
- src/tools/getTrace.ts:69-98 (handler)Main handler for the get_trace tool. Parses input, calls the API client's getTrace() method, formats the trace tree, and returns the result.
export async function handleGetTrace( client: TuskDriftApiClient, args: Record<string, unknown> ): Promise<{ content: Array<{ type: "text"; text: string }> }> { const input = parseGetTraceInput(args); const result = await client.getTrace(input); if (!result.traceTree) { return { content: [ { type: "text", text: `No trace found for ID: ${input.traceId}`, }, ], }; } const header = `Trace: ${input.traceId}\nSpan Count: ${result.spanCount}\n\nTrace Tree:\n`; const tree = formatTraceTree(result.traceTree, 0, input.includePayloads ?? false); return { content: [ { type: "text", text: header + tree, }, ], }; } - src/tools/getTrace.ts:6-41 (schema)Tool definition with inputSchema for get_trace, defining observableServiceId, traceId, includePayloads, and maxPayloadLength parameters.
export const getTraceTool: Tool = { name: "get_trace", description: `Get all spans in a distributed trace as a hierarchical tree. Use this tool to: - Debug a specific request end-to-end - See the full call chain from HTTP request to database queries - Understand timing and dependencies between spans - Identify bottlenecks in a request First use query_spans to find spans, then use the traceId to get the full trace.`, inputSchema: { type: "object", properties: { observableServiceId: { type: "string", description: "Service ID to query. Required if multiple services are available.", }, traceId: { type: "string", description: "The trace ID to fetch", }, includePayloads: { type: "boolean", description: "Include inputValue/outputValue (can be verbose)", default: false, }, maxPayloadLength: { type: "number", description: "Truncate payload strings to this length", default: 500, }, }, required: ["traceId"], }, }; - src/types.ts:269-274 (schema)Zod schema (getTraceInputSchema) for validating get_trace input arguments.
export const getTraceInputSchema = z.object({ observableServiceId: z.string().optional().describe("Service ID to query (required if multiple services available)"), traceId: z.string().describe("Trace ID to fetch"), includePayloads: z.boolean().default(false).describe("Include inputValue/outputValue"), maxPayloadLength: z.number().min(0).default(500).describe("Truncate payload strings"), }); - src/types.ts:405-413 (helper)parseGetTraceInput function that validates and transforms input args into a protobuf request object.
export function parseGetTraceInput(args: Record<string, unknown>): GetTraceInput { const input: GetTraceArgs = getTraceInputSchema.parse(args); return SharedGetTraceSpansRequest.create({ observableServiceId: input.observableServiceId ?? "", traceId: input.traceId, includePayloads: input.includePayloads, maxPayloadLength: input.maxPayloadLength, }); } - src/server.ts:415-464 (registration)Registration of the get_trace tool on the MCP server with description, inputSchema, and handler callback.
// ============================================ // Tool: get_trace // ============================================ server.registerTool( "get_trace", { description: `Get all spans in a distributed trace as a hierarchical tree. Use this tool to: - Debug a specific request end-to-end - See the full call chain from HTTP request to database queries - Understand timing and dependencies between spans - Identify bottlenecks in a request First use query_spans to find spans, then use the traceId to get the full trace.`, inputSchema: getTraceInputSchema.shape, }, async (args) => { const input = parseGetTraceInput(args); if (input.observableServiceId && !(await checkAccess(input.observableServiceId))) { return { content: [{ type: "text" as const, text: "Error: Access denied to observable service" }], isError: true, }; } try { const result = await provider.getTrace(input); if (!result.traceTree) { return { content: [{ type: "text" as const, text: `No trace found for ID: ${input.traceId}` }], }; } const header = `Trace: ${input.traceId}\nSpan Count: ${result.spanCount}\n\nTrace Tree:\n`; const tree = formatTraceTree(result.traceTree, 0, input.includePayloads ?? false); return { content: [{ type: "text" as const, text: header + tree }], }; } catch (error) { return { content: [{ type: "text" as const, text: `Error executing get_trace: ${error}` }], isError: true, }; } } );