Skip to main content
Glama
response-builder.ts4.2 kB
/** * @fileoverview Response builder utility for MCP tool handlers. * Provides a consistent way to build tool responses with proper error handling. * @packageDocumentation */ import { createLogger } from './logging/logger.js'; const logger = createLogger('DeepSourceMCP:ResponseBuilder'); /** * Response structure for MCP tools */ export interface ToolResponse { content: Array<{ type: 'text'; text: string; }>; structuredContent?: unknown; isError: boolean; } /** * Options for building a response */ export interface ResponseBuilderOptions { /** Whether to log the response */ log?: boolean; /** Tool name for logging */ toolName?: string; /** Structured content to include */ structuredContent?: unknown; } /** * Builder class for creating consistent tool responses */ export class ToolResponseBuilder { private content: Array<{ type: 'text'; text: string }> = []; private isError = false; private structuredContent?: unknown; private options: ResponseBuilderOptions; constructor(options: ResponseBuilderOptions = {}) { this.options = options; } /** * Create a success response builder */ static success(data: unknown, options?: ResponseBuilderOptions): ToolResponseBuilder { const builder = new ToolResponseBuilder(options); return builder.withData(data); } /** * Create an error response builder */ static error(error: Error | string, options?: ResponseBuilderOptions): ToolResponseBuilder { const builder = new ToolResponseBuilder(options); return builder.withError(error); } /** * Add data to the response */ withData(data: unknown): this { this.content.push({ type: 'text', text: JSON.stringify(data), }); if (this.options.log && this.options.toolName) { logger.info(`${this.options.toolName} response built successfully`); } return this; } /** * Add an error to the response */ withError(error: Error | string): this { this.isError = true; const errorMessage = error instanceof Error ? error.message : error; this.content.push({ type: 'text', text: JSON.stringify({ error: errorMessage, details: 'Operation failed', }), }); if (this.options.log && this.options.toolName) { logger.error(`${this.options.toolName} response contains error`, { error: errorMessage }); } return this; } /** * Set structured content */ withStructuredContent(content: unknown): this { this.structuredContent = content; return this; } /** * Build the final response */ build(): ToolResponse { const response: ToolResponse = { content: this.content, isError: this.isError, }; if (this.options.structuredContent !== undefined) { response.structuredContent = this.options.structuredContent; } else if (this.structuredContent !== undefined) { response.structuredContent = this.structuredContent; } return response; } } /** * Helper function to create a success response */ export function successResponse(data: unknown, options?: ResponseBuilderOptions): ToolResponse { return ToolResponseBuilder.success(data, options).build(); } /** * Helper function to create an error response */ export function errorResponse( error: Error | string, options?: ResponseBuilderOptions ): ToolResponse { return ToolResponseBuilder.error(error, options).build(); } /** * Helper function to parse and validate a tool response */ export function parseToolResponse<T = unknown>( response: ToolResponse, validator?: (data: unknown) => data is T ): T { if (response.isError) { if (!response.content || !response.content[0]) { throw new Error('Error response has no content'); } const errorData = JSON.parse(response.content[0].text); throw new Error(errorData.error || 'Unknown error'); } if (!response.content || !response.content[0]) { throw new Error('Response has no content'); } const data = JSON.parse(response.content[0].text); if (validator && !validator(data)) { throw new Error('Response data failed validation'); } return data as T; }

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/sapientpants/deepsource-mcp-server'

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