Skip to main content
Glama

Terraform Registry MCP Server

by thrashr888
index.ts5.42 kB
/** * Entry point for MCP resources implementation */ import { handleListError, handleResourceError, addStandardContext } from "../utils/responseUtils.js"; import { TerraformCloudResources } from "./terraform.js"; import { RegistryResources } from "./registry.js"; import logger from "../utils/logger.js"; // Resource response interfaces export interface ResourcesListResponse { type: "success" | "error"; resources?: any[]; error?: string; context?: Record<string, any>; } export interface ResourceReadResponse { type: "success" | "error"; resource?: any; error?: string; context?: Record<string, any>; } export type ResourceHandler = { uriPattern: string; handler: (uri: string, params: Record<string, string>) => Promise<any>; list?: (params: Record<string, string>) => Promise<ResourcesListResponse>; read?: (params: Record<string, string>) => Promise<ResourceReadResponse>; }; // Combine all resource handlers const resourceHandlers: ResourceHandler[] = [...TerraformCloudResources, ...RegistryResources]; /** * Finds a resource handler for the given URI and extracts URI parameters */ function findHandler(uri: string): { handler: ResourceHandler | undefined; params: Record<string, string> } { const params: Record<string, string> = {}; let matchedHandler: ResourceHandler | undefined; logger.debug(`Finding handler for URI: ${uri}`); logger.debug(`Available handlers: ${resourceHandlers.map((h) => h.uriPattern).join(", ")}`); // Find the first matching handler for the given URI for (const handler of resourceHandlers) { if (!handler.uriPattern) { logger.debug(`Handler missing uriPattern, skipping`); continue; } logger.debug(`Checking handler with pattern: ${handler.uriPattern}`); const match = uri.match(handler.uriPattern); if (match && match.groups) { matchedHandler = handler; logger.debug(`Found matching handler with pattern: ${handler.uriPattern}`); // Extract named parameters from regex groups for (const [key, value] of Object.entries(match.groups)) { if (value) params[key] = value; } logger.debug(`Extracted params: ${JSON.stringify(params)}`); break; } } if (!matchedHandler) { logger.debug(`No handler found for URI: ${uri}`); } else { logger.debug( `Handler found with ${matchedHandler.list ? "list" : "no list"} and ${matchedHandler.read ? "read" : "no read"} capabilities` ); } return { handler: matchedHandler, params }; } /** * Handle resources/list requests */ export async function handleResourcesList(uri: string): Promise<ResourcesListResponse> { try { logger.debug(`Processing resources/list for URI: ${uri}`); const { handler, params } = findHandler(uri); if (!handler || !handler.list) { return { type: "error", error: "Resource handler not found or does not support list operation", context: addStandardContext({ uri, availableHandlers: Object.keys(resourceHandlers) }) }; } // Call the handler's list function return await handler.list(params); } catch (error) { logger.error(`Error in handleResourcesList: ${error}`); return { type: "error", error: error instanceof Error ? error.message : "Unknown error occurred", context: addStandardContext({ uri, errorType: error instanceof Error ? error.name : "UnknownError", timestamp: new Date().toISOString() }) }; } } /** * Handle resources/read requests */ export async function handleResourcesRead(uri: string): Promise<ResourceReadResponse> { try { logger.debug(`Processing resources/read for URI: ${uri}`); const { handler, params } = findHandler(uri); if (!handler || !handler.read) { return { type: "error", error: "Resource handler not found or does not support read operation", context: addStandardContext({ uri, availableHandlers: Object.keys(resourceHandlers) }) }; } // Call the handler's read function return await handler.read(params); } catch (error) { logger.error(`Error in handleResourcesRead: ${error}`); return { type: "error", error: error instanceof Error ? error.message : "Unknown error occurred", context: addStandardContext({ uri, errorType: error instanceof Error ? error.name : "UnknownError", timestamp: new Date().toISOString() }) }; } } /** * Handle a resources/templates/list request * @param uri The template URI pattern * @returns List of available template parameters */ export async function handleResourcesTemplatesList(): Promise<any> { try { // This would return template information for parameterized resources // For now, return a basic response return { type: "success", templates: [] }; } catch (error) { return handleListError(error); } } /** * Handle a resources/subscribe request * @param uri The URI to subscribe to * @returns Subscription response */ export async function handleResourcesSubscribe(): Promise<any> { try { // Basic subscription implementation return { type: "success", subscriptionId: `sub_${Math.random().toString(36).substring(2, 15)}` }; } catch (error) { return handleResourceError(error); } }

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/thrashr888/terraform-mcp-server'

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