Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Dependencies
node_modules/
.yarn/cache/
.yarn/unplugged/
.yarn/build-state.yml
.yarn/install-state.gz
.vercel
dist
.xmcp
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ This server provides your AI with dedicated tools for managing your LocalStack e
| [`localstack-aws-replicator`](./src/tools/localstack-aws-replicator.ts) | Replicates external AWS resources into a running LocalStack instance | - Start single-resource replication jobs with a resource type and identifier or ARN<br/>- Start batch replication jobs, such as SSM parameters under a path prefix<br/>- Poll job status by job ID and list existing jobs<br/>- List resource types supported by the running Replicator extension<br/>- Reads source AWS credentials from the MCP server environment and supports optional target account or region overrides |
| [`localstack-app-inspector`](./src/tools/localstack-app-inspector.ts) | Inspects LocalStack application traces, spans, events, and IAM evaluations | - Enable or disable App Inspector for the running LocalStack instance<br/>- List and inspect traces to understand AWS service-to-service flows<br/>- Drill into spans, events, payload metadata, and IAM policy evaluation events<br/>- Filter by service, region, operation, resource, ARN, status, and time range<br/>- Requires a valid LocalStack Auth Token and the App Inspector feature in the connected LocalStack license |
| [`localstack-docs`](./src/tools/localstack-docs.ts) | Searches LocalStack documentation through CrawlChat | - Queries LocalStack docs through a public CrawlChat collection<br/>- Returns focused snippets with source links only<br/>- Helps answer coverage, configuration, and setup questions without requiring LocalStack runtime |
| [`localstack-coverage-advisor`](./src/tools/localstack-coverage.ts) | Checks LocalStack API coverage and deploy-readiness for IaC templates | - Scan Terraform, CloudFormation, CDK, or Pulumi projects and get a per-resource 🟢/🟡/🔴 verdict<br/>- Look up which AWS service operations are implemented vs missing<br/>- Check individual `service:Operation` pairs against the coverage database<br/>- Works fully offline — no running LocalStack instance required |

## Prompts

Expand Down
Binary file added data/coverage.db
Binary file not shown.
4 changes: 4 additions & 0 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@
{
"name": "localstack-app-inspector",
"description": "Inspect LocalStack application traces, spans, events, payload metadata, and IAM policy evaluations"
},
{
"name": "localstack-coverage-advisor",
"description": "Query the LocalStack API coverage database to find out which AWS service operations are implemented and get a deploy-readiness verdict for IaC templates"
}
],
"prompts": [
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"node": ">=20.0.0"
},
"scripts": {
"build": "xmcp build",
"build": "xmcp build && node -e \"require('fs').mkdirSync('dist/data',{recursive:true});require('fs').copyFileSync('data/coverage.db','dist/data/coverage.db')\"",
"dev": "xmcp dev",
"start": "node dist/stdio.js",
"format": "prettier --write .",
Expand All @@ -17,6 +17,7 @@
"test:mcp": "yarn test:mcp:direct && yarn test:mcp:evals"
},
"dependencies": {
"better-sqlite3": "^12.10.0",
"dockerode": "^4.0.7",
"posthog-node": "5.0.0",
"xmcp": "0.6.4",
Expand All @@ -25,6 +26,7 @@
"devDependencies": {
"@gleanwork/mcp-server-tester": "1.0.0-beta.6",
"@playwright/test": "^1.58.2",
"@types/better-sqlite3": "^7.6.13",
"@types/dockerode": "^3.3.43",
"@types/jest": "^30.0.0",
"eslint-config-prettier": "^10.1.8",
Expand Down
1 change: 1 addition & 0 deletions src/core/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export const TOOL_ARG_ALLOWLIST: Record<string, string[]> = {
"localstack-logs-analysis": ["analysisType", "lines", "service", "operation", "filter"],
"localstack-management": ["action", "service", "envVars"],
"localstack-snowflake-client": ["action"],
"localstack-coverage-advisor": ["action", "service"],
};

let posthogClient: PostHog | null = null;
Expand Down
105 changes: 105 additions & 0 deletions src/prompts/coverage-advisor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { z } from "zod";
import { type InferSchema, type PromptMetadata } from "xmcp";
import { withPromptAnalytics } from "../core/analytics";

export const schema = {
iac_path: z
.string()
.optional()
.describe(
"(Optional) Path to a CloudFormation, Terraform, CDK, or SAM project. When provided, the advisor parses the template and checks every required operation automatically."
),
services: z
.string()
.optional()
.describe(
"(Optional) Comma-separated AWS service names to check in full (e.g. 's3,lambda,dynamodb'). Use when you want per-service detail without a template."
),
operations: z
.string()
.optional()
.describe(
"(Optional) Comma-separated 'service:Operation' pairs to check directly (e.g. 's3:CreateBucket,iam:CreateRole'). Overrides auto-extraction when provided."
),
mode: z
.string()
.optional()
.describe(
"(Optional) 'summary' (default) shows only gaps and a deploy verdict; 'full' lists every implemented and missing operation."
),
};

export const metadata: PromptMetadata = {
name: "coverage-advisor",
title: "Coverage Advisor",
description:
"Check LocalStack API coverage for an IaC template, a list of services, or specific operations — and get a clear deploy-readiness verdict.",
role: "user",
};

type PromptArgs = InferSchema<typeof schema>;

export default async function coverageAdvisor(args: PromptArgs): Promise<string> {
return withPromptAnalytics(metadata.name, args, async () => {
const values = {
iac_path: args.iac_path?.trim() ?? "",
services: args.services?.trim() ?? "",
operations: args.operations?.trim() ?? "",
mode: normalize(args.mode, "summary"),
};
return renderCoverageAdvisorPrompt(values);
});
}

function normalize(value: string | undefined, fallback: string): string {
const v = value?.trim();
return v && v.length > 0 ? v : fallback;
}

function renderCoverageAdvisorPrompt(values: {
iac_path: string;
services: string;
operations: string;
mode: string;
}): string {
const hasIac = values.iac_path.length > 0;
const hasServices = values.services.length > 0;
const hasOperations = values.operations.length > 0;

return `# LocalStack Coverage Check

## OUTPUT RULE — follow exactly

Call the tool, then copy its output **verbatim** into your response. No preamble, no summary, no extra analysis, no rephrasing. Your entire response is the raw tool output followed by the patch offer (see below).

## What to call

Use only the \`mcp__localstack__localstack-coverage-advisor\` tool.

${hasOperations
? `Split \`${values.operations}\` on commas and call \`check_operations\` with the resulting array.`
: hasIac
? `Call \`scan_iac\` with \`iac_path: "${values.iac_path}"\`. Do not read the files yourself.`
: hasServices
? `Call \`get_service_coverage\` once for each service in \`${values.services}\` (split on commas).`
: `Call \`scan_iac\` with the workspace root as \`iac_path\`. If the tool returns "No resource types found", ask the user: "I didn't find any IaC files in <path> — where is your Terraform project?"`}

${hasIac && !hasOperations ? `If the template has more than 50 resource types, chunk \`check_resources\` into batches of 50 and concatenate the outputs.` : ""}

## After showing the verdict

If the scan found **any blockers** and the project is Terraform, append exactly this line after the tool output:

> Want me to patch this so it deploys on LocalStack? I'll gate the unsupported resources with \`count = 0\` and add the LocalStack provider config — shown as a diff before anything is changed.

If the user says yes, call \`patch_iac\` with the same \`iac_path\`.

## Absolute prohibitions

- Do NOT read IaC files yourself. The tool does this — call the tool.
- Do NOT add a "LocalStack Tier" column or any tier/edition labels (Community, Pro, etc.).
- Do NOT add file paths or line numbers.
- Do NOT add risk labels, impact descriptions, or percentages.
- Do NOT rewrite, rename, reformat, or reorder any table row.
- Do NOT add any text before the tool output other than the patch offer line above.`;
}
Loading
Loading