ScreenshotNeo

BlogAI agents

How to Run a Playwright MCP Screenshot Agent on an AWS Mumbai Server

Deploy Playwright MCP on an EC2 instance in Mumbai, connect securely with Session Manager, and capture screenshots from an MCP client.

By the ScreenshotNeo team4 October 20268 min read

Run Playwright MCP on a Linux EC2 instance in AWS Asia Pacific (Mumbai), region ap-south-1. Start its headless server on port 8931, keep that port private, and connect an MCP client through an access-controlled route such as AWS Systems Manager (SSM) Session Manager port forwarding. The documented HTTP MCP endpoint is http://localhost:8931/mcp when the client reaches the server locally. Playwright MCP supports browser navigation and screenshot capture; its Node.js setup requires Node.js 20 or newer.

This guide covers a practical single-instance setup. Instance sizing, uptime, latency, and data residency depend on your workload and configuration; the cited documentation does not promise specific results.

1. Choose Mumbai and prepare an EC2 instance

In the AWS console, select Asia Pacific (Mumbai), ap-south-1, and launch a Linux EC2 instance using an AMI currently supported for your environment. Choose CPU and memory based on the pages and concurrency you expect, then adjust after observing actual browser workload. The referenced AWS tutorial includes an older Amazon Linux 2 example; its AMI and instance size should not be treated as universal current recommendations.

Configure Systems Manager access before deploying the service if you plan to administer the host or forward its MCP port with Session Manager. AWS requires the instance to be managed by Systems Manager. If you are not using default host management, attach an instance profile with the AmazonSSMManagedInstanceCore policy, and make sure the instance has the required network connectivity to SSM endpoints. See AWS Session Manager connection prerequisites and the Session Manager guide.

2. Keep the MCP listener private

Playwright MCP’s standalone HTTP example does not document an authentication mechanism. Keep port 8931 off the public internet. With Session Manager forwarding configured, do not add a public inbound security-group rule for the MCP port. Security groups control inbound and outbound instance traffic; use them to limit access to what the deployment needs. If you choose SSH administration instead, restrict SSH ingress to a known administrator source IP range and do not use a wide-open rule.

This private-route recommendation follows from Playwright’s security warnings and AWS’s access features. Playwright states that “Playwright MCP is not a security boundary.” Its documentation also warns that browser_run_code_unsafe runs arbitrary JavaScript in the server process and is RCE-equivalent, and should only be enabled for trusted MCP clients. Treat every client that can control this server as trusted with the browser’s capabilities.

3. Start Playwright MCP with Node.js

Install Node.js 20 or newer on the instance, then launch the headless server. The official getting-started guide documents this command shape:

npx @playwright/mcp@latest --headless --port 8931

For repeatable operation, pin a reviewed package version rather than relying indefinitely on the floating latest tag. Keep the process attached to a terminal while bringing up the deployment; for a persistent service, arrange restart behavior and logs with the host service manager you operate. The cited docs do not prescribe one production supervisor.

For configuration details and supported options, consult Playwright MCP configuration options. The exact available tools and browser behavior depend on the configuration you run. Do not enable unsafe arbitrary-code execution for clients you do not fully trust.

4. Optional: run the documented Docker server

The Playwright MCP repository also documents a long-running Docker example that starts headless Chromium and the MCP CLI on port 8931. It binds inside the container to 0.0.0.0 and maps the port to the host:

docker run -i --rm --init --pull=always \
  --cap-add=SYS_ADMIN \
  -p 8931:8931 \
  mcr.microsoft.com/playwright/mcp \
  --headless --port 8931

Follow the repository’s current command and container guidance when deploying; its example includes --no-sandbox in some launch forms. That flag is not a blanket security recommendation: understand the container isolation assumptions before using it. Docker’s documented MCP implementation currently supports headless Chromium only. Regardless of container choice, keep host firewall and EC2 security-group rules from exposing the mapped port to untrusted networks.

5. Forward the port with Session Manager

Use the AWS CLI’s Session Manager port-forwarding procedure to create a local tunnel from your workstation to port 8931 on the managed instance. Install the Session Manager plugin required for your platform and use the current AWS procedure for the instance ID and remote port. A typical forwarding session maps a local port to the instance’s port 8931; after it is active, configure the client to reach the local forwarded port using the documented MCP path:

http://localhost:8931/mcp

The exact CLI invocation and prerequisites can vary with your AWS CLI, plugin, and network configuration, so use the current AWS Session Manager port-forwarding instructions. This approach lets you administer and reach the service without adding inbound SSH or MCP listener access to the instance security group, once SSM is configured.

6. Connect an MCP client and capture a screenshot

Configure your MCP client to use the HTTP endpoint reachable from that client. If the client runs on the same machine where the Session Manager tunnel is open, use http://localhost:8931/mcp. If the client runs elsewhere, use a private route it can reach; do not assume that a public IP alone provides safe authentication.

  1. Start the server and verify that the Session Manager tunnel is connected.
  2. Point the MCP client at the server endpoint ending in /mcp.
  3. Ask the client to navigate to a public test page and take a screenshot.
  4. Check that the client reports a successful capture and locate the output using that client and server configuration.

Screenshot output location depends on the MCP server configuration and client. Check the chosen configuration rather than assuming a fixed file path. Playwright’s getting-started guide describes connecting to a separate HTTP server and using screenshot capture.

Security and browser state

Trust the clients that can control the browser

Playwright MCP is an automation server, not a security boundary. Limit network reachability and client access, and place the process in an appropriately isolated host or container for your environment. Configuration features such as origin lists, file-access guardrails, and secret redaction are convenience defenses; the configuration guide says they do not replace real isolation.

In particular, do not enable browser_run_code_unsafe for untrusted clients. It can execute arbitrary JavaScript in the server process. See the Playwright security guidance and configuration options.

Handle persistent sessions as secrets

Playwright MCP can retain browser state in its default profile mode. Cookies, login sessions, and other stored browser state can grant access to accounts. Decide whether you need persistent state, use an access-controlled profile for authenticated browsing, and avoid sharing one browser context among untrusted clients.

Reliability, performance, and cost

  • Size empirically: Browser memory and CPU use vary with page weight, concurrency, viewport, and enabled capabilities. The documentation does not benchmark EC2 sizes. Observe the workload and adjust the instance based on those observations.
  • Plan for restarts: Use the host service manager or container runtime you operate to restart the process after failure or reboot, and retain logs useful for diagnosing startup and navigation issues. The sources do not establish a canonical supervisor or availability target.
  • Check network paths: SSM access depends on instance management, role, and connectivity to the required endpoints. MCP access also depends on the server listener, forwarded port, and client endpoint agreeing.
  • Budget for the whole host: EC2 and related AWS charges depend on the instance, storage, data transfer, and other selected services. No instance-size benchmark or price estimate is established by the cited setup materials; consult your AWS configuration and billing view.
  • Keep the region claim precise: Mumbai identifies the AWS region as ap-south-1. Selecting it does not by itself guarantee a particular latency, data-residency outcome, or compliance result.

Common problems and fixes

Symptom Likely cause What to check
The instance does not appear as a managed SSM node SSM prerequisites, instance role, or endpoint connectivity are missing. Confirm the instance is managed, its role includes AmazonSSMManagedInstanceCore where needed, and its network can reach required SSM endpoints.
Session Manager connects, but the MCP client cannot connect The tunnel is not active, the local port differs, or the endpoint path is wrong. Check the forwarding session, local port, server port 8931, and the /mcp path.
The server exits or the command fails to launch Node.js is older than the documented prerequisite, package startup failed, or the process was closed with its terminal. Use Node.js 20 or newer, inspect startup output, and arrange persistent process supervision for a long-running deployment.
The container starts but the service is unreachable The container port is not mapped or a host/network rule blocks access. Check the port mapping and local tunnel. Keep the security group private; a public inbound rule is not needed for Session Manager forwarding.
The agent sees unexpected logged-in pages or account state A persistent browser profile retained cookies or sessions. Review the configured profile and stored state, isolate authenticated sessions, and restrict access to the browser context.
Pages are slow or the host runs out of resources Page content, concurrency, or enabled browser work exceeds available resources. Reduce concurrent work, observe CPU and memory, and resize based on actual measurements. No universal instance size is established here.
A security review assumes origin lists or redaction isolate the service Configuration guardrails are being treated as a security boundary. Use network and OS/container isolation and trusted-client access controls; follow Playwright’s explicit security warnings.

Or skip the browser setup

If you need screenshots from an application rather than a self-hosted browser agent, ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. Cookie banners, popups, and chat widgets are removed before capture; bot checks, blank pages, and failed loads are never billed.

See the ScreenshotNeo API documentation. This cURL example captures a page:

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -o shot.webp

Python:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://stripe.com',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);

ScreenshotNeo includes 1,000 screenshots a month free with no card; paid plans start at $5 for 3,000. Sign up free and get 1,000 screenshots a month with no card.

FAQ

Does choosing Mumbai guarantee low latency for every user?

No. The region is ap-south-1; actual latency depends on where clients and target sites are and how the deployment is configured.

Can I expose port 8931 publicly and rely on Playwright MCP to authenticate clients?

The documented standalone HTTP example does not describe an authentication mechanism. Keep it private or design a separate authenticated access layer before permitting remote access.

Where will the screenshot file be saved?

That depends on the MCP client and server configuration. Confirm the output behavior of the configuration you deploy.

Is the documented Docker implementation cross-browser?

The repository says its Docker implementation currently supports headless Chromium only.

Sources