DEV Community

René Knierim
René Knierim

Posted on Originally published at renmy.net

Let your AI agent run Apex tests: MCP for Salesforce

Nimbus was renamed renmy runtime in October 2026: same tool, same binary. The record of the rename is here.

Short version. AI coding agents are good at Python and TypeScript because they can run what they write and read the result within a second, dozens of times per task. They stall on Salesforce Apex because the only place Apex could run was a Salesforce org, minutes away over the network. renmy runtime is a local Salesforce Apex runtime: it executes real Apex, SOQL, DML and Salesforce Flows on your machine against an embedded PostgreSQL, with no org, no scratch org, no sandbox, no Docker and no JVM. Its renmy mcp command is an MCP server that gives Claude Code, Cursor, GitHub Copilot and any MCP client tools such as run_apex_tests and explain_failure, so the agent gets the same write-run-fix loop it has everywhere else and the org only sees code that has already passed. Deploying stays behind the gates of renmy deploy.

Why coding agents work in TypeScript and stall on Apex

An AI coding agent is a loop: write a change, run something, read what came back, decide what to do next. In a TypeScript or Python project, "run something" means starting a process on the same machine: npm test, pytest, a one-off script. It returns in a second or two with a stack trace the agent can read. An agent goes round that loop twenty or forty times on one task, and what it hands back is code it has watched pass.

Salesforce Apex breaks the loop at "run something". Apex compiles and executes only inside a Salesforce org: the compiler, the database and the test runner live in Salesforce's data centres, not on the developer's machine. To run one test, an agent has to deploy the class to an org, wait, start the test run, poll until it finishes, then fetch and parse a debug log. That is minutes per cycle, and it requires the agent to hold credentials for an org. The published measurement: four open-source Apex suites, 837 tests, about 1 min 46 s in a Salesforce org for deploy and run (method and numbers).

Agents respond in one of two ways, and both are bad. Some stop iterating: they write the class and the test, describe what the test "would" check, and hand back code nobody has run. Others keep going and spend minutes and tokens on every round trip. Either way, the one thing an agent is good at, relentless and cheap verification, is the thing Apex took away from it.

What a local Apex runtime changes

renmy runtime is a local Salesforce Apex runtime and developer toolchain. It executes real Apex (classes, interfaces, enums, generics, triggers), SOQL and DML, and Salesforce Flows (autolaunched, record-triggered, screen) on the developer's machine against an embedded PostgreSQL. No Salesforce org, no scratch org, no sandbox, no Docker, no JVM: one binary for macOS, Linux and Windows. It is not a mock and not a transpiler to Java. Governor limits are enforced; Test.startTest/Test.stopTest, @testSetup, per-test transaction isolation, the Stub API and the order of execution with triggers and flows behave as they do on the platform, and the parity record is public. A typical Apex test completes in tens of milliseconds, SOQL and DML included. The 837-test benchmark above runs in 2.4 s locally, roughly 45 times faster, every test passing in both places.

For a Java developer this is what the JVM on their laptop has always been. For an AI agent it is the missing half of the loop. If a local runtime is a new idea to you, What a local runtime is, and why Salesforce never gave you one explains it from zero, and renmy runtime explained tours the whole toolchain.

What renmy mcp exposes to an agent

The Model Context Protocol (MCP) is how coding agents call tools. A server describes a set of functions with typed inputs; the client, the agent, calls them over JSON-RPC and reads a structured result. renmy mcp is such a server. It runs as a child process of the agent and talks over stdio, so there is no port, no network and no credential. The agent reaches the project on the disk in front of it and nothing else.

The tools are the runtime's own commands with the same engine behind them:

  • run_apex_tests: run a class, a method or a pattern such as "*" and get the results back as data, not as a log to parse.
  • explain_failure: one failure in full. The exception, the source location, expected versus actual, the SOQL and DML that ran just before it, and what the engine could not establish. It is the same payload renmy explain prints.
  • get_coverage: line and branch coverage for the run.
  • get_execution_trace: the execution trace of a run, what ran and in what order.
  • execute_anonymous: run a snippet of Apex against the local database, the agent's equivalent of a REPL.
  • list_test_classes: find out what is already tested before writing more.

The full list is in the CLI reference. The MCP server is a Pro feature, free during the public beta. An agent that can run shell commands, as Claude Code can, gets most of the loop on the Free tier from renmy test and renmy explain; the MCP server returns the same results as structured data instead of terminal output.

How to connect Claude Code, Cursor or Copilot to renmy runtime

Install the runtime

curl -fsSL https://renmy.net/install.sh | sh          # macOS, Linux
irm https://renmy.net/install.ps1 | iex              # Windows PowerShell
cd your-sfdx-project
renmy test "*"
Enter fullscreen mode Exit fullscreen mode

Run that last command yourself once before you hand the project to an agent, so you know the suite runs locally and how long it takes. The quickstart covers the first run in detail.

Register the MCP server

# Registers renmy mcp with the agent clients on this machine
renmy mcp install

# Or in Claude Code directly. The server's registered name is nimbus.
claude mcp add nimbus -- renmy mcp
Enter fullscreen mode Exit fullscreen mode

Cursor reads .cursor/mcp.json in the project. The entry is the same command:

{
  "mcpServers": {
    "nimbus": {
      "command": "renmy",
      "args": ["mcp"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

GitHub Copilot's agent mode and any other MCP client take the same stdio command, renmy mcp. The registered name stayed nimbus through the rename, so an agent configured before October 2026 keeps working. The how-to Let AI agents run Apex tests walks through each client and renmy skills, curated agent workflows for common Salesforce tasks.

What an agent session looks like with a local Apex runtime

Say you tell Claude Code: "Invoices over 10,000 get a 5 per cent discount. Add it to InvoiceService with tests." The loop, with the tool calls named:

  1. list_test_classes finds InvoiceServiceTest. The agent reads it and the service.
  2. It writes the method and a test:
@IsTest
static void appliesFivePerCentAboveThreshold() {
    Invoice__c inv = new Invoice__c(Amount__c = 12000);
    insert inv;

    Test.startTest();
    InvoiceService.applyDiscounts(new List<Id>{ inv.Id });
    Test.stopTest();

    inv = [SELECT Discount__c FROM Invoice__c WHERE Id = :inv.Id];
    Assert.areEqual(600, inv.Discount__c);
}
Enter fullscreen mode Exit fullscreen mode
  1. run_apex_tests on InvoiceServiceTest. One failure, in well under a second.
  2. explain_failure on that method. Expected 600, actual 0, and the SOQL and DML before the assertion show that the service queried the invoice but never issued an update: its query filtered on a status the test never set. The agent fixes the filter.
  3. run_apex_tests again. Green. get_coverage for the class shows branch coverage, which flags the untested path at exactly 10,000, so the agent adds a boundary test.
  4. run_apex_tests with "*". The whole suite, in a couple of seconds. A change to InvoiceService that broke a trigger test somewhere else shows up now, not in the org.

Each round is seconds. The agent runs the whole suite after every edit because it costs nothing, a discipline most humans drop by the third iteration. Nothing has touched an org. What you review is a diff and a test run you can reproduce in your own terminal:

renmy test InvoiceServiceTest
renmy explain InvoiceServiceTest.appliesFivePerCentAboveThreshold
Enter fullscreen mode Exit fullscreen mode

Agentforce, Headless 360 and the Apex behind your MCP tools

There is a second MCP in the picture. Salesforce Headless 360 (April 2026) lets a team configure custom MCP servers in Salesforce that wrap existing Apex hooks: @InvocableMethod, @AuraEnabled, @RestResource and autolaunched Flows become tools an Agentforce agent, or an external one, calls in production. Those hooks are ordinary Apex and flow metadata, and renmy runtime already executes all of them locally, so the code behind a Headless 360 tool is tested offline against the embedded PostgreSQL with no extra setup. How renmy runtime fits Headless 360 has the detail.

Where the agent should stop: deploying

A green local run is necessary and not sufficient. The org has permission sets, managed packages, validation rules and other teams' automation that your repository does not contain, and the parity record is public precisely because it is not 100 per cent. So the agent should not deploy on its own, and the tool for that boundary is renmy deploy. It snapshots the payload into a bundle, runs the local test and coverage gates against that bundle, validates the identical bytes in the target org with a real Salesforce check-only validation, and only then deploys. It is in the Free tier. renmy release validate and renmy release deploy (Pro, free during the beta) split the two halves with an immutable receipt (bundle digest, git revision, org fingerprint, gate results, Salesforce validation job id, quick-deploy expiry) so a human can approve between them. Let the agent run the tests; keep the deploy, or at least the approval, in a human's hands. Deploy and Release describe both commands.

What stays in the org does not change: the UI, the integrations, the final validation. The runtime is where the hundred edits before that happen.

Who this is for

Developers using Claude Code, Cursor or GitHub Copilot on a Salesforce codebase who have watched the agent produce Apex it never ran. Teams building Agentforce or Headless 360 tools who want the Apex behind them tested before it reaches an org. AI-tooling leads who need to answer "can our agents work on Salesforce?" with a demonstration rather than a slide.

Try it

curl -fsSL https://renmy.net/install.sh | sh
cd your-sfdx-project
renmy test "*"
renmy mcp install
Enter fullscreen mode Exit fullscreen mode

The quickstart takes five minutes. The AI and agentic coding page has the integration patterns. Issues, docs, examples and released binaries are at github.com/renmy-solutions/renmy; questions go to the Slack.

Frequently asked questions

Does an AI agent need a Salesforce org to run Apex tests with renmy runtime?

No. renmy runtime executes Apex, SOQL, DML and Salesforce Flows on the developer's machine against an embedded PostgreSQL. The renmy mcp server runs as a child process of the agent over stdio, so it needs no org, no credentials, no network and no port. The org is only involved when you deploy.

Which AI coding agents work with renmy mcp?

Any MCP client. Claude Code registers it with claude mcp add nimbus -- renmy mcp, Cursor through its mcp.json, and GitHub Copilot's agent mode and other clients take the same stdio command, renmy mcp. renmy mcp install does the registration for you. The server's registered name is nimbus.

Is renmy mcp free?

The MCP server is part of the Pro tier, which is free during the public beta; the list price after the beta is $19 per month. The Free tier, $0 and no card, includes unlimited local test runs, so an agent that can run shell commands already gets the loop from renmy test and renmy explain.

Should an AI agent deploy Apex to Salesforce?

Not on its own. A local pass is necessary and not sufficient, because the org holds metadata and automation your repository does not. Deploy through renmy deploy, which runs the local gates and then a real check-only validation of the same bytes in the org before deploying, or through renmy release validate and renmy release deploy, which put a human approval and an immutable receipt between validation and deployment.

Is renmy runtime the same as Nimbus?

Yes. Nimbus was renamed renmy runtime in October 2026. It is the same binary from the same repository line; the nimbus command, the NIMBUS_* variables, nimbus.properties and the MCP server's registered name nimbus all keep working. The record of the rename is at renmy.net/blog/nimbus-is-now-renmy.

Top comments (0)