netsuite-mcp-server
Exposes NetSuite REST API for orchestrating Spendesk × NetSuite integration, providing tools to manage vendors, bills, journal entries, payments, and more.
README
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 DesktopHTTP 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
- Va dans Setup > Integration > Manage Integrations > New
- Remplis :
- Name:
Spendesk MCP Server - State:
Enabled - Coche Token-Based Authentication
- Name:
- Sauvegarde et note le Consumer Key et Consumer Secret
Créer l'Access Token
- Va dans Setup > Users/Roles > Access Tokens > New
- 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
- Application Name:
- 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 checkPOST /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 paginationnetsuite_get_vendor: Récupère un vendor par ID
Vendor Bills (Factures Fournisseurs)
netsuite_get_vendor_bills: Liste les vendor billsnetsuite_get_vendor_bill: Récupère une vendor bill par IDnetsuite_create_vendor_bill: Crée une nouvelle vendor bill avec lignes de dépense (supportedepartment,location,class)netsuite_update_vendor_bill: Met à jour une vendor bill existante
Journal Entries (Écritures Comptables)
netsuite_get_journal_entries: Liste les journal entriesnetsuite_create_journal_entry: Crée une journal entry avec lignes débit/crédit (supportedepartment,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 reportsnetsuite_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 creditsnetsuite_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 comptablenetsuite_get_departments: Liste les départements / cost centersnetsuite_get_subsidiaries: Liste les subsidiariesnetsuite_get_tax_codes: Liste les codes de taxenetsuite_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 fichiernetsuite_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
- Configure les variables d'environnement (les 5 credentials NetSuite + PORT)
- Commande de build :
npm run build - Commande de start :
npm run start:http - 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_tokenoauth_signature_method=HMAC-SHA256oauth_timestamp,oauth_nonceoauth_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
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。