Part 3 of the Architecting Claudeforce series. New here? Start with Part 1 →.
The rep who never logs in is about to do real work through AI. Hand them the wrong tools and “real work” quietly becomes “real damage.” Here’s the door you actually want to build.
The builders made the doors. Now the rep who never logs in walks through one to do their actual job: log the call, update the forecast, submit the deal.
So here’s the question that decides whether this is a slick demo or something you’d put in front of a real salesperson: what tools do you put behind that door? And the most tempting answer is the dangerous one.
The tempting mistake
You already have the SObject servers from the map in Post 1: reads, mutations, all. The path of least resistance is to point the rep’s AI at sobject-all and call it done. There, now it can do anything.
That’s raw CRUD. And raw CRUD, an end user, and a language model make a bad combination.
“Update the Acme opportunity.” Update which fields? Following which rules? The model infers. Sometimes it’s right. Sometimes it writes a value that skips the process your screen flow used to enforce, or fills a field in a way that quietly breaks a downstream automation. It isn’t being malicious. It’s being a general-purpose tool pointed at a general-purpose instruction.
And before you reach for “but runs-as-user protects me,” notice it protects you from the wrong thing. Runs-as-user stops the rep (and their AI) from touching records and fields they’re not allowed to touch. It does nothing about the unwise but permitted write. The rep is allowed to edit that opportunity, so the AI is too. CRUD is a primitive, and your business doesn’t run on primitives. It runs on processes, and a primitive has no idea your process exists.
The fix: expose verbs, not CRUD
Here’s my actual position, and I’ll own it as a position: you don’t hand an end user’s AI database operations. You hand it business actions.
Instead of create and update, you build a custom server (Setup → Integration → Salesforce MCP Servers) whose tools are verbs: submit_expense, log_call, escalate_case, update_forecast. And here’s the part that makes it practical rather than aspirational. Each verb is backed by something you’ve probably already built, an autolaunched Flow or an Apex invocable action. (Also on the menu: @AuraEnabled methods, Apex REST endpoints, API Catalog entries. “No code to configure the server itself.”)
That backing is the whole point. The Flow behind submit_expense carries your rules: the validation, the required fields, the approval routing, the right field updates in the right order. The rep states the intent, “log that I talked to Acme, next step’s a demo Friday,” and the verb does the one sanctioned thing. The AI can’t freelance, because the only tool it holds does exactly one correct action.
This isn’t exotic. It’s the sanctioned pattern
If this sounds like me imposing an opinion, notice that Salesforce’s own custom-server docs get there too. They describe combining tools under a single URL “for a reporting persona,” pairing read tools with an analytics tool for one kind of user.
That word, persona, is the model. You don’t build one giant server and hand it to everyone. You build a per-persona server carrying just that persona’s verbs. The seller gets selling verbs. Support gets case verbs. Nobody gets sobject-all.
Why verbs beat CRUD (the architect’s scorecard)
- Process integrity. The Flow behind the verb enforces your rules; raw CRUD drives straight around them.
- Predictability. One verb, one outcome. A small, legible action surface instead of an open-ended database.
- Safety by design. The verb can’t do the dangerous thing, because the dangerous thing was never exposed as a tool.
- Intelligibility.
submit_expensetells the model, the user, and the audit log what happened.updateSobjectRecord(…)tells them nothing.
“But it asks before it writes, right?”
Yes, and please don’t lean on it. MCP clients default to always_ask: they pause and wait for your approval before a tool runs. That’s a genuine, useful backstop.
But it’s a client-side default, and it’s disable-able. Claude Desktop ships an “Always approve” button, and the moment a busy rep taps it to stop the interruptions, your confirmation is gone. So the confirm prompt is a seatbelt, not a design. Build the verb so it’s safe even when it’s auto-approved. If the only thing standing between your org and a bad write is a human reading every confirmation dialog, you’ve shipped a hazard with a warning label on it.
What you actually design
The end-user door isn’t a database connection with a chat on top. It’s a curated set of actions, your processes made askable. Concretely:
- Map the user’s real jobs to a short list of verbs, not a CRUD matrix.
- Back each verb with a Flow or invocable that encodes the rules.
- Scope a per-persona custom server; never hand an end user the raw SObject servers.
- Keep runs-as-user and confirm-before-write as backstops, belt and braces, not the plan.
The architect’s job just moved. It used to be “design the screens the user clicks.” Now it’s “design the verbs the user can ask for”: what can be requested, and what each request guarantees. Same discipline that made good page layouts, different surface.
The rep submitted the expense through a verb. Clean. Safe. Done.
Except: how do they actually know it’s done, when there’s no screen to show them? That turns out to be its own hard problem.
That’s Post 4.
📬 This is part of the Architecting Claudeforce series. More landing soon. New here? Start with Part 1 →.
Until next time! 🙂