环境变量
自托管 Melso 常用的服务端、存储、集成和运行时配置。
Melso 在进程启动时读取环境变量。修改后通常需要重启对应的 API、Web 或守护进程。Docker Compose 的 docker compose restart 不会重新读取 .env,要用 up -d 重建容器才能生效。
本页只列面向部署者的配置;测试变量和内部任务变量不在这里展开。本页是分组参考;完整部署步骤见自托管快速上手。
生产环境最小配置
DATABASE_URL=postgres://user:password@postgres:5432/multica?sslmode=require
JWT_SECRET=<long-random-secret>
APP_ENV=production
FRONTEND_ORIGIN=https://multica.example.com
MULTICA_APP_URL=https://multica.example.com
MULTICA_PUBLIC_URL=https://api.multica.example.com还需要选择一种邮件服务,否则验证码和邀请只会写入服务端日志。
不要在生产环境使用默认的 JWT_SECRET,也不要设置 MULTICA_DEV_VERIFICATION_CODE。
API 与数据库
| 变量 | 默认值 | 说明 |
|---|---|---|
DATABASE_URL | 本地 multica 数据库 | PostgreSQL 连接地址 |
DATABASE_MAX_CONNS | 25 | 单个 API 进程的最大数据库连接数 |
DATABASE_MIN_CONNS | 5 | 单个 API 进程保留的最小连接数 |
PORT | 8080 | API 监听端口 |
JWT_SECRET | 开发用固定值 | 登录 JWT、部分签名流程使用的密钥 |
APP_ENV | 空 | 生产环境设为 production |
AUTH_TOKEN_TTL | 720h(30 天) | 浏览器 JWT 与 cookie 有效期;接受 Go duration 或正整数秒数 |
LOG_LEVEL | 应用默认 | 日志级别 |
MULTICA_SHUTDOWN_HOLD_DURATION | 0 | 收到终止信号后,开始优雅退出前等待多久 |
在 Kubernetes 中设置 shutdown hold 时,terminationGracePeriodSeconds 要大于 hold 与实际退出所需时间之和。
对外地址与浏览器访问
| 变量 | 默认值 | 说明 |
|---|---|---|
FRONTEND_ORIGIN | 空 | 用户访问的前端 origin;用于 CORS、cookie 和邀请链接 |
MULTICA_APP_URL | 回退到 FRONTEND_ORIGIN | 用户可访问的 Web 地址;CLI 登录和账号绑定链接使用它 |
MULTICA_PUBLIC_URL | 空 | 公网 API 地址;用于 webhook URL 和运行时连接说明 |
CORS_ALLOWED_ORIGINS | 空 | 额外允许的 HTTP origin,逗号分隔 |
ALLOWED_ORIGINS | 回退到 CORS / 前端地址 | WebSocket origin 白名单,逗号分隔 |
COOKIE_DOMAIN | 空 | 前后端不同 host 且浏览器直接访问 API 域时必须设置;单域部署保持为空 |
前端和 API 使用不同 host、且浏览器直接访问 API 域时,必须设置 COOKIE_DOMAIN,否则浏览器读不到 CSRF cookie——所有写请求返回 403 CSRF validation failed,而读请求一切正常。取值用能同时覆盖两个 host 的最窄父域(.agent.example.com 优于 .example.com)。它会把登录会话 cookie 扩散到该域下的所有 host,只有这些 host 都由同一可信主体运维时才可用。修改后需要在两个 host 上清除旧 cookie 并重新登录。若采用自托管快速上手的同源配方(浏览器只访问 app 域),保持为空即可。不要填写 IP 地址,浏览器会忽略带 IP Domain 的 cookie。
自托管部署需要设置 FRONTEND_ORIGIN。缺少它时,邀请链接、cookie 安全属性和 WebSocket origin 校验都可能与实际域名不一致。
邮件与登录
Resend
| 变量 | 默认值 | 说明 |
|---|---|---|
RESEND_API_KEY | 空 | 设置后启用 Resend |
RESEND_FROM_EMAIL | noreply@melso.ai | 发件地址,必须属于已验证域名 |
SMTP
只要 SMTP_HOST 非空,SMTP 就会优先于 Resend。
| 变量 | 默认值 | 说明 |
|---|---|---|
SMTP_HOST | 空 | SMTP 主机;设置后启用 SMTP |
SMTP_PORT | 25 | 常见值:25、587、465 |
SMTP_USERNAME | 空 | 用户名;匿名 relay 留空 |
SMTP_PASSWORD | 空 | 密码 |
SMTP_FROM_EMAIL | 回退到 RESEND_FROM_EMAIL | Envelope From 与邮件 From |
SMTP_TLS | starttls | implicit、smtps 或 ssl 表示隐式 TLS;465 会自动启用 |
SMTP_TLS_INSECURE | false | 跳过证书校验,仅用于可信内网 |
SMTP_EHLO_NAME | 主机名 | 严格 relay 要求的 EHLO/FQDN |
Google OAuth
| 变量 | 默认值 | 说明 |
|---|---|---|
GOOGLE_CLIENT_ID | 空 | Google OAuth client ID |
GOOGLE_CLIENT_SECRET | 空 | Google OAuth client secret |
GOOGLE_REDIRECT_URI | http://localhost:3000/auth/callback | 必须与 Google Console 中的回调地址完全一致 |
注册范围
| 变量 | 默认值 | 说明 |
|---|---|---|
ALLOW_SIGNUP | true | 未配置任何白名单时是否允许创建新账号 |
ALLOWED_EMAILS | 空 | 允许注册的完整邮箱,逗号分隔 |
ALLOWED_EMAIL_DOMAINS | 空 | 允许注册的邮箱域名,逗号分隔 |
DISABLE_WORKSPACE_CREATION | false | 禁止所有用户新建工作区;没有 owner/admin 例外 |
MULTICA_DEV_VERIFICATION_CODE | 空 | 非 production 环境使用的固定 6 位测试验证码 |
白名单的准确判断顺序见登录与注册。
附件存储
没有设置 S3_BUCKET 时,Melso 使用本地磁盘。
S3 或兼容存储
| 变量 | 默认值 | 说明 |
|---|---|---|
S3_BUCKET | 空 | Bucket 名称,不要填写完整 hostname |
S3_REGION | us-west-2 | Bucket 所在区域 |
AWS_ACCESS_KEY_ID | SDK 默认凭据链 | 静态 access key |
AWS_SECRET_ACCESS_KEY | SDK 默认凭据链 | 静态 secret key |
AWS_ENDPOINT_URL | 空 | MinIO 等 S3 兼容 endpoint |
S3_USE_PATH_STYLE | 自定义 endpoint 时为 true | 是否使用 path-style 地址 |
ATTACHMENT_DOWNLOAD_MODE | auto | auto、cloudfront、presign 或 proxy |
ATTACHMENT_DOWNLOAD_URL_TTL | 30m | 签名下载地址的有效期 |
内网 MinIO 等 endpoint 无法被浏览器直接访问时,使用 ATTACHMENT_DOWNLOAD_MODE=proxy。
本地磁盘
| 变量 | 默认值 | 说明 |
|---|---|---|
LOCAL_UPLOAD_DIR | ./data/uploads | 文件与 metadata 的保存目录,需要持久化卷 |
LOCAL_UPLOAD_BASE_URL | 空 | 可选的公开 base URL;留空时返回站内相对地址 |
CloudFront
| 变量 | 说明 |
|---|---|
CLOUDFRONT_DOMAIN | CDN 域名 |
CLOUDFRONT_KEY_PAIR_ID | CloudFront key pair ID |
CLOUDFRONT_PRIVATE_KEY | 完整私钥 |
CLOUDFRONT_PRIVATE_KEY_SECRET | 从 Secrets Manager 读取私钥时使用 |
Redis 与限流
| 变量 | 默认值 | 说明 |
|---|---|---|
REDIS_URL | 空 | 用于共享限流、实时事件和 token cache;未设置时实时事件和邀请限流回退到进程内存,认证限流不生效 |
REDIS_DISABLE_CLIENT_NAME | false | 托管 Redis 禁止 CLIENT SETNAME 时设为 true |
RATE_LIMIT_AUTH | 5 | 单 IP 每分钟发送验证码或发起 Google 登录的次数 |
RATE_LIMIT_AUTH_VERIFY | 20 | 单 IP 每分钟验证验证码的次数 |
RATE_LIMIT_INVITATION_ACTOR_10M | 10 | 每位邀请人在 10 分钟滑动窗口内可创建的工作区邀请数;设为 0 可关闭此项限流 |
RATE_LIMIT_INVITATION_WORKSPACE_24H | 50 | 同一工作区内所有管理员在 24 小时滑动窗口内可创建的邀请总数;设为 0 可关闭此项限流 |
RATE_LIMIT_INVITATION_RECIPIENT_24H | 6 | 同一规范化收件邮箱跨工作区在 24 小时滑动窗口内可收到的邀请数;设为 0 可关闭此项限流 |
RATE_LIMIT_TRUSTED_PROXIES | 空 | 允许提供 X-Forwarded-For 的代理 CIDR,逗号分隔 |
MULTICA_TRUSTED_PROXIES | 空 | 自动化 webhook 与实时连接使用的可信代理 CIDR |
反向代理后的部署需要填写真实代理网段。不要直接信任所有来源,否则客户端可以伪造转发 IP。
认证限流需要配置 REDIS_URL;未配置时,启动日志会提示认证限流已关闭。邀请限流在没有 Redis 时仍使用进程内存,配置 Redis 后则在多个副本间共享额度。如果已配置的 Redis 临时不可用,认证限流仍选择放行,而邀请创建会返回可重试的 503,不会在失去防护时发送邮件。
外部集成
| 集成 | 变量 | 说明 |
|---|---|---|
| GitHub | GITHUB_APP_SLUG | GitHub App slug |
| GitHub | GITHUB_WEBHOOK_SECRET | Webhook HMAC 与连接 state 签名密钥 |
| GitHub | GITHUB_APP_ID | PR 卡片的 CI 状态、可合并性和"从 GitHub 选择"仓库都需要它 |
| GitHub | GITHUB_APP_PRIVATE_KEY | 与 App ID 配套的完整 PEM 私钥,用途同上 |
| 飞书 | MULTICA_LARK_SECRET_KEY | base64 编码的 32 字节凭据加密密钥 |
| Slack | MULTICA_SLACK_SECRET_KEY | base64 编码的 32 字节 token 加密密钥 |
| Composio | COMPOSIO_API_KEY | 启用 Composio 工具连接 |
| Composio | COMPOSIO_CALLBACK_BASE_URL | 回调 API 地址;可回退到 MULTICA_PUBLIC_URL |
| Composio | COMPOSIO_STATE_SECRET | OAuth state 签名密钥;可从 JWT_SECRET 派生 |
| 自托管 Git | MULTICA_VCS_INTEGRATION_ENABLED | Forgejo/Gitea/GitLab 集成开关,compose 默认开启 |
| 自托管 Git | MULTICA_VCS_SECRET_KEY | base64 编码的 32 字节加密密钥(openssl rand -base64 32);未配置时该功能整体不可用 |
不配置 GITHUB_APP_ID 和私钥时,PR 仍会正常关联、镜像和触发合并转 done,但卡片上不显示 CI 与可合并状态,"从 GitHub 选择"仓库入口也会禁用。
配置步骤见 GitHub 集成、飞书 Bot和 Slack Bot。
服务端 LLM
这组配置用于服务端的辅助生成能力,例如对话标题;它不是智能体执行任务时使用的 AI 编程工具凭据。
| 变量 | 默认值 | 说明 |
|---|---|---|
MULTICA_LLM_API_KEY | 空 | OpenAI 兼容 API key |
MULTICA_LLM_BASE_URL | 空 | OpenAI 兼容 endpoint |
MULTICA_LLM_DEFAULT_MODEL | gpt-5.6-luna | 请求未指定模型时使用 |
API key 与 base URL 都为空时,服务端 LLM 生成关闭,调用方会使用本地回退逻辑。
守护进程配置
下面的变量在运行智能体的电脑上读取,不是在 API 容器中读取。
| 变量 | 默认值 | 说明 |
|---|---|---|
MULTICA_SERVER_URL | ws://localhost:8080/ws | Melso API / WebSocket 地址,也接受 http(s) |
MULTICA_DAEMON_DEVICE_NAME | 主机名 | 运行时列表中的设备名 |
MULTICA_AGENT_RUNTIME_NAME | Local Agent | 运行时显示名 |
MULTICA_DAEMON_POLL_INTERVAL | 30s | 没有唤醒事件时的执行任务轮询间隔 |
MULTICA_DAEMON_HEARTBEAT_INTERVAL | 15s | 心跳间隔 |
MULTICA_DAEMON_MAX_CONCURRENT_TASKS | 20 | 单个守护进程的并发执行任务上限 |
MULTICA_AGENT_TIMEOUT | 0 | 单次执行的绝对时限;0 表示不设置 |
MULTICA_AGENT_IDLE_WATCHDOG | 30m | 没有输出且没有工具执行时的静默上限 |
MULTICA_AGENT_TOOL_WATCHDOG | 2h | 单个工具调用持续静默的上限 |
MULTICA_OPENCODE_IDLE_WATCHDOG | 10m | OpenCode 专用静默阈值 |
MULTICA_CODEX_SEMANTIC_INACTIVITY_TIMEOUT | 10m | Codex 语义静默阈值 |
MULTICA_CODEX_FIRST_TURN_TIMEOUT | 0 | 显式覆盖 Codex 首轮无进展上限;0 保持默认值。实际首轮等待仍受 MULTICA_CODEX_SEMANTIC_INACTIVITY_TIMEOUT 和总执行超时限制——需将 MULTICA_CODEX_SEMANTIC_INACTIVITY_TIMEOUT 设为严格大于此值(并留出余量),否则等待会被截断至该值,且会跳过模型目录启动重试。设为相等还不够:语义计时器先启动,两者相等时仍可能丢失该重试 |
MULTICA_CODEX_HANDSHAKE_TIMEOUT | 30s | Codex app-server 启动握手上限 |
MULTICA_DAEMON_AUTO_UPDATE | Cloud true;自托管 false | 是否自动检查并更新 CLI |
MULTICA_DAEMON_AUTO_UPDATE_INTERVAL | 6h | 检查更新的间隔 |
MULTICA_DAEMON_AUTO_RELOAD | true | 是否在 multica 二进制被带外替换(brew upgrade、重新下载、本地构建)后重启到新二进制。与 MULTICA_DAEMON_AUTO_UPDATE 相互独立 |
MULTICA_WORKSPACES_ROOT | ~/multica_workspaces | 执行任务工作目录的根目录 |
MULTICA_AGENT_TEMP_BASE | /tmp(Linux/macOS) | 仅适用于 Linux/macOS。私有 task 临时目录的父目录;必须是现有、可写的绝对路径,无效值会使 task 启动失败,不会回退到 /tmp。请选择较短的路径——子工具可能会在其中绑定 AF_UNIX socket;Linux 的 sun_path 上限为 108 字节,macOS 为 104 字节 |
MULTICA_KEEP_ENV_AFTER_TASK | false | 保留执行任务目录用于调试 |
各 AI 编程工具可以使用 MULTICA_<PROVIDER>_PATH 和 MULTICA_<PROVIDER>_MODEL 覆盖命令路径与默认模型。QwenPaw 是例外:它没有 MULTICA_QWENPAW_MODEL,因为 Melso 不会向它传模型,详见 AI 编程工具对比。DeepSeek Harness 支持 MULTICA_DSH_PATH 和 MULTICA_DSH_MODEL(取值为 dsh 模型目录中的模型 id,例如 deepseek-official/deepseek-chat)。全机默认参数 MULTICA_<PROVIDER>_ARGS 目前支持 Claude Code、Codex、CodeBuddy、Qwen Code 和 QwenPaw 五款工具。对应变量是 MULTICA_CLAUDE_ARGS、MULTICA_CODEX_ARGS、MULTICA_CODEBUDDY_ARGS、MULTICA_QWEN_ARGS 和 MULTICA_QWENPAW_ARGS。例如:
MULTICA_CLAUDE_PATH=/opt/bin/claude
MULTICA_CLAUDE_ARGS=--max-turns 40优先级为命令行 flag → 环境变量 → ~/.multica/config.json → 内置默认。watchdog 的行为见守护进程与运行时。
守护进程配置的持久化
守护进程侧的常用配置也可以写入 ~/.multica/config.json,不必依赖 shell 环境变量;命名 profile 的配置文件在 ~/.multica/profiles/<name>/config.json:
melso config set poll_interval 10s
melso config show支持的键:
| 键 | 默认值 | 说明 |
|---|---|---|
server_url | ws://localhost:8080/ws | Melso API / WebSocket 地址 |
app_url | 空 | 浏览器登录使用的 Web 地址 |
workspace_id | 空 | 默认工作区 |
device_name | 主机名 | 运行时列表中的设备名 |
runtime_name | Local Agent | 运行时显示名 |
workspaces_root | ~ 下按 profile 区分的路径 | 执行任务工作目录的根目录 |
max_concurrent_tasks | 20 | 并发执行任务上限;0 或留空表示未设置 |
poll_interval | 30s | 执行任务轮询间隔 |
heartbeat_interval | 15s | 心跳间隔 |
agent_timeout | 不限制 | 单次执行的绝对时限 |
codex_semantic_inactivity_timeout | 10m | Codex 语义静默阈值 |
codex_handshake_timeout | 30s | Codex app-server 握手上限 |
disable_auto_update | 跟随环境 | true 关闭自动更新;false 清除本地覆盖,回到环境变量或默认 |
auto_update_check_interval | 6h | 检查更新的间隔 |
disable_auto_reload | 跟随环境 | true 让守护进程不再跟随磁盘上被替换的二进制;false 清除本地覆盖。与 disable_auto_update 分开解析 |
几条取值规则:
- duration 类键接受正的 Go duration(如
10s、2h),0s和负值会被拒绝。唯一例外是agent_timeout:0s合法,表示明确关闭执行时限。 - 传空字符串清除已持久化的值,回到环境变量或内置默认,例如
melso config set poll_interval ""。 max_concurrent_tasks要求非负整数。- 相对的
workspaces_root值在保存时会转换为绝对路径。
观测与统计
| 变量 | 默认值 | 说明 |
|---|---|---|
ANALYTICS_DISABLED | false | 设为 true 关闭 PostHog 上报 |
POSTHOG_API_KEY | 空 | 不设置时统计上报关闭;接入自己的 PostHog 项目时填写 |
POSTHOG_HOST | https://us.i.posthog.com | PostHog 地址 |
METRICS_ADDR | 空 | Prometheus metrics 监听地址;空表示不启动 |
REALTIME_METRICS_TOKEN | 空 | 保护 /health/realtime 的 bearer token |