Access NetSuite Data via Natural Language
MCP bridge giving Claude Code, Cursor, and Gemini CLI access to NetSuite via OAuth 2.0 PKCE and SuiteQL/report tools.
Maintainer of this project? Claim this page to edit the listing.
1.0.0Add to Favorites
Why it matters
Securely connect to your NetSuite ERP system using natural language. Retrieve business data, reports, and execute operations without writing code.
Outcomes
What it gets done
Execute SuiteQL queries and run saved searches.
Retrieve, create, and update NetSuite records.
List and run financial reports.
Authenticate and manage your NetSuite session securely.
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/vb-netsuite | bash Capabilities
Tools your agent gets
Execute SuiteQL queries against NetSuite data
List available financial reports in NetSuite
Execute a specific financial report in NetSuite
List saved searches available in NetSuite
Execute a saved search in NetSuite
Retrieve a specific record from NetSuite
Create a new record in NetSuite
Update an existing record in NetSuite
Overview
NetSuite MCP Server
An MCP server bridging Claude Code, Cursor IDE, and Gemini CLI to NetSuite via OAuth 2.0 PKCE authentication, exposing SuiteQL queries, reports, saved searches, and record CRUD. Use when you need natural-language access to NetSuite business data, reports, or records from an MCP-compatible development tool.
What it does
This MCP server provides access to NetSuite data through OAuth 2.0 with PKCE authentication, working with any MCP-compatible client including Claude Code, Cursor IDE, and Gemini CLI. NetSuite's official AI Connector SuiteApp only supports Claude via Anthropic's web interface or ChatGPT via custom GPT connections - developers using MCP-compatible CLI/IDE tools couldn't leverage NetSuite's AI capabilities because no MCP server implementation existed. This server bridges that gap, exposing the same functionality as NetSuite's AI Connector through any MCP client, with the same OAuth 2.0 + PKCE security standard, so developers can query business data, generate reports, and automate NetSuite operations without leaving their IDE or CLI.
When to use - and when NOT to
Use this connector when you need natural-language access to NetSuite data - SuiteQL queries, saved searches, reports, or record CRUD - from an MCP-compatible development tool. Prerequisites: Node.js 18+, a NetSuite account with MCP access, the NetSuite AI Connector SuiteApp (Bundle ID 522506) installed and configured, and a NetSuite Integration Record with OAuth 2.0 and PKCE enabled - without the SuiteApp, MCP tools won't be available even after successful authentication.
Capabilities
Features include OAuth 2.0 with PKCE (no client secret required), automatic token refresh before expiration, environment-variable credential configuration, session persistence across server restarts, and a modular codebase. Once authenticated, available NetSuite MCP tools include ns_runCustomSuiteQL (execute SuiteQL queries), ns_listAllReports/ns_runReport (list and execute financial reports), ns_listSavedSearches/ns_runSavedSearch (list and execute saved searches), and ns_getRecord/ns_createRecord/ns_updateRecord (record CRUD) - the exact set depends on the NetSuite account's configuration.
How to install
First, install the NetSuite AI Connector SuiteApp, then create an OAuth integration record (Setup > Integration > Manage Integrations > New) with Authorization Code Grant and Public Client checked, a redirect URI like http://localhost:8080/callback, and copy the Client ID (no client secret needed for this public-client PKCE pattern). For the MCP client config (~/.claude.json for Claude Code, .cursor/mcp.json for Cursor), the recommended setup runs npx @suiteinsider/netsuite-mcp@latest with NETSUITE_ACCOUNT_ID, NETSUITE_CLIENT_ID, and optional OAUTH_CALLBACK_PORT (default 8080) as environment variables; alternatively clone the repo and run via node with an absolute path for local development, or omit environment variables and supply credentials directly when calling netsuite_authenticate. After configuring, say "Authenticate with NetSuite" to open a browser login flow; tools only appear after restarting the chat or reconnecting the MCP server, which is normal MCP session-caching behavior.
Integrations
The OAuth flow: the user triggers netsuite_authenticate, the server generates a PKCE code verifier and SHA-256 challenge, opens a NetSuite login page via a local callback server, receives the authorization code at the redirect URI, exchanges it for access/refresh tokens using the public-client pattern (no Authorization header), stores tokens in sessions/session.json for persistence, and auto-refreshes tokens within a 5-minute expiry buffer. The codebase is modular by single responsibility: pkce.js (challenge/verifier generation), callbackServer.js (CSRF-protected HTTP callback handling), sessionStorage.js (session persistence), tokenExchange.js (NetSuite OAuth token exchange/refresh), and browserLauncher.js (cross-platform browser opening). Security practices: restrict config file permissions (chmod 600 ~/.claude.json), never commit credential-bearing config files, and rely on PKCE rather than a stored client secret. Troubleshooting: a "port already in use" error means another process holds the OAuth callback port (check with lsof -i :8080, or change OAUTH_CALLBACK_PORT and update NetSuite's redirect URI to match); tools not appearing after auth means the MCP client cached its tool list at session start, fixed by restarting the chat or reconnecting. Standalone authentication can be tested via node authenticate.js <accountId> <clientId>, and a session can be cleared with rm -rf sessions/ or the netsuite_logout tool. This server is MIT-licensed.
Who it's for
Developers using Claude Code, Cursor IDE, Gemini CLI, or other MCP clients who need natural-language access to NetSuite business data, reports, and saved searches directly from their development environment, using the same OAuth 2.0/PKCE security NetSuite's own official AI Connector requires.
Source README
NetSuite MCP Server
A Model Context Protocol (MCP) server providing access to NetSuite data through OAuth 2.0 with PKCE authentication. Works seamlessly with any MCP-compatible client including Claude Code, Cursor IDE, and Gemini CLI.
Motivation and Context
NetSuite provides an official AI Connector SuiteApp that enables AI-powered interactions with NetSuite data. However, NetSuite's AI Connector currently only supports:
- Claude via Anthropic's web interface
- ChatGPT via custom GPT connections
The problem: Developers using MCP-compatible tools like Claude Code, Cursor IDE, Windsurf, or other CLI/IDE environments cannot leverage NetSuite's AI capabilities
because there's no MCP server implementation.
This MCP server solves that gap by:
- Providing the missing bridge between MCP clients (Claude Code, Cursor, Gemini CLI, etc.) and NetSuite's AI Connector
- Enabling the exact same functionality that NetSuite's AI Connector provides, but accessible through any MCP-compatible client
- Allowing developers to interact with NetSuite data using natural language directly within their development environment
- Maintaining the same security standards (OAuth 2.0 with PKCE) required by NetSuite's official AI Connector
In essence, this MCP server brings NetSuite's AI capabilities to the broader MCP ecosystem, allowing developers to query business data, generate reports, and automate
NetSuite operations without leaving their IDE or CLI.
Features
- ✅ OAuth 2.0 with PKCE - Secure authentication without client secrets
- ✅ Automatic Token Refresh - Tokens refresh automatically before expiration
- ✅ Environment Variable Support - Configure credentials once in your MCP config
- ✅ Session Persistence - Authentication survives server restarts
- ✅ Universal MCP Integration - Works with Claude Code, Cursor IDE, Gemini CLI, and other MCP clients
- ✅ NetSuite MCP Tools - Access to all NetSuite MCP capabilities (SuiteQL, Reports, Saved Searches, etc.)
- ✅ Modular Architecture - Clean, maintainable codebase following single-responsibility principle
Quick Start
1. NetSuite Setup
Step 1: Install NetSuite AI Connector SuiteApp
Before creating the integration record, you must install and configure the NetSuite AI Connector SuiteApp:
Important: The NetSuite AI Connector SuiteApp is required for MCP functionality. Without it, the MCP tools will not be available even after authentication.
Step 2: Create OAuth Integration Record
After installing the SuiteApp, create an integration record:
- Navigate to Setup > Integration > Manage Integrations > New
- Fill in the details:
- Name: "MCP Server Integration"
- OAuth 2.0: Checked Authorization Code Grant
Checked Public Client - Redirect URI:
http://localhost:8080/callback(or your custom port)
- Save and copy the Client ID (consumer key)
Note: we dont need client secret (since this is public client and Authorization Code Grant with pkce)
2. MCP Client Configuration
Add to your MCP client's configuration file:
Claude Code: ~/.claude.json
Cursor IDE: .cursor/mcp.json
Gemini CLI: Per Gemini's MCP setup
Option A: Using npx (Recommended - No Installation Required)
{
"mcpServers": {
"netsuite": {
"command": "npx",
"args": ["@suiteinsider/netsuite-mcp@latest"],
"env": {
"NETSUITE_ACCOUNT_ID": "your-account-id",
"NETSUITE_CLIENT_ID": "your-client-id",
"OAUTH_CALLBACK_PORT": "8080"
}
}
}
}
Benefits:
- No manual installation required
- Always uses the latest version with
@latest - Clean, simple configuration
- Works immediately after MCP client restart
Optional Environment Variables:
OAUTH_CALLBACK_PORT- OAuth callback port (default: 8080)
Option B: Local Development Setup
For contributing or local development:
# Clone the repository
git clone https://github.com/dsvantien/netsuite-mcp-server.git
cd netsuite-mcp-server
# Install dependencies
npm install
# Test locally with npm link
npm link
Then configure with absolute path:
{
"mcpServers": {
"netsuite": {
"command": "node",
"args": ["/absolute/path/to/netsuite-mcp-server/src/index.js"],
"env": {
"NETSUITE_ACCOUNT_ID": "your-account-id",
"NETSUITE_CLIENT_ID": "your-client-id",
"OAUTH_CALLBACK_PORT": "8080"
}
}
}
}
Option C: Without Environment Variables
{
"mcpServers": {
"netsuite": {
"command": "npx",
"args": ["@suiteinsider/netsuite-mcp@latest"]
}
}
}
Note: You'll need to provide credentials when calling netsuite_authenticate
3. Authenticate & Use
Start your MCP client and authenticate:
Authenticate with NetSuite
A browser window opens → Login to NetSuite → Authentication complete!
Important: After authentication, you'll need to restart your chat or reconnect the MCP server to see NetSuite tools. This is normal MCP behavior.
Once authenticated, use natural language queries:
Show me all customers
List available saved searches
Run a SuiteQL query to get sales orders from last month
Execute the "Monthly Revenue" report
Architecture
MCP Client (Claude Code, Cursor, Gemini, etc.)
│
│ stdio (JSON-RPC)
▼
┌──────────────────────────────┐
│ MCP Server (Node.js) │
│ │
│ ┌────────────────────────┐ │
│ │ OAuth Manager │ │
│ │ - PKCE generation │ │
│ │ - Local HTTP server │ │
│ │ (port 8080 default) │ │
│ │ - Token storage │ │
│ └────────────────────────┘ │
│ │
│ ┌────────────────────────┐ │
│ │ MCP Tools │ │
│ │ - ns_runCustomSuiteQL │ │
│ │ - ns_runReport │ │
│ │ - ns_listSavedSearches │ │
│ └────────────────────────┘ │
└──────────────────────────────┘
│
│ HTTPS + Bearer Token
▼
┌──────────────────────────────┐
│ NetSuite MCP REST API │
└──────────────────────────────┘
Project Structure
netsuite-mcp-server/
├── src/
│ ├── index.js # Main MCP server entry point
│ ├── oauth/
│ │ ├── manager.js # OAuth flow orchestrator
│ │ ├── pkce.js # PKCE challenge/verifier generation
│ │ ├── callbackServer.js # HTTP callback server with CSRF protection
│ │ ├── sessionStorage.js # Session file management
│ │ └── tokenExchange.js # Token exchange & refresh operations
│ ├── mcp/
│ │ └── tools.js # NetSuite MCP API client
│ └── utils/
│ └── browserLauncher.js # Cross-platform browser launcher
├── sessions/ # OAuth tokens (gitignored)
├── authenticate.js # Standalone CLI authentication utility
├── package.json
├── .gitignore
└── README.md
Modular Design Benefits
The codebase follows the single-responsibility principle:
- pkce.js - PKCE utilities (base64 encoding, challenge generation)
- callbackServer.js - HTTP callback handling (CSRF protection, HTML pages, timeouts)
- sessionStorage.js - Session persistence (save, load, clear, isAuthenticated)
- tokenExchange.js - NetSuite OAuth API communication (token exchange/refresh)
- browserLauncher.js - Cross-platform URL opening (macOS, Windows, Linux)
This modular structure enables:
- ✅ Independent testing of each module
- ✅ Easy maintenance and debugging
- ✅ Reusability in other projects
- ✅ Clear separation of concerns
Environment Variable Configuration
Configuration Example
Recommended npx setup:
{
"mcpServers": {
"netsuite": {
"command": "npx",
"args": ["@suiteinsider/netsuite-mcp@latest"],
"env": {
"NETSUITE_ACCOUNT_ID": "123456-sb1",
"NETSUITE_CLIENT_ID": "your-client-id-here",
"OAUTH_CALLBACK_PORT": "8080"
}
}
}
}
Local development setup:
{
"mcpServers": {
"netsuite": {
"command": "node",
"args": ["path/to/src/index.js"],
"env": {
"NETSUITE_ACCOUNT_ID": "123456-sb1",
"NETSUITE_CLIENT_ID": "your-client-id-here",
"OAUTH_CALLBACK_PORT": "8080"
}
}
}
}
Environment Variables
- NETSUITE_ACCOUNT_ID - Your NetSuite account ID (required)
- NETSUITE_CLIENT_ID - Your OAuth client ID (required)
- OAUTH_CALLBACK_PORT - OAuth callback port (optional, default: 8080)
Resolution Order
- Check arguments first: If
accountIdorclientIdprovided as arguments, use them - Fallback to environment variables: If no arguments, use env vars
- Validation: If neither source provides credentials, show error with instructions
Security Best Practices
- File Permissions: Ensure config file has restrictive permissions
chmod 600 ~/.claude.json - No Secrets: Client secrets not required (PKCE authentication)
- Local Token Storage: OAuth tokens stored in
sessions/directory - Never Commit: Don't commit config files with credentials to git
Available NetSuite MCP Tools
Once authenticated, you'll have access to NetSuite's native MCP tools:
ns_runCustomSuiteQL- Execute SuiteQL queriesns_listAllReports- List available financial reportsns_runReport- Execute a specific reportns_listSavedSearches- List saved searchesns_runSavedSearch- Execute a saved searchns_getRecord- Retrieve a specific recordns_createRecord- Create a new recordns_updateRecord- Update an existing record- And more...
The exact tools available depend on your NetSuite account configuration.
OAuth Flow
- Initiation: User calls
netsuite_authenticatewith credentials - PKCE Generation: Server generates code verifier and SHA-256 challenge
- Authorization URL: Server generates NetSuite OAuth URL and starts local callback server
- User Login: Browser opens NetSuite login page
- Authorization: User approves access
- Callback: NetSuite redirects to
http://localhost:8080/callbackwith authorization code - Token Exchange: Server exchanges code for access/refresh tokens (public client pattern)
- Session Storage: Tokens stored in
sessions/session.json(persists across restarts) - Auto-Refresh: Tokens automatically refresh when expiring (5-minute buffer)
Troubleshooting
now uses absolute paths based on script location
Issue: "Port already in use"
Cause: Another application using the OAuth callback port
Solution:
# Check what's using the port (example for port 8080)
lsof -i :8080
# Option 1: Kill the process
# Option 2: Change port via environment variable
Set custom port in your MCP config:
{
"env": {
"OAUTH_CALLBACK_PORT": "9000"
}
}
Remember to update the redirect URI in your NetSuite integration to match the new port!
Issue: Tools not appearing after authentication
Cause: MCP clients cache tool list at session start
Solution:
- Restart chat - Open new conversation
- Reconnect MCP - Use
/mcpcommand (Claude Code) - Restart app - Close and reopen your IDE
This is normal MCP behavior - tool lists are fetched once per session.
Development
Standalone Authentication
Test authentication without MCP client:
node authenticate.js <accountId> <clientId>
Clearing Session
rm -rf sessions/
Or use the netsuite_logout tool in your MCP client.
Viewing Logs
All server logs output to stderr. When running in MCP clients, these logs appear in the client's console/logs.
Technical Details
PKCE Implementation
- Code Verifier: 32 random bytes, base64url encoded
- Code Challenge: SHA-256 hash of verifier, base64url encoded
- Challenge Method: S256 (required by NetSuite)
Token Exchange (Public Client Pattern)
POST https://{accountId}.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code={authorization_code}
&redirect_uri=http://localhost:8080/callback
&client_id={client_id}
&code_verifier={verifier}
Important: No Authorization header (public client).
Token Refresh
Tokens automatically refresh when expiring in < 5 minutes:
POST https://{accountId}.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
&refresh_token={refresh_token}
&client_id={client_id}
Prerequisites
- Node.js 18.0.0 or higher
- NetSuite Account with MCP access
- NetSuite AI Connector SuiteApp (Bundle ID: 522506) installed and configured
- NetSuite Integration Record with OAuth 2.0 and PKCE enabled
- MCP Client - Any MCP-compatible client (Claude Code, Cursor IDE, Gemini CLI, etc.)
References
FAQ
Common questions
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.