MCPDBWizard

Documentation  ·  Getting started

Quickstart: AWS

This page does one job: get the MCPDBWizard console running in an AWS account and sign you into it. Everything after that — loading a config, generating a server, issuing a token, connecting an agent — is the same wherever the container runs, and it is in the Quickstart.

Use AWS when you want managed capacity: the instance is replaceable, the state survives on EFS, and the template refuses to build network in your account. For a laptop or a server you already administer, Quickstart: Docker is fewer moving parts.

What the stack builds

One EC2 instance running one ECS task, into a VPC and subnets you already have.

It does not create a VPC. A template that builds network in someone else’s account needs a change-review of its own before anyone may run it, which is exactly the friction it was meant to remove. You supply VpcId and SubnetIds; the only requirement on them is that they can reach your Oracle listener.

One instance, one task, and that is not a limitation to fix later. This is a stateful authoring tool, not a horizontally-scalable service: it owns the configs, the accounts, the access matrix and the audit trail, and it launches a child MCP server per running config on loopback inside the container. Two tasks would be two independent products sharing nothing. Scale it by giving the instance more memory, not by adding tasks.

Before you start

1. Put the Oracle password in Secrets Manager

It is passed to the container as a secret rather than an environment variable, so it never appears in docker inspect, the ECS console, the change set or your shell history.

aws secretsmanager create-secret \
  --name mcpdbwizard/oracle \
  --secret-string 'the-password'

Keep the ARN it prints.

2. Get the template

curl -fsSLO https://mcpdbwizard.com/deploy/ecs-ec2.yaml

It is a single CloudFormation template with no dependencies, and it is worth reading before you run it — every decision in it carries a comment saying why.

3. Deploy

aws cloudformation deploy \
  --stack-name mcpdbwizard \
  --template-file ecs-ec2.yaml \
  --capabilities CAPABILITY_IAM \
  --parameter-overrides \
      VpcId=vpc-0123456789abcdef0 \
      SubnetIds=subnet-aaaa\,subnet-bbbb \
      AllowedCidr=10.0.0.0/8 \
      OracleHost=db.example.internal \
      OracleSid=/FREEPDB1 \
      OracleUser=MCPDEMO \
      DbPasswordSecretArn=arn:aws:secretsmanager:eu-west-1:111122223333:secret:mcpdbwizard/oracle-AbCdEf

Two things bite here, both in the first minute:

Escape the comma in SubnetIds. --parameter-overrides uses Key=Value shorthand, in which a bare comma starts the next parameter — so an unescaped list is read as a malformed second override and the error names the wrong parameter.

OracleSid takes a leading / for the service-name form (/FREEPDB1), a bare name for a SID.

The stack takes a few minutes: the ASG has to bring an instance up, the ECS agent has to register it, and the task then pulls the image.

Which image it pulls

ImageSource chooses the registry, and both choices are the same build — one buildx invocation, copied between registries without rebuilding, so they serve the identical manifest digest.

ImageSourceRegistryWho can pull it
Public (default)GitHub Container Registryanyone
MarketplaceAWS Marketplace ECRan account entitled to the product

The Marketplace path needs no IAM change: the task execution role already carries AmazonECSTaskExecutionRolePolicy, and AWS attaches the repository policy that lets an entitled account pull. An account without an entitlement fails the pull, which is the point.

ImageTag names the version and defaults to the current release. Pin it:latest moves under you, and a task that pulls it when the instance is replaced can come back a different build from the one you tested. ImageUri overrides both, for a private mirror or a build of your own.

4. Reach the console

The stack’s ConsoleHint output tells you where.

aws cloudformation describe-stacks --stack-name mcpdbwizard \
  --query 'Stacks[0].Outputs' --output table

Port 8080 is published on the instance and governed by the security group. On a public subnet, browse to the instance’s address on 8080 from within AllowedCidr.

On a private subnet, forward the port rather than opening one. The instance carries AmazonSSMManagedInstanceCore and the template creates no inbound SSH rule even if you pass KeyName:

aws ssm start-session --target i-0123456789abcdef0 \
  --document-name AWS-StartPortForwardingSession \
  --parameters '{"portNumber":["8080"],"localPortNumber":["8080"]}'

Then http://localhost:8080. Do not widen AllowedCidr to make this convenient — 8080 is the admin console as well as the MCP proxy.

5. Sign in

There is no default password, and the stack carries no credential to leak. On first start the container generates one for this deployment, writes it to /data/initial-admin-password on the EFS volume, and the sign-in page names that path. So it has to be read off the instance — which is the whole point of the design.

aws ssm start-session --target i-0123456789abcdef0

then, on the instance:

sudo docker exec "$(sudo docker ps -q --filter name=mcpdbwizard | head -1)" \
     cat /data/initial-admin-password

Sign in as admin and choose your own password. You are made to before the console will do anything else, and the file is deleted when you do.

Seeding happens only when the volume is empty. An existing installation keeps its own accounts, so re-deploying the stack changes nothing — which is the point, but it also means none of this can reset a forgotten password.

Deleting the stack does not delete your data

ConfigFileSystem carries DeletionPolicy: Retain, and it is the single most important line in the template. Every config, every account, the access matrix and the audit trail live there, and none of it exists anywhere else: it was authored by hand and is not reproducible.

So delete-stack leaves the filesystem behind, still accruing a small monthly charge. That is the intended trade — a retained filesystem is a reversible mistake and a deleted one is not. Keep the ConfigFileSystemId output: it is what you need to mount it again, or to delete it deliberately once you are certain.

Four things to know before this faces anything real

Memory is load-bearing. TaskMemory is shared by the web app, the forked generator and one MCP server per running config, each with its own heap. Budget TaskMemory >= (web heap + ~300m) + servers * (server heap + ~200m); at the defaults 4 GB holds the web app and about four concurrent servers, and 8 GB on the instance (t3.large) is the sensible floor. An OOM-killed JVM gets no graceful shutdown, and the kill lands on the largest process rather than the guilty one.

No load balancer, by default. Port 8080 is the admin console as well as the /mcp/<owner>/<config> proxy, so the first version restricts it by security group rather than publishing it. For anything real, put an ALB with an ACM certificate in front and narrow AllowedCidr to the load balancer’s security group.

No rule for 8090–8109, ever. The generated MCP servers bind loopback inside the container and every agent reaches them through the proxy on 8080, which is the only component that knows which account is calling. Opening those ports would bypass the accounts and the access matrix entirely.

Every deployment is a short outage, by design. There is one instance and the task publishes a fixed host port, so a second copy could not start alongside the first even if asked for. The old task stops, then the new one starts. Update by changing ImageTag and deploying again.

Graviton

The image is published for linux/amd64 and linux/arm64, so t4g.large works and is cheaper — but then EcsAmiSsmParameter must be the arm64 AMI:

/aws/service/ecs/optimized-ami/amazon-linux-2023/arm64/recommended/image_id

Changing the instance type alone gives you an instance that cannot run the AMI it was given.

Next

You have a console. Continue at Quickstart step 4 — load the demo config, generate the server, issue a token and point an agent at it.

Auditing, TLS and origin settings, and the licence-tiered retention are in Setting up auditing and Connecting to the MCP server.