NetSuite MCP Server OAuth 2.0 SuiteQL API Access
Enable secure NetSuite access with an MCP server using OAuth 2.0 to run SuiteQL, reports, saved searches and REST API calls via natural language.
npx -y @dsvantien/netsuite-mcp-serverOverview
This MCP (Model Context Protocol) server provides a secure intermediary between large language models (LLMs) or other AI agents and a NetSuite account. It exposes a small, focused API that uses OAuth 2.0 to obtain and manage NetSuite access tokens, then runs SuiteQL queries, saved searches, reports, and REST API calls on behalf of the caller. By centralizing authentication and access logic, the server reduces credential sprawl and lets LLM-driven tools request data using natural language or structured queries.
For developers building AI integrations, the server is useful because it standardizes how downstream models access NetSuite data and enforces security best practices (scoped OAuth credentials, token caching, HTTPS). It also translates simple requests into NetSuite SuiteQL or REST calls, making it straightforward to combine NetSuite data sources with generative models (for chat assistants, automation bots, or analytics).
Features
- OAuth 2.0 client handling for NetSuite (token acquisition and refresh)
- SuiteQL execution endpoint for SQL-style queries against NetSuite records
- Proxy endpoints for saved searches, standard reports, and REST API calls
- Simple JSON-based API suitable for MCP / LLM tool integrations
- Token caching and configurable timeouts to reduce auth overhead
- Configurable access controls and CORS for safe hosting
- Docker-friendly configuration for deployment
Installation / Configuration
Prerequisites: Node.js (14+), npm or Docker.
- Clone the repository and install dependencies:
- Create a .env file (example variables shown):
# NetSuite OAuth2
NETSUITE_ACCOUNT=1234567_SB1
NETSUITE_CLIENT_ID=your_client_id
NETSUITE_CLIENT_SECRET=your_client_secret
NETSUITE_OAUTH_TOKEN_URL=https://account.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token
# Server
PORT=3000
NODE_ENV=production
CACHE_TTL_SECONDS=300
# Security
ALLOWED_ORIGINS=https://your-app.example.com
- Run locally:
# or for development:
- Docker (optional) — build and run:
# Dockerfile (example)
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
ENV NODE_ENV=production
CMD ["node", "dist/index.js"]
Available Resources
Below are typical endpoints the server exposes (paths may vary by implementation). Check the repository for exact route names and payload shapes.
| Endpoint | Method | Purpose |
|---|---|---|
| /auth/token | POST | Obtain or refresh NetSuite OAuth 2.0 access token |
| /suiteql | POST | Run a SuiteQL query; returns tabular results |
| /saved-search | POST | Execute a saved search by internal ID |
| /report | POST | Run a report and retrieve results |
| /rest/* | ANY | Proxy requests to NetSuite REST endpoints |
Example SuiteQL request (curl):
;Response (JSON):
Use Cases
- Natural language assistant: Connect an LLM that accepts a “tool” for NetSuite data. The assistant sends plain-language requests (e.g., “List top 10 customers by revenue this quarter”), which your application translates to SuiteQL and executes via the MCP server.
- Report automation: Trigger scheduled jobs that run saved reports or SuiteQL queries and push summarized results to Slack, email, or a BI tool.
- Data enrichment: Combine NetSuite contact or transaction data with external sources. Use the MCP server to fetch records securely, then enrich them in your application before sending to a model for analysis.
- Restricted service accounts: Host one server that holds OAuth client credentials and enforces scoping/filters, so individual clients never need direct NetSuite credentials.
Security & Best Practices
- Store NETSUITE_CLIENT_SECRET and other secrets in a secure vault or environment variables; do not commit them to source control.
- Serve the MCP server over HTTPS and restrict ALLOWED_ORIGINS to known hosts.
- Use least-privilege OAuth scopes on the NetSuite application credentials.
- Audit and log calls to the proxy endpoints; consider rate limiting and IP allowlists.
- Validate and sanitize SuiteQL and request payloads to prevent abuse.
For full API details and code examples, refer to the repository code and example configuration files. The server is intended to be extended or embedded into larger LLM orchestration systems that use MCP-style tooling to provide secure, auditable access to NetSuite data.
Common Issues & Solutions
You received an unsolicited GitHub issue saying your project is listed on Spark and instructs you to claim it. You're unsure whether the request and link are legitimate or safe to follow.
I ran into this too! I verified the Spark domain and the asset page actually pointed at my repo, then used the claim flow on the site rather than clicking the link in the issue. I signed in with GitHub, checked the OAuth scopes to ensure it only requested repo metadata/push access, and confirmed the site detected my push permission before accepting the claim. After claiming I added the 'Listed on Spark' badge via a normal README PR and closed the issue. If anything felt off I revoked the token in GitHub and emailed [email protected] for confirmation.
The auth flow tries to open a browser, but the MCP server is headless with no browser available. The user wants the auth command to print the URL or a device code so they can copy/paste it from another machine.
I ran into this too! On a headless host I used the device-authorization flow: run mcp auth login --device-code (or mcp auth login --no-browser) and the CLI printed a verification URL and short code instead of opening a browser. I visited that URL on my laptop, entered the code, and the headless server completed the OAuth exchange. For unattended runs I copied the refresh token from ~/.config/mcp/credentials.json into an environment variable (MCP_AUTH_TOKEN) the service reads. If you need fully non-interactive auth, set up a service account/client-credentials flow if supported.