Skip to main content
Glama
localstack

LocalStack MCP Server

Official
by localstack

localstack-management

Control LocalStack's lifecycle: start, stop, restart, or check status of your local AWS development environment.

Instructions

Manage LocalStack lifecycle: start, stop, restart, or check status

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesThe LocalStack management action to perform
envVarsNoAdditional environment variables as key-value pairs (only for start action)

Implementation Reference

  • Primary handler that runs preflights and routes to action-specific helpers based on the 'action' input.
    export default async function localstackManagement({
      action,
      envVars,
    }: InferSchema<typeof schema>) {
      const preflightError = await runPreflights([requireLocalStackCli()]);
      if (preflightError) return preflightError;
    
      switch (action) {
        case "start":
          return await handleStart({ envVars });
        case "stop":
          return await handleStop();
        case "restart":
          return await handleRestart();
        case "status":
          return await handleStatus();
        default:
          return ResponseBuilder.error(
            "Unknown action",
            `❌ Unknown action: ${action}. Supported actions: start, stop, restart, status`
          );
      }
    }
  • Input schema using Zod for validation of 'action' and optional 'envVars'.
    export const schema = {
      action: z
        .enum(["start", "stop", "restart", "status"])
        .describe("The LocalStack management action to perform"),
      envVars: z
        .record(z.string())
        .optional()
        .describe("Additional environment variables as key-value pairs (only for start action)"),
    };
  • Tool metadata defining name, description, and annotations for registration.
    export const metadata: ToolMetadata = {
      name: "localstack-management",
      description: "Manage LocalStack lifecycle: start, stop, restart, or check status",
      annotations: {
        title: "LocalStack Management",
        readOnlyHint: false,
        destructiveHint: false,
        idempotentHint: false,
      },
    };
  • Core logic for starting LocalStack: spawns process, handles output, polls for readiness with timeout.
    async function handleStart({ envVars }: { envVars?: Record<string, string> }) {
      const statusCheck = await getLocalStackStatus();
      if (statusCheck.isRunning) {
        return ResponseBuilder.markdown(
          "⚠️  LocalStack is already running. Use 'restart' if you want to apply new configuration."
        );
      }
    
      const environment = { ...process.env, ...(envVars || {}) } as Record<string, string>;
      if (process.env.LOCALSTACK_AUTH_TOKEN) {
        environment.LOCALSTACK_AUTH_TOKEN = process.env.LOCALSTACK_AUTH_TOKEN;
      }
    
      return new Promise((resolve) => {
        const child = spawn("localstack", ["start"], {
          env: environment,
          stdio: ["ignore", "ignore", "pipe"],
        });
    
        let stderr = "";
        child.stderr.on("data", (data) => {
          stderr += data.toString();
        });
    
        let earlyExit = false;
        let poll: NodeJS.Timeout;
        child.on("error", (err) => {
          earlyExit = true;
          if (poll) clearInterval(poll);
          resolve(ResponseBuilder.markdown(`❌ Failed to start LocalStack process: ${err.message}`));
        });
    
        child.on("close", (code) => {
          if (earlyExit) return;
          if (poll) clearInterval(poll);
          if (code !== 0) {
            resolve(
              ResponseBuilder.markdown(
                `❌ LocalStack process exited unexpectedly with code ${code}.\n\nStderr:\n${stderr}`
              )
            );
          }
        });
    
        const pollInterval = 5000;
        const maxWaitTime = 120000;
        let timeWaited = 0;
    
        poll = setInterval(async () => {
          timeWaited += pollInterval;
          const status = await getLocalStackStatus();
          if (status.isReady || status.isRunning) {
            clearInterval(poll);
            let resultMessage = "🚀 LocalStack started successfully!\n\n";
            if (envVars)
              resultMessage += `✅ Custom environment variables applied: ${Object.keys(envVars).join(", ")}\n`;
            resultMessage += `\n**Status:**\n${status.statusOutput}`;
            resolve(ResponseBuilder.markdown(resultMessage));
          } else if (timeWaited >= maxWaitTime) {
            clearInterval(poll);
            resolve(
              ResponseBuilder.markdown(
                `❌ LocalStack start timed out after ${maxWaitTime / 1000} seconds. It may still be starting in the background.`
              )
            );
          }
        }, pollInterval);
      });
    }
  • Helper for 'status' action: retrieves and formats LocalStack status information.
    async function handleStatus() {
      const statusResult = await getLocalStackStatus();
    
      if (statusResult.statusOutput) {
        let result = "📊 LocalStack Status:\n\n";
        result += statusResult.statusOutput;
    
        // Add helpful information based on the status
        if (statusResult.isRunning) {
          result += "\n\n✅ LocalStack is currently running and ready to accept requests.";
        } else {
          result += "\n\n⚠️  LocalStack is not currently running. Use the start action to start it.";
        }
    
        return ResponseBuilder.markdown(result);
      } else {
        const result = `❌ ${statusResult.errorMessage}
    
    This could happen if:
    - LocalStack is not installed properly
    - There was an error executing the status command
    - LocalStack services are not accessible
    
    Try running the CLI check first to verify your LocalStack installation.`;
    
        return ResponseBuilder.markdown(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/localstack/localstack-mcp-server'

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