Skip to main content
Glama
robhunter

agentdeals

plan_stack

Get infrastructure recommendations, cost estimates, or full audits for your project. Describe your use case for free-tier stack suggestions, or analyze existing services to identify costs and risks.

Instructions

Get stack recommendations, cost estimates, or a full infrastructure audit. Describe what you're building to get a free-tier stack, or pass your current services to estimate costs and find risks.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
modeYesrecommend: free-tier stack for a use case. estimate: cost analysis at scale. audit: risk + cost + gap analysis.
use_caseNoWhat you're building (for recommend mode, e.g. 'Next.js SaaS app')
servicesNoCurrent vendor names (for estimate/audit mode, e.g. ['Vercel', 'Supabase'])
scaleNoScale for cost estimation (default: hobby)
requirementsNoSpecific infra needs for recommend mode (e.g. ['database', 'auth', 'email'])

Implementation Reference

  • The 'plan_stack' tool is registered and implemented in 'src/server.ts'. It handles three modes ('recommend', 'estimate', 'audit') and calls corresponding helper functions ('getStackRecommendation', 'estimateCosts', 'auditStack').
    server.registerTool(
      "plan_stack",
      {
        description:
          "Get stack recommendations, cost estimates, or a full infrastructure audit. Describe what you're building to get a free-tier stack, or pass your current services to estimate costs and find risks.",
        inputSchema: {
          mode: z.enum(["recommend", "estimate", "audit"]).describe("recommend: free-tier stack for a use case. estimate: cost analysis at scale. audit: risk + cost + gap analysis."),
          use_case: z.string().optional().describe("What you're building (for recommend mode, e.g. 'Next.js SaaS app')"),
          services: z.array(z.string()).optional().describe("Current vendor names (for estimate/audit mode, e.g. ['Vercel', 'Supabase'])"),
          scale: z.enum(["hobby", "startup", "growth"]).optional().describe("Scale for cost estimation (default: hobby)"),
          requirements: z.array(z.string()).optional().describe("Specific infra needs for recommend mode (e.g. ['database', 'auth', 'email'])"),
        },
      },
      async ({ mode, use_case, services, scale, requirements }) => {
        try {
          recordToolCall("plan_stack");
    
          if (mode === "recommend") {
            if (!use_case) {
              return {
                isError: true,
                content: [{ type: "text" as const, text: "use_case is required for recommend mode" }],
              };
            }
            const result = getStackRecommendation(use_case, requirements);
            logRequest({ ts: new Date().toISOString(), type: "mcp", endpoint: "plan_stack", params: { mode, use_case, requirements }, result_count: result.stack.length, session_id: getSessionId?.() });
            return {
              content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
            };
          }
    
          if (mode === "estimate") {
            if (!services || services.length === 0) {
              return {
                isError: true,
                content: [{ type: "text" as const, text: "services is required for estimate mode" }],
              };
            }
            const result = estimateCosts(services, scale ?? "hobby");
            logRequest({ ts: new Date().toISOString(), type: "mcp", endpoint: "plan_stack", params: { mode, services, scale: scale ?? "hobby" }, result_count: result.services.length, session_id: getSessionId?.() });
            return {
              content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
            };
          }
    
          if (mode === "audit") {
            if (!services || services.length === 0) {
              return {
                isError: true,
                content: [{ type: "text" as const, text: "services is required for audit mode" }],
              };
            }
            const result = auditStack(services);
            logRequest({ ts: new Date().toISOString(), type: "mcp", endpoint: "plan_stack", params: { mode, services }, result_count: result.services_analyzed, session_id: getSessionId?.() });
            return {
              content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
            };
          }
    
          return {
            isError: true,
            content: [{ type: "text" as const, text: `Unknown mode: ${mode}` }],
          };
        } catch (err) {
          console.error("plan_stack error:", err);
          return {
            isError: true,
            content: [{ type: "text" as const, text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
          };
        }
      }
    );

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/robhunter/agentdeals'

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