Skip to main content
A laptop has no CUDA, so GPU code gets tested in CI that also has none, or not at all. With Claude Code pointed at a free-tier model through Runcrate’s Anthropic-compatible API, the agent costs nothing to run within the daily allowance, and the MCP server gives it run_job: your tests go to a fresh GPU as files, the machine stops when pytest exits, and the agent reads you the result. The same three tool calls run from CI with the script below.

Build it in your project

Paste this line into your agent (Claude Code, Codex, Cursor, OpenCode, Cline). It sets up your key, then builds the pipeline in your project:
After that, ask in plain words: “Run the tests in tests/ on a Runcrate GPU and tell me if they pass.” The agent calls run_job with your test files, follows get_job_logs, and reads the exit code and cost from get_job. The files below do the same from CI, where no agent is signed in.

The code

One file per language. Both read RUNCRATE_API_KEY from the environment; nothing secret is in the code.

What the proof run cost

Claude Code 2.1.280, headless (claude -p), on DeepSeek V4.1 Flash through Runcrate, with the Runcrate MCP server, asked to run a three-test CUDA suite (torch.cuda.is_available, a 1024x1024 matmul against the CPU, bf16 autocast) on a GPU. Measured on 2026-10-23 against api.runcrate.ai; costs are what the account was billed, read from each response’s X-LLM-Cost header or usage.cost. Claude Code printed total_cost_usd: 1.35 for the session: that is its own estimate at Anthropic’s prices for a model it does not recognise, not what was billed. The model calls ran on the free tier. The two CI files were run with --dry-run (they connect to the MCP server, list its tools and print the run_job call) so the suite ran once, from the agent.

Scale it

  • Every pull request: run the script in CI with an API key; it exits with pytest’s exit code.
  • A matrix: count or params on run_job runs the suite on several GPUs or CUDA versions as one group.
  • A bigger project: send code.git with a repository URL instead of files (1 MB in all).

Gotchas found in the proof run

  • Claude Code logs unrecognized_model for a Runcrate model id and prices the session as if it were Anthropic’s; read the cost from get_job and your Runcrate usage instead.
  • Claude Code assumes a 200K context for a model it does not know; set CLAUDE_CODE_MAX_CONTEXT_TOKENS to the model’s window (1,048,576 for DeepSeek V4.1 Flash).
  • Set ANTHROPIC_DEFAULT_HAIKU_MODEL and ANTHROPIC_SMALL_FAST_MODEL too, or Claude Code’s background calls ask for a model the API does not have.
  • With an API key instead of the OAuth sign-in, the MCP server today also needs an X-Project-Id header; any value works, as the key already names your workspace.
  • ubuntu-train has PyTorch for CUDA 12.8 but not pytest: the command installs it first.