How to give Claude Code or Cursor Salesforce case context without full CRM access
Short answer: there isn't a native Salesforce setting that hands your agent one case and its account and nothing else. Permission sets and field-level security scope access by object and by field, not by individual record, so the moment you grant Case read access for the API user your agent connects through, that credential can read every case in the org, not just the one your customer filed. The fix isn't to look harder for a hidden scoping option. It's to stop routing the request through a live Salesforce credential in the first place, for anything short of the volume that justifies building a real integration layer.
That's true whether the agent is Claude Code, Cursor, or anything else calling out to Salesforce over MCP or the REST API. The credential is the unit of access Salesforce hands out, and a credential with read access to Cases has read access to Cases, full stop. What varies is how much you route through that credential versus how much you hand the agent by hand, one case at a time.
Why "just this case" isn't a permission Salesforce ships
A Salesforce Case record carries a lookup to its Account and usually to a Contact, and that Account can carry open Opportunities with stage and amount on them. None of that is a bug in the data model. That's the point of a CRM, everything about a customer sits in one place so a rep isn't hunting across systems. But it means a Case is never "just" a bug report. Query it and you're one relationship hop from the contact's email, the account's renewal date, and whatever a sales rep wrote in an Opportunity's notes.
Salesforce's access controls work at two levels. A profile or permission set decides which objects it can read, write, or see at all, and separately which fields on an allowed object are visible, per Salesforce Ben's rundown of what permission sets actually govern. Both are set once, for a user or an integration, and apply to every record of that object type the credential ever queries. There's no equivalent switch for "this user can see Case 5187 and nothing else." Row-level sharing rules exist, but they're built for org charts and territories, roles and groups, not for handing out access to one ad hoc record on request.
So the honest scoping options are two: narrow which objects and fields the credential can see at all, or don't stand up a credential for this.
Option one: a narrow integration user, done deliberately
If your team is going to wire Claude Code or Cursor to Salesforce through a connected app and a service account, do it as its own integration user rather than reusing a support rep's login, and build the permission set around what the agent actually needs to answer, not around what's convenient to leave open:
- Grant Read on Case, Account, and Contact. Skip Opportunity entirely if a coding agent debugging a bug has no legitimate reason to see pipeline data.
- Hide fields with field-level security, not just object permissions. If Opportunity access is unavoidable for some other reason, strip Amount and Stage from the permission set's field-level security so the credential can confirm a related deal exists without reading what it's worth.
- Skip Contact if you don't need it. Most bug triage needs the account name and tier, not a customer's direct phone number and title.
This is real scoping, and it's worth doing over reusing a broad existing login. But it's blunt in exactly the way described above. Once Case read is granted, the credential can pull any case in the org, filtered only by whatever query the agent happens to write. You're trading "no access" for "read access to a defined, smaller set of objects and fields," not for "read access to one record."
Connected app OAuth scopes don't tighten this further than the permission set does. The api scope on a connected app governs whether the credential can call the API at all; the object and field boundaries still come entirely from the permission set assigned to the user or the connected app's running-user context. Scoping happens in Setup, on the permission set, not in the OAuth consent screen.
Option two: skip the credential, paste the case
For the actual scenario in the question, one customer, one bug, checked occasionally, standing up a connected app and a permission set is more infrastructure than the problem needs. The faster and arguably more scoped answer is to not query Salesforce from the agent at all. Open the case, copy the two or three lines that matter, the account name, the plan tier, whether it's a renewal risk, and paste them into the prompt alongside the bug report. The agent never touches a Salesforce credential, and nothing about pipeline data or other accounts is ever in reach, because nothing beyond what you typed was ever exposed.
The invoice-export bug at Bramblewood Analytics
Every Tuesday, whatever Salesforce cases got tagged Engineering over the weekend land on Rasheed Nkemdirim's list. He's a backend engineer at Bramblewood Analytics, a marketing-attribution platform, and Tuesday triage is less an engineering task than a "whoever has the context" task.
Case #40871, filed by the account's admin: "Our weekly invoice export from the dashboard has been blank for the last two runs. Finance is asking me about it and I don't have an answer."
The case body has the symptom and nothing about who's asking. Rasheed opens the account record separately, since IT declined to give engineering broad Salesforce API access after a contractor's integration credential turned up in a leaked config file the year before, a decision he doesn't disagree with. The account is Halloway Systems, on an annual contract renewing in five weeks, with a note from the account exec about a prior escalation on the same export feature. He copies the account name, the renewal date, and the prior incident number into his Claude Code session before asking it to trace the export job, because a two-line guard clause today reads differently against "renews in five weeks" than it would against an account three months into a fresh contract. It's the former. He ships the fix that afternoon and pings the account exec with the case number attached.
Rasheed does this two or three times most weeks. Each one costs him a few minutes of finding the account record and deciding what's actually relevant to copy over. Nobody's proposed giving engineering a shared Salesforce login again, and nobody's built anything to replace the copy-paste either, so the account context still lives only in whichever engineer happened to look it up that day.
Why the same account gets rediscovered every time
Copying two lines a few times a week costs nothing and exposes nothing beyond what you chose to type. It stops being the right answer once the same account context gets rediscovered by whoever picks up the next case about it, because nobody wrote down that Halloway had already escalated this once, and once "how do I know what's safe to paste" starts requiring its own judgment call on every case.
Modem doesn't change either answer above. Its Salesforce integration is read-only by design and syncs accounts, contacts, opportunities, and users, not case records or their contents. If the question is "how do I scope this Case," Modem isn't the tool for it; the two options above are the real answer.
What Modem is built for is the adjacent question that comes up once you already have the account in front of you: has this happened before, and does anything about the account's tier or pipeline change how urgent it is. Its MCP server exposes a search_modem tool that answers exactly that, a scoped, read-only question like "what's Halloway's plan tier and has this come up before," without handing Claude Code or Cursor a live Salesforce credential capable of browsing the rest of the org. That's the same synced Account data Rasheed already had to go find by hand; Modem just puts it one query away instead of a second login. It doesn't get you into the Case at all. Related reading: the best tools to give Claude Code customer context compares Modem against the alternatives directly, and whether Salesforce can show which engineering ticket fixed a customer's case covers the other half of this loop, once the fix ships.
The short list comes before the credential
Write down what an engineer actually needs to see to make the call, before wiring up anything: account name, tier, renewal proximity, prior incidents. That list is almost always narrower than "Case, Account, Opportunity, read access," and it's the same list you'd hand-copy anyway. Build a permission set around exactly that list if the volume justifies it. If the request only comes up a few times a week, skip the credential and keep pasting. That's the more scoped choice, not the lazier one.
