I want to tell you about an experiment that changed how I think about AI and Salesforce development.

The goal was simple to state and ambitious to attempt: have Claude build a complete hospital-management Salesforce org — custom objects, Apex triggers, tests, and seed data — on its own, through an agent loop. Not “Claude writes code and I paste it into the org.” Claude deploys it, tests it, reads the failures, and fixes them, until the org actually works.

I didn’t write the org. I wrote the tools the loop would use. That distinction is the whole article.

The setup: six tools on Salesforce Hosted MCP

MCP — the Model Context Protocol — is how an external AI client like Claude reaches into systems it doesn’t live in. Salesforce Hosted MCP lets you expose your own Apex as MCP tools, so Claude can call into your org directly.

For this project I built six custom deployment tools:

  • MetadataObjectDeployer — creates custom objects and fields.
  • ApexClassDeployer — deploys Apex classes.
  • ApexTriggerDeployer — deploys triggers.
  • ApexTestRunner — runs the tests and reports pass/fail plus coverage.
  • RecordCreator — inserts records and returns their Ids.
  • AppBuilder — assembles the app so the org is usable, not just deployed.

Notice the shape of that toolset. It isn’t “one giant deploy-anything tool.” Each tool does one thing, and one of them — ApexTestRunner — doesn’t build anything at all. It judges. Hold that thought; it matters more than any of the others.

The target: a hospital org with real rules

The org itself had to be a genuine data model, not a toy. Seven custom objects: Department, Patient, Doctor, Room, Appointment, Prescription, Admission.

Those objects have relationships, which means they have a dependency order. You can’t create an Appointment lookup to Doctor before Doctor exists. So the loop had to deploy parents first, children after — Department before Doctor, Patient and Room before Appointment and Admission — and it had to remember the record Ids the org returned, because the seed data later would need real parent Ids to reference.

On top of the data model, three business rules enforced in Apex triggers:

  1. No double-booking. A doctor can’t have two appointments at the same time — the trigger blocks the second one.
  2. Prescriptions only on Completed appointments. You can’t prescribe against an appointment that hasn’t happened.
  3. Room availability stays in sync. When a patient is admitted, the room flips to unavailable; on discharge, it flips back.

All three handlers were built on the Kevin O’Hara trigger framework — one trigger per object, logic in a handler class. If the loop was going to write Apex, it was going to write Apex the way a professional team would.

The loop: deploy, test, read, fix, repeat

Here’s the cycle Claude ran, over and over:

  1. Deploy the next piece — an object, a class, a trigger — through the matching tool.
  2. Test by calling ApexTestRunner.
  3. Read the failures. Not “did it pass,” but what exactly failed, and why.
  4. Fix the specific cause.
  5. Repeat until the stop condition is met.

The stop condition was objective and non-negotiable: all tests green at ≥90% coverage. Not “the code looks done.” Not “the model is confident.” Green, at ninety, as measured by the runner. The loop doesn’t get to grade its own homework — the verifier does.

Twenty years in classrooms taught me this pattern before I ever saw it in software: students don’t learn from doing the exercise, they learn from seeing what they got wrong and trying again. The loop is the same. The deployment tools are the pencil. ApexTestRunner is the teacher marking the page.

Two moments where the loop earned my trust

Demos always look clean in the retelling. These two moments are why I believe in this approach, because they’re where it could have gone wrong and didn’t.

The 88% that didn’t get waved through

At one point, coverage came back at 88% for PrescriptionTriggerHandler. Two points short.

The easy failure mode here — for a human or a model — is to shrug: “88 is basically 90, and everything’s green.” The loop didn’t. It read the coverage report, found the uncovered lines — the addError guard branches that fire when a prescription’s appointment is missing — and wrote a new test for the null-appointment case to exercise exactly those branches. Then it ran the tests again.

It didn’t declare success. It closed the gap. That’s the difference between a loop with a verifier and a model with good intentions.

The malformed request that didn’t become a retry storm

Another moment: the test runner rejected a request as malformed. A naive loop retries the same call and hopes. A slightly less naive loop retries with small random changes.

This loop did neither. It looked at the rejection, formed a hypothesis — the runner accepts one class per call, and it had sent several — and reissued the requests one class at a time. Diagnosis, not repetition. Root cause, not brute force.

What got built

When the loop hit its stop condition, here’s what existed in the org:

  • 7 custom objects deployed in correct dependency order.
  • 3 trigger handlers on the O’Hara framework, enforcing the three business rules.
  • Test coverage of 92% / 100% / 90% across the handlers — every one at or above the bar.
  • 19 seeded records — departments, doctors, patients, rooms, appointments, prescriptions, admissions — created with the real parent Ids captured during deployment.
  • A working app, assembled by AppBuilder.

And the part that made me smile: the triggers were verified live, end to end. An Admission record with status Admitted went in, and room ICU-01 flipped to unavailable — the business rule firing on real data in a real org, written and deployed by the loop.

What I want you to take from this

The headline is tempting: “AI built a Salesforce org.” But that’s not the lesson I took away.

The lesson is that the human work moved. I didn’t write seven objects and three trigger handlers. I wrote six tools, chose a dependency-safe architecture, picked a trigger framework, and — most importantly — defined what “done” means in a way a machine can check: all tests green at ≥90% coverage.

Give an agent vague goals and generic tools, and you get plausible-looking output. Give it narrow tools and an objective verifier, and you get a working org.

Next in this series, I want to slow down on exactly that: what makes a loop trustworthy — verifiers, stop rules, and why the model must never be the one grading itself.

Mustafa Aksu

Salesforce developer & ISV builder focused on Revenue Cloud, Agentforce, and Data Cloud. I write from real, shipped work.