Suite Utils

Quickstart

Your first session with su-ns-harness. What init does, what the Profile Card shows, and how a "top 20 customers by open AR" question runs.

On this page

This page assumes the plugin is installed and you've run /reload-plugins or started a new session. If not, see Installation.

Ask a question, or run init

Ask Claude anything about your NetSuite account. With an empty cache, Claude runs init by itself before its first answer, and it needs nothing from you. You can also start it yourself:

/su-ns-harness:init

What init does

Init works through these steps in order:

  1. Preflight. It checks that Node 18 or newer is installed and that NetSuite tools are in Claude's tool list. If there are none, it stops and tells you how to connect the connector.
  2. Catalog calls, one at a time. Subsidiaries, accounting books, the report list, saved searches and the SuiteQL record-type list. Then field metadata for the five GL core tables: transaction, transactionline, transactionaccountingline, account and accountingperiod. Other tables' fields are fetched the first time a query uses them.
  3. Profile probes. A few small SuiteQL queries for accounting periods, base currency, which transaction types use approvals, and trailing twelve months of revenue per subsidiary. Then one call to the consolidated Income Statement for group revenue.
  4. Build. The profile is rebuilt and the Profile Card is printed.
  5. Confirm. Claude shows you the Profile Card and asks you to confirm or correct it.
  6. Report. Claude tells you which sections were cached, anything that failed, and how long it took.

The first catalog call doubles as the hook check. Its result should come back as a single [su-ns-harness] Cached … subsidiaries line. If the raw subsidiary list comes back instead, the hooks aren't running in this session, and init stops and asks you to run /reload-plugins.

Init uses very little context, because each result is cached and Claude sees a one-line confirmation. It makes its NetSuite calls one at a time with a pause between them, so expect a few minutes. If the account's integration concurrency is shared with busy integrations, expect 10 to 15.

The Profile Card

The card lists the account facts Claude would otherwise look up again in every session:

  • base currency
  • fiscal year start
  • whether the account is OneWorld and multi-book
  • open accounting periods
  • which transaction types use approval workflows
  • consolidated trailing twelve months of revenue, plus the figure per subsidiary in each one's own currency
  • a materiality amount, taken from consolidated revenue when the Income Statement call worked

Check it before you say yes. If the base currency is unknown, Claude asks you for it. A base currency marked "from transactions at rate 1; confirm" means the query on the subsidiary table was skipped or came back empty, usually because the role can't see that table. The currency was then inferred from transactions at exchange rate 1, so confirm it or correct it.

Claude applies corrections with nsx profile set key=value. Every new session starts with this profile loaded, so you only do this once per connector.

A worked example: top 20 customers by open AR

Ask "top 20 customers by open AR" and this is the sequence.

1. Claude checks the cache, not NetSuite. It looks up the field list with nsx fields transaction --grep amount instead of calling the metadata tool.

2. Claude writes SuiteQL, and the plugin checks it before it runs. Say the first draft caps rows with ROWNUM:

SELECT BUILTIN.DF(t.entity) AS customer, SUM(t.foreignamountunpaid) AS open_ar
FROM transaction t
WHERE t.type = 'CustInvc' AND ROWNUM <= 20
GROUP BY BUILTIN.DF(t.entity)
ORDER BY SUM(t.foreignamountunpaid) DESC

ROWNUM caps rows before GROUP BY and ORDER BY run. This query would add up 20 arbitrary invoice rows and call the result your top 20 customers. The call is blocked before it reaches NetSuite. Claude gets the query back rewritten as ORDER BY … FETCH FIRST 20 ROWS ONLY, so the cap applies after grouping and sorting. The query it sends next looks like this:

SELECT BUILTIN.DF(t.entity) AS customer, BUILTIN.DF(t.currency) AS currency, SUM(t.foreignamountunpaid) AS open_ar
FROM transaction t
WHERE t.type = 'CustInvc' AND t.foreignamountunpaid <> 0
GROUP BY BUILTIN.DF(t.entity), BUILTIN.DF(t.currency)
ORDER BY SUM(t.foreignamountunpaid) DESC
FETCH FIRST 20 ROWS ONLY

The currency column is there because foreign* amounts are in each transaction's own currency. The skill tells Claude not to add EUR and USD together.

3. Large results go to a file. Twenty rows of three columns usually come back inline. Size decides it, not row count. A result larger than inline_max_chars (6,000 characters by default) is saved to a file instead, and Claude gets the row count, column stats, first rows and a result id.

4. Follow-up questions run on the file. When a result was saved and you ask for another cut of the same data, Claude runs nsx results agg on the file instead of querying NetSuite again.

Every financial answer ends with a Source line naming the report or table, the result id and when it was pulled.

If something looks off

Run the doctor. It checks Node, settings, hooks, cache freshness, and whether the connector answers, and it gives one fix per problem:

/su-ns-harness:doctor

It makes one read-only call, ns_getSubsidiaries, and changes nothing in NetSuite. Claude also runs it by itself when NetSuite results come back raw with no [su-ns-harness] line. See Troubleshooting for the common cases.

Install su-ns-harness

Run both inside Claude Code, then /reload-plugins. Version 0.5.1, free and open source.

  1. /plugin marketplace add suiteutils/suiteutils-netsuite-claude-harness
  2. /plugin install su-ns-harness@suiteutils

Page last updated 2026-09-28. NetSuite is a trademark of Oracle. Claude is a trademark of Anthropic. Suite Utils is not affiliated with either.