Best AI for NetSuite coding in 2026: Claude Code, Codex, Cursor or Cline, set up safely for SDF
In short
- AI-assisted NetSuite coding means a coding agent (Claude Code, Codex, Cursor or Cline) writes SuiteScript 2.1 and SuiteCloud Development Framework (SDF) objects locally, and the SuiteCloud CLI (command-line interface) validates them on NetSuite’s servers. No public benchmark says which agent is best.
- Choose on two things: how precisely you can stop the agent from deploying, and your editor. Quality then comes from the setup: Oracle’s agent skills, server-side validation, types, tests and real account objects to imitate.
- Per its published source, SuiteCloud CLI 4.1.0 deploys to the project’s default auth ID without the production warning, and Oracle’s own deploy example runs as Administrator.
- So the agent gets sandbox credentials only, deploy commands are blocked in its settings, and a person deploys from Git after review.
- Oracle’s SuiteCloud Developer Assistant runs an Oracle-hosted model through Cline; its model and price are not published.
As of NetSuite 2026.2 and SuiteCloud CLI 4.1.0 (September 2026). SuiteWorld 2026 (October 25 to 28) may change parts of this page.
Who this is for
Senior NetSuite developers, often at integrators, who want a reproducible AI setup for SDF projects that cannot reach a customer’s production account by accident.
What you need
- Node.js 24 LTS (long-term support), required since CLI 4.0.0, and Oracle JDK (Java Development Kit) 17 or 21. npm does not enforce Node 24: the CLI declares no engine and its dependencies accept Node 22, so a Node 22 install succeeds silently.
- In the sandbox, Setup > Company > Enable Features, SuiteCloud subtab: Custom Records, SuiteCloud Development Framework, Client SuiteScript, Server SuiteScript and OAuth 2.0 (Manage Authentication section), plus what your objects need (SuiteFlow, Custom Transactions, Advanced PDF/HTML Templates…).
- A NetSuite employee for the agent with the Developer role or a customized copy. Not Administrator.
- A sandbox, a Git repository and one coding agent.
Which AI is best for NetSuite development?
No public benchmark ranks agents on SuiteScript or SDF, and all of these run Oracle’s skills. They differ in how precisely you can keep them from deploying:
| Agent | Oracle skills | Blocking project:deploy |
Reads AGENTS.md |
Watch out |
|---|---|---|---|---|
| Claude Code | -a claude-code, or Oracle’s plug-in |
Deny rules per subcommand, plus hooks | When no CLAUDE.md exists, or by import |
Rules match command text |
| Codex | -a codex |
forbidden rules (experimental) |
Yes | Rules cover only commands run outside its sandbox |
| Cursor | -a cursor |
CLI deny rule on the whole suitecloud command |
Yes | Blocks validation too |
| Cline | -a cline |
Command approvals | Yes | Approvals only |
| SuiteCloud Developer Assistant | -a cline |
Same as Cline | Yes | Model and price not published |
GitHub Copilot also reads AGENTS.md and takes Oracle’s skills with -a github-copilot (skills CLI README); its command controls are not covered here.
The only published comparison is anecdotal. In January 2026 Tim Dietrich relayed two developers: one found the Developer Assistant’s scripts good but its SDF objects badly wrong; the other said Claude Code became reliable on SDF objects once it had reference objects and written instructions.
Dietrich recommends Claude Code or Cursor set up that way. Dietrich now builds Sonar AI, an assistant that runs inside NetSuite.
Sonar, an in-account assistant, skips the SDF loop. In Dietrich’s September 2026 live demo, a person created the script and deployment records, then Sonar edited the deployed Suitelet file: changes showed on reload, without a redeploy (SuiteStep, Sonar Performs Live).
Sonar runs in the logged-in user’s role (34:12). Dietrich said he is almost always logged in as Administrator, “and I shouldn’t be”, and recommended a dedicated role (47:29); Oracle’s best practices for its own assistant also say to avoid Administrator.
He advised a sandbox (47:05) and has never connected Sonar to GitHub. Of this guide’s guardrails, the sandbox, a restricted role and Testing status carry over; deploy-command blocks, the suitecloud.config.js guard and Git review do not.
Published effort figures are anecdotal. In April 2026, Prolecto’s Marty Zigman wrote that Mathieu Laporte built his first app with AI, an internal NetSuite management tool, in about 20 hours, roughly 5 of them learning (Prolecto blog). The companion video demos finished apps only: no tools, code or deployment process.
Step-by-step setup
1. Install the SuiteCloud CLI
npm install -g @oracle/[email protected]
suitecloud --version
Pin the version: the safety notes below are read from 4.1.0’s source. In containers, set SUITECLOUD_CLI_ACCEPT_LICENSE=true before the install to accept Oracle’s Free Use Terms non-interactively. The install downloads the SDK jar from system.netsuite.com into ~/.suitecloud-sdk/, so a container that blocks that host fails here.
2. Create the project
Run suitecloud project:create -i and answer yes to Jest unit testing. It creates a folder named after the project: cd into it and run every later command there. Oracle’s non-interactive forms cannot add Jest:
suitecloud project:create --type ACCOUNTCUSTOMIZATION --projectname MyACP
suitecloud project:create --type SUITEAPP --projectid mysuiteapp123 --projectname MySuiteApp --publisherid <your-publisher-id> --projectversion 1.0.0
Without the Jest option, add testing by hand before Layer 3 (Oracle’s unit-testing README): npm init, npm install --save-dev @oracle/suitecloud-unit-testing jest, a "test": "jest" script and the jest.config.js shown in step 5.
Use an account customization project (ACP) for one customer’s account: it can import that account’s objects and files. A SuiteApp is for distribution and needs a publisher ID from SuiteCloud Developer Network. The default .gitignore excludes project.json, which names the default auth ID.
3. Authenticate the agent’s machine to the sandbox only
suitecloud account:setup logs in through a browser, runs only interactively (not in Windows Subsystem for Linux) and stalls a headless agent when tokens expire. The agent needs machine-to-machine (M2M) authentication with suitecloud account:setup:ci, which works headless and stores credentials in ~/.suitecloud-sdk/credentials_ci.p12, encrypted with SUITECLOUD_CI_PASSKEY (32 to 100 alphanumeric characters).
- Run
suitecloud account:setuponce in a browser: Oracle says this installs the integration record in the account. - In a folder outside the repository (for example
~/keys/acme-sbx), create an RSA certificate with Oracle’s RSA-PSS example:
RSA keys must be 3072 or 4096 bits; certificates last two years at most. Use RSA: Oracle’sopenssl req -new -x509 -newkey rsa:4096 -keyout private.pem -sigopt rsa_padding_mode:pss -sha256 -sigopt rsa_pss_saltlen:64 -out public.pem -nodes -days 365account:setup:cipage requires it, and an Oracle maintainer confirmed this on issue #997 after an EC (elliptic curve) certificate failed. Add*.pemto.gitignore. - At Setup > Integration > Manage Authentication > OAuth 2.0 Client Credentials (M2M) Setup > Create New, choose the agent’s employee, its sandbox Developer role and the application SuiteCloud Development Integration, and upload
public.pem. The new row gives the certificate ID. - Store the credentials with
SUITECLOUD_CI_PASSKEYset from a secret store or a gitignored.envfile, not typed into shell history:suitecloud account:setup:ci --account 1234567_SB1 --authid sdf_sbx_deploy --certificateid <certificate-id> --privatekeypath ~/keys/acme-sbx/private.pem
Sandbox account IDs carry a suffix such as _SB1. The command also makes sdf_sbx_deploy the project’s default auth ID.
Oracle’s Help page and the CLI’s own help text disagree on whether sandboxes need --domain <url>; add it if the command fails (domains: Setup > Company > Company Information, Company URLs subtab).
Set SUITECLOUD_CI=1 and the passkey in the agent’s environment; browser authentication is then refused. Keep in mind:
- Every process running as that OS user, the agent included, can use every auth ID in
~/.suitecloud-sdk. account:manageauth --removedeletes an auth ID locally without revoking its tokens in NetSuite.- A sandbox refresh clears the M2M mapping: redo item 3 after each refresh.
4. Install Oracle’s agent skills
Oracle publishes 10 skills in oracle/netsuite-suitecloud-sdk: 8 for development, 2 for business users. Install the ones you need, skill by skill, for each agent in the repository, for example:
npx skills add oracle/netsuite-suitecloud-sdk \
--skill netsuite-suitescript-records-reference netsuite-sdf-roles-and-permissions \
-a claude-code codex -y
Use -a cursor or -a cline for those agents. Oracle documents -a codex and -a cline; claude-code and cursor come from the skills CLI’s README. Commit the installed skills and skills-lock.json so the team uses the version you reviewed.
For Claude Code, Anthropic’s plug-in marketplace lists Oracle’s plug-in with the same 8 skills: /plugin install netsuite-suitecloud@claude-plugins-official. Pick one route. Which skills to pick, and how each route updates: Oracle’s NetSuite agent skills.
Review skills like code. On master on September 26, 2026, the SAFE (SuiteApp Architectural Fundamentals & Examples) Guide gives Map/Reduce 10,000 units per phase (Oracle’s Help Center: map 1,000, reduce 5,000 per invocation). It also suggests Bash(suitecloud project:deploy:*) in Claude Code’s permissions.allow, which pre-approves deploys: skip that.
5. SuiteScript with TypeScript: types, lint and tests
Types turn invented methods and options into compile errors the agent fixes before anything reaches NetSuite.
npm install --save-dev typescript@5 @hitc/netsuite-types
Pin TypeScript 5: TypeScript 7.0, latest on npm since July 2026, drops the module: amd, moduleResolution: node and baseUrl options the package README uses, so SuiteScript’s AMD modules would need a bundler (the anagram-dev/suitecloud-ts template uses Rollup).
A tsconfig.json that compiles ts/ into the ACP’s deployed folder, adapted from the README (target raised: Oracle says SuiteScript 2.1 supports ECMAScript 2023):
{
"compilerOptions": {
"module": "amd",
"target": "es2020",
"moduleResolution": "node",
"baseUrl": ".",
"paths": {
"N": ["node_modules/@hitc/netsuite-types/N"],
"N/*": ["node_modules/@hitc/netsuite-types/N/*"]
},
"strict": true,
"noEmitOnError": true,
"rootDir": "ts",
"outDir": "src/FileCabinet/SuiteScripts"
},
"include": ["ts/**/*.ts"]
}
SDF deploys only paths listed in deploy.xml, and noEmitOnError keeps a file that fails type-checking out of that folder. A typed entry point for the agent to imitate:
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
* @NModuleScope SameAccount
*/
import type {EntryPoints} from 'N/types';
import * as log from 'N/log';
export const beforeSubmit: EntryPoints.UserEvent.beforeSubmit = (context) => {
const memo = context.newRecord.getValue({fieldId: 'memo'});
log.debug({title: 'memo', details: memo});
};
Keep the blank line after the header: without it, tsc 5.9 drops the header from the compiled file, and Oracle requires @NApiVersion and @NScriptType in entry-point scripts. Check that each compiled file starts with the header.
In an existing JavaScript repository, checkJs checks a define() callback only where its parameters carry JSDoc types (/** @param {typeof import('N/record')} record */); untyped ones are any.
The community eslint-plugin-suitescript (npm install --save-dev eslint eslint-plugin-suitescript) checks @NApiVersion values, script types and entry points, but flags valid CustomTool files.
Oracle’s Jest template (step 2) runs @oracle/suitecloud-unit-testing 1.9.1 tests before every deploy. Test the compiled JavaScript (TypeScript tests need ts-jest or Babel, not covered here). N/llm, N/documentCapture, N/machineTranslation and N/pgp have no stubs; declare your own (N/llm examples):
// jest.config.js
const SuiteCloudJestConfiguration = require('@oracle/suitecloud-unit-testing/jest-configuration/SuiteCloudJestConfiguration');
module.exports = SuiteCloudJestConfiguration.build({
projectFolder: 'src',
projectType: SuiteCloudJestConfiguration.ProjectType.ACP,
customStubs: [{ module: 'N/llm', path: '<rootDir>/customStubs/llm.js' }],
});
6. Give the agent the account’s facts (optional)
Import from the sandbox the agent works on:
suitecloud object:import -i
suitecloud file:import --paths "/SuiteScripts/myFile.js"
suitecloud config:import # 4.1.0, ACP only: see the warning below
Warning: config:import writes the account’s features to src/AccountConfiguration/features.xml. The default ACP deploy.xml deploys that folder, and Oracle says an ACP enables or disables features through that file: the next deploy makes the target’s features match.
Move the file out (for example to docs/) or remove the <configuration> entry from deploy.xml.
Re-import an object right before editing it: an ACP deploy overwrites admin changes made in the UI since. Production drift is checked at release (Layer 4). More methods: map and document a NetSuite account with AI.
The sandbox’s NetSuite AI Connector (Oracle’s MCP, or Model Context Protocol, server) adds ns_getRecordTypeMetadata and ns_getSuiteQLMetadata, which need REST Web Services (Full). In Claude Code, deny mcp__<server>__ns_createRecord and mcp__<server>__ns_updateRecord. See connecting AI clients and a least-privilege role.
For runtime feedback, have the agent add log.debug calls, then read Customization > Scripting > Script Execution Logs in the sandbox and paste the lines back. An agent on the AI Connector can instead query the scriptnote table (Server Script Log) if its role allows.
Guardrails, strongest first
The same principles apply to every AI access to NetSuite: governing AI access to NetSuite.
What the CLI leaves to you
- Deploys skip the production warning. In CLI 4.1.0’s published source, every
project:deployskips the warning before deploying to a production account; only--dryrundiffers. Oracle’s Help Center does not describe this. - The target is
project.json. Check it withcat project.jsonandsuitecloud account:manageauth --info <authid>; change it withsuitecloud account:setup:ci --select <authid>. - Any role. The AI Connector refuses the Administrator role; Oracle’s
project:deployexample output shows “Role: Administrator”. - Direct overwrites.
file:uploadreplaces File Cabinet files without project validation. - Feature switches. An ACP deploy applies
AccountConfiguration/features.xml(step 6).
Decide who deploys to the sandbox
| Sandbox | Who deploys there | Deploy rule in the agent |
|---|---|---|
| Shared with the customer or other developers, for UAT (user acceptance testing) | A person | Deny |
| Used only by you (a dedicated sandbox or development account) | The agent, after you approve each deploy | Ask |
In a shared sandbox, keep new script deployments at <status>TESTING</status>, the default in Oracle’s user event and Suitelet XML: only the owner and any audience the XML names run them until Released. Robin Mitchell’s and Tim Dietrich’s recorded sessions did so (VS Code, 22:38; Sonar, 28:07).
Testing does not apply to scheduled scripts: keep scheduled and Map/Reduce deployments at NOTSCHEDULED, as Oracle’s SAFE Guide skill does.
Layer 1: sandbox-only credentials
The only layer independent of the agent’s behavior. Oracle’s OWASP (Open Worldwide Application Security Project) skill: “Never grant agents access to production credentials or deployment tools by default.” Oracle also advises separate auth IDs per account (its example: sdf_sbx_deploy, sdf_prod_deploy).
The agent still needs one credential: since CLI 4.0.0, validation runs only on NetSuite’s servers. If your machine holds auth IDs for customers’ production accounts (suitecloud account:manageauth --list), any process running as you can use them.
Run the agent in a container, virtual machine or separate OS user, one per customer, holding only Node.js 24, Oracle JDK 17 or 21, @oracle/[email protected], a credentials_ci.p12 with that customer’s sandbox auth ID, SUITECLOUD_CI=1 with the passkey, and a project.json naming that auth ID.
Inside it, account:manageauth --list should show only sdf_sbx_deploy, and --info sdf_sbx_deploy its account ID, role ID and domain.
Layer 2: block deploy commands in the agent
Instructions in CLAUDE.md or AGENTS.md are context, not enforcement. Each agent’s settings are.
Claude Code
.claude/settings.json:
{
"permissions": {
"deny": [
"Bash(suitecloud project:deploy *)",
"Bash(suitecloud file:upload *)",
"Bash(suitecloud account:setup *)",
"Bash(suitecloud account:setup:ci *)",
"Edit(/suitecloud.config.js)",
"Edit(/project.json)"
]
},
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-sdf-writes.sh" }
]
}
]
}
}
Deny beats allow, so this also blocks --dryrun; for a sandbox only you use, move the deploy rule to ask and drop project:deploy from the hook.
Rules match command text: npx suitecloud project:deploy, a full path or sh -c slips through. Edit rules cover Claude’s file tools and common shell writes, not scripts.
The hook sees the whole command. .claude/hooks/block-sdf-writes.sh, adapted from Anthropic’s protect-files example (needs jq and chmod +x):
#!/bin/bash
CMD=$(jq -r '.tool_input.command // empty')
if echo "$CMD" | grep -Eq 'project:deploy|file:upload|account:setup'; then
echo "Blocked: a person runs SuiteCloud deploys and account setup" >&2
exit 2
fi
exit 0
It still misses a script the agent writes and runs, npm scripts included: review package.json changes.
Codex
Rules (experimental) control the commands Codex runs outside its sandbox. Put them in ~/.codex/rules/default.rules, or in <repo>/.codex/rules/ once the project is trusted:
prefix_rule(pattern = ["suitecloud", "project:deploy"], decision = "forbidden", justification = "A person deploys SDF projects")
prefix_rule(pattern = ["suitecloud", "file:upload"], decision = "forbidden")
prefix_rule(pattern = ["suitecloud", "account:setup"], decision = "forbidden")
prefix_rule(pattern = ["suitecloud", "account:setup:ci"], decision = "forbidden")
Commands run inside the sandbox are not covered; Layer 1 is.
Cursor
The Cursor CLI reads deny rules from .cursor/cli.json. Its documented pattern is the base command, so "deny": ["Shell(suitecloud)"] blocks every SuiteCloud command, validation included. The Cursor editor agent’s settings are not covered here.
Cline and the Developer Assistant
Cline asks before running a command unless you turn on auto-approval (Execute Safe Commands in Oracle’s guidance). Oracle says to avoid auto-approval for deployments and to keep Plan Mode on.
In a session with only the SuiteCloud Extension installed, Cline could not run SuiteCloud commands, so a person used the command palette (Robin Mitchell, VS Code setup). Without the CLI, Cline cannot validate either; with it installed (step 1), command approvals remain Cline’s guardrail.
Layer 3: a guard in suitecloud.config.js
Oracle documents per-command beforeExecuting hooks; its unit-test template uses one to run Jest before every deploy. In CLI 4.1.0 the hook receives the default auth ID in args.arguments.authid, and a thrown error stops the command. An illustrative guard on Oracle’s template, not an Oracle sample (test it first):
const SuiteCloudJestUnitTestRunner = require('@oracle/suitecloud-unit-testing/services/SuiteCloudJestUnitTestRunner');
const allowed = (process.env.SDF_ALLOWED_AUTHIDS || 'sdf_sbx_deploy').split(',');
const guard = (args) => {
if (!allowed.includes(args.arguments.authid)) {
throw new Error(`Blocked: ${args.arguments.authid} is not an allowed auth ID`);
}
return args;
};
module.exports = {
defaultProjectFolder: 'src',
commands: {
'project:deploy': {
beforeExecuting: async (args) => {
guard(args);
await SuiteCloudJestUnitTestRunner.run({});
return args;
},
},
'file:upload': { beforeExecuting: guard },
},
};
The CLI loads this file for every project command, so all of them fail until @oracle/suitecloud-unit-testing is installed (step 2). The release machine sets SDF_ALLOWED_AUTHIDS=sdf_prod_deploy. The guard stops mistakes, not intent: the agent’s shell can set that variable too.
Layer 4: Git, review, and a person deploys
- The agent loops on
npx tsc,npm testandsuitecloud project:validate --json. - A pull request shows the script and XML diff; Oracle asks for peer review of generated code.
- The sandbox deploy follows the table above; test empty inputs and large datasets. On financial screens, check in the sandbox that totals tie to the general ledger; Laporte builds that check into every app that shows financials (Prolecto video, 6:11).
- Before production, a person checks drift where the production auth ID is the default:
suitecloud object:update --scriptid <changed script IDs>, thengit diff. Any change is an admin edit the deploy would overwrite. Discard those changes (git restore .) before deploying. - A person deploys to production from a CI (continuous integration) job or a release machine, then checks Customization > SuiteCloud Development > Deployment Audit Trail.
A production CI job follows Oracle’s CI steps, on a runner with the same Node.js, JDK and pinned CLI:
- Restore
credentials_ci.p12, created withaccount:setup:cion a trusted machine, into~/.suitecloud-sdk/. - Set
SUITECLOUD_CI=1,SUITECLOUD_CI_PASSKEYandSDF_ALLOWED_AUTHIDS=sdf_prod_deployfrom secrets. - Write
project.jsonwith{ "defaultAuthId": "sdf_prod_deploy" }. - Run
npm ci,npx tsc,suitecloud project:validate,suitecloud project:deploy --dryrun, thensuitecloud project:deploy.
Gate the job behind an approval, such as a GitHub environment with required reviewers (on private repositories, GitHub offers them only on Enterprise plans).
An AGENTS.md or CLAUDE.md for NetSuite projects
Codex, Cursor, GitHub Copilot and Cline read AGENTS.md. Claude Code reads it when no CLAUDE.md exists (v2.1.277 or later) or through an @AGENTS.md import. Illustrative template, not an Oracle or Anthropic standard:
# NetSuite SDF project: instructions for coding agents
- Account customization project in src/. TypeScript in ts/, compiled into src/FileCabinet/SuiteScripts/. SuiteScript 2.1 only.
- The only auth ID here is sdf_sbx_deploy (sandbox).
- After every change: npx tsc, npm test, suitecloud project:validate --json
## Never
- Run suitecloud project:deploy, file:upload or account:setup. A person deploys.
- Edit suitecloud.config.js, project.json or deploy.xml, or add files to src/AccountConfiguration/.
- Edit manifest.xml by hand: use suitecloud project:adddependencies.
- Edit compiled files in src/FileCabinet/SuiteScripts/: edit ts/.
- Guess record, field or script IDs: check src/Objects, the records skill, or ask.
- Hard-code internal IDs of employees, roles or subsidiaries.
## Code
- Header: @NApiVersion 2.1, a valid @NScriptType, @NModuleScope SameAccount, then a blank line.
- No record.load or save in loops; state the script type's usage limit.
- SuiteQL: no WITH, || not +, TO_DATE() for dates, no ROWNUM filter on aggregates.
- Date fields receive Date objects, never formatted strings.
- Never read or change NetSuite's own page DOM (document, jQuery) in client scripts, form customizations or portlets: use SuiteScript APIs (N/currentRecord, N/ui/message, N/ui/dialog, N/ui/serverWidget).
The last rule is Oracle’s: SuiteScript does not support direct access to the NetSuite UI through the DOM (Document Object Model). Its FAQ for NetSuite Next (the redesigned, AI-first experience, rolling out in phases since July 2026) adds that scripts directly manipulating HTML or page structure “may need review”.
What agents get wrong, and how to catch it
| Mistake | What Oracle documents | Catch it with |
|---|---|---|
| SuiteScript 1.0 or 2.0 code | @NApiVersion 2.x resolves to 2.0 by default; all scripts must be 2.1 from 2028.2 |
Header rule, lint, the upgrade skill’s validate mode (migrating to 2.1) |
| Invented record or field IDs | Custom IDs exist only in the account | Imported objects, records skill, metadata tools, sandbox runs |
| Governance overruns | 1,000 units for client, user event and Suitelet scripts; 5,000 RESTlet; 10,000 scheduled; Map/Reduce map 1,000, reduce 5,000 per invocation | Loop review, large-dataset tests |
| Invalid SDF XML | Booleans T/F, upper-case enums, [scriptid=...] references, a SERVERSIDESCRIPTING dependency for server scripts, toolset for custom tools since the September 2026 minor release |
project:validate, project:adddependencies, real objects to imitate |
| Generic SQL in SuiteQL | No WITH, no + concatenation, no date literals, 1,000 values max in IN, 5,000 rows max from query.runSuiteQL(), lowercase result keys |
Sandbox query runs |
ROWNUM on aggregates |
Oracle’s AI Connector skill requires ROWNUM <= 1000 in every query; a WHERE filter runs before GROUP BY, and Oracle SQL assigns ROWNUM before ORDER BY, so sums and top-N lists come out wrong when more than 1,000 rows match |
Date-bounded aggregates; top N ordered in a subquery |
| Dates | Date fields take Date values, else INVALID_FLD_VALUE; format.parse follows the user’s date preference. Oracle’s upgrade skill passes a formatted string |
Unit tests on setValue values |
What an SDF deployment cannot reverse
What an ACP deployment never removes, per Oracle:
- Objects deleted from the project: delete them in the account by hand.
- Files and custom record instances.
- Custom fields and objects it deployed. An ACP cannot be uninstalled.
What it does overwrite or delete:
- Deployed objects replace the account’s version, admin edits included.
- Sublist items missing from the project are deleted.
- An account object of another type with the same ID is deleted.
- Subrecord clashes: an existing script deployment for the same record type under the same script, or a workflow action with the same ID but another action type, is deleted and recreated.
- Account features in
AccountConfiguration/features.xmlare enabled or disabled.
SuiteApps differ: objects and custom record instances a new version drops are deleted, and a SuiteApp can be uninstalled.
Rolling back an ACP change:
- Redeploy the previous Git commit.
- Delete by hand what the bad deploy created. Deleting a custom field deletes its data; inactivating keeps it.
- Check sublists, feature settings, and files left behind by moved paths.
- Confirm in the Deployment Audit Trail.
file:upload leaves no project history: keep uploaded files in Git.
The SuiteCloud Developer Assistant
Oracle’s AI coding assistant for SDF projects: Cline is the agent, and the Developer Assistant is the Oracle-hosted model behind it. It shipped in the SuiteCloud Extension for VS Code 3.1.0 (December 2025) and runs outside VS Code since CLI 3.2.0 (June 2026).
The CLI runs a local proxy on 127.0.0.1 (VS Code default port 8181; proxy:start takes the port you pass) that accepts only /api/internal/devassist/ requests with a local API key. Per the CLI’s source, it forwards them with the chosen auth ID’s token: use a sandbox auth ID.
In VS Code (SuiteCloud Extension and Cline 4.0.0 or later), enable it under Workspace > Extensions > SuiteCloud (Developer Assistant: Auth ID, Local Port, Enable).
Then set Cline to OpenAI Compatible with the API key and Base URL shown, Model ID NetSuite, Supports Images cleared and Context Window Size 1,000,000. Watch it: Robin Mitchell, VS Code setup, from 12:02; his narration (NetSuite 2026.1) skips Model ID, Supports Images and context window.
For WebStorm with Cline, or Cline CLI:
suitecloud proxy:generatekey # shown once; a new key revokes the old one
suitecloud proxy:start --authid sdf_sbx_deploy --port 8383
Base URL http://127.0.0.1:8383/api/internal/devassist. Watch it: Robin Mitchell, WebStorm setup, proxy steps at 4:55.
Not published: the model (Oracle points to a login-only SuiteAnswers article), a price (Oracle says usage limits may apply), and terms on retention of prompts and code. Oracle’s SuiteConnect New York 2026 keynote presents it as aware of an account’s existing customizations (53:02); the Help Center documents project context awareness.
Oracle’s two-minute demo (NetSuite, Developer Assistant demo) says no coding experience is required and deploys “straight to your NetSuite account” (1:09). Oracle’s best practices for the assistant say never to deploy its code directly to production.
Seen in practice. Robin Mitchell (Head in the Cloud Development) recorded two sessions: a user event script in VS Code (May 2026), and an item-label Suitelet with an Advanced PDF/HTML template in WebStorm (August 2026).
- Name the field type. Asked for a “first quote” field, the assistant proposed a text field, and rejecting the change got the same proposal; a prompt naming a date field fixed it (VS Code, 15:35).
- Read the object XML. A second field lacked
appliestocustomer(defaultF), which hides it from customer records; he caught it in review. The next deploy failed on acrmcustomfieldroot tag instead ofentitycustomfield(30:40, 32:33). - Make it log. Logging the query results was the WebStorm turning point (WebStorm, 53:27).
- Small steps, real references. In earlier tries, a one-shot prompt spun about 10 minutes for half-useless output; he builds step by step, correcting from a template downloaded from the account (WebStorm, 9:40, 13:44).
- No error is not working. The first clean Suitelet run printed about 5,000 pages of blank labels (WebStorm, 28:46); a mostly working result took about two hours (1:03:10).
His verdict, before a pitch for his firm’s development services: useful for boilerplate, not yet for large or important projects (VS Code, 37:19).
Common problems
| Symptom | Cause | Fix |
|---|---|---|
Missing suitecloud.config.js in ... |
Command run outside the project folder | Run from the folder project:create made |
| Agent stalls on a prompt or while the CLI opens a browser | Interactive command (-i, account:setup) or expired browser tokens |
A person runs interactive commands; M2M for the agent |
| “The current passkey cannot decrypt the credentials file” | Passkey changed or mismatched | Set the original passkey, or rerun account:setup:ci |
| M2M authentication stops working | Certificate expired or revoked (Oracle emails administrators two months, one month and 14 days before expiry) | New certificate and mapping |
| “500 - Internal Server Error” on validate or deploy | Server error without details (issue #1165) | Read the Deployment Audit Trail |
Status: FAILED though the audit trail shows success |
Open CLI 4.x issue #1171, seen on a custom segment deploy | Check the audit trail before retrying |
Non-interactive object:import: “Objects must be placed under the Objects folder or any of its subfolders.” |
Open issue #1038, reported on CLI 3.1.2 | Import with object:import -i |
FAQ
What is the best AI setup for NetSuite development?
No public benchmark compares agents on SuiteScript or SDF. Pick Claude Code, Codex, Cursor or Cline by how precisely it can be kept from deploying, and by your editor. Then add Oracle’s skills, validation, types, tests and sandbox-only credentials.
Does the SuiteCloud Developer Assistant cost money?
Oracle has not published a price, and says usage limits may apply. Ask your Oracle account team.
Why are LLMs always wrong about NetSuite details?
Much public SuiteScript is 1.0 or 2.0, and models cannot see your custom fields. Give the agent Oracle’s skills, imported objects and metadata tools, then validate on the server and test in a sandbox.
Should the agent log in to NetSuite as me?
The M2M mapping names an employee and a role, so the agent acts as whoever you map: mapped to you, its changes carry your name. A separate employee record keeps them apart; check whether it needs a user license.
Can I send a customer’s scripts and objects to Anthropic or OpenAI?
Check your customer contract and your AI vendor’s data terms first. Imported objects can hold account-specific values, which Oracle says include internal IDs and personal data. The Developer Assistant goes through your NetSuite account, but Oracle has not published its retention terms.
An admin wrote SuiteScript 2.0 scripts with ChatGPT. Is that a problem?
They run today, but 2.0 scripts run as 2.1 by default from 2028.1, and all scripts must be 2.1 from 2028.2. Ask for 2.1 and review governance, error handling and hard-coded IDs. See migrating to 2.1.
Sources
Oracle NetSuite Help Center:
- CLI: prerequisites, installing, project files and hooks, project:create, project:validate, project:deploy, file:upload, config:import, 2026.2 SDK release notes
- Authentication: OAuth 2.0 for SuiteCloud SDK, account:setup, account:setup:ci, account:manageauth, M2M for CI/CD, OAuth 2.0 Client Credentials Setup, Certificate Conditions, credential storage, account-specific domains
- SDF: enabling SDF, Developer role, ACP vs SuiteApp, account configuration, account-specific values, deleting components, object syntax, entitycustomfield, user event script XML, Suitelet XML, deployment status, deployment logs, custom fields
- SuiteScript and SuiteQL: SuiteScript 2.1 JSDoc validation, JSDoc tags, transitioning to 2.1, usage limits, API governance, Map/Reduce governance, script execution logs, SuiteQL limitations, SuiteQL best practices, query.runSuiteQL, Record.setValue, format.parse, SuiteScript FAQ, UI Component Overview
- AI: Agent Skills, using skills, skills with Cline, AI plug-ins, Developer Assistant guide, capabilities, VS Code setup, other tools, proxy:start, best practices, Cline guidance, Developer Assistant FAQ, AI Connector FAQ, ns_getRecordTypeMetadata, ns_getSuiteQLMetadata, NetSuite Next FAQ
Oracle, other: SuiteCloud SDK repository (CLI source, agent skills, unit testing README, issues #997, #1038, #1165, #1168, #1169, #1171); Oracle Database ROWNUM; SuiteConnect New York 2026 keynote; SuiteCloud Developer Assistant demo (January 22, 2026).
Tool vendors: Claude Code permissions, Claude Code hooks, Claude Code memory, Anthropic plug-in marketplace, Codex rules, Cursor CLI permissions, Cline rules, skills CLI, agents.md, GitHub deployment environments, TypeScript 7.0.
Third party: @hitc/netsuite-types, eslint-plugin-suitescript, anagram-dev/suitecloud-ts; Tim Dietrich, Developer Assistant vs Claude Code (January 15, 2026); Robin Mitchell, Developer Assistant setup in VS Code (May 14, 2026) and in WebStorm (August 10, 2026); SuiteStep, Sonar Performs Live, with Tim Dietrich (September 17, 2026); Marty Zigman (Prolecto), Rethinking Make vs. Buy for High Performance NetSuite Applications in the AI Era (April 19, 2026) and its video with Mathieu Laporte.
Related guides
- AI and NetSuite in 2026: every option and where to start.
- Oracle’s NetSuite agent skills: all 10 skills, installed.
- Migrate SuiteScript 1.0 to 2.1 with an AI agent: before 2028.2.
- Map and document a NetSuite account with AI: the account’s facts, safely.
- Connect NetSuite to Claude, ChatGPT and Claude Code: the AI Connector.
- Governing AI access to NetSuite: audit and revoke.
- Community skills, MCP servers and AI tools: agent-ready templates, types and lint.
SeamSet builds what a NetSuite account is missing (screens, scheduled exports, portals, approvals) from a request in plain words. Each change goes to a sandbox first, is tested, documented, approved by your NetSuite admin and audited. Rollback is a redeploy; your admin gets the list of what it cannot remove.