The project is in a healthy, maintained state
Thin Rails wrapper around the mcptask_runner Go binary. Ships the platform-specific binary inside the gem and exposes the same rake tasks as the legacy mcptask_runner gem, delegating 1:1 to the CLI. Drives Claude Code, Codex CLI or OpenCode — pick one with `mcptask_runner:install[--cli <name>]`. Works with GitHub and Bitbucket Cloud repos (`--git-host <name>`).
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

>= 6.0
 Project Readme

mcptask-rails-runner

Rails distribution of the mcptask.online autonomous runner, and the way a Rails app installs it. A thin Ruby wrapper around the mcptask_runner Go binary: the gem ships the platform-specific binary inside itself (libexec/) and exposes the same rake tasks as the legacy mcptask_runner gem, delegating 1:1 to the CLI.

The legacy gem is retired. It gets critical fixes only, and it stays in existence as the reference implementation the Go runner's conformance suite measures against; everything new is written in Go. What you gain by moving: Linux and Windows hosts, a scheduled job with no bundler in its path, and a handful of places where the old implementation was simply wrong (its token resolution read a different half of .mcp.json in each of three places, and its stream reader died mid-run on an API error envelope).

One gem version carries exactly one binary version — mcptask-rails-runner X.Y.Z contains the binary from the vX.Y.Z release of jchsoft/mcptask-releases.

mcptask_runner:install and :update copy that binary out of the gem to ~/.mcptask/bin/mcptask_runner and run it from there. The scheduled job runs that copy, because a job pointing inside a gem directory dies at the next bundle update — at 08:00, in a log nobody reads. So the pin is per project: the Gemfile decides what a foreground rake mcptask_runner:* runs, while the machine has one installed binary however many projects it carries, and the newest version any of them offers is the one that stays. Install and update print which version they wrote, and never replace a newer installed binary with an older one.

Requirements

  • Ruby >= 3.0, Rails >= 6.0
  • One of Claude Code, Codex CLI or OpenCode, signed in by the machine owner — picked per project at install time (--cli below; Codex and OpenCode need their own login on top of the runner account)
  • An mcptask.online account

Installation

# Gemfile
gem "mcptask-rails-runner"
bundle install
bundle exec rake mcptask_runner:install

Migrating from the legacy mcptask_runner gem

The rake surface is identical — the migration is one Gemfile line:

- gem "mcptask_runner", git: "git@github.com:jchsoft/mcptask_runner.git"
+ gem "mcptask-rails-runner"

Then:

bundle install
FORCE=1 bundle exec rake mcptask_runner:install

Re-running install is what regenerates the scheduled job. The legacy launcher runs bundle exec rake and logs the active version by grepping Gemfile.lock for the old gem name — neither survives the rename, so a job left as it is keeps working but stops recording what it ran. The regenerated one execs ~/.mcptask/bin/mcptask_runner directly, with no bundler in the 08:00 path.

Every rake mcptask_runner:* invocation and shell alias keeps working unchanged. Your existing config/mcptask_runner.yml, .mcp.json and .claude/ setup are read by the Go binary as-is — with one exception: a project without a harness: line is now refused by name (no silent default), and mcptask_runner:update will write harness: claude once for a legacy .mcp.json-style install so the host gets through the gate on the next run. The only legacy task without a counterpart is mcptask_runner:prepare:permissions — permission sync is part of mcptask_runner:install now.

Picking the coding CLI and the git host

mcptask_runner:install delegates to mcptask_runner init, which takes the harness choice and the git host as flags. Both reach the binary through the rake task in two equivalent ways — choose whichever fits how the command is invoked:

# Square-bracket form — works inside a Procfile or a CI step:
bundle exec rake "mcptask_runner:install[--cli codex]"
bundle exec rake "mcptask_runner:install[--cli codex,--git-host bitbucket]"

# Environment form — what an operator types at the shell, where a one-line
# override (CLI=opencode rake …) is easier than retyping the rake args:
CLI=codex GIT_HOST=bitbucket bundle exec rake mcptask_runner:install

Env wins on a tie. update does not take flags — re-run install with the ones you want.

Tasks

Task Delegates to
mcptask_runner:install mcptask_runner init [--cli <name>] [--git-host <name>] (from ~/.mcptask/bin)
mcptask_runner:update mcptask_runner update (from ~/.mcptask/bin)
mcptask_runner:bug_report mcptask_runner bug-report
mcptask_runner:version mcptask_runner version
mcptask_runner:manual:once (once_dry, today, daily, review, reviews, workflow, queue) mcptask_runner run <mode>
mcptask_runner:manual:story[123] / manual:task[123] run story_manual --story-id 123 / run task_manual --task-id 123
mcptask_runner:auto:once run once_auto_squash
mcptask_runner:auto:squash:today (queue, story[123], task[123]) run <mode>_auto_squash

verbose=true and ignore_quota=true environment variables are honored by the binary itself, exactly as before.

install and update print one line before handing the process over, and it is coloured the way the binary colours everything after it: green when the install left the machine where it already was, yellow when a binary the host was running has just been replaced or when the version on disk was kept instead. Only at a terminal — a pipe, a redirect and CI get the plain text they always got. NO_COLOR turns it off, and MCPTASK_RUNNER_COLOR (1 / 0) answers it either way, ahead of NO_COLOR. The binary reads the same two variables.

Supported platforms

Platform gems exist for arm64-darwin, x86_64-darwin, aarch64-linux, x86_64-linux and x64-mingw-ucrt. On anything else bundler falls back to the binary-less ruby platform gem, which fails at run time with instructions: install the binary from mcptask-releases (or via install.sh / npm @mcptask/cli) and point MCPTASK_RUNNER_BIN at it. The same variable also serves offline or air-gapped installs.

The wrapper always executes the binary through an absolute path — inside the gem for the run tasks, ~/.mcptask/bin for install and update — and never through PATH: the binary shares its name with the legacy tooling, and a PATH lookup could pick up the wrong install. MCPTASK_RUNNER_BIN overrides both, and install leaves ~/.mcptask/bin untouched while it is set.

The gem ships no mcptask_runner executable of its own. What puts the name on PATH for a person — or a coding CLI they start by hand, which the pr skill asks to run mcptask_runner pr … — is ~/.mcptask_env.d/runner_path, written by install and update from the binary itself: it prepends ~/.mcptask/bin, and the shell startup file install configured sources it. Open a new terminal after an install or update for it to apply. The wrapper still does not look the binary up through PATH.

Development

bundle install
bundle exec rake test          # unit tests (binary resolution + task mapping)
bin/fetch-binaries             # stage release binaries into tmp/binaries/
bundle exec rake package:all   # build all platform gems into pkg/

Releasing

Releases are cut by tagging, twice — the binaries come from the Go repository and the gems from this one:

# 1. bump lib/mcptask_rails_runner/version.rb, commit, push
# 2. in mcptask_go_runner:
git tag -a v0.3.0 -m v0.3.0 && git push origin v0.3.0
# 3. here, straight after — no waiting:
git tag -a v0.3.0 -m v0.3.0 && git push origin v0.3.0

Step 3 needs no waiting because the Release workflow's fetch waits for the binaries itself (MCPTASK_WAIT_FOR_RELEASE, 15 minutes against a Go release that takes about four). It then verifies each archive against the release's checksums.txt, builds the platform gems and publishes them to rubygems.org through OIDC trusted publishing. A tag that disagrees with version.rb is refused before anything is downloaded. See .github/workflows/release.yml.

One-time setup on rubygems.org, before the first tag can publish anything — the gem name has to exist as a trusted-publisher entry:

  1. Sign in on rubygems.org, open Profile → Trusted publishers → Create.
  2. For a gem that has never been pushed, use Create a pending trusted publisher with gem name mcptask-rails-runner; for an existing gem, add the publisher on the gem's own page.
  3. Repository owner jchsoft, repository name mcptask-rails-runner, workflow filename release.yml, environment empty.

No API key is stored anywhere: rubygems/configure-rubygems-credentials exchanges the workflow's OIDC token for a short-lived credential at push time. The same model as the npm publish in the Go repository.

License

MIT