Why finance asks for this in the first week of the month
A controller watches an analyst export a trial balance to CSV, paste it into Claude Desktop, and ask for variance commentary. The data leaves NetSuite and lands in a chat window. Nothing in NetSuite records that it happened. Setting up NetSuite MCP access for finance team members closes that hole, but only after three decisions. What analysts may read. Who may write. What the record shows afterwards.
MCP is the protocol an AI client uses to call tools in other systems. Elaichi serves 450+ from its own infrastructure, so nobody in finance or IT runs an MCP server. The shape most finance teams land on is narrow. Analysts read balances, transactions and saved searches. One or two people post journals. Every attempt lands in an audit trail that names the NetSuite account actually reached.
What does NetSuite MCP access for finance team look like?
Three layers that stay separate. Mixing them up is how a finance rollout goes wrong.
Role first. Permissions in Elaichi are action strings such as tool:execute and audit:view, grouped into roles. A member holds exactly one role, enforced by a unique index, so each role is a complete persona rather than a stack of add-ons. tool:execute gates the MCP endpoint ahead of every other check. Without it the tool list comes back empty, and a call returns an in-band error naming the missing permission. Guest, Billing Admin and Auditor do not have it.
Sharing second. One building block: a grant of view, use or edit on a resource, to a person, a team or the whole organization. A member sees only what they own or what was shared with them. Org owners and admins are not exempt from that.
Restrictions third. They decide which connectors and which individual tools a target may reach. Restrictions make analysts read-only, and most of the work in a finance rollout sits there.
Read-only for analysts is a restriction, not a NetSuite permission
Express it as an allow rule against the role your analysts hold. Restriction targets are role or user only. There is no organization target, because the organization default is the absence of any rule, and that means allow-all.
the allowlist stage engages on the presence of an allow rule, not its contents, so an allow rule that names nothing denies everything. An allow rule that names nothing denies everything. That is the strictest rule you can write, and it is easy to create by accident while drafting. Within the winning layer, allow rules union, block rules union, and blocks always beat allows.
One detail decides how you write the rule. A rule is written against a connector and a tool, but the canonical operation is pinned against the catalog at write time. A block then matches on the advertised tool name or on the pinned operation. An allow matches on the pinned operation only. A tool's advertised name can be changed by whoever edits the connector's documentation, so the name is a token the governed party controls. Governance binds the operation, never the label. The reasoning is worked through in why a block matches a name and an allow matches an operation.
For finance the practical effect is simple. List the read operations you want, and everything else in that connector stays out of reach.
Keep the NetSuite credential narrow as well. A restriction decides what Elaichi will advertise and execute. The account you connect still decides what NetSuite will accept.
Reserving journal posting for a user override
Give the person who posts journals a user-targeted rule. User override beats role rule, which beats the organization default.
There is a trap here worth slowing down for. A user-targeted rule replaces the role rules entirely. It does not layer on top of them. If the controller's rule names the journal posting operation and nothing else, the controller loses every read the analyst role allowed. Write the rule as the complete list for that person, not as a delta.
OAuth scopes sit alongside this, and a scope is the ceiling attached to the client's sign-in. Reads need mcp:read. A journal post needs mcp:write. A delete needs mcp:destructive, and mcp:tools does not substitute for that ladder. A tool classified as forbidden is reachable under no scope at all.
One correction that catches people out during close. A restriction change or a role change takes effect within about two minutes, through a 60-second cache plus edge propagation, on the MCP endpoint, the console and the REST API alike. It is not effective on the next call. Only grant revocation, member removal and suspension are effective on the next call, because a grant's revocation state is re-read from the organization store on every single call.
Freezing the subsidiary the model should not choose
Restrictions decide which tools are reachable. Frozen parameters decide what a reachable tool may be called with.
A toolbox entry is one tool, served through one connection, with part of its argument space fixed. Frozen keys are stripped from the advertised schema, so the model never sees the subsidiary field and cannot ask about it. Frozen values are then merged over caller arguments at execution, so passing the key anyway cannot un-freeze it. The precedence is entry defaults, then caller or model arguments, then frozen parameters.
Subsidiary and period are the obvious candidates. Freeze the subsidiary on the analyst entry for a single-entity team, and the model cannot wander into another entity's ledger even when a prompt asks it to. Enforcement runs at four points against the same resolver: browse, connect, advertise and execute, plus a final check on the fully substituted outbound URL.
Which subsidiary did the agent actually post to?
The audit entry answers that. The connection it records is the account the call actually reached, taken from the execution rather than from the intent. Connect each subsidiary's NetSuite account separately and the entry names which one was used.
There is one entry per tool-call attempt, succeeded or failed, and both name the account. Recorded per call: the operation and tool, the connection, the classification, whether it was approved, the outcome, and an error code. Argument names and counts are logged. Argument values never are, which is what makes the trail safe to hand to a reviewer.
actor_kind is a recorded field rather than an inference drawn afterwards from a user agent. Its values include user, system, scim, api_token and ai_assistant. Whether a posting was made by a person or by an assistant is answered by the record.
Two error strings exist per failed call. The one returned to the caller is derived from the third party's response body. The one written to the audit trail is never derived from the request or the response, because audit records are org-visible and fan out to whatever SIEM you configure. A remote error body in the log pipe is third-party payload leaving the system.
A compliance reviewer does not need a paid seat. Auditor is a free read-only role, and it lacks tool:execute, so a reviewer can read the trail and cannot call anything. The trail is append-only, newest-first, cursor-paginated, filterable by actor, category and time, and eventually consistent, so a row can take a moment to appear. Forwarding to Datadog is implemented. Splunk HEC and Microsoft Sentinel are accepted as destinations but are not yet delivering.
Where the NetSuite credential actually lives
Not in Elaichi. A separate credential service holds per-account secrets, encrypted at rest, and owns refresh. A failed refresh marks the connection needs_reauth rather than failing silently.
Your organization can supply its own OAuth app per connector. The accepted body is client ID, client secret and scopes, and everything endpoint-shaped is deliberately unrepresentable. It is gated on connector:manage, not connection:manage, so everyone who can delete a connection does not silently gain the ability to repoint the organization's OAuth app.
Read-back of an account's configuration returns public values plus secret_paths, the list of dot-paths that were encrypted, carrying none of their values. The connect URL you send an analyst is a one-time session that carries no token, which is why it is safe to return over MCP.
One endpoint for Claude Desktop, ChatGPT and Cursor
Every account connects once, and the tools are served through one organization-wide MCP endpoint at POST /mcp, behind OAuth. There are no per-toolbox URLs and no embedded tokens. Point Claude Desktop at that address through its own admin console, and point ChatGPT and Cursor at the same one. Elaichi and the native AI connectors covers why one address serves several clients.
Expect the connected tools to collapse behind two meta-tools, search_tools and execute_tool. That happens past 30 tools, and the threshold counts control-plane operations and connected tools together. The control-plane catalog alone is dozens of operations, so one connected NetSuite account is normally enough to trip it. Tools withheld by a restriction are excluded from that count, because they were handed to nobody. execute_tool is a naming indirection only. It unwraps to the same name and arguments and falls through the identical gates.
Search over the collapsed set is purely lexical, with a relevance floor. A tool must account for at least half the query's own IDF-weighted mass, which is the weighting that says a rare term counts for more than a common one. The ranking floor, from first principles explains why returning nothing beats returning a tool from an app you did not ask about.
State one limitation plainly to your risk team. The prompt-injection write gate in the Elaichi agent window does not apply to POST /mcp, and cannot, because an MCP server never sees a user prompt. What does hold on the endpoint is the permission check per operation, the forbidden classification, output redaction, OAuth scope limits and full audit logging.
What happens when an analyst leaves during close
removing or suspending a member revokes every live grant in the same transaction as the membership change, so access stops on the next call. The credential cleanup is the part that needs a decision.
Offboarding runs a preflight. A personal connection referenced by a toolbox entry has to be resolved first, by transferring it to the organization, a team or another member, or deleting it. Otherwise the removal is refused. Unreferenced personal connections are cleaned up. A private connection is not transferable at all, because a credential only its owner could use does not become somebody else's. Delegated toolbox entries surface as a non-blocking warning, and re-pinning is the fix. The same sequence run against a short-term worker is in contractor offboarding and AI access.
When a CSV export is still the right answer
If one person in finance uses an AI client and reads from one NetSuite account, this is overhead you do not need yet. A single analyst with a narrow NetSuite role and a manual export has a smaller blast radius than any governance layer you can stand up in a week. The case for waiting is argued in full elsewhere.
The costs of doing it are real. Allow rules need maintenance when NetSuite tooling changes. Rule changes lag by about two minutes, which matters if you are cutting access mid-close and expect an instant stop. The two plans are Gold and Black, with a 14-day trial. Gold is $15 per user per month, or $120 per user per year, with a 14-day trial that needs no card, and the pricing page has the seat rules. Suspended members and free-seat roles do not count toward billable seats.
The case for doing it arrives with the second subsidiary, the second AI client, or the first question from an auditor about which ledger an assistant touched. The sales version of the same sequence is in the playbook on ChatGPT access to Salesforce accounts. The other eleven teams are on the use cases page, and the apps you can connect are in the connector catalog.