Operator Guide
This guide covers everything an operator needs to configure, deploy, and
monitor a Mentionable agent using the llm-agent-vercel reference example.
For a 5-minute quickstart, see Getting Started.
Gmail OAuth setup
Mentionable uses Gmail as the email transport. The agent receives inbound messages via a Gmail Pub/Sub push subscription and sends replies through the Gmail API.
GCP project setup
Create one GCP project per Mentionable deployment (or share one project across multiple agents using separate Pub/Sub topics).
Enable the four required APIs:
| API | Used for |
|---|---|
| Gmail API | Sending / receiving email, users.watch |
| Cloud Pub/Sub API | Push subscription for inbound email events |
| Cloud Resource Manager API | Resolving your project number |
| IAM API | Creating the Pub/Sub push service account |
gcloud services enable \
gmail.googleapis.com \
pubsub.googleapis.com \
cloudresourcemanager.googleapis.com \
iam.googleapis.com
OAuth 2.0 client
Create a Web application OAuth 2.0 client:
- Console → APIs & Services → Credentials → Create Credentials → OAuth client ID
- Type: Web application (not Desktop)
- Authorized redirect URI:
https://<your-domain>/api/setup/oauth/callback - Copy the client ID and client secret — paste them into
/setup
Pub/Sub topic
- Console → Pub/Sub → Topics → Create Topic
- Name it (e.g.
gmail-inbound). The fully qualified name isprojects/<project-id>/topics/gmail-inbound - Allow Gmail to publish to the topic:
gcloud pubsub topics add-iam-policy-binding gmail-inbound \
--member=serviceAccount:gmail-api-push@system.gserviceaccount.com \
--role=roles/pubsub.publisher
This IAM binding cannot be done through /setup — it requires a separate
gcloud invocation. After running it, paste the topic name into /setup
and click Connect Gmail.
Pub/Sub watchdog
users.watch subscriptions expire after 7 days. The reference example ships
a Vercel Cron job at api/cron/watch-renew that renews the subscription. Ensure
CRON_SECRET is set and the cron schedule in vercel.json is active.
Custom domain configuration
- Deploy the Vercel project (see Getting Started)
- In the Vercel dashboard: Settings → Domains → Add
- Set
DOMAINenv var to the same value (e.g.agent.example.com) - Point your DNS to Vercel (Vercel provides the CNAME / A record to add)
- Redeploy so the new
DOMAINvalue takes effect
The DOMAIN value appears in:
- WebFinger responses (
/.well-known/webfinger) - ActivityPub actor documents
- A2A Agent Card (
/.well-known/agent-card.json) - Outbound email
Fromheaders
ActivityPub federation
The agent auto-publishes an ActivityPub actor at
https://<domain>/ap/<name> and WebFinger discovery at
/.well-known/webfinger?resource=acct:<name>@<domain>.
To federate with Mastodon or another server:
- Ensure your domain is publicly reachable over HTTPS
- The actor document is auto-generated on first request after
/setup - Search for
@<name>@<domain>from any Mastodon account to discover the agent - Follows and mentions are processed via the ActivityPub inbox at
https://<domain>/ap/<name>/inbox
HTTP Signatures are used to authenticate outbound activities. Keys are
generated at first boot and stored in the mentionable_ap_keys Postgres table.
A2A endpoint configuration
The A2A endpoint is available at https://<domain>/a2a/<name> immediately
after deploy. No additional configuration is required beyond DOMAIN.
The Agent Card is published at https://<domain>/.well-known/agent-card.json
and describes the agent’s capabilities, supported input/output modes, and
authentication requirements.
Streaming responses are supported via Server-Sent Events. Use the
message/stream JSON-RPC method instead of message/send.
Environment variables reference
All variables are set via pnpm dlx vercel@latest env add <NAME> production
or in the Vercel dashboard under Settings → Environment Variables.
Required
| Variable | Description |
|---|---|
DOMAIN | Public HTTPS origin (e.g. agent.example.com). Must be reachable from the public internet. |
POSTGRES_URL | Neon pooled connection string. Auto-provisioned if you use Vercel’s Neon integration. |
CONFIG_SECRET | 32-byte random hex. Encrypts secrets in the database. Never rotate on an existing deployment. |
CRON_SECRET | 32-byte random hex. Authenticates the Authorization: Bearer header on cron calls. |
Agent backend (pick one)
| Variable | Description |
|---|---|
ANTHROPIC_API_KEY | Anthropic key for Mode A (direct LLM). |
GITAGENT_REPO | GitHub repo URL for Mode B (agent repo import, gitagent or agents.md format). |
GITAGENT_REF | Branch / tag / SHA for the repo import. Defaults to the default branch. |
GITHUB_TOKEN | Fine-grained PAT with Contents: Read. Required for private repos; lifts rate limits otherwise. |
Optional
| Variable | Description |
|---|---|
POSTGRES_URL_NON_POOLING | Direct (non-pooled) connection for migrations / CLI psql. |
AGENT_LOCAL | Restrict this deployment to a single agent local-part. |
GOOGLE_OAUTH_CLIENT_ID | Gmail OAuth client ID (also configurable via /setup). |
GOOGLE_OAUTH_CLIENT_SECRET | Gmail OAuth client secret (also configurable via /setup). |
GOOGLE_PUBSUB_TOPIC | Fully qualified Pub/Sub topic name. |
ADMIN_TOKEN | Pre-set admin token for /setup (generated on first submit if omitted). |
MENTIONABLE_AGENT_REPO_IMPORT_VERSION | 0.1.0 (persona only) or 0.2.0 (enables sandboxed tool execution). Default: 0.1.0. |
Monitoring
Health endpoint
GET https://<domain>/api/health
Returns {"status":"ok"} with HTTP 200 when the runtime is up and the
database connection is healthy. Use this for uptime checks.
Log format
All runtime logs are emitted to stdout in JSON newline format. Key fields:
| Field | Description |
|---|---|
level | info, warn, or error |
msg | Human-readable message |
transport | activitypub, a2a, or email |
thread_id | Normalized message thread identifier |
duration_ms | Time to first byte from the LLM |
err | Error object (on error logs only) |
Logs are available in the Vercel dashboard under Deployments → Functions Logs
and via vercel logs --follow in the CLI.
Pub/Sub subscription status
If the Gmail push subscription lapses (it expires after 7 days), the agent stops receiving inbound email. Signs:
- No email replies from the agent
warnlog:pubsub subscription not active
Fix: visit /setup and click Re-connect Gmail to renew users.watch.
The Cron job runs daily to prevent expiry in normal operation.