Skip to main content
Glama
opentofu

OpenTofu MCP Server

Official
by opentofu

search-opentofu-registry

Search the OpenTofu Registry to find providers, modules, resources, and data sources for infrastructure configuration. Enter simple terms like 'aws' or 'kubernetes' to locate components.

Instructions

Search the OpenTofu Registry to find providers, modules, resources, and data sources. Use simple terms without prefixes like 'terraform-provider-' or 'terraform-module-'.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query for finding OpenTofu components (e.g., 'aws', 'kubernetes', 'database', 's3')
typeNoType of registry items to search forall

Implementation Reference

  • The inline async handler function for the 'search-opentofu-registry' tool. It invokes the RegistryClient.search method, handles empty results and errors, and formats the output using textResult and renderSearchResults.
    async (params) => { try { const results = await client.search(params.query, params.type); if (results.length === 0) { return textResult(`No results found for "${params.query}" in the OpenTofu Registry.`); } return textResult(`Found ${results.length} results for "${params.query}" in the OpenTofu Registry:\n\n${results.map((r) => renderSearchResults(r)).join("\n\n")}`); } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : "Unknown error"; return textResult(`Error searching the OpenTofu Registry: ${errorMessage}`); } },
  • Zod schema defining the input parameters for the search tool: query (string, min 2 chars) and type (enum with default 'all').
    const searchSchema = { query: z.string().min(2).describe("Search query for finding OpenTofu components (e.g., 'aws', 'kubernetes', 'database', 's3')"), type: z.enum(["provider", "module", "resource", "data-source", "all"]).default("all").describe("Type of registry items to search for"), };
  • MCP server.tool registration call that registers the 'search-opentofu-registry' tool with its name, description, schema, and handler function.
    "search-opentofu-registry", "Search the OpenTofu Registry to find providers, modules, resources, and data sources. Use simple terms without prefixes like 'terraform-provider-' or 'terraform-module-'.", searchSchema, async (params) => { try { const results = await client.search(params.query, params.type); if (results.length === 0) { return textResult(`No results found for "${params.query}" in the OpenTofu Registry.`); } return textResult(`Found ${results.length} results for "${params.query}" in the OpenTofu Registry:\n\n${results.map((r) => renderSearchResults(r)).join("\n\n")}`); } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : "Unknown error"; return textResult(`Error searching the OpenTofu Registry: ${errorMessage}`); } }, );
  • Core search logic in RegistryClient class: performs API fetch to /registry/docs/search with query 'q', optionally filters by type.
    async search(query: string, type?: string): Promise<apiDefinition["SearchResultItem"][]> { const params: Record<string, string> = { q: query }; const response = await this.fetchFromApi<apiDefinition["SearchResultItem"][]>("/registry/docs/search", params); let results = response; if (type && type !== "all") { results = response.filter((item) => item.type.toLowerCase() === type.toLowerCase()); } return results; }
  • Utility function to render a formatted string for each search result item, including type-specific details and instructions for further tools.
    export function renderSearchResults(r: apiDefinition["SearchResultItem"]): string { let result = `- ${r.title} ${r.description.trim()} (${r.type})`; result += ` (latest version: ${r.version})`; switch (r.type) { case "provider": result += `\n Provider: ${r.link_variables.namespace}/${r.link_variables.name}`; result += `\n Provider Details: Use 'get-provider-details' with namespace="${r.link_variables.namespace}" and name="${r.link_variables.name}"`; break; case "module": result += `\n Module: ${r.link_variables.namespace}/${r.link_variables.name} (${r.link_variables.target})`; result += `\n Module Details: Use 'get-module-details' with namespace="${r.link_variables.namespace}", name="${r.link_variables.name}", target="${r.link_variables.target}"`; break; case "provider/resource": { const versionParam = r.version ? `, version="${r.version}"` : ""; result += `\n Resource: ${r.link_variables.namespace}/${r.link_variables.name} (${r.link_variables.id})`; result += `\n Full identifier: ${r.link_variables.name}_${r.link_variables.id}`; result += `\n Resource Docs: Use 'get-resource-docs' with namespace="${r.link_variables.namespace}", name="${r.link_variables.name}", resource="${r.link_variables.id}"${versionParam}`; result += `\n Provider Details: Use 'get-provider-details' with namespace="${r.link_variables.namespace}" and name="${r.link_variables.name}"`; break; } case "provider/data-source": { const versionParam = r.version ? `, version="${r.version}"` : ""; result += `\n Data Source: ${r.link_variables.namespace}/${r.link_variables.name} (${r.link_variables.id})`; result += `\n Full identifier: ${r.link_variables.name}_${r.link_variables.id}`; result += `\n Data Source Docs: Use 'get-datasource-docs' with namespace="${r.link_variables.namespace}", name="${r.link_variables.name}", dataSource="${r.link_variables.id}"${versionParam}`; result += `\n Provider Details: Use 'get-provider-details' with namespace="${r.link_variables.namespace}" and name="${r.link_variables.name}"`; break; } default: result += `\n Unknown type: ${r.type}`; } return result; }

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

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