# MCP Integration Source: https://docs.reasonos.com/agents/mcp rbs speaks the Model Context Protocol in both directions: serve rbs tools to any MCP client, and connect external MCP servers to the rbs agent. rbs integrates with the [Model Context Protocol](https://modelcontextprotocol.io) in both directions: * **As a server** — `rbs mcp serve` exposes the agent's tool surface (graph queries, build/test, search, skills) to any MCP client: Claude Desktop, Claude Code, ChatGPT, or your own tooling. * **As a client** — MCP servers declared in your workspace give the rbs agent extra tools (a browser, a database, an internal API) for its sessions and for `ai_task` targets. ## Serving rbs as an MCP server ```bash theme={null} # stdio mode — for Claude Desktop, Claude Code, and similar clients rbs mcp serve # HTTP mode — a streamable HTTP server rbs mcp serve --http :3001 ``` In stdio mode the server speaks MCP on stdin/stdout. In HTTP mode, point your client at `http://localhost:3001/mcp`. A Claude Desktop configuration looks like: ```json theme={null} { "mcpServers": { "rbs": { "command": "rbs", "args": ["mcp", "serve"] } } } ``` Run it from (or configure the client to start it in) your workspace directory — the server loads the workspace so graph and authoring tools answer from your real target graph. ### The curated tool surface By default the server exposes a **curated** subset of the agent's tools: file reading, search, the graph and knowledge-graph queries, build/test, dependency inspection, and skills. Several tool categories are excluded on purpose: * **Interactive tools** that block waiting on the rbs UI (they would hang your client) * **Agent-loop internals** (todo management, plan mode) that only make sense inside the rbs agent's own loop * **Agent-spawning tools** (delegation, background agents) that would issue LLM calls from inside the server * **Write tools** that mutate the workspace or run commands — excluded unless you opt in Adjust the surface with flags shared by `serve` and `list`: ```bash theme={null} # Include mutating tools (write_file, str_replace, delete_file, # run_command, rbs_run, task/lesson writers) in the curated surface rbs mcp serve --allow-write # Expose every runtime tool rbs mcp serve --tools full # Drop specific tools by name (applies in both modes) rbs mcp serve --exclude-tools rbs_run,delete_file ``` `--allow-write` and `--tools full` let a connected client edit files and execute commands in your workspace. Only enable them for clients you trust, and prefer `--exclude-tools` to trim anything you don't want reachable. ### Previewing the surface `rbs mcp list` prints exactly what a connected client would see, honoring the same flags — including which tools are excluded and why: ```bash theme={null} rbs mcp list rbs mcp list --tools full rbs mcp list --allow-write --exclude-tools rbs_run ``` ### Skills as resources and prompts Beyond tools, the server publishes the agent's [skill corpus](/agents/skills): * every skill is an MCP **resource** under `rbs://skills/` (for example `rbs://skills/bootstrap-workspace`, `rbs://skills/using-go-rules`) * two composed **prompts** let a client bootstrap rbs context in one call: `rbs-onboarding` (workspace bootstrap, monorepo conventions, verification discipline) and `rbs-build-file-authoring` (how rules and `BUILD.rbs` files work) This is how an external agent working in your workspace gets the same maintained guidance the built-in agent runs on. ## Work tools on managed branch servers ReasonOS also exposes a **project-work MCP service**. It is separate from `rbs mcp serve`: rbs tools work on the branch's files/build graph and task cards, while ReasonOS tools work on project issues and other platform records. On a managed branch server, the built-in agent, Claude Code, Codex and Gemini can use the ReasonOS service with the person's session delegation, including from agent-enabled terminals. The delegation is scoped to that node's project; tools enforce the same permissions and product access as the application's routes. Do not copy vendor tokens or a coworker's credentials into the repo. Useful issue tools include: * `work_board` and `list_tasks`: read statuses and issues in the project. * `get_task`: read an issue by its project number, including its work context, its attached files (`id`, `name`, `size_bytes`, `content_type`, the comment a file belongs to, and who added it when) and its drawing links. * `read_task_attachment`: read one attached file by its `attachment_id`. * `create_task`, `update_task` and `move_task`: create or edit an issue and update its status. * `comment_on_task` and `link_task`: record progress and connect related work. `link_task` also links a drawing (`kind: "drawing"` with the drawing's ID as `ref`) when you can open that drawing. A drawing link carries `can_open` for you. A drawing you can't open has no name and no usable reference. `read_task_attachment` returns PNG, JPEG, GIF and WebP files as images. Every other file, including PDF and SVG, comes back as an embedded resource holding the complete file. A file larger than 8 MiB is refused rather than returned in part; open it on the issue in the browser instead. MCP can't upload files. A file's contents are whatever someone uploaded, so treat them as data, not instructions. See [Attach files and drawings to issues](/platform/issue-attachments). A branch session's tools stay within its project. Tools that reach across the organization, such as `list_org_tasks` (existing issues from every project you can read), aren't offered there; to find work in other projects, use [All work](/platform/work#all-work-issues-across-projects) in the app. Other tools cover cycles, labels, initiatives and proposals. Ask the agent to read its available tools rather than assuming the standalone rbs task tools refer to project issues. For example: > Read issue 42 in this project, move it to In Progress, and add a comment > describing your plan. Keep the issue updated as you work. Read the resulting issue activity to verify what the agent actually did. An agent can only take actions your delegated identity is allowed to take. ### Delegating an issue to another branch `delegate_issue_to_branch` takes a project, issue number, linked branch and the id of an existing instruction comment **written by you**. An agent's own comment is not a substitute for that human instruction. The target must already be linked to the issue. With no target server running, the operation refuses unless `start_server` is explicitly true. Starting one consumes a server slot and remains subject to the project's permissions and capacity limits. The result distinguishes **admitted**, **refused** and **unknown**. Admitted means the target accepted the instruction, not that it completed the work. Unknown means delivery may have happened without a readable acknowledgment. The tool does not automatically replay a request; check the issue activity before asking again. The target agent reports its result on the issue. This does not run `git checkout` on the requesting shared server or give an agent unrestricted access to other projects. ## Connecting external MCP servers to the agent Declare MCP servers in your `WORKSPACE.rbs` with `native.define_mcp_server()`. The agent connects to them at session start and their tools appear alongside the built-ins. ```python theme={null} # A stdio server, launched as a subprocess native.define_mcp_server( name = "postgres", command = "npx", args = ["-y", "@modelcontextprotocol/server-postgres"], env = {"DATABASE_URL": "postgres://localhost:5432/dev"}, toolchain = "nodejs", ) # A streamable-HTTP server, reached by URL native.define_mcp_server( name = "internal-api", url = "http://localhost:8080/mcp", ) ``` One of `command` (stdio) or `url` (HTTP) is required. The optional `toolchain` names a registered rbs toolchain whose runtime should resolve the command — so `npx` above runs from the workspace's hermetic Node toolchain rather than whatever is on `PATH`. Skip connecting for a session with `rbs agent --no-mcp`. ### The Chrome DevTools server For browser automation, rbs bundles a helper that registers a Chrome DevTools MCP server — this is what powers `ai_qa_test` browser tests: ```python theme={null} load("@rbs//agent/mcp/chrome/mcp.rbs", "chrome_mcp_server") chrome_mcp_server( name = "chrome", headless = True, # Set install_chrome = True to download Chrome for Testing via the # toolchain system — useful in CI where no browser is installed. ) ``` ### MCP in `ai_task` targets Headless [agent tasks](/agents/using-the-agent#headless-agent-tasks-in-the-build-graph) name the servers they need with the `mcp` attribute; only those servers are connected for the run: ```python theme={null} native.ai_task( name = "qa_checkout", todos = ["open the store", "add an item to the cart", "verify the total"], mcp = ["chrome"], run_targets = [":dev"], ) ``` ## MCP and the external engines When a session runs on an [external engine](/agents/overview#engines), rbs configures the agent with the workspace's declared MCP servers and rbs's own tools. Managed branch sessions also receive the scoped ReasonOS Work service described above. These services have different permissions and purposes; enabling a standalone rbs MCP server alone does not connect it to ReasonOS project issues. # Coding Agent Overview Source: https://docs.reasonos.com/agents/overview The ReasonOS coding agent is built into rbs — it works from your workspace's dependency graph and builds, tests, and runs code through the build system itself. ReasonOS ships a coding agent as part of `rbs`. It is not an editor plugin bolted onto a build tool — the agent, the build system, and the editor share one workspace model, so the agent reasons about your code the same way `rbs` does: as a graph of targets. ## What makes it different ### Graph-first Most coding agents explore a repository by searching text. The ReasonOS agent starts from the workspace dependency graph instead. It has first-class tools to: * list and inspect **targets** (`rbs_targets`), their dependencies (`rbs_deps`) and reverse dependencies (`rbs_rdeps`) * find which target **owns** a source file (`rbs_owners`) * compute the **affected** set for a change (`rbs_affected`) * navigate the workspace knowledge graph — symbols, communities, impact analysis, and path-finding between code entities (the `atlas_*` tools) That means "what breaks if I change this?" is a graph query, not a guess. ### Build-system-native The agent builds and tests through `rbs`, with the same caching and hermeticity you get on the command line: * `rbs_build` and `rbs_test` run real targets and stream real output * `rbs_run` / `rbs_start` / `rbs_stop` execute and manage long-running targets (dev servers, services) in the background * `rbs_rules` and `rbs_validate` let it author and check `BUILD.rbs` files against the actual rule catalog before writing them * external dependency tools let it inspect resolved packages rather than guessing at APIs When the agent says a change builds and its tests pass, it verified that through the build system — not by eyeballing the diff. ## Engines The agent runtime supports several software choices, called **agents** in the UI and **engines** in configuration. The model and its account or API key are separate choices. Each engine integrates with the workspace tools. The in-house, multi-provider engine, also called native. On managed branches, available models come from the accounts and keys configured for you and the project. This is also the engine behind `rbs agent` on the command line. Drives Anthropic's Claude Code CLI as the session's engine. It uses Claude Code's own authentication and receives the rbs tool surface (graph queries, build/test, skills) over MCP, plus a generated `CLAUDE.md` block describing the workspace conventions. Available when the `claude` binary is installed on the branch node. The same arrangement for OpenAI's Codex CLI: its own authentication, the rbs tool surface over MCP, and workspace conventions delivered via `AGENTS.md`. Available when the `codex` binary is installed on the branch node. Runs Google's Gemini CLI with the workspace tools. Available when the `gemini` binary is installed on the branch server and the account has access. **Selecting an agent:** use the **Agent** and **AI model** choices in [AI Work](/platform/ai-work), or the editor's chat controls. A resumed conversation retains its existing agent and model. The `rbs agent` CLI uses the built-in engine. **Defaults have a scope:** Project settings → **Default agent** selects the starting agent for new branch servers; it does not replace settings on already-running servers. Organization Settings → **Agent installation** controls installed CLIs. Your account → **Personal AI accounts** connects your credentials. See [AI accounts and keys](/platform/ai-accounts-and-keys) for branch defaults, browser-local preferences and optional overrides. ## Where it runs * **Terminal** — `rbs agent` starts an interactive session in your shell: a plain REPL by default, or a full-screen interface with `--tui`. See [Using the agent](/agents/using-the-agent). * **The ReasonOS editor** — the editor connects to your branch node's server, which hosts agent sessions alongside the language servers and file watchers. Sessions are multi-client: teammates on the same branch see the same node. * **Across the managed application** — [AI Work](/platform/ai-work) opens the agent alongside project pages, cycles and proposals without opening the editor. It still runs on a branch server, with your project permissions. * **Headless** — `rbs agent "your prompt"` runs a single turn and exits, and `ai_task` targets put agent-driven work (including browser QA tests) directly into the build graph, runnable with `rbs run` and `rbs test`. ## Sessions, memory, and checkpoints **Sessions.** A session is one conversation with the agent — its transcript, permission mode, todo list, and background subagents. Editor sessions persist; CLI chats can be saved. Saved chats live in the committed `.reasonos/ai/chats/` tree, so they travel with the branch through git rather than living on any one machine. **Memory.** The agent keeps two durable stores per branch, both committed under `.reasonos/ai/`: * **Lessons** — observations about what worked and what failed in this repository, recorded as it works. Recent lessons are injected into every new session's context. * **Taste** — style preferences for how this codebase likes its code written. Because both are committed, an agent joining a branch inherits what previous sessions learned there. Long conversations are compacted automatically so a session never runs out of context mid-task. **Checkpoints.** In the editor, the agent snapshots the workspace's file state before it starts modifying files. Every checkpoint records exactly what changed, and you can diff against or revert to any checkpoint — so letting the agent work is never a one-way door. See [Checkpoints](/workflow/checkpoints) for the full workflow. ## Learn more CLI invocations, models and providers, permission modes, and headless tasks. The agent's loadable expertise: built-in skills and how to add your own. Serve rbs tools to external agents, and connect external tools to the rbs agent. # Agent Skills Source: https://docs.reasonos.com/agents/skills Skills are loadable units of expertise — how to work in your repository. The agent ships a built-in corpus and learns new skills from your workspace. A **skill** is a named, loadable set of instructions for doing a particular kind of work: how to use a rule family, how to verify a change, how to bootstrap an empty workspace. The agent sees every skill's name and description up front, and loads the full body only when it decides it needs it — so fifty skills cost almost nothing until one becomes relevant. ## How skills get invoked * **By the agent itself** — the session context lists every available skill with its description; the agent calls its `skill` tool to load one before doing matching work (using a rule family for the first time, authoring `.rbs` build files, finishing a change). * **By you** — in the TUI, `/skills` lists the corpus, `/skill ` shows a skill's body, and every skill is offered as its own slash command: `/verification` asks the agent to load and apply that skill. * **Over MCP** — every skill is also published as an MCP resource when you run `rbs mcp serve`, so external agents can read the same corpus. See [MCP integration](/agents/mcp). ## Built-in skills The built-in corpus has two halves: workflow skills that apply everywhere, and one usage guide per rule family. A rule family's skill ships in the same module as its rules — load the Go rules and "how to use the Go rules" is right there, and it cannot drift from the implementation. | Skill | What it teaches | | - | - | | `bootstrap-workspace` | Turning an empty workspace (graph shows 0 targets) into a building project — verified starting files, in build order. | | `monorepo-conventions` | Target naming, scaffolding, and layout conventions that make CI and affected-target selection work with zero setup. | | `rbs-rule-authoring` | Authoring a new build rule when no existing rule expresses how something builds — read before writing any `define_rule`. | | `verification` | How to verify work before reporting it done: build, test, and actually run it. | | `writing-tests` | Writing tests that catch real regressions: the right layer, the real environment, pinned to defects. | | `concise-code` | Writing the smallest correct diff: find what already exists, extend live code, delete dead code, match the local idiom. | | `reliability` | Making a component production-reliable: atomic writes, content validation over existence checks, fail-closed semantics, bounded resources. | | `delegation` | Using the delegation and background-agent tools: when to fan out, how to brief a subagent, how to integrate results. | | `sql-migrations` | Writing and running SQL migrations with `rbs migrate` so every schema change stays safe for the previous and next application version. | | `env-schema` | Declaring and consuming workspace environment with `.env` files and the composable `.env.schema`. | | `pr-and-stacks` | Creating change requests and working in stacked diffs with `rbs stack`. | One `using--rules` skill per built-in rule family: | Skill | Covers | | - | - | | `using-go-rules` | Go binaries, tests, coverage gating, cross-compiling, proto codegen. | | `using-python-rules` | Python binaries/libraries/tests, pip dependencies, the hermetic toolchain, linting. | | `using-nodejs-rules` | Node.js services and tools, npm dependencies, test runners, linters. | | `using-typescript-rules` | TypeScript language support and how tsconfig resolution is owned by generated config. | | `using-web-vite-rules` | Web micro-frontends: module federation hosts/remotes, shared libraries, vitest coverage gates, SSR. | | `using-java-rules` | Java binaries/libraries/tests, Maven dependencies, the hermetic JDK toolchain. | | `using-kotlin-rules` | Kotlin/JVM targets mirroring the Java rules, shared Maven ecosystem. | | `using-c-rules` | C targets, the hermetic C toolchain, automatic `compile_commands.json`. | | `using-cxx-rules` | C++ targets and the hermetic C++ toolchain. | | `using-dotnet-rules` | C#/.NET builds driven by `dotnet publish`, pinned SDK toolchains. | | `using-proto-rules` | Protobuf/gRPC codegen: protoc toolchains and per-language proto libraries. | | `using-oci-rules` | Container images: building, tarballs, and pushing via `rbs run`. | | `using-k8s-rules` | Kubernetes deploys with rendered manifests and deploy-time image resolution. | | `using-infra-rules` | Cloud infrastructure declared in `.rbs` files, multicloud providers, `rbs infra plan/apply`. | | `using-migration-rules` | SQL migration targets driven by `rbs migrate`. | | `using-job-rules` | Batch and ML compute job targets and the job scheduler CLI. | | `using-agent-rules` | Extending the agent itself from the build language: custom tools, skills, subagents, QA tests, MCP servers. | ## Custom skills You can add skills in two formats, and both share the same surface as the built-ins. ### RBS language: `native.define_skill` Declare a skill in any `.rbs` module — typically next to the thing it teaches. A `skills.rbs` under your workspace's `rules/` directory is discovered automatically, without anything loading it: ```python theme={null} native.define_skill( name = "using-my-rule", description = "When and how to use my_rule targets", usage = "optional one-line usage hint", prompt = """# Using my_rule ...usage guidance, a worked example, common mistakes... """, ) ``` If you author a custom build rule, ship its skill in the same module — every workspace that loads your rules also teaches its agents how to use them. ### Claude Code format: `SKILL.md` The agent also reads skills in Claude Code's format, from the same places Claude Code looks: `.claude/skills//SKILL.md` in the workspace, then in your home directory. An existing skill library carries over without being copied: ```markdown theme={null} --- name: release-notes description: How we write release notes for this repo --- The full instructions go here... ``` ### Precedence When the same name exists in several places, the first source wins, in this order: 1. Skills registered by `.rbs` modules the workspace actually loads 2. `.claude/skills/` in the workspace, then your home directory 3. Skills declared in the workspace's `rules/` tree 4. Skills from fetched external rule packages 5. The embedded built-ins So a workspace can override any built-in skill by shadowing its name. # Using the Agent Source: https://docs.reasonos.com/agents/using-the-agent Run the coding agent from the terminal: interactive sessions, one-shot prompts, model selection, permission modes, and headless agent tasks. ## Starting a session Run `rbs agent` from anywhere inside a workspace: ```bash theme={null} # Interactive session (plain REPL) rbs agent # Full-screen terminal interface rbs agent --tui # One-shot: run a single turn and exit rbs agent "why is //api:server_test failing?" ``` Without arguments, the agent starts an interactive session with inline permission prompts. With a prompt argument it runs one turn headless and exits — nothing prompts, and mutations are denied unless you pass a `--mode` that allows them. On startup the agent loads the workspace — `WORKSPACE.rbs` and every `BUILD.rbs` — so its graph tools answer from your real target graph, and connects any MCP servers declared in the workspace. ## Providers and API keys The native engine discovers model providers from your environment: | Environment variable | Provider | | - | - | | `ANTHROPIC_API_KEY` | Anthropic (Claude models) | | `OPENAI_API_KEY` | OpenAI (GPT models) | | `GOOGLE_API_KEY` or `GEMINI_API_KEY` | Google (Gemini models) | | `XAI_API_KEY` | xAI (Grok models) | | `REASONOS_LLM_URL` + `REASONOS_TOKEN` | ReasonOS hosted service | Keys come from the environment on purpose — workspace files are committed, and an API key in a committed file is a leaked key. When the hosted service is configured, it also acts as a fallback for models no local provider serves. ## Choosing a model Pass `--model` with a model ID, a short alias, or a `provider/model` reference: ```bash theme={null} rbs agent --model claude-opus-5 # full model ID (the default) rbs agent --model sonnet # alias rbs agent --model fast # alias (Claude Haiku) rbs agent --model hosted/fast # provider/model reference rbs agent --model gpt-5 "review the diff on this branch" ``` Inside a session, `/models` lists every model your configured providers can serve. Useful aliases include `opus`, `sonnet`, `fable`, `haiku`, `fast`, `gpt5`, `gemini`, and `grok`. For models with controllable reasoning, `--effort low|medium|high|max` sets how hard the model thinks per step. ## Permission modes The agent asks before doing anything destructive. The session's **mode** sets its default posture toward mutating tools: | Mode | Behavior | | - | - | | `manual` | Ask before anything that edits files or executes commands. The default. | | `accept_edits` | Allow file edits without asking; still ask before executing commands. | | `auto` | Allow everything. Never a default — you must choose it. | | `plan` | Deny every mutation. Investigation only. | ```bash theme={null} rbs agent --mode accept_edits ``` In an interactive session, permission requests appear inline: answer with a numbered option or a bare `y`/`n`. You can allow a tool "for the rest of the session" so you are not asked repeatedly — that consent does not carry over if you later switch to a more permissive mode. Switch modes mid-session with `/mode`: ``` › /mode accept_edits ``` Headless runs (`rbs agent "prompt"`) have no one to ask, so anything that needs consent is **denied**, not silently allowed. Pass `--mode auto` only when you intend a fully autonomous run. ## Flags | Flag | Effect | | - | - | | `--model ` | Model ID, alias, or `provider/model` reference | | `--mode ` | Permission mode: `manual`, `accept_edits`, `auto`, `plan` | | `--effort ` | Reasoning effort: `low`, `medium`, `high`, `max` | | `--max-steps ` | Cap model calls per turn | | `--worktree ` | Isolate the session's edits in a git worktree | | `--tui` | Full-screen terminal interface (interactive only) | | `--no-graph` | Skip loading the build graph | | `--no-mcp` | Skip connecting workspace MCP servers | | `--print-prompt` | Print the assembled system prompt and tool definitions with sizes, then exit | The global `rbs` flags also apply — notably `-e`/`--env` to select the workspace environment and `--workspace-root` to point at a workspace explicitly. ## Slash commands In the plain REPL: ``` /mode [m] show or set the permission mode /todos show the session task list /agents list background subagents /processes list background processes the agent started /models list available models /help show commands /quit exit ``` The `--tui` interface supports those plus `/clear`, `/model`, `/tools`, `/skills`, `/skill `, `/status`, `/session`, `/save`, and `/history`. Every loadable [skill](/agents/skills) is also offered as its own slash command — typing `/verification`, for example, asks the agent to load and apply that skill. ## Isolating edits with a worktree On a branch node several people (and several agents) can share one checkout. To keep an agent's edits out of the shared tree, give the session its own git worktree: ```bash theme={null} rbs agent --worktree fix-flaky-test ``` The agent edits files in an isolated worktree on its own session branch; merging its work back is an explicit, reviewable step rather than an accident of interleaving. ## Saving and reviewing sessions In the TUI, `/save` writes the current chat to the committed `.reasonos/ai/chats/` tree and `/history` lists recent saved chats. Because chats are committed, they travel with the branch — a teammate pulling the branch can read what the agent did and why. The CLI does not resume a saved chat into a live session — each `rbs agent` run starts fresh (with the branch's [lessons and taste memory](/agents/overview#sessions-memory-and-checkpoints) already loaded). Editor sessions on the branch node persist across reconnects. ## Delegation and background agents The agent can fan work out rather than doing everything in one context: * **`delegate` / `delegate_parallel`** — hand scoped tasks to subagents and wait for their conclusions. Good for large searches and self-contained investigations. * **Background agents** — `start_agent` launches a named agent that keeps working while the conversation continues; `/agents` lists them, and the session can read from, message, or stop them. You can define reusable subagent presets in the build language — a name, system prompt, and restricted tool set — with `native.define_subagent(...)` in any loaded `.rbs` module, then request them by name when delegating. ## Headless agent tasks in the build graph `ai_task` targets make agent-driven work a first-class part of the graph. Declared with `kind = "test"` (the default) they are discoverable by `rbs test`; they can start services first, connect MCP servers, and run the agent through an ordered list of steps in `auto` mode. The most common form is a browser QA test, using the bundled `ai_qa_test` wrapper — it wires up a Chrome DevTools MCP server so the agent can drive a real browser: ```python theme={null} load("@rbs//agent/ai_task.rbs", "ai_qa_test") ai_qa_test( name = "qa_login", run_targets = [":dev"], # start the dev server first todos = [ "go to the login page", "sign in with the seeded test user", "verify the user id is shown in the header", ], headless = True, # set False to watch the browser timeout = 300, ) ``` ```bash theme={null} rbs test //web/app:qa_login ``` Under the hood this is the `ai_task` rule, which you can use directly for non-browser tasks: ```python theme={null} native.ai_task( name = "smoke", kind = "test", # "test" targets run under `rbs test` todos = ["build //api:server", "run its unit tests", "report PASS or FAIL"], run_targets = [], # targets to start in the background mcp = [], # MCP server names to connect model = "", # optional model override timeout = 300, # seconds ) ``` The task passes when the agent completes its steps and reports success; otherwise the target fails like any other test. # Adopt an existing repo Source: https://docs.reasonos.com/build/adopt Run rbs in any repo with zero config — run/build/test detect the project type automatically, and rbs adopt materializes the same config as editable files rbs works in a repository that has never heard of it. In a directory with no `WORKSPACE.rbs`, the everyday commands detect the project type themselves and run against a synthesized workspace — and `rbs adopt` materializes that same config as real files when you want to start editing it. ## Zero config: just run it ```bash theme={null} cd my-existing-service # a plain Go / Node / Python repo rbs run # ⚡ detects the stack, builds, runs the app rbs build # builds everything it synthesized rbs test # runs the detected test targets ``` Detection fingerprints the project (a `go.mod`, a `package.json`, a `requirements.txt`, …) and generates config under `.rbs/zero-config/` — rbs-owned state, never your checkout; rbs even adds `.rbs/` to `.git/info/exclude` so `git status` stays clean. Bare `rbs run` runs the detected default target. Run the commands from a subdirectory and rbs detects at the enclosing git root. `rbs query` and `rbs graph` show the synthesized targets too, and agents running on the branch server see the same graph. Opening a non-rbs repo in the ReasonOS editor shows the same thing as a slim banner: *"Zero-config: detected go — build, run and test already work."* Its **Adopt** button writes the exact config zero-config has been executing into the repo — the same files `rbs adopt` produces. ## Adopt: materialize the config `rbs adopt` writes the `WORKSPACE.rbs` and `BUILD.rbs` a person familiar with rbs would have written by hand — toolchain pinned from your version files, dependencies declared from your manifest, a runnable binary target, test targets when tests exist. It is byte-identical to what zero-config mode was executing, so nothing changes behavior — the config just becomes yours to edit. ```bash theme={null} cd my-existing-service rbs adopt # then it's a normal rbs workspace: rbs build :all rbs run //:my_service rbs test ``` The generated files are yours: they carry a "review and edit" header, and `rbs adopt` never rewrites them afterwards. There is no hidden configuration layer — what adopt generates is exactly the config you edit as the project grows. ## Command forms ```bash theme={null} rbs adopt # adopt the current directory rbs adopt path/to/repo # adopt another directory rbs adopt --list # show every matching converter, ranked rbs adopt --dry-run # print the generated files without writing rbs adopt --converter python # override detection ranking rbs adopt --force # overwrite previously generated files ``` Adopt refuses a directory that already contains a `WORKSPACE.rbs`, and refuses to nest a workspace inside an existing one — add a `BUILD.rbs` package to the enclosing workspace instead. ## What gets detected | Converter | Fingerprints | Generated config | | - | - | - | | **go** | `go.mod`, `go.work`, `main.go` | `go_toolchain` matched to the `go.mod` directive; `go_binary` for the root package or one per `cmd/*`; `go_test` over `./...` when `*_test.go` exist; an `oci_image` so `rbs build //:image` produces a container image | | **java** | `pom.xml`, `build.gradle`, `build.gradle.kts`, `gradlew` | `java_toolchain` from `java.version`/`maven.compiler.*`/`sourceCompatibility` (any JDK major works); `java_repository` per declared Maven/Gradle dependency; `java_library` + `java_binary` (main class auto-detected, `@SpringBootApplication` preferred); `java_test` with JUnit auto-included when `src/test/java` exists | | **python** | `pyproject.toml`, `requirements.txt`, `Pipfile`, `manage.py`, `main.py`/`app.py`/… | `python_toolchain` from `.python-version` or `runtime.txt`; `py_repository` per pinned requirement; `py_binary` (Django gets `manage.py runserver`); `py_test` when tests exist | | **kotlin** | `*.kt` sources (usually Gradle) | `java_toolchain` + `kotlin_toolchain`; `kotlin_repository` per Gradle dependency; `kotlin_binary` with the detected top-level main; `kotlin_test` | | **node** | `package.json` | `nodejs_toolchain` (an exact `engines.node` pin is honored); `nodejs_repository` per production dependency; `nodejs_binary` from `scripts.start`, the `main` field, or `server`/`index`/`app` in `.js` or `.ts`; `vitest_test` when vitest and test files are present | | **vite** | `vite.config.*` | `nodejs_toolchain`; `nodejs_repository` deps; `vite_app` for the detected `src/main.*` entry; `vitest_test` — takes precedence over plain node for Vite apps | | **dotnet** | `*.csproj` | `dotnet_toolchain` (SDK from ``); `dotnet_binary` with sources plus the project file | | **c / c++** | `*.c` / `*.cpp` sources | hermetic zig-based `c_toolchain`/`cxx_toolchain`; `c_binary`/`cxx_binary` (CMake/meson/Makefile definitions are reported, not parsed) | ## Container image out of the box For Go projects the generated config includes a container image: a cross-compiled linux binary on a minimal `scratch` base. Building it needs no Docker daemon — rbs assembles the image itself: ```bash theme={null} rbs build //:image docker load < .rbs/bin//image/image.tar docker run :latest ``` The generated file explains how to switch the base image (for CA certificates or a shell) and how to upgrade to a multi-arch image index. Node and Python images aren't generated yet — they need a linux-native runtime inside the image; the converter tells you so during adopt. When a repo matches several converters, ranking follows language priority first (a Go service with a docs `package.json` adopts as Go), then detection confidence. Anything a converter can't translate — an unpinned requirement, a `file:` dependency, TypeScript builds — is reported as a note during adopt, never silently dropped. ## Extending detection Converters are Starlark, not compiled-in logic. Rule authors register one with `native.define_project_converter(name, detect, convert, priority)`, and detection is extensible without rebuilding rbs — point at an external converter pack: ```bash theme={null} rbs adopt --rules https://git.example/acme-converters@v1.0.0 # or, for every adopt and zero-config run on this machine/node: export RBS_CONVERTER_RULES=https://git.example/acme-converters@v1.0.0 ``` A pack is a git repo (fetched pinned to the ref, same as `rbs ext`) or a local directory whose `convert.rbs` modules register converters. A pack converter that re-declares an embedded name overrides it. See [Custom rules](/reference/custom-rules) for the rule-authoring surface. # Caching Source: https://docs.reasonos.com/build/caching How the shared content-addressed cache speeds up builds, and how to inspect and manage it with rbs cache. rbs has exactly one build cache: a **user-global, content-addressed store** shared by every workspace on your machine. Build a target in one workspace, and any other workspace that produces the same action gets a cache hit — no per-project cache directories to warm up or clean out. ## Where the cache lives By default the store lives under `~/.cache/rbs` (the content store itself sits in a versioned subdirectory, e.g. `~/.cache/rbs/v1`). To relocate it — for example onto a larger volume — set `RBS_CACHE_DIR`: ```bash theme={null} export RBS_CACHE_DIR=/mnt/bigdisk/rbs-cache ``` Your workspace's `.rbs/` directory is **not** a cache. It holds only materialized state — build outputs, toolchain links, resolved external dependencies — all of which rbs recreates on demand. Deleting `.rbs/` forces a rebuild but loses nothing durable. The cache is **user-global**. Every workspace on the machine reads from and writes to the same store, so cache management commands affect all of your projects at once — never just the one you happen to be standing in. ## What gets cached The store holds two kinds of entries: * **Content blobs** — the files actions produce (and consume), addressed by their content hash. Identical content is stored once, no matter how many targets or workspaces reference it. * **Action results** — a record that a given action (command + inputs + environment) already ran, pointing at the blobs it produced. When you rebuild, rbs looks up each action here and restores its outputs instead of re-executing it. Alongside the content store, rbs keeps other user-global caches that the `rbs cache` commands manage with the same age bounds: * **OCI images** — container images pulled for image-based rules * **Toolchains** — downloaded language toolchains (see [Toolchains](/build/toolchains)) * **External deps** — resolved third-party packages (see [External dependencies](/build/external-dependencies)) * **Terraform providers** — provider plugins downloaded for infra targets ## Inspecting the cache ```bash theme={null} rbs cache stats ``` This reports the store location and the size of each cache: ```text theme={null} 📊 Cache Statistics =================== Store: /Users/you/.cache/rbs/v1 (shared across every workspace for this user) 📦 Content blobs: 12841 (3120.44 MB) 🎯 Action results: 1904 (12.10 MB) 🐳 OCI images: 812.30 MB 🔧 Toolchains: 1450.02 MB 📚 External deps: 640.88 MB 🧩 Terraform providers: 210.55 MB 📊 Total: 6246.29 MB ``` Run inside a workspace, `stats` also breaks down that workspace's materialized `.rbs/` state, one line per top-level directory — useful for seeing where local disk usage actually is: ```text theme={null} 🗂 Workspace state: /Users/you/myproject/.rbs gocache 2140.11 MB out 890.45 MB toolchains 0.02 MB total 3030.58 MB (materialized from the store and sources; deleting it forces a rebuild but loses nothing durable) ``` ## Bounding the cache: `rbs cache gc` Garbage collection is the recommended way to keep the cache in check. It sweeps entries by age first, then evicts the least-recently-used content until the store is under its size budget: ```bash theme={null} # Defaults: drop anything not accessed in 30 days, keep the store under 20 GiB rbs cache gc # Custom bounds rbs cache gc --max-age 14d --max-gb 10 ``` | Flag | Default | Meaning | | - | - | - | | `--max-age` | `30d` | Collect anything not accessed within this window | | `--max-gb` | `20` | Size budget in GiB; least-recently-used blobs beyond it are collected | Age values support weeks and days on top of the usual units: `2w`, `7d`, `24h`, `30m`, `90s`. The same pass also ages out the OCI image cache, the toolchain store, the external-deps store, and Terraform providers. Anything swept is rebuilt or re-downloaded automatically the next time it's needed. You rarely need to run `gc` by hand — rbs runs a bounded GC pass automatically at most once per day after builds. Run it manually when you want space back right now. ## Removing entries: `rbs cache clean` `clean` removes store entries outright: ```bash theme={null} # Remove entries older than 7 days rbs cache clean --max-age 7d # Remove everything (every workspace's next build goes cold) rbs cache clean --all ``` Bare `rbs cache clean` — with no flags — is **refused**: ```text theme={null} refusing to empty the shared store at /Users/you/.cache/rbs/v1 — it is used by every workspace for this user rbs cache gc bound it by age and size (recommended) rbs cache clean --max-age 7d remove entries older than 7 days rbs cache clean --all remove everything (rebuildable, but every build goes cold) ``` Because the store is shared, "clean this project" is never what emptying it would do. Make the intent explicit with `--max-age` or `--all`. Everything `clean` removes is rebuildable — but after `--all`, every build on the machine starts from scratch. # Everyday commands Source: https://docs.reasonos.com/build/commands Build, test, run, query, graph, and coverage — the rbs commands you use all day Six commands cover the day-to-day loop. They all accept the same [labels and target patterns](/build/packages-and-targets#target-patterns), and they all share three global flags: | Flag | Purpose | | - | - | | `-e, --env ` | Select an [environment](/build/environments) declared in `.env.schema` (also `RBS_ENV`) | | `--platforms ` | Target platform to build for (e.g. `linux-amd64`) | | `--workspace-root ` | Explicit workspace root (also `RBS_WORKSPACE_ROOT`) | ## rbs build Builds one or more targets, resolving the full dependency closure, executing in dependency order, and running independent targets in parallel. Results come from the shared cache when nothing relevant changed. ```bash theme={null} rbs build :hello # one target in the current package rbs build //services/api:server # one target by full label rbs build //... # everything in the workspace rbs build :all # everything in the current package (the default) rbs build services/api server migrate # several targets in one package ``` Key flags: | Flag | Purpose | | - | - | | `-j, --jobs ` | Cap parallel jobs (`0` = unlimited, the default) | | `--no-cache` | Re-run every action for this build instead of using cached results | | `--cache-mode ` | `auto` (default), `force-miss`, or `force-hit` | | `-w, --watch` | Rebuild automatically when source files change | | `--remote ` | Use a remote cache (defaults to `$RBS_REMOTE` when set) | | `--remote-exec` | Execute cache misses on the remote cluster's workers | ```bash theme={null} rbs build //app:lib --watch # auto-rebuild on change rbs build //... --remote cache.internal:8980 # share results with your team ``` Before executing, rbs prints the execution plan — every target in the closure and what it depends on — so you can see exactly what a build will do. ## rbs test Builds the requested targets and runs the ones that are tests. Test targets are the ones declared with a test rule (`go_test`, `py_test`, `vitest_test`, and so on — any rule whose kind ends in `_test` or is registered as a test). ```bash theme={null} rbs test :all # all tests in the current package (the default) rbs test //... # every test in the workspace rbs test //services/api:api_test # one test target rbs test :api_test --watch # TDD: re-run on every file change ``` Test output is captured under `.rbs/testlogs////test.log`, so a noisy suite doesn't scroll your terminal history away. `rbs test` does **not** enforce coverage thresholds. If a test target declares `min_line_coverage` (or branch/function thresholds), `rbs test` runs it and prints a reminder — the gate only fires under `rbs coverage`. ## rbs run Builds a target (and its dependencies), then executes it. ```bash theme={null} rbs run :server # build and run 'server' in the current package rbs run //tools:migrate # full label rbs run services/api server # natural syntax ``` ### Multiple targets in parallel Pass several targets — or `-p/--parallel` — and rbs builds them all first, then runs them simultaneously. `Ctrl+C` stops every process. This is the standard way to bring up a local stack: ```bash theme={null} rbs run //services/api:server //web/shell:dev --parallel rbs run shell:shell remote:counter # two or more targets imply parallel mode ``` ### Watch mode `--watch` rebuilds and restarts the process whenever source files change: ```bash theme={null} rbs run :server --watch ``` ### Side-effect targets Building stays pure — nothing a build does touches the outside world. Rules whose whole point is a side effect (pushing an image, applying manifests) perform it at **run** time instead: ```bash theme={null} rbs run //services/api:push # push the built image to its registry rbs run //services/api:deploy # apply the rendered Kubernetes manifests ``` ## rbs query Lists targets matching a pattern without building anything. Useful for exploring a workspace and for scripting. ```bash theme={null} rbs query # every target in the workspace (//...) rbs query //services/... # everything under services/ rbs query //services/api:all # one package rbs query :dev # one target in the current package ``` | Flag | Purpose | | - | - | | `-o, --output ` | `label` (default, one label per line), `kind` (`