Skip to main content
Glama
saasus-platform

SaaSus Docs MCP Server

Official

saasusDocsSearchTool

Search SaaSus Platform documentation with a query to find relevant article URLs. Use this tool to identify articles before retrieving full content.

Instructions

Search SaaSus Platform documentation to find relevant article URLs. Use this tool first to find relevant articles, then use saasus-docs-get-content tool to fetch the full content of specific articles.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query to find relevant SaaSus Platform documentation

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes
resultsYes

Implementation Reference

  • The execute handler function 'searchSaaSusDocs' that fetches a Lunr search index from docs.saasus.io, runs multiple search strategies (exact, wildcard, prefix wildcard, character-split) against it, and returns the top 10 ranked results with scores, titles, URLs and excerpts.
    const searchSaaSusDocs = async (
      query: string
    ): Promise<{ query: string; results: SearchResult[] }> => {
      if (!query) {
        throw new Error("Query is required");
      }
    
      const response = await fetch(INDEX_URL);
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }
    
      const indexData = await response.json();
      if (!Array.isArray(indexData)) {
        throw new Error("Index is not array (expected array)");
      }
    
      const results = indexData.flatMap((indexItem: IndexItem) => {
        const index = lunr.Index.load(indexItem.index);
        const store = indexItem.documents;
    
        // Try multiple search strategies for better recall
        const searchStrategies = [];
    
        // Always try exact query first
        searchStrategies.push(query);
    
        // For single word queries, add wildcard variations
        const words = query.trim().split(/\s+/);
        if (words.length === 1) {
          searchStrategies.push(`${query}*`); // Prefix wildcard
          searchStrategies.push(`*${query}*`); // Contains wildcard
    
          // Only add character-split search for very short single words (1-3 characters)
          if (query.length <= 3) {
            searchStrategies.push(query.split("").join("* ") + "*");
          }
        } else {
          // For multi-word queries, try different combinations
          searchStrategies.push(words.map((word) => `${word}*`).join(" ")); // Each word with prefix wildcard
          searchStrategies.push(words.map((word) => `*${word}*`).join(" ")); // Each word with contains wildcard
        }
    
        const allResults = new Map<string, lunr.Index.Result>();
    
        searchStrategies.forEach((searchQuery, strategyIndex) => {
          try {
            const strategyResults = index.search(searchQuery);
            strategyResults.forEach((result) => {
              const key = String(result.ref);
              if (
                !allResults.has(key) ||
                allResults.get(key)!.score < result.score
              ) {
                // Adjust score based on strategy (exact matches get higher scores)
                const adjustedScore = result.score * (1 - strategyIndex * 0.1);
                allResults.set(key, { ...result, score: adjustedScore });
              }
            });
          } catch (error) {
            // Log search errors for debugging but continue with other strategies
            console.warn(`Search strategy "${searchQuery}" failed:`, error);
          }
        });
    
        return Array.from(allResults.values()).map((searchResult) => {
          const refString = String(searchResult.ref);
          const document = findDocument(store, refString);
    
          return formatResult(searchResult, document);
        });
      });
    
      // Sort by score (descending) and limit to 10 results
      const sortedResults = results.sort((a, b) => b.score - a.score).slice(0, 10);
    
      return { query, results: sortedResults };
    };
  • The tool definition using createTool with id 'saasus-docs-search-urls', inputSchema (query string) and outputSchema (query + results array with score/title/url/excerpt). The execute callback delegates to searchSaaSusDocs.
    export const saasusDocsSearchTool = createTool({
      id: "saasus-docs-search-urls",
      description:
        "Search SaaSus Platform documentation to find relevant article URLs. Use this tool first to find relevant articles, then use saasus-docs-get-content tool to fetch the full content of specific articles.",
      inputSchema: z.object({
        query: z
          .string()
          .describe("Search query to find relevant SaaSus Platform documentation"),
      }),
      outputSchema: z.object({
        query: z.string(),
        results: z.array(
          z.object({
            score: z.number(),
            title: z.string(),
            url: z.string(),
            excerpt: z.string(),
          })
        ),
      }),
      execute: async ({ context }) => {
        return await searchSaaSusDocs(context.query);
      },
    });
  • The MCP server registration where saasusDocsSearchTool is registered alongside saasusDocsContentTool and saasusDocsSitemapTool in the tools map of the MCPServer instance.
    export const mcpServer = new MCPServer({
      name: "SaaSus Platform Docs Search",
      version: packageJson.version,
      tools: {
        saasusDocsSearchTool,
        saasusDocsContentTool,
        saasusDocsSitemapTool,
      },
    });
  • Helper function 'findDocument' that looks up a document by reference number in the store array.
    function findDocument(store: Document[], ref: string): Document {
      return store.find((doc) => doc.i === Number(ref)) || { i: 0 };
    }
  • Helper function 'formatResult' that formats a search result with title, full URL (prefixed with https://docs.saasus.io), and excerpt (first 160 characters).
    function formatResult(
      searchResult: lunr.Index.Result,
      document: Document
    ): SearchResult {
      return {
        score: searchResult.score,
        title: document.s || document.t || "",
        url: `https://docs.saasus.io${document.u || ""}`,
        excerpt: String(document.t || document.s || "")
          .replace(/\s+/g, " ")
          .slice(0, 160),
      };
    }
Behavior3/5

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

No annotations are provided, so the description bears full responsibility. It states the tool returns 'relevant article URLs' but does not disclose search result format, limits, ordering, or pagination. Adequate but incomplete for a search tool.

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?

Two concise sentences: first states purpose, second provides sequential workflow guidance. No redundant information; every sentence adds value.

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?

Given the tool's simplicity (one parameter, output schema present), the description adequately informs the agent of the search-primary-then-fetch-content workflow. Could not be considered incomplete for its complexity level.

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 has 100% coverage for the single 'query' parameter. Description adds no extra meaning beyond 'search query' already in schema. Baseline score is appropriate as schema already documents the parameter.

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?

Clearly states 'Search SaaSus Platform documentation to find relevant article URLs', identifying the verb, resource, and outcome. Distinguishes from siblings by specifying this tool is used first to locate articles before fetching content.

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

Usage Guidelines4/5

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

Explicitly advises to use this tool first, then follow with 'saasus-docs-get-content tool to fetch the full content of specific articles', providing clear sequential guidance. Does not mention when to avoid or alternative scenarios but covers main use case.

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/saasus-platform/saasus-docs-mcp-server'

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