Example: a scoped domain tool
Goal: finance reads a deal completely differently from sales. Give them their own view of Opportunity and their own tool, without touching the seller’s. Configuration, plus deploying generated code.
The problem
Sales looks at an Opportunity and wants stage, next step, competitor, close date. Finance wants amount versus expected revenue, payment terms, billing contact, invoice status, and whether the discount has approval.
One entity can’t serve both. Widen it to cover both and every payload carries the other team’s fields.
1. Create the finance entity
Go to Entities → New Entity:
| Field | Value |
|---|---|
| Object | Opportunity |
| Entity name | Finance View |
| API name | finance_view |
| Description | The finance view of Opportunity: revenue recognition, terms, and billing. |
Then click Create Entity. A domain manager also picks a Home domain here; an admin doesn’t see that field.
Opportunity already has a default entity, so this is a named view — reachable through a domain that serves it, never by accident. See Entities.
2. Curate for finance
Detailed: Name, Amount, ExpectedRevenue, CloseDate, StageName, IsClosed, IsWon, Payment_Terms__c, Discount_Approved__c, Billing_Contact__c, Invoice_Status__c, Account.Name
List: Name, Amount, CloseDate, StageName, Invoice_Status__c
Entity instruction:
Amount is gross before discount; Expected Revenue is net and set manually by the deal desk. When they disagree, Expected Revenue is authoritative for forecasting. A closed-won deal with no invoice status has not been handed to billing yet.
Field instructions:
| Field | Instruction |
|---|---|
Amount | Gross, before discount. |
ExpectedRevenue | Net of discount, set by the deal desk. Authoritative for forecasting. |
Discount_Approved__c | Blank means not submitted, not “no discount”. |
The last one matters most: an agent would otherwise read a blank as a negative.
3. Add a finance metric
Weighted Pipeline — sum of ExpectedRevenue, filtered to IsClosed = false, available for Opportunity. Instruction: “Net of discount. Sales uses gross Amount; these will differ.”
The instruction pre-empts a rep and a controller quoting different numbers and neither knowing why.
4. Create the domain
Go to Domains → New Domain. The description becomes the scoped tool’s purpose statement, so write it for an agent choosing a tool.
| Field | Value |
|---|---|
| Label | Finance |
| API name | finance |
| Description | Revenue, terms, and billing status across the deals and accounts finance owns. |
Click Done. The domain opens on its Roster tab: add finance_view, account_360 and contact_360 there.
Roster everything finance needs, not just the finance-specific view: a user granted this domain reads only what it rosters. Account and Contact are the same entities the sales domain uses, since finance has no different opinion about what an Account is. The domains page shows account_360 as “Also in: Sales Desk” — sharing entities between domains is normal and visible.
5. Grant it to finance
Click the domain’s Users button and add the finance team — a user, or the public group or role you already use. From that moment their agents read the Finance catalog and the default one drops away, so there is nothing to revoke.
Give whoever maintains the domain Managers as well, plus the ContextWorks Domain Manager permission set. → Domain access
6. Check what it serves
The domain card should show:
| Object | Entity | Also in |
|---|---|---|
| Account | Account 360 | Sales Desk |
| Contact | Contact 360 | Sales Desk |
| Opportunity | Finance View | — |
The same opportunity record, read through this domain, now returns the finance curation.
7. Generate the tools
Go to Deploy → Custom:
| Setting | Value |
|---|---|
| Domain | Finance |
| Level | Pin: Detailed (full 360) |
| Format | Pin: Markdown (grounding) |
Picking the domain generates six classes, one per action: FinanceGetRecordsAction, FinanceFindRecordsAction, FinanceGetBriefsAction, FinanceGetSkillAction, FinanceUpdateRecordsAction and FinanceGetCatalogAction. Deploy the ones this agent needs. Pin level and format because the tool has one job, and fewer inputs is less for a planner to get wrong.
8. Deploy and register
Deploy the classes as you deploy any Apex. They live in your namespace and call only the package’s public API, so upgrades won’t break them.
Register them — 3A on the Deploy page for Agentforce, 3B for MCP — named exactly as the classes.
TIP
If finance already has an agent, put the domain’s actions in a topic of their own and add a router transition to it. One topic per domain keeps the planner’s choices clear.
9. Test the difference
Same record, two tools:
Sales tool: “Tell me about the Global Media renewal.” → Stage, next step, close date, competitor, recent activity
Finance tool: “Tell me about the Global Media renewal.” → Amount vs expected revenue, payment terms, discount approval, invoice status
10. Change coverage later
Six weeks later finance starts tracking Invoice__c:
- Create an entity for
Invoice__c. - Add it to the
financedomain.
FinanceGetRecordsAction covers invoices on its next call. You redeploy nothing and republish no agent, and the tool’s description still holds, because it describes purpose rather than contents. A tool with a hard-coded entity list would have needed a code change, a deploy, and an agent update.
When not to bother
If finance and sales genuinely want the same fields, don’t build this. A near-copy entity gives you two places to fix every future change. The test is whether the curation differs, not whether the audience does.