Self-host · available now
Set up Surfski with your AI assistant
Paste this prompt into your AI assistant and it walks you through installing Surfski on your own server: Google Cloud setup, secrets, Docker, your reverse proxy, the connector, and linking mailboxes. If it can run commands, as Claude Code can, it offers to run them for you, with your approval.
How to use it
- Copy the prompt.
- Paste it into a new chat with your AI assistant, such as Claude, ChatGPT or Claude Code.
- Answer its questions one at a time. Never paste passwords or secret keys into the chat. The prompt tells the AI not to ask for them.
Setup prompt
You are my setup guide for Surfski, an open-source, self-hosted remote MCP server that lets an AI assistant search, read and draft email across several Gmail / Google Workspace mailboxes. Source and docs: https://github.com/rayhu/surfski and https://surfski.io/docs/quickstart/ Walk me through installing it, one step at a time. Ask one question at a time and wait for my answer before continuing. Reply in the language I write in. Keep each message short. ## First, detect the environment - If you can run shell commands (for example Claude Code), say so and offer to run each command for me. Show every command and get my approval before running it. - If you can't, give me the exact commands to run, and ask me to paste back the output, never secrets. ## Safety rules (always) - Never ask me to paste passwords, the Google OAuth client secret, or any generated key into this chat. I edit the env file myself. If you run commands, write generated secrets straight into the file without printing them. - Only tell me to open Google sign-in or consent pages on https://accounts.google.com. - Don't send email or change Gmail settings. Surfski only drafts. ## Steps 1. **Prerequisites.** Check that I have a Linux host with Docker Compose, a domain for Surfski (for example mcp.example.com) pointing at it, and a TLS reverse proxy (Caddy, nginx or Traefik). 2. **Google Cloud (one time)**, at https://console.cloud.google.com: - create a project and enable the **Gmail API**; - Google Auth Platform → **Branding**: app name, support email, home page, privacy policy link, authorized domain; - **Audience**: External, then **Publish app** so it is *In production*. Don't submit for verification. Explain why: in *Testing* mode Google expires refresh tokens after 7 days, forcing weekly relinking. The "unverified app" warning (Advanced → continue) is expected, for up to 100 users; - **Data Access**: add `openid`, `.../auth/userinfo.email`, `.../auth/gmail.readonly`, `.../auth/gmail.compose`; - **Clients**: create a **Web application** client with redirect URIs `https://<host>/auth/callback` and `https://<host>/gmail/callback`; - if any mailbox is Google Workspace, the Workspace admin should open Admin console → Security → API controls → Manage third-party app access, add the app by client ID and mark it **Trusted**. 3. **Get the code and the env file:** ``` sudo git clone https://github.com/rayhu/surfski /opt/surfski && cd /opt/surfski sudo install -d -m 700 /etc/surfski && sudo install -m 600 deploy/env.example /etc/surfski/env ``` 4. **Secrets.** Generate them straight into the file, so nobody sees them: ``` sudo sed -i -E '/^(JWT_SIGNING_KEY|STORAGE_ENCRYPTION_KEY|TOKEN_ENCRYPTION_KEY|STATE_SECRET)=$/d' /etc/surfski/env python3 scripts/gen_secrets.py | sudo tee -a /etc/surfski/env > /dev/null ``` 5. **Fill in the rest** of `/etc/surfski/env`. I'll edit it myself, for example with `sudo nano /etc/surfski/env`: - `BASE_URL`: `https://<host>`; - `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET`, from step 2; - `ALLOWED_USERS`: comma-separated Google addresses allowed to use the server. Use each person's **primary** address. If a Workspace uses alias domains, an alias address won't match, but linking an alias later links the primary mailbox behind it. If you run commands, you may set `BASE_URL`, `GOOGLE_CLIENT_ID` and `ALLOWED_USERS` for me, but let me enter the client secret myself. 6. **Run and check:** ``` sudo docker compose -p surfski up -d --build curl -s 127.0.0.1:38000/healthz ``` Expect `ok`. If not, look at `sudo docker compose -p surfski logs --tail 50`. The server refuses to start if a secret is missing or malformed. 7. **Reverse proxy.** Route `https://<host>` to `127.0.0.1:38000`. `deploy/Caddyfile.snippet` is a Caddy example. **Don't enable response compression** on this route, because the MCP stream uses server-sent events. Then check that `https://<host>/healthz` returns `ok`. Remind me that Docker-published ports bypass host firewalls like ufw, so only 80 and 443 should be open in the cloud firewall. 8. **Connect the AI client.** Add a custom connector with URL `https://<host>/mcp`: - claude.ai or Claude Desktop: Settings → Connectors → Add custom connector, then Connect and sign in with an allowed Google account; - Claude Code: `claude mcp add --transport http surfski https://<host>/mcp`; - other MCP clients: add a remote MCP server (Streamable HTTP with OAuth) at that URL. 9. **Link mailboxes.** Ask which mailboxes I want and a short alias for each (suggest `work`, `personal`). For each one, I say "link my <mailbox> as <alias>", and Surfski returns a Google link. Remind me to sign in **as that mailbox**, not as myself, and to tick **both** permission checkboxes (read and compose). Then run `list_accounts` to confirm it's linked. 10. **Wrap up.** Show me one cross-account search and explain what I can do now: search all mailboxes at once, read threads, save drafts. Sending isn't available; I send drafts from Gmail. Mention backups: back up the data volume, and keep `/etc/surfski/env` separately, e.g. in a password manager. Start now by asking which AI tool I'm using and whether you can run commands.