localstack-aws-client
Execute AWS CLI commands against LocalStack for local development and testing without requiring 'awslocal' prefix.
Instructions
Executes an AWS CLI command against the running LocalStack container using the 'awslocal' wrapper.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| command | Yes | The AWS CLI command to execute (e.g., 's3 ls', 'dynamodb list-tables'). Do not include 'awslocal' or 'aws'. |
Implementation Reference
- src/tools/localstack-aws-client.ts:29-73 (handler)Main handler function that executes the provided AWS CLI command against the LocalStack container using Docker API.export default async function localstackAwsClient({ command }: InferSchema<typeof schema>) { const preflightError = await runPreflights([requireLocalStackRunning()]); if (preflightError) return preflightError; try { const dockerClient = new DockerApiClient(); const containerId = await dockerClient.findLocalStackContainer(); const sanitized = sanitizeAwsCliCommand(command); const args = splitArgsRespectingQuotes(sanitized); const cmd = ["awslocal", ...args]; const result = await dockerClient.executeInContainer(containerId, cmd); if (result.exitCode === 0) { return ResponseBuilder.markdown(result.stdout || ""); } // Coverage / unimplemented service hints const stderr = result.stderr || ""; const actionMatch = stderr.match(/The API action '([^']+)' for service '([^']+)' is either not available in your current license plan or has not yet been emulated by LocalStack/i); const serviceMatch = stderr.match(/The API for service '([^']+)' is either not included in your current license plan or has not yet been emulated by LocalStack/i); if (actionMatch) { const service = actionMatch[2]; const link = `https://docs.localstack.cloud/references/coverage/coverage_${service}`; return ResponseBuilder.error( "Service Not Implemented in LocalStack", `The requested API action may not be implemented. Check coverage: ${link}\n\n${stderr}` ); } if (serviceMatch) { const link = "https://docs.localstack.cloud/references/coverage"; return ResponseBuilder.error( "Service Not Implemented in LocalStack", `The requested service may not be implemented. Check coverage: ${link}\n\n${stderr}` ); } return ResponseBuilder.error("Command Failed", result.stderr || "Unknown error"); } catch (err) { const message = err instanceof Error ? err.message : String(err); return ResponseBuilder.error("Execution Error", message); } }
- Zod schema defining the input parameter 'command' for the tool.export const schema = { command: z .string() .trim() .min(1, { message: "The command string cannot be empty." }) .describe( "The AWS CLI command to execute (e.g., 's3 ls', 'dynamodb list-tables'). Do not include 'awslocal' or 'aws'." ), };
- src/tools/localstack-aws-client.ts:20-27 (registration)Tool metadata registration including name, description, and annotations.export const metadata: ToolMetadata = { name: "localstack-aws-client", description: "Executes an AWS CLI command against the running LocalStack container using the 'awslocal' wrapper.", annotations: { title: "LocalStack AWS Client", }, };
- Helper function to split command string into arguments respecting quotes.function splitArgsRespectingQuotes(input: string): string[] { const args: string[] = []; let current = ""; let inSingle = false; let inDouble = false; for (let i = 0; i < input.length; i++) { const ch = input[i]; if (ch === "'" && !inDouble) { inSingle = !inSingle; continue; } if (ch === '"' && !inSingle) { inDouble = !inDouble; continue; } if (!inSingle && !inDouble && /\s/.test(ch)) { if (current.length > 0) { args.push(current); current = ""; } continue; } current += ch; } if (current.length > 0) args.push(current); return args; }