Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free
6,000+ web scrapers for your AI agent, start free logo6,000+ web scrapers for your AI agent, start free

Apify gives your agent live web data: 6,000+ prebuilt scrapers and actors, MCP-ready. Sign up free with $5 in usage credits.

Try Apify free
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it — secured from day one.

Get it set up for you
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free
Reach 48,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here

Works with

Claude CodeClaude DesktopCursorVS CodeClineCodex CLIOpenClaw+ any MCP client

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

Exposes NetSuite REST API for orchestrating Spendesk × NetSuite integration, providing tools to manage vendors, bills, journal entries, payments, and more.

README.md

netsuite-mcp-server

Serveur MCP (Model Context Protocol) qui expose l'API REST NetSuite pour orchestrer les flux d'intégration Spendesk × NetSuite.

Architecture

Ce projet suit la même architecture que le serveur MCP Spendesk (mcp-poc) en production :

  • Node.js 20 + TypeScript
  • @modelcontextprotocol/sdk pour le serveur MCP
  • OAuth 1.0a TBA (HMAC-SHA256) pour l'authentification NetSuite
  • Deux modes de démarrage :
  • stdio : pour Cursor, Claude Desktop
  • HTTP Streamable : pour Dust, ChatGPT, déploiement cloud

Prérequis

1. Node.js 20+

node --version  # v20+

2. Credentials NetSuite (Sandbox)

Tu dois créer une Integration et un Access Token dans ton compte sandbox NetSuite :

Créer l'Integration

  1. Va dans Setup > Integration > Manage Integrations > New
  2. Remplis :
  • Name: Spendesk MCP Server
  • State: Enabled
  • Coche Token-Based Authentication
  1. Sauvegarde et note le Consumer Key et Consumer Secret

Créer l'Access Token

  1. Va dans Setup > Users/Roles > Access Tokens > New
  2. Sélectionne :
  • Application Name: Spendesk MCP Server
  • User: ton utilisateur (avec les bons rôles)
  • Role: Administrator ou custom role avec accès REST API
  1. Sauvegarde et note le Token ID et Token Secret

Installation

# Clone le repo
cd netsuite-mcp-server

# Installe les dépendances
npm install

# Configure les credentials
cp .env.example .env
# puis édite .env avec tes vraies credentials

Fichier .env

# NetSuite Sandbox credentials
NETSUITE_ACCOUNT_ID=TSTDRV1234567        # ton account ID sandbox
NETSUITE_CONSUMER_KEY=xxx
NETSUITE_CONSUMER_SECRET=xxx
NETSUITE_TOKEN_ID=xxx
NETSUITE_TOKEN_SECRET=xxx

# HTTP server (pour mode HTTP Streamable)
PORT=3001
HOST=0.0.0.0
ALLOWED_HOSTS=localhost

⚠️ Sécurité : .env est dans .gitignore, ne committe jamais tes vrais credentials.

Utilisation

Mode stdio (Cursor, Claude Desktop)

# Build
npm run build

# Lancer le serveur stdio
npm start

Configuration Cursor

Ajoute dans ton MCP config (~/.cursor/mcp.json ou équivalent) :

{
  "mcpServers": {
    "netsuite": {
      "command": "node",
      "args": ["/chemin/absolu/vers/netsuite-mcp-server/dist/index.js"],
      "env": {
        "NETSUITE_ACCOUNT_ID": "TSTDRV1234567",
        "NETSUITE_CONSUMER_KEY": "xxx",
        "NETSUITE_CONSUMER_SECRET": "xxx",
        "NETSUITE_TOKEN_ID": "xxx",
        "NETSUITE_TOKEN_SECRET": "xxx"
      }
    }
  }
}

Mode HTTP Streamable (Dust, ChatGPT, déploiement)

# Build
npm run build

# Lancer le serveur HTTP
npm run start:http

Le serveur écoute sur http://0.0.0.0:3001 par défaut.

Endpoints :

  • GET / : health check
  • POST /mcp : endpoint MCP Streamable HTTP (JSON-RPC + SSE)

Test du serveur HTTP

# Dans un terminal, lance le serveur :
npm run start:http

# Dans un autre terminal, teste :
npm run test:http

Tools MCP disponibles

Le serveur expose 25 tools pour orchestrer les flows Spendesk × NetSuite :

Vendors (Fournisseurs)

  • netsuite_get_vendors : Liste les vendors avec pagination
  • netsuite_get_vendor : Récupère un vendor par ID

Vendor Bills (Factures Fournisseurs)

  • netsuite_get_vendor_bills : Liste les vendor bills
  • netsuite_get_vendor_bill : Récupère une vendor bill par ID
  • netsuite_create_vendor_bill : Crée une nouvelle vendor bill avec lignes de dépense (supporte department, location, class)
  • netsuite_update_vendor_bill : Met à jour une vendor bill existante

Journal Entries (Écritures Comptables)

  • netsuite_get_journal_entries : Liste les journal entries
  • netsuite_create_journal_entry : Crée une journal entry avec lignes débit/crédit (supporte department, location, class)

Employees (Master Data)

  • netsuite_get_employees : Liste les employees (pour matcher Spendesk Members → NetSuite Employees)
  • netsuite_get_employee : Récupère un employee par ID

Expense Reports (Notes de Frais)

  • netsuite_get_expense_reports : Liste les expense reports
  • netsuite_create_expense_report : Crée un expense report pour un employee avec lignes de dépense (supporte devise étrangère, analytics)

Bill Payments (Paiements Fournisseurs)

  • netsuite_create_bill_payment : Crée un vendor payment et l'applique à une ou plusieurs vendor bills

Vendor Credits (Avoirs Fournisseurs)

  • netsuite_get_vendor_credits : Liste les vendor credits
  • netsuite_create_vendor_credit : Crée un vendor credit (credit note) et l'applique optionnellement à des vendor bills

Référentiel

  • netsuite_get_accounts : Liste le plan comptable
  • netsuite_get_departments : Liste les départements / cost centers
  • netsuite_get_subsidiaries : Liste les subsidiaries
  • netsuite_get_tax_codes : Liste les codes de taxe
  • netsuite_get_currencies : Liste les devises

Champs Analytiques (Analytics)

  • netsuite_get_locations : Liste les locations (dimension analytique)
  • netsuite_get_classifications : Liste les classifications / classes (dimension analytique)

Les trois dimensions analytiques NetSuite (department, location, class) sont supportées dans tous les tools de création (vendor bills, journal entries, expense reports, vendor credits).

File Cabinet (Pièces Jointes)

  • netsuite_upload_file : Upload un fichier (PDF, PNG, JPEG...) dans le File Cabinet NetSuite, retourne l'ID du fichier
  • netsuite_attach_file_to_record : Attache un fichier (via son ID) à un record NetSuite (vendor bill, expense report, vendor credit)

SuiteQL

  • netsuite_execute_suiteql : Exécute une requête SuiteQL (read-only, SELECT uniquement)

Exemples de requêtes SuiteQL :

-- Trouver un vendor par externalId
SELECT id, companyName, email FROM vendor WHERE externalId = 'spk_supplier_xxx'

-- Lister les vendor bills non approuvées
SELECT id, tranId, entity, amount, status FROM transaction
WHERE type = 'VendBill' AND status = 'VendBill:B'

-- Mapping account par numéro
SELECT id, acctNumber, acctName, type FROM account WHERE acctNumber LIKE '6%'

Tests

# Test de connexion NetSuite (liste 5 vendors)
npm run test:vendors

# Test du serveur HTTP MCP complet
npm run test:http

# Test de tous les 25 tools MCP
npm run test:all

Documentation détaillée

Pour les guides complets et les rapports métier, voir le dossier docs/ :

  • Guides de déploiement : docs/deploy/ (Quickstart, checklist, guide complet Railway/Dust)
  • Permissions & setup NetSuite : docs/setup/
  • Scénarios de test & rapports : docs/testing/
  • SuiteQL & fallbacks REST : docs/suiteql/
  • Mapping métier (vendors, bills, payments, expense reports) : docs/overview/, docs/vendors/, docs/bill-payments/

Déploiement

Docker

Un Dockerfile est prévu (à créer si besoin, inspiré du mcp-poc) :

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY dist ./dist
EXPOSE 3001
CMD ["node", "dist/server-http.js"]

Railway / Render / Fly.io

  1. Configure les variables d'environnement (les 5 credentials NetSuite + PORT)
  2. Commande de build : npm run build
  3. Commande de start : npm run start:http
  4. Port : 3001

Architecture technique

src/
├── index.ts                    # Entry point stdio
├── server-http.ts              # Entry point HTTP Streamable (Hono)
├── netsuite-client.ts          # Client REST NetSuite (OAuth 1.0a)
├── tools/
│   ├── index.ts                # Enregistre tous les tools
│   ├── vendors.ts              # Tools vendors
│   ├── vendor-bills.ts         # Tools vendor bills (+ location, class)
│   ├── journal-entries.ts      # Tools journal entries (+ location, class)
│   ├── employees.ts            # Tools employees (NEW)
│   ├── expense-reports.ts      # Tools expense reports (NEW)
│   ├── payments.ts             # Tools bill payments (NEW)
│   ├── vendor-credits.ts       # Tools vendor credits (NEW)
│   ├── analytics.ts            # Tools locations + classifications (NEW)
│   ├── file-cabinet.ts         # Tools file upload + attach (NEW)
│   ├── reference.ts            # Tools référentiel
│   └── suiteql.ts              # Tool SuiteQL
└── utils/
    ├── oauth1.ts               # Génération header OAuth 1.0a HMAC-SHA256
    └── pagination.ts           # Helper pagination NetSuite

Authentification NetSuite

Le client utilise OAuth 1.0a avec signature HMAC-SHA256, implémenté from scratch (pas de lib externe) dans utils/oauth1.ts.

Chaque requête inclut un header Authorization: OAuth ... avec :

  • oauth_consumer_key, oauth_token
  • oauth_signature_method=HMAC-SHA256
  • oauth_timestamp, oauth_nonce
  • oauth_signature (HMAC-SHA256 de la Signature Base String)

Gestion des erreurs

Tous les tools MCP catchent les erreurs NetSuite et retournent des messages clairs, ex :

NetSuite 401: Invalid credentials. Check NETSUITE_TOKEN_ID and NETSUITE_TOKEN_SECRET.
NetSuite 400: Bad Request

Idempotence

Les tools de création acceptent un paramètre externalId (ex: spendesk_supplier_id, spendesk_payable_id) pour éviter les doublons si l'agent rejoue un flow.

Logs

Les logs sont sur stderr (pas stdout, qui est réservé au protocole stdio MCP).

Exemple :

Starting NetSuite MCP HTTP server on 0.0.0.0:3001
Health check: http://0.0.0.0:3001/
MCP endpoint: http://0.0.0.0:3001/mcp

Ressources

Dépannage

Erreur 401 Invalid credentials

Vérifie que :

  • Les 5 variables d'environnement sont correctement renseignées
  • L'Access Token n'est pas expiré (dans NetSuite : Setup > Access Tokens)
  • Le rôle associé au token a les permissions REST API

Erreur 400 Bad Request sur un endpoint

Certains endpoints référentiels (/account, /department, etc.) peuvent ne pas exister ou nécessiter une syntaxe différente selon la version NetSuite. Utilise SuiteQL comme alternative :

SELECT id, acctNumber, acctName FROM account LIMIT 10

Le serveur HTTP ne répond pas

Vérifie que le port 3001 est libre :

lsof -ti:3001  # Si un PID apparaît, kill-le
npm run start:http

Licence

MIT

See related servers & alternatives →

Related MCP servers

Browse all →

Related guides

Hand-picked reading to help you choose and use Finance & Payments servers.