Composing MCP servers

Pinion ships 23 packaged MCP tools, but it does not decide who gets which ones — you do. A native Salesforce Hosted MCP server is admin-composed: you define an McpServerDefinition and choose exactly which packaged tools it exposes. The connection can only ever call the tools you put in it. That single fact is the strongest access control you have — an LLM mistake, or a prompt-injection attempt riding in on some record’s text, can only invoke a tool that is in the toolset. A write that isn’t in the server can’t be called, no matter what the model is talked into.

So the job here is least privilege: give each connection only the tools its users actually need, and keep the tools that can change data (especially price data) in the smallest, tightest-scoped servers.

Every tool already runs as the user

Before the composition model, hold onto the guarantee it builds on: every tool runs as the signed-in user and enforces that user’s CRUD and FLS. A connection can never see or change more than the person driving it already could in the UI. Composition doesn’t replace that — it narrows it further, so that even a user who could do something in the UI isn’t handed an AI shortcut to it unless you meant them to have it.

Two more safety layers sit alongside composition:

  • Per-tool approval on writes. The seven write tools surface a confirmation prompt to the user in the AI client before they execute. Nothing mutates silently — the user sees what’s about to happen and confirms it. This protects at the call layer, complementing the connection-level scoping this page describes.
  • Read tools cannot mutate. The 16 read tools only query. A server built from read tools alone is safe to approve broadly precisely because there is no write in the toolset for anything to reach.

The three-ring model

The recommended pattern composes access as three concentric rings, each adding a smaller, higher-trust set of tools on top of the ring below it. A user connects to exactly one ring; the outer rings are broad and safe, the inner ring is narrow and powerful.

These are recommendations, not the only shape — a small, trusted power-user team may be fine with a single all-tools server (see A simpler alternative). But for anything beyond a handful of people, the rings keep the blast radius of a model mistake proportional to trust.

Ring 1 — Insights (read-only)

The 16 read tools. This server cannot change anything — it only answers questions (“why is this price what it is?”, “what’s pending my approval?”, “what’s my renewal forecast?”). Because there is no write in the toolset, an org-wide grant is easy to reason about: the worst a model error or injection can do is read data the user could already read.

Grant broadly. This is the “ask Claude about my pipeline” use case, and it’s the default most of your users should get.

Ring 2 — Operate

Insights plus the six free-persona action tools: Decide Approval, Submit for Approval, Create Renewal, Create Amendment, Log Follow-Up, and Generate Quote PDF. These are exactly the monitor / decide / triage / lifecycle actions your free personas — Approver, RevOps Manager, Account Manager, Deal Desk — already perform without a paid configurator seat. They write, but they don’t touch the pricing save path.

Grant to the people who act on the pipeline — the approvers, the renewal/amendment owners, the deal desk.

Ring 3 — Author

Operate plus one tool: Configure Price. This is the capstone write tool. It configures, prices, and persists line items on the tier-zero pricing save path — it wraps the exact “Save & Sync” entry the configurator UI calls, so a mistake here can persist a wrong price. It deserves the tightest grant: the fewest users, the highest trust.

Notice that the two axes point at the same tool. On the licensing axis, authoring is a paid seat (Pinion User / Administrator). On the safety axis, Configure Price is the one tier-zero tool. Least privilege and the license model agree: keep Ring 3 small.

Tool catalog

Every packaged tool, its nature, the ring it belongs to, and the persona whose work it supports:

ToolRead/WriteRingPersona
Explain PriceReadInsightsAny
Estimate PriceReadInsightsAny
Get Opportunity LinesReadInsightsAny
Simulate RulesReadInsightsAny
Get Approval StatusReadInsightsAny
Get Account OverviewReadInsightsAny
Lookup Contracted PriceReadInsightsAny
Contract MetricsReadInsightsAny
Renewal ForecastReadInsightsAny
Get ProductsReadInsightsAny
Get My ApprovalsReadInsightsAny
Get Approval DetailReadInsightsAny
Get Contract LinesReadInsightsAny
Find DealsReadInsightsAny
Get Activity TimelineReadInsightsAny
Pipeline SummaryReadInsightsAny
Decide ApprovalWriteOperateApprover, Deal Desk
Submit for ApprovalWriteOperateAny deal owner
Create RenewalWriteOperateAccount Manager, RevOps Manager
Create AmendmentWriteOperateAccount Manager
Log Follow-UpWriteOperateAny deal owner
Generate Quote PDFWriteOperateQuote Manager, deal owner
Configure PriceWriteAuthorPinion User (paid seat)

Which persona connects which ring

Compose the ring servers, then gate each one to the personas that need it. The Pinion MCP User permission set names who may connect at all; you scope what they can do by which ring server you point them at.

RingGrant toWhy
InsightsEveryone who benefits from asking — Pinion Home floor and upRead-only; nothing to protect against beyond existing FLS
OperateApprover, RevOps Manager, Account Manager, Deal Desk, deal ownersThe free-persona lifecycle/decide/triage actions they already perform
AuthorPinion User (paid configurator seat), and only where AI-driven configuration is wantedThe one tier-zero, paid, price-persisting tool — smallest, highest-trust grant

This maps the rings straight onto the persona / permission-set model: free personas monitor, decide, and triage (Operate); the paid configurator seat authors deals (Author). The MCP ring you connect a persona to should never exceed what that persona can already do in the UI — it should usually be narrower.

How you compose a server

The mechanics live in AI Assistant Access; the parts specific to composition:

  1. Define an McpServerDefinition for each ring and list only that ring’s tools in it. The tool a connection cannot see is the tool it cannot call.
  2. Activate it under Setup → MCP Servers and confirm its tool list renders as you intend.
  3. Create the OAuth connection in Setup. The External Client App / OAuth connection is created manually in the Setup UI — it is not automatable. Point each ring’s connection at the permission set for the personas allowed to use that ring.

A simpler alternative

If your MCP audience is a small, trusted, high-context group — a couple of admins and a power user or two — a single all-tools server is a legitimate choice. The three rings buy you proportional blast radius as the audience grows and trust varies; a two-person team of experts doesn’t need that separation. Start simple, and split into rings the moment you’re granting MCP to people whose trust levels differ — especially the moment Configure Price would land in front of anyone who shouldn’t be authoring prices.