Skip to main content
Glama

find_stack

Recommends a complete AI harness stack spanning orchestration, memory, guardrails, and evaluation based on your project description.

Instructions

Assemble a complete AI harness stack for a use case. Given a description of what you're building, returns recommended tools across harness layers: orchestration, tools/MCPs, memory, guardrails, context assembly, and evaluation. This is the key differentiator — Unfragile understands that modern AI systems are composed of 5-15 tools working together.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
descriptionYesWhat you're building (e.g., 'a customer support agent that connects to our Postgres database and Slack, with memory of past conversations')
focusNoStack focus: 'full' = all layers, 'tools-only' = just MCPs and integrations, 'infrastructure' = frameworks and platformsfull

Implementation Reference

  • src/index.ts:629-709 (registration)
    Registration of the 'find_stack' tool on the MCP server with its name, description, and Zod schema for parameters.
    server.tool(
      "find_stack",
      "Assemble a complete AI harness stack for a use case. Given a description of what you're building, returns recommended tools across harness layers: orchestration, tools/MCPs, memory, guardrails, context assembly, and evaluation. This is the key differentiator — Unfragile understands that modern AI systems are composed of 5-15 tools working together.",
      {
        description: z.string().min(10).max(1000).describe("What you're building (e.g., 'a customer support agent that connects to our Postgres database and Slack, with memory of past conversations')"),
        focus: z.enum(["full", "tools-only", "infrastructure"]).default("full").describe("Stack focus: 'full' = all layers, 'tools-only' = just MCPs and integrations, 'infrastructure' = frameworks and platforms"),
      },
      async ({ description, focus }) => {
        log("find_stack", description);
        try {
          // Parallel queries across harness layers
          const layers = focus === "tools-only"
            ? [
                { name: "MCP Servers / Tools", query: `MCP server for ${description}`, type: "mcp" as const },
                { name: "APIs", query: `API for ${description}`, type: "api" as const },
                { name: "Extensions", query: `extension for ${description}`, type: "extension" as const },
              ]
            : focus === "infrastructure"
            ? [
                { name: "Frameworks", query: `framework for ${description}`, type: "framework" as const },
                { name: "Platforms", query: `platform for ${description}`, type: "platform" as const },
                { name: "CLI Tools", query: `CLI for ${description}`, type: "cli" as const },
              ]
            : [
                { name: "Orchestration / Framework", query: `agent framework for ${description}`, type: "framework" as const },
                { name: "MCP Servers / Tools", query: `MCP server for ${description}`, type: "mcp" as const },
                { name: "APIs", query: `API for ${description}`, type: "api" as const },
                { name: "Agents", query: `agent for ${description}`, type: "agent" as const },
                { name: "CLI Tools", query: `CLI tool for ${description}`, type: "cli" as const },
              ];
    
          const results = await Promise.all(
            layers.map(async (layer) => {
              try {
                const data = await searchAPI(layer.query, { limit: 3, type: layer.type });
                return { layer: layer.name, matches: data.matches };
              } catch {
                return { layer: layer.name, matches: [] };
              }
            })
          );
    
          const lines: string[] = [];
          lines.push(`# Harness Stack for: ${description}\n`);
          lines.push(`> Every AI system is a harness — the model is just one component.`);
          lines.push(`> Here's a recommended stack assembled from the Unfragile match graph.\n`);
    
          let totalTools = 0;
          for (const { layer, matches } of results) {
            if (matches.length === 0) continue;
            totalTools += matches.length;
    
            lines.push(`## ${layer}\n`);
            for (const m of matches) {
              const mName = cleanName(m.artifact.name, m.artifact.url);
              const verified = m.artifact.verified ? " ✓" : "";
              const pricing = m.artifact.pricing.free ? "Free" : m.artifact.pricing.model;
              lines.push(`**${mName}${verified}** — ${pricing} | Rank: ${m.artifact.unfragileRank}/100`);
              if (m.artifact.description) lines.push(`${m.artifact.description.slice(0, 200)}`);
              if (m.capabilities.length > 0) {
                const capNames = m.capabilities.slice(0, 3).map((c) => c.name).join(", ");
                lines.push(`Key capabilities: ${capNames}`);
              }
              lines.push(`→ ${m.artifact.url}\n`);
            }
          }
    
          if (totalTools === 0) {
            lines.push("No matching tools found for this use case. This gap has been recorded — the Unfragile graph learns from every query.");
          } else {
            lines.push(`---`);
            lines.push(`*${totalTools} tools across ${results.filter((r) => r.matches.length > 0).length} harness layers. Every query improves the graph.*`);
            lines.push(`*Browse more: https://unfragile.ai/hub*`);
          }
    
          return { content: [{ type: "text" as const, text: lines.join("\n") }] };
        } catch (err) {
          return { content: [{ type: "text" as const, text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };
        }
      }
    );
  • Zod schema defining the input parameters: 'description' (string, 10-1000 chars) and 'focus' (enum: full, tools-only, infrastructure, default full).
    {
      description: z.string().min(10).max(1000).describe("What you're building (e.g., 'a customer support agent that connects to our Postgres database and Slack, with memory of past conversations')"),
      focus: z.enum(["full", "tools-only", "infrastructure"]).default("full").describe("Stack focus: 'full' = all layers, 'tools-only' = just MCPs and integrations, 'infrastructure' = frameworks and platforms"),
    },
  • The handler function for 'find_stack'. Based on the focus parameter, it runs parallel searches across harness layers (orchestration/framework, MCP servers, APIs, agents, CLI tools, etc.), then assembles a markdown stack recommendation.
      async ({ description, focus }) => {
        log("find_stack", description);
        try {
          // Parallel queries across harness layers
          const layers = focus === "tools-only"
            ? [
                { name: "MCP Servers / Tools", query: `MCP server for ${description}`, type: "mcp" as const },
                { name: "APIs", query: `API for ${description}`, type: "api" as const },
                { name: "Extensions", query: `extension for ${description}`, type: "extension" as const },
              ]
            : focus === "infrastructure"
            ? [
                { name: "Frameworks", query: `framework for ${description}`, type: "framework" as const },
                { name: "Platforms", query: `platform for ${description}`, type: "platform" as const },
                { name: "CLI Tools", query: `CLI for ${description}`, type: "cli" as const },
              ]
            : [
                { name: "Orchestration / Framework", query: `agent framework for ${description}`, type: "framework" as const },
                { name: "MCP Servers / Tools", query: `MCP server for ${description}`, type: "mcp" as const },
                { name: "APIs", query: `API for ${description}`, type: "api" as const },
                { name: "Agents", query: `agent for ${description}`, type: "agent" as const },
                { name: "CLI Tools", query: `CLI tool for ${description}`, type: "cli" as const },
              ];
    
          const results = await Promise.all(
            layers.map(async (layer) => {
              try {
                const data = await searchAPI(layer.query, { limit: 3, type: layer.type });
                return { layer: layer.name, matches: data.matches };
              } catch {
                return { layer: layer.name, matches: [] };
              }
            })
          );
    
          const lines: string[] = [];
          lines.push(`# Harness Stack for: ${description}\n`);
          lines.push(`> Every AI system is a harness — the model is just one component.`);
          lines.push(`> Here's a recommended stack assembled from the Unfragile match graph.\n`);
    
          let totalTools = 0;
          for (const { layer, matches } of results) {
            if (matches.length === 0) continue;
            totalTools += matches.length;
    
            lines.push(`## ${layer}\n`);
            for (const m of matches) {
              const mName = cleanName(m.artifact.name, m.artifact.url);
              const verified = m.artifact.verified ? " ✓" : "";
              const pricing = m.artifact.pricing.free ? "Free" : m.artifact.pricing.model;
              lines.push(`**${mName}${verified}** — ${pricing} | Rank: ${m.artifact.unfragileRank}/100`);
              if (m.artifact.description) lines.push(`${m.artifact.description.slice(0, 200)}`);
              if (m.capabilities.length > 0) {
                const capNames = m.capabilities.slice(0, 3).map((c) => c.name).join(", ");
                lines.push(`Key capabilities: ${capNames}`);
              }
              lines.push(`→ ${m.artifact.url}\n`);
            }
          }
    
          if (totalTools === 0) {
            lines.push("No matching tools found for this use case. This gap has been recorded — the Unfragile graph learns from every query.");
          } else {
            lines.push(`---`);
            lines.push(`*${totalTools} tools across ${results.filter((r) => r.matches.length > 0).length} harness layers. Every query improves the graph.*`);
            lines.push(`*Browse more: https://unfragile.ai/hub*`);
          }
    
          return { content: [{ type: "text" as const, text: lines.join("\n") }] };
        } catch (err) {
          return { content: [{ type: "text" as const, text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };
        }
      }
    );
Behavior2/5

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

No annotations are present, so the description carries the full burden. It only states that the tool returns recommendations, but fails to disclose behavioral traits such as whether it is read-only, requires authentication, or if there are rate limits or side effects.

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?

The description is two sentences long, front-loaded with the core purpose, and includes a differentiating statement. Every word earns its place with no redundancy.

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

Completeness3/5

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

Given the lack of output schema and annotations, the description adequately summarizes the tool's function but omits details about the output format or any behavioral implications. It is minimally complete for a recommendation tool, but could be improved.

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?

Input schema coverage is 100%, with both parameters well-described in the schema. The description adds no further semantics beyond restating the purpose, so it meets the baseline without adding extra value.

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 assembles a complete AI harness stack for a use case, and highlights its uniqueness as a key differentiator. It distinguishes itself from siblings like find_mcps by emphasizing a holistic view across multiple harness layers.

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

Usage Guidelines3/5

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

The description implies use when building a complete stack, but does not explicitly state when to avoid this tool or compare it directly to alternatives like find_mcps. The presence of a sibling 'find_mcps' suggests a narrower focused tool, but no exclusion is provided.

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

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