DEV Community

Cover image for A 🪨 roc for you
Andrei Merlescu
Andrei Merlescu

Posted on

A 🪨 roc for you

https://github.com/andreimerlescu/roc

This is roc a new #rust project that I wrote with Claude Cowork Opus 5.5 Max. I needed:

  1. To run either claude (code), codex (openAI), goose (by block), or opencode.
  2. I wanted the roc to run on a single Mac Studio that has 256GB of RAM with multiple parallel loaded models (concurrency set to 1).
  3. I wanted to also be able to use public models too.
  4. I wanted a state file that kept track of my settings.
  5. I wanted to give the agent full read/write access to my system, but I did not want to let it remove critical or personal files by accident. roc isolates the agent in a container.

github about roc

I was sick of having to babysit the agent. In an isolated environment, please, go build. Implement AGENTS.md is such a powerful prompt to use.

I configured my roc 🪨 to support 4 concurrent models at the same time. They are each 16GB in size and they do a pretty good job. Each have a context window of 256K tokens. This means that I have 4 concurrent workers with a window of 1M tokens before a flush of any quarter. It's configured to use a rolling window and connect to LMStudio when it runs.

lmstudio

roc -h returns:

roc (run opencode container): launch AI coding agents (opencode, goose, claude code, codex) against LM Studio, Ollama or any OpenAI-compatible model inside a disposable Docker container with 1:1 host path mounts and a policy-enforced MCP gateway.

Usage: roc [OPTIONS] [-- <AGENT_ARGS>...]

Arguments:
  [AGENT_ARGS]...  Arguments for the agent (after --)

Options:
      --provider <KIND>       Model server: lmstudio | ollama | openai | none (saved to state) [env: ROC_PROVIDER=]
      --ai-host <URL>         OpenAI-compatible base URL, e.g. http://127.0.0.1:1234/v1 (saved to state) [env: ROC_AI_HOST=]
      --ai-api-token <TOKEN>  API token for the model server (never saved; default: $ROC_AI_API_TOKEN)
      --ai-model <ID>         Model id; LM Studio workers are <model>, <model>:2, … (saved to state)
      --qty <N>               Number of model workers in the pool (saved to state)
      --state <PATH>          State file [env: ROC_STATE=]
      --binary <NAME>         Agent: opencode | goose | claudecode | codex
  -w, --write-dir <CSV>       Read-write directories (CSV, repeatable), mounted 1:1
  -r, --read-dir <CSV>        Read-only directories (CSV, repeatable), mounted 1:1
      --workdir <PATH>        Working directory inside the container (default: current dir if mounted)
      --image <IMAGE>         Agent image [env: ROC_IMAGE=]
      --worker <N>            Use this worker number (default: lowest available)
      --wait <SECS>           Wait up to SECS for a worker to become available [default: 0]
      --publish <CSV>         Publish agent container ports on host 127.0.0.1 (CSV: 5173,8080:80)
      --env <CSV>             Extra env for the agent (CSV): NAME passes the host value, NAME=VALUE sets it
      --list                  Show worker status: `Q #N: running|available|offline`
      --json                  With -list: machine readable JSON
      --cleanup               Remove resources of dead sessions and orphaned roc containers
      --init                  Guided setup: asks questions and writes the state file and agent configs
      --yes                   With -init: accept every default without asking (also used when stdin is not a terminal)
      --agent-config          Show (and create) this config's agent files for -binary, and where they apply
      --force                 With -init: overwrite an existing state file (a backup is kept)
      --show-state            Print the state file
      --build-image           Build the agent image from the Dockerfile embedded in roc
      --with-playwright       With -build-image: include Playwright + Chromium for the playwright MCP
      --dry-run               Print what would run (docker command and generated configs) and exit
      --assume-available      Do not probe the model server; treat every free worker as available
      --keep-images           Keep images the agent built/pulled when the session ends
      --no-mcp                Do not start the MCP gateway or configure MCP servers
      --save                  Save -binary, -image, -read-dir, -write-dir and -publish as defaults
  -h, --help                  Print help
  -V, --version               Print version

EXAMPLES:
  roc -init                      # guided setup
  roc -list
  roc -write-dir ~/friends_of/planning -read-dir ~/work
  roc -ai-model qwen3.8-27b -qty 4 -binary opencode \
      -write-dir "~/friends_of/planning,~/friends_of/knowledge" -read-dir "~/work,~/statuses"
  roc -provider ollama -ai-model qwen3:27b -qty 2
  roc -provider openai -ai-host https://api.openai.com/v1 -ai-model gpt-5 -qty 8
  roc -binary codex -worker 3 -- --search
  roc -agent-config -binary claudecode
  roc -cleanup

Flags may be written with one dash (-list) or two (--list).
Docs: https://github.com/andreimerlescu/roc
Enter fullscreen mode Exit fullscreen mode

You'll need to have docker running and you'll need to run roc -build-image in order to get the container that can run the roc session. roc doesn't run in the container, the opencode, codex, claude, and goose binaries are installed via the Dockerfile and used there. My roc is using -binary opencode.

Once you have the container you can run roc -init and begin the setup process. It writes your answers to your state file, or you can use the -save option after supplying your items manually. That writes them to the state file. Don't pass your API keys in CLI arguments since they are leaked in history.

For my setup, I am using 4 worker agents that I am calling Q #1, Q #2, Q #3 and Q #4 since that's short for Qwen and the models are trained off from Qwen3.8-27b for mlx. Since -worker 4 is set on my hardware, the first time I run roc the Q #1 is assigned first. Then the second time I run roc then Q #2 is selected. Then #3 and then #4.

I share roc with you so that you too can set your agents up for success and let them build in an isolated environment.

Feel free to perform your own security review or code review of the project.

https://github.com/andreimerlescu/roc

PSA If you have web endpoints that you use services like httpd or nginx to protect, consider placing concert in front of it as an enhanced x402 supporting waiting room reverse proxy that has fast lane support and is also open source under Apache 2.0.

https://github.com/andreimerlescu/concert

Enjoy!

With great power comes great responsibility!

Top comments (0)