DEV Community

Cover image for Build a referral waitlist with your AI agent: Postgres, Auth, Redis and email over one MCP connection
CloudHike Team
CloudHike Team

Posted on

Build a referral waitlist with your AI agent: Postgres, Auth, Redis and email over one MCP connection

This is week 1 of Build with CloudHike, a weekly series where we build a small, real-world app with an AI coding agent and let the agent set up the backend. Disclosure: I built CloudHike, so keep that in mind.

Every side project starts the same way: "I'll put up a waitlist first." Then the waitlist turns into a project of its own. You need a database for the signups, a way to stop bots, a confirmation email, some way to reward people who share it, and a private page where you can see who joined. That's four services before you've written a line of your actual product.

This week we'll build that waitlist with Cursor or Claude Code, and let the agent provision the whole backend through one MCP connection. Every prompt is below, so you can run it yourself.

What we're building

A launch waitlist with referrals:

  • A landing page with an email form. Each signup gets a personal referral link like /?ref=abc123.
  • A "you're #N" confirmation email with that link in it.
  • A live referral leaderboard: every friend who joins with your link moves you up.
  • Rate limiting, so one IP can't flood the list.
  • A private admin page behind a login, showing every signup and the top referrers.

Here's how each piece maps to CloudHike, all in one project:

  • Postgres 16 stores the signups (DATABASE_URL)
  • Redis 7 runs the leaderboard and the rate limiter (REDIS_URL)
  • Email sends the confirmation (EMAIL_API_URL, EMAIL_API_KEY, EMAIL_FROM)
  • Auth protects the admin page (AUTH_URL, AUTH_PUBLISHABLE_KEY, AUTH_SECRET_KEY)

Normally that's a database host, a Redis provider, an email provider and an auth provider: four accounts, four sets of keys, four bills. Here it's one project, one .env and one credit balance, and the agent sets it up.

What you need

  • A CloudHike account. New accounts get $10 in free credits (eligible accounts, once per inbox, valid for 90 days), no card needed. The Free plan allows 2 projects, which is plenty for this.
  • Cursor or Claude Code (Codex, VS Code, Windsurf and Gemini CLI work too).
  • Node.js, for a Next.js app.

Step 1: Connect CloudHike to your agent (once)

In the CloudHike dashboard, open Connect MCP in the sidebar, pick your editor and click Copy with key. That creates your workspace API key and gives you a snippet with the key already filled in. The server is remote (Streamable HTTP), so there's nothing to install.

Claude Code

claude mcp add --transport http --scope user cloudhike https://cloudhike.dev/api/mcp \
  --header "Authorization: Bearer icu_your_api_key"
Enter fullscreen mode Exit fullscreen mode

Run /mcp inside Claude Code to check that it's connected.

Cursor (~/.cursor/mcp.json)

{
  "mcpServers": {
    "cloudhike": {
      "url": "https://cloudhike.dev/api/mcp",
      "headers": {
        "Authorization": "Bearer icu_your_api_key"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Open Cursor Settings → MCP and look for the green dot. Snippets for the other editors are in the MCP docs.

Treat that key like a password. It lives in your home folder, not in the repo, and you can revoke it from the same page.

Step 2: Scaffold the app

npx create-next-app@latest waitlist
cd waitlist
Enter fullscreen mode Exit fullscreen mode

Open the folder in Cursor, or run claude in it.

Step 3: Let the agent provision the backend

This is the step that usually takes an evening of dashboards. Paste this prompt:

Use the cloudhike MCP tools to set up the backend for this app. It's a launch waitlist with referrals.

Create a CloudHike project called "waitlist" and deploy postgres, redis, email and auth. Wait until they're ready. Put the .env into .env.local, make sure it's git-ignored, and don't show me any secret values. Then read the docs for each service with get_docs so you know how to use them. Don't write app code yet. Just tell me which services are running and which variable names are in .env.local.

Behind the scenes, the agent works through CloudHike's MCP tools:

  1. create_project makes the project (or list_projects finds it if it already exists).
  2. deploy_services deploys Postgres, Redis, Email and Auth, with the same plan and billing checks as the dashboard.
  3. wait_for_services waits until each one reports ready.
  4. get_environment returns the project's .env, which the agent writes into .env.local. It can also ask for format: "names" to list just the variable names with no secrets.
  5. get_docs pulls the Postgres, Redis, Email and Auth pages as Markdown, so the code it writes next follows the real API instead of a guess.

One note: the Email service asks you to accept CloudHike's email acceptable use policy, because it's for transactional mail only. If the agent says Email couldn't be deployed, open the project in the dashboard, tick the box on the Email card, click Deploy, and ask the agent to fetch the .env again.

In editors that show MCP prompts as slash commands, CloudHike also offers a built-in setup_backend prompt that does this step in one go.

Step 4: The signups table

Read https://cloudhike.dev/docs/md/postgres. Using node-postgres, create a signups table with a migration script in this repo: id, email (unique), referral_code (unique, short and random), referred_by (nullable referral code), ip, and created_at. Create the pool once in lib/db.ts, keep it on globalThis so hot reloads reuse it, and use max 5 connections. Run the migration, then use the cloudhike describe_table tool to show me the table.

Why a migration in the repo and not SQL straight through MCP? On the Free plan, CloudHike's database tools are read-only: query_database always runs one statement in a READ ONLY transaction. Writing SQL over MCP (execute_sql) is a Pro-only tool, runs in a single transaction, and is marked destructive, so your editor asks before running it. The docs recommend migrations in your code for schema changes anyway, so they're reviewed and repeatable. And no MCP tool can delete a project or service. Your agent gets enough access to build, and no way to wipe your backend.

Step 5: The signup endpoint, rate limit and leaderboard

Read https://cloudhike.dev/docs/md/redis. Add a POST /api/join route that:

  1. Rate limits by IP with Redis using INCR and EXPIRE: at most 5 joins per IP per 10 minutes, answering 429 when over.
  2. Validates the email and inserts it into signups with a new referral_code. If the email already exists, return the existing referral code instead of an error.
  3. If a valid ?ref code came with the request, saves it as referred_by and runs ZINCRBY on a Redis sorted set called "leaderboard" for that code.
  4. Returns the user's position in the list and their referral link. Use one shared ioredis connection from lib/redis.ts, server code only.

The rate limiter is the same INCR and EXPIRE pattern the Redis docs show, and a sorted set is a natural fit for a leaderboard. One thing worth knowing: CloudHike's Redis runs with noeviction (32 MB on Free), so a full Redis refuses writes instead of silently dropping keys. That's why the rate-limit keys get an expiry and the leaderboard stays small.

Step 6: The confirmation email

Read https://cloudhike.dev/docs/md/email. After a new signup in /api/join, send a confirmation email from server code: POST to EMAIL_API_URL/send with the x-api-key header set to EMAIL_API_KEY, from EMAIL_FROM, with fromName "Waitlist" and replyTo set to my support address from a SUPPORT_EMAIL env variable. Subject "You're on the list (#N)". Include their referral link in both html and text. If the API answers 429, still save the signup and log the error. Don't send anything for duplicate signups.

There's no SMTP to configure and no separate email account. Mail goes out from a CloudHike address straight away, and you can switch to your own domain later by verifying it under Email → Domains in the project. Once it's verified, fetching the .env again picks the domain up. The Logs tab shows who each message went to and whether it was delivered. Message bodies aren't stored.

Keep it transactional: a "you're on the list" confirmation is fine, while a launch-day blast to the whole list would be marketing mail, which the Email service doesn't allow.

Step 7: The admin page

Read https://cloudhike.dev/docs/md/auth. Add an admin area with my CloudHike Auth service: a /login page (email and password sign-in), a server route that stores the returned token in an HTTP-only cookie, and a protected /admin page. On /admin, call get-session from server code and allow access only when the user's email matches an ADMIN_EMAIL env variable. Show the total number of signups, the newest 50, and the top 10 referrers from the Redis leaderboard. Add a sign-out button. Never send AUTH_SECRET_KEY to the browser.

Sign up once with your admin email (a tiny /signup page or the sign-up/email endpoint from the Auth docs works). Because the project already has Postgres, Auth uses its auth schema by default, so your users sit next to your signups and there's still nothing new to host. If you'd rather sign in with GitHub or Google, the Auth card has a shared OAuth app you can switch on.

To check the data without leaving the editor, ask:

Use the cloudhike query_database tool to show the 10 most recent signups and how many came from a referral.

That runs read-only, so it's safe to let the agent explore. You can also open the database explorer in the dashboard to browse the rows.

Step 8: Deploy to Vercel

CloudHike doesn't host apps yet (app hosting is coming soon), so we deploy the Next.js app to Vercel and keep the backend on CloudHike:

  1. Push the repo to GitHub. Check that .env.local is not in the commit.
  2. Import the repo in Vercel.
  3. Add the variables from .env.local under the project's Environment Variables, plus ADMIN_EMAIL and SUPPORT_EMAIL. In the CloudHike dashboard, Environment → Copy as .env gives you the whole file, so you don't have to retype it.
  4. Deploy.

A few production notes from the docs:

  • Keep the database pool small. DATABASE_URL already goes through a connection pooler (PgBouncer), but each serverless instance opens its own pool, so max: 5 matters.
  • Free databases sleep. A Free database with no connections for 6 hours is stopped until you click Wake on the card. Pro databases are always on and run in their own container.
  • Email limits. Free sends 100 emails a day and 3,000 a month. On Pro there's no daily limit, 3,000 a month are included per project, and more cost $0.40 per 1,000. If your launch goes viral, that's the limit you'll hit first.
  • Auth return sites. If you turn on "Require a verified email" or social sign-in, add your Vercel domain under Sites users can return to on the Auth card.

What CloudHike handled

Look back at what you didn't do: you didn't sign up for a Redis provider, configure SMTP, set up an auth service or copy connection strings between tabs. One MCP connection let the agent:

  • create the project and deploy four services,
  • write the .env without showing secrets in chat,
  • read the real docs for each service before writing code,
  • inspect the schema and data with read-only tools.

Everything shows up in one dashboard and comes out of one credit balance. If you outgrow Free, Pro is $10/month with $10 of usage credits included every month and unlimited projects. The details are on the plans and billing page.

Your turn

The whole build is the five prompts above, plus the optional query. Run them, tweak them, and see how far your agent gets.

👉 Start free at cloudhike.dev. You get $10 in credits, no card required.

Next week: we put background jobs to work and build an AI app that runs slow work outside the request with retries and webhooks. Follow along so you don't miss it.

If you try this one, tell me in the comments what your agent built, or where it got stuck. I read every comment.

Top comments (0)