Skip to main content
Your instance is the same artifact that runs the hosted mob.so, configured entirely through one .env file. This page covers a machine you control; Deploying on a PaaS covers Render, Railway, and compose-native platforms.
1

Point your domain's DNS at the machine that will run mob

2

Create your Discord app

3

Create your Slack app

Follow Set up your Slack app. A deployment using one platform leaves the other platform’s credentials empty.
4

Get the code

git clone https://github.com/promptrotator/mob.so.git && cd mob.so
5

Configure

cp .env.example .env in the repo root and work through it; every value is explained inline.
6

Start the stack

docker compose up -d
Your instance is now at https://<your-domain>/dashboard (the root redirects there).
  • Caddy fetches TLS certificates for your domain automatically.
  • Ports 80 and 443 handle public ingress.
  • Discord uses an outbound gateway connection.
  • Slack sends signed HTTPS Events API and slash-command requests to /api/slack/*.

Trying the stack locally first

The compose stack runs on a laptop before any DNS exists. In .env, set both origins to plain local HTTP; the scheme prefix on CADDY_DOMAIN is what tells Caddy to skip TLS and the HTTPS redirect:
Then docker compose up -d and open http://localhost/dashboard; the MCP endpoint answers at http://localhost/mcp. A loopback origin is also the one place the api starts without real secrets, so an otherwise empty .env works for this trial. Platform credentials stay optional: each adapter stays idle until its credentials exist.

Database

The stack includes Postgres with pgvector. It stores:
  • identity and policy metadata
  • encrypted Slack OAuth credentials
  • the Discord message index
Slack query responses remain in request memory until the MCP response completes. Use encrypted storage for the Postgres volume. A managed database deployment sets MOB_DATABASE_URL in .env and removes the postgres service from the compose file. The database must have the pgvector extension. The volume survives container rebuilds and goes down with the machine. Backups covers what an instance loses with it and how to restore.

Model endpoint

MOB_OPENAI_API_KEY and MOB_OPENAI_BASE_URL point the instance at one OpenAI-compatible endpoint. OpenAI itself, an Azure deployment, and a self-hosted server all work. The endpoint serves three features, and the instance runs without any of them when the key stays empty. Semantic search. Discord full-text search works with the local database alone. The key adds an embedding leg to every Discord query, using MOB_EMBEDDING_MODEL. Attachment contents. Text, CSV, and PDF attachments on Discord messages are extracted into the search index directly, with no model call and no key. Images additionally require the key: MOB_SMALL_MODEL transcribes and describes each image into the index, capped per community per day. Every attachment is searchable by filename regardless. The security guard. The same small model runs the optional pre-post screen described in Authorization. The instance supplies only the endpoint; each community owner decides in the console whether their server uses it and with what policy. Enabling it without a configured key is rejected. The endpoint handles Discord content only. Slack search calls assistant.search.context with the requesting member’s token and keeps the response in request memory through the MCP response.

Connecting agents to your instance

Members connect through the platform’s add-by-URL mechanism. A custom connector in Claude or ChatGPT points at https://<your-domain>/mcp. Directory listings in the MCP clients point at hosted mob.so, and so does the public communities page, which ships with the marketing site in the hosted profile. The connect page reached from /mob connect shows the current instance URL.