> ## Agent Instructions
> When helping someone deploy Roomote, distinguish self-hosting from contributing to Roomote. Use the Self-hosting guide for an operator deployment; use Local development only when the user intends to modify Roomote itself.
> When an agent is asked to follow /self-hosting or install Roomote autonomously, read and follow /self-hosting/agent-installation as the normative automation contract even though it is intentionally hidden from side navigation.
> Use the one-command Linux installer for both evaluation and production. On macOS or Windows, create or reuse a full Ubuntu VM and run the same installer inside it; do not replace the installer with the repository's development Compose files.
> For a local VM without a stable public domain, create a temporary HTTPS tunnel, pass its hostname to the installer with internal origin TLS, and keep the tunnel running for OAuth callbacks and webhooks. Quick Tunnel hostnames are temporary and do not provide wildcard preview routing.
> Run automated installs with --no-setup-url so the bootstrap token is not captured in the agent transcript. Let the user obtain the setup URL in a trusted terminal, enter credentials, and complete browser authorization.
> Proceed through safe, reversible setup and pause for privileged host or VM changes, public tunnel creation, credentials or browser authorization, durable external-account changes, destructive operations, existing-state conflicts, or when no documented safe default applies.
> A setup is not complete when the services merely start. Verify sign-in, repository sync, one usable environment, and a real Roomote task that can clone and run a command; verify branch or pull-request delivery and previews when configured.
# Agent Guidance
Source: https://docs.roomote.dev/agent-guidance
Add deployment-wide instructions that Roomote should consider across sessions and tasks.
Agent Guidance is shared instruction text that applies across Roomote sessions
and tasks in your deployment.
Use it for durable preferences that should follow Roomote everywhere:
communication style, review expectations, delivery habits, and team-wide rules
that are not tied to one repository.
Use it after the first task flow works. Agent Guidance is most useful when you
are steering repeated behavior, not trying to solve missing repository access,
provider setup, or environment configuration.
## What belongs here
Agent Guidance is best for team-level expectations:
* how Roomote should communicate progress and blockers
* what kind of evidence final updates should include
* when Roomote should ask before making a risky change
* review or delivery habits your whole team expects
* terminology your team uses across projects
Good examples:
```text theme={null}
When changing code, summarize the validation you ran before handing work back.
Ask before changing public API behavior.
Prefer small pull requests with focused explanations.
Call out uncertainty instead of presenting guesses as facts.
```
## What should go somewhere else
Do not use Agent Guidance as the place for everything Roomote might ever need.
| Put it in | Use it for |
| ------------------------ | ------------------------------------------------------------------------------------- |
| **Agent Guidance** | Deployment-wide expectations that apply to most tasks |
| **Environment guidance** | Repository setup, commands, ports, service dependencies, and workspace-specific rules |
| **Automations** | Instructions for a specific recurring automation |
| **Task prompt** | Context or constraints that only apply to the current ask |
| **Personal Settings** | A teammate's own linked accounts, profile, and app preferences |
Never put secrets, tokens, or temporary credentials in Agent Guidance. Use
environment variables and integration setup for access.
Agent Guidance should also avoid one-off project instructions. If the rule
belongs to one repository or one recurring automation, put it closer to that
workflow so other tasks do not inherit noise.
## Keep it short enough to follow
The best guidance is specific and compact. Roomote can use a short set of
durable rules more reliably than a long policy document.
Prefer:
```text theme={null}
For code changes, include the tests or checks you ran. If you could not
verify, say why and name the next best check.
```
Avoid:
```text theme={null}
Be excellent. Follow best practices. Make sure everything is high quality.
```
If a rule only matters for one repository, move it to that environment
instead. If a rule only matters for one automation, put it in that
automation's additional instructions.
## When to update it
Update Agent Guidance when you notice a repeated behavior you want to steer
for the whole team.
Common reasons:
* final task messages are missing validation details
* Roomote is too eager or too cautious for your team's review process
* teammates need a consistent handoff format
* your team has a durable policy around risky changes
After you save changes, send a new message in a Fast Session or start a small
new task and check whether the guidance shows up in the behavior you expected.
Fast reloads the guidance for each turn, so saved changes apply to its next
reply. Running coding tasks keep the context they already started with.
## Common issues
* **The guidance is ignored in one repository.** Check whether environment
guidance or the task prompt conflicts with it.
* **Roomote sounds constrained or repetitive.** Shorten the guidance and
remove broad style rules.
* **The same instruction only matters for one workflow.** Move it to the
relevant environment, automation, or task prompt.
# Anonymous Telemetry
Source: https://docs.roomote.dev/anonymous-analytics
What anonymous usage data a Roomote deployment can share, how it is identified, and how admins turn it off.
Roomote can share **anonymous telemetry** with the Roomote team to help
improve the product. This is on by default, controlled entirely by
deployment admins, and designed so that Roomote-generated identifiers and the
default payload cannot identify your company, users, code, or repositories.
## What gets sent
When anonymous telemetry is enabled, your deployment sends:
* **Usage events** — page views (as route patterns like `/task/[taskId]`,
never actual URLs or IDs) and product events such as tasks being created
or settling as completed, failed, or canceled, plus setup progress such as
reaching authenticated setup and configuring or connecting communications,
source-control, inference, and sandbox providers. Setup events include only
the provider type and, where Roomote can determine it from deployment state,
whether it was configured before the wizard. Other events include
non-identifying facts like the harness, model, source surface, and sandbox
provider used. Fast session events include bounded outcome and retry counts;
setup and response phase durations; aggregate model-request and token-usage
counts; prompt-size, context-size, environment, integration, and active-task
counts; and whether a turn is the session's first human message. They do not
include conversation or message identifiers, prompt or reply text, or tool
content.
* **A daily instance report** — aggregate deployment metadata and usage:
setup timestamps; counts of users, environments, and connected repositories;
task, model, token, and cost totals for the past day; pull-request statistics
for the past week; configured provider types; and enabled built-in
integrations.
What is **never** sent: names, emails, repository names, task contents,
prompts, code, access tokens, or credentials.
## How it is identified
Activity is identified by two anonymous IDs:
* an **instance ID** for the deployment as a whole
* a **user analytics ID** for each user
By default, both are short random strings created locally. They are not derived
from your domain, company, email addresses, or any other real-world identifier,
and they cannot be edited or read through the app.
If you override `R_INSTANCE_ID`, use a random, non-identifying value. Roomote
sends the configured value with telemetry and version checks.
## Turning it off
Anonymous telemetry is opt-out:
* during setup, the final step includes an **Anonymous analytics** switch
* afterwards, admins can change it any time in **Settings > Deployment**
The setting applies to everyone in the deployment. When disabled, no
analytics code runs in the browser and no usage events or daily reports
leave your servers.
## Roomote Cloud Specifics
Roomote Cloud deployments always keep Roomote anonymous analytics enabled and
do not show this switch, as described in our privacy policy. Cookie consent
controls only optional support and product-experience services such as Intercom
and PostHog.
## Version checks
Separately from analytics, your deployment checks once a day whether a newer
Roomote release is available. This check is not optional and carries only
the anonymous instance ID and your running version — no usage data.
## Local development
Deployments running in development or preview mode send nothing by default.
Telemetry runs there only when `ROOMOTE_FORCE_TELEMETRY=true` and a Ping
endpoint is explicitly configured.
# Architecture
Source: https://docs.roomote.dev/architecture
A contributor-oriented map of the apps and packages that make up Roomote.
This page is for contributors and operators who need a quick map of the source
tree. It is intentionally high level. Public docs should explain how to run,
configure, and use Roomote.
Roomote is a pnpm + Turborepo monorepo with applications under `apps/` and
shared libraries under `packages/`.
## Applications
| App | Description |
| ---------------------- | ------------------------------------------------------------------------------------ |
| `apps/web` | Next.js web dashboard for setup, settings, tasks, and review. |
| `apps/docs` | Mintlify public documentation site published at `docs.roomote.dev`. |
| `apps/api` | Hono API server: webhooks, MCP and task-control routes, artifact APIs, backend tRPC. |
| `apps/controller` | Worker-dispatch control plane: dequeues jobs and launches sandbox workers. |
| `apps/worker` | Task runtime that runs inside each sandbox and executes the agent. |
| `apps/bullmq` | Background workers, scheduled jobs, and the opt-in Discord Gateway supervisor. |
| `apps/discord-gateway` | Reusable Discord Gateway connection and durable inbound-delivery subsystem. |
| `apps/preview-proxy` | Reverse proxy that exposes live previews from task sandboxes. |
| `apps/dev` | Local dev CLI that orchestrates the PM2-managed services (`pnpm dev`). |
## Packages
| Package | Description |
| -------------------------------------------------------- | ------------------------------------------------------------------- |
| `packages/cloud-agents` | Agent definitions, prompt assembly, routing, workflows, and skills. |
| `packages/db` | Drizzle ORM schema and migrations. |
| `packages/sdk` | Shared contract between API, controller, and worker. |
| `packages/auth` | Authentication and session handling. |
| `packages/compute-providers` | Sandbox provider integrations. |
| `packages/github`, `gitlab`, `gitea`, `ado`, `bitbucket` | Source-control provider integrations. |
| `packages/slack`, `linear`, `communication` | Conversation-surface and issue-tracker integrations. |
| `packages/redis`, `env`, `types`, `feature-flags` | Shared infrastructure utilities. |
## Request flow
1. A task is created from the web dashboard, Slack, or another entry surface.
2. The API records it and enqueues work; the controller dequeues and provisions
a sandbox with the selected sandbox provider.
3. The worker runs inside the sandbox, executes the agent against your
repositories, and streams progress back.
4. Live previews from the sandbox are exposed through the preview proxy, and
results are delivered back to the surface that started the task.
For local setup, see [Local development](/local-development). For running a
deployment, see [Self-hosting](/self-hosting).
# Automations
Source: https://docs.roomote.dev/automations
Set up background Roomote work for PR review, conflict resolution, recurring triage, and team updates.
Automations let Roomote work without waiting for a teammate to write a new
prompt every time.
Use them after your first environment is working well. Connect source control
or a communications provider when an automation depends on those services.
Automations are most useful when your team already trusts the normal task
review flow and wants Roomote to keep an eye on repeated work.
Unsure of how Automations can help? Get inspiration from the [Cookbook](/cookbook).
## Before you turn them on
Make sure the basics are in place:
* source control is connected for PR and repository automations
* a communications provider is connected for automations that post updates to
channels
* Roomote has at least one healthy environment for the repositories it should
work in
* the team knows where automation output will appear
Automations can create useful work quickly. Start with one or two that map to
a real team habit, tell the team where output will appear, then expand once
the signal is good.
Session-backed automations that post to a chat channel are replyable. Reply in
the thread Roomote started and you continue the Session behind that report,
without needing to mention Roomote. That works on Slack, Discord, Teams, and
Telegram, and it works after delegated tasks have finished. Deterministic alerts
such as **Inference Provider Usage Alerts** do not create a task or Session, so
their cards are informational rather than replyable Session threads.
## Recommended automations
Members can create and manage their own custom automations in **Settings >
Automations** or through Roomote chat. Admins can manage all custom automations,
including those created by other members and those without a creator. Built-in
automations and deployment-wide settings remain admin-only.
During setup, Roomote checks connected repositories for recurring work that an
automation could handle. Admins can review the recommendations, turn individual
automations on or off, and continue to apply the selected set. Skipping the
review does not enable anything.
Recommendations are a starting point rather than a fixed policy. After applying
them, use **Settings > Automations** to adjust schedules, destinations, workspace
targets, prompts, or models, and to create other automations from scratch.
Members and admins can also ask Fast to create recurring work during a conversation. Roomote
confirms the schedule, checks for an existing matching automation, and asks for
approval before it saves anything. After creation, Fast offers to run the
automation immediately so you can verify the prompt and destination. Members
manage the custom automations they create; managing someone else's automation
requires an admin.
## Review automation results
Enable **Results inbox** under **Settings > Experimental** to collect durable
automation reports and structured follow-ups in one review queue. Open
**Results** from the main navigation to see unread items ordered by priority and
recency. Critical and high-priority findings appear before normal results.
Use **Check** to open a result and review its full report and suggested work.
From there, you can edit the prepared prompt, choose a model, and start it as a
normal Session. The item is marked accepted only after the Session starts. Use
**Clear** when no follow-up is needed, or **Clear all** to dismiss the current
queue.
The inbox complements configured chat and Email report destinations rather
than replacing them. Automation runs still keep their normal Sessions and
delivery behavior when the experiment is off.
## Pull request automations
These automations react to pull requests, issues, and repository state.
| Automation | What it does | Good first use |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| **Review Code** | Reviews pull requests automatically or on demand | Add an extra reviewer for regressions, risky changes, and missed tests |
| **Triage Issues** | Posts clarifying questions or an implementation plan when an issue is opened/reopened on GitHub, GitLab, or Gitea | Get a grounded plan on the issue without auto-opening a PR |
| **Resolve PR Conflicts** | Looks for merge conflicts and helps fix them on open PRs | Keep long-running branches from getting stuck |
| **Merge announcer** | Summarizes commits pushed to active repositories' default branches and names the pusher | Keep the team aware of changes that land outside pull requests |
For **Review Code**, decide whether Roomote should review new commits
automatically and whether draft pull requests should be included. If your team
treats drafts as active collaboration, include them. If drafts are noisy or
half-formed, keep them out until they are ready. You can also publish each
GitHub review as a **Roomote code review** check on the reviewed commit. Roomote
controls whether it publishes the check; GitHub branch protection or rulesets
control whether that check is required before merging. The GitHub App
installation must grant **Checks: Read and write**; update and reapprove older
installations that do not have that permission.
For **Triage Issues**, turn the toggle on once a supported source-control
provider is connected (GitHub, GitLab, or Gitea) and the repos you care about
have configured Roomote environments. When an issue is opened or reopened,
Roomote starts a task immediately, investigates the issue, and posts a concrete
plan or clarifying questions as a comment on that issue. It does not need a
Manager Channel, does not post Slack digests, does not implement the fix, and
does not open a pull request automatically. Azure DevOps work items and
Bitbucket issues are not covered yet.
For **Resolve PR Conflicts**, pick a schedule, PR age cap, and label. The
label is the team-controlled opt-in for scheduled scans. Make sure the label
exists in your repositories, add it to PRs where you want Roomote to attempt
conflict resolution, and remove it when a human should handle the conflict
instead. Roomote only tries this on labeled PRs that are still active, and it
skips PRs older than the age cap you set.
For **Merge announcer**, connect a source-control provider and turn the toggle
on. Choose Slack, Microsoft Teams, Telegram, or Discord, then select a channel
or **DM me**. Choose **Default** to use the shared Manager Channel or normal
primary-conversation fallback. Roomote reacts to provider-deduplicated push
webhooks for each active repository's current default branch, uses the
deployment helper model to write a brief commit summary, and includes the pusher
and commit authors. Feature-branch pushes and branch deletions are ignored.
GitHub, GitLab, Azure DevOps, Bitbucket, and Gitea are supported.
For GitHub merge commits that Roomote can match to a pull request, the summary
uses that pull request's context and **View changes** opens the pull request.
When the pull request body contains a suitable image, the Slack announcement
can also show one representative screenshot after Roomote validates its URL and
image type. Announcements continue without an image when validation fails.
Other announcements link to the provider's compare view.
## Custom automations
**Settings > Automations** shows built-in and custom automations together in a
searchable list. Filter the list to **All**, **Built-in**, or **Custom** when you
need a narrower view. Each row shows its current configuration and actions;
select **Configure** to edit an automation.
Members can list, inspect, edit, enable or disable, delete, and run their own
custom automations. Admins can perform these actions on all custom automations,
including those without a creator. These ownership rules apply in the dashboard
and in Roomote chat.
These management permissions are separate from viewing a run. Any signed-in
deployment member with a Session link can view its timeline and linked task
transcripts, logs, and artifacts, including runs of another member's custom
automation. The link does not grant management or execution permissions, and
does not make the Session public. Lists and filters retain their existing
visibility restrictions.
Create arbitrary scheduled agent runs with:
* a clear **name**
* the **prompt** Roomote should run
* a **cadence** (`every hour`, `every 6 hours`, `daily`, or `weekly`)
* an optional **preferred environment**: a named environment, **All
repositories**, or **Blank slate**. Blank slate always delegates the run to a
sandbox without repositories; leave it as **Let Roomote decide** to route
normally
* an optional **model** override for the automation's Fast session, including
later turns; without an override, it uses the deployment orchestration default.
Delegated coding tasks use their own model selection or deployment coding default
* an optional **effort** override (`low`, `medium`, `high`, `extra high`, or
`max`) when the selected model supports configurable reasoning
* an optional **report destination**: a direct message to the automation owner,
or a channel, through Slack, Discord, Teams, or Telegram; **Email** is also
available as a private destination when AgentMail is configured and the owner
has an explicitly verified account email
Each custom automation row summarizes its cadence, workspace target, report
destination, creator, and most recent run. Its runs also appear as Sessions in
the normal Session history. Blank slate runs do not clone repositories or
require source-control credentials.
When creating an automation through Roomote chat, ask for **suggested tasks** or
**launchable follow-ups** if qualifying findings should become tasks that
teammates can start from the report. Asking only for a summary or list of action
items keeps those actions as report text. Launchable suggestions require a chat
report destination. Each suggestion can select its own named environment,
**All repositories**, **Blank slate**, or **Fast** target, so one report can offer
follow-ups for different workspaces and execution modes. Repository-specific suggestions from
**All repositories** runs start in a matching named environment when one is
available. Choosing **All repositories** is a delegation preference, not a
request to prepare every repository on every run. Use a named environment when
the automation only needs a specific repository set.
Suggestions can accompany the Session's report after a delegated task finishes,
not just its initial response. Accepting one keeps the follow-up in the
originating report's context. In Slack, each accepted suggestion starts a
separate top-level execution thread and Session instead of reusing the report
thread; retrying that same suggestion reuses its execution thread. Thread or
topic placement on other providers depends on the provider and execution
target.
For a custom automation you manage, choose **Custom schedule** and enter either a standard
five-field cron expression or a natural-language schedule such as “weekdays at
9am.” Roomote previews the interpreted schedule before saving and asks for
clarification rather than guessing when the recurrence itself is ambiguous.
Custom schedules do not support seconds or cron macros.
Every run is a Session. On each due tick, Roomote opens a Session for the run
and hands it the prompt exactly as if a teammate had typed it. The Session
answers from integrations when that is enough, and delegates a normal task when
repository or workspace work is needed, using the preferred environment as a
routing hint when one is set. Delegated tasks report back to the Session, and
the Session is what talks to the report destination.
Runs deliver to every custom-automation report destination: Slack, Discord,
Microsoft Teams, Telegram, or Email. Chat providers support a channel/chat or
a direct message to the automation owner; Email is private only. Each run keeps
a distinct Session, and the report links
back to that Session in the web app. The Session transcript shows the
automation's configured prompt and any delegated task cards, and its normal
composer lets a signed-in teammate continue the run from the dashboard. Replies
on chat providers continue the Session directly there, and replies to an Email
report continue it in the same mail thread. Roomote verifies the active provider
installation, conversation, and linked user before resuming. Runs with no report
destination remain stored Sessions and do not post externally.
Runs execute as the automation's creator. An automation without a creator
cannot run until an administrator re-saves it.
A run can skip or fail before execution when its configuration or launch state
prevents it from starting. When the report destination is reachable, startup or
delegated-task failures are reported there. If the destination is disconnected
or cannot be resolved, check the automation's latest run error in the dashboard.
When a report destination is set, Roomote uses that conversation for actionable
or important findings, meaningful completed results, blockers, and questions
that need input. Routine success, healthy status, and no-change results stay
silent unless the automation prompt explicitly asks for a report in those
cases. In Slack, the first report starts a thread and later updates continue
that thread. On other providers, updates use the run's conversation or topic.
Reply to the report to continue the Session. There is no progress chatter in
between. Without a destination, the run happens silently and its
results remain in its stored web Session, including any delegated task cards.
Unless the prompt asks for a different presentation, custom automation reports
lead with the result, stay concise, and use short Markdown headings and bullets
when there are several findings. A report sent to chat keeps the essential
conclusions and actions in its first message; supporting detail can continue in
thread replies. Explicit instructions in the automation prompt about format,
length, tone, audience, or detail placement always take precedence.
In Slack, automation reports appear as structured cards. Markdown tables render
as tables when they fit, and the card can include links to the task, related pull
requests, and automation settings. Completed runs also show their trigger or
schedule, model, estimated inference cost, and elapsed time.
Direct-message destinations require the automation owner to link an account for
the selected communications provider and make the bot reachable there.
Email destinations use the owner's one account email, and only once Roomote
records it as verified. If that
address changes, loses verification, is suppressed, the owner is removed, or
AgentMail becomes unavailable, delivery stops rather than switching to another
address or communications provider.
Microsoft Teams channel destinations must match an active conversation already
known to the connected Teams installation; custom Bot Framework service URLs
are not accepted.
Use **Run now** on an enabled automation to test it immediately. Each card has
its own run state, so starting one custom automation does not prevent you from
running another. A queued result confirms that Roomote accepted a Session turn,
not that a coding task launched or the work completed. A task ID is not promised
at this point; follow the Session or configured report destination for the final
result and any delegated tasks.
### Upgrading to 1.4
Existing custom automations now use this Session-first flow. Review prompts
that assumed a sandbox would always start: specify the repository work you need,
and check the preferred environment. Their model override now controls Fast;
delegated coding tasks use an explicitly selected model or the deployment coding
default instead.
Set an explicit report destination if you want external delivery. Without one,
the run stays in a stored web Session rather than falling back to the owner's
direct messages or email.
Existing automations with a creator do not need to be re-saved just to upgrade;
only creatorless automations require an administrator to re-save them before
they can run. Use **Run now** to verify the prompt, routing, and destination.
The deployment cap is 25 custom automations.
See [Schedule maintenance](/cookbook/scheduled-housekeeping)
for three copyable custom automation prompts, or
[draft a product-updates newsletter](/cookbook/product-updates-newsletter) with
a custom MCP server and a natural-language schedule.
The admin-only **Scheduling timezone** setting is available on both the Automations and
Deployment settings pages. Members can choose schedules for their own custom
automations but cannot change this shared timezone or other deployment settings.
It applies to all scheduled automations and to
natural-language schedule interpretation. Existing deployments continue using
their Slack workspace timezone (or UTC when unavailable) until an admin pins
an explicit IANA timezone.
Members can also manage their own custom automations conversationally, and
admins can manage all custom automations, through the
`manage_custom_automations` tool: list eligible destinations and models, inspect,
resolve a schedule, create, update, delete, or run an enabled automation
immediately. List results omit
stored prompts to keep the conversation focused; after choosing an automation,
Roomote can inspect its prompt by exact ID. The tool is available both from a
Roomote task and directly in a Fast session, so a quick chat message can handle
the full automation lifecycle without launching a task.
Fast sessions can also reach the deployment's enabled MCP servers, the
same ones delegated tasks use. Use the tool's model-list action to
see the deployment's enabled model IDs and default before setting an override.
Model IDs preserve the configured inference route: `openrouter/...` targets
OpenRouter, while `openai/...` uses the deployment's OpenAI route, including a
connected ChatGPT subscription when configured. A model-specific reasoning
effort can be set alongside the model; Roomote maps the selected level to the
provider's supported reasoning or thinking-budget format.
## Call Roomote via emoji
Use **Call Roomote via emoji** to let teammates summon Roomote by reacting to a
message in Slack, Discord, or Microsoft Teams. An admin chooses the emoji name,
such as `:white_check_mark:`, and can add optional instructions that apply to
every request started this way.
When the configured reaction is added, Roomote handles it like a teammate
replied in that thread with `@Roomote Act on this`. Existing Roomote task
threads continue the active task; other threads start a task with the thread's
conversation as context. Optional automation instructions are added after the
default `Act on this` prompt.
The teammate adding the reaction must have a linked Roomote account, just as
they would when mentioning Roomote directly from that communications provider.
Provider support differs slightly:
* Slack supports standard and workspace custom emoji reactions.
* Discord supports standard and server custom emoji reactions.
* Microsoft Teams sends reaction activities only for messages posted by
Roomote. Teams supports its native `like`, `heart`, `laugh`, `surprised`,
`sad`, and `angry` reactions; choose an equivalent configured emoji such as
`:thumbsup:` for Like or `:heart:` for Heart.
Telegram reactions on Roomote Fast replies are supported, but Telegram is not
available for **Call Roomote via emoji** on arbitrary messages. Its Bot API
reaction updates are handled only for user-attributed reactions on Roomote
replies and suggested-task cards.
## Channel automations
The channel section starts with **Auto-respond to channels**.
Use it to let Roomote start a Fast Session from new top-level messages in
selected Slack or Discord channels, even when nobody mentions Roomote directly.
Fast can answer or delegate the work to a task; if Fast cannot accept an
automated entry, Roomote falls back to a direct task launch so the request is
not dropped. You can add multiple channels across both providers, and each one
can include its own optional instructions and launch criteria.
Good first examples:
* `#ask-engineering`
* `#bugs`
* `#support-inbound`
* `#ops-requests`
For Slack channels, invite Roomote to every auto-respond channel before you
save it. For Discord channels, pick from the text and announcement channels
the Roomote bot can already see in your server.
A few provider-specific behaviors to know:
* On Discord, messages from people who have not linked their Discord account
to Roomote do not start tasks; Roomote sends them a direct message
explaining how to link instead.
* Messages posted by other bots or webhooks (for example a deploy or alert
feed) can start Fast Sessions too. Roomote uses the deployment's automation
identity for these entries. Use launch criteria to keep noisy feeds in check
— for example, only launching on new or worsening alerts.
If Roomote cannot determine whether to start a task or encounters an unexpected
startup error, it notifies human users but stays silent for bot and webhook
messages. Specific issues such as unavailable access or a read-only deployment
can still receive a status reply.
Start with a low-risk channel first. Auto-response can feel noisy if the
channel mixes casual discussion with requests that should become Roomote
tasks.
See how channel instructions and launch criteria work together in the
[vendor outage triage](/cookbook/vendor-outage-triage) and
[support channel](/cookbook/support-channel) recipes.
## Manager automations
The manager section controls the shared Manager Channel plus recurring
manager-facing updates and suggestions.
| Automation | What it posts | Typical cadence |
| ----------------------------------- | ------------------------------------------------------------------ | ------------------------------------------- |
| **Automation output** | The shared Manager Channel destination | Configure once |
| **Weekly Manager Stats** | A weekly summary of Roomote activity | Weekly |
| **Inference Provider Usage Alerts** | Warnings when an inference-provider quota approaches exhaustion | Hourly |
| **Triage Sentry Issues** | Prioritized Sentry follow-up work | Daily or weekly |
| **Triage Dependabot Alerts** | Suggested follow-up tasks for open dependency alerts | Daily or weekly |
| **Triage CodeQL Alerts** | Remediation follow-up tasks for open code-scanning / CodeQL alerts | Daily or weekly |
| **Security Auditor** | Security follow-up work from recently merged PRs | Every hour, every 6 hours, daily, or weekly |
| **Code Quality Auditor** | Code quality follow-up work from recently merged PRs | Every hour, every 6 hours, daily, or weekly |
| **Suggest Ideas** | Useful coding work Roomote thinks the team could do | Daily or weekly |
| **CI Failure Triage** | Automatic repro-and-fix tasks for failing default-branch CI runs | Immediate via webhook |
| **Platform Issue Alerts** | Configuration and access issues reported by Roomote tasks | Immediate when an issue is reported |
| **Summarize Merged PRs** | A digest of recently merged pull requests | Daily or weekly |
Weekly Manager Stats is enabled by default on new deployments and starts
posting only after a valid report destination is configured. Slack reports
include a daily chart of created and merged pull requests for the reporting
period. Existing deployments keep their saved automation settings.
Set **Automation output** first. This is the shared Slack or Discord Manager
Channel for manager-facing posts, suggestions, summaries, and setup alerts.
Make sure the Roomote app can access the channel before you save it.
For Slack, the first account connection after app installation automatically
sets up public `#roomote-managers` if no Slack or Discord Manager Channel is
configured. Existing automation destinations are unchanged, and no automations
are enabled by channel setup. See [Slack setup](/providers/communications/slack#automatic-manager-channel)
for required permissions and retry instructions.
**Inference Provider Usage Alerts** is enabled at an hourly cadence with an 85% threshold
when it first appears, preserving the provider warning behavior from earlier
Roomote releases. Admins can disable it, choose a Slack or Discord destination,
and set the warning threshold from 5% through 95% in 5% increments. Roomote
checks hourly, posts an alert card for each provider that crosses the threshold
in a quota cycle, and sends a fresh critical alert if the quota later reaches
100%. The automation-specific destination wins, followed by the shared Manager
Channel and then the supported primary Teams, Telegram, or Discord conversation
fallback. The check is deterministic, supports **Run now**, and never starts a
Roomote task or session.
**Platform Issue Alerts** are enabled by default. Their own Slack or Discord
destination wins, followed by the shared Manager Channel. If neither channel is
configured, Roomote sends the alert directly to active deployment admins using
each admin's first linked provider in this order: Slack, Teams, Telegram, then
Discord. Admins need a linked account and must be reachable by the bot for this
fallback to work. When only some admins receive an alert, Roomote keeps it
pending and retries the remaining deliveries instead of marking the report
complete. Disable the automation explicitly if the deployment should not send
these alerts.
Each automation card shows a **Reports to** line with the destination the next
run will use and which setting produced it. Reports go to the automation's own
channel when one is set, otherwise to the shared Manager Channel. If Slack is
not connected, fallback selection runs only when no destination is saved or the
saved destination is a Slack channel. Roomote then checks your primary Microsoft
Teams conversation, the configured Telegram chat, and the default Discord
channel in that order (see
[Communications](/communications#supported-providers) for connecting those
surfaces).
**Suggest Ideas** can also report to Teams or Telegram as first-class
destinations. When you select Telegram, Roomote creates a sticky **Suggest
Ideas** forum topic in your primary Telegram chat (create once, reuse on later
runs) and posts digests there. You cannot pick an existing Telegram thread —
Roomote owns the recurring topic. When you select Teams, digests go to the
primary Teams conversation captured for the deployment.
Cards also show a plain provider-support line for what each automation supports
today: the chat surfaces it can report to and the source-control providers it
works with. Triage Dependabot Alerts and Triage CodeQL Alerts are GitHub-only
by nature. CI Failure Triage supports GitHub Actions, GitLab Pipelines, Azure
DevOps builds, Bitbucket Pipelines, and Gitea Actions. Triage Issues supports GitHub, GitLab,
and Gitea issues.
Security Auditor, Code Quality Auditor, Weekly Manager
Stats, Suggest Ideas, Summarize Merged PRs, and Triage Sentry Issues work with
any connected source-control provider. Resolve PR Conflicts supports GitHub,
GitLab, Azure DevOps, and Gitea. Bitbucket is not supported because its API
does not expose the mergeability and label signals required for an unattended
opt-in scan. CI Failure Triage reacts immediately to GitHub
Actions, GitLab Pipeline, Azure DevOps `build.complete`, Bitbucket
Pipelines commit-status, and Gitea Actions `workflow_run` webhooks rather than
running on a daily or weekly schedule.
**Code Quality Auditor** inspects recently merged PR diffs and only posts
high-confidence maintainability issues worth a real follow-up task. It is
meant to catch confusing abstractions, file bloat, brittle branching, and other
quality regressions, not correctness bugs or security issues.
**Triage Sentry Issues** scans connected Sentry projects and posts the issues
that look worth engineering follow-up. Leave project slugs blank to scan
everything available to the configured token, or scope it to specific
projects.
**Triage Dependabot Alerts** scans open GitHub Dependabot alerts across your
active repositories and suggests tightly scoped follow-up update tasks. It
does not open PRs directly from the scheduled scan. Follow-up remediation
preserves the repository's dependency minimum-age and exclusion policies and
uses only versions those policies allow. When a matching Dependabot update entry
or Renovate rule names reviewers or assignees, the remediation pull request
requests those reviewers and assigns those owners after creation. Roomote does
not infer dependency owners from `CODEOWNERS`. When every repository is scanned
successfully and no alerts are open, Roomote stays silent instead of posting an
empty report. Access failures, actionable alerts, and remediation work still
produce a report.
**Triage CodeQL Alerts** scans open GitHub code-scanning alerts (especially
CodeQL findings) across your active repositories and launches tightly scoped
remediation follow-up tasks. It does not open PRs directly from the scheduled
scan.
**Security Auditor** reviews recently merged PRs for concrete security issues
and secure-by-default gaps that are worth a real follow-up task.
**CI Failure Triage** reacts the moment CI fails on a repository's default
branch (GitHub Actions workflow runs, GitLab Pipelines, Azure DevOps
builds, Bitbucket Pipelines, and Gitea Actions). When a failure persists (it is not already fixed by a newer run and is
not a one-off flake), Roomote starts a fix task that reproduces the failing
job inside the repository's configured environment, finds the root cause, opens
a PR with the fix, and posts one summary to the configured destination when it
finishes. Only repositories that belong to a configured Roomote environment are
triaged. For GitLab, ensure Pipeline Hooks are enabled on the webhook Roomote
receives. For Azure DevOps, Roomote ensures the project-scoped
`build.complete` service hook when Azure DevOps repositories are synced. For Bitbucket, repository webhooks include `repo:commit_status_created` and
`repo:commit_status_updated`, and the OAuth client needs the Pipelines scope.
For Gitea, repository webhook resync includes the `workflow_run` event so
Actions completions reach Roomote; host matching uses the deployment
`GITEA_BASE_URL`.
For **Suggest Ideas**, **Summarize Merged PRs**, **Security Auditor**, **Code
Quality Auditor**, **CI Failure Triage**, and **Merge announcer**, choose the
standard report destination and optionally describe **Additional rules** in
natural language:
> Only triage backend and platform. Send platform failures to #platform-ci in our Engineering Slack workspace.
Roomote checks rules against accessible repositories and connected destinations
when you save. Include the source-control provider or host, or the communication
workspace, when names could be ambiguous. Unclear, contradictory, unavailable,
or unsupported rules cannot be saved. An inference provider must be available
to interpret new rules. A failed save leaves the previous configuration intact.
Repository restrictions apply to scheduled runs, **Run now**, and webhook runs
where the automation uses them. Explicit
restrictions select the matching repositories at save time; save revised rules
to include newly added repositories. Destination-only rules do not limit scope:
other repositories continue using the standard destination. Workflow and
report-writing guidance can also be included. Pre-run workflow, job, branch,
and time conditions are not supported in Additional rules. Clear the rules to
restore the automation's all-repository behavior using the standard
destination. Existing **Suggestion preferences** and merged-PR **Additional
instructions** remain separate and keep their current meaning.
Repositories still need an active source-control connection. CI Failure Triage
also requires a configured environment for the repository it repairs. Security
and code-quality scans can inspect connected repositories without an
environment, but launchable remediation still needs a matching environment.
**Run now** processes the eligible scope and can produce separate runs for
different providers, hosts, or report destinations. CI Failure Triage is
webhook-driven; scheduled checks do not scan repositories.
Follow the [CI failure auto-fix recipe](/cookbook/ci-failure-auto-fix) for a
copyable noise-control configuration.
## Add instructions to reduce noise
Several automations include an **Additional instructions** field. Use it to
tell Roomote what good signal looks like for your team.
Helpful instructions are specific:
```text theme={null}
Prioritize changes that reduce repeated support escalations.
Skip suggestions that require product approval before engineering can start.
For merged PR summaries, call out customer-visible changes first.
```
Avoid broad instructions such as "only send good ideas." Roomote needs to
know what your team considers useful, risky, or out of scope.
## Run an automation now
Some automations include a **Run now** action. Use it when you want to test
the current configuration before waiting for the next scheduled run.
After you run one, check the destination channel and the task view. A healthy
automation should leave enough context for a reviewer to understand why
Roomote posted and what should happen next.
If the automation creates a task, review the same evidence you would review for
manual work: transcript, logs, diffs, previews, artifacts, and final summary.
## Use Slack workflows for event-driven custom triggers
For **scheduled** work with a fixed prompt, prefer **Custom automations**
above. For **event-driven** team workflows, use Slack's own workflow builder
and end the workflow with a Roomote mention.
Good custom event triggers include:
* send new bug-channel posts to Roomote for triage
* turn operational requests from another system into Roomote tasks
* ask Roomote to gather diagnostics when a support escalation arrives
This keeps event routing in Slack while still letting Roomote run a normal,
reviewable task.
## Possible issues
* **Nothing posts to chat.** Check that the selected communications provider is
connected, Roomote can access the destination channel, and the automation is
enabled.
* **Suggestions are too broad.** Add narrower instructions about what to
prioritize and what to ignore.
* **Review Code comments on too much.** Turn off draft PR review or adjust
when automatic reviews run.
* **Conflict resolution starts on the wrong PRs.** Use the configured label as
the opt-in boundary and remove it from PRs that need human handling.
# Communications Overview
Source: https://docs.roomote.dev/communications
Connect Slack, Microsoft Teams, Telegram, Discord, or email so Roomote can start, continue, and summarize work from chat.
Communications providers are the chat and collaboration surfaces where people
already coordinate work.
Roomote can run from the web dashboard alone, but a communications provider
turns it into something you can reach from wherever work is happening. You can
start Sessions from chat, continue an existing conversation, receive updates
while the agent works, and get proactive summaries when background work needs
attention. When a Session delegates execution, its task workspace keeps the
logs, diffs, previews, and artifacts.
## Supported providers
| Provider | Best for | Setup |
| ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| | Teams that coordinate work in Slack channels and threads | Slack can also be used for Roomote sign-in. |
| | Teams that use Microsoft 365, Teams channels, and Microsoft Entra accounts | Microsoft can also be used for sign-in and account linking. |
| | Lightweight personal, group, or forum-topic chat access | Telegram is a messaging provider, not a sign-in provider. |
| | Communities and teams that organize work in channels, threads, and forums | Discord is a messaging provider, not a sign-in provider. |
| | Low-frequency task requests and results over email | Email conversations are replyable in both directions; not a sign-in provider. |
Configure communications providers from **Settings > Communications**.
## Setup checklist
Before connecting a communications provider, make sure your deployment has:
1. a stable public HTTPS URL when the provider uses callbacks or webhooks
2. provider app or bot credentials
3. at least one Roomote user who can sign in
4. an environment that tasks can run against
After connecting the provider, start a small Session from chat and confirm that:
* Roomote acknowledges the request in the same conversation
* the Session appears in the dashboard
* replies in the thread continue the same Session
* final summaries and links are posted back to chat
## Start suggested tasks
When a Session or automation report identifies independent follow-up work,
Roomote can post each action as a suggested task in the originating
conversation. Start the exact suggestion you want by reacting to its message:
* on Slack, add a thumbs-up reaction
* on Discord, add a 👍 reaction
* on Microsoft Teams, use the native Like reaction
* on Telegram, add a new 👍 reaction or use the suggestion's **Start** button
The person starting the suggestion must have a linked Roomote account. Roomote
also needs an environment that can run the suggestion's target repository.
Configured **Call Roomote via emoji** automations are separate from these
suggestion reactions.
When the suggestion is not pinned to an execution target, Fast-capable chat
surfaces start it in Fast so Roomote can answer or delegate as needed. A pinned
environment, repository-only surface, or provider without Fast support starts
the coding task directly. On Slack, each accepted suggestion starts in its own
top-level execution thread and Session, while retaining its connection to the
report that proposed it. Separate suggestions therefore do not share execution
conversation state, and retrying the same accepted suggestion reuses its
execution thread. Thread or topic placement on other providers depends on the
provider and execution target.
## React to Roomote replies
When you react to a Roomote reply in an active Fast conversation, Roomote can
use that reaction as context, including as an answer to a question it asked.
The linked user who owns the Fast conversation must add the reaction. Roomote
posts a text reply when the reaction warrants a response and otherwise stays
silent; it does not react to the reaction event itself.
| Provider | Fast reply reactions | Provider limits |
| ----------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Slack | Supported | Slack sends standard and workspace custom `reaction_added` events. |
| Discord | Supported | Discord Gateway sends standard and server custom reaction-add events, but the event does not include the reacted-to message text. |
| Microsoft Teams | Supported | Bot Framework sends native `messageReaction` activities only for messages posted by Roomote. Reaction removals are ignored. |
| Telegram | Supported | Roomote uses user-attributed `message_reaction` updates. Anonymous aggregate `message_reaction_count` updates are not supported because they do not identify the reacting user. |
| Email (AgentMail) | Not supported | Email has no reaction mechanism; reply in the thread instead. |
These reaction paths apply only to Roomote replies that were recorded for the
current Fast conversation. Reactions on older or unrelated messages do not gain
access to that conversation. Suggested-task reactions keep their dedicated
launch behavior described above.
Use the same stable public URL for every provider app setting that requires a
callback or webhook. If you change that URL, update those provider settings and
restart Roomote with the matching deployment URL. Discord receives messages
through its Gateway connection and does not need a public callback URL.
## Authentication and linking
Slack and Microsoft Teams can do two jobs:
* they can be task surfaces where Roomote starts, resumes, and reports on work
* they can be authentication surfaces so users sign in or link the same
workplace identity they use in chat
Task ownership follows the person who asked for the work. When identities are
linked, Roomote can attribute a task to the right user, respect access rules,
and continue the right thread when someone replies later.
If someone asks Roomote to do work from chat before their account is linked,
Roomote prompts them to link the account. Slack resumes the original request
through Fast after linking; on other providers, they may need to send the
request again.
Telegram and Discord use one-time link codes instead of acting as sign-in
providers. Generate a code under **Settings > Personal > Linked Accounts** and
send the corresponding link command to the bot.
Email needs no separate linking step: Roomote recognizes senders by the
verified email addresses on their Roomote accounts. See
[Email (AgentMail)](/providers/communications/agentmail).
## Related setup
Communications providers are only one part of a working Roomote deployment.
Most deployments also need:
* [Sandbox Providers](/compute), so tasks have sandboxes to run in
* [Environments](/environments), so tasks know which repositories and setup
commands to use
* [Source Control](/source-control), so tasks can clone repositories and open
reviewable changes
* [Integrations](/integrations), so tasks can reach issue trackers,
monitoring, docs, and MCP-backed tools
* [Automations](/automations), if you want proactive summaries and scheduled
work to post back into chat
# Sandboxes Overview
Source: https://docs.roomote.dev/compute
Choose where Roomote runs task sandboxes: local Docker or a hosted sandbox backend.
Sandbox providers decide where Roomote tasks actually run.
When a Roomote agent starts work, it needs more than a model response. It needs
a temporary workspace where it can clone repositories, install dependencies,
run commands, start services, open previews, and collect evidence. Roomote calls
that workspace a task sandbox.
A sandbox provider is the backend that creates and manages those sandboxes.
## What sandbox providers are for
Think of a sandbox as a clean development machine for one task. It is separate
from the web app, database, queue, and model provider. The model decides what
to do; the sandbox provider gives the agent a place to do it.
Roomote uses sandbox providers to:
* start one workspace for each task
* clone the repositories from the selected environment
* run setup commands, tests, scripts, and background services
* expose preview ports when a task starts a web app or API
* stream logs back into the task view
* stop, destroy, or snapshot the workspace when the task is done
You configure sandbox providers during setup and can change them later from
**Settings > Sandboxes**.
## Supported providers
Roomote supports local and hosted sandbox backends:
| Provider | Best for | Notes |
| ----------------------------------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------- |
| | Local development and trusted single-host self-hosting | Retains stopped task containers so resumable work can restart in place. |
| | Hosted task sandboxes with snapshot support | Uses a hosted runtime and can resume some sandboxes from snapshots. |
| | Hosted task sandboxes with snapshot support | Runs task sandboxes on E2B-managed infrastructure. |
| | Hosted task sandboxes with snapshot support | Supports environment and task-level snapshot flows. |
| | Hosted perpetual task sandboxes | Uses automatic standby for resumable tasks. |
| | Hosted task sandboxes | API-key setup, Docker projects, private previews, and same-sandbox task resume. |
| | Hosted task sandboxes on Azure Container Apps (preview) | Supports memory+disk snapshots and sub-second standby resume. |
Docker is the default because it works well for local development and simple
self-hosted deployments. Hosted providers are useful when you want task work to
run away from the Roomote server, scale beyond one host, or use provider-managed
sandbox infrastructure.
For resumable Docker tasks, Roomote retains the stopped container and writable
workspace so a follow-up can restart in place on the same host.
## Local Docker versus hosted sandboxes
Docker keeps the system easy to reason about. The controller starts a worker
container on the same host, connects it to the local Docker network, and uses
that container as the task sandbox.
This is a good fit when:
* you are developing Roomote locally
* you run a trusted single-host deployment
* your tasks are modest enough for the host machine
* you want the fewest external provider accounts and credentials
The tradeoff is that Docker uses the same host that runs the rest of your
deployment. Heavy tasks can compete with the web app, API, database, queues, or
other local services. Docker also depends on a restricted socket proxy that
can create and manage worker containers on the host. The proxy is still
privileged infrastructure, but the controller does not receive the raw host
socket and unrelated Docker API sections remain blocked. Docker is not a
multi-host scheduler.
Hosted providers move the task sandbox into a provider-managed environment.
Roomote still controls the task, streams logs, and connects previews, but the
compute-heavy work happens outside your Roomote server.
Hosted sandboxes are a better fit when:
* several people may run tasks at the same time
* tasks need more CPU, memory, or isolation than your Roomote host should provide
* you want task sandboxes to be easier to start, stop, and recover
* you are comfortable managing provider credentials and account-level limits
The tradeoff is extra setup. Hosted providers need API credentials and network
access back to your Roomote deployment.
## Choosing a default provider
The default provider is the sandbox backend Roomote uses when a task does not
explicitly choose one. New deployments can start with Docker, then add a hosted
provider when concurrency, isolation, or provider-managed infrastructure becomes
important.
A practical path is:
1. Start with Docker if you are validating Roomote on one host
2. Run a small task and confirm the environment can clone, install, test, and
open previews
3. Add a hosted provider from **Settings > Sandboxes** when the first task flow
feels stable
4. Set the hosted provider as the default only after its credentials and
connection are healthy
Environment setup still matters no matter which provider you choose. The
sandbox provider supplies the sandbox; the environment tells Roomote what to
put inside it.
## Common issues
* **A hosted provider cannot start tasks.** Confirm its API credentials are
saved and the deployment URL is reachable from the provider.
* **Tasks start slowly.** Check provider capacity and whether the environment
setup commands are doing more work than necessary.
* **Docker tasks affect the deployment host.** Move heavier or concurrent work
to a hosted provider, or give the host more CPU and memory.
* **A task cannot run project commands.** Update the environment with missing
services, secrets, setup commands, or tool versions. The sandbox provider
only provides the machine; it does not know your repository setup by itself.
# Cookbook
Source: https://docs.roomote.dev/cookbook/index
Copyable recipes for turning Roomote automations, skills, and integrations into standing team systems.
Roomote's abilities go way beyond ad hoc prompt → PR interactions. With integrations and automations, you can put many of your team's workflows on autopilot, from investigation to resolution and beyond.
This cookbook collects proven recipes to help you boost your team's productivity
and the quality of your output.
| Recipe | Use to |
| ------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| [Draft product updates](/cookbook/product-updates-newsletter) | Turn recent product work into a customer-ready draft |
| [Ease your team into cloud agents](/cookbook/ease-your-team-into-cloud-agents) | Build trust in Roomote through small, visible, low-risk team habits. |
| [Evaluate outage impact](/cookbook/vendor-outage-triage) | Filter vendor status noise by comparing each incident with your real code, regions, and feature usage. |
| [Fix CI failures](/cookbook/ci-failure-auto-fix) | Keep the build green by having Roomote verify and fix CI breakages automatically. |
| [Record feature demo videos](/cookbook/feature-demo-videos) | Ask Roomote for a polished, narrated demo video of a feature, recorded live with cursor effects, captions, and an optional voice-over. |
| [Schedule maintenance](/cookbook/scheduled-housekeeping) | Turn flaky-test scans, feature-flag audits, and dependency reviews into recurring Roomote work. |
| [Triage customer issues](/cookbook/support-channel) | Give support escalations a repeatable path through production evidence, data, and code. |
## Contribute a recipe
Have a Roomote workflow other teams could reuse? Start with
[contributing recipes](/cookbook/template), fill in every section, and open a
[Cookbook recipe issue](https://github.com/RooCodeInc/Roomote/issues/new?template=cookbook-recipe.yml)
on the Roomote repository.
# Contributing recipes
Source: https://docs.roomote.dev/cookbook/template
Propose a reusable Roomote system for the Cookbook through a repository issue.
Use this skeleton when proposing a Cookbook recipe. Replace every placeholder
and remove the comments before opening a
[Cookbook recipe issue](https://github.com/RooCodeInc/Roomote/issues/new?template=cookbook-recipe.yml).
Do not open a pull request unless a maintainer invites you to. Fill in the
contributor fields in the frontmatter and repeat the contributor in the
Overview metadata. If the recipe comes from another team, use those fields for
the attribution.
````markdown theme={null}
---
title: Outcome-first recipe title
description: One sentence explaining the finished system and why it matters.
icon: lucide-icon-name
contributor: Name or team
contributor_url: https://example.com/contributor
contributor_company: Company
contributor_company_url: https://example.com/company
---
## Overview
Overview paragraph.
- **Trigger**: Trigger type
- **Setup time**: About N minutes
- **Requires**: Product access, integrations, permissions
- **Serves**: Teams or roles
- **Cooked By**: [Name or team](https://example.com/contributor) from [Company](https://example.com/company)
## Ingredients
- Ingredient
## Steps
1. First step.
## Paste-ready configuration
```text
Configuration or prompt
```
## Variations
- Variation
**Pairs well with:** [Related recipe](/cookbook/scheduled-housekeeping)
````
Before submitting, test every paste block against the current product and make
sure the recipe never relies on a prompt alone to enforce a security boundary.
# Cost Analytics
Source: https://docs.roomote.dev/cost-analytics
Review Roomote inference spend by type, source, environment, provider, model, or user.
Cost Analytics helps deployment teams understand how Roomote uses inference
across tasks, Fast sessions, and automations. It reports cost in US dollars and
token usage, so you can spot the environments, models, and work types that drive
spend or high-volume inference.
Any signed-in deployment user can open **Analytics** from the dashboard. The
page opens to **Costs** by default.
## What you can review
The Costs view includes summary cards, a chart, and a detailed breakdown of
recorded inference usage. Use it to answer questions such as:
* which task and automation types account for the most spend
* how much Session orchestration and Memory contribute to spend
* which product features or runtime sources account for inference spend
* whether a particular environment or model is driving costs
* how usage differs between people and automations
* how a provider's cost changes over time
* how token volume changes even when a request has no recorded price
The view starts grouped by **Type**. It distinguishes manual and automated
tasks, **Session** orchestration, **Memories** synthesis, and other **Non-task
inference**. You can instead group or filter the data by source, user,
environment, provider, or model. **Source** preserves the usage event that
recorded the inference, so it can separate work such as task routing, title
generation, and the main agent runtime even when those requests use the same
model and provider. The source also appears in the detail drilldown. Choose a
time range before comparing periods so the chart and breakdown use the same
window.
The chart overlays a **Total tokens** trend line on the cost bars. Its tooltip
shows token and cost totals for the same day and grouping. The breakdown table
includes **Total tokens** and **Avg tokens / task** alongside cost. Selecting a
chart segment opens the matching token-aware detail rows.
Analytics date presets and daily chart buckets use the web server's timezone,
including daylight-saving transitions. Costs, Tasks, and PR analytics use the
same calendar-day boundaries; these are not based on each viewer's browser
timezone or the deployment's automation scheduling timezone.
## Exporting data
Select **Download data** to export the currently filtered detail rows as a CSV
file. Apply the time range and filters first so the export contains the slice
you intend to share or analyze elsewhere.
## Reading the results
Cost Analytics records inference usage reported by the configured model
providers. It is separate from [Anonymous Analytics](/anonymous-analytics):
cost data stays inside your deployment for your team to review, while anonymous
analytics is optional product telemetry sent to the Roomote team.
If a provider reports tokens but no price for a request, that activity appears
in token totals even though it contributes no cost. A request with neither
pricing nor token usage cannot contribute to those metrics. Use provider and
model filters to narrow an investigation when totals do not match an external
provider invoice.
Deleting a task does not remove its recorded inference usage from Cost
Analytics. The historical usage still contributes to totals, task counts, and
averages, but its detail row becomes **Deleted task** and no longer exposes the
task title, user, task type, pull request, or task link.
# Environment Variables
Source: https://docs.roomote.dev/environment-variables
Understand Roomote environment-variable precedence, production recommendations, and supported deployment configuration keys.
Environment variables are the strongest configuration source for a Roomote
deployment. They are best for values that belong to infrastructure: public
URLs, database and Redis connections, storage credentials, provider API keys,
signing keys, and production-only overrides.
Most day-to-day setup can also be managed from the Roomote UI. Use environment
variables when you want configuration to be explicit, reproducible, managed by
your deployment platform, or unavailable to in-app editors.
## Precedence
Roomote resolves configuration in layers:
1. **Process environment variables** supplied by Docker Compose, the one-command
installer, a PaaS, or the shell.
2. **Saved deployment environment variables** encrypted in Roomote during setup
or from Settings pages.
3. **Persisted runtime settings** such as the selected default model, sandbox
provider, or preview settings.
4. **Derived defaults** for local development and release-managed values.
The exact order depends on the setting. A few important cases:
* Provider credentials usually resolve as process env first, then saved
deployment env vars.
* Model role env vars such as `R_MODEL` override the same role selected
in **Settings > Models**.
* Preview env vars such as `PREVIEW_PROXY_BASE_URL` override values saved from
the preview pane's admin setup on the task page.
* Sandbox provider credentials resolve as process env first, then saved
deployment env vars. The default sandbox provider is special: an explicit
admin selection saved in Roomote wins over `DEFAULT_COMPUTE_PROVIDER` because
local and Compose stacks often set a default automatically.
* Local development has safe defaults for Postgres, Redis, MinIO, signing keys,
and local URLs. Dev login also stores an intentionally invalid inference
placeholder when no provider is configured, so setup can complete without a
secret; inference fails until you connect a real provider. Production does
not use this behavior.
## UI locking
When a supported setting is provided by the process environment, Roomote treats
it as operator-managed infrastructure. Settings pages may show the value as
configured, masked, or env-managed, but they should not overwrite it.
This is intentional. It lets production operators keep secrets and platform
configuration in the deployment system while still letting admins manage
non-env settings in the app.
Use the UI when:
* the value is safe for an admin to rotate from Roomote
* the setting is expected to change without redeploying
* the deployment platform does not make env management easy
Use environment variables when:
* the value is required for boot, networking, or storage
* the value is a production secret managed by your host or secret manager
* you want changes reviewed in infrastructure config
* you need to prevent in-app overrides
`/setup` also respects env-managed provider configuration. If an inference
provider is fully configured from environment variables, setup skips the
inference-provider step. If a hosted sandbox provider such as Modal, E2B, or
Daytona is fully configured from environment variables, setup skips the sandbox
provider step too. Local Docker is still treated as the default local fallback,
so Docker-only configuration does not skip that step.
## Production recommendations
For production and shared self-hosted deployments:
* Set `NODE_ENV=production` and `R_APP_ENV=production`.
* Set stable public URLs with `R_APP_URL`, `TRPC_URL`, and, when previews
are enabled, `PREVIEW_PROXY_BASE_URL`.
* Provide `DATABASE_URL`, `REDIS_URL`, and S3-compatible artifact storage.
* Generate strong `ENCRYPTION_KEY`, `ARTIFACT_SIGNING_KEY`, and
`DASHBOARD_PASSWORD` values.
* Either provide both job and preview auth keypairs or set
`R_AUTO_GENERATE_KEYS=true` so Roomote generates and persists them.
* Keep provider credentials in environment variables or a secret manager when
they are controlled by the operator.
* Avoid `SKIP_ENV_VALIDATION` outside build tooling or one-off diagnostics.
## Naming convention
Deployment env var names follow three rules:
* **`R_*`** — configuration Roomote itself defines and operators set:
URLs and model roles (`R_APP_URL`, `R_MODEL`), Roomote's registered
integration-app credentials (`R_GITHUB_*`, `R_SLACK_*`, `R_MICROSOFT_*`,
`R_TEAMS_BOT_*`, `R_TELEGRAM_*`, `R_DISCORD_*`, `R_LINEAR_*`), and boot knobs
such as `R_AUTO_GENERATE_KEYS`.
* **Conventional infrastructure names** stay unchanged: `DATABASE_URL`,
`REDIS_URL`, `S3_*`, `NODE_ENV`, `HOST`, `PORT`.
* **Third-party provider credentials** keep the provider's standard names:
`MODAL_*`, `E2B_*`, `DAYTONA_*`, `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`.
A few `ROOMOTE_*` names remain for Roomote-internal plumbing and
installer/upgrade machinery (for example `ROOMOTE_APP_DOMAIN`,
`ROOMOTE_VERSION`, and `ROOMOTE_WORKER_IMAGE_REPO` in installer-managed
deployments); they are intentional exceptions, documented in the
`deploy/README.md` naming section of the Roomote repository.
## Supported env vars
The table below lists operator-supported deployment configuration. It does not
include task-scoped internal variables that Roomote injects into sandboxes, such
as per-task auth tokens or workspace paths.
### Runtime and URLs
| Env var | Required | Used for |
| --------------------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `NODE_ENV` | Production | Node runtime mode: `development`, `test`, or `production`. Production deploys should set `production`. |
| `R_APP_ENV` | Recommended | Roomote app environment: `development`, `preview`, or `production`. Also affects monitoring and local URL defaults. |
| `R_PUBLIC_URL` | Local callbacks | Stable public HTTPS origin used by local development for OAuth and webhook callbacks. |
| `R_APP_URL` | Production | Public web app origin. Workers and integrations use it for links back to Roomote. |
| `TRPC_URL` | Production | API/tRPC origin used by workers and services. In single-origin production, this is often the app URL plus `/_roomote-api`. |
| `R_PING_BASE_URL` | Optional | Base URL for anonymous telemetry and version checks. Defaults to `https://ping.roomote.dev`. |
| `R_INSTANCE_ID` | Optional | Stable anonymous deployment identifier sent with telemetry and version checks. Use a random, non-identifying value when overriding it. |
| `R_STATUSPAGE_INCIDENTS_URL` | Optional | URL of a Statuspage-compatible unresolved-incidents JSON feed. Setting it enables incident banners and Slack warnings; leaving it unset disables Statuspage checks. |
| `ROOMOTE_FORCE_TELEMETRY` | Development only | Force-enables telemetry in development or preview environments when a Ping endpoint is explicitly configured. |
| `ROOMOTE_APP_TMPFS_SIZE` | Self-host Compose | Size of the temporary filesystem used by the web, API, controller, and bullmq services for Fast runtime files and caches. Defaults to `512m`; changing it requires recreating the affected containers. |
| `R_API_SHUTDOWN_DRAIN_MS` | Optional | Milliseconds the API allows in-flight Fast turns to finish during shutdown before aborting the remainder so they resume on the next process. Defaults to `20000`; set to `0` to abort immediately. Keep it below the hosting platform's SIGTERM-to-SIGKILL grace period. Also the fallback for `R_BULLMQ_SHUTDOWN_DRAIN_MS`. |
| `R_BULLMQ_SHUTDOWN_DRAIN_MS` | Optional | Same window for the bullmq service, which executes the Fast turns the queue resumes. Defaults to `R_API_SHUTDOWN_DRAIN_MS`, then `20000`. |
| `R_FAST_DURABLE_RETRY_DISABLED` | Optional | Set to `true` to keep inference retry waits in the current process instead of parking in-flight Fast turns durably. Durable admission remains enabled. |
| `R_CLOUD_ENABLED` | Roomote Cloud only | Deployment-managed switch for Roomote Cloud behavior, including required anonymous analytics and Cloud support integrations. Do not set this for self-hosted deployments. |
| `R_CURATED_INTEGRATIONS_DISABLED` | Optional | Operator policy for the curated **Settings > Integrations** catalog, which is enabled by default. Set to `true` and restart Roomote to prevent those integrations from being configured or used. Existing connections remain stored while disabled and become available again once the value is unset. Communications, source-control, inference, sandbox providers, and environment-defined MCP servers are unaffected. |
| `R_GITHUB_APP_SLUG` | GitHub setup | Primary GitHub App slug used by server-rendered setup, mentions, and GitHub integration flows. |
| `R_GITHUB_ADDITIONAL_APP_SLUGS` | Optional GitHub setup | Comma-separated additional GitHub App slugs that Roomote should trust as managed bot identities for review attribution and notifications. |
| `SETUP_TOKEN` | Required (non-local) | One-time bootstrap token that admits the first admin at `/setup`. Required on every non-local deployment — tokenless bootstrap is allowed only when `NODE_ENV` is not `production` and `R_APP_ENV` is `development`, so anything running with `NODE_ENV=production` needs it. Without it, first-admin bootstrap stays closed so nobody can claim the founding-admin slot by reaching the URL first. Optional only in local development. |
| `DASHBOARD_PASSWORD` | Production | Local fallback/admin password value used by the deployment. Generate a strong secret. |
| `WEB_DEV_LOGIN_EMAIL` | Local only | Convenience email for development login flows. Do not use as production access control. |
| `WEB_DEV_LOGIN_ENABLED` | Local only | Explicit opt-in (`true` or `1`) for the `/auth/dev-login` development login route. Dev login stays disabled without it, even in development app envs. `pnpm dev` sets it automatically for local development. |
| `SKIP_ENV_VALIDATION` | Avoid | Skips env validation when present. Useful for narrow tooling cases, not normal deployments. |
### Database, Redis, and artifacts
| Env var | Required | Used for |
| ----------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `DATABASE_URL` | Production | Postgres connection string. Local development defaults to the local Compose database. |
| `REDIS_URL` | Production | Redis connection string for queues and runtime coordination. |
| `S3_ENDPOINT` | Production | S3-compatible artifact storage endpoint used by services. |
| `S3_PRESIGN_ENDPOINT` | Recommended | Endpoint used when signing artifact URLs for workers or browsers. Set this when the public or worker-reachable URL differs from `S3_ENDPOINT`. |
| `S3_REGION` | Production | S3 region. MinIO deployments commonly use `us-east-1`. |
| `S3_ACCESS_KEY_ID` | Production | Artifact-storage access key. |
| `S3_SECRET_ACCESS_KEY` | Production | Artifact-storage secret key. |
| `S3_BUCKET_ARTIFACTS` | Production | Bucket used for Roomote artifacts. |
| `S3_AUTO_CREATE_BUCKET` | Optional | Set to `true` or `1` to create the artifacts bucket at API boot when it is missing. |
### Security and signing
| Env var | Required | Used for |
| ----------------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ENCRYPTION_KEY` | Production | Secret used to encrypt deployment-stored secrets. Must be at least 32 characters. |
| `BETTER_AUTH_SECRET` | Optional | Dedicated secret for signing sign-in session cookies. At least 32 characters. Falls back to `ENCRYPTION_KEY` when unset; setting it later invalidates existing sessions. |
| `ARTIFACT_SIGNING_KEY` | Production | Secret used to sign artifact access. Must be at least 32 characters. |
| `ARTIFACT_SIGNING_KEY_PREVIOUS` | Rotation | Previous artifact signing key during rotation. |
| `R_LICENSE_KEY` | More than 10 registered users | Deployment license key for user limits above the free tier. |
| `JOB_AUTH_PRIVATE_KEY` | Production unless auto-generated | Base64-encoded P-256 private key for run and user auth tokens. |
| `JOB_AUTH_PUBLIC_KEY` | Production unless auto-generated | Base64-encoded P-256 public key for run and user auth token verification. |
| `PREVIEW_AUTH_PRIVATE_KEY` | Production unless auto-generated | Base64-encoded P-256 private key for preview auth tokens. |
| `PREVIEW_AUTH_PUBLIC_KEY` | Production unless auto-generated | Base64-encoded P-256 public key for preview auth token verification. |
| `R_AUTO_GENERATE_KEYS` | Optional | Set to `true` or `1` to generate missing job and preview keypairs at first startup and persist them encrypted in the database. |
| `SANDBOX_OIDC_PRIVATE_KEY` | Optional | Private key for sandbox OIDC token signing when using OIDC-backed sandbox auth flows. |
| `SANDBOX_OIDC_PUBLIC_KEY` | Optional | Primary public key for sandbox OIDC verification. |
| `SANDBOX_OIDC_PUBLIC_KEY_SECONDARY` | Rotation | Secondary sandbox OIDC public key during key rotation. |
### Models and inference providers
| Env var | Required | Used for |
| ---------------------------------------- | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `R_MODEL` | Optional | Env-level default coding model. Overrides the default selected in **Settings > Models** for new task starts. |
| `R_ORCHESTRATION_MODEL` | Optional | Model for Fast answers and coordination of delegated task launches. Defaults to `R_MODEL`. |
| `R_SMALL_MODEL` | Optional | Helper model for routing, titles, summaries, and lightweight model calls. |
| `R_VISION_MODEL` | Optional | Vision-capable model for visual inspection and screenshot/image work. |
| `R_CODE_REVIEW_MODEL` | Optional | Model for initial PR/MR review and review-sync tasks. |
| `R_EXPLORE_MODEL` | Optional | Exploration/helper model for investigation-oriented subtasks. |
| `R_PLANNING_MODEL` | Optional | Advisor model used for planning turns and advisor consultations inside coding tasks. |
| `R_MODEL_REASONING_EFFORT` | Optional | Reasoning level for the coding model: `low`, `medium`, `high`, `xhigh`, or `max`. |
| `R_ORCHESTRATION_MODEL_REASONING_EFFORT` | Optional | Reasoning level for the orchestration model. |
| `R_SMALL_MODEL_REASONING_EFFORT` | Optional | Reasoning level for the helper model. |
| `R_VISION_MODEL_REASONING_EFFORT` | Optional | Reasoning level for the vision model. |
| `R_CODE_REVIEW_MODEL_REASONING_EFFORT` | Optional | Reasoning level for the code review model. |
| `R_EXPLORE_MODEL_REASONING_EFFORT` | Optional | Reasoning level for the exploration model. |
| `R_PLANNING_MODEL_REASONING_EFFORT` | Optional | Reasoning level for the advisor model. |
| `R_MODEL_ENV_KEYS` | Optional | Comma- or space-separated list of extra provider key env vars to forward to task workers. |
| `OPENROUTER_API_KEY` | Provider key | OpenRouter API key. Can also be saved from **Settings > Models**. |
| `REQUESTY_API_KEY` | Provider key | Requesty API key. Can also be saved from **Settings > Models**. |
| `AI_GATEWAY_API_KEY` | Provider key | Vercel AI Gateway API key. |
| `BASETEN_API_KEY` | Provider key | Baseten API key. |
| `TOGETHER_API_KEY` | Provider key | Together AI API key. |
| `OPENAI_API_KEY` | Provider key | OpenAI API key. |
| `AZURE_API_KEY` | Provider key | Azure OpenAI API key. |
| `AZURE_RESOURCE_NAME` | Provider config | Azure OpenAI resource name, without the domain or URL. |
| `AZURE_COGNITIVE_SERVICES_API_KEY` | Provider key | Azure AI Foundry / AI Services API key. |
| `AZURE_COGNITIVE_SERVICES_RESOURCE_NAME` | Provider config | Azure AI Foundry / AI Services resource name, without the domain or URL. |
| `ANTHROPIC_API_KEY` | Provider key | Anthropic API key. |
| `XAI_API_KEY` | Provider key | xAI / Grok API key. Optional when a SuperGrok / eligible X Premium+ subscription is connected from **Settings > Models**. |
| `XAI_OAUTH_CLIENT_ID` | Optional | Override for the public Grok CLI OAuth client id used by the SuperGrok device-code connect flow. Defaults to the public CLI client id. |
| `MOONSHOT_API_KEY` | Provider key | Moonshot AI / Kimi Open Platform API key. |
| `KIMI_API_KEY` | Provider key | Kimi for Coding API key for `kimi-for-coding/...` models. |
| `MINIMAX_API_KEY` | Provider key | MiniMax API key. |
| `ZAI_API_KEY` | Provider key | Z.AI platform API key for the region set by `ZAI_REGION`. |
| `ZAI_REGION` | Provider key | Z.AI region: `global` (International) or `china`. Defaults to `global` when unset. |
| `ZAI_CODING_PLAN_API_KEY` | Provider key | Z.AI Coding Plan API key for `zai-coding-plan/...` models. Not a general platform key. |
| `ZAI_CODING_PLAN_REGION` | Provider key | Z.AI Coding Plan region: `global` (International) or `china`. Defaults to `global` when unset. |
| `OPENCODE_API_KEY` | Provider key | OpenCode Zen API key. |
| `OPENCODE_GO_API_KEY` | Provider key | OpenCode API key for an active Go subscription and `opencode-go/...` models. |
| `GEMINI_API_KEY` | Provider key | Google Gemini API key. Can also be saved from **Settings > Models**. |
| `GOOGLE_GENERATIVE_AI_API_KEY` | Provider key | Alternate Google/Gemini provider key forwarded when configured or inferred. |
| `AWS_BEARER_TOKEN_BEDROCK` | Provider key | Amazon Bedrock Mantle API key. Can also be saved from **Settings > Models**. |
| `AWS_REGION` | Provider key | AWS region where the Bedrock API key was created. Defaults to `us-east-1` at runtime when unset. |
| `LITELLM_BASE_URL` | LiteLLM | LiteLLM endpoint URL, usually including its `/v1` path. |
| `LITELLM_API_KEY` | LiteLLM | LiteLLM gateway API key. Required when configuring LiteLLM. |
| `OLLAMA_BASE_URL` | Ollama | Ollama endpoint URL. Use the service root, for example `http://ollama:11434`. |
| `OPENAI_COMPATIBLE__BASE_URL` | OpenAI-compatible | Endpoint URL for a named OpenAI-compatible connection (see Settings > Models). Example: `OPENAI_COMPATIBLE_COMPANY_PROXY_BASE_URL`. |
| `OPENAI_COMPATIBLE__API_KEY` | Optional | Bearer API key for that named OpenAI-compatible connection. |
| `OPENAI_COMPATIBLE__LABEL` | Optional | Display label stored with a named OpenAI-compatible connection. |
| `VLLM_BASE_URL` | vLLM | vLLM OpenAI-compatible endpoint URL, usually including its `/v1` path. |
| `VLLM_API_KEY` | Optional | Bearer API key for a vLLM endpoint that requires authentication. |
| `R_BRAIN_OPENROUTER_API_KEY` | Memory provider | OpenRouter key that enables Memory embeddings and synthesis. |
| `R_BRAIN_OPENAI_API_KEY` | Memory provider | OpenAI key that enables Memory embeddings and synthesis. |
| `SANDBOX_OPENROUTER_API_KEY` | Preview inference | Dedicated spend-capped OpenRouter key mapped to `OPENROUTER_API_KEY` while preparing an environment workspace. Save it under **Settings > Environments > Deployment Environment Variables** or set it on the parent controller; do not put it in an environment definition. |
| `R_BRAIN_MODEL` | Optional | Memory synthesis model in the configured provider's naming. Changes apply immediately. |
| `R_BRAIN_EMBEDDING_MODEL` | Before first Memory boot | Embedding model id that sizes Memory's vector storage. Changing it later requires re-embedding. |
| `R_BRAIN_EMBEDDING_DIMENSIONS` | Before first Memory boot | Output width for `R_BRAIN_EMBEDDING_MODEL`; it must match the served model. |
| `R_BRAIN_EMBEDDINGS_UPSTREAM_URL` | Optional | OpenAI-compatible embeddings endpoint used instead of the Memory provider. |
| `R_BRAIN_INFERENCE_UPSTREAM_API_KEY` | Optional | Bearer key for the self-run embeddings upstream; omit it for a trusted private-network service. |
### Sandbox providers
| Env var | Required | Used for |
| ------------------------------------ | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DEFAULT_COMPUTE_PROVIDER` | Optional | Runtime default sandbox provider when no admin default is saved. Supported values are `docker`, `modal`, `e2b`, `daytona`, `blaxel`, `box`, `azure`, and the Roomote Cloud-only `roomote`. |
| `EXCLUDED_COMPUTE_PROVIDERS` | Optional | Comma-separated provider IDs to hide or exclude from default selection. |
| `DOCKER_WORKER_IMAGE` | Optional | Worker image used by Docker. In production, prefer an immutable registry-qualified tag. |
| `ROOMOTE_WORKER_IMAGE_REPO` | Optional | Registry repository used to derive the worker image from `RELEASE_VERSION` when `DOCKER_WORKER_IMAGE` is unset. |
| `DOCKER_WORKER_PLATFORM` | Optional | Docker worker platform. Defaults to the host architecture (`linux/arm64` on arm hosts, `linux/amd64` otherwise). |
| `DOCKER_WORKER_NETWORK` | Self-host Docker | Docker network for worker containers in Compose/self-host mode. |
| `DOCKER_WORKER_RELEASE_PATH` | Optional | Path to a packaged worker release archive used by Docker worker bootstrap. |
| `DOCKER_WORKER_CPU_LIMIT` | Optional | CPU limit per Docker task. Defaults to `2`. |
| `DOCKER_WORKER_MEMORY_LIMIT` | Optional | Memory and memory+swap limit for each Docker worker. Defaults to `4g`. |
| `DOCKER_TASK_DAEMON_MEMORY_LIMIT` | Optional | Memory and memory+swap limit for the nested Docker daemon used by Docker-project tasks. Defaults to `8g`. |
| `DOCKER_WORKER_PIDS_LIMIT` | Optional | Process limit per Docker task. Defaults to `512`. |
| `DOCKER_WORKER_DISK_LIMIT` | Optional | Writable-layer limit. Defaults to `20g`; tasks fail closed when the Docker storage driver cannot enforce it. |
| `DOCKER_WORKER_ALLOW_UNBOUNDED_DISK` | Optional | Explicitly permits startup without `--storage-opt size`. Defaults to `false`; use only with an equivalent host-level quota. |
| `DOCKER_WORKER_LOG_MAX_SIZE` | Optional | Maximum size of each Docker JSON log file. Defaults to `10m`. |
| `DOCKER_WORKER_LOG_MAX_FILES` | Optional | Number of rotated Docker JSON log files retained. Defaults to `3`. |
| `DOCKER_WORKER_EGRESS_POLICY` | Optional | `internet` (public egress; self-host blocks private+metadata ranges, local dev blocks metadata) or `none` (no external egress). |
| `DOCKER_STANDBY_MAX_COUNT` | Optional | Maximum stopped Docker task containers retained for resume. Defaults to `10`; `0` disables retention. |
| `DOCKER_STANDBY_MAX_AGE_HOURS` | Optional | Maximum age of a retained Docker task container. Defaults to `24`, capped at `168`. |
| `MODAL_TOKEN_ID` | Modal | Modal token ID. Can also be saved from **Settings > Sandboxes**. |
| `MODAL_TOKEN_SECRET` | Modal | Modal token secret. |
| `MODAL_ENDPOINT` | Optional | Modal endpoint override. |
| `MODAL_ENVIRONMENT` | Optional | Modal environment name. |
| `MODAL_APP_NAME` | Optional | Modal app name override. |
| `MODAL_REGIONS` | Optional | Comma-separated Modal sandbox placement regions (for example `us` or `us-west`). Unset keeps Modal default placement. |
| `MODAL_VM_MEMORY_MIB` | Optional | Memory allocated to Modal VM sandboxes used for nested Docker workloads. Defaults to `8192` MiB. |
| `E2B_API_KEY` | E2B | E2B API key. Can also be saved from **Settings > Sandboxes**. |
| `E2B_DOMAIN` | Optional | E2B domain for self-hosted or custom E2B clusters. |
| `E2B_MAX_SANDBOX_TIMEOUT_MS` | Optional | Maximum E2B sandbox timeout Roomote will request. Defaults to one hour. |
| `DAYTONA_API_KEY` | Daytona | Daytona API key. Can also be saved from **Settings > Sandboxes**. |
| `DAYTONA_API_URL` | Optional | Daytona API URL override. |
| `DAYTONA_TARGET` | Optional | Daytona target or region. |
| `BL_API_KEY` | Blaxel | Blaxel API key. Can also be saved from **Settings > Sandboxes**. |
| `BL_WORKSPACE` | Blaxel | Blaxel workspace name. |
| `BLAXEL_REGION` | Optional | Blaxel sandbox placement region. Unset lets Blaxel choose the closest region. |
| `BLAXEL_STANDBY_MAX_COUNT` | Optional | Maximum Blaxel standby sandboxes retained for resume. Defaults to `25`; `0` disables retention. |
| `BLAXEL_STANDBY_MAX_AGE_HOURS` | Optional | Maximum age of a Blaxel standby sandbox. Defaults to `168`, capped at `168`. |
| `BOX_API_KEY` | Box | Box API key. Can also be saved from **Settings > Sandboxes**. |
| `BOX_API_BASE_URL` | Optional | Box-compatible API base URL override. |
| `BOX_MACHINE_TYPE` | Optional | Box machine type override: `small`, `default`, or `large`. |
| `BOX_TIMEOUT_MS` | Optional | Active Box sandbox timeout in milliseconds. Defaults to 2 hours (the Box free-trial maximum). |
| `BOX_STANDBY_MAX_COUNT` | Optional | Maximum stopped Box task sandboxes retained for resume; `0` disables retention. |
| `BOX_STANDBY_MAX_AGE_HOURS` | Optional | Maximum age in hours of a retained Box task sandbox. |
| `AZURE_SUBSCRIPTION_ID` | Azure | Azure subscription ID hosting the sandbox group. Can also be saved from **Settings > Sandboxes**. |
| `AZURE_RESOURCE_GROUP` | Azure | Resource group containing the Azure sandbox group. |
| `AZURE_SANDBOX_GROUP` | Azure | Azure Container Apps sandbox group name. |
| `AZURE_SANDBOX_REGION` | Azure | Data-plane region for the sandbox group, for example `canadacentral`. |
| `AZURE_SANDBOX_DISK_IMAGE` | Azure | Worker disk image ID. Auto-provisioned from the worker OCI image during setup when unset. |
| `AZURE_CLIENT_ID` | Optional | User-assigned managed identity client ID — or the service principal's app ID when paired with `AZURE_TENANT_ID` + `AZURE_CLIENT_SECRET`. Unset uses `az login` locally or the system-assigned identity when deployed. |
| `AZURE_TENANT_ID` | Optional | Service principal tenant ID (with `AZURE_CLIENT_ID` + `AZURE_CLIENT_SECRET`). Recommended for containerized installs. |
| `AZURE_CLIENT_SECRET` | Optional | Service principal client secret (with `AZURE_TENANT_ID` + `AZURE_CLIENT_ID`). |
| `AZURE_SANDBOX_REGISTRY_USERNAME` | Optional | Username for pulling a private worker image during disk-image provisioning (GHCR: token owner's GitHub username). |
| `AZURE_SANDBOX_REGISTRY_TOKEN` | Optional | Token for pulling a private worker image during disk-image provisioning (GHCR: PAT with `read:packages`). |
| `AZURE_SANDBOX_SIZE` | Optional | Sandbox size override: `XS` (0.25/0.5 GiB/5 GiB disk), `S` (0.5/1 GiB/10 GiB disk), `M` (1/2 GiB/20 GiB), `L` (2/4/40 GiB), `XL` (4/8/80 GiB). When unset, Roomote uses its 4 GiB task allocation. ACA caps memory at cores×2Gi (CPU scales up to fit) and disk at cores×20Gi (clamped). |
| `AZURE_SANDBOX_EGRESS_INSPECTION` | Optional | ACA egress TLS inspection override: `Legacy`, `Full`, `Partial`, or `None`. Defaults to `Partial` when unset; configured values are passed to ACA. Use `Full` only with egress rules or transforms because it TLS-resigns all traffic and blocks non-HTTP traffic. |
| `WORKER_RELEASE_CHANNEL` | Optional | Worker release channel, `stable` or `preview`, for hosted worker release selection. |
| `WORKER_RELEASE_VERSION` | Optional | Explicit worker release version for hosted worker bootstrap. |
| `LOCAL_SANDBOX_FILES_DIR` | Local development | Local override for sandbox bootstrap files. Used only by development workflows. |
### Source control providers
| Env var | Required | Used for |
| ------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------- |
| `R_GITHUB_APP_SLUG` | GitHub | Primary GitHub App slug. |
| `R_GITHUB_ADDITIONAL_APP_SLUGS` | Optional | Comma-separated additional GitHub App slugs trusted as Roomote-managed bot identities. |
| `R_GITHUB_APP_ID` | GitHub | GitHub App ID. |
| `R_GITHUB_APP_PRIVATE_KEY` | GitHub | Raw GitHub App private key PEM, usually with newlines escaped as `\\n`. |
| `R_GITHUB_CLIENT_ID` | GitHub | GitHub OAuth client ID. |
| `R_GITHUB_CLIENT_SECRET` | GitHub | GitHub OAuth client secret. |
| `R_GITHUB_WEBHOOK_SECRET` | GitHub | GitHub webhook secret. |
| `GITHUB_MCP_SERVER_URL` | Optional | GitHub MCP server URL override. |
| `GITHUB_AUTOMATED_SKIP_REPOS` | Optional | Repository skip list for unsolicited GitHub automations (reviews, triage, conflict checks). Mentions still get a response. |
| `GITHUB_AUTOMATED_SKIP_OWNERS` | Optional | Owner skip list for unsolicited GitHub automations. Mentions still get a response. |
| `GITLAB_BASE_URL` | Optional | GitLab base URL for self-managed GitLab. |
| `GITLAB_CLIENT_ID` | GitLab | GitLab OAuth application ID. |
| `GITLAB_CLIENT_SECRET` | GitLab | GitLab OAuth application secret. |
| `GITLAB_WEBHOOK_SIGNING_TOKEN` | Optional | GitLab webhook signing token. |
| `GITLAB_WEBHOOK_SECRET` | Optional | GitLab webhook secret. |
| `GITEA_BASE_URL` | Gitea | Gitea base URL. |
| `GITEA_CLIENT_ID` | Gitea | Gitea OAuth application client ID for deployment and personal account-linking grants. |
| `GITEA_CLIENT_SECRET` | Gitea | Gitea OAuth application client secret. |
| `GITEA_WEBHOOK_SECRET` | Optional | Gitea webhook secret. |
| `BITBUCKET_BASE_URL` | Optional | Bitbucket base URL. Defaults to `https://bitbucket.org` (Cloud only). |
| `BITBUCKET_CLIENT_ID` | Bitbucket | Bitbucket OAuth consumer client ID for deployment authorization and personal account linking. |
| `BITBUCKET_CLIENT_SECRET` | Bitbucket | Bitbucket OAuth consumer client secret. |
| `BITBUCKET_WEBHOOK_SECRET` | Optional | Bitbucket webhook secret. |
| `ADO_ORGANIZATION` | Azure DevOps | Azure DevOps organization. |
| `ADO_TOKEN` | Azure DevOps | Azure DevOps access token. |
| `ADO_AUTH_MODE` | Optional | `pat`, `entra`, or `delegated`; omitted values retain legacy PAT/Entra inference. |
| `ADO_LINKED_ACCOUNT_ID` | Optional | Linked Azure DevOps account key used by delegated authentication. |
| `ADO_BASE_URL` | Optional | Azure DevOps base URL. |
| `ADO_USERNAME` | Optional | Azure DevOps username. |
| `ADO_CLIENT_ID` | Optional | Microsoft Entra client ID for Azure DevOps service-principal authentication. |
| `ADO_CLIENT_SECRET` | Optional | Microsoft Entra client secret for Azure DevOps service-principal authentication. |
| `ADO_TENANT_ID` | Optional | Microsoft Entra tenant ID for Azure DevOps service-principal authentication. |
| `ADO_WEBHOOK_SECRET` | Optional | Azure DevOps webhook secret. Generated automatically when Roomote configures service hooks. |
### Communications and sign-in
| Env var | Required | Used for |
| ------------------------------ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SLACK_APP_ID` | Slack app | Slack app ID for communications setup. |
| `R_SLACK_CLIENT_ID` | Slack app/auth | Slack OAuth client ID. Also accepted for Slack sign-in setup. |
| `R_SLACK_CLIENT_SECRET` | Slack app/auth | Slack OAuth client secret. Also accepted for Slack sign-in setup. |
| `SLACK_REDIRECT_URI` | Optional | Slack redirect URI override. |
| `SLACK_AUTH_URI` | Optional | Slack auth URI override. |
| `R_SLACK_SIGNING_SECRET` | Slack app/auth | Slack signing secret for webhook verification. |
| `SLACK_API_BASE_URL` | Optional | Slack API base URL. Defaults to `https://slack.com/api/`. |
| `SLACK_UNFURL_ALLOWED_DOMAINS` | Optional | Domains Slack unfurl handling may allow. |
| `SLACK_API_TIMEOUT_MS` | Optional | Slack API timeout. Defaults to `API_EXTERNAL_REQUEST_TIMEOUT_MS` or 10 seconds. |
| `SLACK_DEBUG_LOGS` | Optional | Set to `true` or `1` to enable extra Slack logs. |
| `R_TEAMS_BOT_APP_ID` | Teams | Microsoft Teams bot app ID. |
| `R_TEAMS_BOT_APP_PASSWORD` | Teams | Microsoft Teams bot password. |
| `R_TEAMS_BOT_TENANT_ID` | Optional | Microsoft Teams bot tenant ID. |
| `R_TEAMS_BOT_NAME` | Optional | Teams bot display name for generated app packages and invocation guidance. |
| `R_TEAMS_BOT_TOKEN_ENDPOINT` | Optional | Teams bot token endpoint override. |
| `R_TEAMS_BOT_OAUTH_SCOPE` | Optional | Teams bot OAuth scope override. |
| `R_TELEGRAM_BOT_TOKEN` | Telegram | Telegram bot token. |
| `R_TELEGRAM_WEBHOOK_SECRET` | Telegram | Optional. Telegram webhook secret; generated automatically when unset in the UI. |
| `R_DISCORD_BOT_TOKEN` | Discord | Discord bot token. The bot and application identity are read from this token. |
| `R_DISCORD_GATEWAY_SECRET` | Discord | Shared internal secret for Discord event delivery between BullMQ and API. Auto-generated when Discord is saved in the UI if unset, and auto-healed when Discord is already configured without one. |
| `DISCORD_API_BASE_URL` | Optional | Discord REST API base URL override, primarily for testing. |
| `R_EMAIL_CHANNEL_ENABLED` | Optional | Set to `true` to enable the email (AgentMail) channel. Without it, email is absent from settings, inbound webhooks are ignored, and Roomote never sends email. Enabling it also turns on account email verification. |
| `R_AGENTMAIL_API_KEY` | Optional | AgentMail API key for email, created from inside the deployment's inbox (inbox-scoped). Overrides the value saved in the settings UI. |
| `R_AGENTMAIL_WEBHOOK_SECRET` | Optional | AgentMail webhook secret. Overrides the value managed by the settings UI. |
| `R_AGENTMAIL_INBOX_ID` | Optional | AgentMail deployment inbox. Normally derived from the key on save; set it to pin the inbox for env-var-only setups. |
| `AGENTMAIL_API_BASE_URL` | Optional | AgentMail API base URL override, primarily for testing. Defaults to `https://api.agentmail.to`. |
| `R_MICROSOFT_CLIENT_ID` | Microsoft sign-in | Microsoft OAuth client ID. |
| `R_MICROSOFT_CLIENT_SECRET` | Microsoft sign-in | Microsoft OAuth client secret. |
| `R_MICROSOFT_TENANT_ID` | Microsoft sign-in | Microsoft tenant ID. Also accepted as the Azure DevOps tenant ID fallback. |
| `R_ALLOWED_EMAILS` | Optional | Comma-separated email allowlist for deployments that restrict sign-in by email. |
| `R_ELEVENLABS_API_KEY` | Optional | ElevenLabs API key for narrated feature-demo videos. The key stays on the control plane; sandboxes reach text-to-speech only through an authenticated Roomote endpoint. A key scoped to text-to-speech only is sufficient and recommended. |
| `R_ELEVENLABS_VOICE_ID` | Optional | ElevenLabs voice ID used for feature-demo narration. Required alongside the API key for narration to be available. |
| `R_VOICE_OPENAI_API_KEY` | Optional | OpenAI key dedicated to GPT-Live voice conversations. Requires project access to `gpt-live-1`; the general `OPENAI_API_KEY` is not used for Voice. The key stays on the control plane; browsers receive only a server-negotiated WebRTC session answer. |
During Microsoft Teams setup, Roomote uses the Microsoft Entra app values for
the Teams bot by default. Use **Show advanced config** after the Directory
(Tenant) ID field only when your Azure Bot app ID is different from the Entra
app ID, or when you need to set the optional bot name or token overrides.
### Integrations
| Env var | Required | Used for |
| ------------------------- | -------- | ----------------------------- |
| `R_LINEAR_CLIENT_ID` | Linear | Linear OAuth client ID. |
| `R_LINEAR_CLIENT_SECRET` | Linear | Linear OAuth client secret. |
| `R_LINEAR_WEBHOOK_SECRET` | Linear | Linear webhook secret. |
| `R_LINEAR_REDIRECT_URI` | Optional | Linear redirect URI override. |
### Declarative environments
| Env var | Required | Used for |
| --------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `ROOMOTE_ENVIRONMENTS_DIR` | Optional | Directory of environment definition files (`*.yaml`, `*.yml`, `*.json`) applied at API startup. One environment per file. |
| `ROOMOTE_ENVIRONMENTS_YAML` | Optional | Inline multi-document YAML with environment definitions applied at API startup, for platforms where mounting files is awkward. |
See [Environments](/environments#provision-environments-declaratively) for the
apply semantics.
### Live previews
| Env var | Required | Used for |
| --------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------ |
| `PREVIEW_PROXY_BASE_URL` | Preview support | Public preview-proxy origin. Overrides the origin saved from the preview pane's admin setup when set. |
| `PREVIEW_DOMAINS` | Optional | Comma-separated preview domains allowed by the preview proxy. Usually derived from `PREVIEW_PROXY_BASE_URL`. |
| `ROOMOTE_PREVIEW_DOMAIN` | Optional | Roomote preview domain override used by preview runtime analysis. |
| `PREVIEW_TOKEN_TTL_SECONDS` | Optional | Preview auth token lifetime. Defaults to 3600 seconds. |
### Observability and request timing
| Env var | Required | Used for |
| ---------------------------------------- | ---------------- | ------------------------------------------------------------------------------------- |
| `SENTRY_DSN` | Optional | Shared Sentry DSN fallback for Node services that do not have a service-specific DSN. |
| `NEXT_PUBLIC_SENTRY_DSN` | Optional | Browser and Next.js web Sentry DSN. |
| `API_SENTRY_DSN` | Optional | API service Sentry DSN. Falls back to `SENTRY_DSN`. |
| `CONTROLLER_SENTRY_DSN` | Optional | Controller service Sentry DSN. Falls back to `SENTRY_DSN`. |
| `BULLMQ_SENTRY_DSN` | Optional | BullMQ service Sentry DSN. Falls back to `SENTRY_DSN`. |
| `WORKER_SENTRY_DSN` | Optional | Worker service Sentry DSN. Falls back to `SENTRY_DSN`. |
| `API_DEBUG_LOGS` | Optional | Set to `true` or `1` to enable extra API logs. |
| `API_EXTERNAL_REQUEST_TIMEOUT_MS` | Optional | Default external request timeout. Defaults to 10 seconds. |
| `API_SLOW_REQUEST_THRESHOLD_MS` | Optional | Threshold for slow API request logging. Defaults to 5 seconds. |
| `API_SLOW_EXTERNAL_REQUEST_THRESHOLD_MS` | Optional | Threshold for slow external request logging. Defaults to 2 seconds. |
| `RELEASE_VERSION` | Release images | Baked release version used for release tagging and worker image derivation. |
| `RELEASE_PRODUCT_VERSION` | Release images | Baked product (changelog) version shown by in-app release notices on channel builds. |
| `GITHUB_SHA` | Release metadata | Commit SHA fallback for monitoring release metadata. |
| `VERCEL_GIT_COMMIT_SHA` | Release metadata | Vercel commit SHA fallback for monitoring release metadata. |
### Local development and deploy helpers
| Env var | Required | Used for |
| ------------------------------ | --------------------------- | ----------------------------------------------------------------------------------------- |
| `NGROK_AUTH_TOKEN` | Local callbacks | Lets `pnpm dev` configure ngrok automatically for local public callbacks. |
| `ROOMOTE_ENV_FILE` | Self-host scripts | Alternate dotenv file for local self-host Compose scripts. |
| `ROOMOTE_DOCKER_LOAD_ENV_FILE` | Self-host scripts | Compose wrapper flag controlling image-baked dotenv loading. Normally managed by scripts. |
| `ROOMOTE_APP_DOMAIN` | Production example | Domain helper used by production dotenv examples and Caddy deployment files. |
| `ROOMOTE_PREVIEW_DOMAIN` | Production example/previews | Preview domain helper used by production dotenv examples and preview runtime config. |
| `SKILLS_API_URL` | Optional | Skill marketplace/API URL override for skill-related tooling. |
## Environment variables versus environment settings
Roomote also has **environment variables** inside **Settings > Environments**.
Those are task workspace variables: they are made available to Roomote tasks
running in that environment.
This page is about deployment configuration variables. Deployment variables
configure Roomote itself; environment variables inside an environment configure
the codebase Roomote is working on.
# Environments
Source: https://docs.roomote.dev/environments
Give Roomote the repositories, services, secrets, and guidance it needs to run and verify work.
An environment is the workspace configuration Roomote uses when it runs a
task. It can specify repositories to clone, services to start, environment
variables, and guidance to follow.
This is what turns a Roomote agent from a generic coding tool into something
grounded in your actual product.
For the full YAML schema behind an environment, including every field and how
it relates to Dev Containers, see the
[environment definition reference](/environments/definition).
## Start with one environment that can prove work
The first environment matters more than the fifth. Start with one repository
or repository set where Roomote can do real work and show enough evidence for
your team to evaluate the result.
A good first environment usually makes at least one of these possible:
* run the main test command
* start the app locally
* open a preview
* reproduce a bug with the services your team already uses
* inspect the repositories that matter for a common support, product, or
engineering workflow
## How the first environment is created
Open **Settings > Environments > New** and choose repositories when the
workspace needs source code. Add any setup guidance you already know, then
select **Start Agent** so Roomote can define a reusable workspace
configuration. If you already know the configuration you need, select **Enter
YAML directly** instead.
An environment can combine repositories from different source-control
providers, such as GitHub and GitLab. Each provider must have working
credentials in the deployment or the task cannot prepare the complete
workspace. Repositories connected through GitHub must also belong to the same
GitHub App installation. Repository full names must be unique within the
environment, including across source-control connections.
If the resulting environment needs changes, edit it from
**Settings > Environments** and update the repositories, guidance, services, or
YAML definition there.
## Start from a brand-new repository
You do not need an existing codebase to set up an environment. From
**Settings > Environments > New**, choose **Create a new repository** to open
github.com with the right owner pre-filled — either a brand-new repository or a
fork of an existing one by URL. Once you create it on GitHub, it appears in the
repository list automatically; if the GitHub App only has access to selected
repositories, grant it access to the new repository first.
An empty repository is fine. When you start setup against a repository with
no commits, Roomote pushes a minimal initial commit (a README and a
.gitignore) to the default branch and creates a basic environment. Building
the actual project is then just your first task in that environment.
## What to include
Add enough context for Roomote to start productively:
* repositories and the default branch to use
* setup commands, package manager expectations, and tool versions
* services such as databases, caches, or local APIs
* environment variables and secrets required for local development
* named preview ports for web apps or APIs so Roomote can open a live preview
* instructions that are specific to this workspace
Environment changes apply to new tasks. Running tasks keep the workspace they
already started with.
## Edit an environment
When you edit an existing environment, Roomote gives you four views of the
same configuration:
* **Editor** is the visual form for common environment settings.
* **YAML** is the raw configuration for precise edits and advanced options.
* **Diff** compares the saved configuration with your editable YAML draft.
* **Preview** shows the saved structure in a more readable form before you use
it for new tasks.
The visual editor is organized around the parts Roomote needs to prepare a
workspace:
* **Basics** set the environment name, description, and initial URL that
previews should open first.
* **Services** add managed dependencies such as PostgreSQL, Redis, MySQL,
MariaDB, ClickHouse, or the AWS CLI before repository setup commands run.
* **Repositories** choose the repositories to clone, optional branches,
repository-specific tool fallbacks, and setup commands for each repository.
* **Docker Compose & Dockerfile** build and start an existing Docker Compose
project or a single Dockerfile from one of the selected repositories.
* **Environment Variables** provide values that tasks can read.
* **Environment `.tool-versions`** writes a shared `.tool-versions` file at
the workspace root.
* **Exposed Ports** name the local web apps or APIs Roomote should preview.
* **Agent Instructions** add environment-specific guidance that every task in
this environment should receive.
Less common options, such as custom MCP servers, are available in the YAML
view.
## Write guidance Roomote can act on
Good environment guidance is specific, durable, and tied to the workspace.
Prefer guidance like:
```text theme={null}
Use pnpm for this repository.
Start Postgres before running the API.
The web app runs on port 3000 and the API on port 3001.
Run the dashboard test suite before changing task review flows.
```
Avoid vague guidance like:
```text theme={null}
Be careful.
Use best practices.
Follow the normal process.
```
If a repository has a known trap, say it plainly. Short warnings such as
"Preview will not load unless Redis is running" are more useful than general
preferences.
## Choose setup commands
Add commands that make the repository ready for useful work. Good setup
commands are the same durable steps a teammate would run after cloning the
repository, such as:
* install dependencies, for example `pnpm install`, `npm ci`,
`bundle install`, or `pip install -r requirements.txt`
* generate local code or clients, for example `pnpm prisma generate`
* run database migrations or seed scripts when local services need them
* start long-running services, for example `pnpm dev`, with
**Run in the background** enabled
* write logs to a predictable file when a background process is important to
debug
Keep commands focused on setup, not final verification. Put test expectations
in agent instructions when you want Roomote to run them before finishing a
task, and include the exact command, package, or path when it matters.
Use **Don't block setup even if it fails** only for helpful-but-optional
steps. If the app cannot run without the command, let setup fail so the issue
is visible.
## Use an existing Docker setup
If the repository already defines its development dependencies in Docker, add
a **Docker project** (`docker_projects` in YAML) instead of duplicating that
setup as Roomote-managed services. A project can use one or more Compose files
or build a single Dockerfile. Roomote starts it after the repository is cloned
and waits for its services to become healthy before repository setup commands
run.
Map container ports to named environment ports when a service should have a
live preview. Compose mappings also identify the service that owns the port.
Startup is required by default; mark a project optional only when tasks can
still work usefully without it.
Docker projects are supported by all sandbox providers. They are isolated with
the task and are removed when the task sandbox is destroyed. They are still
customer-controlled code, so review Compose files and Dockerfiles with the same
care as repository setup scripts.
## Set tool versions at the right level
Use **Repo tool fallbacks** for tools one cloned repository still needs when
they are not already pinned in that repository's own `.tool-versions`. This is a
good fit when one repository needs an extra fallback version without changing
the repository itself.
Use **Environment `.tool-versions`** for tools that should exist at the shared
workspace root. This is most useful for workspace-level scripts, shared MCP
servers, or as a broad fallback when a repository does not already pin a tool
locally.
When a repository already includes its own `.tool-versions`, keep that file as the
source of truth. Environment-configured repository tool versions are fallback
entries, not overrides, so checked-in repository pins still win.
## When to create multiple environments
Use separate environments when work needs meaningfully different setup.
Common examples:
* one environment per product surface, such as web app, API, or background service
* one environment for a monorepo service with heavy dependencies
* one staging-style environment with extra credentials
* one lightweight environment for code review, questions, and investigation
## Provision environments declaratively
Self-hosted deployments managed as infrastructure as code can provision
environments from declarative definitions at startup instead of creating them
in the UI:
* `ROOMOTE_ENVIRONMENTS_DIR` points at a mounted directory of definition
files (`*.yaml`, `*.yml`, or `*.json`), one environment per file.
* `ROOMOTE_ENVIRONMENTS_YAML` carries one or more inline YAML documents
(separated by `---`) for platforms where mounting files is awkward.
Definitions use exactly the same YAML format as the environment editor's YAML
view, so they copy/paste between the UI and your files, and you can keep them
in git next to the rest of your deployment configuration.
The set is re-applied on every startup, keyed by environment name: missing
environments are created, existing ones are updated, and identical re-applies
are no-ops. The declarative definition wins — these environments stay
editable and show a "Managed from file" badge, but UI edits are overwritten
on the next restart (every overwrite is kept in version history). Removing a
definition never deletes the environment; it just returns it to normal manual
management.
Definitions may reference repositories that are not linked yet; the
environment is created anyway and repository mappings backfill on the next
startup after linking. Keep secrets out of definition files — the
per-environment `env` map is stored in plaintext, so use deployment
environment variables under **Settings > Environments > Deployment Environment
Variables** for secret values.
See the [self-hosting guide](/self-hosting) for the compose mount pattern and
operational details.
## Make verification possible
Roomote works best when the environment lets it prove what changed. Include
the commands and services needed to run tests, start the app, and open
previews. For UI work, configure preview ports so teammates can inspect the
result without pulling the branch locally.
## How to tell an environment is healthy
An environment is in good shape when Roomote can do more than clone code:
* setup finishes without manual intervention
* the main commands it needs are discoverable and runnable
* required services and secrets are available
* previews or logs exist when the task should produce them
* follow-up tasks can reuse the environment instead of rebuilding context from
scratch
## Common issues
* **Missing secrets or services** keep setup from getting to a runnable state.
* **No preview ports** make UI work harder to verify.
* **Too many repositories in one environment** can make the first setup slower
and harder to debug.
* **Overly broad guidance** forces Roomote to guess what actually matters for
this workspace.
# Environment definition
Source: https://docs.roomote.dev/environments/definition
Understand the environment definition YAML: the schema, how it relates to Dev Containers, and how to write your own by hand or with a coding agent.
An environment definition is the YAML document that describes a Roomote
[environment](/environments): repositories to clone, services to start, tools
and environment variables to provide, ports to preview, and guidance every task
in that environment should receive.
The visual editor and the onboarding setup agent both produce this same YAML.
This page documents the format directly so you can read, review, and write a
definition yourself, or point a local coding agent at these docs and have it
generate a valid definition for you.
## What the definition is for
When a Roomote agent starts a task, the [sandbox provider](/compute) gives it a
clean sandbox. The environment definition is what turns that empty sandbox into
a workspace grounded in your product. It is applied in a predictable order:
1. requested services (databases, caches) start while repositories are prepared
2. shared workspace tool fallbacks are installed after repositories are ready
3. configured Docker projects are built and started from cloned repositories
4. each repository's setup commands run, in order
5. named ports become live previews, and agent instructions are attached to
every task
The definition is declarative and reproducible: the same YAML produces the same
workspace shape for every task, and it is easy to review in a pull request or
regenerate from scratch.
## Relationship to Dev Containers
If you have used [Dev Containers](https://containers.dev), the environment
definition will feel familiar. Both describe a development workspace as a
version-controllable, declarative file so that anyone (or any agent) gets the
same setup. The concepts map closely:
| Concept | Dev Container (`devcontainer.json`) | Roomote environment definition |
| ------------------- | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------- |
| Base machine | [`image` / `build`](https://containers.dev/implementors/json_reference/#image-specific) | Provided by the [sandbox provider](/compute) worker image, not set here |
| Extra tooling | [`features`](https://containers.dev/features) | `services` and `tool_versions` |
| Setup steps | [`onCreateCommand` / `postCreateCommand`](https://containers.dev/implementors/json_reference/#lifecycle-scripts) | Repository `commands` |
| Forwarded ports | [`forwardPorts` / `portsAttributes`](https://containers.dev/implementors/json_reference/#port-attributes) | `ports` |
| Workspace env vars | [`containerEnv` / `remoteEnv`](https://containers.dev/implementors/json_reference/#variables-in-devcontainer-json) | `env` (and per-command `env`) |
| Tool customizations | [`customizations`](https://containers.dev/supporting) | `agentInstructions`, `mcpServers`, `skills` |
The important difference: **Roomote uses its own schema and does not read
`devcontainer.json`.** The comparison is conceptual. If a repository already has
a Dev Container, treat it as a reference for which tools, services, and commands
matter, then express those in the environment definition described below. For
the Dev Container spec itself, see the
[Dev Container specification](https://containers.dev/implementors/spec/) and the
[metadata reference](https://containers.dev/implementors/json_reference/) rather
than duplicating them here.
## A complete example
The definition below is a self-contained example that uses most of the
available fields. Every field is explained in the reference sections that
follow.
```yaml theme={null}
name: Acme Web
description: Web app and API for the Acme product.
initialUrl: http://127.0.0.1:3000
# Tools installed at the shared workspace root, as a broad fallback.
tool_versions:
node: 22.14.0
pnpm: 9.12.0
# Workspace-level environment variables available to every task.
env:
NODE_ENV: development
LOG_LEVEL: debug
# Managed services started before repository setup runs.
services:
- postgres16
- name: redis7
port: 6380
repositories:
- repository: acme/web
branch: main
# Per-repo tool fallbacks, used only when the repo does not pin them itself.
tool_versions:
python: 3.12.1
commands:
- name: Install dependencies
run: pnpm install
- name: Run migrations
run: pnpm db:migrate
timeout: 300
- name: Start dev server
run: pnpm dev
detached: true
logfile: /tmp/web-dev.log
- name: Optional cache warm
run: pnpm cache:warm
continue_on_error: true
- repository: acme/api
commands:
- name: Install dependencies
run: pnpm install
# Start an existing Compose project after acme/web is cloned.
docker_projects:
- type: compose
name: app
repository: acme/web
files:
- compose.yaml
services:
- web
ports:
- named_port: WEB
service: web
container_port: 3000
# Named ports exposed as human-facing previews.
ports:
- name: WEB
port: 3000
initial_path: /
primary: true
- name: API
port: 3001
# Environment-specific guidance attached to every task.
agentInstructions: |
This is a monorepo. The web app is in acme/web and the API is in acme/api.
Start Postgres and Redis before running the API.
Run `pnpm test` in acme/web before finishing UI changes.
```
## Top-level fields
| Field | Type | Required | Notes |
| ------------------------- | ----------------- | -------- | ------------------------------------------------------------------------------------------------------------------------- |
| `name` | string | yes | Environment name, 1–100 characters. |
| `description` | string | no | Short summary, up to 500 characters. |
| `repositories` | list | no | Repositories to clone. See [Repositories](#repositories). |
| `initialUrl` | string | no | Absolute URL or `about:blank` that the preview surface opens first. |
| `agentInstructions` | string | no | Guidance attached to every task, up to 10,000 characters. |
| `tool_versions` | map | no | Tools installed at the shared workspace root via mise. |
| `env` | map | no | Workspace environment variables available to every task. |
| `services` | list | no | Managed services to start. See [Services](#services). |
| `docker_projects` | list | no | Existing Compose or Dockerfile projects to build and start. See [Docker projects](#docker-projects). |
| `ports` | list | no | Named preview ports. See [Ports](#ports). |
| `oidc` | map | no | Sandbox OIDC targets. See [OIDC](#oidc). |
| `mcpServers` | map | no | Custom MCP servers for this environment. See [MCP servers](#mcp-servers). |
| `skills` | map | no | Installable skills by `owner/repo`. See [Skills](#skills). |
| `manualSkills` | list | no | Inline skills defined in the environment. See [Skills](#skills). |
| `auth_bypass_header` | boolean or string | no | Header-based auth bypass control for exposed authenticated previews. A fixed string secret must be at least 8 characters. |
| `auth_bypass_header_name` | string | no | Custom bypass header name. Defaults to `x-bypass-roomote-auth`. |
### Basics
`name` is the only required top-level scalar. `description` and `initialUrl` are
optional but recommended: `initialUrl` is the URL the shared preview surface
opens first, so point it at the app entry a reviewer would expect, for example
`http://127.0.0.1:3000`. Use `about:blank` when there is no default page.
## Repositories
`repositories` is optional. Each listed repository is cloned onto the shared
workspace.
| Field | Type | Required | Notes |
| --------------- | ------ | -------- | ---------------------------------------------------------------------------------------- |
| `repository` | string | yes | Slash-separated full name, such as `owner/repo`; some providers use additional segments. |
| `branch` | string | no | Branch to check out. Defaults to the repository's default branch. |
| `tool_versions` | map | no | Repo-local tool fallbacks installed via mise. |
| `commands` | list | no | Setup commands for this repository. See [Commands](#commands). |
Keep the first environment focused. One repository, or a small set that must be
cloned together, sets up faster and is easier to debug than a large multi-repo
environment.
GitHub repositories in one environment must belong to the same GitHub App
installation.
### Commands
Each entry in a repository's `commands` list runs in order after the repository
is cloned. Commands are the durable setup steps a teammate would run after
cloning: installing dependencies, generating code, running migrations, and
starting long-running services.
| Field | Type | Required | Notes |
| ------------------- | ------- | -------- | --------------------------------------------------------------------------------------------------------------- |
| `name` | string | yes | Human-readable label for the step. |
| `run` | string | yes | The shell command to run. |
| `env` | map | no | Command-specific environment variables, merged over workspace `env`. |
| `working_dir` | string | no | Directory to run the command in. |
| `cwd` | string | no | Alias for `working_dir`. |
| `timeout` | number | no | Seconds before the command is killed. Defaults to `600`. |
| `retries` | integer | no | Extra attempts for a failing command, with a 1-second delay. Use only for idempotent commands. Defaults to `0`. |
| `continue_on_error` | boolean | no | When `true`, setup continues even if this command fails. Defaults to `false`. |
| `detached` | boolean | no | Run in the background under supervision. Use for long-running servers. Defaults to `false`. |
| `logfile` | string | no | Path to capture stdout and stderr. Used with `detached: true`. |
Guidance:
* keep commands focused on setup, not final verification. Put "run the tests
before finishing" expectations in `agentInstructions` instead.
* use `detached: true` with a `logfile` for servers such as `pnpm dev`, so the
process keeps running and its output is debuggable.
* use `continue_on_error: true` only for helpful-but-optional steps. If the app
cannot run without a command, let it fail so the problem is visible.
## Services
`services` starts managed dependencies before repository setup runs. Each entry
is either a service name string or an object with a name and a custom `port`.
Supported services:
| Service | Default port |
| ---------------------------------------- | ----------------- |
| `redis6`, `redis7` | 6379 |
| `postgres15`, `postgres16`, `postgres17` | 5432 |
| `mysql8`, `mariadb10` | 3306 |
| `clickhouse` | 9000 |
| `aws` | CLI tool, no port |
```yaml theme={null}
services:
- postgres16 # default port 5432
- name: redis7
port: 6380 # custom port
```
A service name cannot collide with a port name in the same environment.
## Docker projects
`docker_projects` runs Docker Compose or Dockerfile definitions already owned
by a configured repository. Roomote validates the Compose model, builds images,
starts services with `docker compose up --wait`, and treats startup as required
unless `required: false` is set.
Common fields:
| Field | Type | Required | Notes |
| ------------------------- | ------------------------- | -------- | -------------------------------------------------------------------------- |
| `type` | `compose` or `dockerfile` | yes | Selects the source format. |
| `name` | string | yes | Unique project name. |
| `repository` | string | yes | Must exactly match a repository in this environment. |
| `working_dir` | string | no | Relative directory inside the repository. Defaults to `.`. |
| `env` | map | no | Variables passed to Compose. Deployment-variable references are supported. |
| `ports` | list | no | Maps container ports to names from the top-level `ports` list. |
| `required` | boolean | no | Fail task startup when the project fails. Defaults to `true`. |
| `startup_timeout_seconds` | integer | no | Build and health-wait timeout. Defaults to 600, maximum 3600. |
For `type: compose`, `files` is a required list of relative Compose file paths.
Optional `profiles` enables Compose profiles, and optional `services` limits
startup to those services. Each port mapping requires `named_port`, `service`,
and `container_port`.
```yaml theme={null}
docker_projects:
- type: compose
name: development
repository: acme/web
working_dir: infra/local
files: [compose.yaml, compose.override.yaml]
profiles: [development]
ports:
- named_port: WEB
service: web
container_port: 3000
```
For `type: dockerfile`, Roomote generates a one-service Compose project.
`context` defaults to `.`, `dockerfile` defaults to `Dockerfile`, and `target`,
`build_args`, and `command` are optional. Dockerfile port mappings omit
`service` because the generated service is implicit.
```yaml theme={null}
docker_projects:
- type: dockerfile
name: web
repository: acme/web
context: .
dockerfile: Dockerfile
target: development
ports:
- named_port: WEB
container_port: 3000
```
All paths must be relative and stay inside the selected repository. Docker
projects are supported by all sandbox providers. Modal runs them in its beta VM
sandbox runtime.
## Ports
`ports` declares the human-facing application URLs Roomote should expose as
[live previews](/environments#make-verification-possible). Inside the sandbox,
each named port gets a shareable `ROOMOTE__PREVIEW_URL`, protected by
preview authentication unless `unauthenticated` is enabled.
`ROOMOTE__HOST` points to that preview URL for proxied ports and to the
direct machine host for unproxied ports. Agents and browser tooling should use
`ROOMOTE__PREVIEW_URL` to test the preview entrypoint.
| Field | Type | Required | Notes |
| ------------------- | ------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `name` | string | yes | Starts with a letter; letters, numbers, and underscores only. Case-insensitive and unique. `SANDBOX_SERVER` and `EDITOR` are reserved. |
| `port` | number | yes | The listening port, 1024–65535. |
| `primary` | boolean | no | Marks the main preview surface. At most one port may be primary. |
| `initial_path` | string | no | Path the preview opens first. Must start with `/`. |
| `proxied` | boolean | no | Whether the port is served through the preview proxy. Defaults to proxied. |
| `unauthenticated` | boolean | no | Allow access without the normal preview auth. |
| `auth_bypass_paths` | list | no | Up to 20 paths (each starting with `/`) that skip preview auth. |
| `subdomain` | string | no | DNS-safe subdomain prefix for the preview host. |
| `wildcard_prefix` | boolean | no | Serve wildcard subdomains under the port. |
Limits: at most 10 proxied ports and at most 2 non-proxied ports per
environment.
```yaml theme={null}
ports:
- name: WEB
port: 3000
initial_path: /dashboard
primary: true
- name: API
port: 3001
```
## Environment variables and tool versions
`env` provides workspace-level variables that every task can read. These are
workspace variables for the code Roomote is working on, distinct from the
[deployment environment variables](/environment-variables) that configure
Roomote itself. Secrets are typically added through the editor rather than
committed to a definition you share.
Tool versions can be set at two levels:
* **`tool_versions` at the top level** installs tools at the shared workspace
root via mise. Use this for workspace-level scripts, shared MCP servers, or as
a broad fallback.
* **`tool_versions` on a repository** provides fallbacks for a single
repository.
In both cases, a repository's own checked-in `.tool-versions` stays
authoritative. Environment-configured versions are fallbacks that fill in
missing tools; they do not override repository-owned pins.
```yaml theme={null}
tool_versions:
node: 22.14.0
python: 3.12.1
```
## Agent instructions
`agentInstructions` is guidance delivered to every task in the environment.
Good guidance is specific, durable, and tied to the workspace:
```yaml theme={null}
agentInstructions: |
Use pnpm for this repository.
Start Postgres before running the API.
The web app runs on port 3000 and the API on port 3001.
Run the dashboard test suite before changing task review flows.
```
Avoid vague instructions like "be careful" or "use best practices." If a
repository has a known trap, state it plainly.
## Routing rules
Admins can configure natural-language routing rules from **Settings →
Environments**. Each rule maps a description, such as “Messages sent in the
hospital-bugs Slack channel,” to an environment or the broad **All repositories**
workspace. A rule can also recommend a coding model for work that Fast delegates.
Rules are guidance rather than exact string matchers. An environment explicitly
named in a request takes precedence, and a specific rule takes precedence over a
catch-all default. Fast evaluates the saved rules when it chooses an environment
or model for a delegated task; they do not override a model or environment the
user explicitly requested. Rules that point to a deleted environment are ignored
until an admin updates or removes them.
## MCP servers
`mcpServers` adds environment-specific [MCP servers](/integrations) that are
merged with built-in tools when a task starts. Each entry is either a streamable
HTTP server (`url`, optional `headers`) or a stdio server (`command`, optional
`args` and `env`).
```yaml theme={null}
mcpServers:
linear:
url: https://mcp.linear.app/mcp
local-tool:
command: my-mcp-server
args:
- --stdio
env:
MY_TOKEN: value
```
## Skills
`skills` installs published skills by source, keyed by `owner/repo`. The value
is either `all` or a list of specific skill names.
```yaml theme={null}
skills:
dbt-labs/dbt-agent-skills: all
anthropics/skills:
- frontend-design
vercel-labs/agent-skills:
- web-design-guidelines
```
`manualSkills` defines inline skills directly in the environment. Each entry
needs a unique `name`, a `description`, and `content` with the skill
instructions.
```yaml theme={null}
manualSkills:
- name: acme-conventions
description: Adds Acme-specific coding conventions.
content: |
# Acme Conventions
Always use the shared logger from @acme/log.
```
## OIDC
`oidc` declares sandbox OIDC targets. Roomote mints the tokens, writes them into
the sandbox filesystem, and refreshes them while the sandbox is active. Use
`aws` for an AWS role and `custom` for additional audiences.
```yaml theme={null}
oidc:
aws:
role_arn: arn:aws:iam::123456789012:role/example
region: us-east-1
custom:
- audience: my-audience
token_file: /home/roomote/.roomote/oidc/custom/token
```
Each `token_file` must be an absolute path and must be unique across targets.
## Write a definition with a coding agent
Because this page fully describes the schema, you can have a local coding agent
generate a definition as an alternative to the in-app setup agent. A reliable
approach:
1. give the agent this page as context, along with the repository you want to
set up
2. ask it to infer the tools, services, setup commands, and preview ports from
the repository's own README, package manifests, lockfiles, CI config, and any
existing `devcontainer.json`
3. have it emit a single YAML document that matches the schema above, starting
from `name` and `repositories`
4. paste the result into the **YAML** view when you create or edit an
environment in **Settings > Environments**
The editor validates the definition when you save, so schema mistakes are caught
before the environment is used for a task.
## Validate and iterate
The visual **Editor**, **YAML**, **Diff**, and **Preview** views in the
environment editor all operate on this same document, so you can switch between
hand-written YAML and the form freely. **Diff** keeps the saved configuration
read-only on the left while you edit the YAML draft on the right. Roomote
validates the definition on save; fix any reported errors before the environment
runs a task.
After saving, the surest test is to run a real task. A healthy environment
finishes setup without manual intervention, exposes the previews or logs a task
needs, and can be reused by follow-up tasks. See
[Environments](/environments) for the broader workflow and common failure modes.
# Sessions
Source: https://docs.roomote.dev/fast-sessions
Follow a conversation and every execution it delegates from one continuous Roomote workspace.
Sessions are the primary way to follow work in Roomote. A Session keeps the
conversation, delegated executions, review activity, artifacts, pull requests,
cost, and unread state together, whether it started in chat, source control, an
automation, the API, or the web dashboard. Fast is the conversational
orchestrator inside a Session: it answers directly when it can and delegates
execution work when needed across Slack, Discord, Microsoft Teams, Telegram,
automations, and the web dashboard.
A Session can also run Roomote's structured code review on demand. Ask it to
review a pull request and the Review Code pipeline runs as a task inside the
Session; in a pull request discussion, it reviews that pull request. You can
name an enabled model and reasoning effort in the request when a review needs a
specific balance of speed and depth. If you omit either choice, the review uses
the deployment's code review defaults.
When a task in a Session opens a pull request, that pull request belongs to the
Session. A mention on it joins the Session instead of starting a new one, and
Roomote answers on the pull request as well as in the Session's home surface.
## Start a Session from the dashboard
On the home page, leave the workspace selector on **Fast** to start a
conversation. Roomote answers directly when it can and delegates execution
when the request needs a repository workspace. Selecting an environment or
repository still starts a Session: the Session records your request, delegates
the task into that workspace right away without a model turn, and opens the
task workspace. You can return to the Session at any time to continue the
conversation around that task.
Fast is the default for unpinned requests across the web dashboard and
supported chat providers. Choose an environment or repository explicitly when
you already know where the work should run.
When work needs a sandbox but no source code, ask Fast to delegate it to
**Blank slate**. The delegated task starts with an empty workspace and does not
clone repositories or require source-control credentials. This is useful for
artifact generation, integration work, and other tasks that need command
execution without a repository. Custom automations can also select Blank slate
as their preferred environment.
Select **New Session** in the navigation to open the same launcher from any
dashboard page.
You do not need to choose a separate conversation mode. The Session grows from
conversation to execution to review without changing identity.
## Source-control work without a workspace
Fast discovers the available tools and capabilities of configured source-control
integrations for focused repository exploration. Reading files and directories,
searching code, or inspecting commits, pull/merge request diffs, and reported CI
results does not require a
coding task, local clone, or workspace provisioning. Available reads depend on
the integration's tools and permissions. Reading CI results is not the
same as running tests: local checkout, code edits, command execution, and testing
are delegated to a task, as are investigations that need a workspace.
APIs are preferred for focused questions such as "Do we have X?" or locating a
setting, not mandatory for every investigation. Roomote can choose a coding
task directly when expected file volume, broad cross-module tracing, exhaustive
caller or coverage needs, search-index limits, or excessive API round trips make
a local checkout substantially more appropriate. There is no fixed file-count
threshold. If a focused search grows into broad investigation, Roomote carries
useful findings into the task rather than continuing endless API calls.
Roomote paginates or narrows searches sensibly and uses immutable
commit references for consistent follow-up reads where supported and identifies
limitations when results are partial, truncated, or limited to a search index.
An empty search is not proof that code is absent. Source inspection is not a
test run or reproduction, and an access denial is not bypassed through a task.
Requests for a code review still use the structured Review Code pipeline.
With an eligible deployment GitHub App installation and an active connected
repository, active Roomote members can use the existing GitHub tools to read
public `github.com` repositories, including source and code search. Public
repositories do not themselves need to be connected, and no personal GitHub
account linkage is required. See
[public GitHub reads](/providers/source-control/github#public-github-reads)
for access requirements. Private reads and writes still require the target to
be connected; access denials are not retried anonymously.
The existing [GitHub integration](/providers/source-control/github#daily-github-management)
also supports updates to existing pull requests, issue or PR comments,
review-comment replies, and reactions using the deployment's GitHub App.
See that guide for supported actions and access requirements.
[GitLab API tools](/providers/source-control/gitlab#native-gitlab-api-tools-for-fast)
reuse the existing deployment OAuth connection for bounded repository reads,
merge request title, description and close/reopen updates, notes, and discussion
replies. No additional MCP server or installation is needed. Tools require an
active member, an active connected repository on the configured GitLab host, and
valid deployment OAuth access; curated integrations must be enabled.
[Bitbucket Cloud API tools](/providers/source-control/bitbucket#api-first-work-in-fast)
reuse the existing deployment OAuth connection for files, directories, code
search, commits, pull requests, diffs, and comments, plus supported PR updates
and replies. No additional MCP server is needed. See that guide for access
requirements, pagination limits, and the code-search deprecation.
## The session view
A Session header shows the other people currently viewing that Session. Your
own avatar is omitted from the viewer list.
A Session timeline shows prompts, replies, and delegated execution activity.
Execution cards show their status, workspace, pull requests, artifacts, latest
error, and cost. Select a card to open its details panel. For a live nested
task, you can reply, attach files, use commands, answer pending requests, cancel
work, or wake a sleeping task without leaving the Session. Choose **Open full
workspace** for terminal, logs, diff, and preview tools.
To pause just one active coding task, select **Stop** on its Session card. This
requires execution access and interrupts the task's current work while
preserving the task, sandbox, and artifacts, so a later message can resume it.
The parent Session and sibling tasks continue. Explicitly canceling the task is
different: cancellation terminally ends the current run and shuts down its
sandbox. Stop or cancellation errors appear on the card; check the resulting
task status rather than assuming the request succeeded.
On desktop, you can keep several task workspaces open beside the Session,
resize them, and switch between the conversation and task panels without losing
your place. On smaller screens, Roomote shows one workspace at a time so the
active conversation or task remains usable.
When delegated tasks keep working after the conversation becomes idle, the
timeline shows the live task count. Select that activity to open the **Tasks**
panel. The **Artifacts** panel combines the latest uploaded outputs from every
task with documents created directly during the conversation, labels each item
by its Session or task source, and opens previews without leaving the Session.
Links to a Session-created artifact, including the link the Session shares when
it creates one, open that artifact directly in the Artifacts panel. Individual
task details continue to show their own artifacts. When a reply attaches
screenshots or other images captured by a task, they appear inline with that
reply in the transcript. Delegated tasks also report their completion, blockers,
and relevant results back into the parent Session; open the task workspace when
you need its full logs or diff.
Fast quietly follows the coding tasks it launches after the conversation becomes
idle. It reports meaningful progress, blockers, and questions that need input,
and can send an evidence-backed correction when a task is drifting from the
request. Routine status stays quiet. Follow-through stops when the Session's
coding work settles instead of leaving a recurring monitor behind.
**Session info** shows the total inference cost for the conversation and its
attached tasks. Open the cost breakdown to separate direct Session orchestration
from each task's usage.
The Sessions page supports list and board views, pins, recent Sessions, and
unread indicators. Common scope, status, and time filters stay visible; turn on
advanced filters for user, environment, pull request, model, and source. Active
advanced filters remain visible until you clear them, and Roomote remembers the
selected list or board view. Search matches Session and task titles,
repositories, and conversation text. Queries of at least three characters
include transcript matches and show a highlighted excerpt. **Ready** is not a
terminal state: you can reply or start another execution in the same Session
later.
Session rows show who or which automation started the work, its source and
cost, and links to accumulated active pull requests. In the Session workspace,
those pull requests remain available across delegated tasks. Selecting the live
task count opens the only running task directly or shows the task list when
several are active. A Session link with a selected task opens that task's full
workspace while keeping the Session conversation alongside it on desktop.
The transcript renders prompts, replies, and tool activity in real time with a
generated title that updates as the Session evolves. Replies appear as the
model writes them, then settle into the saved message once the reply is
delivered.
Expand a tool receipt to inspect the request and result, including messages sent
to delegated tasks, reports received from them, and image-inspection questions
and answers. Task-message receipts link to the source or destination task by
title, with its ID as a fallback. Details are sanitized for display; internal
event metadata is not exposed. A running receipt may show its input before a
result arrives.
Fast sessions can also render presentational widgets such as status cards,
tables, and plans directly in the transcript. Widget HTML is sanitized and
sandboxed in the web view. Chat surfaces receive a concise text preview and a
link to open the rendered widget when both are available.
Agent replies and delegated reports can also include up to two pie, bar, area,
or line charts. Roomote renders each chart responsively in the web transcript
with a keyboard-accessible data table. Slack receives a native chart with its
Markdown fallback; other chat providers receive the fallback text.
## Reply to a session
Conversational Sessions have a reply box at the bottom of the transcript;
follow-ups continue the same conversation with full context. For conversations
that live on another surface, Roomote posts the answer back into the originating
thread with a quoted copy of your web message, so the conversation stays in one
place for everyone following it there.
For substantive requests, Fast sends a brief acknowledgement before it starts
model-invoked work. An eligible Slack message may receive an acknowledgement
reaction instead. Immediate answers and clarifying questions remain single
responses, and delegated tasks keep their existing kickoff message rather than
posting a duplicate acknowledgement.
Fast replies across Slack, Discord, Microsoft Teams, and Telegram link back to
the Session view and can resume the same Session directly from chat. Roomote
verifies the provider installation, conversation, and linked user before it
accepts the follow-up. On Slack, a longer reply streams into the thread as the
model writes it and settles into the finished message.
Follow-ups sent while Fast is responding are retained before Roomote reports
that they were accepted. A correction from the same person can steer the active
response between completed tool calls; messages from another participant wait
for a separate turn under that participant's identity. This keeps shared
conversations ordered without losing instructions that arrive during active
work.
Fast turns also survive API or worker interruptions. Roomote durably admits the turn before acknowledging it, records every action the turn takes as it happens, and resumes unfinished work on another process. The resumed run receives the transcript of its earlier attempt, up to the point it was cut off, so it continues from there instead of repeating actions or asking you to send the request again. If the cut lands on the final reply itself, the resumed run finishes from the transcript: a reply that was recorded is not posted again, and a reply the process died while posting goes out once more without another model request. This covers turns started by a typed message, by an emoji reaction, and by platform events such as a setup kickoff. Provider-side retry waits are honored the same way: short waits keep the turn in place, and longer waits park it durably until the scheduled time.
### Message Suggestions
An empty task or Session composer can show one contextual follow-up after an
agent turn completes. Press **Tab** or select the suggestion to insert it, press
**Escape** to dismiss it, or start typing to replace it with your own message.
Roomote generates each suggestion with the deployment's helper model using a
bounded view of visible conversation history. This adds one small inference
call per completed turn for each task or Session where the suggestion is
requested.
In shared Slack and Discord conversations, Fast can stay silent when linked
participants are talking to each other. A direct reply to Roomote, a mention,
or a direct message still requires a response.
## Reminders and monitors
A Session can schedule a message to itself. Ask Fast to "remind me in twenty
minutes", "check every ten minutes whether CI is green, up to six times", or
"every weekday at nine, summarize the open pull requests", and it creates a
wakeup for that Session. When the wakeup fires, Fast picks the conversation back
up with its full history in context, does what was asked, and replies on the same surface
the Session lives on: the transcript in the dashboard, or the originating Slack,
Discord, Teams, or Telegram thread.
Reporting policy is separate from the schedule. One-shot wakeups default to
replying every run; recurring wakeups default to replying only when there is
something notable, such as a change, a result, a blocker, or a decision you need
to make. Ongoing-process checks can be one-shot or recurring and stay quiet
without news. Ask for a reply on every run when you want a recurring reminder
or report instead. When a monitored condition resolves, Fast tells you and
cancels any remaining checks. You can also ask Fast to list or cancel wakeups
at any time; archiving a Session cancels all of its wakeups.
In the dashboard, active scheduled wakeups appear above the Session composer,
ordered by their next run. Each row shows the wakeup's name and a countdown.
**Due soon** means the scheduled time has arrived, not that the check has run
or completed. The Session owner or an admin can use the row's **Cancel wakeup**
control to stop it; other viewers can see the schedule but cannot cancel it
from this list.
Fast can proactively offer a follow-up when an ongoing process has a concrete
unresolved outcome worth checking and it has verified that available tools can
check it. The offer names the outcome, evidence source, timing, and stop bound.
Fast waits for your acceptance before scheduling; an explicit request to monitor
already gives that permission. Before scheduling, it rechecks access and reuses
an equivalent active check rather than duplicating monitoring or notifications.
Coding work that Fast starts for your request is a separate exception. The
Session follows its own running tasks without asking for additional monitoring
consent, reports important milestones, blockers, or needed input, and can send a
factual status after roughly ten minutes without a useful update. It may also
correct a running task when inspected evidence shows that it has drifted from
the accepted request. This follow-through is hidden from the scheduled wakeup
list and ends when no linked task is running; it does not change the consent and
finite-bound rules for monitoring an external process.
For ongoing-process monitoring, Fast uses a one-shot check or sets a finite run
count or end time on a recurring schedule at any cadence, without automatic
renewal. It stops earlier if the outcome resolves, the check becomes irrelevant,
or it loses the capability to verify the outcome. Missing evidence or reaching
the bound without evidence of resolution is not success. This is how Fast is
instructed to manage monitors, not a scheduler restriction on every recurring
wakeup: explicitly requested recurring reminders or reports can remain unbounded
where the scheduling limits below allow it.
Wakeups belong to the conversation and do not require an administrator. A
Session may hold up to ten active wakeups, intervals range from one second to
seven days, and recurring wakeups can be bounded by a run count or an end time.
Intervals under five minutes must carry one of those bounds. A recurring wakeup
whose turns fail five times in a row is retired. Deployment-wide recurring work
that should run outside a conversation or report to a channel is an
[automation](/automations) instead.
Relative and interval schedules use `in s|m|h|d` and
`every s|m|h|d`: seconds, minutes, hours, or days. Use `in 30s`,
not fractional `in 0.5m`. For a short recurring check, use `every 30s x3` or an
`until` end time; recurring intervals under five minutes still require a bound.
Cron schedules remain five-field expressions, such as `cron 0 9 * * 1-5`.
Delivery is best effort: `in 30s` does not guarantee a reply exactly 30 seconds
later.
## Session and execution access
Any signed-in deployment member with a Session link can view its timeline,
including custom automation Sessions and their linked task transcripts, logs,
and artifacts. A Session link does not provide anonymous or public access.
Viewing is separate from acting. Custom automation management remains restricted
to its creator and administrators. Existing permissions still apply to replies,
edits, deletion, execution, terminals, previews, and secrets; a link does not
grant those permissions. Replies are attributed to the teammate who sent them.
The Sessions list and filter options remain scoped to the member's existing
visibility permissions. Direct-link viewing does not make other members' custom
automations discoverable in those lists.
# File attachments
Source: https://docs.roomote.dev/file-attachments
Attach files that Roomote can read directly in chat and the web app.
Roomote can read supported file attachments from the web app and from chat
threads where you start or continue a Roomote task.
Support varies by chat provider. The web app, Slack, and Telegram can read the
formats below. Discord supports images and a smaller text and code subset, but
not Office documents, PDFs, or presentations. Microsoft Teams currently
supports image attachments only. Slack can also describe one supported video
attachment per message.
Attachments sent to Fast stay available as conversation context. When Fast
delegates work or follows up with a coding task, it can forward the relevant
supported attachments with the instruction.
Use attachments when the file itself is the fastest way to show the problem: a
bug report export, a config file, a markdown handoff, a spreadsheet, or a PDF
from a customer.
Attachments work best when they are paired with a clear ask. Tell Roomote what
the file is, which part matters, and what you want back: an explanation, a
plan, a patch, or a follow-up question.
## What works well
Attach files when you want Roomote to:
* inspect structured data without pasting it into the message
* read logs, config files, or source snippets as-is
* work from a spreadsheet or report export
* use screenshots and other images as direct visual context
If the attachments are large, Roomote reads them in the order you attach them
and applies a shared text budget so the task stays responsive. Very large
earlier files can leave later files included by name only.
Text-extracted files are limited to 8 MB each. Image, video, and provider
transport limits vary by surface.
## Accepted file types
| Content type | File types |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| Pure text | `.txt`, `.md`, `.markdown` |
| Structured text | `.json`, `.yaml`, `.yml`, `.xml`, `.log`, `.conf`, `.config`, `.ini`, `.env`, `.sh`, `.bash`, `.zsh`, `.toml`, `.properties` |
| Code | `.html`, `.htm`, `.css`, `.js`, `.jsx`, `.ts`, `.tsx`, `.py`, `.rb`, `.go`, `.rs`, `.java`, `.c`, `.h`, `.cpp`, `.cc`, `.cxx`, `.hpp`, `.sql` |
| Spreadsheets | `.csv`, `.tsv`, `.xlsx`, `.xls` |
| Documents | `.pdf`, `.docx` |
| Presentations | `.pptx` |
| Images | `.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`, `.svg` |
## How Roomote uses them
Text, code, spreadsheet, document, and presentation files are read into the
task as attachment context. Images are passed through as image inputs so
Roomote can inspect them directly. `.svg` files are normally read as text
markup, but Discord treats an SVG reported with the `image/svg+xml` content type
as an image input.
Images never change which model handles your request. When the active model
accepts image input, it sees the image itself. When it does not, Roomote keeps
that model in charge and has the configured vision model (or, failing that,
the helper or coding model) describe the image on request, the same way a
coding task delegates visual inspection to a hidden subagent.
That means you can ask things like:
* "Compare this export to the expected format and tell me what is broken."
* "Read this config and explain why the service is failing."
* "Check this customer PDF and draft the fix plan."
* "Look at this screenshot and tell me what UI state it shows."
## Videos from Roomote
For new screencasts, Roomote prefers final MP4 (H.264) artifacts optimized for
playback while retaining the native recording. Visual proof may use the original
WebM when conversion tools or time are unavailable, or conversion fails. This
preference does not convert arbitrary uploads or replace existing artifacts.
Task recordings remain available as uploaded artifacts. In Slack, you can ask
Roomote to share a selected recording as a native video file, including one from
an earlier task in the current Session. This requires the Slack app's
`files:write` permission; existing installations need reinstall or workspace
admin reapproval after the scope is added. See
[Slack video replies](/providers/communications/slack#video-replies)
for recording ownership and size limits.
WebM recordings are converted to MP4 for Slack delivery without replacing the
original artifact. If conversion or upload fails, or native delivery is not
available on the current surface, Roomote shares only the artifact viewer link,
without an error or unavailability explanation. Roomote only describes a video
as attached when native delivery succeeds.
## Best practices
* Attach the smallest file that shows the issue clearly.
* Add one sentence explaining what you want Roomote to do with the file.
* Remove secrets or credentials before attaching files unless your deployment
is explicitly configured to handle that material.
* For spreadsheet or report exports, mention the tab, column, or row range
that matters most.
* For PDFs and documents, call out the section or page if you already know it.
## Common issues
* **The attachment is huge.** Trim it down or export just the relevant sheet,
log window, or section. Text-extracted files larger than 8 MB are rejected.
* **The attachment is a format not listed here.** Export it as one of the
accepted formats above.
* **The task still needs more context.** Add a short prompt that explains the
question, expected behavior, or failure you want Roomote to investigate.
# Goal Mode
Source: https://docs.roomote.dev/goal-mode
Keep a Roomote task working toward one objective across multiple turns.
Goal Mode keeps a Roomote task focused on one objective when the work may take
more than a single agent turn. Roomote carries the objective into each turn,
checks whether the full outcome is complete, and can continue automatically
when more work remains.
Use Goal Mode for work that has a clear finish line but may require several
rounds of investigation, implementation, or verification. For a normal scoped
request that should finish in one turn, send an ordinary task message instead.
## Start Goal Mode
Goal Mode starts on an existing task. The command does not create a new task.
### From the web task view
Enter `/goal` followed by the objective in the task composer:
```text theme={null}
/goal Reduce p95 checkout latency below 120 ms, verified by the checkout benchmark, while keeping the correctness suite green
```
You can also open the command picker from the composer and select `/goal`.
Describe the complete outcome after the command. Goal Mode does not accept file
attachments, so send any supporting files to the task before starting the goal.
### From Discord
In an active Roomote task thread or direct message, run:
```text theme={null}
/goal objective:Make the checkout test suite pass on the current branch without changing public API behavior
```
If there is no active task, start one with `/new` or mention Roomote first. See
[Discord](/providers/communications/discord) for the complete task workflow.
## What happens next
The first Goal Mode turn receives the objective as its task instruction. If the
agent reaches the end of a turn before the objective is complete, Roomote can
start another turn automatically in the same task and workspace.
By default, a goal can use up to five automatic continuation turns after its
initial turn. The goal stops earlier when the agent verifies that the complete
objective is done. It can also stop when the same concrete blocker prevents
progress across three consecutive goal turns. If neither happens before the
continuation budget is exhausted, the task settles without claiming the goal is
complete.
Ordinary follow-up messages in the task keep the active objective in context.
Starting `/goal` again replaces the previous objective and resets the
continuation budget for the new goal. If another Goal Mode activation is still
pending, wait for it to finish before starting a replacement goal.
## Write a useful objective
State what must be true when the work is done, the concrete evidence that will
verify it, and any constraints that must remain intact. The path to the outcome
can be uncertain, but the finish line should not be.
A weak goal names an activity without defining success:
```text theme={null}
/goal Improve checkout performance
```
A stronger goal defines the outcome, verification surface, and constraint:
```text theme={null}
/goal Reduce p95 checkout latency below 120 ms, verified by the checkout benchmark, while keeping the correctness suite green
```
Other verifiable objectives include:
* `/goal Make the checkout test suite pass on the current branch, verified by a clean test run, without changing public API behavior`
* `/goal Publish a Goal Mode guide that explains supported commands and completion states, verified by the docs build and current product behavior`
* `/goal Produce a deployment comparison that recommends one option and includes sourced cost estimates, operational tradeoffs, and remaining uncertainties`
Avoid open-ended objectives such as "keep improving the app." Without a
concrete finish line, the agent cannot reliably decide when the goal is
complete.
## When Goal Mode stops
Review the final task message, logs, diff, artifacts, and pull request just as
you would for any other task. A stopped goal may have one of these outcomes:
* **Complete**: the agent verified the entire objective before closing out.
* **Blocked**: the same external dependency or required user input prevented
progress across three consecutive goal turns.
* **Continuation limit reached**: the automatic continuation budget ran out
before the agent could verify completion.
If the goal stops before the outcome is complete, send the missing information
or narrow the remaining work, then start a new `/goal` in the same task when
the existing workspace and context are still useful.
# Homelab deployment
Source: https://docs.roomote.dev/homelab
Run Roomote on a Proxmox VM or another Linux server in your homelab.
Run Roomote on hardware you control with a dedicated Linux VM, private
administration over Tailscale, and a public HTTPS origin for provider callbacks
and task previews.
This guide uses **Proxmox VE with a Debian or Ubuntu VM** as the worked example.
Proxmox and Tailscale are not Roomote requirements: a bare-metal Linux server,
another hypervisor, WireGuard, or a conventional VPN can provide the same
roles.
Use a full virtual machine rather than an LXC container for the default Docker
sandbox provider. Roomote depends on Docker networking, cgroups, packet-filter
rules, and writable-layer quotas that are much easier to operate reliably in
a VM. LXC installations require host-specific privileged-container changes
and are not covered by this guide.
## Plan the deployment
The recommended homelab shape separates private administration from public
application traffic:
* **Proxmox VM:** runs Roomote, its datastores, and the default Docker task
sandboxes
* **Tailscale:** provides private SSH and administrative access to the VM
* **Public HTTPS origin:** receives source-control and communications-provider
callbacks and serves links generated by Roomote
* **Caddy:** terminates traffic for the application and task preview hostnames
Roomote supports x86\_64 and arm64. The installer requires at least 4 GB of RAM.
For a deployment that runs Docker task sandboxes on the same host, start with:
| Resource | Recommended starting point |
| -------- | --------------------------------------- |
| CPU | 4 vCPU, host CPU type |
| Memory | 8 GB |
| Disk | 60 GB or more on quota-capable storage |
| OS | Debian 12 or later, or Ubuntu 24.04 LTS |
The default limit for each Docker task is 2 CPUs, 4 GiB of memory, and a 20 GiB
writable layer. Increase the VM resources for concurrent or Docker-heavy tasks,
or use a [hosted sandbox provider](/compute) so task workloads do not compete
with the Roomote services.
## Create the Proxmox VM
Create a VM from a Debian or Ubuntu cloud image or installation ISO:
1. allocate at least 4 vCPU, 8 GB RAM, and 60 GB of disk
2. set the CPU type to `host` and use VirtIO for disk and networking
3. install and enable `qemu-guest-agent`
4. assign a DHCP reservation or static address on the LAN
5. enable SSH and apply operating-system updates
A bare-metal mini PC, an existing Debian or Ubuntu server, or a VM on another
hypervisor works too. The important boundary is a clean Linux host where Docker
Engine and its networking and storage controls can operate normally.
## Add private administration with Tailscale
Install Tailscale on the VM using the
[official Linux instructions](https://tailscale.com/kb/1031/install-linux), then
confirm you can reach the host over its tailnet address before changing router
or firewall rules. Use Tailscale SSH or regular SSH over the tailnet for host
administration.
Tailscale does not replace Roomote's public application origin. GitHub, Slack,
and other providers must reach callbacks from outside your tailnet. Live task
previews also use per-task hostnames, including wildcard preview DNS in the
normal production configuration.
Docker task sandboxes block private, link-local, shared-address, cloud
metadata, and Tailscale ranges by default. A repository hosted only on your
LAN or tailnet may be reachable from the VM but unreachable from a Roomote
task. Give self-hosted GitLab or Gitea a public, worker-reachable hostname
instead of disabling the sandbox network guard.
## Choose public ingress
Choose one stable hostname before completing the setup wizard. Changing it
later also means updating source-control, sign-in, and communications-provider
redirect and webhook URLs.
| Path | Best for | Tradeoffs |
| ------------------------------ | -------------------------------------------------------- | -------------------------------------------------------------------------- |
| Public DNS and port forwarding | Public IPv4, router control, and the simplest data path | Requires forwarding ports 80 and 443; dynamic addresses need DDNS |
| Cloudflare Tunnel | CGNAT or networks where inbound ports should stay closed | Requires tunnel and wildcard-hostname configuration |
| Tailscale Funnel | A limited public trial without router changes | Does not provide the wildcard hostname model needed for full live previews |
### Public DNS and port forwarding
Create DNS records for the application and wildcard previews:
```text theme={null}
roomote.example.com A/AAAA
*.roomote.example.com A/AAAA
```
Forward TCP ports 80 and 443 from the router to the VM, then run:
```sh theme={null}
curl -fsSL https://get.roomote.dev | sudo bash -s -- \
--domain roomote.example.com
```
The installer defaults to flat preview hostnames such as
`task-port-preview.`, covered by the `*.` wildcard record. Pass
`--preview-domain preview.` when you prefer the dedicated
`task-port.preview.` namespace; that layout needs
`preview.` and `*.preview.` records instead of `*.`.
If the public address changes, configure DDNS for both records. This path does
not work behind carrier-grade NAT unless the ISP supplies a public address.
### Cloudflare Tunnel
Cloudflare Tunnel can publish Roomote without forwarding inbound router ports.
Install Roomote with Caddy's internal TLS mode because Cloudflare terminates the
public certificate:
```sh theme={null}
curl -fsSL https://get.roomote.dev | sudo bash -s -- \
--domain roomote.example.com \
--tls-mode internal
```
Route both the application hostname and preview wildcard through the same Caddy
instance rather than routing directly to individual Roomote containers. Standard
Cloudflare certificates require Roomote's flat preview-hostname layout, which
the install command above already produces by default. Follow the canonical
[Cloudflare Tunnel and flat preview hostname configuration](https://github.com/RooCodeInc/Roomote/blob/main/SELF_HOSTING.md#flat-preview-hostnames)
for the tunnel ingress, origin TLS setting, and **Match SNI to Host** option
before testing or exposing task previews.
### Tailscale Funnel
Tailscale Funnel can expose a stable tailnet hostname to public callback
providers, but it does not support Roomote's normal wildcard preview hostname
layout. Treat it as a limited dashboard and callback trial, not the default
full deployment path. Use public DNS or Cloudflare Tunnel when users need live
task previews.
## Let a local agent prepare the host
Paste the following prompt into a local coding agent running on the VM or one
that can SSH to it. The agent prepares the host and installer; you complete
credential and authorization steps in Roomote's browser wizard.
```text theme={null}
Set up a self-hosted Roomote deployment on this homelab server.
Safety and scope:
- Work only on a dedicated Debian 12+ or Ubuntu 24.04+ VM or bare-metal host.
- Stop if this is an LXC container or if fewer than 4 GB RAM or 40 GB free disk
are available. Warn me and ask before continuing if other production
workloads share the host.
- Explain changes before using sudo. Do not disable the firewall or expose
database, Redis, object-storage, API, or queue-dashboard ports.
- Never ask me to paste model, GitHub, Slack, or other provider secrets into
chat or the shell. Those belong in Roomote's browser setup wizard.
Process:
1. Report the OS, architecture, CPU count, memory, free disk, default route,
public IPv4 detection result, and current Docker/storage configuration if
Docker is already installed. Do not change anything yet.
2. Ask me to choose one ingress path: public DNS plus ports 80/443, or
Cloudflare Tunnel. If I am behind CGNAT, recommend Cloudflare Tunnel. Ask for
the final application domain and optional preview domain.
3. Ask whether to install Tailscale for private SSH/admin access. If approved,
use Tailscale's official Linux package instructions and confirm access. Do
not treat the tailnet hostname as Roomote's public application origin.
4. For public DNS, tell me the exact app and wildcard DNS records (plus any
dedicated preview records if I chose a separate preview domain) and router
forwards I must create, then wait for me. Verify public DNS and ports
from outside the LAN where possible. For Cloudflare Tunnel, guide me through
creating the app and wildcard public hostnames without asking me to reveal a
tunnel token, and use Roomote's documented internal-TLS and flat-preview
configuration.
5. Download https://get.roomote.dev to a temporary file, show me the file path
and the exact installer flags you will use, and ask me to inspect it before
approval. Then run it with --domain and, for Cloudflare Tunnel, --tls-mode
internal. Do not write a new installer or manually recreate the Compose
stack.
6. Run `sudo roomote status`. If healthy, tell me to run `sudo roomote
setup-url` in a separate trusted terminal and open the result. Do not print,
capture, or repeat the tokenized URL in agent output or transcripts. Stop
while I complete sign-in, source control, inference, communications, and
environment setup in the browser.
7. After I confirm setup is complete, validate Docker's writable-layer quota
support, a small Roomote task, repository cloning, artifact upload, and a
configured preview. Summarize any failure and the relevant `roomote logs`
output without printing secrets.
```
## Complete setup in the browser
The installer sets up Docker, Compose, generated secrets, Caddy, the Roomote
services, a systemd unit, and the `roomote` host CLI. When it finishes, open the
tokenized setup URL it prints and configure:
1. the first admin account
2. a source-control provider and repository access
3. a ChatGPT subscription or inference provider
4. Docker or a hosted sandbox provider
5. an optional communications provider such as Slack
6. the first environment and Roomote task
Keep provider credentials in the setup wizard or your deployment secret store,
not in shell history or an agent conversation.
## Verify the homelab path
After setup:
1. run `roomote status` on the VM and confirm the services are healthy
2. open the public Roomote URL from a device outside the home network
3. confirm the expected repositories appear in Roomote
4. validate the sandbox provider from **Settings > Sandboxes**
5. run a small task and confirm it clones, executes, and uploads an artifact
6. test a configured live preview from outside the home network
7. if configured, mention the Roomote app in Slack and confirm it replies
Common homelab failures include:
* **The public URL works on cellular but not on Wi-Fi.** The router may not
support hairpin NAT. Add split-horizon DNS for LAN clients or use a resolver
that returns the correct internal route.
* **An `sslip.io` hostname does not resolve on the LAN.** DNS-rebind protection
may reject names that resolve to private addresses. Use a domain you control
or allow the exact hostname in the local resolver.
* **Certificates never issue.** Confirm public DNS, router forwarding, and host
firewall rules for ports 80 and 443. With a tunnel, use `--tls-mode internal`
and check the tunnel-to-Caddy origin TLS settings.
* **Port forwarding has no effect.** Compare the router WAN address with an
external public-IP check. Different addresses usually indicate CGNAT; use a
tunnel or request a public address from the ISP.
* **A task cannot clone a LAN repository.** Use a public, worker-reachable
source-control hostname. Do not remove the sandbox private-network guard.
## Back up and update
Use `roomote backup`, `roomote upgrade`, and `roomote rollback` for supported
day-2 operations. A Proxmox snapshot is useful before host maintenance, but it
does not replace an encrypted Roomote backup stored off the VM with its
passphrase stored separately. See [Self-hosting](/self-hosting#day-2-operations)
for backup, restore, and upgrade behavior.
# How Roomote works
Source: https://docs.roomote.dev/how-roomote-works
Understand where work starts, how Roomote runs, and how results come back.
Roomote is designed to act like a shared teammate inside the workflow your team
already has. It is not an IDE, a local copilot, or a desktop app. It is a
reviewable cloud agent that is most at home in chat, where teammates can ask
questions, assign work, and review updates from the conversations they already
use.
Roomote also works from your source-control provider, Linear, and the web
dashboard, but a chat surface such as Slack is the primary day-to-day surface
for most teams.
## Shared engineering work
Most natural-language work starts as a Roomote Session. The recommended first
path is to mention Roomote in chat with a scoped ask. Use it for
implementation, debugging, investigation, small refactors, test fixes,
documentation updates, planning, and codebase questions.
Good handoffs include:
* the outcome you want
* the repository, environment, or thread context Roomote should use
* links to related issues, pull requests, logs, or screenshots
* any constraints, such as "do not change the API contract" or "keep this
behind the existing feature flag"
* how you want the result returned, such as a plan, explanation, patch, or PR
Roomote acts autonomously on authorized work when the next step is clear, but
that autonomy does not give it authority over people. Unless you explicitly ask
it to coordinate teammates, Roomote leaves human ownership open instead of
assigning work, setting deadlines, or presenting proposed commitments as
accepted.
## Work that starts itself
Some work starts from repository events instead of a manual prompt. For
example, Roomote can review pull requests, follow up on PR comments, or help
with merge-conflict resolution when the relevant automation is enabled. Admins
manage these in the web app under **Automations** — see
[Automations](/automations).
The same review is available on demand. Mention Roomote on a pull request and
ask for a review, or ask in any Session, and the Review Code pipeline runs as a
task inside that Session and reports back when it finishes.
A pull request opened by a Roomote task stays part of the Session that asked
for the work. Mentions on that pull request join that Session rather than
starting a new one, and Roomote answers both on the pull request and where the
Session lives.
## Where work starts
| Surface | How work starts | Where updates appear |
| ------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------- |
| Slack | Mention Roomote or reply in an active Roomote thread | Slack thread and Session view |
| Teams | Mention the bot in a channel or group chat, or message it directly in a personal chat | Teams thread and Session view |
| Telegram | Mention the bot in a group chat, or message it directly in a private chat | Telegram chat and Session view |
| Discord | Mention the bot in a server or send it a direct message | Discord thread, forum post, or DM |
| Email | Email the deployment's AgentMail inbox from a verified account address | Replies in the same email thread and Session view |
| Web dashboard | Submit a prompt from **Home** | Session view in Roomote |
| Linear | Start an agent session or mention Roomote on an issue | Agent session replies and Session view |
| GitHub | Pull request events or `@`-mentions in PR and issue comments | GitHub comments, reviews, and Session view |
| GitLab | Repository or merge request follow-up when configured | GitLab activity and Session view |
| Gitea | Repository or pull request follow-up when configured | Gitea activity and Session view |
| Bitbucket | Pull request events or `@`-mentions when configured | Bitbucket activity and Session view |
| Azure DevOps | Repository or pull request follow-up when configured | Azure DevOps activity and Session view |
Chat is the recommended surface for the first Session after setup because it
makes Roomote visible inside an existing team conversation. Use the dashboard
when you want to continue a Session or open delegated task details such as
logs, diffs, and previews.
## How Roomote stays reviewable
Roomote runs delegated work in an isolated sandbox and keeps it visible. The
Session holds the conversation and reports; each task view exposes its
transcript, logs, diffs, previews, artifacts, and execution metadata before
anything ships.
For code changes, Roomote hands work back through normal delivery paths such
as a branch, pull request, or reviewable diff. For questions and planning, it
gives a clear answer or next step without pretending code was changed.
## Choosing an environment
In chat, Roomote's Fast Session decides whether a request needs a workspace
and which environment fits, and it says so before delegating. Reply in the
same thread to redirect it. When you start from the dashboard, choose the
environment yourself or leave the selector on **Fast** to let the Session
decide. A Linear agent session works the same way: the Session reads the
issue and chooses the environment before delegating.
If a request is ambiguous, the Session asks a clarifying question in the same
thread before it delegates, so you can name the environment or repository in
your reply. If the deployment's inference provider is unavailable, Roomote says
so in the thread instead of silently doing nothing; ask an admin to check the
provider connection in that case.
For more detail, see [Environments](/environments).
# Introduction
Source: https://docs.roomote.dev/index
Roomote is an open, self-hostable platform for cloud coding agents.
Roomote is an open, self-hostable platform for cloud coding agents. It runs
Roomote agents in isolated sandboxes, connects them to your repositories, and
lets your team start, follow, and review agent work from the web dashboard,
Slack, Microsoft Teams, Telegram, Discord, email, and your source-control
provider.
Use Roomote when agent work should be shared, reviewable, and available
outside one developer's editor. You keep control of the deployment,
repositories, inference provider, sandbox provider, and collaboration surfaces.
## Highlights
* **Quick setup** — a one-command installer brings up the full stack, then a
guided conversation helps you connect providers and start useful work.
* **Self-hosted by default** — run Roomote on your own server and connect the
providers your team already uses.
* **Self-configuring environments** — Roomote agents prepare their own
sandboxes from your repositories and setup guidance.
* **Easy to use web dashboard** — launch, follow, and steer tasks from the
browser.
* **Model agnostic** — bring your own key for OpenRouter, Anthropic, OpenAI,
and other inference providers.
* **Source control integrations** — GitHub, GitLab, Gitea, Bitbucket Cloud, and
Azure DevOps.
* **Conversation surfaces** — Slack, Microsoft Teams, Telegram, Discord, and
email through AgentMail.
* **Choose your own sandbox provider** — including Docker-in-Docker on your
own host.
## Where to go next
* [Self-hosting](/self-hosting) — run Roomote on your own server with the
one-command installer or Docker Compose.
* [How Roomote works](/how-roomote-works) — where work starts, how it
runs, and how results come back.
* [What to ask Roomote](/use-cases) — frame asks so tasks stay scoped,
useful, and reviewable.
* [Environments](/environments) — give Roomote the repositories, services,
secrets, and guidance it needs to run and verify work.
* [Review a task](/tasks) — inspect the transcript, logs, diffs, and
previews before anything ships.
* [Local development](/local-development) — set up the repository to
contribute to Roomote itself.
* [Architecture](/architecture) — a contributor-oriented map of the apps and
packages that make up Roomote.
## License
Roomote is released under the Fair Core License 1.0 (FCL-1.0-ALv2) —
source-available, with each release converting to Apache-2.0 two years after it
is published. A deployment is free for up to 10 registered users;
adding more users requires a paid license key (Settings → Users, or the
`R_LICENSE_KEY` environment variable). You can [buy a self-hosted license on
Roomote Cloud](https://cloud.roomote.dev/sign-up); purchased keys are refreshed
annually from the Cloud portal, and licensed deployments report their current
user count for subscription billing. The license prohibits disabling or
circumventing the license key functionality. See
the [LICENSE](https://github.com/RooCodeInc/Roomote/blob/main/LICENSE)
file for details.
# Asana
Source: https://docs.roomote.dev/integrations/asana
Bring Asana project and task context into Roomote tasks.
Connect Asana when your team plans or tracks work there and you want Roomote to
inspect projects, tasks, teams, and comments during a task.
## When to use it
* Turn an Asana task into a scoped investigation or implementation ask
* Pull project context into a Roomote task without copying it by hand
* Keep the task prompt grounded in the work your team is already tracking
## How setup works
Admins connect Asana from **Settings > Integrations** with a shared token. After
that, Roomote can use the shared connection inside tasks for the deployment.
## What to expect
Asana gives Roomote planning context. The reviewable work still happens in the
Roomote task view and, when code changes are involved, in your normal repository
review flow.
# Better Stack
Source: https://docs.roomote.dev/integrations/better-stack
Bring monitoring and incident context into Roomote tasks.
Connect Better Stack when investigations depend on logs, incidents, uptime
signals, or other monitoring context that already lives there.
## When to use it
* Investigate a production issue with the monitoring context already attached
* Inspect uptime or incident signals before deciding what to fix next
* Give Roomote operational evidence without pasting screenshots or summaries
into the prompt
## How setup works
Admins connect Better Stack once from **Settings > Integrations**.
## What to expect
Roomote uses Better Stack as task context for investigation and triage. Code
changes, validation, and review still happen through the normal Roomote task and
repository workflow.
## Recipes using this
* [Triage customer issues](/cookbook/support-channel)
# Braintrust
Source: https://docs.roomote.dev/integrations/braintrust
Give Roomote access to Braintrust prompts, runs, and results.
Connect Braintrust when your team evaluates prompts, runs, or model behavior
there and you want that context available in Roomote tasks.
## When to use it
* Inspect existing prompts before changing an AI feature
* Compare past runs or results during debugging
* Ground follow-up work in the evaluation system your team already uses
## How setup works
Admins enable Braintrust from **Settings > Integrations**. Each teammate then
links their own Braintrust account from [Personal Settings](/personal-settings)
when they need it.
## What to expect
Braintrust provides context for analysis and follow-up work. Roomote still hands
implementation and review back through the normal task and repository flow.
# Custom MCP Servers
Source: https://docs.roomote.dev/integrations/custom-mcp-servers
Connect MCP servers that are not in the built-in catalog
Custom MCP servers let agents use services that Roomote does not ship a
built-in integration for. Deployment admins configure them under
**Settings → Integrations → Custom MCP Servers**. Remote servers become
available to both Fast Sessions and sandbox tasks. Local stdio servers need a
task sandbox because Roomote launches their process inside that workspace.
Most MCP servers publish a JSON snippet in their docs. The add dialog's
**Import from JSON** button accepts a pasted `mcpServers` snippet (or a bare
server config) and prefills the form from it, for both remote and local
servers. Snippets that launch `mcp-remote` are converted to remote servers on
the upstream URL, which keeps credentials behind the Roomote proxy and
enables per-tool management.
Three kinds of servers are supported:
| Kind | How it connects | Where credentials live |
| ------------------- | ----------------------------------------- | --------------------------------------------- |
| Remote, no auth | Streamable HTTP through the Roomote proxy | None |
| Remote, header auth | Streamable HTTP through the Roomote proxy | Encrypted server-side; injected by the proxy |
| Remote, OAuth | Streamable HTTP through the Roomote proxy | Tokens stored and refreshed server-side |
| Local (stdio) | Launched inside the task sandbox | Encrypted at rest; visible inside the sandbox |
## How remote servers are reached
Remote custom servers are never handed to the task sandbox directly. The
sandbox and Fast use an authenticated Roomote proxy, and the proxy injects the
real credentials per request. This means:
* Header values and OAuth tokens never appear in sandbox-readable
configuration or in the browser after saving.
* Header auth covers servers that expect a static
`Authorization: Bearer ` as well as custom schemes like
`x-api-key`. Roomote's own caller credentials are never forwarded
upstream.
* OAuth tokens refresh centrally, so long-running tasks keep working across
token expiry.
* Per-tool disables (the **Manage tools** dialog) are enforced at the proxy:
disabled tools are hidden from agents and blocked even if called directly.
## OAuth
For servers that support the MCP authorization spec, pick **OAuth** and use
**Connect** after saving. Roomote discovers the authorization server, uses
Dynamic Client Registration when the server supports it, and completes the
flow with PKCE. For servers without Dynamic Client Registration, register an
OAuth client for the callback URL shown in the dialog
(`https:///api/mcp-oauth/callback`) and enter the client ID and
secret manually.
If a token refresh is rejected by the server, the connection is marked as
needing reconnection: agents get a clear error pointing at Settings, and the
server card shows **Connect** again.
Roomote sends the RFC 8707 `resource` indicator by default, as required by
the current MCP authorization spec. A per-server toggle disables it for
servers that reject unknown parameters.
## Local (stdio) servers
Local servers run inside the task sandbox, launched with the command,
arguments, and environment variables you configure. Two things to know:
* The process runs with the same privileges as the agent itself; its
environment values are visible inside the sandbox at runtime, exactly like
environment-scoped stdio servers.
* Environment values can reference
[deployment environment variables](/environment-variables) with `${VAR}`
syntax. References to Roomote runtime credentials are rejected at save
time.
The sandbox image ships `node`, `npx`, `uvx`, and `python`, so
`npx -y ` style servers work out of the box.
## Scoping and precedence
Custom servers configured in Settings apply to every task. An environment's
own [`mcpServers`](/environments/definition#mcp-servers) entry with the same
name takes precedence in that environment, so the more specific scope wins.
Names that collide with built-in integrations (for example `linear` or
`github`) are reserved and rejected.
## Private networks and self-hosting
For security, the Roomote control plane refuses to connect to private and
special-use address ranges (RFC 1918, link-local, cloud metadata) when
proxying to custom servers or running OAuth discovery. Self-hosted
deployments that intentionally run MCP servers on an internal network can
allow specific ranges with the `R_CUSTOM_MCP_ALLOWED_PRIVATE_CIDRS`
environment variable, for example:
```bash theme={null}
R_CUSTOM_MCP_ALLOWED_PRIVATE_CIDRS=10.20.0.0/16,192.168.7.0/24
```
This is a CIDR list rather than an on/off switch so that opening one internal
host does not expose adjacent services (databases, caches) to
operator-configured URLs. Redirects from custom servers are never followed.
## Operator controls
* Custom servers are managed by deployment admins only.
* `R_CUSTOM_MCP_DISABLED=true` disables the feature entirely: the Settings
section, the proxy routes, and delivery to tasks. It is independent of
`R_CURATED_INTEGRATIONS_DISABLED`, so a deployment can disable the built-in
catalog while still using its own custom servers.
* A custom server's tool descriptions are provided by that server and are
untrusted model input; review new servers the way you would review a
dependency.
## Notes
* Changes to custom servers apply to newly started tasks. Remote credential
edits (headers, reconnects) apply immediately because the proxy resolves
them per request.
* Editing a server's URL or auth mode clears its stored OAuth tokens and
requires reconnecting, so credentials can never be replayed against a
different endpoint.
# ElevenLabs
Source: https://docs.roomote.dev/integrations/elevenlabs
Add voice narration to Roomote feature-demo videos.
Connect ElevenLabs when you want Roomote to add voice-over narration to
[feature-demo videos](/cookbook/feature-demo-videos).
## How setup works
A deployment admin connects ElevenLabs once from **Settings > Integrations**
with:
* an ElevenLabs API key scoped to text-to-speech only, preferably with a credit
limit
* the voice ID to use for narration
## What to expect
ElevenLabs is a credential-only integration. Roomote uses it on the control
plane to synthesize narration; agents receive no ElevenLabs tools, and the API
key is not sent to task sandboxes.
Self-hosted operators can instead set `R_ELEVENLABS_API_KEY` and
`R_ELEVENLABS_VOICE_ID`. The connection configured in **Settings >
Integrations** takes precedence when both sources are available.
# Grafana
Source: https://docs.roomote.dev/integrations/grafana
Let Roomote inspect shared Grafana dashboards, alerting state, annotations, and data sources during a task.
Connect Grafana when your team uses it as the shared source of truth for
dashboards, alerting, and operational annotations.
## When to use it
* Inspect dashboards and panel definitions while debugging an incident
* Review alert rules plus current alert instances and states without leaving
the task
* Pull annotation history and data source context into monitoring-heavy
investigations
## How setup works
Admins connect Grafana from **Settings > Integrations** with the Grafana
instance URL and a shared service account token.
## What to expect
The current Grafana integration is read-only. It gives Roomote monitoring
context during a task, but it does not create dashboards, edit alerts, or change
Grafana configuration.
## Recipes using this
* [Triage customer issues](/cookbook/support-channel)
# Granola
Source: https://docs.roomote.dev/integrations/granola
Give Roomote read-only access to shared Granola meeting context.
Connect Granola when decisions, action items, and implementation context live in
your meeting notes and you want that context available in Roomote tasks.
## When to use it
* Browse past meetings for relevant decisions and discussions
* Read meeting notes and transcripts while planning or implementing work
* Find action items, attendees, and related meeting folders during follow-up work
## How setup works
A deployment operator connects Granola once from **Settings > Integrations**
with an API key. Granola API keys require a Business or Enterprise plan.
Prefer a **workspace API key** from **Granola Settings > Connectors > Workspace
API keys**. Workspace keys belong to the workspace rather than an individual,
do not expire, and cannot read ordinary private notes. They can read:
* notes visible to everyone in the workspace, including the Team space
* notes in spaces where **Allow Granola API access** is enabled
Granola enables API access by default for newly created spaces. Review
**Settings > Spaces** and turn it off anywhere Roomote should not read notes.
If a workspace key is not available, create a personal key from **Settings >
Connectors > API keys** and select only **Public notes**, leaving **Personal
notes** unchecked.
## What to expect
The built-in Granola connection is read-only. Roomote can list and read the
notes, folders, meeting details, and transcripts allowed by the configured key,
but it cannot modify Granola content or manage Granola webhooks.
# Integrations Overview
Source: https://docs.roomote.dev/integrations/index
Connect the tools that give Roomote the right context inside tasks.
Integrations give Roomote more context inside a task: tickets, docs,
monitoring, analytics, data systems, customer history, deployment state, and
shared memory.
This section does not list provider categories that have their own setup paths:
communications providers, source-control providers, inference providers, and
sandbox providers. Configure those from the provider-specific docs instead.
Deployment operators can prevent every integration in this curated catalog
from being configured or used by setting
`R_CURATED_INTEGRATIONS_DISABLED=true` and restarting Roomote. Existing
connections remain stored but inactive, so unsetting the value restores
them. This policy does not affect the separate provider categories above or
MCP servers defined on an environment.
## Connection patterns
You will usually see one of these setup models:
* **Admin connection once**: an admin connects the integration for the
deployment from **Settings > Integrations**
* **Enable first, then teammates link accounts**: an admin enables the
integration, then each teammate links their own account from
[Personal Settings](/personal-settings) when they need it
* **Workspace plus user identity**: the deployment connects the integration,
then individual users link their identity so Roomote can associate actions
correctly
## Manage available tools
Some connected integrations expose a **Manage tools** action in
**Settings > Integrations**. Admins can use it to restrict the types of
operations Roomote can make with the service.
Use this as a coarse permissions system, for example allowing only read
operations or restricting access to a certain type of entity. The list varies
depending on the integration.
Some integrations can only list tools after the first user links their account
from [Personal Settings](/personal-settings).
## Supported integrations
| Integration | Best for | Connection model |
| ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | ------------------------------------------ |
| | Project and task context from Asana | Admin connection once |
| | Monitoring and incident context | Admin connection once |
| | Prompts, runs, and evaluation context | Enable first, then teammates link accounts |
| | Voice narration for feature-demo videos | Admin connection once |
| | Dashboards, alerting, and monitoring context | Admin connection once |
| | Meeting notes, transcripts, and decisions | Admin connection once |
| | Issues, projects, and JQL-backed issue context | Admin connection once |
| | Turning issues into Roomote work | Workspace plus user identity |
| | Board, item, and workspace context | Enable first, then teammates link accounts |
| | Database inspection in Neon | Enable first, then teammates link accounts |
| | Shared docs and database context | Admin connection once |
| | Product analytics, experiments, and error context | Admin connection once |
| | Customer issue and account context | Admin connection once |
| | Project and service context from Railway | Admin connection once |
| | Email delivery and infrastructure management | Admin connection once |
| | Authoritative employee and reporting context | Admin connection once |
| | Error and performance investigation | Admin connection once |
| | Data warehouse exploration | Admin connection once |
| | Read-only database access in Supabase | Enable first, then teammates link accounts |
| | Shared memory across tasks and Fast sessions | Admin connection once |
| | Deployments, logs, and domain availability | Admin connection once |
| | Voice calls with Roomote on Fast Sessions | Admin connection once |
| | Public X posts, users, trends, and news | Admin connection once |
| | Paid external capabilities via Zero | Admin connection once |
## Custom MCP servers
Beyond the built-in catalog, you can connect your own MCP servers at two
scopes:
* **Deployment-wide**, under Settings → Integrations →
[Custom MCP Servers](/integrations/custom-mcp-servers): remote servers
(with header or OAuth authentication, credentials held server-side) and
local stdio servers, available to agents in every task.
* **Per-environment**, in the YAML view of the environment editor. See
[Environments](/environments). An environment entry with the same name as a
deployment-wide server takes precedence in that environment.
Use deployment or user-linked integrations when the tool is broadly useful
across teams. Use an environment-level MCP server when the tool only makes
sense for one workspace, repository set, or self-hosted service.
To use Roomote itself from an external OAuth-capable MCP client, connect the
[Roomote MCP](/integrations/roomote-mcp). It can inspect Roomote and connected
chat context, search and read tasks, list launch environments, launch or cancel
tasks, and send follow-up messages. Its browser-issued credential does not grant
general API or admin access.
## A practical order
For most teams, this order works well:
1. the required providers:
[Comms](/communications), [Source Control](/source-control),
[Inference](/models), and [Sandboxes](/compute)
2. one task-tracking integration, such as Linear, Jira, or Asana, if your team
already works there
3. one monitoring or deployment integration, such as Sentry, Grafana, Railway,
Better Stack, or Vercel, when investigations need it
4. one knowledge-base integration, such as Notion, to get tasks done directly
from specs and runbooks
5. one data integration, such as Snowflake, Supabase, or Neon, when tasks need
database or warehouse context
6. Supermemory when you want durable team context to carry across tasks and
Fast sessions
After each connection, run a small task that uses the new context. For example,
ask Roomote to summarize a linked issue, inspect a monitoring alert, or explain
which environment a support thread belongs to.
# Jira
Source: https://docs.roomote.dev/integrations/jira
Bring Jira issue and project context into Roomote tasks.
Connect Jira when your team already tracks engineering work there and you want
Roomote to read issue, project, workflow, and JQL-backed context directly.
## When to use it
* Start with the acceptance criteria and discussion already on the Jira issue
* Inspect related issues or project context before planning work
* Keep the prompt grounded in the same ticket system your team already uses
## How setup works
Admins connect Jira from **Settings > Integrations** for the deployment.
## What to expect
Jira gives Roomote richer issue context. The task transcript, evidence, and any
resulting code review still live in Roomote and your repository workflow.
# Linear
Source: https://docs.roomote.dev/integrations/linear
Turn Linear issues into scoped Roomote work.
The Linear integration lets Roomote receive work from Linear, post progress back
to the issue or agent session, and keep the full run available in the Roomote
task view. When the Brain is configured, Roomote also indexes issues from the
connected workspace so agents can recall product context before opening Linear.
Linear is optional during onboarding. Connect it when your team wants Roomote to
work from issues that already have product context, acceptance criteria,
priority, or discussion.
## Setup
On a self-hosted deployment, an administrator goes to **Settings >
Integrations**, selects **Set up Linear**, and then selects **Create the
app** to open the pre-filled manifest. The app name defaults to `Roomote`.
After creating the private app, copy its client ID, client secret, and
webhook secret back into Roomote. Roomote encrypts the saved credentials.
Select **Connect Linear**, approve the app in Linear, and return to Roomote.
Deployments that provide `R_LINEAR_CLIENT_ID`,
`R_LINEAR_CLIENT_SECRET`, and `R_LINEAR_WEBHOOK_SECRET` in the runtime
environment skip Roomote's credential-entry flow, but the Linear app must
still use `https:///api/mcp-oauth/callback` as its OAuth
redirect URI and `https:///api/webhooks/linear` as its
`AgentSessionEvent` webhook URL.
A deployment administrator can return to **Settings > Integrations** and
select **Configure** on Linear. Saving a new client ID or client secret
disconnects the current workspace so it can be authorized again. Removing
saved credentials disables Linear but does not delete the app in Linear.
Credentials managed by the deployment environment must be changed there.
Link your Linear identity when prompted so Roomote can associate issue
activity with your Roomote user.
Roomote needs an environment that matches the repository or workspace the
issue refers to.
## Starting work from Linear
You can start Roomote work from a Linear agent session or by mentioning Roomote
on an issue. Each agent session is a Roomote Session: Roomote reads the issue,
its comments, and any agent guidance, answers directly when no workspace is
needed, and otherwise picks the environment and starts a task bound to the
session. Reply in the same session to redirect it, ask a follow-up, or steer a
running task. The session links to the Session page in Roomote so you can
follow the full transcript there.
Good Linear asks include:
* draft an implementation plan for this issue
* investigate whether this bug is reproducible
* implement the smallest fix that satisfies the acceptance criteria
* explain what code paths this issue touches
* open a PR and link it back to the issue
## Progress and follow-up
Roomote posts its replies and the outcome of delegated tasks back to the agent
session. While a delegated task runs, its thoughts, actions, and plan updates
stream into the session live, and it asks its questions there when it needs
your input. The Roomote Session and task views remain the best place to
inspect logs, diffs, artifacts, and previews.
## Brain context
The Brain keeps one durable page per visible Linear issue, including its current
workflow state, team, project, priority, labels, assignee, description, and a
bounded set of recent comments. When available, issue pages also include cycle,
estimate, start date, parent, and related-issue context. Collection uses the same
workspace connection configured above; it does not require another Linear token.
Roomote refreshes changed issues incrementally and periodically checks the full
visible issue set. Archived issues remain available as historical context. If an
issue is deleted or the connected app can no longer see it, Roomote removes its
page only after a complete visibility check, avoiding deletion from a partial or
failed API response.
Put acceptance criteria and relevant repository links directly in the Linear
issue before starting agent work.
# monday.com
Source: https://docs.roomote.dev/integrations/monday
Bring monday.com board, item, update, and workspace context into Roomote tasks.
The monday.com integration connects Roomote to monday.com's hosted MCP server.
It gives agents read-only access to the monday.com data the connected user can
already access.
Use it to inspect:
* boards, groups, columns, items, and activity
* item updates and monday WorkDocs
* workspaces, users, teams, forms, and assets
* automations, meetings, and monday dev sprint context
## Setup
A deployment administrator opens **Settings > Integrations**, finds
**monday.com**, and selects **Enable**. The administrator can also manage
which read-only monday.com tools are available to tasks.
Each user opens **Personal Settings**, selects **Link account** for
monday.com, and approves the OAuth request. Tool calls use that user's
monday.com permissions.
Include a monday.com board or item link in the request, or ask Roomote to
find the relevant board, item, update, or document after your account is
linked.
## Access model
The connection is user-scoped. Roomote does not share one person's monday.com
credentials with another person or use them for tasks that have no acting user.
The built-in integration exposes a read-only subset of monday.com's MCP tools.
It does not create or modify boards, items, columns, updates, workflows, agents,
or other monday.com data.
This MCP connection provides monday.com context inside Roomote tasks. Starting
Roomote tasks from monday.com assignments or mentions is not part of this
integration.
## Troubleshooting
If monday.com is unavailable in a task:
* confirm an administrator enabled it in **Settings > Integrations**
* confirm you linked your account in **Personal Settings**
* reconnect your account if monday.com reports that authorization expired or
was revoked
* confirm your monday.com user can access the requested board, item, or document
# Neon
Source: https://docs.roomote.dev/integrations/neon
Let Roomote inspect Neon databases during a task.
Connect Neon when Roomote needs direct database context from your Neon projects
while it investigates, plans, or explains a change.
## When to use it
* Inspect database state while debugging
* Answer schema or data questions tied to a task
* Connect repository work to the database environment it depends on
## How setup works
Admins enable Neon from **Settings > Integrations**. Each teammate then links
their own Neon account from [Personal Settings](/personal-settings) when they
need it.
## What to expect
Neon gives Roomote database context inside the task. Keep any repository changes
and human review on the normal Roomote and Git workflow.
## Recipes using this
* [Triage customer issues](/cookbook/support-channel)
# Notion
Source: https://docs.roomote.dev/integrations/notion
Bring approved Notion pages and data sources into Roomote tasks.
Connect Notion when product specs, runbooks, notes, or operating context already
live there and Roomote should use that material during tasks and automations.
## Access boundary
Roomote uses a Notion **internal integration**, not Notion's hosted MCP OAuth
connection. Notion itself restricts the token to pages and data sources that
have been explicitly shared with the internal integration. Unshared content,
including private pages, is unavailable to Roomote.
Sharing a parent page may also grant access to its children. Review the content
access list in Notion whenever the page hierarchy changes.
## Set up Notion
1. In [Notion integrations](https://www.notion.so/profile/integrations/internal),
create an internal integration for Roomote.
2. In the integration's **Configuration** tab, enable only the capabilities
Roomote should have: read, update, insert, and comment access are controlled
independently by Notion. If Memory should link Notion identities to
Roomote members, also grant the user-information capability that includes
email addresses; without it, Memory keeps stable but unlinked Notion
user references.
3. In Notion, share only the approved pages and data sources with the new
integration. You can manage this from the integration's **Content access**
settings or a page's **Connections** menu.
4. Copy the internal integration secret.
5. In Roomote, open **Settings > Integrations**, choose **Configure Notion**,
and paste the secret.
The secret is encrypted server-side and is never sent to task sandboxes.
When Memory is enabled, Roomote also backfills the pages shared with this
integration and keeps their Markdown snapshots current. Notion pages are
stored under the `notion/` namespace. New and edited pages are picked up on
regular Memory collector ticks, and a daily full sweep discovers older pages
that were newly shared without being edited. Because Notion's search index
does not reliably surface pages that live inside databases, the sweep also
enumerates every shared data source and walks page trees to capture database
rows and other inheritance-shared pages, running that discovery to
completion in a continuous loop rather than trickling across scheduled
ticks. The same sweep replaces pages
that are no longer shared with unavailable tombstones, so their former
content is no longer retained in Memory search results.
When the integration's capabilities allow listing users, Memory also
refreshes the workspace user directory once a day to link page authors,
people properties, and mentions to people cards. Verified email addresses
are used only to match Notion users to Roomote members and are never copied
into Memory pages. Users removed from the workspace have their Notion
identity cards marked deleted on the next daily refresh, and revoking the
user-information capability retracts the whole directory the same way.
Roomote agents can read and update page content as enhanced Markdown, move
regular pages beneath another page or into a data source, and create blocks at
the start or end of existing content or after a specific child block. Agents
can also create a database, its initial data source, and its first table view
beneath an approved page or as a private workspace page. After creation, agents
can update database metadata and placement, add, rename, reconfigure, or delete
data source properties, and create, configure, or delete database views. These
operations use Notion's public API rather than Notion's hosted MCP tools, so
their schemas and limitations follow the public API.
The database update API can replace an icon or cover, but its current schema
does not accept `null` to remove either one. Data source icons can be cleared.
Notion's public API cannot move or reorder an existing block. Positional block
insertion applies only to newly created blocks. Preserving a block's ID while
recreating it in another position is also unsupported.
Roomote's deployment-wide integration is not a proxy for Notion's hosted MCP.
Hosted-only features such as connected-source search, attachment helpers, page
duplication, folders, meeting-note queries, and workspace team or user lookup
are not currently exposed as agent tools.
(Memory's identity linking reads the workspace user directory directly
through the public API, as described above.) Roomote instead provides the
direct public-API operations that work with a restricted internal
integration token.
A previous hosted-MCP OAuth connection is not reused because it inherits the
authorizing person's full Notion permissions. Configure an internal
integration before enabling this deployment-wide connection.
## Control capabilities
Notion's **Configuration** tab is the source of truth for what Roomote can do.
Disable update, insert, or comment capabilities there when the connection
should be read-only. Roomote exposes its Notion tools, but Notion rejects any
operation the integration's capabilities do not permit.
Creating databases and inserting blocks require **Insert content**. Creating a
view requires both **Insert content** and **Update content**. Updating database
metadata, data source schemas, views, page locations, or page Markdown requires
**Update content**, including access to destination parents. Notion does not
allow deleting the last remaining view in a database. Changing capabilities on
an existing internal integration takes effect without reconnecting Roomote.
# PostHog
Source: https://docs.roomote.dev/integrations/posthog
Let Roomote inspect analytics, experiments, and error-tracking context from PostHog.
Connect PostHog when tasks depend on product analytics, feature flags,
experiments, or error-tracking context that already exists there.
## When to use it
* Investigate why a metric changed
* Inspect feature-flag or experiment context before making a change
* Answer product questions without exporting data into the prompt
## How setup works
Admins connect PostHog once from **Settings > Integrations**.
## What to expect
PostHog gives Roomote deployment-level product context during a task.
Implementation work and review still happen through the normal Roomote and
repository flow.
# Pylon
Source: https://docs.roomote.dev/integrations/pylon
Bring customer issue and account context from Pylon into Roomote tasks.
Connect Pylon when your team investigates support issues there and you want
Roomote to start with the customer history and account context already attached.
## When to use it
* Investigate a customer-reported issue without copying the whole thread
* Connect support context to the repositories or environments that matter
* Speed up follow-up work on issues your support team already triages
## How setup works
Admins connect Pylon once from **Settings > Integrations**.
## What to expect
Pylon gives Roomote customer context for the task. Technical review and code
review still happen in the Roomote task view and your normal repository
workflow.
# Railway
Source: https://docs.roomote.dev/integrations/railway
Let Roomote inspect Railway projects and services during a task.
Connect Railway when your team runs services there and Roomote should be able to
inspect the project and service context that surrounds a task.
## When to use it
* Investigate deployment or service questions tied to a Railway project
* Inspect the service context behind a bug report or operational issue
* Connect repository work to the platform state your team is operating
## How setup works
Admins connect Railway once from **Settings > Integrations**.
## What to expect
Railway provides deployment-level service context during a task. Roomote still
returns work through the task view and your normal engineering review flow.
# Resend
Source: https://docs.roomote.dev/integrations/resend
Inspect and manage shared email infrastructure from Roomote tasks.
Connect Resend when tasks need email delivery status, received messages,
domains, contacts, templates, broadcasts, or other email infrastructure.
## How setup works
An admin connects Resend once from **Settings > Integrations** using OAuth. The
connection is shared across the deployment and requests Resend's
`full_access` scope so Roomote can use inspection and management tools.
## Safer defaults
Roomote initially disables tools that send or reschedule email, create or
remove API credentials, mutate domains or webhooks, mutate or trigger
automations, and mutate contacts. Read operations remain available, and
canceling a pending scheduled email remains enabled as a safety action.
The disabled tools include:
* single, batch, and broadcast sending
* rescheduling a scheduled email
* creating or removing API keys that could bypass Roomote's tool policy
* creating or updating automations, or sending events that trigger them
* updating or removing domains
* creating or updating webhooks
* creating, updating, or removing contacts
* creating, updating, or removing contact properties
* changing contact segment or topic membership
* importing contacts from CSV
An admin can opt in to individual tools from **Settings > Integrations >
Resend > Manage tools**. Disabled tools are hidden from tasks and rejected by
the server if called directly. Admin choices persist when Resend is reconnected
or disabled and enabled again.
## Verify the connection
After connecting Resend, start with a read-only request such as listing recent
emails or checking domain status. Enable only the additional tools your team
expects Roomote to use.
# Rippling
Source: https://docs.roomote.dev/integrations/rippling
Give Memory an authoritative employee directory and reporting structure from Rippling HRIS.
Connect Rippling when Memory should use your HR system as the source of truth for
who works at the company, where they sit in the organization, and who they
report to.
## Prerequisites
Rippling's V2 REST API requires the API product for your company. The admin who
creates the token needs access to the **API Tokens** app and a company-wide
permission profile. A token limited to the creator's direct or indirect reports
cannot produce an authoritative company roster.
Create a token with the scopes needed to read the roster and its expanded
references:
* `workers.read`
* `users.read`
* `departments.read`
* `teams.read`
* `work-locations.read`
Rippling applies both the token scopes and the token owner's permission profile.
Review both if employees or fields are missing. Rippling also revokes a token
when its owner is terminated or the token is unused for more than 30 days.
See Rippling's [API token and permission
guide](https://developer.rippling.com/documentation/rest-api/essentials/api-tokens)
and [HRIS getting-started
guide](https://developer.rippling.com/documentation/rest-api/guides/hris-getting-started)
for the current account requirements.
## Connect Rippling
1. Create a company-wide API token in Rippling with the required read scopes.
2. In Roomote, open **Settings > Integrations** and choose **Configure
Rippling**.
3. Paste the API token and save.
Roomote verifies the token against Rippling's V2 workers endpoint before it is
stored. The token is encrypted on the control plane and is never sent to task
sandboxes or exposed as an agent tool.
## What Memory collects
Roomote collects the Rippling worker resource ID, permanent employee number when
Rippling returns one, manager ID, work email, name, title, department and team
memberships, employment type, available location and time-zone data, start and
end dates, and Rippling's worker status. A work email that exactly matches a
Roomote account links the Rippling identity to that existing person card.
Person pages preserve:
* `rippling-hris` provenance and the snapshot observation time
* exact Rippling status alongside Memory's active or inactive status
* explicit `reports_to` and membership fields marked as authoritative HRIS data
* a clear distinction between those source-of-truth relationships and
collaboration relationships inferred from messages, meetings, or code review
Memory is deployment-wide. Work emails and HR attributes collected through
this integration are available to teammates who can use the deployment's
Memory.
## Sync and lifecycle behavior
Roomote follows Rippling's cursor pagination and builds resumable full roster
snapshots. It retries temporary failures and `429` rate limits with bounded
backoff. Inventory reconciliation happens only after the final page succeeds,
so a failed or interrupted snapshot cannot deactivate employees accidentally.
Terminated workers remain represented with Rippling's exact status and end date.
Workers absent from a later complete snapshot, or left behind after the
integration is disconnected, become unavailable tombstones so stale active
profiles and relationships do not remain searchable.
Rippling's Worker Changes API is a separately entitled product. Roomote does not
assume it is available; the baseline integration uses safe snapshots for every
customer instead.
# Roomote MCP
Source: https://docs.roomote.dev/integrations/roomote-mcp
Start, inspect, and continue Roomote Sessions and tasks from your MCP client.
Roomote MCP brings your Roomote workspace into the coding tools you already
use. From any OAuth-capable MCP client, you can start a Session, inspect its
conversation and delegated tasks, and follow up without switching back and
forth between tools.
## What you can do
### Start a Session
Ask your MCP client to start Roomote with a clear message. The ordinary start
action creates a Session, where Fast can answer directly or delegate repository
work to tasks. You can keep working locally and return to the same Session for
the result. When work must start directly in a known compute environment, your
client can still use the explicit environment-targeted task launch action.
### Check on and steer existing work
Search finds Sessions by default. Once you find one, provide its Session ID to
read the summary or newest conversation messages and to send a follow-up. When
you need one concrete coding task instead, use task search and pass its task ID;
the task ID takes precedence if both identifiers are supplied. Compute logs,
cancellation, environment-targeted launch, and task model controls remain
task-specific operations.
For extended coordination, clients can use `get_updates` instead of re-reading
the full transcript. Each response contains only new user-visible
narrative in chronological order, an opaque cursor for the next poll, current
Session or task state, and an explicit response-needed flag. Tool calls, tool
results, hidden reasoning, and transcript metadata are excluded. Reusing the
cursor after no new activity returns an empty narrative delta rather than the
same messages again; full transcript reads remain available for debugging.
When relaying between Codex and Roomote, summarize substantive messages with
the labels `Codex → Roomote` and `Roomote → Codex`. Relay questions or input
needs promptly, skip narration for unchanged polls, and make the final answer
self-contained. Relay summaries should cover visible narrative and decisions,
not credentials, raw tool traces, hidden reasoning, or oversized internal
payloads. Successful follow-up sends include the exact target and text accepted
by Roomote so the client can summarize the outbound message without guessing.
This is useful when you want to:
* catch up on a Session that is already active
* find an earlier investigation or implementation
* inspect a delegated task when you need its execution details
* pull the result of a Roomote task into your current conversation
* send follow-up instructions or cancel task work that is no longer needed
Follow-up instructions normally wait behind the task's current turn. When the
new instruction must take effect immediately, ask your MCP client to steer the
running task; steering interrupts the active turn instead of adding the message
to the task queue.
### Bring in Roomote and chat context
Ask what your Roomote deployment can do or which integrations are connected.
You can also read relevant conversation history from connected chat channels.
For Slack and Discord, provide a channel or message link when you want context
from a specific conversation.
Roomote still applies the access rules from the connected service, so the MCP
only returns conversations your signed-in user is allowed to read.
## Things to try
* “Push what I’m working on to a remote branch, then start a Roomote task from
that branch to take over.”
* “Start a Roomote Session to investigate this bug.”
* “Find my active Sessions related to OAuth and summarize their progress.”
* “Find the coding task for this pull request and show its compute logs.”
* “Show me the messages and compute logs from the task that failed this
morning.”
* “Tell the running task to add a regression test before it opens the PR.”
* “Read the latest messages from this Fast Session and send a follow-up.”
* “Use this Slack message as context and explain what the team decided.”
* “Cancel the task working on the old approach.”
## Connect your MCP client
Use your Roomote URL with `/mcp` appended:
```text theme={null}
/mcp
```
For example:
```text theme={null}
https://roomote.example/mcp
```
### Claude Code
Add Roomote at user scope so it is available across your projects, then start
the browser sign-in:
```bash theme={null}
claude mcp add --transport http --scope user roomote /mcp
claude mcp login roomote
```
You can also open `/mcp` inside Claude Code to manage the connection and sign
in.
Claude Code requests a temporary loopback URL for the browser to return the
authorization result to the running CLI. Roomote accepts localhost, IPv4, and
IPv6 loopback callbacks with client-selected ports.
### Codex
Add the streamable HTTP server, then authenticate it:
```bash theme={null}
codex mcp add roomote --url /mcp
codex mcp login roomote
```
The Codex CLI and IDE extension share this MCP configuration.
Codex Desktop can request a native app link during OAuth so the browser returns
the authorization result to the originating connection flow. The CLI and IDE
extension may instead use a loopback HTTP callback.
### Cursor
Add Roomote to `~/.cursor/mcp.json` to use it in every project, or to
`.cursor/mcp.json` to keep it project-specific:
```json theme={null}
{
"mcpServers": {
"roomote": {
"url": "/mcp"
}
}
}
```
Open **Customize** in Cursor, find Roomote under MCP servers, and complete the
browser sign-in.
Cursor can request a native app link, a hosted HTTPS callback, or a loopback
HTTP callback. Roomote accepts each form and returns the authorization result
to the exact callback Cursor registered.
In each client, Roomote opens a browser so you can sign in and approve the
connection. During OAuth dynamic client registration, the client sends Roomote
its callback URL in `redirect_uris`. Roomote validates and saves that URL, then
only sends the result to the same registered URL after approval. You do not
need to create or copy an API token.
Roomote validates callbacks by callback class instead of maintaining a list of
client-specific URLs: HTTPS for hosted clients, HTTP only on loopback
interfaces for local clients, and non-browser private URI schemes for native
apps. Unsafe browser, file, and network schemes are rejected. The approval page
shows the exact registered callback before Roomote redirects to it.
On a self-hosted deployment, the configured `R_PUBLIC_URL` (or `R_APP_URL`)
must be a browser-reachable HTTPS address. Desktop clients may use a loopback
HTTP callback. Roomote supports the callback forms described above for all
three documented clients.
## Access and safety
Roomote MCP works with the permissions of your signed-in Roomote user. It can
use the task and context tools described above, but it does not provide general
Roomote API access or administrator privileges. Existing Roomote permissions
and connected-service access checks still apply to every request.
You can revoke the connection from your MCP client. If a saved session expires
or is revoked, Roomote asks you to approve access again in the browser.
Access tokens last one hour. Clients that request refresh tokens can refresh
access within a 30-day session; rotating a refresh token does not extend that
session. The client registration is separate: each successful authorization
code exchange or token refresh keeps the same client ID available for another
90 days. Token expiration or revocation does not itself delete that registration
or let a revoked token regain access.
To limit unused registrations, initial registration must be followed by a
successful authorization code exchange within one hour. After 90 days without
a successful exchange or refresh, an activated registration expires. If that
happens, remove and re-add Roomote in your MCP client to register again.
## Troubleshooting
If your client does not open a browser or complete sign-in, make sure it
supports OAuth for remote MCP servers and that you entered the exact Roomote
MCP URL. On a self-hosted deployment, confirm that the URL is reachable from
the browser and uses HTTPS.
# Sentry
Source: https://docs.roomote.dev/integrations/sentry
Bring Sentry issue and performance context into Roomote tasks.
Connect Sentry when bug investigations depend on real error, alert, or
performance context from production.
## When to use it
* Investigate an error without manually copying stack traces and issue history
* Connect production evidence to the repository work that should follow
* Answer whether an issue is widespread, recent, or tied to a specific release
## How setup works
Admins connect Sentry once from **Settings > Integrations**. Sentry's consent
screen lists four access groups, all selected by default:
* **Inspect Issues & Events** is read-only: issues, events, traces, replays,
releases, monitors, profiles, documentation, and project metadata.
* **Seer**, **Triage Issues**, and **Manage Projects & Teams** grant write
access: AI analysis runs, resolving and assigning issues, and creating or
editing projects, teams, DSNs, and uptime monitors.
Roomote does not restrict the connection beyond what you approve there. For a
read-only connection, leave only **Inspect Issues & Events** selected. You can
also disable individual tools afterwards from the integration's tool settings.
Most Sentry operations run through the `execute_sentry_tool` gateway, so
disabling that tool removes the whole catalog rather than a single operation.
## What to expect
Sentry gives Roomote incident and performance context during a task. It can also
support scheduled Sentry triage. The final decision, code change, and review
still happen in the normal task and repository flow.
Roomote agents are instructed to treat Sentry as read-only unless a request
explicitly asks them to change Sentry state. That instruction is not enforced
by Roomote; the access you approve on Sentry's consent screen is the boundary.
## Scope a triage request
Name the Sentry organization, projects or workloads, time window, and relevant
environments. For example: "Triage checkout errors in the storefront project
in our Sentry organization over the last 24 hours, production only."
Roomote discovers accessible scope and asks for clarification when the target
or window is missing or ambiguous instead of assuming project names or scanning
other organizations. Include multiple organizations only when you want them
scanned, and preserve any region-specific Sentry URL in your request.
Triage scans stay read-only. Ask explicitly for follow-up work and identify the
eligible repository or environment if you want findings turned into execution;
otherwise recommendations stay in the report. Specify a report destination and
whether clean scans should stay quiet. Access or scope blockers are reported
rather than treated as a clean result.
The built-in **Triage Sentry Issues** [automation](/automations) supplies its own
schedule-derived scan window and configured project scope. Leaving its project
slugs blank selects all projects available to the configured connection; it
does not restore an implicit project list for ad hoc or custom triage requests.
Roomote still asks which organization to use if that selection is ambiguous.
## Recipes using this
* [Triage customer issues](/cookbook/support-channel)
# Snowflake
Source: https://docs.roomote.dev/integrations/snowflake
Let Roomote query and explore your Snowflake warehouse during a task.
Connect Snowflake when Roomote needs warehouse context to answer data-heavy
questions or support an investigation.
## When to use it
* Inspect schemas or tables related to a task
* Query warehouse data while debugging a product or operations issue
* Connect engineering work to the analytics warehouse your team already uses
## How setup works
Admins connect Snowflake from **Settings > Integrations** with an account
identifier, username, role, and PKCS8 PEM-encoded private key. Add the matching
public key to the Snowflake user first. Supply the private-key passphrase too
when the key is encrypted.
Generate a dedicated encrypted RSA key on a secure operator machine. Keep the
private key out of shell arguments, repositories, chat, and logs. For example,
run `umask 077`, then use `openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -aes-256-cbc -out roomote_snowflake_key.p8` and enter the passphrase interactively. Export only the public key with `openssl pkey -in roomote_snowflake_key.p8 -pubout -out roomote_snowflake_key.pub`.
The `execute_sql` tool can run any statement permitted by the configured
Snowflake role, including statements that change data or schema. Use a
dedicated least-privilege role, preferably read-only when tasks only need
warehouse context.
## Rotate from an existing credential
1. Install the new public key in Snowflake's unused `RSA_PUBLIC_KEY_2` slot and verify its fingerprint before changing Roomote.
2. Enter the encrypted PKCS8 private key and passphrase in **Settings > Integrations > Snowflake**. Leave both fields blank on later edits to keep the stored key.
3. Run a Roomote task that calls `list_databases`, `list_schemas`, and `execute_sql` with `SELECT CURRENT_USER(), CURRENT_ROLE(), CURRENT_WAREHOUSE()`. Confirm the configured role can read only the intended data.
4. Review Roomote and Snowflake login logs for a successful JWT login without credential material. A saved connection is not proof that Snowflake accepted it.
5. After an observation window, revoke the previous public-key slot and verify a fresh Roomote task still connects.
## What to expect
Snowflake provides shared data warehouse context inside Roomote tasks.
Engineering changes and approvals still happen through your normal task and
repository review flow.
## Recipes using this
* [Triage customer issues](/cookbook/support-channel)
# Supabase
Source: https://docs.roomote.dev/integrations/supabase
Let Roomote inspect read-only database context from Supabase.
Connect Supabase when Roomote needs direct database context from a Supabase
project while it investigates, plans, or explains work.
## When to use it
* Inspect read-only database state during debugging
* Connect app behavior to the underlying Postgres data model
* Answer questions that depend on the current database shape or contents
## How setup works
Admins enable Supabase from **Settings > Integrations**. Each teammate then
links their own Supabase account from [Personal Settings](/personal-settings)
when they need it.
## What to expect
Supabase gives Roomote read-only database context during a task. Code changes,
migrations, and review still go through your normal engineering workflow.
## Recipes using this
* [Triage customer issues](/cookbook/support-channel)
# Supermemory
Source: https://docs.roomote.dev/integrations/supermemory
Save and recall shared memories across Roomote tasks and Fast sessions.
Connect Supermemory when your deployment needs durable context that can carry
across tasks and Fast sessions, such as team preferences, recurring
decisions, or important project conventions.
## When to use it
* Recall relevant context from earlier Roomote tasks before starting new work
* Carry durable context into Fast sessions
* Preserve explicit team preferences that should affect future tasks
* Keep durable decisions available without adding them to every prompt
## How setup works
Admins connect Supermemory once from **Settings > Integrations**.
## What to expect
Supermemory is a shared deployment memory store for Roomote tasks and Fast
sessions. When it is connected, Roomote proactively saves durable shared
context from completed tasks so future work can reuse it — team preferences,
lasting decisions, workflow conventions, and recurring gotchas — without
waiting for someone to say "remember this."
In Fast, ask Roomote to remember a durable preference, decision, correction, or
fact. Fast uses Supermemory's available writing tools, and later tasks or
conversations can recall that context. When more than one memory integration is
connected, Roomote uses one as the primary store and avoids writing the same
learning to every store.
Task status, secrets, code snippets, one-off progress notes, and anything
already encoded in the repository still do not belong in memory.
Roomote can also recall relevant memories near the start of substantive tasks
and requests and use them as additional context.
# Vercel
Source: https://docs.roomote.dev/integrations/vercel
Let Roomote inspect shared Vercel teams, projects, deployments, logs, and domain availability during a task.
Connect Vercel when Roomote needs deployment, project, or runtime context that
already lives in your Vercel workspace.
## When to use it
* Inspect projects and recent deployments while debugging a release or incident
* Pull build logs and runtime logs into a Roomote task without leaving the
thread
* Check domain availability and pricing while planning infrastructure or launch
work
## How setup works
Admins connect Vercel from **Settings > Integrations** with a shared Vercel
access token. They can also save an optional default team ID or slug so tool
calls stay scoped to the shared workspace by default.
## What to expect
The current Vercel integration is read-only. It gives Roomote deployment and
operational context during a task, but it does not replace your normal review
and approval flow for shipping or billing changes.
# Voice
Source: https://docs.roomote.dev/integrations/voice
Let your team talk to Roomote on a voice call.
Connect Voice when you want people to [talk to Roomote](/voice) on a call from
any Fast Session, on the home page, or in the New Session dialog.
## How setup works
A deployment admin connects Voice once from **Settings > Integrations** with an
OpenAI API key from a project that has GPT-Live access. We recommend a key
separate from any key used for task inference, so voice can be billed and
revoked on its own.
The setup dialog also lets the admin choose any voice supported by GPT-Live and
play a short AI-generated preview before saving. Previews use OpenAI's speech
endpoint, so a restricted key needs the **Audio** model permission
(`api.model.audio.request`) in addition to GPT-Live access; without it, calls
still work and the dialog says what the key is missing. New and previously unset
connections use Marin, one of OpenAI's recommended voices. Existing voice
selections stay unchanged.
## What to expect
Voice is a credential-only integration. Roomote uses the key on the control
plane to open GPT-Live calls and to clean up spoken transcripts; agents receive
no tools from it, and the key is not sent to task sandboxes. The browser sends
its WebRTC connection offer to Roomote and receives only the negotiated answer.
Self-hosted operators can instead set `R_VOICE_OPENAI_API_KEY`. When both are
present the environment variable is used. Roomote's general `OPENAI_API_KEY`
is never used for voice, so enabling OpenAI for task inference does not turn
voice on. An environment-managed connection is read-only in Settings and uses
Marin because it has no stored voice selection.
# X
Source: https://docs.roomote.dev/integrations/x
Let Roomote search public X posts and look up users, trends, and news during a task.
Connect X when Roomote needs public X context: what people are saying about a
launch, a thread someone pasted into Slack, an account's recent posts, or
what's trending.
## When to use it
* Pull a pasted X post or thread into task context without leaving the thread
* Search recent public posts while investigating feedback, sentiment, or an
incident
* Look up accounts, their posts, and follower context during research tasks
* Read trends, news, lists, Spaces, and community data
## How setup works
Admins connect X from **Settings > Integrations** with an app-only bearer
token from the [X Developer Console](https://console.x.com/): go to **Apps**,
open your app, then generate the Bearer Token from its **Keys and tokens**
tab. One deployment-wide connection covers every task.
What the token can read depends on your X API plan: recent post search is
broadly available, while full-archive search and some other endpoints require
higher tiers.
## What to expect
The X integration is read-only public data by design. App-only bearer tokens
cannot act as a user, so posting, bookmarks, DMs, and other account actions
are not available, and Roomote additionally restricts the tool list to
read-only operations. If a task needs an unavailable X capability, Roomote
will say so rather than attempt it.
# Zero
Source: https://docs.roomote.dev/integrations/zero
Discover and pay for external capabilities with a workspace Zero connection.
Connect Zero when agents need capabilities outside their native tools — image
generation, transcription, real-world data lookups, and other paid APIs — using
a Zero wallet connected once for the deployment.
## When to use it
* give agents a free capability search path when they hit something they cannot
do natively
* fund paid external capability calls from a workspace-connected Zero wallet
* keep wallet custody and funding on the Zero side instead of Roomote billing
## How setup works
1. An admin enables Zero from **Settings > Integrations**.
2. That admin connects Zero once for the workspace via OAuth.
When Zero is enabled for the deployment, Roomote installs the `zero` CLI for
matching tasks and activates the packaged Zero skill. Completing the org OAuth
connection lets agents authenticate through the MCP connector and run the
capability loop with shell commands.
## What to expect
* **Search is free.** Agents can discover services without spending.
* **Paid fetches use the workspace wallet.** Roomote does not front a shared
platform wallet for Zero.
* **CLI-first loop.** Preferred commands are `zero search`, `zero get`,
`zero fetch`, and `zero review`. Treat `--max-pay` as required for unfamiliar
paid calls.
* **Auth and funding helpers.** The Zero MCP connection is for authentication
and funding; the CLI owns discovery and paid calls.
## Practical tips
* Connect Zero with an account appropriate for shared agent spend, then fund the
wallet from the Zero profile page when a call needs balance.
* Ask Roomote to search Zero for a concrete capability before expecting a paid
fetch.
* Review spend and balances in Zero's own product surfaces; Roomote does not
meter Zero spend into product billing.
# Local development
Source: https://docs.roomote.dev/local-development
Set up the repository to develop on Roomote itself.
This page is for contributors who want to develop Roomote itself from a local
checkout. If you want to operate Roomote for a team, start with
[Self-hosting](/self-hosting) instead.
The full contributor walkthrough lives in the repository
[LOCAL\_DEVELOPMENT.md](https://github.com/RooCodeInc/Roomote/blob/main/LOCAL_DEVELOPMENT.md).
## Prerequisites
* **Docker Engine with Compose** — for the Postgres, Redis, and artifact
storage containers (Docker Desktop on macOS also works). x86\_64 and arm64
are both supported; on Apple Silicon the task worker builds and runs
natively, with no amd64 emulation.
* **mise** — manages the repository toolchain (Node.js, pnpm, and friends).
* **OpenCode CLI** — provides the `opencode` binary used to run tasks
(`npm install -g opencode-ai`).
* **A public HTTPS URL** — set `R_PUBLIC_URL` to a URL that reaches local port
13000\. An ngrok domain, Cloudflare Tunnel, Tailscale Funnel, or your own
domain works. Install ngrok only when you use an ngrok domain.
## Install and run
```sh theme={null}
mise install && pnpm install
printf 'R_PUBLIC_URL=https://your-public-domain.example\n' >> .env.local
pnpm dev
```
`pnpm dev` starts all services locally under PM2 supervision: it prepares
service code, resolves your public callback URL, starts Postgres, Redis, and
MinIO if needed, builds the local worker release archive, and starts the
Roomote services.
The public development edge also proxies signed artifact-storage paths to
local MinIO. Hosted compute providers such as E2B, Modal, Daytona, and Box can
therefore upload screenshots and other artifacts without direct access to your
machine's localhost ports. An explicit `S3_PRESIGN_ENDPOINT` continues to take
precedence when you use separate object storage.
`pnpm dev` requires the public HTTPS URL even when you only plan to use the
dashboard, because the development stack resolves callback and artifact URLs
during startup.
Useful process-management commands:
```sh theme={null}
pm2 status # see all running services
pm2 logs [service-name] # tail logs for one service
pnpm dev --reset # start with a database reset
```
## Validation
```sh theme={null}
pnpm lint # oxfmt check + oxlint + residual workspace ESLint
pnpm check-types # TypeScript type checking
pnpm lint:fast # oxlint + residual ESLint; matches pre-push lint
pnpm check-types:fast # Matches the pre-push hook's typecheck step
pnpm knip # Also part of the pre-push hook
pnpm test # Vitest across all workspaces
pnpm check # lint + check-types + test + knip
```
## When to use self-hosting instead
Use [Self-hosting](/self-hosting) when you want a stable deployment for a team,
want published images instead of a local checkout, or do not plan to edit
Roomote code. Local development is intentionally more moving parts because it
runs the development services, queues, workers, and callback plumbing from
source.
# Memory
Source: https://docs.roomote.dev/memory
Give Roomote shared memory, so agents start each task knowing what your team already decided, shipped, and discussed.
Memory is Roomote's shared memory. Without it, every Roomote task starts
from zero: it reads the repository, works out the conventions again, and has no
idea that the same question was answered three weeks ago. With it, agents can
recall what your deployment already knows, with citations back to the source.
Memory is deployment-wide by design. There is no per-user corpus and no
per-task corpus: one deployment, one memory, shared by everyone who can run a
Roomote task.
## What goes into it
Roomote fills Memory from what it can already see:
* **completed Roomote tasks**, including a short memory the agent writes about
its own work: what it decided, why, and what is still open. When a pull
request the task opened later merges or closes unmerged, the task's memory is
refreshed with that outcome, so recall can tell work that shipped from work
that was abandoned
* **pull requests** from your connected source-control provider
* **public Slack channels** the Roomote bot has been added to
* **public Discord server channels and active public threads** the Roomote bot
can read
* **GitHub issues** in connected repositories
* **Notion pages** explicitly shared with the deployment's Notion integration
including readable database property values such as status, dates, people,
labels, relations, and formula or rollup results
* **meeting notes** from Granola, when that integration is connected
* **employee directory and reporting structure** from Rippling, when that
integration is connected; HRIS reporting and membership fields remain
explicitly authoritative rather than being mixed with inferred collaboration
signals
* **people identities**, projected from Roomote accounts, linked provider
handles, and the human members in connected Slack workspace directories;
Slack display names, real names, and job titles help agents connect people
across sources even when they do not have Roomote accounts. When the Notion
integration can list workspace users, verified Notion email addresses link
those identities to matching Roomote members; users without a visible,
verified email remain separate identities rather than being matched by name
Pull-request memories retain the context agents need to answer more than whether
a change merged. Pages include the PR description and labels, the files and
leading code areas it changed, available line totals, and review outcomes. That
lets searches connect a decision to why it was made, which part of the codebase
it affected, and who reviewed it. Descriptions are bounded and treated as
source evidence rather than agent instructions; large file lists are summarized
with a count and truncation marker so the page stays useful without becoming
unbounded.
Descriptions and labels come from the normal provider sync. File and review
details require additional provider requests, so Roomote enriches a bounded set
of pull requests during each hourly analytics pass, prioritizing merged work.
Older pages gain this context progressively as the sync reaches them.
Turning Memory on also backfills history rather than starting from the
moment you enabled it. Completed tasks are enqueued immediately, and each
source drains its own deeper history in bounded background passes that resume
after an interruption.
Private Slack channels and DMs are never read. Adding the Roomote bot to a
public channel is what designates that channel as a source, so the corpus stays
inside what your team has already made visible company-wide. Slack directory
cards contain names, handles, and job titles, but never copy profile email,
status, timezone, or avatar fields into Memory.
Discord collection follows the server's permission model: Roomote includes only
channels visible to the server's `@everyone` role where the bot also has **View
Channel** and **Read Message History**. Private channels, private threads, group
DMs, and direct messages are never collected. Active public threads and forum
posts inherit the visibility of their public parent channel. Roomote re-reads a
bounded recent window so edits and deletions are reflected, and removes stored
pages when an authoritative permission scan shows that a channel is no longer
publicly accessible.
Notion only returns pages explicitly shared with its integration. Workspace
guests and restricted users may omit email addresses, and some integration
configurations cannot list users at all. Roomote still keeps stable Notion user
references in page snapshots in those cases, but it does not guess a match from
the display name. The workspace user directory is refreshed once a day; people
removed from the workspace (or hidden when the integration loses its
user-listing capability) have their Notion identity cards marked deleted on
the next refresh. Notion may truncate long multi-value database properties;
Memory marks those partial values and links back to the source page for the
complete list.
## Turning it on
Memory runs as its own service alongside Roomote, reachable only on your
deployment's internal network. On the hosted templates (Railway, Render,
Coolify) that service is already there after a deploy, sitting idle.
New Roomote Cloud deployments enable Memory when initial setup completes.
Existing deployments keep their current setting. Administrators can change it
with the **Enable Memory** toggle at the top of **Settings → Memory**; no
provider key is required. Synthesis runs through your deployment's helper model
— the same small model that already writes task titles and summaries.
Deployments that enabled Memory before the toggle existed, by setting
`R_BRAIN_OPENROUTER_API_KEY` or `R_BRAIN_OPENAI_API_KEY`, stay enabled without
doing anything; using the toggle stores an explicit choice that wins over the
key from then on.
Semantic recall still needs embeddings. Those come from an OpenRouter or
OpenAI key — a Memory-specific `R_BRAIN_*` key to bill Memory separately, or
the deployment's general provider key once Memory is enabled — or from a
self-run embeddings upstream (below). The Memory service holds no provider
key of its own: it asks Roomote for embeddings and synthesis, and Roomote
forwards them. Changing a key later takes effect on Memory's next request,
with no redeploy.
OpenRouter and OpenAI both support Memory's embedding calls.
### Run embeddings locally
Self-hosted Compose deployments can keep embeddings on their own hardware
while continuing to send chat synthesis to the configured Memory provider.
Enable both services and point Memory at the bundled inference server:
```sh theme={null}
COMPOSE_PROFILES=brain,local-inference
R_BRAIN_EMBEDDINGS_UPSTREAM_URL=http://infinity:7997
R_BRAIN_EMBEDDING_MODEL=BAAI/bge-m3
R_BRAIN_EMBEDDING_DIMENSIONS=1024
```
The bundled CPU service uses multilingual models so recall can cross languages.
Its anonymous usage reporting is disabled by default in the Roomote Compose
bundle. This is separate from Roomote's own optional anonymous analytics.
For a smaller CPU host, `Alibaba-NLP/gte-multilingual-base` with `768`
dimensions is a lighter embedding alternative. Choose the embedding model and
dimensions before Memory's first boot; changing that pair later requires
re-embedding the corpus.
The upstream URL can instead target any OpenAI-compatible embedding server.
Set `R_BRAIN_INFERENCE_UPSTREAM_API_KEY` when that server requires a bearer
key. Roomote forwards model names unchanged to self-run upstreams, so
`R_BRAIN_EMBEDDING_MODEL` must exactly match a model that server exposes,
without a provider prefix.
While Memory is disabled, it stays inert. Agents are not told it exists,
and nothing is ingested.
Roomote schedules one maintenance pass each night. It retrieves a bounded,
source-balanced evidence set from gbrain, produces a cited digest of material
effective-dated since the previous successful pass, then stores it under
`daily/digests/` in both the searchable index and the persistent Markdown
corpus. The digest
focuses on concrete decisions, shipped work, blockers, commitments, and
cross-source connections rather than generating a reflection for every raw
page. Each page records how many Slack, task, GitHub, and Notion or meeting
pages were considered and cited, so missing source coverage is visible.
Beginning Tuesday, the same pass also updates
`weekly/summaries/-W`. That bounded synthesis connects durable
decisions, unresolved blockers, commitments, and recurring or superseded
information across the week's available daily digests. Roomote reads those
digest pages by their exact slugs and supplies their content as the complete
evidence set, so raw or historical Memory pages cannot enter the weekly pass.
The daily cutoff trails active ingestion and overlaps the previous pass so
collector writes around the nightly boundary are reconsidered. gbrain's
durable worker still owns structural maintenance such as link extraction,
fact consolidation, embedding catch-up, orphan checks, and purging. Roomote
does not run gbrain's prediction-proposal and calibration queue unattended;
that upstream feature requires an operator review workflow before proposals
become canonical memory.
Self-hosted Compose deployments start Memory from the `brain` profile, so
add `brain` to `COMPOSE_PROFILES` in your environment file to bring the
container up, then enable Memory in Settings. Production installs pull
`ghcr.io/roocodeinc/roomote-gbrain` with the same `v*` release tag as Roomote;
a complete custom image reference can be pinned with `GBRAIN_IMAGE`.
Everything after that is the same.
## Seeing what it knows
**Settings → Memory** is the deployment-wide view of the memory, for admins.
**Memory issues** appears first only when completed tasks are missing memories or
memory writes exhausted their retries. Its repair actions queue missing memories
and retry failed writes without bringing back the removed task-memory stats.
**Memory Stats** breaks the corpus down by what each page came from, such as task
memories, pull requests, Slack, meetings, and people, followed by a chart of the
pages written over the last 30 days and the memories written most recently.
**Browser memories** embeds the corpus page by page, searchable and filterable by
source. Selecting a new memory opens it in the browser and updates the page URL
without adding browser history.
**Status** reports whether recall is semantic or keyword-only and which provider
is serving its embeddings and synthesis. Memory that is running but has no
provider key is called out as needing attention rather than shown as healthy:
without one it can only match keywords, so recall would look real while missing
everything semantic.
**Sources** shows connected sources with their current collection state, when
they were last read, and how far their one-time history sweep has got. Sources
without a connected upstream integration are omitted.
**Configuration** appears last and shows the synthesis model (changeable through
`R_BRAIN_MODEL`, applied immediately) and the embedding model, which is fixed
when Memory is created because it sizes the vector store.
## How agents use it
Agents get the built-in Memory as an MCP server with read-only tools. They can
search it, recall relevant pages, browse what exists, and ask for a synthesized
answer with sources. They cannot write to the built-in Memory directly.
For a substantive topic, agents query Memory before consulting overlapping
Slack, GitHub, task-history, meeting, or pull-request sources. They check those
live sources when Memory coverage is insufficient, freshness could change the
answer, or you explicitly ask for live verification.
Writes go through Roomote instead. When an agent finishes substantial work it
records a short memory of what it did, and the platform places that text under
a slug it controls, after scrubbing credential-shaped strings. An agent can
therefore contribute what only it knows without being able to touch any other
page.
Fast sessions use the same pipeline. Ask Fast to remember something — or
state a durable preference, decision, or correction — and it saves the fact to
the session's own memory entry, which the platform redacts and files just
like a task memory. Saved facts become searchable after the next ingestion
pass, so they surface in later sessions rather than instantly.
Additional memory integrations, such as Supermemory, can also provide shared
context to tasks and Fast sessions. Roomote chooses one connected memory
store for the initial recall so multiple stores do not repeat the same preflight.
Agents can still consult another store when it has distinct context or you ask
for it by name. Each integration uses its own available memory-writing tools;
Roomote does not duplicate the same learning across stores.
Memories carry the environment they came from, so a page written while working
in staging is distinguishable from one written against production.
## Choosing models
Two settings pick Memory's models:
| Variable | What it does | Written as | Changeable |
| ------------------------- | ----------------- | ---------------------- | --------------------- |
| `R_BRAIN_MODEL` | Sourced synthesis | your provider's naming | any time |
| `R_BRAIN_EMBEDDING_MODEL` | Semantic recall | a plain model id | before the first boot |
Leave them unset and Memory uses OpenAI's `gpt-5.6-luna` and
`text-embedding-3-small` through whichever provider you configured.
Memory search does not use a cross-encoder reranker: retrieval is hybrid
(vector + keyword fusion), which keeps search latency flat and provider
requirements minimal.
The synthesis model is applied by Roomote when it forwards the call and passed
to the provider as written, so use that provider's naming
(`openai/gpt-5.6-mini` on OpenRouter, `gpt-5.6-mini` on OpenAI). Changing
it takes effect on the next request with nothing to restart.
The embedding model works differently, and the difference matters. Its
output width sizes Memory's vector storage when Memory is first
created, and that cannot be resized in place afterwards. So it is given to
Memory at creation rather than applied per request, written as a plain
model id (`text-embedding-3-large`) that Roomote translates for whichever
provider is serving. Set it together with `R_BRAIN_EMBEDDING_DIMENSIONS`
(1536 for `text-embedding-3-small`, 3072 for `text-embedding-3-large`)
before Memory's first boot, or leave both alone.
Changing it later is not silently applied: Memory keeps its original
model and width, and reports the mismatch in its logs on every start.
Moving existing Memory to a different embedding model means re-embedding
the whole corpus with `gbrain migrate embeddings`.
## If you turned Memory on later
Memory that first boots without a provider key is created with semantic
recall switched off, because the embedding model sizes its vector storage at
creation time. Adding a key later is still fine: Memory notices on its next
start, enables semantic recall, and embeds whatever it already holds. It logs
`semantic recall enabled` when it does.
That repair runs once and is safe, since Memory in this state has no
embeddings to lose and its pages are preserved. If it cannot complete, the
service logs the commands to run by hand and keeps serving in the meantime,
matching on keywords alone.
## Operating it
* **Back up both Memory stores together.** The Railway template schedules
backups for the Memory volume. On supported self-hosted installs, `roomote
backup` includes both the `gbrain_data` volume and the isolated `gbrain`
database when Memory is enabled. The volume holds the Markdown system of
record; Postgres holds the searchable index, extracted facts, and durable
maintenance jobs. Restoring only one can leave the storage layout and index
inconsistent, so keep them at the same backup consistency point.
* **Losing Memory is recoverable only from connected sources.** If both stores
are recreated, Roomote can reset ingestion checkpoints and backfill task
history and connected integrations, but user-saved facts and generated
synthesis may not be reproducible. The deployment starts cold until the
backfill finishes.
* **The filesystem cutover rebuilds older memory once.** The first start of a
filesystem-backed image replaces a Postgres-only Memory service instead of
trying to merge the old index into an empty checkout. Roomote then repopulates
it from its connected sources.
* **Memory has no public service route.** It is never exposed to the internet,
and task sandboxes reach it only through Roomote's API with their run token,
which grants read access only.
* **To run with no memory at all**, leave Memory disabled in Settings.
Deployments that want to reclaim the resources entirely can delete the
Memory service from their compose file or template.
# Inference Overview
Source: https://docs.roomote.dev/models
Choose inference providers, enable task models, and tune model roles for different kinds of Roomote work.
Models decide how Roomote thinks through a task.
The sandbox provider gives a Roomote agent a sandbox to work in. The inference
provider gives it access to the model that reads the prompt, reasons about the
workspace, writes code, runs tools, reviews output, and explains what changed.
Configure models from **Settings > Models**.
## Inference providers
An inference provider is the service that hosts or routes model calls. Roomote
supports direct model APIs, multi-provider gateways, coding subscriptions, and
self-hosted OpenAI-compatible endpoints.
You can connect more than one inference provider in the same deployment. That
lets you mix and match models by provider instead of betting the whole
deployment on one account, one vendor, or one model family.
### Managed Roomote inference
Some hosting deployments provision **Roomote inference** with a limited,
spend-capped credit grant during setup. It is separate from your own provider
connections: in particular, you can add an OpenRouter key in **Settings >
Models** even when Roomote inference is active. If the hosting deployment does
not offer it, the option is not shown. The Roomote Cloud trial includes \$5 of
inference, enough to complete several tasks before you connect your own
provider. Trial token usage and estimated model cost appear in task details and
[Cost Analytics](/cost-analytics), while the remaining credit line reflects the
hosted grant's authoritative limit. Its key is stored with your other provider
credentials, so deleting the Roomote inference provider in **Settings > Models**
disables it permanently.
For example, a deployment might use:
* an OpenRouter-routed model for the default coding model
* a direct Anthropic or OpenAI model for planning or review
* a lower-cost provider model for helper work
* a vision-capable model only when visual inspection is needed
Connecting an API-key provider that has no configured models yet automatically
adds a short list of recommended models for it — enabled and including the
provider's default model — so you land on a usable model list right away, both
in the setup wizard and from **Settings > Models**. You stay in control: you
can disable or remove any of the added models, add more later, and reconnecting
a provider never re-adds models you removed.
When you connect or update an API-key provider, Roomote first checks the
submitted credentials with a small live model request. If the provider rejects
the key, or the account has no remaining credits, nothing is saved: fix the
credential and save again. Other failures (a rate limit, a model your account
cannot access, or a transient provider outage) never block the save.
Self-hosted OpenAI-compatible endpoint connections are checked by listing the
endpoint's models instead. Saving again without changing any credential skips
the live check.
### API and gateway providers
These connections use metered API billing or a provider-managed gateway:
| Provider | Credential | Cost source |
| -------------------------------------------------------------------------------------------------------- | ------------------------------------------- | -------------------------------- |
| [Amazon Bedrock](/providers/inference/amazon-bedrock) | Mantle API key and optional AWS region | AWS account |
| [Anthropic](/providers/inference/anthropic) | Anthropic API key | Anthropic API organization |
| [Azure AI Foundry](/providers/inference/azure-foundry) | Azure AI Services API key and resource name | Azure subscription |
| [Azure OpenAI](/providers/inference/azure-openai) | Azure OpenAI API key and resource name | Azure subscription |
| [Baseten](/providers/inference/baseten) | Baseten API key | Baseten workspace |
| [Google Gemini](/providers/inference/google-gemini) | Google AI Studio key | Google Cloud project |
| [MiniMax](/providers/inference/minimax) | MiniMax API key | MiniMax account |
| [Moonshot AI (Kimi)](/providers/inference/moonshot-ai) | Kimi Open Platform key | Moonshot Open Platform balance |
| [OpenAI](/providers/inference/openai) | OpenAI API key | OpenAI API project |
| | OpenCode API key | OpenCode account |
| [OpenRouter](/providers/inference/openrouter) | OpenRouter API key | OpenRouter balance and key limit |
| [Requesty](/providers/inference/requesty) | Requesty API key | Requesty organization |
| [Together AI](/providers/inference/together-ai) | Together AI API key | Together AI account |
| | AI Gateway API key | Vercel team |
| [xAI](/providers/inference/xai) | xAI API key | xAI API team |
| [Z.AI](/providers/inference/zai) | Regional Z.AI platform key | Z.AI or BigModel API balance |
### Subscription providers
Subscription connections consume an included plan allowance instead of a
general API balance:
| Provider | Connection | Usage behavior |
| --------------------------------------------------------------------------------------------------------- | --------------------------- | -------------------------------------- |
| [ChatGPT Subscription](/providers/inference/chatgpt) | OpenAI device authorization | ChatGPT plan windows |
| | GitHub device authorization | Copilot plan allowance |
| [Kimi for Coding](/providers/inference/kimi-for-coding) | Kimi membership key | Coding membership allowance |
| [OpenCode Go](/providers/inference/opencode-go) | OpenCode API key | Go plan allowance |
| [xAI Grok Subscription](/providers/inference/xai-subscription) | xAI account authorization | SuperGrok or eligible X plan allowance |
| [Z.AI Coding Plan](/providers/inference/zai-coding-plan) | Regional Coding Plan key | Coding Plan quota windows |
Roomote shows plan usage for subscription providers when the provider returns
usable quota data. These usage endpoints are not always documented or stable,
so a missing usage line does not by itself mean the connection is broken.
### Self-hosted and gateway providers
OpenAI-compatible endpoints let you bring any server that speaks the OpenAI
`/v1` API — including LiteLLM, Ollama, vLLM, and custom proxies. Models are
discovered from the configured endpoint instead of Roomote's recommended
catalog. Connect the provider in **Settings > Models**, then select from the
discovered models and choose the defaults and role mappings that fit your
deployment.
| Provider | Best for | Setup |
| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | --------------------------------------------------- |
| [LiteLLM](/providers/inference/litellm) | A single gateway that routes to one or more model vendors | Endpoint URL and required API key |
| [Ollama](/providers/inference/ollama) | Local or private model serving without provider API keys | Endpoint URL |
| [OpenAI-compatible](/providers/inference/openai-compatible) | Any OpenAI API endpoint (LiteLLM, vLLM, custom proxies, local servers); multiple named connections supported | Connection name, endpoint URL, and optional API key |
| [vLLM](/providers/inference/vllm) | Serving OpenAI-compatible models on your own GPU infrastructure | Endpoint URL and optional API key |
These endpoints must be reachable from the Roomote deployment, not merely from
your laptop or an individual task sandbox. See the provider page for the
expected URL, network, security, and cost behavior.
The recommended set is a single curated list of models that ships with each
Roomote release, so it is predictable for a given version. Every catalog-backed
provider draws from the same list: a provider offers the subset it serves, under
its own model ids, with the same names everywhere. Endpoint providers that
discover models dynamically use the model list returned by their endpoint.
**Available Models** always lists the full recommended set for every connected
catalog-backed provider: recommendations you have not enabled appear toggled
off, and they cannot be deleted while their provider stays connected — turn a
model off to stop using it. To go beyond the recommended set, add any model by
its slug from the add-model field.
**GPT-6 Astra** is also recommended through [Vercel AI Gateway](/providers/inference/vercel-ai-gateway),
[GitHub Copilot](/providers/inference/github-copilot), and
[OpenCode Zen](/providers/inference/opencode). Connect the provider, enable Astra
in **Available Models**, and assign it to a role or select it for a Session or
task. Adding these routes does not change existing model defaults; access still
depends on the connected provider account or plan.
**DeepSeek V4.1 Flash** is recommended through
[OpenRouter](/providers/inference/openrouter),
[Vercel AI Gateway](/providers/inference/vercel-ai-gateway), and
[OpenCode Go](/providers/inference/opencode-go). Roomote uses the provider's
matching route and no longer recommends the older V4 Flash 0731 model. Existing
defaults do not change automatically; enable V4.1 Flash and assign it to a role
when you want to use it.
### Recommended default models
Providers also carry recommended defaults for the model roles below — for
example a strong model for planning and code review and a fast, low-cost model
for helper and explore work. Connecting a provider in the setup wizard applies
its recommended defaults automatically, so a fresh deployment starts with a
sensible split instead of one model for everything.
From **Settings > Models**, use **Use a mapping preset** on the **Model
mapping** card to preview and apply a connected provider's recommended model
mapping. Confirm the preset to set the role selections and enable any missing
recommended models. It is an apply-once action, not a lock: you can adjust
every role afterward. Roles a provider has no specific recommendation for are
set to **Same as coding model**, and roles managed by environment variables are
left untouched.
## Env-based setup
Most deployments should configure providers from **Settings > Models**. Use
environment variables when provider credentials are managed by your hosting
platform, secret manager, or local development shell.
At minimum, set a default coding model and the matching provider key:
```sh theme={null}
R_MODEL=openrouter/anthropic/claude-sonnet-5
OPENROUTER_API_KEY=...
```
The provider is the first segment of the model ID. Direct-provider access uses
the provider's normal key:
```sh theme={null}
R_MODEL=anthropic/claude-sonnet-5
ANTHROPIC_API_KEY=...
```
You can also split model roles with env vars:
```sh theme={null}
R_ORCHESTRATION_MODEL=openrouter/google/gemini-3.8-flash
R_ORCHESTRATION_MODEL_REASONING_EFFORT=low
R_SMALL_MODEL=openrouter/openai/gpt-4.1-mini
R_VISION_MODEL=openrouter/openai/gpt-5.6-sol
R_CODE_REVIEW_MODEL=openrouter/openai/gpt-5.6-sol
R_EXPLORE_MODEL=openrouter/openai/gpt-5.6-luna
```
Roomote automatically makes common provider configuration available to the
model runtime, including OpenRouter, Requesty, Vercel AI Gateway, OpenAI, Azure
OpenAI, Azure AI Foundry, Anthropic, Google Gemini, Moonshot, Kimi for Coding,
MiniMax, Z.AI, OpenCode, Amazon Bedrock, xAI, and GitHub Copilot. For
gateway-supported providers, credentials stay on the control plane and model
requests are proxied instead of forwarding the credentials into task workers.
Use `R_MODEL_ENV_KEYS` when a provider key uses a custom env var name and must be
forwarded:
```sh theme={null}
R_MODEL_ENV_KEYS=CUSTOM_PROVIDER_API_KEY
CUSTOM_PROVIDER_API_KEY=...
```
See [Environment Variables](/environment-variables) for the full supported key
list.
## What Models settings controls
**Settings > Models** has two layers:
* **Inference Providers** stores the provider credentials Roomote can use.
* **Models** controls the provider/model pairs that are available, the default
model, and specialized model roles.
When you connect an inference provider in setup, Roomote tests the candidate
credentials and selected model before saving them. Authentication, quota,
model-access, endpoint, and timeout failures are reported during setup so you
can correct the connection before starting a task. Providers configured through
environment variables are validated by the deployment at startup instead.
For subscription-based providers (ChatGPT, GitHub Copilot, Kimi for Coding,
xAI Grok / SuperGrok, and Z.AI Coding Plan), the provider row also shows current
plan usage when the provider reports it, such as remaining legacy Copilot
premium-request quota, the percent used of the ChatGPT 5-hour and weekly
limits, or Grok included-usage windows.
These numbers come from unofficial provider endpoints, so the usage line is
hidden whenever the provider does not return usable data.
Under **Settings > Automations > Inference Provider Usage Alerts**, admins can
configure hourly checks for queryable limits from ChatGPT subscription, GitHub
Copilot, xAI Grok subscription, OpenRouter, Kimi for Coding, OpenCode Go, Z.AI,
and Z.AI Coding Plan. Roomote posts one warning when a credential crosses its
configured threshold in a limit window, plus a critical warning at 100%. Alerts
can report through Slack or Discord destinations and supported primary
conversations in Teams, Telegram, or Discord. The warning names the provider,
credential fingerprint or label, limit window, and reported usage. A provider
that does not return usable quota data is skipped.
xAI can be connected with an API key, a SuperGrok or eligible X Premium+
subscription, or both. When both are configured, the subscription is preferred
at runtime for `xai/` models.
Admins can enable or disable models from the task model list. The default model
must stay enabled, because Roomote uses it when a task does not request a
specific model.
Model settings affect new task starts. Running tasks and resumed snapshots keep
the model that was selected when they started.
## Model roles
Roomote can use different models for different parts of the system. You can
leave these roles on the default model at first, then split them when you know
where you want more speed, quality, or cost control.
| Role | What it is for | Optimize for |
| -------------------- | ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| Default coding model | Normal Roomote tasks: code changes, debugging, tests, repo investigation, and follow-ups | Strong tool use, coding quality, long-context reliability, and good instruction following |
| Orchestration model | Fast answers and coordination of delegated task launches | Low latency, conversational quality, and reliable tool routing |
| Helper model | Lightweight routing, titles, summaries, and quick internal decisions | Low latency, low cost, and enough accuracy for short judgments |
| Vision model | Visual inspection, screenshots, UI review, and image-heavy work | Image understanding, layout reasoning, and concise visual feedback |
| Code review model | Initial PR or MR review tasks and review-sync work | Careful reasoning, bug finding, security awareness, and willingness to cite evidence |
| Explore model | Repository search and focused codebase exploration | Fast tool use, low latency, and reliable source-grounded investigation |
| Advisor model | Planning turns and advisor consultations inside longer coding tasks | Deliberate reasoning, decomposition, and ability to keep constraints in mind |
You do not need a separate model for every role. Set a specialized role to
**Same as coding model** to inherit the default. Many teams start with one
strong default model, then split out a faster orchestration or helper model, or
a stronger review model, after they can see real usage.
## Reasoning settings
Some models expose reasoning controls. Roomote lets admins set reasoning levels
for the main model roles: **Low**, **Medium**, **High**, **Extra high**, or
**Max**.
Higher reasoning can improve planning, debugging, and review quality, but it
can also increase latency and cost. Use it where deeper thinking changes the
outcome, not everywhere by default.
A practical starting point:
* use **Medium** for the default coding model
* use **Low** for orchestration, helper, vision, and explore work unless you see quality issues
* use **High** for code review and advisor work when you want more careful
analysis
* reserve **Extra high** or **Max** for models and workflows where the added
cost is justified
If a model does not support reasoning controls, Roomote hides or ignores the
reasoning selector for that role.
## Per-task model switching
Deployment settings define the defaults, but each task can override them from
the web task view. The model chip in the message composer shows the task's
current coding model and reasoning level; open it to switch the coding model,
or expand **All roles** to override the planning, code review, explore,
helper, or vision role for that task only.
Changes apply from the next message: a turn that is already running finishes
on the old settings, and the next turn (including its sub-agents) uses the new
ones. Overrides persist for the life of the task, including snapshot resumes,
and **Reset to defaults** returns every role to the deployment configuration.
You can also just ask the agent — for example "switch to Fable 5 with max
reasoning for the rest of this task". The agent applies the same change
through its task-management tool, subject to the same allowed-models list.
Viewing a custom automation's Session does not grant control over its task
model. Only the automation's creator or a deployment administrator can change
model selection for those tasks.
Conversational Sessions expose the same model and reasoning choices in their
composer. New Sessions show the deployment's orchestration model by default;
direct environment and repository tasks show the coding model. Leaving the
Session selection untouched keeps deployment-default behavior, while an
explicit selection is saved before the next message can be sent, persists
across page refreshes, and applies to later Fast turns without changing a turn
that is already running.
## Fast delegation and consultation
Fast mode sees the exact coding models enabled for delegated tasks. When it
launches repository work, it can choose one of those models for that task or
omit the choice to use the deployment default. An unavailable model is rejected
before launch, so Fast can correct the selection without consuming its launch
attempt. The chosen model applies to the delegated task just as if it had been
selected when starting a task from the web app.
For a structured pull request review, Fast can likewise choose an enabled model
and a supported reasoning effort for the review task. Ask for those choices when
the review needs a particular balance of speed and depth; omitted choices use
the deployment's code review defaults.
A single Fast turn can launch multiple independent tasks, so one request can
delegate separate workstreams without waiting for each task to finish first.
Fast still posts a kickoff for every task and keeps repeated identical launch
requests from creating duplicate work.
Fast can also consult the advisor and judge roles for focused planning or
completion checks without launching a workspace-backed task. These consultations
can read deployment integrations and task status for context, but they cannot
inspect a repository workspace, post to chat, or launch, message, or cancel
tasks. Fast remains responsible for the user-facing answer and any execution it
delegates.
OpenCode allows two levels of subagents: the main agent can delegate to a
subagent, which can make one further nested delegation or consultation. This
does not permit unbounded recursion or expand a role's permissions. Fast
consultants still cannot inspect a repository workspace or control tasks;
Fast owns any workspace-backed execution.
## Choosing models
Start by choosing for reliability, then optimize for cost and speed once tasks
are working.
For the default coding model, prioritize:
* strong coding and debugging performance
* reliable tool use across long multi-step tasks
* enough context window for your repositories and logs
* predictable behavior with your preferred inference provider
For helper work, prioritize:
* fast responses
* low cost
* acceptable accuracy on short routing and summarization prompts
For vision work, prioritize:
* support for image inputs
* layout and screenshot understanding
* clear descriptions of what changed or what looks wrong
For code review, prioritize:
* careful reasoning over speed
* good false-positive control
* attention to tests, regressions, security, and edge cases
For advisor work, prioritize:
* structured reasoning
* ability to break work into practical steps
* consistency with your deployment-wide and environment-specific guidance
## Mixing providers
Mixing providers is normal. It can help when:
* one provider has better pricing for a model you use heavily
* another provider has better availability or rate limits
* you want direct-provider access for one model and gateway routing for another
* you are comparing model families before changing the default
* a specialized model, such as a vision model, only exists behind one provider
The main tradeoff is operational complexity. Each provider adds credentials,
account limits, billing, and possible regional or data-handling requirements.
Keep the enabled list focused enough that teammates can understand which models
to pick.
## Keep model metadata fresh
Model context windows, output limits, supported input types, reasoning support,
and pricing can change. **Settings > Models** can refresh model metadata so the
admin UI has current information for enabled and custom models.
Refresh metadata after adding custom models, changing providers, or upgrading a
deployment. It helps admins compare models without relying on stale defaults.
## Common issues
* **No models are available.** Connect at least one inference provider and
enable at least one model.
* **A model cannot be selected.** Confirm its provider is connected and that
the model is enabled in **Settings > Models**.
* **Tasks are expensive or slow.** Move helper work to a cheaper model, lower
reasoning where quality allows, or choose a faster default model.
* **A vision task cannot inspect images.** Use a model with image input support
for the vision role.
* **A model works from one provider but not another.** Check provider-specific
credentials, rate limits, model availability, and model ID prefix.
# Personal Settings
Source: https://docs.roomote.dev/personal-settings
Manage your profile, linked accounts, theme, and personal app preferences.
Personal Settings are for the Roomote preferences and accounts that belong to
you, not the whole deployment.
Admins use the other settings pages to connect tools and configure shared
behavior. Individual teammates use Personal Settings to link their own
identities, adjust the app, and manage profile details.
## Open your profile
Use **Profile** to update account details such as your name, email,
avatar, and security settings.
These settings affect your own Roomote account. They do not change deployment
membership, environment access, or integration setup for the rest of the team.
### Set a password
If you signed in through a communications or source-control provider, you can
select **Set password** to add email-and-password sign-in to the same Roomote
account. After setting a password, you can update it from Personal Settings.
## Link your accounts
Use **Linked Accounts** to connect your personal identity for tools your
deployment has enabled.
You may see rows for:
* your source-control provider
* your communications provider
* Linear
* user-linked integrations such as docs, issue trackers, databases, or
analytics tools
If an integration is not listed, it usually means an admin has not enabled it
for the deployment yet, or the integration does not require personal linking.
## Why personal linking matters
Personal linked accounts help Roomote act with the right context. Depending on
the integration, linking can help Roomote:
* associate your chat, source-control, or Linear identity with the Roomote
task
* use your user-scoped connection for tools that require individual
authorization
* route follow-up activity back to the right person or thread
Deployment-level setup and personal linking are different. An admin may enable
an integration once, and then each teammate links their own account only when
they need to use it.
## Adjust the app
Personal Settings also include app preferences such as:
* **Color Theme** for light, dark, or system-defined appearance
* **Mind Reader Mode** to expand LLM thoughts by default in task conversations;
you can still collapse or expand individual thought messages
* **Narration Mode** for a more streamlined task conversation view
* **Therapist Mode** to explain which remembered fact informed a Session or task
* **How to work with me** for private personal instructions and conversational
learning
Most teammates only need profile, linked accounts, and theme settings.
### Understand Therapist Mode
Therapist Mode is an opt-in disclosure setting. When a specific fact returned
by [Memory](/memory) materially informs Roomote's answer or work, Roomote names
that remembered fact in human terms and explains how it was used. It does not
narrate unrelated retrievals or expose internal memory identifiers, storage
paths, metadata, or provenance fields.
## Personalize how Roomote works with you
Use **How to work with me** for durable preferences such as your preferred
name, language, formality, answer length, use of examples, directness, update
frequency, or accessibility and presentation preferences you choose to share.
These instructions apply to conversations with you; they do not silently
rewrite code or customer-facing deliverables.
**Learn from conversations** is on by default. Roomote may save a preference
you state explicitly and may form modest, revisable style preferences from
repeated behavior. Turning learning off stops new automatic updates but keeps
the instructions already shown in the text box active. **Reset** clears both
edited and learned instructions. A reset does not rebuild them from older
conversation history.
Fast captures each participant's personalization when they first speak in a
conversation and keeps that private snapshot for their later turns in the same
conversation. New preferences stated in a message still guide that request and
are saved for future conversations, but they do not rewrite the current
conversation's snapshot. Edits and resets in Personal Settings likewise apply
to new conversations, or to a participant who has not spoken in the current
conversation yet.
Personalization follows the trusted account associated with the current
speaker on supported chat surfaces and with the person who requested a task.
In a shared thread, Roomote adapts its conversation to the current speaker
while preserving the original requester's task requirements when they conflict.
Personalization is encrypted at rest and is not available to other members or
admins through Roomote's normal UI or API. It is excluded from shared task
transcripts, summaries, memory, and ordinary tool output. It remains subject to
the deployment operator's infrastructure access, backups, and retention
policies. Roomote does not use public-web or LinkedIn enrichment for this
feature.
## Common issues
* **A linked account is missing.** Ask an admin to enable the integration from
**Settings > Integrations**.
* **A task uses the wrong identity.** Check that the relevant account is
linked and that you started the task from the expected chat, source-control,
or dashboard user.
* **You cannot link an account.** Try again after confirming pop-ups and
redirects are allowed for the Roomote app.
# Email (AgentMail)
Source: https://docs.roomote.dev/providers/communications/agentmail
Connect an AgentMail inbox so Roomote can receive tasks and reply over email.
Email is a deployment-owned communications provider backed by
[AgentMail](https://agentmail.to), an email API. It is not a Roomote sign-in
provider.
Roomote can receive email sent to a dedicated deployment inbox, start tasks
from those messages, and reply in the same email thread. AgentMail delivers
inbound mail through a `message.received` webhook, so Roomote must be reachable
at a stable public HTTPS URL. Each deployment brings its own AgentMail account
and API key.
## Enable the email channel
Email is off by default. Set `R_EMAIL_CHANNEL_ENABLED=true` in the
deployment's environment and restart. Until then the provider does not
appear in settings, inbound webhook deliveries are acknowledged and dropped,
and Roomote never sends email. On Roomote Cloud this is enabled per
deployment by the Roomote team.
Enabling the channel gives the deployment an email sender for the first
time, so new password sign-ups also receive a verification email (see
[Account email verification](#account-email-verification) below). Sign-in
is never blocked on verification.
## Connect an AgentMail inbox
Create an AgentMail account at [console.agentmail.to](https://console.agentmail.to),
then:
1. **Create the inbox** Roomote should receive mail at (or pick an existing
one). AgentMail's free tier includes 3 inboxes and 100 emails per day and
adds a "Sent via AgentMail" footer to outbound mail; custom domains, with
AgentMail-managed SPF/DKIM/DMARC, need a paid plan and are recommended for
production.
2. **Create an API key from inside that inbox**, so the key is scoped to it.
Give it these permissions (or full access): `inbox_read`, `inbox_update`,
`webhook_read`, `webhook_create`, `webhook_update`, `webhook_delete`,
`message_read`, and `message_send`.
3. In the Roomote UI (**Settings > Communications > Email (AgentMail)**),
paste the key and save.
Roomote uses the inbox the key is scoped to; there is nothing else to enter.
On save it validates the key, registers a webhook on the inbox for
`message.received`, `message.bounced`, and `message.complained` events, and
shows the connected address and webhook URL in settings. Missing permissions
fail at save time with an error naming the refused request, except
`message_send`, which has no side-effect-free check and is exercised on the
first reply.
An inbox-scoped key is the intended shape: it cannot read other inboxes or
create new ones, so a leaked key exposes one mailbox rather than the
account. An organization-level key is accepted only while the account has
exactly one inbox, since Roomote would otherwise have no way to tell which
inbox is for this deployment.
For self-hosted env-var configuration instead of the UI, all values are
optional overrides of the settings UI:
```sh theme={null}
# Optional — configure email entirely from settings when unset:
# R_AGENTMAIL_API_KEY=
# R_AGENTMAIL_WEBHOOK_SECRET=
# R_AGENTMAIL_INBOX_ID=
```
## Email Roomote
Send an email to the deployment inbox from an email address on your Roomote
account. The address must be verified. Roomote replies in the same email
thread, and follow-up emails in that thread continue the same conversation; a
running delegated task receives them as follow-ups. Start a new request with a
new email so it opens a new thread.
Only verified account email addresses are recognized. Mail from any other
address may receive a polite refusal explaining that it must come from the
verified email on a Roomote account; resend from that address once it is
verified. Refusals are limited to one per thread and one per sender each day,
with a deployment-wide limit of 25 per day. Forwarding a Roomote email thread
to someone else does not give them access to the original conversation or
task; their message starts a separate conversation of their own.
Roomote silently ignores auto-submitted or auto-generated messages and mail
marked as bulk, list, or junk traffic. This prevents vacation responders,
mailing lists, and similar automated senders from creating reply loops.
Email is deliberately low-frequency: expect roughly two emails per task, an
acknowledgment and the result, plus questions when the agent genuinely needs
input. Roomote does not send play-by-play progress messages over email.
When the agent asks a structured question, the question email includes a
button for each option. Clicking a button opens a one-tap confirmation
page; confirming records your answer and the agent continues. (The extra
tap exists so corporate mail link scanners cannot answer on your behalf.)
You can always answer by replying to the email instead. Multi-question
prompts are answered by reply, one answer per line.
## Roomote-initiated email
Roomote can also initiate email — for example, notifying you that a GitHub
App installation you requested was approved when you have no chat
integration linked. Strict consent rules are enforced in code:
* Roomote only initiates email to your own verified account address. It
never emails an address just because someone typed it in.
* Every Roomote-initiated email carries a one-click unsubscribe link
(RFC 8058 `List-Unsubscribe`). Unsubscribing stops Roomote from initiating
new email to that address; replies to email you send Roomote are
unaffected.
* Addresses that bounce permanently or file a spam complaint are suppressed
automatically and never emailed again.
* If you also have a chat integration linked (Slack, Teams, Telegram, or
Discord), broadcast-style notices go there instead of email — email is the
fallback reach, not another copy.
Custom automations can explicitly select **Email** as their report destination.
This is opt-in, never a fallback. The picker offers the automation owner's
account email once Roomote records it as verified. Each run uses that exact
selected identity for its initial message and threaded report. If verification or membership is
removed, the address changes, delivery is suppressed, or AgentMail is disabled
or unconfigured, Roomote records a delivery failure and does not substitute
another address or provider.
Replying to a Roomote-initiated email works like any other thread: the reply
routes back into the same conversation.
## Account email verification
Roomote only initiates email to an address it has verified. With the email
channel enabled:
* New email-and-password sign-ups receive a verification email. Confirming
it lets Roomote recognize the address on the email channel; signing in
does not wait for it, and a verification email that cannot be sent (the
AgentMail key is not configured yet, or the address is suppressed) never
blocks the account.
* Existing password accounts that never verified (sign-ups from before the
channel was enabled) verify from **Personal settings > Linked Accounts**.
* **Personal settings > Linked Accounts** shows the Email row's verification
status. When the login email is not verified and AgentMail is ready to
deliver, use **Resend** to request another verification message. A delivery
failure is shown instead of reporting success.
* Sign-ins through Slack, Microsoft, GitHub, and the other OAuth providers
are unaffected; those providers assert a verified email.
* Password reset links are emailed to the user as well as shown to the
admin who requested them.
Verification and password-reset emails carry no unsubscribe link (the user
asked for them) and are sent even to an address that unsubscribed from
Roomote notifications. Addresses that bounced or filed a spam complaint are
never emailed.
## Limitations
Current limitations:
* Email automation destinations are private; channel-style posting is not
supported
* each account has one email address for the channel, its verified login
email; there is no way to add other sender addresses
* reactions are not supported
* attachments from inbound email are not yet processed
* each deployment has one inbox
# Discord
Source: https://docs.roomote.dev/providers/communications/discord
Configure a Discord bot so Roomote can start and continue tasks in DMs, channels, threads, and forums.
Discord is a deployment-owned communications provider. It is not a Roomote
sign-in provider.
Roomote can receive direct messages and server mentions, work each task in a
thread on the message that requested it (or a forum post in forum channels),
accept follow-ups in that conversation, and deliver onboarding suggestions to
the default channel. Discord connects to Roomote through the Gateway, so it
does not require an inbound webhook or public callback URL.
## Create the Discord bot
1. Open the [Discord Developer Portal](https://discord.com/developers/applications)
and create an application.
2. Open **Bot**, create the bot if needed, and copy or reset its token.
3. Under **Privileged Gateway Intents**, enable **Message Content Intent**.
Roomote needs this to understand natural-language messages and follow-ups.
4. In Roomote, open **Settings > Communications > Discord**, paste the bot
token, and save.
Roomote reads the bot and application identity from the token and registers
the `/new`, `/goal`, `/link`, and `/help` commands automatically. You
do not need to copy an application ID or bot name into Roomote.
Treat the bot token like a password. Do not put it in a repository, task
prompt, or Discord message.
## Add Roomote to a server
After you save the bot token, the **Add to Discord** button appears in Roomote.
Select it and choose the server. The generated installation link requests the
permissions Roomote needs; administrator access is not required.
For tasks started in a server, the bot needs these permissions:
* view channels
* send messages
* read message history
* embed links
* attach files
* create public threads
* send messages in threads
* add reactions
* manage threads (only when a required-tag forum has no unmoderated tags)
A task started from a normal text or announcement channel runs in a public
thread started on the message that requested it — like a threaded reply — so
the conversation stays anchored where it began. A task started in a forum gets
its own forum post, and `/new` starts a fresh, separate task thread. When a
forum requires a tag, Roomote applies an available unmoderated tag
automatically. If every tag is moderated, the bot needs Manage Threads to
apply one.
Unlike a Slack workspace, a Discord server can be public or shared with
people outside your team. Task threads are visible to everyone who can see
the channel, including repository names, task descriptions, and PR links.
Only add Roomote to servers whose members you trust with that context, and
use private channels for sensitive work.
When deployment Memory is enabled, Roomote also collects message history from
server channels visible to `@everyone` where the bot has **View Channel** and
**Read Message History**. Active public threads and forum posts are included;
private channels, private threads, and DMs are not. Removing public visibility
or the bot's read access removes that channel's collected pages after the next
successful permission scan.
If Roomote cannot see the server or channel, confirm that the bot was added to
the server and that its role and channel overrides grant the permissions above.
Use **Repair** to register commands again and refresh server discovery.
## Link your account
Discord tasks are attributed only to people who have linked their Discord
account to a Roomote user.
Generate a link command under **Settings > Personal > Linked Accounts** and run
it in a direct message with the bot. This verifies that Roomote can reach you
for onboarding work. If Discord blocks the DM, open the server's **Privacy
Settings** and enable **Direct Messages**. The command expires after ten
minutes. Once linked, work you start from Discord is attributed to your Roomote
account.
During onboarding, Roomote posts the setup suggestions to the default channel
so the whole team can see and start them. When no default channel is
configured yet, they are sent to the linked setup user's direct messages
instead; Discord can block those messages when the user's server-member DM
privacy setting is disabled, and the task remains available in the Roomote web
app in that case.
## Default channel for proactive posts
Roomote posts proactive updates (automation suggestions, reports, and other
messages that are not replies to an existing conversation) to a default
channel you pick. Choose it in the Discord section of Roomote's comms settings:
select a server and a text or forum channel where the bot has permission to
post and create threads. Replies always stay in the conversation they started
in. Required-tag forums work when Roomote can apply a usable tag — an
unmoderated tag, or a moderated tag when the bot has Manage Threads.
Individual automations can also report to their own Discord channel instead of
the default: pick a Discord channel in that automation's destination selector
under **Settings > Automations**, the same way you would pick a Slack channel.
## Start and continue tasks
* mention the bot with a request in a server channel
* mention the bot in a thread reply to start work in that same thread (Slack-
style), with earlier thread messages and supported attachments as context
* send the bot a direct message
* use `/new request:` in a server channel or thread to open a fresh
conversation in its own thread instead of continuing the current one; in a
DM, `/new` sends the request into the DM conversation
* use `/goal objective:` to keep working toward an objective across
multiple turns in an active task thread or DM; this does not create a new task
* Discord DMs, mentions, attachments, and eligible thread replies from your
linked account always enter a Fast Session, which answers directly or
delegates repository work into tasks
* replies in a Fast-owned DM or thread continue that Session; replies in an
existing task conversation continue or resume the task
* reply naturally inside a task thread, forum post, or DM to continue it
(same Slack-style rules: after someone else posts or is @mentioned in the
thread since Roomote's last reply, tag Roomote again to keep going)
* paste a Discord message link (`https://discord.com/channels/.../.../...`) in a
task so the agent can pull that message and nearby channel/thread context
(lookups outside the originating task thread require a linked Discord account)
* use `/help` to see the available commands
Fast can read bounded context from the current Discord thread or channel, use
MCP servers and user-scoped integrations that you are allowed to access, and
delegate repository work to Roomote tasks. Members can create and manage their
own [custom automations](/automations#custom-automations) through Fast; deployment
admins can manage all custom automations, including those without a creator.
Built-in automations and deployment settings remain admin-only.
Fast does not read other channels implicitly
or inspect repository contents without delegating the work to a task. When the
request spans every repository, Fast can delegate it to the deployment's
all-repositories environment.
Fast automation reports can be delivered to configured Discord channels or the
automation owner's DM. Replies continue the report's Fast session in Discord.
Every Fast reply ends with a compact footer: **Reply anytime**, a plain
running-task count when at least one task is running, links to pull requests the
Session is working on, and **Open in Roomote**, which opens the Session transcript.
Roomote keeps the footer on the latest reply current as delegated tasks start
and finish (checking about every 30 seconds while work is running), and
earlier replies drop their footer when a new reply posts.
Roomote does not quote every message it answers. In a task thread, the
conversation itself supplies the context. When you start a task by tagging
Roomote in an existing thread, Roomote reads earlier messages in that thread
(including supported attachments, up to a few hundred recent thread messages) so the agent
has that background. Follow-ups in an active or resumed task thread also carry
undelivered earlier Discord messages the same way Slack does, so the agent keeps
full thread context across turns. Natural follow-ups without an @mention work
for people already in the conversation with Roomote (the task owner, the thread
starter, or anyone who tagged Roomote earlier). If somebody else posts or is
mentioned after Roomote's last reply, tag Roomote again so side chat is not
treated as a new instruction. Native forwarded messages contribute their text
and supported attachments to the task context. Image attachments are passed to
the task as image input, and supported documents are downloaded and added to
the request. Attachment downloads are size-limited and restricted to Discord's
media hosts.
## Self-hosted configuration
The setup UI stores the token for the deployment. To configure it with an
environment variable instead, set:
```sh theme={null}
R_DISCORD_BOT_TOKEN=
R_DISCORD_GATEWAY_SECRET=
```
The Discord Gateway runs as an opt-in subsystem inside Roomote's existing
BullMQ process, so enabling Discord does not add another container, process, or
port. It stays dormant until a token is saved, uses Redis to elect a single
active replica, and disconnects if Discord is removed. Durable event delivery
uses Redis and a dedicated internal shared secret. Saving Discord credentials in
settings generates `R_DISCORD_GATEWAY_SECRET` when it is not already configured.
If Discord was already set up without one (for example after an upgrade),
Roomote generates and persists the secret automatically the next time the
gateway or API needs it, or when you use **Repair**. For env-var-only setups,
set the same secret on the API and BullMQ processes yourself (installers and
platform templates also generate one).
Gateway session state is stored in the Roomote database. On a service restart
or leader handoff, Roomote asks Discord to resume the previous session and
replay any missed events; Discord can fall back to a fresh session when the old
one has expired.
Restart BullMQ after changing either environment variable. Tokens saved in the
setup UI are detected automatically without a restart.
## Verify setup
1. confirm the Discord settings page shows the bot identity and a connected
Gateway
2. confirm **Message Content intent** and **Slash commands** pass their checks
3. link your personal Discord account
4. mention the bot with a small request and confirm Roomote creates a task
thread or forum post
5. reply in that conversation and confirm the same task continues
If the Gateway remains disconnected, verify BullMQ is running and has access to
the same Redis, database, token, and internal secret as the API. If natural
messages are ignored but slash commands work, enable Message Content Intent in
the Developer Portal and restart BullMQ.
# Microsoft Teams
Source: https://docs.roomote.dev/providers/communications/microsoft-teams
Configure Microsoft sign-in and Microsoft Teams bot messaging for Roomote.
Microsoft can be used for Roomote sign-in through Microsoft Entra and for
Teams messaging through a Microsoft Bot Framework bot. Configure sign-in when
users should authenticate with Microsoft. Configure the Teams bot when Roomote
should receive Teams messages, mentions, and replies.
Use `` below for your stable public Roomote URL.
## Microsoft sign-in
Create a Microsoft Entra app registration:
1. open the [Microsoft Entra admin center](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade)
2. go to **Applications > App registrations > New registration**
3. choose the tenant or account type this Roomote deployment should accept
4. under **Authentication**, add this **Web** redirect URI:
```text theme={null}
/api/auth/oauth2/callback/microsoft-entra-id
```
5. under **Certificates & secrets**, create a client secret
6. save the client ID, secret value, and tenant ID in Roomote setup or env vars
```sh theme={null}
R_MICROSOFT_CLIENT_ID=...
R_MICROSOFT_CLIENT_SECRET=...
R_MICROSOFT_TENANT_ID=...
```
Roomote enables Microsoft sign-in only when all three values are present.
For a single-purpose Teams deployment, use the same Entra app for Microsoft
sign-in and the Teams bot. Roomote setup uses the Microsoft client ID, secret,
and tenant values for the Teams bot by default. If your Azure Bot registration
has a different bot app ID from the Entra app ID, choose **Show advanced config**
after the Directory (Tenant) ID field during setup and enter the bot-specific
values there.
After Microsoft sign-in, **Settings > Linked Accounts** shows the Microsoft
Teams account. Users who signed in with another provider can link Microsoft
from that settings page.
## Teams bot registration
Create an [Azure Bot resource](https://learn.microsoft.com/en-us/azure/bot-service/abs-quickstart?view=azure-bot-service-4.0)
in the Azure portal. Use one bot registration per Roomote deployment.
Set the bot messaging endpoint to:
```text theme={null}
/api/webhooks/teams
```
Enable the Microsoft Teams channel in the bot resource. Roomote setup stores
these bot values from the Microsoft app values unless you open **Show advanced
config** and enter separate Teams bot credentials. Use advanced config when the
Azure Bot app ID is not the same as the Entra app ID. If you configure with env
vars instead, set:
```sh theme={null}
R_TEAMS_BOT_APP_ID=
R_TEAMS_BOT_APP_PASSWORD=
R_TEAMS_BOT_TENANT_ID=
R_TEAMS_BOT_NAME=
```
`R_TEAMS_BOT_NAME` is optional, but recommended when your Teams app is not named
Roomote. Roomote uses it in generated Teams app packages and user-facing
invocation guidance.
Advanced token overrides are available when your tenant or cloud environment
requires custom Bot Framework token settings:
```sh theme={null}
R_TEAMS_BOT_TOKEN_ENDPOINT=
R_TEAMS_BOT_OAUTH_SCOPE=
```
Restart Roomote after changing Teams env vars.
## Teams app package
Roomote generates the Teams app package for you: a zip with the app manifest
and icons, pre-filled with your bot app ID and deployment URL. Download it:
* during setup, from the **Configure Microsoft Teams app** step
* later, from the Microsoft Teams card in **Settings > Communications**
Upload the package in Teams under **Apps > Manage your apps > Upload an app**,
or import it in the
[Microsoft Teams Developer Portal](https://dev.teams.microsoft.com/apps).
The generated manifest uses Teams manifest v1.25, declares channel feature
readiness, and enables all three messaging scopes:
* **Personal** - direct messages to the bot start tasks
* **Team** - channel messages that mention the bot start tasks
* **Group chat** - group-chat messages that mention the bot start tasks
If you prefer to build the app package yourself in the Developer Portal, add a
bot capability that uses the same Microsoft App ID as `R_TEAMS_BOT_APP_ID` and
include the bot entry in the manifest:
```json theme={null}
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.25/MicrosoftTeams.schema.json",
"manifestVersion": "1.25",
"accentColor": "#d6ee26",
"authorization": {
"permissions": {
"resourceSpecific": [
{ "name": "Channel.Create.Group", "type": "Application" },
{ "name": "ChannelMember.Read.Group", "type": "Application" },
{ "name": "ChannelMessage.Read.Group", "type": "Application" },
{ "name": "ChannelMessage.Send.Group", "type": "Application" },
{ "name": "ChannelSettings.Read.Group", "type": "Application" },
{ "name": "ChatMessage.Read.Chat", "type": "Application" },
{ "name": "ChatMessage.Send.Chat", "type": "Application" },
{ "name": "Member.Read.Group", "type": "Application" }
]
}
},
"bots": [
{
"botId": "",
"scopes": ["personal", "team", "groupChat"],
"supportsFiles": true,
"isNotificationOnly": false
}
],
"supportsChannelFeatures": "tier1",
"validDomains": [""]
}
```
Upload and install the app in the Teams tenant you are using. Install it
personally to test DMs, and add it to a team or group chat to test mentions.
## Verify setup
1. run Roomote with the public URL you entered in Azure
2. send a direct message to the bot, or mention the bot in a channel or group chat
3. confirm Roomote answers in Fast and includes a web continuation link
4. reply to the Fast answer, or reply in the same Fast-owned thread, and confirm
the same Fast session continues
Ordinary task-entry messages from linked users start in Fast in personal chats,
group chats, and team channels. Channel and group-chat starts require the same
mention or eligible thread-reply signals used for task entry. Sessions are
isolated by linked Roomote user even when several people share one Teams thread.
Unlinked senders receive the account-link prompt instead of starting work.
Replies to Fast messages continue the bound Fast session. Existing task
conversations keep their active-task and resumable-snapshot behavior, and Fast
delegates repository work into normal Roomote tasks. If Fast cannot start a
conversation, Roomote says so in the chat instead of starting a task another
way. Bot Framework and Microsoft Graph images, image-only messages, and
transcribed audio continue through the same attachment handling.
When a task calls `request_user_input`, Teams accepts a text reply in the same
conversation. Sensitive input remains in the web app; Teams does not currently
render interactive answer buttons. Fast automation reports can target a Teams
channel, chat, or owner direct message. Replies continue the report's Fast
session.
Every Fast reply ends with a compact footer: **Reply anytime**, a plain
running-task count when at least one task is running, links to pull requests the
Session is working on, and **Open in Roomote**, which opens the Session transcript.
Roomote keeps the footer on the latest reply current as delegated tasks start
and finish (checking about every 30 seconds while work is running), and
earlier replies drop their footer when a new reply posts.
The first verified Teams message also captures the conversation Roomote uses
for proactive output. When Slack and Telegram are not connected, setup
onboarding messages and automation summaries post to the most recently active
captured conversation, preferring team channels. Until Roomote captures a
conversation — typically from that first message, though other verified Teams
activity such as adding the app to a team can also capture one — the Microsoft
Teams card in **Settings > Communications** shows a reminder to open the app
and send the bot one message.
When an inbound Teams activity includes a Microsoft Entra AAD object ID,
Roomote can map it to an existing Microsoft sign-in account. If no mapping
exists yet, Roomote asks the sender to link their Microsoft account before
starting a task rather than launching it under another owner.
## Local URL changes
When the public URL changes, update the Azure Bot messaging endpoint, update
the Teams app package if its valid domain changed, reinstall the app if the
manifest changed, and restart Roomote with the matching URL.
# Slack
Source: https://docs.roomote.dev/providers/communications/slack
Configure Slack sign-in, Slack app callbacks, events, and interactivity for Roomote.
Slack can be both a Roomote sign-in provider and a communications provider.
You may use one Slack app for both jobs.
## What you need
* a Slack workspace where you can create and install apps
* a stable public Roomote URL
* access to Roomote setup or deployment environment variables
Use `` below for the exact public URL printed by local development
or configured for your self-hosted deployment.
## Fast path
In `/setup` or **Settings → Communications**, paste a Slack **app configuration
token** and Roomote creates the Slack app for you through Slack's
`apps.manifest.create` API:
1. open [api.slack.com/apps](https://api.slack.com/apps) and click
**Generate Token** under **Your App Configuration Tokens** (at the bottom of
the page), picking the workspace where Roomote should live
2. paste the access token into Roomote and click **Create Slack app**
Roomote creates the app with redirect URLs, webhook URLs, interactivity,
scopes, and events preconfigured for the current public URL, then saves the
**Client ID**, **Client Secret**, and **Signing Secret** automatically. The
configuration token is used once to create the app and never stored. Finish
the Slack install step so Roomote can receive events and post replies.
If Slack is already configured, Settings → Communications shows the saved
credentials and still offers **Create a new Slack app with a configuration
token** when you need to replace them.
### Update an existing Slack app
After connecting a workspace, use **Settings → Communications → Slack → Update
app** to bring the existing app manifest up to date with the current Roomote
configuration. Generate and paste a fresh app configuration token when
prompted. Roomote exports the app's current manifest, preserves custom fields,
adds or updates Roomote's required capabilities, scopes, events, redirect URLs,
and callback URLs, validates the result, and then applies it. The token is not
stored.
If the update changes permissions, Roomote shows **Reinstall in Slack**. Finish
that approval step before testing the new capabilities because Slack does not
add scopes to existing installations automatically.
### Alternative: env vars or an existing app
If you already have a Slack app, or production secret management should own the
credentials, create the app in Slack (optionally from a prefilled manifest) and
set these deployment env vars instead of using the config-token flow:
```sh theme={null}
R_SLACK_CLIENT_ID=...
R_SLACK_CLIENT_SECRET=...
R_SLACK_SIGNING_SECRET=...
```
After the values are available to Roomote, finish the Slack install step so
Roomote can receive events and post replies.
`SLACK_APP_ID` is optional for manual preconfiguration. Roomote saves Slack's
`app_id` from the OAuth installation response after workspace install.
During OAuth install, Roomote also records the installed bot display name when
Slack exposes it, so setup and automation guidance can show the actual Slack
app users should mention instead of assuming `@Roomote`.
## Automatic manager channel
After the app is installed, the first user who links their Slack account to
Roomote triggers setup of a public `#roomote-managers` channel in that workspace.
Installing the app alone does not trigger setup. Roomote creates the channel or
reuses an existing public, unarchived, nonshared channel with that exact name,
ensures the bot is a member, and sets it as the shared **Manager Channel** under
**Settings > Automations > Automation output**.
Existing Slack or Discord Manager Channel settings and explicit automation
destinations are preserved. This setup does not create or enable automations.
Private channels are not selected, converted, or read by automatic setup; they
remain available for manual configuration with the appropriate bot access.
Automatic setup requires the bot scopes `channels:manage` and `channels:join`.
For an existing installation, use **Update app**, then **Reinstall in Slack** to
approve these permissions. If workspace restrictions, unavailable permissions,
or Slack errors prevent setup, account authentication still succeeds. Link your
Slack account again to retry, or configure the Manager Channel manually.
## Redirect URLs
Slack sign-in uses Slack OpenID Connect. Add the sign-in redirect URL:
```text theme={null}
/api/auth/oauth2/callback/slack
```
If the same app handles the Slack communications integration, add the
integration redirect URL too:
```text theme={null}
/api/slack/callback
```
The current deployment configuration uses one Slack client credential pair for
both sign-in and communications:
```sh theme={null}
R_SLACK_CLIENT_ID=...
R_SLACK_CLIENT_SECRET=...
```
## Bot scopes
Add these bot token scopes under **OAuth & Permissions > Scopes > Bot Token
Scopes**:
```text theme={null}
app_mentions:read
assistant:write
channels:read
channels:history
channels:manage
channels:join
chat:write
files:read
files:write
groups:read
groups:history
im:read
im:history
im:write
links:read
links:write
mpim:read
mpim:history
reactions:read
reactions:write
team:read
users:read
```
After adding or changing scopes, reinstall the app from **OAuth & Permissions >
Install to Workspace**. Slack does not apply new scopes to an existing
installation until you reinstall.
Native video replies require `files:write`. For an existing installation,
reinstall the app and obtain workspace admin reapproval if required before
expecting videos to appear as Slack files. Updating the manifest alone does not
grant the installed bot this permission.
## Video replies
Roomote can share selected task recordings as native Slack video files in the
conversation. Ask for the recording from a task associated with the current
Session, including an earlier task in that Session, and Roomote can recover its
uploaded artifact and share it without recording again. Native delivery is
limited to uploaded recordings from that Session's task runs, not arbitrary
recordings from other Sessions.
Uploading a task artifact alone does not automatically post it to Slack.
The recording must be no larger than 50 MiB. When conversion is needed, the
converted file must also fit within 50 MiB. Larger recordings use an artifact
viewer link instead of a native Slack attachment.
For WebM recordings, delivery converts a copy to MP4 for Slack playback while
preserving the original task artifact. If permissions, conversion, or upload
prevent native delivery, Roomote shares only an artifact viewer link, without
an error or unavailability explanation. Roomote only describes a video as
attached when native delivery succeeds.
## Events and interactivity
Turn on **Event Subscriptions** and set **Request URL** to:
```text theme={null}
/api/webhooks/slack
```
Subscribe to these bot events:
```text theme={null}
app_context_changed
app_home_opened
app_mention
message.im
message.channels
message.groups
message.mpim
reaction_added
member_joined_channel
link_shared
entity_details_requested
function_executed
```
Turn on **Interactivity & Shortcuts** and use the same request URL:
```text theme={null}
/api/webhooks/slack
```
Roomote uses this endpoint for button clicks and other interactive Slack
payloads.
## Agent messaging experience
Roomote-created apps enable Slack's current **Agent messaging experience**
(`features.agent_view`). This keeps conversations in the app's Messages tab,
opens Fast-mode responses in threads, and allows Slack to render native loading
states and streamed task cards. Tasks delegated by Fast appear as native cards
that stream coding progress and settle to their final result in the same thread.
For an existing app, use **Update app** in Settings → Communications to apply
these settings. You can also configure them manually by enabling the **Agents**
feature, selecting the Agent messaging experience, adding the `assistant:write`
scope and the `app_home_opened` and `app_context_changed` events, and then
reinstalling the app. Hard-refresh Slack afterward. Keep `message.im` enabled
so direct messages continue reaching Roomote.
## Fast answers
**Fast response mode** is always on across Slack, Discord, Microsoft Teams, and
Telegram: ordinary messages from your linked account go through the Fast
orchestrator, which can delegate work into tasks. In channels, mention the app,
for example `@Roomote summarize this thread` or `@Roomote fix the failing CI
job`. Replies in a Fast-owned Slack thread continue that Fast session; replies
in an existing task-only thread continue the task.
Fast can read a bounded history from the current Slack channel, discover other
channels in the same workspace, and post standalone updates to channels where
the Roomote app is authorized. Reactions remain scoped to the current inbound
message. Fast can also use MCP servers and user-scoped integrations that you are
allowed to access and delegate repository work to Roomote tasks. Members can
create and manage their own [custom automations](/automations#custom-automations)
through Fast; deployment admins can manage all custom automations, including
those without a creator. Built-in automations and deployment settings remain
admin-only. Fast does not read other
channels implicitly or inspect repository contents without delegating the work
to a task. When the request spans every repository, Fast can delegate it to the
deployment's all-repositories environment.
Every Fast reply ends with a compact footer: **Reply anytime**, a plain
running-task count when at least one task is running, links to pull requests the
Session is working on, and **Open in Roomote**, which opens the Session transcript.
Roomote keeps the footer on the latest reply current as delegated tasks start
and finish, checking about every 30 seconds while work is running, so the
thread shows whether coding is still going without another reply. Only the
newest reply carries the footer; earlier replies drop it when a new reply
posts.
Agent replies and delegated reports can include up to two native Slack charts.
Ask Roomote to visualize suitable data as a pie, bar, area, or line chart. Each
chart keeps a Markdown fallback for notifications and accessibility, and the
same structured data renders as a chart with an accessible table in the Roomote
web transcript. No additional Slack scope is required.
## Local URL changes
Keep the public URL stable. When it changes, update the Slack app's redirect
URLs, Event Subscriptions request URL, and Interactivity request URL, then
restart Roomote with the matching URL.
## Verify setup
1. sign in with Slack, if Slack sign-in is enabled
2. install the Slack app to the workspace
3. mention the app in a channel or send it a direct message
4. confirm Roomote answers in Fast and includes a web continuation link
5. reply in the same thread and confirm the message continues the same Fast
session; when Fast delegates work, confirm the task card stays in that thread
# Telegram
Source: https://docs.roomote.dev/providers/communications/telegram
Configure a Telegram bot and webhook so Roomote can start and continue tasks from Telegram.
Telegram is a deployment-owned messaging provider. It is not a Roomote sign-in
provider.
Roomote can receive Telegram bot messages, start tasks from private chats or
bot mentions, and reply back through the same chat or forum topic. Telegram
delivers updates through the Bot API webhook endpoint, so Roomote must be
reachable at a stable public HTTPS URL.
Use `` below for your stable public Roomote URL.
## Create a Telegram bot
Message `@BotFather` in Telegram and create or select a bot. In the Roomote UI
(**Settings > Communications > Telegram**), enter the bot token, then save.
Roomote reads the bot identity from Telegram, generates a webhook secret,
registers the Bot API webhook, and adds `/start` and `/new` to the bot's command
menu for you.
In BotFather, open **Bot Settings > Threaded Mode** and enable it. Roomote will
then create a separate topic in your private bot chat for each new task. If
Threaded Mode is unavailable or disabled, Roomote uses the existing single-chat
flow. When a new topic opens, Roomote replies in the source conversation with
its name; open it from Telegram's topic list. Telegram's Bot Developer Terms
currently withhold a 15% fee from Stars purchases made through a bot while
private-chat topics are enabled.
When Telegram initially labels an implicit topic **New Chat**, Roomote replaces
it with the same generated title shown for the task in the web app.
For a shared team chat, create a Telegram supergroup, enable topics, then add
the Roomote bot as an administrator with **Manage Topics** permission. Telegram
requires a user to create the group and enable topics; the Bot API cannot do
those provisioning steps. Once configured, Roomote can create task topics in
the forum automatically. The source conversation receives an **Open topic**
button so the handoff is visible instead of relying on the topic list alone.
If Telegram rejects topic creation, Roomote starts the task in the source
conversation and explains that Threaded Mode or **Manage Topics** needs attention.
For self-hosted env-var configuration instead of the UI:
```sh theme={null}
R_TELEGRAM_BOT_TOKEN=
# Optional — Roomote generates one on save when unset:
# R_TELEGRAM_WEBHOOK_SECRET=
```
Roomote reads the bot username from Telegram using the bot token, so it does
not need to be configured separately.
When Roomote asks you to confirm an environment, you can use the buttons or
reply naturally in the same chat or topic. Replies such as `yes`, `never mind`,
or `use API instead` confirm, cancel, or revise the pending route without
turning the reply into a second task.
Restart Roomote after changing Telegram env vars. Inbound webhooks are accepted
only when Telegram sends the matching `X-Telegram-Bot-Api-Secret-Token`
header, and outbound replies use `R_TELEGRAM_BOT_TOKEN`.
## Register the webhook
When you save Telegram credentials in Roomote, the webhook is registered
automatically at `/api/webhooks/telegram` with the managed secret
token and `allowed_updates` including `message`, `callback_query`, and
`message_reaction`. Roomote uses newly added 👍 reactions on suggested-task
messages to launch the selected task and user-attributed reactions on Roomote
Fast replies as conversation input. Roomote does not request
`message_reaction_count`: those aggregate updates do not identify the reacting
user, so they cannot satisfy Roomote's account and conversation ownership
checks.
If the connection check reports a mismatch, delivery error, or stale update
configuration, use **Repair** in Telegram settings to re-register it.
If you are bootstrapping only from env vars and need to register manually
before the first UI save:
```sh theme={null}
curl -sS "https://api.telegram.org/bot${R_TELEGRAM_BOT_TOKEN}/setWebhook" \
-H "content-type: application/json" \
-d '{
"url": "/api/webhooks/telegram",
"secret_token": "",
"allowed_updates": ["message", "callback_query", "message_reaction"]
}'
```
Use the same value for `secret_token` and `R_TELEGRAM_WEBHOOK_SECRET` when you
pass a secret explicitly.
## Account linking
Telegram tasks are attributed only to senders who have linked their Telegram
account to a Roomote user.
Generate a link code under **Settings > Personal > Linked Accounts** and send
it to the bot. Until a sender links, Roomote will not start, resume, or follow
up on tasks on their behalf.
## Verify setup
1. send a direct message to the bot, or mention the bot in a group
2. confirm Roomote answers in Fast and includes a web continuation link
3. reply to the Fast answer, or reply in the same Fast-owned topic, and confirm
the same Fast session continues
4. use `/new ` and confirm a fresh conversation opens in its own
topic when Threaded Mode is enabled
5. reply in the task topic to send a follow-up
Every message from a linked user enters a Fast Session: in private chats
directly, and in groups from bot mentions. Fast answers directly or delegates
a task into the right environment. A Fast-owned topic can continue without
another mention, and a direct reply to a Fast message resumes the bound
session even when the chat has no topics. Sessions are isolated by linked
Roomote user. `/new` starts a fresh conversation instead of continuing the
current one, opening a new topic when Telegram supports it; in a plain private
chat the request joins that chat's conversation.
Existing task chats and topics keep their active-task, `request_user_input`,
and resumable-snapshot behavior. If Fast cannot start a conversation, Roomote
says so in the chat instead of starting a task another way. Fast automation
reports can target a Telegram chat, topic, or owner direct message; replies
continue the report's Fast session.
Every Fast reply ends with a compact footer: **Reply anytime**, a plain
running-task count when at least one task is running, links to pull requests the
Session is working on, and **Open in Roomote**, which opens the Session transcript.
Roomote keeps the footer on the latest reply current as delegated tasks start
and finish (checking about every 30 seconds while work is running), and
earlier replies drop their footer when a new reply posts.
Photos are passed to Fast or the task as image input. Supported text documents
are downloaded server-side and their extracted content is added to the request;
voice and audio messages are transcribed when supported. The bot token is never
included in the prompt or attachment URL.
## Local URL changes
When the public URL changes, call `setWebhook` again with the new
`/api/webhooks/telegram` URL and restart Roomote with the matching
URL.
# Azure Container Apps
Source: https://docs.roomote.dev/providers/compute/azure
Run Roomote tasks on Azure Container Apps sandboxes.
Azure Container Apps sandboxes are hardware-isolated microVMs that run Roomote
tasks on your own Azure subscription. The provider supports memory+disk
snapshots and sub-second suspend/resume standby, so both environment setup
caching and task sleep/resume flows keep the full workspace state.
Azure Container Apps sandboxes are in public preview; expect API drift.
## When to use Azure Container Apps
Use Azure Container Apps when:
* task work should run inside your own Azure subscription
* you want hosted sandboxes without managing an API key (auth uses the
ambient Azure login or a managed identity)
* memory+disk snapshots or standby with sub-second resume is useful
## Prerequisites
1. An Azure subscription and resource group.
2. A sandbox group (one-time bootstrap):
```sh theme={null}
aca sandboxgroup create --name --location --set-config
```
The calling principal is granted the Container Apps SandboxGroup Data
Owner role automatically; grant it explicitly to any additional principal,
such as a deployed controller's managed identity.
3. Authentication: `az login` for local runs; a managed identity when the
Roomote controller itself runs in Azure (set `AZURE_CLIENT_ID` for a
user-assigned identity); or a service principal (recommended for
containerized installs, where `az login` is impractical) —
`az ad sp create-for-rbac --name --skip-assignment`, then grant the
app the Data Owner role from step 2 and set all three of
`AZURE_TENANT_ID`/`AZURE_CLIENT_ID`/`AZURE_CLIENT_SECRET`.
## Configuration
Add Azure Container Apps from **Settings > Sandboxes**, or provide the values
as deployment env vars:
```sh theme={null}
DEFAULT_COMPUTE_PROVIDER=azure
AZURE_SUBSCRIPTION_ID=...
AZURE_RESOURCE_GROUP=...
AZURE_SANDBOX_GROUP=...
AZURE_SANDBOX_REGION=...
```
Optional values:
```sh theme={null}
AZURE_CLIENT_ID=...
AZURE_SANDBOX_DISK_IMAGE=...
# Service principal auth (all three together; recommended for Docker installs)
AZURE_TENANT_ID=...
AZURE_CLIENT_SECRET=...
# Worker image registry pull credentials (only for private images)
AZURE_SANDBOX_REGISTRY_USERNAME=...
AZURE_SANDBOX_REGISTRY_TOKEN=...
# Sandbox size (XS/S/M/L/XL; defaults to Roomote's 4 GiB task allocation)
AZURE_SANDBOX_SIZE=...
# Egress TLS inspection override (Legacy/Full/Partial/None; default Partial)
AZURE_SANDBOX_EGRESS_INSPECTION=...
```
`AZURE_SANDBOX_DISK_IMAGE` selects the worker disk image. Leave it unset to
let Roomote provision it automatically: the setup wizard and the Settings >
Sandboxes page bake a disk image from the published worker OCI image after
the Azure settings are saved. Private registries (e.g. a private GHCR
worker image) need `AZURE_SANDBOX_REGISTRY_USERNAME` +
`AZURE_SANDBOX_REGISTRY_TOKEN`.
## Snapshots and standby
Azure snapshots capture memory and disk, so a restored sandbox resumes in
sub-second time with processes still alive. Task standby uses the same
memory-preserving suspend/resume, and sandboxes bill storage-only while
suspended. Preview port URLs do not survive a snapshot restore; Roomote
re-adds ports after resume.
## Idle suspension and cost control
Roomote enables Azure's memory-preserving auto-suspend policy for new
sandboxes and refreshes it when restoring snapshots or resuming standby.
The idle interval follows the task's sandbox timeout, normally five hours.
This gives Azure a fallback when Roomote's cleanup service is offline or a
development database has been reset. CPU and memory charges stop while the
sandbox is suspended.
Azure measures idle time from incoming traffic, API code execution, shell
sessions, and file operations. This is an idle fallback, not a hard runtime
or spending cap: continued activity can keep a sandbox running. Roomote's
normal task sleep and timeout handling still applies.
The separate auto-delete policy retains stopped task sandboxes for at least
30 days. Its timer starts after suspension; it cannot stop a running sandbox.
Upgrading refreshes lifecycle settings as sandboxes are reused. Existing
orphaned sandboxes that Roomote no longer tracks need to be inspected and
suspended separately in Azure.
## Egress TLS inspection
The ACA egress proxy can TLS-inspect (MITM) outbound traffic. Roomote defaults
to `trafficInspection: Partial`, so with no egress rules configured nothing is
inspected: package managers (npm, Maven/Gradle, pip) see normal public
certificate chains, and non-HTTP traffic such as SSH git works. Override this
with `AZURE_SANDBOX_EGRESS_INSPECTION`, which accepts `Legacy`, `Full`,
`Partial`, or `None` and passes the selected mode to ACA. The service default
(`Full`) resigns all TLS traffic with the proxy CA
(`/etc/ssl/certs/adc-egress-proxy-ca.crt`, preinstalled in the system store
and referenced by `NODE_EXTRA_CA_CERTS`/`SSL_CERT_FILE`) and blocks non-HTTP
traffic; choose `Full` only when wiring deny-default egress rules or header
transforms, and note Java's per-JDK cacerts still needs a manual import in
that mode.
## Verify setup
1. save the Azure subscription, resource group, sandbox group, and region
2. select Azure Container Apps as the default sandbox provider
3. start a small task from an environment
4. confirm the task starts, streams logs, and can run project commands
5. verify preview links if the task starts a web app
## Common issues
* **Authentication fails.** Run `az login` locally, or confirm the deployed
controller's managed identity holds the Container Apps SandboxGroup Data
Owner role on the sandbox group.
* **Sandbox creation is slow on first use.** Cold disk image pulls take
longer; the worker disk image bake is a one-time provisioning step.
# Blaxel
Source: https://docs.roomote.dev/providers/compute/blaxel
Run Roomote tasks in Blaxel perpetual sandboxes.
Blaxel is a hosted sandbox provider. Roomote creates a sandbox, exposes task
ports through Blaxel preview URLs, and starts the task worker as a keep-alive
process.
## When to use Blaxel
Use Blaxel when task work should run outside the Roomote host and you want
provider-managed microVMs with automatic standby and fast wake-up.
## Configuration
Create a key from the [Blaxel API keys page](https://app.blaxel.ai/profile/security),
then add Blaxel from **Settings > Sandboxes** or provide:
```sh theme={null}
BL_API_KEY=...
BL_WORKSPACE=my-workspace
```
You can optionally select a region:
```sh theme={null}
BLAXEL_REGION=us-pdx-1
```
Standby retention can be bounded separately from active task timeouts:
```sh theme={null}
BLAXEL_STANDBY_MAX_COUNT=25
BLAXEL_STANDBY_MAX_AGE_HOURS=168
```
Region and standby retention are also editable under **Settings > Sandboxes >
Blaxel > Advanced settings**. Process environment variables take precedence
and appear as locked values in Settings.
Roomote's provisioned Blaxel worker image includes Docker, Docker Compose, and
the legacy iptables backend required for
[Docker projects](/environments/definition#docker-projects). Container
builds and services share the task sandbox's memory allocation. Roomote
requests 8 GiB for these tasks and 4 GiB for tasks that do not need nested
Docker.
## Verify setup
1. Save the API key and workspace name.
2. Select Blaxel as the default sandbox provider.
3. Start a small task and confirm logs reach the task view.
4. Start a web app and verify its preview link.
## Common issues
* **Authentication fails.** Confirm the API key belongs to `BL_WORKSPACE`.
* **A preview has no URL.** Confirm the configured workspace can create public
sandbox previews and that the requested ports are valid.
# Box
Source: https://docs.roomote.dev/providers/compute/box
Run Roomote tasks in Box-hosted sandboxes.
Box is a hosted sandbox provider for running Roomote tasks away from the
Roomote server.
## When to use Box
Use Box when:
* task work should run on provider-managed machines
* you want API-key-only setup without building a provider-side worker image,
template, or snapshot during Roomote setup
* environments need Docker, Docker Compose, or private preview URLs
* retaining the same stopped task sandbox for a follow-up is sufficient
Box supports Roomote environment snapshots through named snapshots (template
boxes); see [Environment snapshots](#environment-snapshots) below. A retained
Box can also resume the task that created it directly.
## Configuration
Create a key from the [Box dashboard](https://box.ascii.dev/box/dashboard),
then add Box from **Settings > Sandboxes**. You can also provide the key as a
deployment env var:
```sh theme={null}
DEFAULT_COMPUTE_PROVIDER=box
BOX_API_KEY=...
```
Optional settings:
```sh theme={null}
# Custom Box-compatible API endpoint. Defaults to
# https://ascii.dev/api/box/v1
BOX_API_BASE_URL=https://box.example.com/api/box/v1
# small, default, or large
BOX_MACHINE_TYPE=default
# Active sandbox timeout in milliseconds. Defaults to 2 hours, the Box
# free-trial maximum; paid accounts can set a higher value.
BOX_TIMEOUT_MS=...
# Standby retention policy. Defaults to 25 Boxes for 168 hours (7 days).
# Set the count to 0 to disable retained task sandboxes.
BOX_STANDBY_MAX_COUNT=25
BOX_STANDBY_MAX_AGE_HOURS=168
```
These optional values are also available under **Settings > Sandboxes > Box >
Advanced settings**. Process environment variables take precedence and appear
as locked values in Settings.
Roomote does not provision a worker artifact in your Box account during setup.
Saving a valid API key is enough to configure the provider.
Roomote installs its worker into each Box when the sandbox starts. Box supports
[Docker projects](/environments/definition#docker-projects), including Docker
Compose services, without additional provider-side setup. Named environment
ports are exposed through authenticated private preview URLs in the Roomote task
view.
## Cleanup and resume behavior
Roomote stops and archives a Box when retaining it for task resume. This takes a
filesystem snapshot, pauses billing, and preserves the Box for a later resume.
Box's permanent-delete API is being reworked, so Roomote also uses stop/archive
as its cleanup fallback for canceled, failed, and retention-expired
tasks. Those archived Boxes remain in the provider account until permanent
deletion is available.
## Environment snapshots
Roomote environment snapshots map to Box named snapshots (template boxes):
snapshotting an environment saves a `roomote-snap-*` template, and tasks that
start from the snapshot fork it into a fresh Box in seconds instead of
re-running environment setup. Box accounts are limited to 10 named snapshots,
so delete stale `roomote-snap-*` templates from the Box dashboard when
re-snapshotting environments repeatedly. Free-trial accounts also cap
concurrent boxes (2 at the time of writing), which bounds how many tasks can
run at once.
`BOX_STANDBY_MAX_COUNT` and `BOX_STANDBY_MAX_AGE_HOURS` bound how many stopped
task sandboxes Roomote retains and for how long. This standby behavior preserves
one task's machine; it is not a Roomote environment snapshot.
## Verify setup
1. Save the Box API key.
2. Select Box as the default sandbox provider.
3. Start a small task and confirm logs reach the task view.
4. If the environment exposes a port, open its preview from the task view.
5. Send a follow-up while the task sandbox is retained and confirm it resumes.
## Common issues
* **Authentication fails.** Confirm `BOX_API_KEY` is active and belongs to the
expected Box account.
* **The API cannot be reached.** Remove `BOX_API_BASE_URL` to use the provider
default, or verify the custom endpoint is reachable from the Roomote
deployment.
* **A follow-up starts a new sandbox.** Check the standby count and age limits.
Roomote may no longer retain the previous Box as the task's resume target.
* **A task stops after two hours.** Free-trial accounts require a timeout of two
hours or less. Paid accounts can increase `BOX_TIMEOUT_MS`; Roomote still caps
the Box lifetime to the task's configured timeout.
* **A preview does not open.** Confirm the environment declares the port and the
application listens on `0.0.0.0`, not only `localhost`.
* **An environment snapshot fails to save.** Box accounts allow at most 10
named snapshots; delete stale `roomote-snap-*` templates from the Box
dashboard and re-run the snapshot.
# Daytona
Source: https://docs.roomote.dev/providers/compute/daytona
Run Roomote tasks on Daytona-hosted sandboxes.
Daytona is a hosted sandbox provider with straightforward API-key setup.
It supports environment and task-level filesystem snapshots for faster resume
flows.
## When to use Daytona
Use Daytona when:
* task work should run outside the Roomote host
* you want hosted sandboxes with simple credential setup
* you can provide a Daytona API key
* environment setup caching or task sleep/resume via snapshots is useful
## Configuration
Add Daytona from **Settings > Sandboxes** with your API key, or provide the
values as deployment env vars.
Create the key on the
[API Keys page](https://app.daytona.io/dashboard/keys) with **write** and
**delete** permissions on both **Sandboxes** and **Snapshots**. No other
scopes are needed.
```sh theme={null}
DAYTONA_API_KEY=...
```
Optional values:
```sh theme={null}
DAYTONA_API_URL=...
DAYTONA_TARGET=...
```
Use `DAYTONA_API_URL` for custom Daytona endpoints. Use `DAYTONA_TARGET` when
your account or deployment needs a specific target or region.
Roomote's Daytona worker snapshot includes Docker and Docker Compose, so
environments can run
[Docker projects](/environments/definition#docker-projects). Daytona
runs these through Docker-in-Docker inside the task sandbox. Container builds
and services share the sandbox's resources. Roomote requests 8 GiB for these
tasks and 4 GiB for tasks that do not need nested Docker.
## Verify setup
1. save `DAYTONA_API_KEY`
2. select Daytona as the default sandbox provider
3. start a small task from an environment
4. confirm the task starts, streams logs, and can run project commands
5. verify preview links if the task starts a web app
## Common issues
* **The provider starts in the wrong region or target.** Set
`DAYTONA_TARGET` to the intended target.
* **Container startup is slow or runs out of memory.** Increase the Daytona
sandbox resources; Docker-in-Docker adds daemon and image-build overhead.
# Docker
Source: https://docs.roomote.dev/providers/compute/docker
Run Roomote task sandboxes as Docker containers on the same host as the deployment.
Docker is the simplest sandbox provider for local development and trusted
single-host self-hosting. Roomote starts one worker container per task, connects
it to the configured Docker network, streams logs back to the task view, and
stops the container when the task is finished.
## When to use Docker
Use Docker when:
* you are developing Roomote locally
* you are trying Roomote on one trusted host
* task volume is modest enough for the host machine
* you want the fewest external sandbox accounts and credentials
* you want resumable tasks to restart the same workspace on the same host
Move to a hosted provider when multiple users run heavier tasks, when task
work should not compete with the Roomote server, or when you need stronger
provider-managed isolation.
## Configuration
Docker does not need provider API credentials. Select Docker during setup or
from **Settings > Sandboxes**.
Common env vars:
```sh theme={null}
DEFAULT_COMPUTE_PROVIDER=docker
DOCKER_WORKER_IMAGE=roomote-worker:local
# Optional: defaults to the host architecture (linux/amd64 or linux/arm64)
DOCKER_WORKER_PLATFORM=linux/amd64
DOCKER_WORKER_NETWORK=roomote_worker
DOCKER_WORKER_RELEASE_PATH=/roomote/releases/worker-current.tar.gz
DOCKER_WORKER_CPU_LIMIT=2
DOCKER_WORKER_MEMORY_LIMIT=4g
DOCKER_TASK_DAEMON_MEMORY_LIMIT=8g
DOCKER_WORKER_PIDS_LIMIT=512
DOCKER_WORKER_DISK_LIMIT=20g
DOCKER_WORKER_ALLOW_UNBOUNDED_DISK=false
DOCKER_WORKER_LOG_MAX_SIZE=10m
DOCKER_WORKER_LOG_MAX_FILES=3
# internet allows public egress but blocks private/metadata ranges
# none disables external egress entirely
DOCKER_WORKER_EGRESS_POLICY=internet
DOCKER_STANDBY_MAX_COUNT=10
DOCKER_STANDBY_MAX_AGE_HOURS=24
```
Local development builds `roomote-worker:local` automatically. Self-hosted
Compose deployments normally use `docker-compose.compute-docker.yml`, which
sets the worker image, platform, network, and release path for sibling worker
containers.
For production deployments, prefer an immutable registry-qualified worker image
tag when workers need a published image instead of a local tag.
## Resource and network isolation
Every Docker task receives a dedicated bridge network. In Compose deployments,
Roomote attaches the API and, when enabled, the optional preview proxy to that
network; sibling task containers and datastore containers are not reachable.
The controller reconciles replacement API and preview-proxy containers onto
running task networks, removes empty task networks periodically, and reaps
stale provisioning containers after a restart.
Environments that use [Docker projects](/environments/definition#docker-projects)
also receive a dedicated Docker daemon and workspace volume. Customer Compose
services share the task's network namespace so configured preview ports keep
the same task-scoped routing, while their Docker control plane is not exposed
to other tasks. The daemon, inner containers, network, and workspace volume are
stopped or removed with the task lifecycle.
Workers default to 2 CPUs, 4 GiB of memory with no additional swap, 512 PIDs,
a requested 20 GiB writable-layer quota, and three 10 MiB JSON log files. The
dedicated Docker daemon used by Docker-project tasks receives an 8 GiB memory
limit by default while inheriting the other worker resource limits. The
variables above can tune those bounds.
Writable-layer quotas require a Docker
storage driver that supports `--storage-opt size`. When the driver rejects that
option, Roomote refuses to start the task rather than allowing untrusted code to
consume the host disk. Configure a quota-capable Docker data root. Operators
that enforce an equivalent host-level quota can explicitly set
`DOCKER_WORKER_ALLOW_UNBOUNDED_DISK=true`; Roomote then logs a warning and
starts without `--storage-opt size`.
Completed resumable tasks keep their stopped container and writable layer so a
follow-up can restart the same workspace. Roomote retains at most 10 containers
for 24 hours by default. Configure `DOCKER_STANDBY_MAX_COUNT` and
`DOCKER_STANDBY_MAX_AGE_HOURS` to change those bounds; a count of `0` disables
Docker standby retention. The five-minute retention sweep removes the oldest
or expired containers and their task networks.
These retention limits are also editable under **Settings > Sandboxes > Local
Docker > Advanced settings**. Process environment variables take precedence
and appear as locked values in Settings.
The default `internet` egress policy allows public repository and tool access
while installing immutable blackhole routes for private, shared-address, and
cloud metadata ranges (including AWS/GCP/Azure, Alibaba, and Oracle endpoints).
The task's own, more-specific network route still reaches its API and preview
proxy peers. In networked self-host deployments, direct connections to the
Docker bridge gateway are also blocked without disrupting its use as the
public-egress next hop. Local development blocks metadata ranges but retains
private and gateway access because its API runs on the host. The worker never
receives the network-administration capability needed to remove the policy. Set
`DOCKER_WORKER_EGRESS_POLICY=none` for tasks that need only the Roomote API and
preview proxy.
## Security notes
Docker sandboxes require the Roomote controller to create and manage worker
containers. Production Compose routes those operations through an internal
socket proxy that allows only the container, exec, image, network, and volume API
sections Roomote needs; the controller does not mount the raw socket. Treat the
proxy and Docker host as trusted infrastructure, and do not use Docker
sandboxes as a multi-tenant isolation boundary for untrusted operators or
repositories.
## Verify setup
1. select Docker as the sandbox provider
2. use **Validate environment** in Settings → Sandboxes (Local Docker
section) to check the Docker daemon, worker image, and worker release
archive before starting anything
3. start a small task from an environment
4. confirm the task can clone the repository and run a simple command
5. open task logs and verify output streams back to Roomote
6. check that the worker container stops after the task completes
The validation runs in the background worker service (the process with Docker
socket access), so it reflects exactly what task boots will see.
## Common issues
Before creating any sandbox resources, Roomote preflights the Docker
environment: it checks that the daemon responds, and that the worker image is
available locally (pulling it when a registry hosts it). When a boot fails, the
task startup screen explains the failure category; the sections below map each
one to a fix.
* **Roomote couldn't reach the Docker daemon.** Start Docker Desktop (or the
Docker Engine service) and confirm the host running the controller can access
the Docker socket. In production Compose, check the socket proxy container.
* **Roomote couldn't find or pull the worker image.** Build or publish the
worker image configured in `DOCKER_WORKER_IMAGE` (for local development,
`pnpm dev` builds `roomote-worker:local`). For private registries, make sure
the host is logged in.
* **A required host port is already in use.** Another process holds a port the
sandbox needs. Stop it, or change the conflicting service's port, then retry.
* **The worker release archive is missing.** The Docker provider installs the
worker from a local release archive. For local development, run
`pnpm dev --use-release` (or the worker-release build step) so the archive
exists before starting tasks.
* **The worker failed while contacting the Roomote API (`fetch failed`).**
The container cannot reach the API URL from inside Docker. Verify
`R_PUBLIC_URL`/the API address resolves from a container (often via
`host.docker.internal`) and that the API is running.
* **The worker did not start in time, or the container exited during boot.**
Open the task's failure details for the container logs and process list —
they include the underlying crash, missing dependency, or fetch failure.
* **The task cannot reach Roomote services.** Check `DOCKER_WORKER_NETWORK` and
the Compose network used by the API and controller.
* **A worker reports that its disk limit is unsupported.** Configure a Docker
storage driver with per-container writable-layer quota support. Only set
`DOCKER_WORKER_ALLOW_UNBOUNDED_DISK=true` when an equivalent host-level quota
is already enforced.
* **Docker's address pools are exhausted.** List Roomote-managed task networks
and remove only unused ones:
```sh theme={null}
docker network ls --filter label=dev.roomote.sandbox.managed=true
docker network prune --filter label=dev.roomote.sandbox.managed=true
```
Docker asks for confirmation and prunes only networks with no attached
containers. On Docker Desktop with the WSL2 backend, restart Docker Desktop if
released networks do not restore address space. If exhaustion recurs, set
Docker's `default-address-pools` in the Docker Engine configuration to a
larger private range that does not overlap the host, VPN, or deployment
networks, then restart Docker. Roomote does not assign static task subnets
because host and VPN ranges differ between deployments.
# E2B
Source: https://docs.roomote.dev/providers/compute/e2b
Run Roomote tasks on E2B-hosted sandboxes.
E2B is a hosted sandbox provider for running task sandboxes away from the
Roomote server.
## When to use E2B
Use E2B when:
* task work should run outside the Roomote host
* you want hosted sandboxes with snapshot support
* you can provide an E2B API key
* your deployment can reach E2B and E2B task sandboxes can reach Roomote
## Configuration
Add E2B from **Settings > Sandboxes** with your API key, or provide the values
as deployment env vars:
```sh theme={null}
E2B_API_KEY=...
```
Optional values:
```sh theme={null}
E2B_DOMAIN=e2b.app
E2B_MAX_SANDBOX_TIMEOUT_MS=3600000
```
Use `E2B_DOMAIN` only for self-hosted or custom E2B clusters. The default E2B
domain is enough for standard hosted E2B.
Roomote's provisioned E2B worker template includes Docker and Docker Compose,
so environments can run [Docker projects](/environments/definition#docker-projects).
Container builds share the task's CPU and memory; use an appropriately sized
sandbox for larger images or multi-service stacks. E2B template resources are
fixed at build time, so Roomote's template uses 8 GiB for every task.
## Verify setup
1. save `E2B_API_KEY`
2. select E2B as the default sandbox provider
3. start a small task from an environment
4. confirm the task starts, streams logs, and can run project commands
5. verify preview links if the task starts a web app
## Common issues
* **Preview links fail.** Confirm the deployment URL and preview proxy are
reachable from hosted sandboxes.
# Modal
Source: https://docs.roomote.dev/providers/compute/modal
Run Roomote tasks on Modal-hosted sandboxes with snapshot support.
Modal is a hosted sandbox provider for running task sandboxes away from the
Roomote server. It is a good fit when you want provider-managed sandbox
infrastructure, better isolation from the app host, and snapshot-capable
resume flows.
## When to use Modal
Use Modal when:
* several people may run tasks at the same time
* task work should not consume CPU or memory on the Roomote host
* you want hosted sandboxes with snapshot support
* you can provide Modal credentials
## Configuration
Add Modal from **Settings > Sandboxes**, or provide the values as deployment env
vars:
```sh theme={null}
MODAL_TOKEN_ID=...
MODAL_TOKEN_SECRET=...
```
Optional values:
```sh theme={null}
MODAL_ENDPOINT=...
MODAL_ENVIRONMENT=...
MODAL_APP_NAME=...
# Optional sandbox placement; also available as Advanced infrastructure in
# Settings > Sandboxes. Comma-separated Modal regions, for example us or us-west.
MODAL_REGIONS=us
```
`MODAL_REGIONS` is an optional comma-separated list of Modal container placement
regions (for example `us`, `us-west`, or `us,eu`). When unset, Modal chooses
placement. Prefer broader tokens such as `us` for capacity and cold-start
behavior. Pinning a region can add a Modal pricing multiplier and only applies
to newly created or resumed sandboxes, not sandboxes that are already running.
Environments with
[Docker projects](/environments/definition#docker-projects) automatically
use Modal's beta VM sandbox runtime so Docker and Docker Compose can run inside
the task. Roomote starts Docker as the VM sandbox's primary service and requests
2 CPU cores and 8 GiB of memory for these tasks. Other Modal tasks use the
standard sandbox runtime with 2 CPU cores and 4 GiB of memory.
Container builds and services share the task sandbox's CPU and memory.
## Verify setup
1. save Modal credentials
2. select Modal as the default sandbox provider
3. start a small task from an environment
4. confirm the task starts, streams logs, and can run project commands
5. try resuming or following up on a task that can use a saved snapshot
Modal-backed task snapshots remain eligible for resume until Modal removes the
underlying snapshot; Roomote does not apply its seven-day application expiry to
them. Provider availability and capacity can still prevent a resume. Other
providers may use a bounded retention window, so treat a restorable snapshot in
the task view as the source of truth.
## Common issues
* **Tasks fail immediately after launch.** Check `MODAL_TOKEN_ID`,
`MODAL_TOKEN_SECRET`, and any Modal environment or endpoint overrides.
# Amazon Bedrock
Source: https://docs.roomote.dev/providers/inference/amazon-bedrock
Connect Roomote to native Amazon Bedrock and Bedrock Mantle models.
Amazon Bedrock provides managed access to models from multiple model developers
inside AWS. Roomote supports both native Bedrock Runtime models and models
served through Bedrock's Mantle endpoints. Both use a Bedrock API key, so setup
does not require long-lived IAM access-key and secret-key credentials.
## Get a Mantle API key
Open the [Bedrock API keys console](https://us-east-1.console.aws.amazon.com/bedrock-mantle/api-keys)
and generate a key. Select the AWS region where you intend to use Bedrock before
creating it; model availability and the key are region-dependent.
## Configuration
Add **Amazon Bedrock** in **Settings > Models**, enter the Mantle API key, and
optionally specify its AWS region. Environment-variable configuration uses:
```sh theme={null}
AWS_BEARER_TOKEN_BEDROCK=...
AWS_REGION=us-east-1
```
Roomote exposes Mantle models with the `bedrock-mantle/` prefix and OpenCode's
native Bedrock provider models with the `amazon-bedrock/` prefix. The region
defaults to `us-east-1` when omitted. Native Claude and other Bedrock Runtime
models can use regional and cross-region inference-profile prefixes, such as
`eu.`, `us.`, or `global.`. OpenAI models selected through the native provider
continue to use Mantle's Responses endpoint automatically. Enable only models
your account and configured region can access, then choose the default and role
mappings.
Roomote keeps Mantle models as the recommended defaults. Use native Bedrock
models when you need standard Bedrock Runtime behavior or a regional inference
profile that is not available through Mantle. Inference-profile ARNs are not
supported through Roomote's hosted inference gateway; use the plain model or
cross-region profile ID instead.
## Cost behavior
Bedrock bills the AWS account according to the selected model, request type,
region, and any provisioned capacity. Roomote records model usage and estimates
cost from model metadata; AWS billing remains authoritative. Review current
rates on the [Bedrock pricing page](https://aws.amazon.com/bedrock/pricing/).
## Verify setup
1. save the Mantle API key and matching region
2. confirm Amazon Bedrock models appear in **Settings > Models**
3. enable a Mantle or native model available in that region and assign it to a role
4. run a small task and confirm usage appears in the task and AWS account
## Common issues
* **The key is rejected.** Confirm it is a Bedrock Mantle API key, not an AWS
access key, and that it was created in the configured region.
* **A model fails although it is listed.** Confirm the model is available to
your AWS account in `AWS_REGION` and that any required model access is enabled.
* **A native Anthropic model is denied.** Complete Anthropic's first-time-use
and AWS Marketplace access requirements for Bedrock Runtime. These
requirements do not apply to the same model through Mantle.
* **Costs differ from Roomote's estimate.** AWS may apply regional, caching,
provisioned-throughput, or model-specific pricing that changes independently.
# Anthropic
Source: https://docs.roomote.dev/providers/inference/anthropic
Use Anthropic API models directly for Roomote tasks and model roles.
Anthropic provides direct API access to Claude models. Choose this provider when
you want Anthropic billing and rate limits without routing requests through a
multi-provider gateway.
## Get an API key
Create a key in the [Anthropic Console](https://console.anthropic.com/settings/keys).
The organization that owns the key must have billing and model access enabled.
## Configuration
Add **Anthropic** in **Settings > Models** and paste the key, or configure:
```sh theme={null}
ANTHROPIC_API_KEY=...
```
Roomote adds a recommended Claude model set after the provider connects. Model
IDs use the `anthropic/` prefix. You can keep one Claude model for every role or
use a faster model for helper and explore work and a stronger model for coding,
planning, and review.
## Cost behavior
Anthropic charges the account for input and output tokens, with model-specific
pricing and possible differences for features such as prompt caching. Roomote
records token usage and estimates cost from its current model metadata. The
[Anthropic pricing page](https://www.anthropic.com/pricing#api) and console bill
are the source of truth.
## Verify setup
1. save `ANTHROPIC_API_KEY`
2. confirm recommended Anthropic models appear and enable at least one
3. assign an `anthropic/...` model as the coding model or another role
4. run a small task and check that it completes and reports token usage
## Common issues
* **Authentication fails.** Recreate the key and confirm it belongs to the
organization with active API billing.
* **A model is unavailable.** Confirm the model is available to the key's
organization, then refresh model metadata in Roomote.
* **Requests are rate-limited.** Check the Anthropic Console limits and reduce
concurrent work or request a higher usage tier.
# Azure AI Foundry
Source: https://docs.roomote.dev/providers/inference/azure-foundry
Run supported GPT deployments from Azure AI Foundry in Roomote tasks.
Azure AI Foundry provides model deployments through Azure AI Services resources.
Roomote supports API-key authentication for resources at
`https://.cognitiveservices.azure.com`.
## Prerequisites
Before connecting Azure AI Foundry, create:
* an Azure AI Services resource in Azure AI Foundry
* an API key for that resource
* a deployment for every model you intend to use
The **deployment name must exactly match the model ID** expected by OpenCode.
For example, using `azure-cognitive-services/gpt-5.6-terra` requires a
deployment named `gpt-5.6-terra`.
## Configuration
Add **Azure AI Foundry** in **Settings > Models**, then enter the API key and
resource name shown in the Azure portal. Enter the resource name only, not the
full endpoint URL.
Environment-variable configuration uses:
```sh theme={null}
AZURE_COGNITIVE_SERVICES_API_KEY=...
AZURE_COGNITIVE_SERVICES_RESOURCE_NAME=my-resource
```
Roomote adds recommended GPT models under the `azure-cognitive-services/`
prefix. In gateway mode, the API key stays on the Roomote control plane and
model requests are proxied to the configured Foundry resource. The non-secret
resource name remains available to the task runtime so OpenCode can initialize
the provider.
## Verify setup
1. save the API key and resource name
2. confirm each Foundry deployment name matches its model ID
3. enable an `azure-cognitive-services/...` model and assign it to a role
4. run a small task and confirm usage appears for the Azure resource
## Common issues
* **The resource cannot be reached.** Enter only the resource name, such as
`my-resource`, without a URL, path, or domain.
* **Azure reports that the deployment does not exist.** Rename or recreate the
deployment so its name exactly matches the model ID.
* **A non-GPT catalog model fails through the gateway.** This provider's
first-class gateway support covers the default Azure OpenAI SDK route. Use
direct mode for models whose Azure catalog entry uses another SDK or host.
# Azure OpenAI
Source: https://docs.roomote.dev/providers/inference/azure-openai
Run OpenAI models from an Azure OpenAI resource in Roomote tasks.
Azure OpenAI serves OpenAI models from a resource in your Azure subscription.
Roomote supports API-key authentication for resources at
`https://.openai.azure.com`.
## Prerequisites
Before connecting Azure OpenAI, create:
* an Azure OpenAI resource
* an API key for that resource
* a deployment for every model you intend to use
The **deployment name must exactly match the model ID** expected by OpenCode.
For example, using `azure/gpt-5.6-terra` requires a deployment named
`gpt-5.6-terra`.
## Configuration
Add **Azure OpenAI** in **Settings > Models**, then enter the API key and the
resource name from the Azure portal. The resource name is the first hostname
segment, not a full URL.
Environment-variable configuration uses:
```sh theme={null}
AZURE_API_KEY=...
AZURE_RESOURCE_NAME=my-resource
```
Roomote adds recommended GPT models under the `azure/` prefix. In gateway mode,
the API key stays on the Roomote control plane and model requests are proxied to
the configured Azure resource. The non-secret resource name remains available
to the task runtime so OpenCode can initialize the provider.
## Verify setup
1. save the API key and resource name
2. confirm each Azure deployment name matches its model ID
3. enable an `azure/...` model and assign it to a role
4. run a small task and confirm usage appears for the Azure resource
## Common issues
* **The resource cannot be reached.** Enter only the resource name, such as
`my-resource`, without a URL, path, or domain.
* **Azure reports that the deployment does not exist.** Rename or recreate the
deployment so its name exactly matches the model ID.
* **Authentication fails.** Confirm the key belongs to the configured Azure
OpenAI resource and has not been regenerated.
# Baseten
Source: https://docs.roomote.dev/providers/inference/baseten
Route Roomote tasks to supported foundation models through Baseten.
Baseten is a hosted inference platform for deploying and serving open and custom
models. Roomote's built-in provider exposes a curated set of Baseten-hosted
models through the standard Models workflow.
## Get an API key
Create a key from [Baseten API key settings](https://app.baseten.co/settings/api_keys).
Use a key from the workspace that has access to the models you plan to enable.
## Configuration
Add **Baseten** in **Settings > Models** and paste the key, or configure:
```sh theme={null}
BASETEN_API_KEY=...
```
Roomote adds its recommended Baseten models after connection. Their IDs use the
`baseten/` prefix. Enable only models available to the key's workspace and set
the coding and specialized role mappings you want.
## Cost behavior
Baseten billing depends on the model endpoint and whether it uses serverless or
dedicated deployment capacity. Roomote records model usage and estimates costs
when catalog pricing is available, but the Baseten workspace bill is
authoritative. See [Baseten pricing](https://www.baseten.co/pricing/) for current
compute and inference terms.
## Verify setup
1. save `BASETEN_API_KEY`
2. confirm Baseten models appear in **Settings > Models**
3. enable one model and assign it as the coding model
4. run a small task and confirm the request appears in Baseten observability
## Common issues
* **Authentication fails.** Confirm the key is active and belongs to the
intended Baseten workspace.
* **A model cannot run.** Verify that the workspace can access that foundation
model or deployment and refresh Roomote's model metadata.
* **Cold requests are slow.** Check the endpoint's autoscaling and minimum
replica settings in Baseten; Roomote does not control model replicas.
# ChatGPT Subscription
Source: https://docs.roomote.dev/providers/inference/chatgpt
Connect an eligible ChatGPT subscription to Roomote through OpenAI sign-in.
The ChatGPT subscription provider lets Roomote use supported coding models under
an eligible ChatGPT account. It is separate from the [OpenAI API
provider](/providers/inference/openai): it uses subscription sign-in and plan
limits instead of an `OPENAI_API_KEY` and API usage billing.
If you are choosing between a subscription and an API key, start with [Use your
ChatGPT subscription with Roomote](/use-chatgpt-subscription).
## Connect a subscription
Add **ChatGPT (subscription)** in **Settings > Models** and follow the OpenAI
device authorization flow. Sign in with the ChatGPT account whose subscription
you want Roomote to use. No API key or deployment environment variable is
required.
Roomote stores and refreshes the authorization securely. Connected models retain
the `openai/` model prefix, so the Models page identifies the active connection
rather than creating a separate model namespace.
## Cost behavior
Requests count against the included limits of the connected ChatGPT plan rather
than an OpenAI API balance. Roomote shows the provider-reported 5-hour and weekly
usage windows when available. These values come from an unofficial OpenAI usage
endpoint and may temporarily disappear without blocking tasks. Review plan terms
on [ChatGPT pricing](https://chatgpt.com/pricing).
## Verify setup
1. complete the device authorization flow
2. confirm ChatGPT shows as connected in **Settings > Models**
3. enable a supported `openai/...` model and assign it to a role
4. run a small task and confirm the subscription usage display updates
## Common issues
* **Authorization expires or fails.** Use **Reconnect** and finish the device
flow with the same eligible ChatGPT account.
* **Usage is not displayed.** The unofficial usage endpoint may be unavailable;
this does not necessarily mean model access is disconnected.
* **A plan limit is reached.** Wait for the displayed window to reset or connect
the OpenAI API provider for separately billed capacity.
# GitHub Copilot
Source: https://docs.roomote.dev/providers/inference/github-copilot
Use models included with an eligible GitHub Copilot account in Roomote.
GitHub Copilot gives Roomote access to supported models through a user's active
Copilot plan. This inference connection is independent of Roomote's [GitHub
source-control app](/providers/source-control/github).
## Connect GitHub Copilot
Add **GitHub Copilot** in **Settings > Models** and follow the GitHub device-code
flow. Sign in to a GitHub account with an active Copilot plan and approve the
connection. See [GitHub Copilot plans and setup](https://docs.github.com/en/copilot)
if the account does not have access yet.
No API key or environment variable is required. Roomote stores the OAuth record
and exposes supported models with the `github-copilot/` prefix.
GPT-6 Astra is available as `github-copilot/gpt-6-astra`. Enable it in
**Settings > Models** and assign it to a role or select it for a task or Session.
Existing defaults stay unchanged. Availability depends on your Copilot plan and
organization's model-access policy.
## Cost behavior
Requests use the connected Copilot plan. For qualifying legacy annual Pro and
Pro+ plans, some models consume premium requests according to GitHub's
multipliers, and Roomote shows the remaining legacy quota when GitHub returns
it. Other current plans use GitHub AI Credits. GitHub billing and [Copilot plan
details](https://github.com/features/copilot/plans) are authoritative.
## Verify setup
1. complete the GitHub device-code flow
2. confirm GitHub Copilot shows as connected
3. enable a `github-copilot/...` model and assign it to a role
4. run a small task and check the plan-usage line when available
## Common issues
* **GitHub authorizes but Roomote reports no Copilot access.** Confirm the signed-in
account has an active individual or organization-provided Copilot seat.
* **A model is unavailable.** Model availability and premium multipliers vary by
plan; select another supported model or check the organization's Copilot policy.
* **The connection stops working.** Reconnect if GitHub revoked or expired the
device authorization.
# Google Gemini
Source: https://docs.roomote.dev/providers/inference/google-gemini
Use Google Gemini API models directly through an AI Studio key.
Google Gemini provides direct API access to Gemini models. Use it when you want
Google-managed inference without routing through another gateway.
## Get an API key
Create a key in [Google AI Studio](https://aistudio.google.com/app/apikey). The
key's Google Cloud project must have the Gemini API available and any required
billing configured.
## Configuration
Add **Google Gemini** in **Settings > Models** and paste the key, or configure:
```sh theme={null}
GEMINI_API_KEY=...
```
Roomote adds recommended Gemini models under the `google/` prefix. A practical
mapping uses a Pro model for coding and planning and a Flash model for helper
and explore work. Refresh model metadata after Google changes preview model IDs.
## Cost behavior
Google applies model-specific input, output, caching, and context pricing. Some
projects may have free-tier quotas, but production workloads should not assume
free capacity. Roomote records usage and estimates model cost; Google Cloud
billing and [Gemini API pricing](https://ai.google.dev/gemini-api/docs/pricing)
remain authoritative.
## Verify setup
1. save `GEMINI_API_KEY`
2. confirm Gemini models appear in **Settings > Models**
3. enable a model and assign it to the coding or another role
4. run a small task and confirm usage reaches the key's Google Cloud project
## Common issues
* **The key is rejected.** Confirm it came from AI Studio and that the Gemini
API is available in the associated project.
* **A preview model stops resolving.** Refresh model metadata and select its
current replacement; Google periodically retires preview IDs.
* **Quota errors occur.** Check project quota and billing in Google AI Studio or
Google Cloud, then reduce concurrency or request more quota.
# Kimi for Coding
Source: https://docs.roomote.dev/providers/inference/kimi-for-coding
Connect a Kimi for Coding membership key and use its included coding models.
Kimi for Coding is Moonshot AI's membership-based coding service. Its keys use a
dedicated coding endpoint and are not interchangeable with Moonshot Open
Platform API keys.
## Get a membership key
Activate a Kimi for Coding membership, then create a key in the
[Kimi Code console](https://www.kimi.com/code/console). Use the separate
[Moonshot AI provider](/providers/inference/moonshot-ai) for keys created at
`platform.kimi.ai`.
## Configuration
Add **Kimi for Coding** in **Settings > Models** and paste the membership key,
or configure:
```sh theme={null}
KIMI_API_KEY=...
```
Roomote exposes supported models under the `kimi-for-coding/` prefix. The
recommended mappings can use Kimi's stronger model for coding, vision, planning,
and review while assigning its faster coding model to helper and explore work.
## Cost behavior
Requests consume the allowance included with the Kimi for Coding membership,
not a Moonshot Open Platform API balance. Roomote displays the provider-reported
usage window when the Kimi service returns it. Plan limits and renewal behavior
in the Kimi Code console are authoritative.
## Verify setup
1. save `KIMI_API_KEY`
2. confirm Kimi for Coding models appear in **Settings > Models**
3. apply a recommended mapping or assign one model manually
4. run a small task and confirm the membership usage display updates
## Common issues
* **The key is rejected.** Confirm it came from the Kimi Code console after
membership activation, not the Moonshot Open Platform.
* **The allowance is exhausted.** Wait for the plan window to reset or change
to a separately billed inference provider.
* **Usage is missing.** Kimi's usage endpoint can change or be unavailable;
model requests may still work normally.
# LiteLLM
Source: https://docs.roomote.dev/providers/inference/litellm
Route Roomote model calls through a LiteLLM gateway.
LiteLLM is an OpenAI-compatible inference gateway. Use it when you want one
deployment-owned endpoint to route Roomote tasks to different model vendors,
apply gateway policies, or centralize model credentials and spend controls.
## Configure LiteLLM
In **Settings > Models**, add LiteLLM and provide its endpoint URL and API key.
You can instead manage both values as deployment environment variables:
```sh theme={null}
LITELLM_BASE_URL=https://litellm.example.com/v1
LITELLM_API_KEY=...
```
`LITELLM_API_KEY` is required. The endpoint must be reachable from the Roomote
deployment. For a Compose deployment, use a service DNS name such as
`http://litellm:4000/v1` when LiteLLM runs on the same private network. Do not
use `localhost` unless LiteLLM runs in the same network namespace as the
Roomote service that proxies inference requests.
After saving the provider, Roomote discovers the models exposed by the gateway.
Enable the models you want and select a default coding model and any specialized
roles. Model IDs use the `litellm/` form, where `` is the
name configured by your gateway.
### LiteLLM proxy flags
Start LiteLLM with the configuration and network settings appropriate for your
deployment. A typical proxy command supplies a config file and listen port:
```sh theme={null}
litellm --config /path/to/config.yaml --port 4000
```
Use LiteLLM's master-key configuration to require the same key supplied as
`LITELLM_API_KEY`, and configure model aliases and pricing in the LiteLLM config
file. Keep the proxy bound to a private interface unless Roomote reaches it
through a protected ingress.
## Secure the gateway
Keep LiteLLM private to Roomote whenever possible. Put it on an internal network
or behind a private ingress, require its API key, and use TLS when traffic
crosses an untrusted network. Store `LITELLM_API_KEY` in your deployment secret
manager or as an encrypted Roomote deployment variable, not in an environment's
task variables or repository files.
Roomote proxies model traffic through its inference gateway, so task sandboxes
do not need direct network access to LiteLLM or the gateway key. Restrict the
gateway key to the model access and spend limits Roomote needs.
## Cost behavior
LiteLLM can calculate and return usage costs for requests it routes. When your
LiteLLM model catalog has pricing configured, Roomote can show that
gateway-reported cost alongside task usage. LiteLLM remains the source of truth
for its budgets, rate limits, provider billing, and any model-specific pricing
overrides.
## Verify setup
1. save the endpoint URL and API key
2. confirm models appear in **Settings > Models**
3. enable one model and make it the default coding model
4. start a small Roomote task and confirm it completes through the gateway
5. check LiteLLM logs and usage data for the request
## Common issues
* **No models appear.** Confirm the endpoint URL includes the LiteLLM `/v1`
API path and that the API key can list models.
* **Tasks cannot reach LiteLLM.** Check DNS, container networking, firewall
rules, and whether the endpoint is reachable from the Roomote deployment.
* **Costs are missing or unexpected.** Check LiteLLM's model pricing and
routing configuration; local gateway settings can override upstream defaults.
# MiniMax
Source: https://docs.roomote.dev/providers/inference/minimax
Use MiniMax API models directly for Roomote coding tasks.
MiniMax provides hosted language models through its API platform. Roomote's
direct provider is useful when you want MiniMax billing and model access without
a multi-provider gateway.
## Get an API key
Create a key from the [MiniMax API platform](https://platform.minimax.io/user-center/basic-information/interface-key).
Make sure the account has an active balance or plan for the models you intend to
use.
## Configuration
Add **MiniMax** in **Settings > Models** and paste the key, or configure:
```sh theme={null}
MINIMAX_API_KEY=...
```
Roomote adds supported models with the `minimax/` prefix. Enable the recommended
coding model, assign it to the roles you want, and refresh metadata when MiniMax
publishes a replacement model ID.
## Cost behavior
MiniMax charges the connected account according to its current API plan and
model token pricing. Roomote records usage and estimates cost from model
metadata; the MiniMax console balance and [pricing documentation](https://platform.minimax.io/docs/guides/pricing-paygo)
are authoritative.
## Verify setup
1. save `MINIMAX_API_KEY`
2. confirm MiniMax models appear in **Settings > Models**
3. enable a model and assign it as the coding model
4. run a small task and check usage in Roomote and the MiniMax console
## Common issues
* **Authentication fails.** Confirm the key belongs to the international API
platform expected by the provider and has not been revoked.
* **Requests fail for insufficient balance.** Add credit or activate the required
plan in MiniMax.
* **A model ID no longer works.** Refresh model metadata and select the current
supported MiniMax model.
# Moonshot AI (Kimi)
Source: https://docs.roomote.dev/providers/inference/moonshot-ai
Use Kimi models through the metered Moonshot AI Open Platform API.
Moonshot AI provides metered API access to Kimi models through its Open
Platform. This connection is separate from the membership-based [Kimi for
Coding](/providers/inference/kimi-for-coding) service.
## Get an API key
Create a key on the [Kimi API Platform keys page](https://platform.kimi.ai/console/api-keys).
Do not paste a Kimi for Coding membership key here; the two services use
different endpoints and billing.
## Configuration
Add **Moonshot AI (Kimi)** in **Settings > Models** and paste the Open Platform
key, or configure:
```sh theme={null}
MOONSHOT_API_KEY=...
```
Models use the `moonshotai/` prefix. Roomote recommends available Kimi coding
models and can map a multimodal model to vision, planning, and review roles.
## Cost behavior
Open Platform requests draw from the account's API balance and are billed by
model usage. This is independent of any Kimi for Coding membership allowance.
Roomote records token usage and estimates cost from model metadata; the Kimi API
Platform balance and published pricing are authoritative.
## Verify setup
1. save `MOONSHOT_API_KEY`
2. confirm Moonshot AI models appear in **Settings > Models**
3. enable a `moonshotai/...` model and assign it to a role
4. run a small task and confirm usage appears in the Open Platform console
## Common issues
* **The key is rejected.** Confirm it was created at `platform.kimi.ai`, not in
the Kimi Code membership console.
* **The balance does not change as expected.** Check that the selected model has
the `moonshotai/` prefix rather than another gateway's Kimi model.
* **A model lacks a required capability.** Choose a Kimi model that supports the
task's tool calling, context, or image-input requirements.
# Ollama
Source: https://docs.roomote.dev/providers/inference/ollama
Use locally or privately served Ollama models with Roomote.
Ollama serves models on infrastructure you control. Use it for local
development, private deployments, or workloads where you want to keep inference
inside your own network.
## Configure Ollama
In **Settings > Models**, add Ollama and provide the endpoint URL. Ollama does
not require an API key. You can also set the endpoint as a deployment variable:
```sh theme={null}
OLLAMA_BASE_URL=http://ollama:11434
```
Use the Ollama service root, not its `/v1` path. The local default is
`http://127.0.0.1:11434`; in a container deployment, use a hostname that
Roomote can resolve, such as `http://ollama:11434`.
After saving the provider, Roomote discovers available Ollama models. Enable the
models you need and select them using `ollama/`, for example
`ollama/qwen3-coder`.
## Connectivity and security
The Ollama endpoint must be reachable from the Roomote deployment. It does
not need to be exposed to every Roomote task sandbox. When Roomote and Ollama
run in separate containers, `127.0.0.1` points to the Roomote container, not
the Ollama container; use a shared network and service DNS instead.
Ollama normally accepts unauthenticated requests. Keep it bound to loopback or
a private network, and do not publish it directly to the internet. If traffic
must leave a trusted network, place a TLS-terminating, authenticated proxy in
front of Ollama and point Roomote at that private or protected endpoint.
### Ollama listen address
Ollama listens only where its `OLLAMA_HOST` setting permits. To make it
reachable by another container on a private network, configure a listen address
that accepts the network connection, for example:
```sh theme={null}
OLLAMA_HOST=0.0.0.0:11434 ollama serve
```
Do not use a public bind address without a protected reverse proxy or equivalent
network controls. Keep `OLLAMA_BASE_URL` pointed at the private service URL.
## Cost behavior
Ollama does not charge a per-token provider price for locally served models.
Roomote can record model usage, but it cannot infer your hardware, electricity,
hosting, or capacity costs. Monitor GPU utilization and infrastructure spend
separately when comparing Ollama with hosted providers.
## Verify setup
1. pull a model with Ollama and confirm it appears in `ollama list`
2. save `OLLAMA_BASE_URL` or the equivalent Settings value
3. confirm the model appears in **Settings > Models**
4. enable it, make it the default coding model, and start a small task
## Common issues
* **The model list is empty.** Confirm Ollama is running, the model is pulled,
and Roomote can reach the configured endpoint.
* **Connection refused in Docker.** Use the Ollama service name instead of
`127.0.0.1`, and confirm both services share a network.
* **Responses are slow or fail under load.** Choose a smaller model, add GPU
capacity, or reduce concurrent task demand.
# OpenAI
Source: https://docs.roomote.dev/providers/inference/openai
Use OpenAI API models with separately billed API capacity.
The OpenAI provider gives Roomote direct, usage-billed API access to supported
OpenAI models. It is separate from [ChatGPT Subscription](/providers/inference/chatgpt),
which uses an eligible ChatGPT plan instead of API credits.
## Get an API key
Create a key on the [OpenAI API keys page](https://platform.openai.com/api-keys).
The key's project must have billing, model access, and suitable usage limits.
## Configuration
Add **OpenAI** in **Settings > Models** and paste the key, or configure:
```sh theme={null}
OPENAI_API_KEY=...
```
Roomote adds recommended models under the `openai/` prefix. Apply a recommended
mapping or choose separate models for coding, helper, planning, and review work.
When both OpenAI API and ChatGPT Subscription are connected, they expose the
same model prefix and Roomote uses the subscription. Disconnect ChatGPT
Subscription before using billed OpenAI API capacity.
## Cost behavior
OpenAI API requests are billed to the API project by model and token usage; a
ChatGPT Plus or Pro subscription does not include API credits. Roomote records
usage and estimates cost from model metadata. The [OpenAI API pricing page](https://openai.com/api/pricing/)
and project bill are authoritative.
## Verify setup
1. save `OPENAI_API_KEY`
2. confirm OpenAI models appear and enable at least one
3. assign an `openai/...` model to a role
4. run a small task and confirm usage appears in the OpenAI project
## Common issues
* **The key works elsewhere but not in Roomote.** Disconnect ChatGPT Subscription
first, then confirm the API key is active and its project has API billing.
* **Quota or rate-limit errors occur.** Check project spend limits, usage tier,
and model-specific limits in the OpenAI Platform.
* **The wrong connection is used.** If ChatGPT Subscription is also connected,
disconnect the subscription before using billed OpenAI API capacity.
# OpenAI-compatible
Source: https://docs.roomote.dev/providers/inference/openai-compatible
Connect one or more OpenAI API endpoints as Roomote inference providers.
OpenAI-compatible is the generic option for any server that implements the
OpenAI `/v1` API. Use it for LiteLLM proxies, vLLM, local OpenAI servers, or
other OpenAI-shaped gateways when you do not need a provider-specific setup page.
You can connect **multiple** OpenAI-compatible endpoints. Each connection needs
a name so Roomote can keep their credentials, discovered models, and model ids
separate.
## Configure an OpenAI-compatible endpoint
In **Settings > Models**, add **OpenAI-compatible**, enter a connection name
(for example `company-proxy`), and provide the endpoint URL. An API key is
optional and only needed when your endpoint requires bearer auth.
Roomote stores each connection under namespaced deployment variables derived
from the connection name. For a connection named `company-proxy`:
```sh theme={null}
OPENAI_COMPATIBLE_COMPANY_PROXY_BASE_URL=https://proxy.example.com/v1
OPENAI_COMPATIBLE_COMPANY_PROXY_API_KEY=...
OPENAI_COMPATIBLE_COMPANY_PROXY_LABEL=company-proxy
```
The endpoint must be reachable from the Roomote deployment. For a Compose
deployment, use a service DNS name such as `http://litellm:4000/v1` when the
proxy runs on the same private network. Do not use `localhost` unless the
endpoint runs in the same network namespace as the Roomote service that proxies
inference requests.
After saving the provider, Roomote discovers models from `/v1/models`. Enable
the models you want and select a default coding model and any specialized roles.
Model IDs use the `openai-compatible-/` form, where
`` is the slug from the connection name and `` is the
name returned by your endpoint.
## When to use this versus LiteLLM, Ollama, or vLLM
Choose **OpenAI-compatible** when you want one clear setup path for any OpenAI
API endpoint, or when you need several custom endpoints side by side. Choose the
named LiteLLM, Ollama, or vLLM providers when you prefer those labels or their
dedicated env var names. Runtime discovery and chat completion behavior are the
same OpenAI `/v1` protocol for all of them.
## Secure the endpoint
Keep the endpoint private to Roomote whenever possible. Put it on an internal
network or behind a private ingress, require an API key when the server supports
it, and use TLS when traffic crosses an untrusted network. Store connection API
keys in your deployment secret manager or as encrypted Roomote deployment
variables, not in an environment's task variables or repository files.
Roomote proxies model traffic through its inference gateway, so task sandboxes
do not need direct network access to the endpoint or the API key.
## Verify setup
1. add OpenAI-compatible with a connection name, endpoint URL, and optional API key
2. confirm models appear in **Settings > Models** under that connection
3. enable one model and make it the default coding model
4. start a small Roomote task and confirm it completes through the endpoint
5. check the upstream server logs for the request
## Common issues
* **No models appear.** Confirm the endpoint URL includes the OpenAI `/v1` API
path and that the API key can list models when auth is required.
* **Tasks cannot reach the endpoint.** Check DNS, container networking, firewall
rules, and whether the endpoint is reachable from the Roomote deployment.
* **Tool calling fails.** Roomote needs models that support tool calling. Confirm
the upstream model and gateway configuration expose tools over chat completions.
* **Two endpoints collide.** Give each OpenAI-compatible connection a distinct
name so their env vars and `openai-compatible-/...` model ids stay unique.
# OpenCode Zen
Source: https://docs.roomote.dev/providers/inference/opencode
Use OpenCode's routed Zen model service with Roomote.
OpenCode Zen provides an OpenCode-managed catalog of coding models behind one
account and API key. Use this provider when you want OpenCode routing and
billing rather than separate credentials for each upstream model company.
## Get an API key
Sign in to [OpenCode](https://opencode.ai/) and create or copy an API key for
your Zen account. The account must have an active balance that can use the
selected models.
## Configuration
Add **OpenCode Zen** in **Settings > Models** and paste the key, or set:
```sh theme={null}
OPENCODE_API_KEY=...
```
Roomote exposes routed Zen models under the `opencode/` prefix and adds a recommended
set after connection. The preset can use inexpensive routed models for helper
work and stronger models for coding, planning, vision, and review.
GPT-6 Astra is available as `opencode/gpt-6-astra`. Enable it in
**Settings > Models** and assign it to a role or select it for a task or Session.
Existing defaults stay unchanged, and the Zen account must have access and
sufficient balance for the model.
## Cost behavior
OpenCode applies the pricing rules shown for Zen and the routed
model. Roomote records token usage and estimates cost from model metadata, while
the OpenCode account balance and [Zen documentation](https://opencode.ai/docs/zen/)
remain authoritative.
## Verify setup
1. save `OPENCODE_API_KEY`
2. confirm OpenCode models appear in **Settings > Models**
3. apply a preset or assign an `opencode/...` model manually
4. run a small task and confirm it appears in OpenCode usage
## Common issues
* **The key is rejected.** Confirm it is an OpenCode service key rather than a
key for one of the upstream model vendors.
* **A routed model is unavailable.** Check the model's availability and your
Zen balance, then select another model from the connected catalog.
* **Costs differ by model.** OpenCode routes multiple vendors; check the exact
`opencode/...` model rather than assuming one rate for the provider.
# OpenCode Go
Source: https://docs.roomote.dev/providers/inference/opencode-go
Use an OpenCode Go subscription with Roomote.
OpenCode Go is a subscription for a curated catalog of coding models. Use this
provider when you want Roomote tasks to consume the allowance included with
your Go plan.
## Subscribe and get an API key
Sign in to [OpenCode](https://opencode.ai/auth), subscribe to Go, and copy your
API key. OpenCode currently allows one Go subscription per workspace.
## Configuration
Add **OpenCode Go** in **Settings > Models** and paste the key, or set:
```sh theme={null}
OPENCODE_GO_API_KEY=...
```
Roomote uses a separate environment variable so Zen and Go can be configured
independently. Paste the OpenCode API key issued for the workspace; Roomote
binds it to OpenCode's `opencode-go` provider at runtime.
Go models use the `opencode-go/` prefix. Connecting the provider adds a curated
set of eligible models and recommends lower-cost options for helper work.
## Usage behavior
Requests consume the rolling and monthly allowances defined by your Go plan.
The OpenCode account console is authoritative for current usage and resets. If
you enable **Use balance** in OpenCode, requests can fall back to your Zen
balance after the included allowance is exhausted.
See [OpenCode Go documentation](https://opencode.ai/docs/go/) for current
models, limits, pricing, and retention details.
## Verify setup
1. save `OPENCODE_GO_API_KEY`
2. confirm OpenCode Go models appear in **Settings > Models**
3. apply a preset or assign an `opencode-go/...` model manually
4. run a small task and confirm it appears in OpenCode usage
## Common issues
* **The key is rejected.** Confirm the workspace has an active Go subscription
and that you copied its OpenCode API key.
* **A model is unavailable.** Go's catalog can change; select another model
shown in the OpenCode Go console.
* **Requests stop after sustained use.** Check the plan's rolling, weekly, and
monthly allowance windows in OpenCode.
# OpenRouter
Source: https://docs.roomote.dev/providers/inference/openrouter
Access models from many vendors through one OpenRouter account and key.
OpenRouter is a multi-provider inference gateway with a broad model catalog and
provider routing controls. It is Roomote's default inference option because one
connection can cover many recommended models.
## Get an API key
Create a key on the [OpenRouter keys page](https://openrouter.ai/settings/keys).
Add credits or configure the account's billing and set an optional key spending
limit before connecting it to Roomote.
## Configuration
Add **OpenRouter** in **Settings > Models** and paste the key, or configure:
```sh theme={null}
OPENROUTER_API_KEY=...
```
Models use the `openrouter//` form. Roomote adds its full curated
recommended set and offers balanced and quick-turnaround mapping presets. You
can still disable recommendations or add another OpenRouter model by slug.
## Cost behavior
OpenRouter deducts model and provider-route usage from the account balance. Its
model catalog shows current pricing and any route-specific differences. Roomote
records usage, estimates model cost, and displays the remaining key limit when
OpenRouter returns one. The [OpenRouter activity page](https://openrouter.ai/activity)
and account balance are authoritative.
## Verify setup
1. save `OPENROUTER_API_KEY`
2. confirm the recommended model list appears
3. apply a mapping preset or select a default coding model
4. run a small task and confirm the request appears in OpenRouter activity
5. check that Roomote shows a remaining key limit when the key has one
## Roomote previews inside environment tasks
When an environment task starts another Roomote deployment for development or
smoke tests, create a separate spend-capped OpenRouter key and set it as
`SANDBOX_OPENROUTER_API_KEY` under **Settings > Environments > Deployment
Environment Variables**. You can alternatively set it on the parent controller.
Do not store it in an environment definition.
The environment worker maps the value to `OPENROUTER_API_KEY` while preparing
the workspace. The nested deployment therefore uses Roomote's native OpenRouter
provider without requiring the parent's normal `OPENROUTER_API_KEY`. Configure
the nested deployment's models normally in its own Settings. The parent task's
model mapping, presets, trial provider, and role overrides are not copied into
the nested deployment.
The mapped key is available to setup commands and services in that environment
workspace, so use a capped key appropriate for sandbox access. The launcher
source variable is not exposed there. Deployment environment variable changes
apply to new tasks, so start a new task after saving or rotating the key.
## Common issues
* **The key has no usable balance.** Add credits or raise its spending limit.
* **A model has no available route.** Check provider routing, privacy settings,
and model availability in OpenRouter, or select a fallback model.
* **The credit line is absent.** Roomote only shows it when OpenRouter returns a
numeric remaining limit; uncapped keys may not display one.
# Requesty
Source: https://docs.roomote.dev/providers/inference/requesty
Route Roomote model calls through Requesty's multi-provider AI gateway.
Requesty is a multi-provider inference gateway with centralized routing,
fallbacks, usage analytics, and cost controls. Use it when you want one
connection for models from several vendors.
## Get an API key
Sign up for Requesty and create a key on the [API Keys page](https://app.requesty.ai/api-keys).
Add credits or configure billing and any key-level spending limits before
connecting the key to Roomote.
## Configuration
Add **Requesty** in **Settings > Models** and paste the key, or configure:
```sh theme={null}
REQUESTY_API_KEY=...
```
Roomote exposes its recommended Requesty models under the `requesty/`
prefix. Some model IDs include a region suffix such as `@eu`. Apply the
recommended mapping or select models individually for each role.
## Cost behavior
Requesty bills routed model usage according to the account's plan, provider
pricing, and any bring-your-own-key configuration. Roomote records token usage
and estimates model cost from metadata, but Requesty's usage dashboard and bill
are authoritative. See [Requesty pricing](https://www.requesty.ai/pricing) for
current terms.
## Verify setup
1. save `REQUESTY_API_KEY`
2. confirm Requesty models appear in **Settings > Models**
3. apply the recommended mapping or assign a model to the coding role
4. run a small task and confirm it appears in [Requesty analytics](https://app.requesty.ai/analytics)
## Common issues
* **The key is rejected.** Confirm it is active and belongs to the intended
Requesty organization.
* **A model cannot be routed.** Check model availability, approved-model rules,
routing policies, regional support, and account balance in Requesty.
* **A spending limit blocks tasks.** Raise the applicable Requesty key or
organization limit, or choose a model with available budget.
# Together AI
Source: https://docs.roomote.dev/providers/inference/together-ai
Use Together AI's hosted open-model catalog for Roomote tasks.
Together AI hosts a broad catalog of open and specialized models behind one
inference API. Roomote's direct provider exposes a curated subset suited to
coding and agent work.
## Get an API key
Create a key from [Together AI API key settings](https://api.together.ai/settings/api-keys).
Make sure the account has credits or billing enabled for the models you select.
## Configuration
Add **Together AI** in **Settings > Models** and paste the key, or configure:
```sh theme={null}
TOGETHER_API_KEY=...
```
Roomote adds supported models with the `togetherai/` prefix. Enable the models
you want and assign the default coding and specialized roles. Provider model
names are case-sensitive, so use the IDs shown in Roomote rather than typing a
similar slug from another gateway.
## Cost behavior
Together AI charges the connected account according to the selected serverless
model or dedicated endpoint. Roomote records usage and estimates cost when model
metadata includes pricing; Together AI billing and the [pricing page](https://www.together.ai/pricing)
are authoritative.
## Verify setup
1. save `TOGETHER_API_KEY`
2. confirm Together AI models appear in **Settings > Models**
3. enable one model and assign it as the coding model
4. run a small task and confirm the request appears in Together AI usage
## Common issues
* **Authentication or balance errors occur.** Confirm the key is active and the
account has enough credit.
* **A model ID is rejected.** Use the exact `togetherai/...` ID shown in Roomote;
IDs from OpenRouter or another provider are not interchangeable.
* **Requests are queued or throttled.** Check the model's serverless limits or
dedicated endpoint capacity and reduce concurrent Roomote tasks.
# Vercel AI Gateway
Source: https://docs.roomote.dev/providers/inference/vercel-ai-gateway
Route Roomote model calls through Vercel AI Gateway.
Vercel AI Gateway provides one endpoint for models from multiple vendors, with
centralized usage, budgets, and routing. Use it when your team already manages
AI access through a Vercel team or project.
## Get an API key
Follow Vercel's [AI Gateway authentication guide](https://vercel.com/docs/ai-gateway/authentication)
to create an AI Gateway API key for the intended team. Configure billing or
provider credentials in Vercel as required by the models you plan to use.
## Configuration
Add **Vercel AI Gateway** in **Settings > Models** and paste the key, or set:
```sh theme={null}
AI_GATEWAY_API_KEY=...
```
Roomote exposes supported models under the `vercel//` prefix and
adds a recommended cross-vendor set. Apply the recommended mapping or choose
models individually for each role.
GPT-6 Astra is available as `vercel/openai/gpt-6-astra`. Enable it in
**Settings > Models** and select it for the work you want it to handle; existing
defaults stay unchanged. Your Vercel gateway must allow access to that model.
## Cost behavior
Vercel records gateway usage and applies the billing terms, budgets, and
upstream provider pricing configured for the team. Roomote records token usage
and estimates model cost from metadata; Vercel's AI Gateway usage and invoice
are authoritative. See [AI Gateway pricing](https://vercel.com/docs/ai-gateway/pricing).
## Verify setup
1. save `AI_GATEWAY_API_KEY`
2. confirm Vercel models appear in **Settings > Models**
3. enable a model and assign it to the coding role
4. run a small task and confirm it appears in Vercel AI Gateway usage
## Common issues
* **The key is rejected.** Confirm it is an AI Gateway key for the intended
Vercel team, not an unrelated Vercel access token.
* **A model cannot be routed.** Check model availability, provider credentials,
budgets, and routing policy in Vercel.
* **A budget blocks tasks.** Raise the applicable Vercel budget or select a model
and provider route with available capacity.
# vLLM
Source: https://docs.roomote.dev/providers/inference/vllm
Serve OpenAI-compatible models on vLLM infrastructure for Roomote tasks.
vLLM exposes OpenAI-compatible APIs for models that you serve on your own GPU
infrastructure. Use it when you need control over model hosting, capacity, and
network placement while keeping the standard Roomote model workflow.
## Configure vLLM
In **Settings > Models**, add vLLM and provide its endpoint URL. If your vLLM
server requires bearer authentication, also provide an API key. You can manage
the same values as deployment environment variables:
```sh theme={null}
VLLM_BASE_URL=https://vllm.example.com/v1
VLLM_API_KEY=...
```
`VLLM_API_KEY` is optional only when the vLLM endpoint intentionally accepts
unauthenticated traffic. The endpoint normally includes the `/v1` API path.
After saving it, Roomote discovers the served models. Enable the models you want
and use IDs in the `vllm/` form.
### vLLM server flags
Set the served model name to the model ID you want Roomote to discover, and use
vLLM's host, port, and API-key flags to match the endpoint configuration:
```sh theme={null}
vllm serve --host 0.0.0.0 --port 8000 --api-key "$VLLM_API_KEY" \
--served-model-name
```
When vLLM is behind a reverse proxy, keep the `/v1` path available and point
`VLLM_BASE_URL` at the proxy's OpenAI-compatible API URL.
## Connectivity and security
The vLLM endpoint must be reachable from the Roomote deployment. Place a
same-host service behind a private network or connect remote infrastructure over
TLS and a restricted ingress. A task sandbox does not need direct vLLM access:
Roomote's inference gateway holds the deployment credential and proxies model
requests.
Require `VLLM_API_KEY` when the endpoint is reachable beyond a tightly
controlled private network. Store the key in your deployment secret manager or
as an encrypted Roomote deployment variable, never in a repository or task
environment. Limit inbound access to Roomote and trusted operators; OpenAI-
compatible inference endpoints are not safe to expose publicly without an
authentication and network boundary.
## Cost behavior
vLLM can report token usage, but Roomote cannot calculate the cost of hardware
you operate. Account separately for GPU instances, reserved capacity,
electricity, storage, and idle time. Use task usage to understand demand and
your infrastructure monitoring to set the cost per token or per task.
## Verify setup
1. confirm the vLLM server lists its served model at its `/v1/models` endpoint
2. save `VLLM_BASE_URL` and, when required, `VLLM_API_KEY`
3. confirm the model appears in **Settings > Models**
4. enable it, select it for a model role, and start a small task
## Common issues
* **No models appear.** Confirm the endpoint includes `/v1` and that Roomote
can call the server's models endpoint.
* **Requests return unauthorized.** Check `VLLM_API_KEY`, its bearer-token
configuration on vLLM, and any reverse-proxy authentication.
* **Tasks are slow or queue.** Check GPU memory, batch and concurrency settings,
and capacity at the vLLM server.
# xAI
Source: https://docs.roomote.dev/providers/inference/xai
Use metered Grok API access through an xAI API key.
xAI provides direct, usage-billed API access to Grok models. This connection is
separate from [xAI Grok Subscription](/providers/inference/xai-subscription),
which uses included SuperGrok or eligible X Premium+ plan capacity.
## Get an API key
Create an API key in the [xAI Console](https://console.x.ai/) and enable billing
for the account or team that should pay for Roomote usage.
## Configuration
Add **xAI** in **Settings > Models** and paste the key, or configure:
```sh theme={null}
XAI_API_KEY=...
```
Roomote exposes Grok models with the `xai/` prefix. Connecting xAI seeds
**Grok 4.6** as the default coding model, and Grok chat models released after
the connection appear automatically, without a Roomote update. Models you
disable or remove stay that way. Deployments configured only through the
`XAI_API_KEY` environment variable start picking up new models once model
settings are first saved in **Settings > Models**. If both xAI API and a Grok
subscription are connected, Roomote prefers the subscription for `xai/`
models.
## Cost behavior
API-key requests are billed by xAI according to model usage. Roomote records
tokens and estimates cost from model metadata; the xAI Console and [API pricing](https://docs.x.ai/docs/models)
are authoritative. When a subscription is also connected, requests may consume
the subscription allowance instead of API credits because it takes precedence.
## Verify setup
1. save `XAI_API_KEY`
2. confirm xAI models appear in **Settings > Models**
3. pick a Grok chat model and assign it to a role
4. run a small task and confirm usage in the xAI Console
## Common issues
* **The API key is not used.** Disconnect the Grok subscription if you want
`xai/` requests to use separately billed API capacity.
* **Authentication or credit errors occur.** Check key status, team selection,
billing, and spend limits in the xAI Console.
* **A model is unavailable.** Refresh model metadata and confirm the API account
can access the selected Grok model.
# xAI Grok Subscription
Source: https://docs.roomote.dev/providers/inference/xai-subscription
Connect an eligible SuperGrok or X Premium+ subscription to Roomote.
The xAI Grok subscription provider lets Roomote use included Grok capacity from
an eligible SuperGrok or X Premium+ account. It uses account authorization and
plan limits instead of an `XAI_API_KEY` and metered API billing.
## Connect a subscription
Add **xAI (Grok subscription)** in **Settings > Models** and complete the xAI
authorization flow with the account that owns the eligible plan. No API key or
deployment environment variable is required.
Subscription models keep the `xai/` prefix. Connecting the subscription seeds
**Grok 4.6** as the default coding model. Grok chat models that xAI publishes
after the connection appear in **Settings > Models** and the task model
switcher automatically, without a Roomote update; image and video Grok models
are omitted, and models you disable or remove stay that way. When both
subscription and [xAI API key](/providers/inference/xai) connections exist,
Roomote prefers subscription access for those models.
## Cost behavior
Requests consume the plan's included usage windows rather than an xAI API
balance. Roomote displays plan and allowance information when xAI's unofficial
CLI usage service returns it. That service can change without notice, so the
usage line may disappear even while inference still works. Your xAI or X plan
and billing page is authoritative.
## Verify setup
1. complete the xAI authorization flow
2. confirm the Grok subscription shows as connected
3. pick a Grok chat model and assign it to a role
4. run a small task and check the subscription usage display when available
## Common issues
* **Authorization succeeds but models fail.** Confirm the account has an
eligible active plan with coding or API-compatible Grok access.
* **Usage is not displayed.** The provider's unofficial usage endpoint may be
unavailable; try a task before reconnecting.
* **The allowance is exhausted.** Wait for the plan window to reset or disconnect
the subscription so a configured `XAI_API_KEY` can provide metered capacity.
# Z.AI
Source: https://docs.roomote.dev/providers/inference/zai
Use metered GLM API access from the international Z.AI or China BigModel platform.
Z.AI provides direct API access to GLM models. Roomote supports both the
international Z.AI platform and the China BigModel platform; the key and region
must match. General platform keys are separate from Coding Plan membership keys.
## Get an API key
Create an international key on the [Z.AI API keys page](https://z.ai/manage-apikey/apikey-list).
For China, create the key in the Zhipu BigModel console. Use [Z.AI Coding
Plan](/providers/inference/zai-coding-plan) for a Coding Plan membership key.
## Configuration
Add **Z.AI** in **Settings > Models**, paste the platform key, and select its
region. Environment-variable configuration uses:
```sh theme={null}
ZAI_API_KEY=...
ZAI_REGION=global # or china
```
Both values are required. Models use the `zai/` prefix; Roomote can also map a
supported GLM vision model to the vision role.
## Cost behavior
Requests consume the API balance of the matching regional platform. Roomote
records usage and estimates cost from model metadata. The selected Z.AI or
BigModel account's balance, pricing, and quota are authoritative; Coding Plan
allowances do not fund this connection.
## Verify setup
1. save `ZAI_API_KEY` with the correct `ZAI_REGION`
2. confirm Z.AI models appear in **Settings > Models**
3. enable a `zai/...` model and assign it to a role
4. run a small task and confirm usage in the matching regional console
## Common issues
* **Authentication fails.** International keys require `global`; BigModel keys
require `china`.
* **A Coding Plan key is rejected.** Connect it through the separate Z.AI Coding
Plan provider.
* **Quota display is missing.** Roomote uses an undocumented regional endpoint;
missing quota data does not necessarily mean inference is unavailable.
# Z.AI Coding Plan
Source: https://docs.roomote.dev/providers/inference/zai-coding-plan
Connect a regional Z.AI Coding Plan key and use its included GLM allowance.
Z.AI Coding Plan is a membership-based coding service for GLM models. Its keys
and included quotas are separate from usage-billed [Z.AI platform API
keys](/providers/inference/zai).
## Get a Coding Plan key
Activate a plan and follow the [Z.AI Coding Plan documentation](https://docs.z.ai/devpack/overview)
to create a key. Generate it in the same international or China region you will
select in Roomote.
## Configuration
Add **Z.AI Coding Plan** in **Settings > Models**, paste the plan key, and select
its region. Environment-variable configuration uses:
```sh theme={null}
ZAI_CODING_PLAN_API_KEY=...
ZAI_CODING_PLAN_REGION=global # or china
```
Both values are required. Models use the `zai-coding-plan/` prefix, keeping
their membership quota separate from metered `zai/` model IDs.
## Cost behavior
Requests consume the Coding Plan's included quota and reset windows rather than
a general Z.AI API balance. Roomote shows quota information when the provider's
regional monitoring endpoint returns it. The plan console remains authoritative
for allowance, renewal, overage, and regional terms.
## Verify setup
1. save the Coding Plan key and matching region
2. confirm Z.AI Coding Plan models appear
3. enable a `zai-coding-plan/...` model and assign it to a role
4. run a small task and check the quota display when available
## Common issues
* **The key is rejected.** Confirm it is a Coding Plan key, not a general API
platform key, and that the selected region matches.
* **The plan quota is exhausted.** Wait for its reset or switch the role to a
separately billed provider.
* **Quota is not displayed.** The upstream monitor endpoint is undocumented and
may be unavailable while inference continues to work.
# Azure DevOps
Source: https://docs.roomote.dev/providers/source-control/azure-devops
Configure Azure DevOps repository sync for Roomote.
Azure DevOps support uses an organization plus either a deployment-owned
personal access token, a Microsoft Entra service principal, or a delegated
Microsoft account. Choose the PAT path for the fastest setup, the service
principal path for a deployment identity, or delegated sign-in when access
should follow a specific Azure DevOps user.
## Choose an authentication method
### Personal access token
Create a dedicated Azure DevOps bot or service-account user and give it access
to the organization, projects, or repositories Roomote should use. Create a PAT
for that identity with Code read/write permissions appropriate for cloning,
branch creation, and commits. Enable Build read access for CI Failure Triage and
Work Items read access for work-item comment triggers. Grant Service Hooks read
and manage access so Roomote can configure repository, pull-request, work-item,
and build event delivery.
Save the organization and token in setup, deployment env vars, or local
`.env.local`. Onboarding only asks for those two values by default:
```sh theme={null}
ADO_ORGANIZATION=
ADO_TOKEN=
```
Optional values:
```sh theme={null}
ADO_BASE_URL=https://dev.azure.com
ADO_USERNAME=ado
ADO_CLIENT_ID=
ADO_CLIENT_SECRET=
ADO_TENANT_ID=
```
`ADO_BASE_URL` defaults to `https://dev.azure.com`. `ADO_USERNAME` defaults to
`ado` and is used as the Git-over-HTTPS username paired with the PAT.
### Microsoft Entra service principal
Instead of `ADO_TOKEN`, configure an Entra application that has been added to
the Azure DevOps organization and granted access to the required projects:
```sh theme={null}
ADO_ORGANIZATION=
ADO_CLIENT_ID=
ADO_CLIENT_SECRET=
ADO_TENANT_ID=
```
Roomote acquires short-lived bearer tokens with the client-credentials flow
and uses them for Azure DevOps REST and Git operations. `ADO_TENANT_ID` falls
back to `R_MICROSOFT_TENANT_ID` when the shared Microsoft tenant is configured.
The service principal must be explicitly added to the Azure DevOps
organization and given an appropriate access level and project permissions.
Service hook webhook secrets are generated automatically when Roomote
configures service hooks. Advanced values remain editable later in Settings →
Source Control.
#### Required API permissions
Azure DevOps does not use Microsoft Entra application permissions for service
principals. Add the service principal to the Azure DevOps organization, assign
at least **Basic** access, and grant the required project and repository
permissions in Azure DevOps.
### Connect with your Microsoft account
Choose **Connect with your Microsoft account** in setup or Settings to authorize the Azure
DevOps account that should own the deployment connection. Roomote stores the
linked account reference with the deployment and refreshes its short-lived
Entra access token as needed. The Entra client ID, client secret, and tenant ID
are still required so Roomote can refresh the connection in background jobs.
This mode uses the same app registration. Grant the linked user the required
Azure DevOps organization, project, and repository access.
Add the web redirect URI shown by Roomote to the app registration:
```text theme={null}
/api/auth/oauth2/callback/ado
```
The linked account can be reconnected or replaced later in Settings. Switching
to PAT or service-principal mode removes the inactive credential path from the
deployment configuration.
## Sync repositories
After the Azure DevOps values are available, open Settings, go to the
Environments page, and use the Source Control section's Azure DevOps sync
button. Roomote lists repositories from:
```text theme={null}
https://dev.azure.com//_apis/git/repositories?api-version=7.1
```
Roomote stores the results as Azure DevOps repository rows.
If the sync reports that Azure DevOps rejected the credential, confirm the
service principal or linked user belongs to the organization and has the
required Azure DevOps access level and project permissions.
Azure DevOps-backed tasks clone from the synced repository row, so sync must
run before launching an Azure DevOps-backed task. Worker tasks write
host- and clone-path-scoped Azure DevOps credentials into the file-backed Git
credential helper instead of exporting `ADO_TOKEN` into task shells.
## Service hooks and automations
When Azure DevOps repositories are mapped into environments, Roomote ensures
service hooks for:
* pull request created/updated and PR comments (Review Code and task follow-up)
* work item commented (`@roomote` on work items)
* build completed (CI Failure Triage on failed default-branch builds)
Service hook webhook secrets are generated automatically. The deployment API
must be reachable from Azure DevOps for those deliveries.
## Mention Roomote on pull requests and work items
Mention `@roomote` in a pull request comment or a work item comment to talk to
Roomote about it. Each pull request or work item is a Roomote Session: Roomote
reads the discussion, answers as a comment when no workspace is needed, and
otherwise starts a task on the pull request's source branch (or the project's
mapped repository for a work item) and reports back in the same discussion.
Pull request replies stay in the comment thread the mention came from. The
commenter must have a linked Azure DevOps account. Ask for a review in the
mention (for example `@roomote review this`) and Roomote runs the Review Code
automation's structured review on the current head, posts the findings on the
pull request, and reports back in the same discussion.
## Current limits
Classic TFVC repositories and non-Git build repository types are not triaged.
CI Failure Triage only investigates failed builds on each repository's default
branch, one active investigation per repository.
## Verify setup
1. sync Azure DevOps repositories from Settings
2. create or update an environment from a synced repository
3. start a small task and confirm Roomote can clone the repository
4. confirm Roomote can push a branch when the task produces changes
5. optionally enable CI Failure Triage and push a default-branch commit that
fails CI to confirm a triage task starts
# Bitbucket Cloud
Source: https://docs.roomote.dev/providers/source-control/bitbucket
Configure Bitbucket Cloud repository sync and pull request webhooks and pipeline failure triage for Roomote.
Bitbucket Cloud support uses one deployment-scoped OAuth client. The
authorized account's accessible workspaces define the repositories Roomote can
sync. Bitbucket Server and Data Center are not supported.
## Create a Bitbucket OAuth client
In the Bitbucket Cloud workspace that owns the repositories, open **Workspace
settings → Apps and features → OAuth clients**, then create an OAuth client.
Set its callback URL to:
```text theme={null}
/api/auth/oauth2/callback/bitbucket
```
Grant these scopes:
| Scope | Needed for |
| ------------------------------------- | ------------------------------------------------ |
| `account` | deployment identity |
| `repository` and `repository:write` | repository sync and Git operations |
| `pullrequest` and `pullrequest:write` | pull request workflows |
| `webhook` | automatic webhook setup |
| `pipeline` | CI Failure Triage (read pipelines and step logs) |
Save the client values in setup or deployment environment variables:
```sh theme={null}
BITBUCKET_CLIENT_ID=
BITBUCKET_CLIENT_SECRET=
```
`BITBUCKET_BASE_URL` is optional and defaults to `https://bitbucket.org`.
`BITBUCKET_WEBHOOK_SECRET` is optional; Roomote generates one when webhooks are
first configured.
## Connect and sync repositories
After saving the consumer values, an admin is redirected to Bitbucket to
authorize the deployment. The callback exchanges and encrypts the OAuth
connection, synchronizes all accessible repositories, and registers repository webhooks (including `repo:commit_status_created` and `repo:commit_status_updated` for Pipelines) before returning to setup.
Bitbucket-backed tasks use `x-token-auth` for Git HTTPS credentials. OAuth API
requests use bearer authentication.
## Mention Roomote on pull requests
Mention `@roomote` in a pull request comment to talk to Roomote about that
pull request. Each pull request is a Roomote Session: Roomote reads the
discussion, answers as a comment when no workspace is needed, and otherwise
starts a task on the pull request's source branch and reports back in the same
discussion. Mention it again to redirect it, ask a follow-up, or steer a
running task. The commenter must have a linked Bitbucket account. Ask for a
review in the mention (for example `@roomote review this`) and Roomote runs the
Review Code automation's structured review on the current head, posts the
findings on the pull request, and reports back in the same discussion.
## API-first work in Fast
With an active Bitbucket OAuth connection and a synced, active Bitbucket Cloud
repository, deployment members and admins can use Fast for bounded API operations
without a repository clone or coding task:
| Operation | Available tools |
| --------------------------------------- | ------------------------------------------------------------------------- |
| Read files and directories at a ref | `get_file`, `list_directory` |
| Search code in one connected repository | `search_code` |
| Read commit history at a ref | `list_commits` |
| Read a commit by SHA1 | `get_commit` |
| Read a PR, its diff, or its comments | `get_pull_request`, `get_pull_request_diff`, `list_pull_request_comments` |
| Change a PR title and/or description | `update_pull_request` |
| Decline a PR | `decline_pull_request` |
| Add a PR comment or reply | `add_pull_request_comment` |
Every tool requires `repositoryFullName` as `workspace/repo`. PR operations also
require `pullRequestNumber`. File and directory reads require `ref`; file reads
also require `path`. Commit history requires `ref` (a commit SHA1 or ref name),
while a single commit requires `hash` (a full or abbreviated hexadecimal SHA1,
not a branch or tag name). Prefer the full SHA1; Bitbucket resolves abbreviated
hashes and may reject ambiguous prefixes. Reading commits does not create commits.
Title/description updates accept only those fields, not state changes. Comments
use `body`; a reply additionally uses `parentCommentId` belonging to the same PR.
Writes must match the requested action, and reading a PR does not authorize changing it.
Reads are bounded: responses are limited to 1 MiB and list/search pages contain
up to 50 entries. Request another page by its positive page number when needed.
One page is not an exhaustive result. Code search accepts
plain terms (letters, digits, underscores, spaces, dots, and hyphens), not query
operators, `AND`/`OR`/`NOT`, or user-supplied repository filters. Roomote fixes the
search to the connected repository and rejects scope or identity mismatches.
Bitbucket's code search API is deprecated November 1, 2026. Roomote reports
search and response-size limitations and can use a coding task when a local
checkout is substantially more appropriate for the investigation. Focused reads
prefer APIs; broad investigations do not require an API attempt first. An
authorization or repository-scope denial must never be bypassed through a task.
The Fast API does not support reopening or merging PRs, writing files, creating
commits or PRs, or review administration such as approvals, reviewer changes, and
thread resolution. A request for an actual code review still uses Roomote's
structured review workflow; reading or summarizing a diff does not require it.
Roomote reuses its native Bitbucket API client and existing deployment OAuth token
refresh flow for these tools. No separately installed MCP server or additional
authentication is required.
## Personal account linking
Users may link personal Bitbucket accounts separately for commenter identity
and access-policy checks. Linked accounts do not provide deployment source
control credentials.
## CI Failure Triage
When enabled, Roomote triages failed default-branch Bitbucket Pipelines via `repo:commit_status_created` / `repo:commit_status_updated` webhooks and Manual Run now. Only environment-mapped repositories are included.
## Current limits
* Bitbucket Cloud only. Server and Data Center are not supported.
* One deployment OAuth connection is supported.
# Gitea
Source: https://docs.roomote.dev/providers/source-control/gitea
Configure Gitea repository sync, pull request webhooks, and Actions failure triage for Roomote.
Gitea support uses a deployment-owned OAuth application, instance URL, and
authorized service account. An operator provides the application details,
authorizes the service account, and syncs repositories from Settings.
Repository sync can also create pull request webhooks, allowing Review Code
automation and `@roomote` pull request comments to work for synced Gitea
repositories.
Use `` below for your stable public Roomote URL.
## Create a Gitea OAuth application and service account
Create a dedicated Gitea bot or service-account user and give it access to the
organizations or repositories Roomote should use. New deployments use a Gitea
1.23+ OAuth application and a dedicated service account. Create the application
with the redirect URI shown by Roomote:
```text theme={null}
/api/source-control/gitea/oauth/callback
```
Authorize it with the scopes `read:user`, `read:repository`,
`write:repository`, `write:issue`, and `read:organization`.
If Roomote should configure webhooks automatically, the service account also
needs repository admin access for the synced repositories.
Save the instance URL and OAuth application credentials in setup, deployment
env vars, or local `.env.local`:
```sh theme={null}
GITEA_BASE_URL=https://git.example.com
GITEA_CLIENT_ID=
GITEA_CLIENT_SECRET=
```
Optional values:
```sh theme={null}
GITEA_WEBHOOK_SECRET=
```
Roomote runs deployment operations as the authorized service account and uses
that login for Git-over-HTTPS credentials.
The setup flow asks for the Gitea instance URL and OAuth application
credentials, then sends the operator through the authorization flow. Roomote
generates the webhook secret during repository sync.
## Sync repositories
After the Gitea values are available, open Settings, go to the Environments
page, and use the Source Control section's Gitea sync button. Roomote lists
repositories from the Gitea API and stores them as Gitea repository rows.
Gitea-backed tasks clone from the synced repository row, so sync must run
before launching a Gitea-backed task. Worker tasks route selected Gitea HTTPS
clone traffic through a local proxy instead of exposing OAuth tokens to task
shells.
After repository sync, Roomote best-effort creates or refreshes a repository
webhook for each synced Gitea repository. The webhook target is:
```text theme={null}
/api/webhooks/gitea
```
If only loopback Roomote URLs are configured, webhook setup is skipped and
repository sync still succeeds. If `GITEA_WEBHOOK_SECRET` is missing, Roomote
generates and persists one as an encrypted deployment environment variable.
## Enable review automation
Gitea pull request reviews use the same Review Code automation targeting model
as GitHub and GitLab. After syncing repositories, associate the Gitea repository
with the intended environment and enable Review Code automation for that target.
Open or reopened PR events enqueue initial review tasks. PR sync events enqueue
delta reviews. `@roomote` comments on Gitea pull requests and issues continue
the Roomote Session for that discussion, or start one when it does not exist.
## CI Failure Triage
Associate the Gitea repository with an environment, configure the Manager
Channel destination, and enable **CI Failure Triage** under Automations.
When a Gitea Actions run fails on the repository's default branch, Roomote
launches one investigate-and-fix task for that repository. Failures outside
the default branch are ignored. Manual **Run now** inspects the latest
default-branch Actions run on the configured Gitea host only (self-managed
deployments match repository `host` against `GITEA_BASE_URL`).
Roomote reads a bounded tail of failed job logs with the deployment Gitea
credential when the Actions API exposes them. Re-sync repositories after
upgrading so webhooks include the `workflow_run` event.
## Mention Roomote on pull requests and issues
Mention `@roomote` in a pull request or issue comment to talk to Roomote about
it. Each pull request or issue is a Roomote Session: Roomote reads the
discussion, answers as a comment when no workspace is needed, and otherwise
starts a task on the pull request's head branch (or the issue's repository)
and reports back in the same discussion. Mention it again to redirect it, ask a
follow-up, or steer a running task. The commenter must have a linked Gitea
account. Ask for a review in the mention (for example `@roomote review this`)
and Roomote runs the Review Code automation's structured review on the current
head, posts the findings on the pull request, and reports back in the same
discussion.
## Current limits
Gitea OAuth applications accept one redirect URL. The setup flow configures the
deployment callback, so the same OAuth application cannot also provide personal
Gitea account linking. Pull-request comment mentions still use the Gitea webhook
sender identity and never use the deployment service-account grant to identify
the commenter.
## Verify setup
1. sync Gitea repositories from Settings
2. create or update an environment from a synced repository
3. start a small task and confirm Roomote can clone the repository
4. open or update a pull request and confirm configured review automation runs
5. optionally enable CI Failure Triage and push a failing default-branch Actions
run to confirm triage starts
# GitHub
Source: https://docs.roomote.dev/providers/source-control/github
Configure a GitHub App so Roomote can sync repositories, clone code, and work with pull requests.
Use GitHub when your Roomote environments should come from GitHub repositories.
Roomote uses a GitHub App installation token to sync repositories, clone code,
push branches, and work with pull requests.
Use `` below for your stable public Roomote URL.
## Fast path
Open `/setup` and complete the short account and inference bootstrap. In the
setup conversation, choose GitHub in the source-control card, open its
configuration dialog, and click **Create GitHub App**. Roomote sends GitHub a
manifest with the callback, webhook, permissions, and events preconfigured.
After GitHub redirects back, Roomote saves the generated app ID, app slug,
OAuth client credentials, webhook secret, and private key, then sends you to
install the app on repositories. You pick the account or organization to
install on during that install step.
By default the app is created on your personal GitHub account and marked as
installable on any account, so you can install it on any organization you
belong to. If your organization should own the app instead, click **Show
advanced config** and enter the organization name before clicking **Create
GitHub App**.
Use the manual steps only when you already have a GitHub App or want to manage
these values in deployment environment variables yourself.
## Manual GitHub App setup
1. Go to [GitHub App settings](https://github.com/settings/apps/new). For an
organization-owned app, use the organization's **Developer settings > GitHub
Apps > New GitHub App** page.
2. Set **GitHub App name** to a unique name.
3. Keep **Identifying and authorizing users** enabled.
4. Set **Homepage URL** to ``.
5. Set **Setup URL** to:
```text theme={null}
/github/callback
```
6. Check **Redirect on update**.
7. Set **Callback URL** to:
```text theme={null}
/github/callback
```
8. Enable **Expire user authorization tokens**.
9. Set **Webhook URL** to:
```text theme={null}
/api/webhooks/github
```
10. Generate a webhook secret and save the same value in Roomote:
```sh theme={null}
openssl rand -hex 32
```
11. Under **Where can this GitHub App be installed?**, choose **Any account**
if you want to install the app somewhere other than the account that owns
it. **Only on this account** also works when the owning account is where
you will install it.
## Permissions and events
Grant these repository permissions:
* **Actions**: Read and write
* **Checks**: Read and write
* **Contents**: Read and write
* **Commit statuses**: Read-only
* **Deployments**: Read-only
* **Dependabot alerts**: Read-only
* **Code scanning alerts**: Read-only
* **Issues**: Read and write
* **Merge queues**: Read-only
* **Metadata**: Read-only
* **Organization projects**: Read and write
* **Pull requests**: Read and write
* **Workflows**: Read and write
Subscribe to these events:
* **Check run**
* **Check suite**
* **Commit comment**
* **Create**
* **Delete**
* **Dependabot alert**
* **Deploy key**
* **Deployment**
* **Deployment protection rule**
* **Deployment review**
* **Deployment status**
* **Fork**
* **Gollum**
* **Installation target**
* **Issue comment**
* **Issue dependencies**
* **Issues**
* **Label**
* **Merge group** (merge queue entry)
* **Meta**
* **Milestone**
* **Public**
* **Pull request**
* **Pull request review**
* **Pull request review comment**
* **Pull request review thread**
* **Push**
* **Release**
* **Repository**
* **Repository dispatch**
* **Security advisory**
* **Star**
* **Status**
* **Sub issues**
* **Watch**
* **Workflow dispatch**
* **Workflow job**
* **Workflow run**
GitHub Apps also receive `installation` and `installation_repositories`
events automatically; you do not need to subscribe to them in the app form.
Roomote uses the **Repository** and `installation_repositories` events to
pick up newly created or newly granted repositories without a manual refresh.
If your app was created before the **Repository** event was part of the
manifest, confirm it is enabled under the app's **Permissions & events** page
— GitHub has no API to update an app's event subscriptions.
## Save credentials
Copy these values into the source-control card's configuration dialog,
deployment env vars, or your local `.env.local`:
```sh theme={null}
R_GITHUB_APP_ID=
R_GITHUB_CLIENT_ID=
R_GITHUB_CLIENT_SECRET=
R_GITHUB_WEBHOOK_SECRET=
R_GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"
```
`R_GITHUB_APP_SLUG` is required when your GitHub App slug is not
`roomote`; Roomote uses it for GitHub mentions and bot-authored PR detection.
If trusted review or notification activity can also come from other Roomote
GitHub Apps, list their exact slugs in `R_GITHUB_ADDITIONAL_APP_SLUGS`:
```sh theme={null}
R_GITHUB_ADDITIONAL_APP_SLUGS=roomote-community,roomote-reviewer
```
Roomote treats only the primary slug and this comma-separated allowlist as
managed bot identities. Do not add unrelated GitHub Apps.
Fast can use the GitHub App's Actions access to inspect workflow runs, jobs, and
logs when it explains a CI failure. That diagnostic path is read-only even
though the app keeps broader Actions and Workflows permissions for normal task
and automation workflows.
Generate a private key from the app's **Private keys** section. GitHub
downloads a `.pem` file. Convert it to an escaped single-line value before
saving it in an env var:
```sh theme={null}
awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' ~/Downloads/.private-key.pem
```
Install the GitHub App on the repositories Roomote should use. Then sign in,
complete the GitHub card in the setup conversation, and confirm repository
sync sees the expected repositories.
To replace a saved GitHub App, open **Settings > Source Control** and select
**Remove**. Roomote removes the saved deployment credentials and disconnects
existing GitHub repositories so you can configure another app. Process
environment variables are not changed.
If you add Organization projects permission to an existing app, an organization
owner must approve the updated permission before Roomote can manage project
items.
## Public GitHub reads
An eligible deployment GitHub App installation with an active connected
repository is required to mint the scoped installation token used by the GitHub
tools, including public reads. With that connection, active
Roomote members can inspect any public `github.com` repository in Fast without
connecting the public target or linking a personal GitHub account. The same
reads are available in coding tasks, including automated tasks without a human
driver. No clone or personal access token is needed.
Use the existing GitHub tools for files and directories, code search, issues,
and pull requests. Tool discovery supplies their native descriptions and
argument schemas. Searches require exactly one positive `repo:owner/name`
qualifier, for example `Hello repo:octocat/Hello-World`. GitHub's tool
availability, permissions, rate limits, pagination, and search-index limits
apply; partial or empty search results are not proof of absence.
Native reads of unconnected repositories are limited to 2 MiB of response
bytes and a 15-second upstream deadline, including JSON or SSE body reads.
Oversized, timed-out, or failed reads are not retried through another path.
These additional limits do not apply to connected repository calls.
Unconnected reads use a token scoped to one active connected repository.
GitHub denies private repositories outside that token's scope.
Private reads and all writes still require an eligible connection to the
target repository. Connected access keeps its existing authorization; Roomote
does not retry lookup or authorization failures through another credential.
The coding-task GitHub MCP remains read-only; writes use the existing
authorized coding-task source-control workflow. Other source-control providers
are unchanged.
## Multiple installations and searches
GitHub tool discovery supports multiple installations of the configured GitHub
App. Connected repository reads and supported writes use the installation
connected to the requested active repository, with a token scoped to that repository. Suspended
installations, inactive or disconnected repositories, and installations of a
different app are not eligible. Personal GitHub account linkage is not required
for these deployment-connected tools; coding-run tokens remain read-only on this
MCP path.
Identify the repository with `owner` and `repo` for repository tools. For code,
pull request, and repository searches, include exactly one `repo:owner/name`
qualifier, for example `repo:example/service is:open`. Searches without a
repository scope, across multiple repositories, or with ambiguous boolean,
negation, grouping, quoted, or regex syntax are rejected with guidance to split
the request. Optional `owner` and `repo` search arguments must match the query.
This applies with one installation too: Roomote does not return partial
cross-repository search coverage. Run separate, bounded searches for each
connected or public repository when investigating several.
## Daily GitHub management
Fast can use the native `update_pull_request`, `add_issue_comment`, and
`add_reply_to_pull_request_comment` tools without starting a coding task.
Their discovered descriptions and schemas define the supported arguments,
including title and body changes, closing or reopening an existing pull request,
reviewer requests, draft status, base retargeting, maintainer edit permission,
comments, replies, and reactions. These actions use the deployment
GitHub App, require an active Roomote member and an active connected repository,
and remain subject to the installation's issue or pull request write permission.
No personal GitHub OAuth connection is required. Ask for the specific change and
identify the repository and target issue, pull request, or comment. Authorization
is repository-scoped, not restricted to pull requests. A reaction-only call on an
existing review comment can use `commentId` without `pullNumber` when allowed by
the discovered native schema.
For example, ask Roomote to:
* mark PR #42 in `example/repo` ready for review
* request a review from `octocat` on that PR
* add a thumbs-up reaction to an existing comment, providing its GitHub URL
Retargeting a pull request's base to an existing branch does not write a branch
or change files. Merging, creating or deleting pull requests, writing branches
or files, editing or deleting comments, and repository administration are
not available through this bounded Fast path; those requests still require a
coding task. [GitLab](/providers/source-control/gitlab#native-gitlab-api-tools-for-fast)
and [Bitbucket Cloud](/providers/source-control/bitbucket#api-first-work-in-fast)
have their own supported Fast operations and limits.
Native updates that combine several actions are not guaranteed to be atomic.
After an error, Roomote inspects the resulting state before retrying so an action
that already succeeded is not blindly repeated.
Roomote tasks can manage routine repository work through the GitHub App
installation. Requests default to the repository mapped to the task:
* list, create, edit, delete, and apply labels to issues or pull requests
* create, update, delete, and report progress for milestones; assign issues to milestones
* list accessible GitHub Projects V2, inspect an issue or pull request's Status,
and update an existing project item's single-select Status field
An environment-backed task can also push branches and create or update pull
requests in another active GitHub repository connected to the same GitHub App
installation, even when that repository is not part of the environment
workspace. This write access does not automatically add the repository to the
prepared workspace. Roomote rejects inactive repositories, repositories
connected through another provider, and repositories that belong to a different
GitHub App installation.
Read-only requests, creations, and additive label actions run directly. Before
editing, replacing, assigning, clearing, moving, or deleting an item, Roomote
shows the proposed change and asks for confirmation. Deletions name the resource
and URL in that confirmation. After a write, Roomote reads the result back and
shares its GitHub URL.
Projects V2 operations require the **Organization projects** permission above.
If a project or Status field is ambiguous, Roomote asks you to choose one. An
issue or pull request that is not already on a project is reported as such;
Roomote does not add it automatically.
Native GitHub saved views are not currently supported. Roomote can share an
issue-search URL, but it does not represent that URL as a saved GitHub view.
## Start work from issues and pull requests
Once the app is installed and an environment maps the repository:
* mention `@roomote` (or your deployment's GitHub App slug) in a pull request
comment, review comment, or review to talk to Roomote about that pull request
* mention the same handle in a GitHub issue comment, or in a new issue body, to
talk to Roomote about that issue
* link your GitHub account under Settings -> Linked Accounts so Roomote can
run the conversation as you
Each pull request or issue is a Roomote Session. Roomote reads the discussion,
answers as a comment when no workspace is needed, and otherwise starts a task
on the pull request's branch (or the issue's repository) and reports back in
the same discussion. Mention it again to redirect it, ask a follow-up, or
steer a running task. Replies to a review comment stay in that review thread.
Ask for a review in the mention (for example `@roomote review this`) and
Roomote runs the Review Code automation's structured review on the current
head, posts the findings on the pull request, and reports back in the same
discussion.
To request a fresh review through GitHub, use **Re-run** on the Roomote code
review check for the pull request's current head. Roomote ignores rerun events
for stale commits and checks that were not created by the configured Roomote
GitHub App.
Roomote only responds to comments that `@mention` it, including replies inside
a review thread it opened, so people can discuss a finding among themselves
without summoning it. On a pull request that a Roomote task opened, replies in
its review threads are collected as review feedback for the owning Session,
described below.
A pull request that a Roomote task opened already belongs to the Session that
started the work, for example the Slack thread where the task was requested.
Mentions on that pull request join that Session instead of opening a second
one: Roomote answers on the pull request and in the Session's home surface,
and any work it delegates runs on the pull request's branch from the same
Session.
When a Roomote task opens a pull request, actionable review feedback returns to
the owning Session and appears in both Fast and standard web task transcripts.
Use **Resolve these issues** to address the current feedback, **Auto-resolve on
this PR** to handle later actionable feedback automatically, or **Dismiss** to
take no action.
Failed GitHub checks also return to every Roomote task linked to the pull
request and to the conversation that started the work. Roomote consolidates a
burst of failures into one actionable notification with the check names and
links. It suppresses failures from an outdated head commit and stays silent for
successful or non-failing conclusions. Keep the **Checks** permission and
**Check run** event enabled so these notifications reach Roomote, including for
pull requests opened from forks.
## Verify setup
1. connect GitHub in setup or Settings
2. install the app on at least one repository
3. create or update an environment from that repository
4. start a small task and confirm Roomote can clone the repository
5. finish the task and confirm Roomote can push a branch or open a pull request
6. optionally mention Roomote on a test issue and confirm a reply with a task link
## URL changes
Keep the public URL stable. If it changes, update both the GitHub App callback
URL and webhook URL, then restart Roomote with the matching URL.
# GitLab
Source: https://docs.roomote.dev/providers/source-control/gitlab
Configure GitLab repository sync, merge request webhooks, and pipeline failure triage for Roomote.
GitLab does not have a GitHub-style App installation flow. Configure a GitLab
OAuth application for Roomote's deployment, then authorize it once so Roomote
can sync repositories, run tasks, add merge-request notes, and manage webhooks.
Use `` below for your stable public Roomote URL (`R_PUBLIC_URL`
when set, otherwise `R_APP_URL`). The GitLab OAuth application redirect URI must
match the callback Roomote builds for authorize and token exchange.
## Create a GitLab OAuth application
Create the application on the GitLab account, group, or instance that should
own Roomote's access. Use these settings:
* **Confidential**: enabled
* **Redirect URI**: `/api/source-control/gitlab/oauth/callback`
* **Scopes**: `api`
Save the application credentials in setup, deployment env vars, or local
`.env.local`:
```sh theme={null}
GITLAB_CLIENT_ID=
GITLAB_CLIENT_SECRET=
```
For self-managed GitLab, also set `GITLAB_BASE_URL`.
## Sync repositories
After the application credentials are configured, open Settings, go to the
Environments page, authorize GitLab, and use the Source Control section's sync
button. Roomote lists the projects visible to the authorized GitLab account and
stores them as GitLab repository rows.
GitLab-backed tasks clone from the synced repository row, so sync must run
before launching a GitLab-backed task.
## Configure webhooks
Create a GitLab project or group webhook for merge request, issue, comment,
and pipeline events. Repository sync configures these project webhook events
automatically when the authorized identity has permission to manage hooks.
Webhook URL:
```text theme={null}
/api/webhooks/gitlab
```
Enable:
* **Merge request events**
* **Issues events**
* **Comments**
* **Pipeline events**
Preferred verification uses GitLab signed webhook headers. Set a GitLab
signing token on the webhook and save the same value in Roomote:
```sh theme={null}
GITLAB_WEBHOOK_SIGNING_TOKEN=
```
Legacy secret-token verification is also supported:
```sh theme={null}
GITLAB_WEBHOOK_SECRET=
```
## Enable merge request comment triggers (recommended)
Once the application is configured, users can link their personal GitLab
accounts in Roomote's Personal settings and talk to Roomote by mentioning
`@roomote` in merge request or issue notes. Each merge request or issue is a
Roomote Session: Roomote reads the discussion, answers as a note when no
workspace is needed, and otherwise starts a task on the merge request's source
branch (or the issue's repository) and reports back in the same discussion.
Mention it again to redirect it, ask a follow-up, or steer a running task.
Ask for a review in the mention (for example `@roomote review this`) and
Roomote runs the Review Code automation's structured review on the current
head, posts the findings on the merge request, and reports back in the same
discussion.
## Enable review automation
GitLab merge-request reviews use the same Review Code automation targeting
model as GitHub. After syncing repositories, associate the GitLab repository
with the intended environment and enable Review Code automation for that target.
Open or reopened merge request events enqueue initial review tasks. Update
events enqueue sync reviews when GitLab includes `oldrev`, which indicates a
code-related update.
## Enable CI failure triage
Associate the GitLab repository with an environment, configure the Manager
Channel destination, and enable **CI Failure Triage** under Automations.
Failed default-branch Pipeline Hooks start an environment-backed Roomote task.
Roomote reads a bounded tail of the failed job logs with the deployment GitLab
credential, reproduces the relevant commands locally, and opens a merge
request when it can fix the failure.
## Verify setup
1. sync GitLab repositories from Settings
2. create or update an environment from a synced repository
3. start a small task and confirm Roomote can clone the repository
4. open or update a merge request and confirm configured review automation runs
5. trigger a failing default-branch pipeline and confirm CI Failure Triage starts
## Native GitLab API tools for Fast
Fast can read code and handle supported merge request requests directly through
GitLab's API without cloning a repository. These tools are built into Roomote:
no extra MCP server, package installation, or server URL is required.
Roomote reuses its active deployment OAuth connection with the existing `api`
grant and refreshes the access token when needed. No second OAuth application,
user authorization flow, or static GitLab credential is needed.
[GitLab's official MCP server](https://docs.gitlab.com/user/model_context_protocol/mcp_server/#reuse-a-single-oauth-application)
uses `mcp`-scoped authorization; it is not a drop-in replacement for Roomote's
unchanged `api` grant.
A community MCP server is not required for these operations. Hosting one would
add responsibility for deployment, version pinning and upgrades, network and
TLS configuration, authentication, credential protection, tool permissions,
monitoring, and incident response. It would also introduce another service
trusted with GitLab credentials and repository data. The native tools avoid
that additional operational burden while using the connection configured above.
### Available operations and limits
All tools require `project_id`: a positive integer project ID (number or decimal
string without leading zeros), or a `group/project` path, including subgroups.
MR tools also require `merge_request_iid` as a positive decimal string without
leading zeros, within JavaScript's safe integer range. Unknown inputs are
rejected. Inputs listed as optional below may be omitted.
| Tools | Inputs and supported scope |
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `get_file_contents` | Required `file_path` and `ref`, a full immutable 40-character hexadecimal commit SHA. Resolve a branch with `get_commit` first. UTF-8 text only; files over 1 MiB and binary files are rejected, even for a small window. Optional integer `offset` is zero-based, minimum 0, default 0; optional integer `limit` is 1-2000 lines, default 2000. Continue with `next_offset` at the same SHA; `null` means the end. |
| `get_repository_tree` | Optional `path`, nonempty `ref`, boolean `recursive`, `per_page`, and `page_token`. Always keyset pagination; optional `pagination` accepts only `keyset`. Returns `items` and `next_page_token`; pass the token as `page_token` to continue, stopping at `null`. |
| `search_project_code` | Required nonempty `search`; optional nonempty `ref`, `page`, and `per_page`. Searches code in one connected project only. Requires GitLab instance and connection support for blob search; no unscoped fallback. |
| `list_commits` | Optional nonempty `ref_name`, `path`, `page`, and `per_page`. Reads commit history. |
| `get_commit` | Required `sha`, a commit identifier or branch name subject to the path rules below. Reads commit details. |
| `get_merge_request` | Reads an existing MR; no inputs beyond `project_id` and `merge_request_iid`. |
| `list_merge_request_diffs`, `get_merge_request_notes`, `mr_discussions` | Read an MR's diffs, notes, or discussions. Optional `page` and `per_page`. |
| `update_merge_request` | Optional nonempty `title`, `description` (may be empty), and `state_event` (`close` or `reopen`). At least one must be supplied; no other fields can be changed. |
| `create_merge_request_note` | Required nonempty `body`. Adds a top-level MR note. |
| `create_merge_request_discussion_note` | Required nonempty `body` and `discussion_id` containing only letters, digits, underscores, or hyphens. Replies to an existing discussion on that MR. |
Paths (`file_path`, `path`, and `sha`) must be nonempty and cannot contain
backslashes, control characters, empty slash-separated segments, or `.` / `..`
segments. Project paths use letters, digits, underscores, dots, and hyphens in
each segment. Decimal string project IDs must fit JavaScript's safe integer
range. Tree page tokens are nonempty and contain only letters, digits,
underscores, `+`, `/`, `=`, or `-`.
Paginated tools accept integer `per_page` from 1-100, default 20. Tools other
than trees accept integer `page` of at least 1, default 1, with no additional
page-number cap. They return `items` and `next_page`; `null` means no next page.
The complete incoming request is limited to 64 KiB. GitLab responses and the
complete tool result are each capped at 1 MiB. Operations have a 20-second
abort deadline; OAuth refresh requests have a 10-second timeout. Request smaller
pages or file windows if a result exceeds the response limit. There are no
separate native character caps for titles, descriptions, or note bodies;
the request-size limit and GitLab's own validation still apply.
Every operation requires an active Roomote member or admin, an active connected
repository on the configured host, and valid deployment OAuth access. MR writes
also verify the target MR and, for replies, its discussion before sending the write.
These native tools do not expose file or branch writes, MR
creation or merging, approvals, thread resolution, note editing/deletion, issue
tools, CI tools, or arbitrary GraphQL. Fast uses available APIs first for this
supported scope. Local checkout inspection, edits, commands, and validation
still need a task. Task authorization and structured code reviews are unchanged.
### Verify safely
1. From a signed-in member or admin Session, ask Roomote to discover available
GitLab tools and read a small known file in an active synced repository at a
resolved commit SHA. Confirm it uses the API without launching a clone task.
2. If tools are missing, check that you are an active Roomote member or admin,
the deployment's GitLab OAuth connection is active with the `api` scope,
and repository sync includes an active repository on the configured GitLab
host. Reauthorize if required. Curated integrations must not be disabled on
the Roomote deployment. No external MCP server needs to be installed or repaired.
3. Test writes only with explicit authorization on a designated disposable MR.
Specify the exact note, reply, or reversible title/state change, inspect the
result in GitLab, and restore any changed fields. Never mutate arbitrary MRs
as a connectivity check. Successful discovery or reads do not prove live
authorized writes; verify each required operation before relying on it.
# Self-hosting
Source: https://docs.roomote.dev/self-hosting
Deploy the cloud coding agent you own on Roomote Cloud or your own infrastructure.
Roomote is the cloud coding agent you actually own. It runs your development
environment in isolated sandboxes, uses your repositories and tools, verifies
its work, and returns reviewable pull requests with previews when they apply.
Run the same single-tenant product on Roomote Cloud or infrastructure you
control.
Choose the fastest path for your team. Every deployment needs model inference:
use hosting-provisioned Roomote inference when it is offered, or connect a
ChatGPT subscription or inference provider API key. You also need source control
and a sandbox provider. Connect communications providers and other tools when
your team needs them.
Asking a coding agent to install Roomote? Send it this page. Agents should
follow the [agent installation guide](/self-hosting/agent-installation). It
uses the standard installer on Linux and creates a Linux VM plus temporary
HTTPS ingress when the current machine is macOS or Windows.
## Choose your deployment
* **Roomote Cloud** is the fastest way to get started. Your deployment remains
isolated while Roomote manages hosting, networking, sandboxes, and upgrades.
* **Railway** and **Render** provision the application, PostgreSQL, and Redis
from a template so you can run Roomote on managed infrastructure you control.
* **Your own server** gives you the most infrastructure control with the
one-command installer below.
Running Roomote on Proxmox or another server at home? Follow the
[Homelab deployment guide](/homelab) for VM sizing, Tailscale administration,
public ingress, and a prompt that a local agent can follow.
By the end of setup, you should have a reachable Roomote URL, sign-in, a
source-control provider, managed Roomote inference or a connected inference
provider, at least one environment, and a first reviewable Roomote task.
The canonical, always up-to-date guide for operating your own server lives in
[`SELF_HOSTING.md`](https://github.com/RooCodeInc/Roomote/blob/main/SELF_HOSTING.md)
in the repository.
## One-command install
SSH into a fresh Ubuntu or Debian server (x86\_64 or arm64, 4 GB+ RAM) and run:
```sh theme={null}
curl -fsSL https://get.roomote.dev | sudo bash
```
The installer brings up the full stack from published images and prints a setup
link. Open it in a browser to create the first administrator and configure
inference. Roomote then opens a persistent setup conversation where trusted
cards guide you through source control, your first task, a sandbox provider,
and recommended automations.
No DNS setup is needed to try it out; pass `--domain roomote.example.com` for a
production install on your own domain.
Prefer to read what you are about to run as root? Download, inspect, then run
the same script:
```sh theme={null}
curl -fsSL https://get.roomote.dev -o install.sh
less install.sh
sudo bash install.sh
```
## Setup checklist
Have these ready before setup asks for them:
* a public HTTPS URL for the deployment, especially when source-control or chat
callbacks need to reach it
* a sign-in provider for the people who will use the deployment
* a source-control provider account with permission to install or configure the
app for the repositories Roomote should reach
* a ChatGPT subscription or inference provider API key, such as OpenRouter,
Anthropic, or OpenAI, unless your host already provisioned Roomote inference
* a communications provider workspace, such as Slack, Microsoft Teams,
Telegram, or Discord, if your team wants to start work from chat
* at least one repository that can become the first Roomote environment
## Day-2 operations
The installer also sets up the `roomote` host CLI for common operations:
```sh theme={null}
roomote upgrade # pull and roll out newer images
roomote rollback # return to the release before the last upgrade
roomote backup # create an encrypted deployment recovery bundle
roomote logs # tail service logs
```
`roomote backup` prompts for a passphrase and writes a versioned `.roomote`
bundle under `/opt/roomote/backups`. The bundle contains PostgreSQL, the
deployment configuration and encryption/signing keys, local MinIO artifacts,
schema metadata, the exact deployed image identities, and both the Memory volume
and isolated Memory database when the `brain` profile is enabled. Store the
passphrase separately in your secret manager; the backup cannot be restored
without it.
Use `roomote backup --include-redis` when queued work, BullMQ schedules,
sessions, and other transient Redis state must survive. Backups briefly stop
application writers (and active Docker task workers) so the included stores
share a documented consistency point. If object storage is external, the
bundle records its endpoint and bucket but does not copy its objects; keep a
provider-level backup of that bucket.
Restore only after installing Roomote on the replacement host:
```sh theme={null}
roomote restore /path/to/backup.roomote --yes
```
Restore verifies the encrypted bundle and checksums before replacing any
state, restores the original `.env` (including `ENCRYPTION_KEY`), repopulates
empty PostgreSQL/MinIO/Redis volumes, and starts the recorded Roomote release.
## Upgrades and rollback
`roomote upgrade` is designed so a bad release cannot strand your deployment:
* **A backup comes first.** Every upgrade creates an encrypted pre-upgrade
bundle under `/opt/roomote/backups` before anything changes. Pass a
passphrase with `--backup-passphrase-file` (or `ROOMOTE_BACKUP_PASSPHRASE`);
otherwise one is generated and stored next to the bundle. Use
`--skip-backup` to opt out.
* **Migrations run before services are replaced.** Database migrations apply
in a single transaction while the previous release keeps serving. If a
migration fails, the schema rolls back, the previous configuration is
restored, and the previous release stays up.
* **Rollback is one command.** Every release's schema keeps the previous
release working, so `roomote rollback` re-deploys the prior release without
touching the database. `roomote upgrade ` does the same for any
retained tag, and restoring the pre-upgrade bundle is the last-resort path
that also rewinds data.
Use `roomote upgrade` instead of updating application image references alone.
The command refreshes the release's Compose and Caddy configuration together;
mixing newer application images with an older Caddyfile can leave routes used
by the new controller unavailable until the deployment configuration is also
updated.
The supported rollback target is the release immediately before the current
one. Check the running application version and applied schema migration at any
time under **Settings → Deployment → Diagnostics**; both are also recorded in
every backup bundle's manifest.
Roomote surfaces release history and available updates in the web app:
* **Admins** on self-hosted deployments see an update notice in the sidenav when
a newer GitHub release is available. The update dialog keeps that target and
its GitHub link visible even when the running image does not yet contain the
newer release's notes. Use `roomote upgrade` (or your image roll-forward
process) to install it.
* **Everyone** can open **About Roomote** and select **See all Roomote releases**
to browse the current and previous release notes bundled in the running
image, with the latest release expanded. After an upgrade, Roomote also shows
the latest "what's new" notice once.
## Deployment modes
* **One-command install** — `deploy/install.sh` on an existing server, using
published GHCR images.
* **Railway** — deploy the managed Railway template with hosted sandboxes. New
Railway signups get \$20 in credit through [our referral link](https://railway.com?referralCode=roomote).
* **Local development** — `pnpm dev` runs the services from your checkout with
PM2 for fast source edits.
* **Production Compose with Caddy** — `docker-compose.production.yml` adds a
Caddy container as the HTTPS entrypoint for your app and preview domains, and
runs the containerized stack in production mode with per-install secrets
(locally or on a server).
## Requirements
* Managed Roomote inference from an eligible host, or a ChatGPT subscription or
inference provider API key (OpenRouter, Anthropic, OpenAI, and others).
* An account with a supported source-control provider. For GitHub, the setup
conversation creates the GitHub App; other providers use their documented
OAuth or credential flow.
* For Slack, Microsoft Teams, Telegram, and Discord: a workspace or server where
you can install an app or bot; the setup assistant prefills the Slack app
manifest and creates Discord's installation link for you.
## Verify the deployment
After sign-in and inference are ready, setup continues entirely in a persistent
conversation with Roomote. Trusted action cards appear beside the relevant
messages for source control, first work, sandbox configuration, and automation
recommendations. Detailed provider instructions and credential entry open in a
dialog from the source-control card; Roomote never asks for credentials in
chat.
The conversation also asks briefly about the tools your team uses for
documents, monitoring, and project tracking, one topic at a time.
You can skip these questions. The optional integrations card lists only supported
tools you said you use and opens their secure configuration without leaving setup.
If there are no eligible matches, setup moves on without showing suggestions.
Tools without a built-in connector are not presented as supported. Use
**Keep going** to move on without connecting; you can connect tools later in
Settings. Integration choices do not change the starter tasks offered.
Services that are also source-control, communications, inference, or sandbox
providers are excluded from this optional step; their separate setup is unchanged.
The Vercel deployments integration remains available separately from Vercel AI
Gateway inference.
Setup completes once inference and a sandbox provider are ready, source control
is successfully configured, and at least one repository has synchronized.
Roomote then offers preselected starter tasks in one structured multi-select
question. Starter work is optional and does not gate setup completion; selected
work launches visibly in the same session. A launch failure does not reopen
setup; ask Roomote to retry that item. Automation recommendations are analyzed
after repository sync and appear only after at least one starter task launches.
They remain optional.
After setup, run a small task that uses the first environment if you did not
start one from the starter list. A healthy deployment should let you:
* sign in from the public Roomote URL
* connect source control and see the expected repositories
* create or select an environment
* start a task from the dashboard or chat
* inspect the task transcript, logs, and any generated diff or artifact
* open a preview when the task starts a web app
## Common issues
* **Callbacks fail.** For providers that use callbacks or webhooks, confirm the
deployment has a public HTTPS URL and that the provider is using that exact
URL. Discord uses its Gateway service instead of a public callback.
* **The first task cannot clone a repository.** Workers authenticate git with a
short-lived GitHub App installation token created when the run starts — they
do not read a `GH_TOKEN`/`GITHUB_TOKEN` from the container environment. If a
task fails with "No GitHub credentials are available", verify the GitHub App
is installed for the repository owner, the installation covers the
repository, and the repository appears in the source-control settings after a
sync.
* **The agent cannot run useful commands.** Add missing services, environment
variables, setup commands, or tool versions to the environment.
* **Chat messages do not reach Roomote.** Confirm the app is installed, invited
to the channel, and using the current callback URL.
* **Fast reports that local working storage is full.** Clean up container
storage, then recreate the affected application containers. Installer-managed
Compose deployments can raise `ROOMOTE_APP_TMPFS_SIZE` above its `512m`
default before recreating them; keep the limit within the host's available
memory.
* **Memory climbs for hours, or a service is OOM-killed under a container
memory limit.** Node sizes its heap from the memory it can see (the host's,
not the container's), so it defers garbage collection and lets memory drift
well above what the service needs; a container memory cap then kills the
process before Node ever feels pressure. Current app images cap each Node
service's heap by default (768 MB for web and api, 512 MB for controller and
bullmq, reduced to \~75% of the container's memory when a cgroup limit is
set). Set `NODE_OPTIONS=--max-old-space-size=` on a service to override
the default, or on older images to add the cap manually.
## Agent-guided installation
The [agent installation guide](/self-hosting/agent-installation) keeps the
one-command Linux installer as the single deployment path. On macOS or Windows,
an agent runs it inside a Linux VM and adds temporary HTTPS ingress for OAuth
callbacks and webhooks.
# Skills
Source: https://docs.roomote.dev/skills
Create reusable instance-wide playbooks for Sessions and coding tasks, alongside existing environment and repository skills.
Skills are reusable instructions Roomote can use when a task needs a
specialized workflow.
In the task prompt, type `/` to search the packaged skills available to
Roomote, then select one to insert its slash invocation.
In a Fast conversation, start a message with `$skill-name` to explicitly load
a packaged, instance, or environment skill. Instance skills are available to
members even when no environments are configured. Roomote resolves existing
environment skills only from environments you can use. If those environments
define different versions with the same name, Roomote asks which one you mean.
When you ask Fast which skills are available, its unscoped inventory includes
packaged skills, instance skills, and environment skills you can use.
Repository-defined skills remain scoped to a specific environment or
repository.
Use Skills when the same guidance keeps showing up across Sessions and tasks:
a framework-specific review checklist, a release process, a
design-system rule, a data workflow, or a repeatable debugging path.
Skills are for durable playbooks that help a Roomote agent decide how to work.
They are not a replacement for connecting providers, adding environment
variables, or writing the one-off prompt for the current task.
## What Skills settings controls
**Settings > Skills** opens one searchable skill catalog. The **All** and
**Everywhere** filters are available to every signed-in member; admins can also
filter for **Env-Specific** skills. The **Availability** column shows
**Everywhere** for instance skills and the selected environments for scoped
skills. Select a skill to view its instructions and access any permitted
**Edit** and **Delete** actions.
Instance skills are stored once for the Roomote instance, independently of
environments. Any member can create or read them. Only the creator or an admin
can edit or delete them; these permissions also apply to conversational creation.
Choose **Add Custom Skill** to create reusable instructions. Members create
skills available everywhere. Admins can instead select environments in the
creation dialog. Existing skills keep their current availability when edited;
the settings UI does not move skills between instance and environment storage.
Admins can use **Add from Marketplace** to open the Vercel Marketplace search,
install published skills, and choose which environments use them. Admins can
also edit or delete inline environment skills and manage installed marketplace
availability from the unified catalog.
The same configuration remains available in the environment editor's **YAML**
view: use `manualSkills` for inline custom instructions and `skills` for
published skills. See the
[environment definition reference](/environments/definition#skills) for examples.
| Skill type | How it is added | Availability |
| ----------------- | ------------------------------------------------------- | ---------------------------------------------- |
| Instance skill | Ask in conversation or use Add Custom Skill in Settings | All Sessions and coding tasks on this instance |
| Environment skill | Admins use Settings or edit environment YAML | Selected environments only |
| Repository skill | Maintain a skill in the repository | The authorized repository or environment scope |
Instance skills do not have an environment selection. Environment skills apply
to the environments whose YAML includes them.
## When to use a custom skill
Create a custom skill when the instruction is:
* repeatable across many tasks
* specific enough that Roomote can tell when to use it
* more detailed than a short line of environment guidance
* durable enough to maintain over time
Good custom skills include:
* a support-investigation workflow for your product
* a design-system implementation checklist
* a release-note drafting process
* a database migration review guide
* a customer-escalation triage playbook
The [support channel recipe](/cookbook/support-channel) shows a complete custom
skill with launch criteria and a production-safe investigation flow.
If the instruction is only one sentence, it probably belongs in
[Agent Guidance](/agent-guidance),
[environment guidance](/environments), or the task prompt instead.
## Create a skill in conversation
Any member can ask Roomote to save an instance skill directly in a Session,
without starting a coding task or creating a repository file. Include a slug,
a description of when to use the skill, and Markdown instructions. For example:
```text theme={null}
Save an instance skill named release-checklist.
Description: Use when preparing a release for review.
Instructions: Summarize the changes, check the release tests, and list any
unresolved rollout risks. Do not publish the release without approval.
```
The skill appears in **Settings > Skills**. There is no
environment selection and no environment needs to exist. Refresh an
already-open settings page to see a skill created in conversation.
Roomote confirms persistence and instance-wide availability after creation.
Fast can discover and load newly created or updated skills immediately in the
same conversation. Coding tasks fetch a fresh catalog at startup and on resumed
runs; an already-running agent does not reload skill files mid-turn. A failure
to fetch that catalog stops startup rather than silently using stale skills.
Instance skill names are unique. A duplicate is rejected without overwriting;
choose another slug or edit the existing skill if you own it or are an admin.
Names use lowercase letters, numbers, and hyphens, up to 64 characters. Each
description is limited to 1,024 characters, and the rendered Markdown document
to 64 KiB. An instance can hold up to 128 instance skills.
Deleting a skill removes it from future discovery and runtime refreshes, not
from text already loaded in an active conversation. Locally modified skill
files in an existing coding workspace are preserved rather than deleted as
unrelated work.
## Write the description carefully
The description helps Roomote decide when the skill is relevant. Make it
concrete.
Prefer:
```text theme={null}
Use when changing React components in the dashboard design system.
```
Avoid:
```text theme={null}
Use for frontend stuff.
```
The skill content can be more detailed, but the description should quickly
answer: "When should Roomote reach for this?"
## How Skills interact with repository-defined skills
Some repositories define their own skills in the repository, usually as
checked-in `SKILL.md` files. Those repository-defined skills travel with the
repository and are best for instructions that should stay versioned with that
codebase.
Skills configured in Roomote settings are different:
* **Instance skills are shared across the instance.** They are available to all
members, Sessions, and coding tasks without environment configuration.
* **Environment skills keep their existing scope.** They apply only to their
selected environments and remain admin-managed.
* **Repository-defined skills are codebase-level.** They apply when the task
is working in that repository and the active workflow finds them relevant.
* **Fast mode can discover these skills before starting a task.** It can load
instance skills directly, environment skills only from authorized environments,
and it reads repository skill Markdown only from repositories in configured
environments. If the workflow needs a workspace, Fast starts a task in a
matching environment and the task loads the environment-scoped or checked-out
copy of the skill.
* **Custom skills are supplemental.** They help Roomote perform specialized work; they
do not replace the built-in task flow, environment setup, or the user's
prompt.
* **Built-in Roomote skills stay authoritative.** When names collide, Roomote
prefers packaged skills, then instance skills, then environment skills, then
repository skills. Use distinct names for team skills. Skill instructions
cannot grant permissions or override higher-priority policies.
Use repository-defined skills when the instruction should be reviewed and
changed with the code. Use instance skills for shared playbooks without a
repository change. Existing environment skills remain useful where an admin
wants guidance scoped to selected environments.
## Choosing the right home
| Put it in | Use it for |
| ----------------------------- | ---------------------------------------------------------------------- |
| **Instance skills** | Shared playbooks for Sessions and coding tasks across the instance |
| **Environment skills** | Existing playbooks scoped to selected environments |
| **Repository-defined skills** | Codebase-specific playbooks that should live with the repository |
| **Environment guidance** | Setup commands, services, ports, secrets, and workspace-specific rules |
| **Agent Guidance** | Deployment-wide expectations that apply to most tasks |
| **Task prompt** | One-off context for the current ask |
## Common issues
* **Roomote does not use the skill.** Make the description more specific. For
environment skills, check that it is enabled in the selected environment.
* **Fast cannot find `$skill-name`.** Check the exact invocation name and whether
a higher-priority skill has the same name. For environment skills, check access.
* **The skill applies too broadly.** Narrow its when-to-use description. Instance
skills are shared, not private or environment-scoped.
* **Two skills seem to overlap.** Keep the more specific one, or split the
workflow so each skill has a clear trigger.
* **A repository already has a similar skill.** Prefer the repository-defined
skill for codebase-owned behavior, and use Settings skills for
cross-environment behavior.
# Source Control Overview
Source: https://docs.roomote.dev/source-control
Connect GitHub, GitLab, Gitea, Bitbucket, or Azure DevOps so Roomote can clone repositories and open reviewable changes.
Source-control providers give Roomote access to the repositories where your
team's work happens.
Roomote uses source control to sync repositories into environments, clone code
inside task sandboxes, push branches, open or update pull requests, and respond
to review events or comments when the provider supports them.
## Supported providers
| Provider | Best for | Setup model |
| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------- |
| | GitHub-hosted repositories and pull request review workflows | GitHub App installation (default provider). |
| | Azure DevOps repositories | PAT, Microsoft Entra service principal, or delegated Microsoft account. |
| | Bitbucket Cloud repositories and pull request workflows | Deployment-scoped Bitbucket OAuth and repository sync. |
| | Self-hosted Gitea repositories | Deployment OAuth application, service-account authorization, and repository sync. |
| | GitLab projects and merge request review workflows | Deployment OAuth application, one-time authorization, and optional webhooks. |
## Setup checklist
Before connecting source control, make sure your deployment has:
1. a stable public HTTPS URL for callbacks and webhooks
2. an admin or bot identity with access to the repositories Roomote should use
3. provider credentials saved in setup, Settings, or deployment environment
variables
4. at least one environment that can use the synced repositories
After setup, verify that Roomote can:
* list the expected repositories
* create or update an environment from a repository
* clone the repository inside a task sandbox
* push a branch or open a reviewable change when the task finishes
## Manage pull requests from tasks
During an environment-backed task, Roomote can update, close, or reopen pull
requests and merge requests on GitHub, GitLab, Gitea, Bitbucket Cloud, and Azure
DevOps. Updates can change the target branch, title, description, or draft state
when the provider exposes that capability. Gitea cannot clear a native draft
state through this interface; Bitbucket and Azure DevOps draft updates are
skipped when the provider does not return the current draft state.
Closing does not merge the change or delete its source branch. The provider may
describe the resulting state as closed, declined, or abandoned. Roomote reports
when a requested provider operation was unsupported instead of treating it as
applied.
## Attribution on pull requests and commits
Roomote keeps human-readable attribution inside private repositories. For
public repositories, it uses the task participant's linked source-control
username when one is available. If Roomote cannot resolve a linked username,
the pull request or merge request says only that it was created by Roomote.
Roomote never derives public attribution from an account email address. Commit
emails use the source-control provider's `noreply` identity when available, or
the Roomote identity otherwise. A workspace containing any public or
unresolved repository uses the public-safe identity for all new commits because
Git author configuration applies across the workspace.
Linked GitLab and Gitea accounts retain the username verified by that provider,
scoped to the configured source-control host. Bitbucket does the same only when
its profile API returns a username; a nickname is not treated as a public
handle. Azure DevOps
accounts retain their verified display name for Settings and private-repository
context, but public attribution remains generic because Azure DevOps does not
provide a stable non-email public handle. GitLab.com can also provide a verified
`noreply` commit identity; other non-GitHub providers use Roomote as the Git
author for public work.
Existing account links pick up verified profile attribution after their OAuth
token refreshes or after the account is linked again.
Changing a repository from private to public does not rewrite existing Git
history. Roomote sanitizes a legacy named attribution line the next time it
updates an open public pull request.
## Pull request review comments
When **Review Code** finds an issue on a changed line, Roomote posts the finding
as an inline comment on GitHub, GitLab, Gitea, Bitbucket, and Azure DevOps. It
replies to an existing thread when the provider supports threaded replies and
the same lines are already under discussion. On Gitea, that reply becomes a
pull request comment that references the original thread. Roomote can anchor
new findings to added, changed, or deleted lines.
If a provider rejects an inline location, Roomote retries with the current diff
and then includes the finding with a file and line reference in the review
summary. On later sync reviews, Roomote resolves its inline thread when the
flagged issue is clearly fixed and the provider supports thread resolution.
### Mark clean Roomote drafts ready for review
When **Pull request delivery** is set to **Draft pull request**, admins can
enable **Mark Roomote PR ready after clean review** under **Settings > Source
Control**. The setting is off by default. After Roomote's automated reviewer
records a clean result, Roomote marks its own draft ready for human review on
GitHub, GitLab, Gitea, Bitbucket Cloud, or Azure DevOps.
Roomote verifies that the pull request or merge request is still open, still a
draft, and still points at the exact reviewed commit before changing its state.
Human-created drafts, reviews with findings, stale or incomplete reviews, and
branches that changed after review remain drafts. This setting does not approve
or merge anything, and it is inactive when delivery is already set to
**Ready-for-review pull request** or **Push branch only**.
## Pull request status notifications
When a tracked, Roomote-created GitHub pull request becomes conflicted, Roomote
notifies the Slack, Teams, Telegram, Discord, or Fast session where the
task started. The notification is automatic and is sent once for each
transition into a conflicting state. If the pull request becomes clean and then
conflicts again, Roomote sends a new notification.
This status notification does not run **Resolve PR Conflicts**. Enable that
automation separately under **Settings > Automations** when you want Roomote to
attempt conflict resolution.
## Public URLs
Use the same deployment URL across source-control callbacks and webhooks. If
the public URL changes, update the provider app settings and restart Roomote
with the matching deployment URL before testing again.
Local development commonly uses `R_PUBLIC_URL`. Production deployments
usually derive callbacks from the public app URL configured by the installer or
Compose environment.
During setup, Roomote shows the exact callback URL for the selected provider.
Copy that value into the provider application instead of constructing it by
hand.
## Remove a provider configuration
Admins can remove any saved source-control provider from **Settings > Source
Control**. Roomote first attempts to remove external webhooks, then deletes the
saved database configuration and any provider OAuth connection, then disconnects
that provider's synced repositories. Removing a delegated Azure DevOps
configuration also unlinks the account used by that connection.
Process environment variables are not removed. If the provider is configured
through deployment environment variables, remove or replace those values in the
deployment configuration too. Roomote reports warnings when an external hook or
OAuth cleanup cannot be completed, so review those warnings before reconnecting
the provider.
## Related setup
* [Environment Variables](/environment-variables) lists source-control env vars.
* [Environments](/environments) explains how repositories become task context.
* [Tasks](/tasks) explains how to review output, logs, diffs, and previews.
# Review a task
Source: https://docs.roomote.dev/tasks
Inspect the transcript, logs, diffs, previews, and follow-up path before you trust the result.
A task is one independently controllable execution. It may run inside a Session
or start directly from chat, source control, Linear, the API, or the web
dashboard. The task workspace remains the place to inspect operational details
such as logs, terminal output, diffs, previews, retries, and artifacts.
For a delegated task, use the owning Session for conversation, input, reports,
and follow-up. For a standalone task, continue from the task view instead. In
either case, open the task view as the execution-review surface when you need
evidence for your normal review process. A task is complete only when that
evidence is clear enough for a teammate to trust, continue, or reject the
result.
## What to check first
Before you dive into details, check the basics:
* what Roomote was asked to do
* which environment or repository context it used
* whether the task is still running, needs input, or has finished
* whether Roomote used the expected model, source-control context, and
compute environment when those details matter
* whether the end state matches the kind of outcome you wanted: answer, plan,
patch, branch, or PR
## Sessions and the task board
Use the board view on the Sessions page to scan shared work by lifecycle.
Roomote places Sessions in **Active**, **Needs input**, **Blocked**, or **Ready**
from their current task, goal, and run state, so your team does not need to
maintain a separate status field.
Each Session card shows its owner and participants, recent activity, delegated
execution count, workspace or pull-request context, aggregate cost, and unread
state. Use the **Tasks** scope when you only want Sessions containing execution
work. Board and list choices remain in the URL so views are shareable.
## Recover from a failed start
When a task cannot start, select **Try in a new task** to open an editable task
launcher prefilled with the original text prompt, selected model, and linked
environment. Review or change those values before starting it. This creates a
new task instead of retrying the failed task, and attachments are not copied, so
reattach any files the new task needs.
## Task view
The task view gives you the working context for a run:
* a header breadcrumb linking back to the owning Session (when you opened the
workspace from a filtered Sessions view, browser Back returns to that view)
* conversation history and Roomote updates
* inline widgets for structured tables, status cards, plans, and other
presentational results an agent chooses to show
* terminal and runtime logs, including individual environment setup-command
logs when setup is still running or needs troubleshooting
* generated artifacts
* code diffs
* previews for running apps
* task metadata and links back to the surface that started the task
If a task started from Slack, Teams, Telegram, Discord, Linear, or source
control, use the task view when the chat or provider thread does not show enough
detail to review the work. Presentational widgets remain available in the task
transcript; when an agent provides a text fallback, Roomote also sends that
fallback to the originating Slack, Teams, Telegram, or Discord conversation.
For a Markdown plan artifact, **Build this** starts a Session and delegates the
plan to a task inside it. Roomote preserves the selected environment, branch,
and model, and retries the same kickoff if the first launch is interrupted. Use
the confirmation link to follow the Session, then open the delegated task for
its operational details.
Generated HTML artifacts open in a sandboxed **Preview** by default. Switch to
**Code** to inspect the saved HTML source without executing it in the page that
runs the Roomote dashboard.
### Native widget styling
Roomote widgets inherit the task view's selected light or dark theme. Agents can
use the built-in `rw-card`, `rw-stack`, `rw-row`, `rw-grid`, `rw-stat`,
`rw-badge`, `rw-callout`, and `rw-muted` classes for common layouts without
supplying custom CSS.
When a widget needs a custom layout, its CSS can use Roomote's `--rw-*` theme
variables. The main variables are `--rw-background`, `--rw-surface`,
`--rw-surface-muted`, `--rw-text`, `--rw-text-muted`, `--rw-border`,
`--rw-primary`, `--rw-accent`, `--rw-success`, `--rw-warning`, and
`--rw-danger`. This keeps the result visually consistent with Roomote and lets
the same widget adapt when the viewer changes themes.
Widgets work best as compact visual summaries. Agents should keep labels and
datasets concise, choose a height that fits the expected content without
scrolling, and use normal task narration or an artifact for longer material.
## Review the evidence
Roomote is most useful when it can show its work. For implementation tasks,
look for:
* commands, tests, or checks it ran
* logs or errors it used to make decisions
* screenshots, recordings, or live previews for UI changes
* a diff or pull request for code changes
* a clear explanation when something could not be verified
Roomote chooses screenshots, recordings, both, or no visual proof according to
what best demonstrates the work. Screenshots suit stable appearance; recordings
can show motion and interactions, even when you did not explicitly ask for a
video. Roomote skips visual proof when it would not add useful evidence. Judge
the evidence against the stated result rather than requiring a recording for
every change.
Visual proof should use genuine application, authentication, database, and
backend state when practical. When an artifact instead uses disclosed simulated
state to make a UI reachable, treat it as evidence only for the rendered
appearance, layout, or interaction under that setup. It does not verify real
data flow, authorization, backend behavior, network behavior, or an end-to-end
journey. The task report and artifact metadata should identify the simulation
and state those limits explicitly.
| Surface | What to look for |
| ----------------- | ------------------------------------------------------------------------------------------ |
| Transcript | Whether Roomote understood the ask, adapted to new context, and explained blockers clearly |
| Terminal and logs | The concrete commands, errors, and runtime signals behind the final answer |
| Diff or PR | Whether the actual code change matches the requested outcome |
| Preview | Whether the visible result matches the claim for UI or workflow changes |
| Artifacts | Plans, reports, screenshots, or other outputs you may want to reuse or review |
When an environment setup command fails, open the task **Logs** panel and
select its `Setup: ` entry. The command's output is available there
without needing to enter the sandbox workspace.
## Continuing work
You can send follow-up instructions while a task is active. If a task has
completed and Roomote has a restorable snapshot, a follow-up can resume from
that prior workspace instead of starting over. Snapshot retention depends on
the sandbox provider: Modal-backed snapshots do not have Roomote's seven-day
application expiry, while other providers may use a bounded window.
When a task delegated from a Fast session asks for input, reply naturally in
the originating session. If one input request is pending, Roomote
applies a matching reply to that request instead of treating it as a separate
task instruction.
For an objective that may need several agent turns, use
[Goal Mode](/goal-mode). It keeps the complete outcome in context and can
continue the task automatically within a bounded continuation budget.
Good follow-ups are specific:
* "Apply the second option and add a regression test."
* "Use the existing settings card pattern instead of adding a new component."
* "Open a PR with the fix."
* "Explain the tradeoff before changing code."
## When to resume versus start a new task
* Resume the same task when the follow-up depends on the existing workspace,
context, or unfinished implementation.
* Start a new task when the work is a separate objective, should use a
different environment, or would make the current task thread too broad.
## Before you merge or ship
Before you merge changes, review the diff and the verification Roomote ran.
Roomote can move quickly, but your normal review process still matters. For
implementation work, ask Roomote to include the tests or validation it ran in
the final task message.
If verification is missing, ask Roomote to run the specific command or explain
why it cannot. If the task touched user-facing behavior, inspect the preview,
screenshots, or product surface before shipping.
## Multi-person tasks
Different teammates can run separate tasks in parallel. Teammates can also
join the same task conversation when the work needs shared context, for
example when a PM clarifies requirements and an engineer reviews the
implementation plan.
# What to ask Roomote
Source: https://docs.roomote.dev/use-cases
Frame asks so Roomote can stay scoped, useful, and reviewable.
Roomote is built for the work that constantly pulls teams out of focus:
questions, planning, investigations, bugfixes, review follow-up, and
backlogged improvements.
The best asks give a Roomote agent a clear first milestone. Teams usually start
with codebase questions and small fixes, then move into bugfixes, PR review,
and more complex implementation work once the workflow feels natural.
## Good asks
Start with work that is scoped, visible, and easy to verify:
* explain how a part of the codebase works
* investigate a failing test, flaky preview, or confusing error
* make a small UI or API change
* draft a plan for a larger feature
* review a pull request for regressions
* apply feedback from a source-control or Linear thread
* clean up a small maintenance item that keeps falling off the backlog
A good Roomote prompt includes the desired outcome, links to the relevant
issue or pull request, and any constraints Roomote should respect.
## What to include in the ask
The strongest prompts usually include:
* the outcome you want
* the repository, environment, file path, issue, or PR Roomote should use
* any constraints that matter, such as "do not change the API contract"
* whether you want an explanation, a plan, implementation work, or review
## Ask patterns that work well
| Goal | Good prompt shape |
| -------------------- | ------------------------------------------------------------------------------- |
| Understand something | "Explain how this flow works and point to the code that matters." |
| Plan work | "Read this issue and draft the smallest implementation plan that satisfies it." |
| Investigate | "Figure out why this test or preview is failing and show what you found." |
| Implement | "Make this small change, run the relevant checks, and open a PR." |
| Review | "Review this PR for regressions and call out anything risky." |
## Who uses it
Roomote is meant for the whole team, not just engineers sitting in an IDE.
| Teammate | Good uses |
| ---------------- | ------------------------------------------------------------------------------------- |
| Engineers | Start implementation, fix bugs, investigate failures, review diffs, resolve conflicts |
| PMs and founders | Ask codebase questions, draft plans, turn backlog ideas into scoped tasks |
| Designers | Request UI fixes, verify previews, ask how a flow is implemented |
| Support and ops | Investigate customer-reported issues, attach logs, ask for plain-English explanations |
## What makes a task reviewable
Roomote should leave you with enough evidence to decide what happens next:
* the transcript of what it did and why
* commands, tests, or checks it ran
* logs and terminal output when relevant
* screenshots or live previews for UI work
* code diffs and artifacts
* a pull request or clear next step when code changed
## When to keep the task smaller
Break work down when the ask spans many systems, has unclear product
requirements, or needs human judgment before implementation. Roomote is useful
for getting complex work started, but the best handoffs still give it a clear
first milestone.
# Use your ChatGPT subscription with Roomote
Source: https://docs.roomote.dev/use-chatgpt-subscription
A practical, low-cost model setup for founders and small teams.
This guide is for founders and small teams that want reliable coding models
without starting with usage-billed API keys.
## Recommended starting point
Connect a **ChatGPT Plus** subscription first. Plus currently costs $20/month
and gives Roomote access to supported coding models within the plan's included
limits. If you regularly run many or long tasks, **ChatGPT Pro** currently costs
$200/month and provides higher usage limits. Check [ChatGPT
pricing](https://chatgpt.com/pricing) for current prices and plan limits.
Unlike an API key, a ChatGPT subscription does not create a separate per-token
model bill. Roomote tasks count against the subscription's usage windows instead.
This makes costs easier to predict while you learn how much model capacity your
team needs.
The ChatGPT plan covers model access. Roomote Cloud, self-hosting
infrastructure, and sandbox compute are separate costs.
## Connect ChatGPT
During first-time setup, choose **ChatGPT (subscription)** under **Model
provider**, then select **Connect ChatGPT**. For an existing deployment:
1. Open **Settings > Models** as an admin.
2. Under **Inference Providers**, select **Add provider**.
3. Choose **ChatGPT (subscription)**, then select **Connect ChatGPT**.
4. In the connection dialog, select **Open verification page**.
5. Sign in to the ChatGPT Plus or Pro account you want Roomote to use and enter
the code shown by Roomote.
6. Return to Roomote and wait for **ChatGPT (subscription)** to show as
connected.
7. Enable a supported `openai/...` model, assign it to the coding role, and run
a small task to verify the connection.
No OpenAI API key or deployment environment variable is required. Roomote keeps
the authorization on its control plane rather than exposing it to task
sandboxes. See the [ChatGPT provider reference](/providers/inference/chatgpt)
for usage windows and troubleshooting.
## What about Claude?
Anthropic does not allow Claude Pro or Max subscription credentials to be used
by third-party products such as Roomote. Roomote therefore cannot connect a
Claude subscription the way it connects ChatGPT Plus or Pro.
To use Claude models, add the [Anthropic provider](/providers/inference/anthropic)
and supply an Anthropic API key. Anthropic bills that usage separately by token;
depending on the model, task length, and repository context, a single task can
cost several dollars. Set provider spend limits and monitor costs before making
it the default for frequent tasks.
## Limits to expect
* Plus and Pro are not unlimited. Long tasks and parallel work consume the
plan's included usage windows more quickly.
* Roomote displays 5-hour and weekly ChatGPT usage windows when OpenAI makes
that data available. A missing usage display does not necessarily mean the
connection is broken.
* ChatGPT workspace policies can block the device authorization flow. If Roomote
reports that the Codex app is blocked, ask the ChatGPT workspace admin to
allow it, then restart the connection.
* OpenAI controls which models and limits are included with each ChatGPT plan,
and those can change independently of Roomote.
# Users
Source: https://docs.roomote.dev/users
Manage who can sign in to a Roomote deployment, what role they have, and how password resets work.
Use **Settings > Users** to control who can access your Roomote deployment.
Users are deployment-level. Roomote does not make each deployment manage
separate organizations or workspaces inside the app. Instead, admins choose who
can sign in, invite new people, assign roles, remove access, and create
password reset links for email/password accounts.
## Roles
Roomote has two user roles:
| Role | What it can do |
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Admin | Configure the deployment, manage users, connect providers, edit environments, configure automations, and use Roomote. |
| Member | Use Roomote without changing deployment-wide settings. Members can launch and review tasks with Admin-configured environments, manage their own profile, and link their own accounts. Only Admins can create, inspect, edit, or delete environment configuration. |
The first user in a deployment becomes the founding admin. After that, admins
can invite people as either **Admin** or **Member**, and can change another
user's role from the user list.
Roomote protects the deployment from losing all admins:
* you cannot change your own role
* you cannot demote the last active admin
* you cannot remove yourself
* you cannot remove the last active admin
If you need to step down as admin, promote another user first.
## Who can sign in
Roomote supports several sign-in paths. Which ones appear depends on how the
deployment is configured.
| Mechanism | Who it is for | Notes |
| ------------------ | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| Invite links | New users who should join the deployment directly | Admins create invite links from **Settings > Users**. |
| Email and password | Users who join through an invite and want a local credential | Existing email/password users can keep signing in with that credential. |
| Slack | Deployments that use a Slack workspace as their identity boundary | Slack can admit users from the connected workspace when Slack sign-in is configured. |
| Microsoft | Deployments that use Microsoft Teams or Microsoft Entra accounts | Microsoft sign-in can admit users from the configured Microsoft tenant. |
An invite link can be used with email/password or with any configured sign-in
provider. This is useful when you want to invite someone who is outside your
Slack workspace or Microsoft tenant, or when you want to grant a specific role
at join time.
When someone opens a valid invite, Roomote identifies the invited role before
they sign in and lets them continue with a configured provider or create an
email/password account. New Members then link any eligible personal accounts
and see the ways they can invoke Roomote. Existing users can still sign in when
an invite has expired, been revoked, or been used up.
Operators can also configure an email allowlist for a self-hosted deployment.
When that allowlist is active, a user still needs to pass the normal sign-in
rules and have an allowed email address.
## Staying signed in
Web sign-in sessions last 30 days from sign-in or the last renewal. While you
use the web app, eligible browser requests renew both the session and its
cookie, at most once every 24 hours. Simply leaving a sleeping or closed browser
open does not renew a session. After the session expires, sign in again.
Signing out, removal by an admin, and password resets still revoke sessions.
Clearing browser cookies or rotating the deployment's session-signing secret
also requires signing in again. Sign out when using a shared device.
## License and seats
A Roomote deployment is free for up to 10 users. Every registered user
account in the deployment counts toward the limit, whichever sign-in path or
surface they use. Removed users free their seat.
To add more than 10 users, [buy a self-hosted license on Roomote
Cloud](https://cloud.roomote.dev/sign-up), then apply its key in either of these
ways:
* enter it in **Settings > Users > License** as an admin, or
* set `R_LICENSE_KEY` on the deployment (for example in Compose / `.env.production`);
when that env var is set, it takes precedence over any key stored in Settings
The License section shows the current seat usage, license status, licensee, and
expiry date. Purchased keys are issued annually and can be refreshed from the
Roomote Cloud portal while the subscription is active. Replace the key in
Settings or `R_LICENSE_KEY` after refreshing it.
Keys are signature-verified locally. On self-hosted deployments, they are then
activated with Roomote Cloud for the deployment's stable installation ID. A
paid seat limit remains active while the Cloud activation lease is current (up
to 72 hours); without it, the deployment uses the free-seat limit. Roomote
Cloud deployments use their provisioned valid license directly. Roomote Cloud
records the current user count and short-lived peaks for subscription billing,
independently of anonymous analytics. License usage is not sent to the Ping
analytics service.
Each license may be active on one deployment at a time. If you move a
deployment, contact Roomote support to reset the existing activation before
using its license key on the replacement.
When all seats are in use, existing users keep working normally — only new
sign-ups are blocked until a seat is freed by removing a user or a license key
with more seats is added.
## Create invites
Admins create invites from **Settings > Users**.
Each invite has:
* a label, such as the person or team it is for
* a role, either **Admin** or **Member**
* a maximum number of uses
* a 14-day expiration
When an invite is created, Roomote copies the link to your clipboard when the
browser allows it. The full invite URL is only shown at creation time, so copy
it before leaving the page.
You can revoke an invite before it is used. Revoking an invite does not affect
people who already joined with it.
## Customize account linking help
Admins can add deployment-specific guidance under **Settings > Users > Account
linking help**. Roomote appends this text when an unlinked user tries to start
work from a source-control comment, Discord, or Telegram.
Use it to explain how someone can request an invite or whom to contact. Markdown
links are supported, but plain text with a full URL works across every supported
surface. Leave the field blank to use Roomote's built-in account linking message
without extra guidance.
Slack and Microsoft Teams prompts do not use this setting because users enter
through their configured workspace or tenant rather than an invite.
## Manage existing users
The user list shows active users, their email address, join date, and current
role.
Admins can:
* promote a member to admin
* demote an admin to member, as long as another admin remains
* remove a user from the deployment
* create a password reset link for users with an email/password credential
Removing a user signs them out immediately and removes their linked auth
accounts. Their task history stays in Roomote so old work still has useful
attribution. A removed person can join again later through a new invite or
through an allowed organization sign-in path.
## Password reset flow
Roomote uses admin-created password reset links for email/password accounts.
There is no public self-serve "forgot password" email flow.
To reset a user's password:
1. Open **Settings > Users**.
2. Find the user.
3. Click the reset password action.
4. Create the reset link.
5. Send the link to the user through your preferred secure channel.
Reset links expire after one hour. When the user opens the link, they choose a
new password on the Roomote reset page and then sign in again. Existing
sessions are revoked after the password is reset.
The reset action is only available for users who have an email/password
credential. If a user signs in only through Slack, Microsoft, or another OAuth
provider, reset their password in that provider instead.
## Common issues
* **A new teammate cannot create an account.** Send them an invite link, or
confirm they belong to the configured Slack workspace or Microsoft tenant.
If they see a message about the licensed user limit, the deployment is out
of seats — free one up or add a license key under **Settings > Users**.
* **The invite link no longer works.** It may be expired, revoked, or used up.
Create a new invite from **Settings > Users**.
* **The password reset action is disabled.** The user is OAuth-only. Reset their
password in Slack, Microsoft, or the identity provider they use.
* **An admin cannot be demoted or removed.** Promote another active admin first.
## Related setup
* [Personal Settings](/personal-settings) covers profile details and linked
accounts for individual users.
* [Communications Providers](/communications) explains how Slack and
Microsoft Teams can act as both chat surfaces and auth surfaces.
# Voice
Source: https://docs.roomote.dev/voice
Talk naturally with a Fast Session using GPT-Live.
Voice turns a Fast Session into a natural, full-duplex spoken conversation.
GPT-Live handles listening, speaking, and interruptions while the actual Fast
Session handles questions and work with its selected model, tools, context, and
durable transcript. You can move between voice and text without switching to a
separate voice-only agent.
## Enabling voice
Voice uses OpenAI GPT-Live-1 and needs an OpenAI API key from a project with
GPT-Live access. A deployment admin can enter one from **Settings >
Integrations > Voice**, or a self-hosted operator can set
`R_VOICE_OPENAI_API_KEY`; the environment variable is used when both exist.
Voice is opt-in: the deployment's general `OPENAI_API_KEY` is not used, so
enabling OpenAI for task inference does not turn voice on. See the
[Voice integration](/integrations/voice) page for details.
The Voice integration settings include the GPT-Live voice selection and an
AI-generated audio preview. Existing selections are preserved. New and unset
connections default to Marin, one of OpenAI's recommended voices.
When the voice key is not configured the voice button does not appear. The key
stays on the control plane. The browser sends its WebRTC connection offer to Roomote
and receives only the negotiated session answer; it never receives the API key.
## Using voice
1. Select the voice button in a composer: in an open Session, or on the home
page and the **New Session** dialog. From the home page or dialog a new
Session is created and the call starts inside it.
2. Grant microphone access when the browser asks. A short rising tone
confirms the call is open; a falling tone marks the end. A **Call started**
marker appears in the Session.
3. Talk to Roomote the way you would on a phone call. It acknowledges each
request in a few words, hands the work to the Fast Session, and reports the
result out loud when it lands. Greetings, thanks, and small talk are
answered directly without starting Fast work.
4. Speak at any time to interrupt. Roomote keeps listening while it speaks,
and follow-ups go back through the same Fast Session. You can also type in
the composer during the call.
5. Use the in-call controls to mute your microphone, silence Roomote's audio
without muting yourself, or end the call. The button stays highlighted
while the call is active, and a **Call ended** marker records its length.
Voice input requires a browser with microphone and WebRTC support, which
includes current Chrome, Edge, Safari, and Firefox.
## How the transcript works
A voice call is transcribed into the Session as the record of what was said.
Your speech appears as your messages, and what Roomote said out loud appears
as its replies. The Fast Session's work, such as tool calls, launched tasks,
and reports, appears between those turns exactly as it does in a typed
Session, so the timeline shows both the conversation and the work behind it.
During a call the Fast Session returns its results to the voice rather than
writing them as chat replies; Roomote then reports them in its own words,
keeping numbers, names, paths, and link labels exact. The exact Fast result stays
in the transcript as a collapsed **Reported result to voice** row, including when
the call drops or speech is interrupted. Typed messages sent during a call are
answered in writing as usual.
Each spoken request is cleaned up (filler words, false starts, and misheard
terms) by the deployment's helper model before it reaches the Fast Session.
GPT-Live is told which repositories, environments, and integrations the Fast
Session can reach, so it recognises their names, and the same names guide the
cleanup so a misheard repository name is corrected to the real one.
Ending the call stops the microphone; Fast work already started remains
visible in the Session and follows the normal Session lifecycle.