Skip to main content
Glama
sorodriguezz

IRIS ObjectScript MCP Server

by sorodriguezz

smart_search

Search IRIS ObjectScript documentation by querying local cache first, then downloading documents if needed to find relevant information.

Instructions

Búsqueda inteligente: primero en caché local, luego descarga documentos si es necesario

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
qYesSearch query
keysNoKEYs específicos de documentos a descargar si no hay resultados en caché (opcional)

Implementation Reference

  • Core handler function for smart_search tool: performs intelligent search by first checking local cache, downloading relevant documents if cache is insufficient, and returning formatted results.
    export async function smartSearch(
      query: string,
      suggestedKeys?: string[]
    ): Promise<SmartSearchResult> {
      // Paso 1: Buscar en caché local
      const cacheResults = await searchInCache(query);
      const hasGoodCacheResults =
        cacheResults.length > 200 &&
        !cacheResults.includes("No se encontraron resultados");
    
      if (hasGoodCacheResults) {
        return {
          foundInCache: true,
          cacheResults,
          finalResults: `# Resultados encontrados en caché local\n\n${cacheResults}`,
        };
      }
    
      // Paso 2: Si no hay buenos resultados en caché, intentar descargar documentos relevantes
      const downloadedDocs: string[] = [];
      const potentialKeys = suggestedKeys || generatePotentialKeys(query);
    
      // Intentar descargar documentos que podrían contener la información buscada
      for (const key of potentialKeys) {
        const doc = await fetchDocByKey(key);
        downloadedDocs.push(key);
      }
    
      // Paso 3: Buscar nuevamente en caché después de las descargas
      let finalResults = "";
      if (downloadedDocs.length > 0) {
        const newCacheResults = await searchInCache(query);
        finalResults = `# Resultados después de descargar documentos\n\n## Documentos descargados:\n${downloadedDocs
          .map((key) => `- ${key}`)
          .join("\n")}\n\n## Resultados de búsqueda:\n\n${newCacheResults}`;
      } else {
        finalResults = `# No se encontraron resultados\n\nNo se pudieron encontrar documentos relevantes para "${query}".\n\n## Caché local:\n${cacheResults}\n\n## Sugerencias:\n- Verifica la ortografía del término\n- Intenta con términos más específicos\n- Usa las herramientas open_by_key u open_class directamente`;
      }
    
      return {
        foundInCache: false,
        cacheResults,
        downloadedDocs,
        finalResults,
      };
    }
  • Tool schema definition including input schema for 'q' (required query) and optional 'keys'.
    export const SMART_SEARCH: Tool = {
      name: "smart_search",
      description:
        "Búsqueda inteligente: primero en caché local, luego descarga documentos si es necesario",
      inputSchema: {
        type: "object",
        properties: {
          q: {
            type: "string",
            description: "Search query",
            minLength: 2,
          },
          keys: {
            type: "array",
            items: {
              type: "string",
            },
            description:
              "KEYs específicos de documentos a descargar si no hay resultados en caché (opcional)",
          },
        },
        required: ["q"],
      },
    };
  • Registration of smart_search tool as part of core tools array.
    export const coreTools = async () => {
      return {
        tools: [SMART_SEARCH, SEARCH_OBJECTSCRIPT, OPEN_BY_KEY, OPEN_CLASS],
      };
    };
  • MCP tool dispatcher handler that invokes smartSearch and formats response for the smart_search tool.
    case "smart_search": {
      const query = args?.q as string;
      const suggestedKeys = args?.keys as string[] | undefined;
    
      if (!query) {
        throw new Error("Query is required");
      }
    
      const result = await smartSearch(query, suggestedKeys);
      return {
        content: [
          {
            type: "text",
            text: result.finalResults,
          },
        ],
      };
    }
  • Helper function to search within local cache files, used by smartSearch.
    export async function searchInCache(query: string): Promise<string> {
      const results: SearchResult[] = [];
    
      try {
        const files = await readdir(cacheDir);
        const mdFiles = files.filter((f) => f.endsWith(".md"));
    
        for (const file of mdFiles) {
          const filePath = path.join(cacheDir, file);
          const content = await readFile(filePath, "utf-8");
    
          // Buscar la query en el contenido (case insensitive)
          const lines = content.split("\n");
          const matches: SearchResult["matches"] = [];
    
          lines.forEach((line, index) => {
            if (line.toLowerCase().includes(query.toLowerCase())) {
              // Agregar contexto (línea anterior y siguiente si existen)
              const contextLines: string[] = [];
              if (index > 0)
                contextLines.push(`  ${index}: ${lines[index - 1].trim()}`);
              contextLines.push(`> ${index + 1}: ${line.trim()}`);
              if (index < lines.length - 1)
                contextLines.push(`  ${index + 2}: ${lines[index + 1].trim()}`);
    
              matches.push({
                lineNumber: index + 1,
                line: line.trim(),
                context: contextLines.join("\n"),
              });
            }
          });
    
          if (matches.length > 0) {
            results.push({
              fileName: file
                .replace(".md", "")
                .replace("doc_", "")
                .replace("class_", ""),
              matches: matches.slice(0, 5), // Limitar a 5 coincidencias por archivo
            });
          }
        }
    
        if (results.length === 0) {
          return `No se encontraron resultados para "${query}" en el caché local.\n\nSugerencias:\n- Verifica la ortografía\n- Intenta con términos más específicos\n- Usa las herramientas open_by_key u open_class para buscar documentación específica`;
        }
    
        // Formatear resultados
        const formattedResults: string[] = [];
        formattedResults.push(
          `Se encontraron ${results.length} archivo(s) con coincidencias para "${query}":\n`
        );
    
        results.forEach((result, index) => {
          formattedResults.push(`## ${index + 1}. ${result.fileName}`);
          formattedResults.push(
            `Coincidencias encontradas: ${result.matches.length}\n`
          );
    
          result.matches.forEach((match, matchIndex) => {
            formattedResults.push(
              `### Coincidencia ${matchIndex + 1} (Línea ${match.lineNumber})`
            );
            if (match.context) {
              formattedResults.push("```");
              formattedResults.push(match.context);
              formattedResults.push("```\n");
            }
          });
        });
    
        return formattedResults.join("\n");
      } catch (error) {
        return `Error al buscar en el caché: ${
          error instanceof Error ? error.message : "Error desconocido"
        }`;
      }
    }
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. It mentions the cache-first then download approach, but doesn't describe what happens when documents are downloaded (where they go, format, permissions needed), rate limits, error conditions, or what 'smart' entails beyond the two-phase process.

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

Conciseness4/5

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

The description is a single, efficient Spanish sentence that clearly states the core functionality. It's appropriately sized for the tool's complexity, though it could be slightly more structured by separating the two phases more explicitly.

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

Completeness2/5

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

For a search tool with no annotations and no output schema, the description is insufficient. It doesn't explain what constitutes a 'result', what format results come in, whether there's pagination, how many results are returned, or what happens when downloads fail. The two-phase approach is mentioned but not elaborated.

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 documents both parameters well. The description adds minimal value beyond the schema - it implies 'keys' parameter is used for downloading when cache misses, but doesn't provide additional context about key formats or relationships between query and keys.

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

Purpose4/5

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

The description clearly states the tool performs 'smart search' with a two-phase approach: first in local cache, then downloading documents if needed. It specifies the verb 'search' and resource 'documents', but doesn't differentiate from sibling tools like 'search_objectscript' or 'open_by_key' which might have overlapping functionality.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives like 'search_objectscript' or 'open_by_key'. It mentions the two-phase approach but doesn't specify scenarios where this is preferable over direct download or cache-only searches.

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/sorodriguezz/iris-mcp-intelligence'

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