Skip to main content
Glama
Use-Tusk
by Use-Tusk

get_spans_by_ids

Retrieve detailed span recordings including payloads by specifying their IDs. Use to examine specific API requests, database queries, or distributed traces captured by Tusk Drift.

Instructions

Fetch specific span recordings by their IDs.

Use this tool when you have span IDs from a previous query and need the full details including payloads.

This is useful for:

  • Getting full details for spans found via query_spans

  • Examining specific requests in detail

  • Comparing multiple specific spans

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
observableServiceIdNoService ID to query (required if multiple services available)
idsYesSpan recording IDs to fetch
includePayloadsNoInclude inputValue/outputValue
maxPayloadLengthNoTruncate payload strings

Implementation Reference

  • Main handler function: parses input with schema, calls API client.getSpansByIds, formats spans as markdown text response.
    export async function handleGetSpansByIds(
      client: TuskDriftApiClient,
      args: Record<string, unknown>
    ): Promise<{ content: Array<{ type: "text"; text: string }> }> {
      const input = getSpansByIdsInputSchema.parse(args) as GetSpansByIdsInput;
      const result = await client.getSpansByIds(input);
    
      if (result.spans.length === 0) {
        return {
          content: [
            {
              type: "text",
              text: `No spans found for the provided IDs.`,
            },
          ],
        };
      }
    
      const spansText = result.spans
        .map((span, i) => {
          const lines = [
            `## Span ${i + 1}: ${span.name}`,
            `- **ID:** ${span.id}`,
            `- **Trace ID:** ${span.traceId}`,
            `- **Span ID:** ${span.spanId}`,
            `- **Package:** ${span.packageName}`,
            `- **Duration:** ${span.duration.toFixed(2)}ms`,
            `- **Status:** ${span.status.code === 0 ? "OK" : span.status.code === 1 ? "UNSET" : "ERROR"}`,
            `- **Timestamp:** ${span.timestamp}`,
            `- **Root Span:** ${span.isRootSpan ? "Yes" : "No"}`,
          ];
    
          if (span.inputValue) {
            lines.push(`\n**Input:**\n\`\`\`json\n${JSON.stringify(span.inputValue, null, 2)}\n\`\`\``);
          }
    
          if (span.outputValue) {
            lines.push(`\n**Output:**\n\`\`\`json\n${JSON.stringify(span.outputValue, null, 2)}\n\`\`\``);
          }
    
          return lines.join("\n");
        })
        .join("\n\n---\n\n");
    
      return {
        content: [
          {
            type: "text",
            text: `Found ${result.spans.length} spans:\n\n${spansText}`,
          },
        ],
      };
    }
  • Zod input schema defining parameters: observableServiceId, ids (array 1-20), includePayloads, maxPayloadLength.
    export const getSpansByIdsInputSchema = z.object({
      observableServiceId: z.string().optional().describe("Service ID to query (required if multiple services available)"),
      ids: z.array(z.string()).min(1).max(20).describe("Span recording IDs to fetch"),
      includePayloads: z.boolean().default(true).describe("Include inputValue/outputValue"),
      maxPayloadLength: z.number().min(0).default(500).describe("Truncate payload strings"),
    });
  • Tool object registration: defines name, description, and inline JSON schema (mirrors Zod schema). Exported and collected in tools/index.ts for MCP server.
    export const getSpansByIdsTool: Tool = {
      name: "get_spans_by_ids",
      description: `Fetch specific span recordings by their IDs.
    
    Use this tool when you have span IDs from a previous query and need the full details including payloads.
    
    This is useful for:
    - Getting full details for spans found via query_spans
    - Examining specific requests in detail
    - Comparing multiple specific spans`,
      inputSchema: {
        type: "object",
        properties: {
          observableServiceId: {
            type: "string",
            description: "Service ID to query. Required if multiple services are available.",
          },
          ids: {
            type: "array",
            items: { type: "string" },
            description: "Span recording IDs to fetch (max 20)",
          },
          includePayloads: {
            type: "boolean",
            description: "Include full inputValue/outputValue",
            default: true,
          },
          maxPayloadLength: {
            type: "number",
            description: "Truncate payload strings to this length",
            default: 500,
          },
        },
        required: ["ids"],
      },
    };
  • Central registration: adds getSpansByIdsTool to tools[] array and maps get_spans_by_ids to handleGetSpansByIds in toolHandlers. Used by src/index.ts to register with MCP server.
    export const tools: Tool[] = [
      querySpansTool,
      getSchemaTool,
      listDistinctValuesTool,
      aggregateSpansTool,
      getTraceTool,
      getSpansByIdsTool,
    ];
    
    export type ToolHandler = (
      client: TuskDriftApiClient,
      args: Record<string, unknown>
    ) => Promise<{ content: Array<{ type: "text"; text: string }> }>;
    
    export const toolHandlers: Record<string, ToolHandler> = {
      query_spans: handleQuerySpans,
      get_schema: handleGetSchema,
      list_distinct_values: handleListDistinctValues,
      aggregate_spans: handleAggregateSpans,
      get_trace: handleGetTrace,
      get_spans_by_ids: handleGetSpansByIds,
    };
  • API client helper: makes HTTP POST to /api/drift/query/spans-by-id with resolved service ID and input params.
    /**
     * Get span recordings by IDs
     */
    async getSpansByIds(input: GetSpansByIdsInput): Promise<{
      spans: SpanRecording[];
    }> {
      const { observableServiceId, ...rest } = input;
      return this.request("/spans-by-id", {
        observableServiceId: this.resolveServiceId(observableServiceId),
        ...rest,
      });
    }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively explains the tool's purpose and use cases, but doesn't mention rate limits, authentication requirements, or error conditions. However, it does specify that it fetches 'full details including payloads' which adds useful context beyond basic functionality.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is perfectly structured with a clear purpose statement first, followed by usage guidance, then specific use cases. Every sentence earns its place by providing distinct value - no redundancy or wasted words. The bulleted list efficiently communicates multiple scenarios.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read operation with no annotations and no output schema, the description does well by explaining purpose, usage context, and specific scenarios. However, it doesn't describe the return format or what 'full details' includes beyond payloads. Given the complexity of span data, some additional context about the response structure would be helpful.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already fully documents all 4 parameters. The description mentions 'full details including payloads' which relates to the includePayloads parameter, but doesn't add significant semantic value beyond what's in the schema. This meets the baseline expectation when schema coverage is complete.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('fetch') and resource ('span recordings by their IDs'), distinguishing it from siblings like query_spans (which finds spans) and get_trace (which gets trace-level data). The first sentence directly explains what the tool does without restating the name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool ('when you have span IDs from a previous query') and provides a clear alternative ('spans found via query_spans'). It also lists three specific use cases, giving concrete guidance on appropriate contexts for invocation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Use-Tusk/drift-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server