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 was approved.

One entity can’t serve both — widening it to cover both means every payload carries the other team’s fields.

1. Create the finance entity

Go to Entities → Add Entity:

FieldValue
ObjectOpportunity
Entity nameFinance View
API namefinance_view
DescriptionThe finance view of Opportunity: revenue recognition, terms, and billing.

Opportunity already has a default entity, so this is a named view — reachable by name or through a domain, 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:

FieldInstruction
AmountGross, before discount.
ExpectedRevenueNet of discount, set by the deal desk. Authoritative for forecasting.
Discount_Approved__cBlank 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:

FieldValue
LabelFinance
Namefinance
DescriptionRevenue, terms, and billing status across the deals and accounts finance owns.
Entitiesfinance_view, account_360, contact_360

Account and Contact are the same entities the sales domain uses — finance has no different opinion about what an Account is, so there’s no reason for a second one. The domains page shows account_360 as “Also in: Sales Desk”; sharing entities between domains is normal and visible.

Roster everything finance needs, not just the finance-specific view. A user granted this domain reads only what it rosters — that is why Account and Contact are on it.

4b. 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

5. Check what it serves

The domain card should show:

ObjectEntityAlso in
AccountAccount 360Sales Desk
ContactContact 360Sales Desk
OpportunityFinance View

The same opportunity record, read through this domain, now returns the finance curation.

6. Generate the tools

Go to Deploy → Custom:

SettingValue
DomainFinance
LevelPin: Detailed
FormatPin: Markdown

This generates three classes: FinanceGetCatalogAction, FinanceFindRecordsAction, FinanceGetRecordsAction. Pin level and format because this tool has one job — fewer inputs is less for a planner to get wrong.

7. Deploy and register

Deploy the three 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.

8. 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

One record, one engine, two curations, no code deciding which is which.

9. Change coverage later

Six weeks later finance starts tracking Invoice__c:

  1. Create an entity for Invoice__c.
  2. Add it to the finance domain.

FinanceGetRecordsAction covers invoices on its next call. Nothing is redeployed, no agent is republished, and the tool’s description is still accurate — it describes purpose, not 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 is a maintenance liability — two places to fix every future change. The test is whether the curation differs, not whether the audience does.

What’s next