couchbase-mcp-ec2-nginx-https

scottsappen/couchbase-mcp-ec2-nginx-https

3.2

If you are the rightful owner of couchbase-mcp-ec2-nginx-https and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

The Model Context Protocol (MCP) server is a versatile tool designed to facilitate seamless communication and data exchange between clients and Couchbase databases, leveraging both stdio and streamable HTTP(S) protocols.

Couchbase MCP Server on EC2 + MCP Inspector (stdio, streamable_http)

If you follow these steps, you’ll run a Couchbase MCP Server on AWS EC2, expose it over HTTPS on your own domain, and validate both stdio and streamable_http(s) using MCP Inspector.

  • Validated with modelcontextprotocol/inspector@latest
  • Renewal is automatic; if you’re paranoid, add a root cron to reload NGINX after certbot renew.

Goals

  • Spin up an EC2 instance and run the Couchbase MCP Server.
  • Verify stdio locally via MCP Inspector (fast, no-network sanity check).
  • Expose the server over HTTPS using your domain + NGINX + Let’s Encrypt.
  • Verify streamable_http(s) via MCP Inspector from your laptop.

Prerequisites

  • An AWS account (permissions to create EC2 and Security Groups).
  • A registered domain (WordPress.com, Route 53, Cloudflare, etc.) to create a subdomain (e.g., mcp.<your-domain>) pointing at EC2.
  • Basic SSH familiarity.
  • Couchbase cluster you can connect to (Capella or self-managed), with a user that has read permissions for your demo.
  • MCP Inspector installed locally: npx @modelcontextprotocol/inspector@latest

Tip: For early validation, allowlist your laptop IP in your Couchbase firewall/security controls, then later allowlist your EC2 egress IP once HTTPS is in place.


High-Level Workflow

  • Provision EC2 → open 22/80/443 inbound in the Security Group.
  • Install runtime and Couchbase MCP Server on EC2.
  • Validate locally (bind MCP to 127.0.0.1).
  • Install NGINX + Certbot → request TLS for mcp.<your-domain>.
  • Reverse-proxy /mcp → local MCP server with SSE‑friendly settings.
  • Test with MCP Inspector:
    • stdio (local launch)
    • streamable_http(s) (remote HTTPS URL)


1) Launch EC2 & Prepare the Host

1.1 Create the EC2 instance

  • AMI: Amazon Linux 2023
  • Instance type: t3.small (or t3.micro for tiny demos)
  • Security Group (inbound):
    • 22/tcp (SSH) — restrict to your IP(s)
    • 80/tcp (HTTP) — needed for Let’s Encrypt HTTP‑01
    • 443/tcp (HTTPS)
  • Key pair: create/download (e.g., your-keypair.pem)

1.2 SSH in & basic prep

chmod 600 your-keypair.pem
ssh -i your-keypair.pem ec2-user@<EC2_PUBLIC_IP>
sudo dnf update -y
sudo dnf install -y tmux git curl


2) Install & Run Couchbase MCP Server (EC2)

Couchbase’s MCP server can run as stdio (spawned by the client) or as streamable HTTP(S) for remote access. We’ll run HTTP on localhost and let NGINX provide public HTTPS.

2.1 Install Python and a modern runner (uv)

sudo dnf install -y python3 python3-pip
curl -LsSf https://astral.sh/uv/install.sh | sh
exec $SHELL -l
uv --version

2.2 Start Couchbase MCP (HTTP on localhost)

Bind to 127.0.0.1:8000 for safety (public traffic will hit NGINX, not the MCP process directly).

Replace placeholders before running: connection string (Capella or on‑prem), username, password.

# Example: streamable HTTP on localhost:8000 (read-only mode recommended for demos)
uvx couchbase-mcp-server   --transport=http   --host=127.0.0.1   --port=8000   --connection-string "couchbases://<YOUR_CONN_STRING>"   --username "<DB_USERNAME>"   --password "<DB_PASSWORD>"   --read-only-query-mode=true

Confirm listening socket:

sudo ss -ltnp | grep 8000
# Expect: LISTEN ... 127.0.0.1:8000 ... (python/uvx)


3) Test Locally with MCP Inspector — stdio (laptop)

This tests the server locally on your laptop (no EC2/HTTPS yet). It proves the MCP server launches and your Couchbase creds are valid. If this step fails, fix DB access before moving on.

Launch Inspector:

npx @modelcontextprotocol/inspector@latest

In the UI, Connect with:

  • Transport / Type: stdio
  • Command: uvx
  • Args: couchbase-mcp-server
  • Env (set in the UI or your shell):
    • CB_CONNECTION_STRING=couchbases://<YOUR_CONN_STRING>
    • CB_USERNAME=<DB_USERNAME>
    • CB_PASSWORD=<DB_PASSWORD>

Validate:

  • initialize → returns serverInfo & capabilities
  • tools/list → tools are visible
  • Run a simple tool (e.g., list buckets/scopes/collections)


4) Add HTTPS with NGINX + Let’s Encrypt (reverse proxy)

4.1 Create DNS for your HTTPS endpoint

You’ll expose MCP at a friendly name like mcp.<your-domain>.

  1. Go to your DNS records
  2. Add A record
    • Name/Host: mcp
    • Value/Points to: <EC2_PUBLIC_IP>
    • TTL: default is fine

I'd suggest a short wait (a few minutes) for propagation.

Verify from your laptop:

dig +short mcp.<your-domain>
# expect your EC2 IP
curl -I http://mcp.<your-domain>
# expect 200 OK (or plaintext nginx index) on port 80 once nginx is running

4.2 Install and start NGINX (EC2)

sudo dnf install -y nginx certbot python3-certbot-nginx

4.3 Issue the certificate first (standalone mode)

sudo systemctl stop nginx
sudo certbot certonly --standalone   -d mcp.<your-domain>   -m you@example.com   --agree-tos -n
# Confirm files now exist:
sudo ls -l /etc/letsencrypt/live/mcp.<your-domain>
# expect fullchain.pem and privkey.pem symlinks

4.4 NGINX vhost with SSE‑friendly proxy (EC2)

sudo tee /etc/nginx/conf.d/mcp.conf >/dev/null <<'NGINX'
server {
    listen 80;
    server_name mcp.<your-domain>;

    location /.well-known/acme-challenge/ { root /var/www/html; }
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name mcp.<your-domain>;

    ssl_certificate     /etc/letsencrypt/live/mcp.<your-domain>/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mcp.<your-domain>/privkey.pem;

    # Couchbase MCP control + streaming endpoint (streamable_http)
    location /mcp {
        proxy_pass http://127.0.0.1:8000/mcp;

        proxy_set_header Host            $host;
        proxy_set_header X-Forwarded-For $remote_addr;

        # Streaming/SSE-friendly bits
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_buffering off;
        proxy_read_timeout 1h;
        chunked_transfer_encoding off;
    }

    # Simple health at root
    location = / {
        return 200 "OK
";
        add_header Content-Type text/plain;
    }
}
NGINX

sudo nginx -t
sudo systemctl start nginx


5) Test Remotely with MCP Inspector — streamable_http(s)

5.1 Quick curl sanity checks (laptop)

Initialize (must accept both JSON + SSE):

curl -iS -X POST https://mcp.<your-domain>/mcp   -H 'Content-Type: application/json'   -H 'Accept: application/json, text/event-stream'   -d '{
    "jsonrpc":"2.0",
    "id":1,
    "method":"initialize",
    "params":{
      "protocolVersion":"2025-06-18",
      "capabilities":{},
      "clientInfo":{"name":"curl","version":"0.1"}
    }
  }'

5.2 Inspector: Streamable HTTP (laptop)

npx @modelcontextprotocol/inspector@latest
  • Transport / Type: Streamable HTTP
  • URL: https://mcp.<your-domain>/mcp
  • Expect: live session; initialize returns; tools/list works; tools stream results as events.

Make sure you use HTTPS. NGINX sends a 301 redirect to the HTTPS URL for HTTP calls. But if the MCP Inspector uses HTTP it will fail because MCP Inspector’s “Streamable HTTP” connection doesn’t follow redirects for the long-lived SSE streams. Over https://…/mcp, there’s no redirect and the proxy to your local MCP server works—so it connects.



Real-World Considerations

  • So yeah, let's state the obvious here. This is just for a sanity check. In a real world scenario, you would implement real security among other things like using systemd service.