download_for_offlineOne static binary — into any git project on GitHub, Bitbucket Cloud or GitLab

Install mcptask_runner, the AI developer

Pick your operating system, framework and coding CLI, and every command on this page becomes the one you actually type.

verifiedFree 30-day trial. No credit card. Cancel any time.

Pick your machine, your framework/platform and your coding CLI

Everything below is then written for exactly that combination — no branch left for you to resolve in your head.

Operating system

What You Need Before You Start

Three things — and you almost certainly already have them. The checks below follow the coding CLI you picked above, and name all three hosts the runner opens pull requests on: GitHub, Bitbucket Cloud and GitLab.

description

Project

Your project has to be a git repository with its origin on GitHub, Bitbucket Cloud or GitLab, and it has to be possible to commit and open pull requests from it on the machine the runner runs on. That means working access: an ssh key that can push, write permission on the repository, and the host's own credential for the pull request — a signed-in gh on GitHub; on Bitbucket, BITBUCKET_ACCESS_TOKEN or BITBUCKET_EMAIL + BITBUCKET_API_TOKEN in the environment before init (app passwords are refused); on GitLab, a signed-in glab, which holds its own login — the runner stores no GitLab credential of its own. The runner works under your identity — what you cannot push, it cannot push either.

terminal

A Coding CLI

Set up the coding CLI you picked — Claude Code, Codex CLI or OpenCode — the way you would if you were about to use it yourself: installed, signed in, and on a plan that can carry a working day (for Claude Code, at least Pro); a run left to work on its own gets through more than asking questions by hand does. Leave a CLAUDE.md in the repository — that is where the runner picks up the project context; on Codex CLI, init adds an AGENTS.md pointer to it. The check for your CLI is below.

vpn_key

An mcptask.online Account

An account on mcptask.online with at least one project, plus a personal API token from the user menu. The token authenticates the runner as you, so it can read your tasks, write progress, and post messages on your behalf. No token, no runner — the install step asks for it because the installer needs it to wire up your .mcp.json.

Now Check, Don't Assume

The cards above explain; this block checks. Run each command and compare what prints with the expected answer — if yours differs, fix that before you touch the installer.

account_tree

git, and an origin on GitHub, Bitbucket Cloud or GitLab

The runner opens pull requests, so your project must be a git repository whose origin points at GitHub, Bitbucket Cloud or GitLab — gitlab.com and self-managed instances both count. GitHub Enterprise is the host refused by name: it is matched by its exact hostname and rejected with a message that says so, never quietly treated as github.com.

codeShell command
git remote get-url origin
git@github.com:org/your-app.git

git@bitbucket.org:workspace/your-app.git and git@gitlab.com:group/your-app.git are equally good answers. An SSH alias, a mirror or a self-managed GitLab that hides the host is what init --git-host bitbucket or init --git-host gitlab is for.

local_cafe

Homebrew macOS only

The macOS install channel comes from Homebrew — on Linux or Windows there is nothing to check here and you can move on.

codeShell command
brew --version
Homebrew 4.6.7

The version does not matter — the check is that a version prints at all.

smart_toy

Claude Code — installed and signed in

Every other prerequisite on this page fails loudly and immediately. This one fails politely, hours later, somewhere nobody is looking: a machine with Claude Code installed but not signed in looks completely healthy. At 08:00 the scheduled job starts, the child cannot authenticate, and the day ends with nothing done — the only trace is a log you do not yet know exists. It is the single most expensive omission available on this page, so it gets the most space. Give the sign-in as much attention as the install.

Install it

codeShell command
curl -fsSL https://claude.ai/install.sh | bash

macOS and Linux — on Windows use the native installer: irm https://claude.ai/install.ps1 | iex.

Sign in

codeShell command
claude

The first run opens the sign-in in your browser. Finish it — only the next step proves it happened.

Prove the sign-in

codeShell command
claude -p "Reply with exactly one word: pong"
pong

Anything but pong — above all a login error — means the sign-in, not the installer, is the next thing to fix.

merge_type

The PR host — signed in where the pull request opens

Pushing a branch needs nothing but git. Opening the pull request is a separate call to the host, made by mcptask_runner pr — the one command the runner opens, checks and merges pull requests with — and each host takes its own credential. Check the one your origin names.

GitHub

Prove gh is signed in

codeShell command
gh auth status
✓ Logged in to github.com account your-name

On GitHub, mcptask_runner pr goes through gh and its own login — an ssh key pushes the branch but cannot open the pull request. Not logged in means gh auth login is the next thing to run.

Bitbucket Cloud

Put the credential in the environment before init

codeShell command
export BITBUCKET_ACCESS_TOKEN=<your-access-token>

An access token (Bearer) for a machine. For a person, BITBUCKET_EMAIL plus BITBUCKET_API_TOKEN (Basic) instead — never both. App passwords are refused: Atlassian ended them on 2026-06-09. In PowerShell: $env:BITBUCKET_ACCESS_TOKEN = "<your-access-token>".

What init does with it

codeShell command
ls -l ~/.mcptask_env.d/bitbucket_credentials
-rw------- 1 you staff … bitbucket_credentials

init writes the credential to this file at mode 0600 — it never overwrites it with nothing and never prints it. On Windows the permission check is skipped.

GitLab

Prove glab is signed in

codeShell command
glab auth status
✓ Logged in to gitlab.com as your-name

On GitLab, mcptask_runner pr goes through the glab CLI, which holds its own login — the runner stores no GitLab credential of its own. Not signed in means glab auth login is the next thing to run. What pr create opens there is a merge request.

Self-managed: say so once

codeShell command
mcptask_runner init --git-host gitlab

A self-managed instance needs this because its origin URL is not gitlab.com. The runner never takes a GitLab URL — glab already knows the instance it is logged in to.

  • settingsThe coding CLI is named once per machine per project: mcptask_runner init --cli claude, codex or opencode. There is no default — a project that never named one is refused by name, not quietly assumed to be Claude Code.
  • settingslauncher.command only overrides the argv of the CLI you named; it cannot swap in a different one.
Both are documented on the Runner pagearrow_forward

Then the Framework's Own Toolchain

The checks above are the same for every project. These are not — pick a framework above and only its block stays on the page.

check_circle

No framework

Nothing beyond the checks above. That is the whole answer and not a block that failed to load: a project built with a Makefile, a shell script or nothing at all has no framework toolchain to check, so git with a GitHub, Bitbucket Cloud or GitLab origin and a signed-in coding CLI is the entire list.

info

bin/ci is a convention, not a requirement. If the project has one, the runner runs it; if it does not, that step is skipped. Nothing to install, nothing to write — go on to the next screen.

Install the runner and run init

Two steps: A) the runner onto this machine, B) init, which writes everything else into the project — the token, the MCP entry (.mcp.json on Claude Code), the CLAUDE.md section, the skills and the scheduled run. Init asks for your API token; find it at mcptask.online → your name (top right) → Show → Enhanced information → API Token. You type none of it by hand; anyone the binary does not suit has the by-hand walk at the foot of the page.

A

Install the runner

One command, chosen by what you picked above. Six frameworks get their operating system's own package manager; Ruby on Rails gets a wrapper gem instead of it; Node.js and React get npm alongside it.

zshHomebrew
a cask, not a formula — the runner is a single static binary, not something you build from source
brew install jchsoft/tap/mcptask_runner
output:==> Installing Cask mcptask_runner
output:🍺 mcptask_runner was successfully installed!

The cask also clears the com.apple.quarantine attribute Gatekeeper attaches to an unsigned download. Without that, the first run dies with no output at all — which reads as a broken binary rather than as the security prompt it really is.

Whatever the channel: the same six release archives per tag — darwin/amd64, darwin/arm64, linux/amd64, linux/arm64, windows/amd64, windows/arm64 — and the same SHA-256 verification against the same checksums.txt before anything is unpacked. There is no separate "Windows trust chain" that is weaker or stronger than the others.

B

Run init, with the options you want

One command installs the runner into this project. Written out with its flags rather than bare, because the flags are what decide where auto-filed bugs go, which mode the scheduled job runs and when.

zshinit, answered up front
--cli: the coding CLI this machine drives the project with — claude, codex or opencode; required on the first init, there is no default
--epic-id: the Epic that holds bugs the runner files itself; 0 keeps them at the project root
--epic-name: the display name written next to that number, so the config says which Epic it is
--mode: which work loop the scheduled job runs
--at: the time of day it runs; a value that is not a time of day is refused, never rounded
--until: the end of your workday, written to config where you can edit it later
mcptask_runner init --cli claude --epic-id 42001 --epic-name Auto-bugs --mode today_auto_squash --at 06:30 --until 19:00

Omit any of them and init asks — it is an interactive installer first. What it will not do is guess: --cli has no default, so a project that never named its coding CLI is refused by name rather than assumed to be Claude Code; and a non-interactive install (a pipe, a provisioning script, no terminal on the other end) with no --mode named SKIPS scheduling altogether rather than picking a mode for you. --at defaults to 08:00. --until has no default at all: leave it out and there is no end of day, and the runner works until its quota is spent.

Seven more flags

--git-host HOST
Pins the PR host — github, bitbucket or gitlab — when the origin URL cannot say it: an SSH alias, a mirror, a self-managed GitLab. Left out, it is derived from git remote get-url origin. GitHub Enterprise is refused by name.
--schedule
Regenerate the scheduled job and nothing else — skills, permissions, token and the config sections are left exactly as they are.
--force
Overwrite what is already on this host: skills, config sections and the scheduled job.
--helper-bin-dir PATH
Where the CI and test helper scripts are written. Default ~/.claude/bin.
--home-dir PATH
Re-roots the token directory, the shell rc file and the scheduled job. Default is the user's own home.
--verbose
Dump every stream line instead of the filtered view. Lives on the root command, so it applies to every subcommand.
--ignore-quota
Skip every quota check. Also a root-command flag.

Three of them are what make this command usable from a provisioning script: --force so a re-run is not a question, --helper-bin-dir and --home-dir so a build agent can write somewhere other than a real user's home.

What init left on your disk

Not reassurance — an inventory, so you can find each of these later. Re-run init any time: every step is idempotent, and anything you edited by hand is kept.

  • Skills copied for your CLI — twelve on Claude Code, nine on Codex CLI and OpenCode

    Claude Code gets twelve in .claude/skills/: ci-runner, ci-start, ci-wait, wait-unlock, test-runner, test-start, test-wait, discover, memory-search, mcptask-read, mcptask-write and pr. Codex CLI gets nine in .agents/skills/ and OpenCode nine in .claude/skills/ — the same list without discover, memory-search and mcptask-read, which fork a subagent only Claude Code can start. Each one gets an MD5 content hash in .mcptask_runner_manifest.json, so a later mcptask_runner update can tell a shipped file from one you edited.

  • One MCP entry added — nothing else touched

    Only the mcptask-online server is added, against https://mcptask.online/mcp and reading your token variable — in .mcp.json on Claude Code, .codex/config.toml on Codex CLI, opencode.json on OpenCode. Every other MCP server in that file is left exactly as it was. On Claude Code the entry is "type": "http": a host already on it is never downgraded back to SSE, and a .mcp.json that does not parse is refused rather than replaced — --force moves it aside to .mcp.json.bak first.

  • Token exported under the name your MCP config declares

    The token is stored under the variable name your project's own MCP config declares — not a hard-coded MCPTASK_TOKEN. On Unix it is written into ~/.mcptask_env.d/ and ~/.zshrc is taught to source that directory; on Windows it is persisted with setx. A Bitbucket credential goes the same way, into ~/.mcptask_env.d/bitbucket_credentials at mode 0600 — never overwritten with nothing, never printed; on Windows that permission check is skipped. A token that already resolves is never asked for again.

  • Approvals set for your CLI, additively

    On Claude Code the baseline permissions are merged into .claude/settings.local.json strictly additively: allow and deny become unions with what is already there, enableAllProjectMcpServers is only ever flipped on, and every other key in the file is left alone. Nothing you granted or refused by hand is dropped. Those Claude Code permissions apply to Claude Code only: Codex CLI works from the .codex/config.toml init wrote, and OpenCode from opencode.json, with the permission map the runner injects because OpenCode has no read-only flag.

  • Scheduled job generated, helpers and config written

    The schedule is generated for whichever OS you are on — a launchd LaunchAgent, a systemd user timer, or Task Scheduler XML — to run ~/.mcptask/bin/mcptask_runner on weekdays at the time you picked, and the enable command is printed for you to run. Alongside it, nine helper scripts (ci_start, ci_wait, _ci_filter_tail, test_start, test_lock, check_test_lock, run_with_log, kill_tree and runner-log, the one that tails a running runner's log) land in ~/.claude/bin, and your bug destination and waiting strategy are written into config/mcptask_runner.yml.

The scheduled job is generated and NOT activated. init writes the LaunchAgent, the systemd user timer or the Task Scheduler XML, prints the one command that switches it on — and stops there. Nothing spends any quota until a human runs that command, two screens further down.

Look first, change nothing

once_dry is the only mode that skips triage entirely: it shows the next task and exits. No branch, no commit, no quota — it answers the only question you have right now: is the token right, and does the runner see your project?

zsha task is waiting
mcptask_runner run once_dry
output:TASKRUNNER_TASK_INFO:
output:ID: 11581
output:TITLE: Fix invoice numbering after the year end
output:DESCRIPTION: Numbering restarted at 1 instead of continuing the 2026 sequence…
output:END_TASK_INFO
and that is all — it exits right here
zshnothing is waiting — also good
mcptask_runner run once_dry
output:TASKRUNNER_RESULT: {"status": "no_more_tasks"}

An empty queue is a perfectly good result. You are testing the connection, not asking for work — assigning something comes later, when it actually matters.

Then one task, picked by you

Still a no-stakes experiment. --task-id addresses one specific piece directly instead of going through the queue, so it does not matter who the task is assigned to — point the runner at any of them; in practice, make a throwaway task and watch what happens.

zsha manual run
mcptask_runner run task_manual --task-id 11581
output:[WorkLoop] Starting task #11581 — Fix invoice numbering after the year end
output:[WorkLoop] PR #482 opened for review: feature/11581-invoice-numbering
output:TASKRUNNER_RESULT: {"status": "success", "pr_number": 482, "branch_name": "feature/11581-invoice-numbering"}

--task-id is required for task_manual and task_auto_squash — the mode is refused without it.

On the command line task, story and queue work too: they are aliases for task_manual, story_manual and queue_manual, so nobody has to guess which spelling is right.

What "done" looks like: a branch, commits and a pull request left open for review — opened by mcptask_runner pr on whichever host the origin names — GitHub, Bitbucket Cloud or GitLab. task_manual is a manual mode — nothing is merged; the auto-squash variants are the ones that merge after CI goes green. The full mode table lives on the Runner page: Loop + goal

This is the first command on this page that spends real quota. When the daily quota is already spent, --ignore-quota skips the check — accepting it means the runner works past the limit, knowingly, on your say-so.

Now for real: the job on a schedule

Enable the scheduled job, kick it off once by hand, and follow the log. This is the first screen where the runner works without you sitting there.

The <slug> is the project directory's basename with underscores turned into hyphens — it shows up in the plist label, the systemd unit names, the Windows task name, the wrapper script and the log filename, so the placeholder reads the same wherever it appears.

A worked example, because a placeholder alone is easy to mis-read: the project lives in ~/Projects/my_shop, so the basename is my_shop, the underscore becomes a hyphen, and the slug is my-shop. Read every line on this screen with my-shop wherever <slug> stands:

zshexample — project ~/Projects/my_shop, slug my-shop
an example, not your commands — your slug comes from your own directory name:
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/online.mcptask.runner-my-shop.plist
~/.claude/bin/mcptask-runner-my-shop
and the log is ~/logs/mcptask_runner/my-shop.log

This example is informative only — you never assemble these lines by hand. mcptask_runner init ends by printing the finished commands for your own project, slug already filled in and colour-highlighted, ready to copy. The screens here are so you recognise what init printed and know how to switch the job off again.

zshenable the scheduled job
macOS — the path form is the only one that works here, and launchctl bootout uses the label:
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/online.mcptask.runner-<slug>.plist
stop it again with the label form (the path form fails even under sudo):
launchctl bootout gui/$(id -u)/online.mcptask.runner-<slug>
zshkick it off now, without waiting for tomorrow
RunAtLoad=false and Persistent=false are deliberate — enabling the job does NOT start a run. Call the launcher wrapper directly (same script, same log, same token resolution):
~/.claude/bin/mcptask-runner-<slug>
zshfollow the log with runner-log
runner-log follows the newest run and auto-switches when the runner opens a new file — plain tail -F goes quiet at the switch and looks like a hang:
runner-log
list every project and its newest log:
runner-log --list
follow one project:
runner-log <projekt>
print the last 200 lines instead of following:
runner-log <projekt> -n 200
~/.claude/bin is not on PATH by default — call it by absolute path (~/.../runner-log) or add the directory to PATH. The log lives at ~/logs/mcptask_runner/<slug>.log on every OS; MCPTASK_RUNNER_LOG_DIR moves it.

One line worth keeping from the old page: a scheduled job never sources your shell profile. The token is read from the variable .mcp.json declares (MCPTASK_TOKEN by default) and baked into the job at install time. When nothing resolves, the literal string SET_MCPTASK_TOKEN_HERE is written and the runner refuses to start rather than running as nobody.

webWeb UI

The Web UI, From Tomorrow On

Two things have to happen in the browser before the runner can pick its own work: turn on the runner display, and assign pieces to the user whose API token is in .mcp.json. The first makes the grid visible; the second makes the queue non-empty.

Everything before this screen was the reader trying the runner out — a free look, one task by id, then the job running unattended. None of that needed the web UI, and none of it needed anything assigned, because --task-id addresses a piece directly. This screen is the switch from "let me see what it does" to "this is how I will use it".

dashboard_customize

Turn on the runner display

The runner grid is gated on a per-user home-page element. Without it the home page does not render the section at all, and the runner looks like it is not there even though it is connected and idle.

1

Open Users, then Edit on the user the runner authenticates as.

2

On the Dashboard elements card, under Show, tick "Runner sessions".

3

Save. The runner grid appears on the home page for that user — empty until something connects.

The grid is empty by design. Nothing renders inside it until a runner actually connects; "no card" on a fresh install is the expected state, not a broken one.

person

Assign work to the user the runner authenticates as

The queue only ever offers assigned work. An unassigned piece is invisible to @next — not deprioritised, invisible. From here on the runner picks its own work, and it can only pick what has been handed to it, so the piece's assignee has to be the user whose API token went into .mcp.json.

warning

The user in question is the one whose token is in .mcp.json — not necessarily the reader, and on a shared machine very often not. Assigning to yourself while the runner holds a colleague's token produces a runner that sits there with nothing to do.

visibility_off

Assigned-only, not deprioritised

There is no "low priority for unassigned" lane. The queue is a flat list of pieces assigned to the runner's user; the rest do not appear in it. Assigning late is a fix, not a re-prioritisation.

report

Three things the runner will not pick up

Each one looks like a broken install on first contact, because the piece exists, it is open, and nothing happens. The common thread: the runner recognises the piece but treats it as not-yet-ready. The queue is doing what it was told.

block
Piece type: idea

Ideas are never offered. The runner queue is tasks, stories and recurents only — an idea has to be promoted to a task before a runner can pick it up.

block
Story with no subtasks

A story that has no tasks under it is never offered. Open the story, add at least one task, and the runner can see it. A story with a single subtask is a story with a ticket; that is the smallest unit the queue will dispatch.

block
Assigning a Story

Assigning a story to the runner's user gates the queue: its subtasks leave the general queue and the runner walks that story instead. Useful on purpose (one story, one PR, one squash), surprising if you expected it to behave like a task. Assign the task, not the story, when you want the queue to keep flowing.

tips_and_updates

Feed it something worth doing

The runner is only as good as the piece it is given. A first unattended run against vague tickets — open-ended acceptance criteria, an undefined "done", a task whose title is the whole feature — teaches the wrong lesson about the product, because the runner did exactly what the ticket said, and what the ticket said was nothing useful. Write the next task the way you would brief a new hire on day one.

visibilityThe payoff

Watch It Work: The Live Runner Card

The one screen on this page that is a picture, because seeing the card move is the whole point. Everything above was you typing; this is the runner answering back.

The runner grid on the mcptask.online home page, with a live runner card mid-task
This is the runner grid on the home page. The card is one live WebSocket carrying whole snapshots — the runner's state, the task it is on, the elapsed time — refreshed about twice a second while the runner works.
schedule

What to expect in time

The gap between starting the runner and seeing the card is where most people conclude something is broken. It is not — the card has a lifecycle of its own, and it looks like this:

check_circle

The card appears within seconds of the runner starting. With the runner display on and the grid visible, nothing more is needed.

check_circle

It moves through starting → triage → processing as the run progresses — the state machine in the open, not hidden behind a spinner.

check_circle

When the loop ends, the finished card lingers for 60 seconds and then goes. A card that disappears is a runner that finished, not a grid that broke.

check_circle

A runner started without a token says so — once, out loud, at startup. It does not silently fail to appear.

grid_off

An empty grid means one of two things

Either the runner has not started — check the scheduler screen above — or it started but could not connect, which it would have said at startup. What it does not mean is that the install failed: a finished install has its grid on the home page whether or not anything is running.

Wire It Up By Hand — No Binary Involved

Any MCP-capable AI client can talk to mcptask.online directly. Four steps, all of them plain configuration: get a token, declare the server, point the agent at your project, verify.

1

Get your API token

Log in to mcptask.online, open your name (top right) → Show → Enhanced information → API Token. Copy the string exactly as it is shown — it is an opaque secret with no fixed prefix or length, so never retype it from memory. Treat it like a password: anyone holding it acts as you on mcptask.online.

Where to find it
codeWhere to find it
mcptask.online → your name (top right) → Show → Enhanced information → API Token
Shell command
codeshell
export MCPTASK_TOKEN='<paste your API token here>'

infoThe variable name is yours to choose — nothing on our side fixes it. What matters is that the name you export here is the exact name your .mcp.json interpolates in step 2. If the two drift apart — you export MCPTASK_KAMR_TOKEN while the config still reads ${MCPTASK_TOKEN} — the client substitutes whatever that other variable happens to hold, or an empty string. In the first case the agent authenticates as a different user and the work lands on somebody else's dashboard; in the second it is simply rejected.

What just happened

Put the export line in your shell profile so every MCP client you start can see the token — and write it into a file a login shell reads too. A token exported only in ~/.zshrc or ~/.bashrc is there when you open a terminal and gone when launchd or a systemd user timer starts the same work; ~/.zprofile (on Linux ~/.bash_profile or ~/.profile) is the file that survives both. On Windows $env:MCPTASK_TOKEN lasts as long as the window — setx, or SetEnvironmentVariable with the User scope, is what writes it into the user environment a Task Scheduler run reads.

2

Declare the mcptask-online server in your MCP config

Open your client's MCP config file — .mcp.json in the project root for Claude Code, or Claude Desktop's developer settings — and add the entry below. The Authorization header interpolates the very same variable you exported in step 1, so rename both together or neither.

.mcp.json
code.mcp.json
{
  "mcpServers": {
    "mcptask-online": {
      "type": "http",
      "url": "https://mcptask.online/mcp",
      "headers": {
        "Authorization": "Bearer ${MCPTASK_TOKEN}"
      }
    }
  }
}

infoWrite new configs as "type": "http" against https://mcptask.online/mcp. Older configs use "type": "sse" against https://mcptask.online/mcp/sse — the server still accepts that spelling, so an existing SSE entry keeps working, but it is the legacy form. For Claude Desktop, paste the same entry into its own MCP config file, claude_desktop_config.json — open it from Claude Desktop's settings rather than from a path we print here, because both the file location and the wording of that settings screen differ by OS and by version.

3

Tell the agent which project to work on

Open your project's CLAUDE.md (or the equivalent context file your AI client reads) and add the section below. Without it the agent has no idea which project or account to read and write tasks for — this is the human-readable way it gets its bearings. The template below is the only one the page ships; keep the work-loop line in it, because that line is what keeps the agent in its loop, and one without it stops after a single task.

CLAUDE.md
codeCLAUDE.md
## mcptask.online
- Project name: <your project name>
- project_relative_id=<your project id>
- account_code: `<your account code>`

## Usage notes
- Access mcptask.online via the MCP server (key: `mcptask-online`).
- Everything is a **piece** — URIs never use `/tasks/` or `/stories/`.
- Always use `relative_id` in URLs / references, never the internal `id`.
- Read with: mcptask://pieces/{account_code}/{piece_id}
- Current user: mcptask://user (a literal URI — it takes no account code)
- Create pieces via the write tools; **content in English**.
- The work loop: load the most important task → work on it → check the daily quota → repeat.

What just happened

Read project_relative_id and account_code off the screen rather than guessing them from the project name: project_relative_id is the number in the URL when you open the project on mcptask.online, and account_code is the short code shown under the account name in the account switcher. Without those two values the runner refuses to start. Not a warning it prints and carries on past — it has no account to ask and no project to ask about, so it stops.

4

Verify the connection

Restart your AI client (or reload its MCP config). Ask the agent one plain-English question to confirm it can reach mcptask.online. If it returns a piece, you are connected. If it errors, jump to the FAQ below.

Ask your agent
codeAsk your agent
List the next open task from my mcptask.online project.
Shell command
codeshell
mcptask://pieces/{account_code}/@next?project_relative_id={project_relative_id}&exclude_relative_ids={exclude_relative_ids}

What just happened

That URI is the canonical read entry point. The project_relative_id query parameter belongs to it — the discovery URI is the whole string, not the part before the question mark. If the agent can fetch it and return one task, every other piece URI works too.

How to Confirm It Works

Three quick checks, in order. If all three pass, the connection is good. If any fails, the FAQ below has the most common cause for each.

check_circle

The agent lists your projects

Ask the agent to list your projects. It should return at least one row with a project name and a project_relative_id. If it returns nothing, the token is wrong or the account_code is missing from CLAUDE.md.

Ask your agent
What projects do I have on mcptask.online?
check_circle

The agent fetches the next open task

Ask for the next task. It should return one piece with a name, description, and difficulty (the scrum_point field). If you have no open tasks, it returns no piece but a short message saying there is nothing to work on — the exact wording comes from the server and may vary. That is still fine, the connection is working.

Ask your agent
Fetch the next open task for me.
check_circle

The agent can read a specific task by URI

Give it an exact URI from the web UI (open any task, copy the relative_id from the URL). The agent should return that task's full details. This is the most reliable end-to-end check.

Ask your agent
Read mcptask://pieces/{account_code}/{piece_id} and summarise it for me.

Common Questions, Plain Answers

help_outline

What is MCP, in plain language?

Think of MCP as a USB cable between your coding CLI and mcptask.online — the runner plugs Claude Code, Codex CLI or OpenCode into your task queue so the AI can read, work, and log tasks directly. The acronym itself is defined once in the glossary on the integrations page.

help_outline

Does this work on Linux / Windows / a server?

Yes — the runner, .mcp.json and the bundled skills run on any desktop OS. Scheduling has three real back-ends, not a macOS-only one: a launchd LaunchAgent on macOS, a systemd user timer on Linux, and a Task Scheduler job on Windows. On any other platform init prints Scheduling: skipped (no generator for ...) rather than guessing, and the install finishes without a schedule. File paths, enable commands and the headless-server fallback all live in the unattended run screen above.

help_outline

Is the runner safe to leave running unattended?

Yes — a well-specified task lands in a PR. The runner runs on your machine against your real database, so it tests, takes screenshots, and pushes commits the same way you would. If the agent gets stuck, runs out of context, or is interrupted, the harness recovers and the task lands in a PR instead of dying halfway. And if the runner hits a bug in code it was not asked to fix, it spawns its own tracked task, fixes it, merges, and gets back to your original work.

help_outline

Can I undo or remove the installation?

Yes. Delete the skills init copied — on Claude Code the twelve in .claude/skills/: ci-runner, ci-start, ci-wait, wait-unlock, test-runner, test-start, test-wait, discover, memory-search, mcptask-read, mcptask-write and pr; on Codex CLI (.agents/skills/) and OpenCode (.claude/skills/) the nine of them without discover, memory-search and mcptask-read. Remove the mcptask-online entry from .mcp.json, .codex/config.toml or opencode.json, delete ~/.mcptask_env.d/bitbucket_credentials if init wrote one, and on macOS run launchctl bootout gui/$(id -u)/online.mcptask.runner-<slug>. The binary leaves through the channel it came in on: by hand for the install script, brew uninstall jchsoft/tap/mcptask_runner for Homebrew, scoop uninstall mcptask_runner for Scoop, npm uninstall -g @mcptask/cli for the npm wrapper, or — for the Rails wrapper gem — remove the mcptask-rails-runner line from the Gemfile. Nothing else is touched.

forward_to_inbox

Not a Developer? Send This to Your Team

Setup takes about two minutes for whoever runs the project. Forward this page to your dev lead and they will have an autonomous dev wired up before their next coffee.

rocket_launch

Get the Token, Then Run the Installer

Two minutes from now you can have an AI agent picking up your most important task. Create a free account, grab your MCPTASK_TOKEN, and you're set.

verified_userFree 30-day trial. No credit card. Cancel any time.