How to integrate Netsuite MCP with LangChain

This guide walks you through connecting Netsuite to LangChain using the Composio tool router. By the end, you'll have a working Netsuite agent that can generate monthly profit and loss report, list overdue invoices for all customers, create new sales order for a client through natural language commands. This guide will help you understand how to give your LangChain agent real control over a Netsuite account through Composio's Netsuite MCP server. Before we dive in, let's take a quick look at the key ideas and tools involved.

Netsuite logoNetsuite
Oauth2

NetSuite by Oracle is a cloud-based ERP suite combining accounting, CRM, e-commerce, and inventory management. It streamlines business operations with real-time insights and unified data.

85 Tools

Introduction

This guide walks you through connecting Netsuite to LangChain using the Composio tool router. By the end, you'll have a working Netsuite agent that can generate monthly profit and loss report, list overdue invoices for all customers, create new sales order for a client through natural language commands.

This guide will help you understand how to give your LangChain agent real control over a Netsuite account through Composio's Netsuite MCP server.

Before we dive in, let's take a quick look at the key ideas and tools involved.

Also integrate Netsuite with

TL;DR

Here's what you'll learn:
  • Get and set up your OpenAI and Composio API keys
  • Connect your Netsuite project to Composio
  • Create a Tool Router MCP session for Netsuite
  • Initialize an MCP client and retrieve Netsuite tools
  • Build a LangChain agent that can interact with Netsuite
  • Set up an interactive chat interface for testing

What is LangChain?

LangChain is a framework for developing applications powered by language models. It provides tools and abstractions for building agents that can reason, use tools, and maintain conversation context.

Key features include:

  • Agent Framework: Build agents that can use tools and make decisions
  • MCP Integration: Connect to external services through Model Context Protocol adapters
  • Memory Management: Maintain conversation history across interactions
  • Multi-Provider Support: Works with OpenAI, Anthropic, and other LLM providers

What is the Netsuite MCP server, and what's possible with it?

The Netsuite MCP server is an implementation of the Model Context Protocol that connects your AI agent and assistants like Claude, Cursor, etc directly to your Netsuite account. It provides structured and secure access to your business data, so your agent can perform actions like creating invoices, managing inventory, tracking customer records, and automating financial workflows on your behalf.

  • Automated invoice creation and management: Let your agent generate, send, and update invoices for customers, streamlining your accounts receivable process.
  • Real-time inventory control: Ask your agent to check stock levels, update inventory records, and manage supply chain transactions seamlessly.
  • Customer and vendor record management: Have the agent create, update, or retrieve customer and vendor profiles, keeping your CRM data fresh and accurate.
  • Financial reporting and analytics: Direct your agent to pull balance sheets, profit & loss statements, or transaction histories for up-to-date business insights.
  • Order processing automation: Enable your agent to create sales orders, manage purchase orders, and track fulfillment status across your operations.

What is the Composio tool router, and how does it fit here?

What is Composio SDK?

Composio's Composio SDK helps agents find the right tools for a task at runtime. You can plug in multiple toolkits (like Gmail, HubSpot, and GitHub), and the agent will identify the relevant app and action to complete multi-step workflows. This can reduce token usage and improve the reliability of tool calls. Read more here: Getting started with Composio SDK

The tool router generates a secure MCP URL that your agents can access to perform actions.

How the Composio SDK works

The Composio SDK follows a three-phase workflow:

  1. Discovery: Searches for tools matching your task and returns relevant toolkits with their details.
  2. Authentication: Checks for active connections. If missing, creates an auth config and returns a connection URL via Auth Link.
  3. Execution: Executes the action using the authenticated connection.

Step-by-step Guide

Step by step10 STEPS
1

Prerequisites

Before starting this tutorial, make sure you have:
  • Python 3.10 or higher installed on your system
  • A Composio account with an API key
  • An OpenAI API key
  • Basic familiarity with Python and async programming
2

Getting API Keys for OpenAI and Composio

OpenAI API Key
  • Go to the OpenAI dashboard and create an API key. You'll need credits to use the models, or you can connect to another model provider.
  • Keep the API key safe.
Composio API Key
  • Log in to the Composio dashboard.
  • Navigate to your API settings and generate a new API key.
  • Store this key securely as you'll need it for authentication.
3

Install dependencies

npm install @composio/langchain @langchain/core @langchain/openai @langchain/mcp-adapters dotenv

Install the required packages for LangChain with MCP support.

What's happening:

  • @composio/langchain provides Composio integration for LangChain
  • @langchain/mcp-adapters enables MCP client connections
  • @langchain/core is the core agent framework
  • dotenv/config loads environment variables
4

Set up environment variables

bash
COMPOSIO_API_KEY=your_composio_api_key_here
COMPOSIO_USER_ID=your_composio_user_id_here
OPENAI_API_KEY=your_openai_api_key_here

Create a .env file in your project root.

What's happening:

  • COMPOSIO_API_KEY authenticates your requests to Composio's API
  • COMPOSIO_USER_ID identifies the user for session management
  • OPENAI_API_KEY enables access to OpenAI's language models
5

Import dependencies

import { Composio } from '@composio/core';
import { LangchainProvider } from '@composio/langchain';
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
import { createAgent } from "langchain";
import * as readline from 'readline';
import 'dotenv/config';

dotenv.config();
What's happening:
  • We're importing LangChain's MCP adapter and Composio SDK
  • The dotenv/config import loads environment variables from your .env file
  • This setup prepares the foundation for connecting LangChain with Netsuite functionality through MCP
6

Initialize Composio client

const composioApiKey = process.env.COMPOSIO_API_KEY;
const userId = process.env.COMPOSIO_USER_ID;

if (!composioApiKey) throw new Error('COMPOSIO_API_KEY is not set');
if (!userId) throw new Error('COMPOSIO_USER_ID is not set');

async function main() {
    const composio = new Composio({
        apiKey: composioApiKey as string,
        provider: new LangchainProvider()
    });
What's happening:
  • We're loading the COMPOSIO_API_KEY from environment variables and validating it exists
  • Creating a Composio instance that will manage our connection to Netsuite tools
  • Validating that COMPOSIO_USER_ID is also set before proceeding
7

Create a Tool Router session

const session = await composio.create(
    userId as string,
    {
        toolkits: ['netsuite']
    }
);

const url = session.mcp.url;
What's happening:
  • We're creating a Tool Router session that gives your agent access to Netsuite tools
  • The create method takes the user ID and specifies which toolkits should be available
  • The returned session.mcp.url is the MCP server URL that your agent will use
  • This approach allows the agent to dynamically load and use Netsuite tools as needed
8

Configure the agent with the MCP URL

const client = new MultiServerMCPClient({
    "netsuite-agent": {
        transport: "http",
        url: url,
        headers: {
            "x-api-key": process.env.COMPOSIO_API_KEY
        }
    }
});

const tools = await client.getTools();

const agent = createAgent({ model: "gpt-5", tools });
What's happening:
  • We're creating a MultiServerMCPClient that connects to our Netsuite MCP server via HTTP
  • The client is configured with a name and the URL from our Tool Router session
  • getTools() retrieves all available Netsuite tools that the agent can use
  • We're creating a LangChain agent using the GPT-5 model
9

Set up interactive chat interface

let conversationHistory: any[] = [];

console.log("Chat started! Type 'exit' or 'quit' to end the conversation.\n");
console.log("Ask any Netsuite related question or task to the agent.\n");

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    prompt: 'You: '
});

rl.prompt();

rl.on('line', async (userInput: string) => {
    const trimmedInput = userInput.trim();

    if (['exit', 'quit', 'bye'].includes(trimmedInput.toLowerCase())) {
        console.log("\nGoodbye!");
        rl.close();
        process.exit(0);
    }

    if (!trimmedInput) {
        rl.prompt();
        return;
    }

    conversationHistory.push({ role: "user", content: trimmedInput });
    console.log("\nAgent is thinking...\n");

    const response = await agent.invoke({ messages: conversationHistory });
    conversationHistory = response.messages;

    const finalResponse = response.messages[response.messages.length - 1]?.content;
    console.log(`Agent: ${finalResponse}\n`);
        
        rl.prompt();
    });

    rl.on('close', () => {
        console.log('\n👋 Session ended.');
        process.exit(0);
    });
What's happening:
  • We initialize an empty conversationHistory list to maintain context across interactions
  • A readline interface is used to continuously accept user input from the command line
  • When a user types a message, it's added to the conversation history and sent to the agent
  • The agent processes the request using the invoke() method with the full conversation history
  • Users can type 'exit', 'quit', or 'bye' to end the chat session gracefully
10

Run the application

main().catch((err) => {
    console.error('Fatal error:', err);
    process.exit(1);
});
What's happening:
  • We call the main() function to start the application

Complete Code

Here's the complete code to get you started with Netsuite and LangChain:

import { Composio } from '@composio/core';
import { LangchainProvider } from '@composio/langchain';
import { MultiServerMCPClient } from "@langchain/mcp-adapters";  
import { createAgent } from "langchain";
import * as readline from 'readline';
import 'dotenv/config';

const composioApiKey = process.env.COMPOSIO_API_KEY;
const userId = process.env.COMPOSIO_USER_ID;

if (!composioApiKey) throw new Error('COMPOSIO_API_KEY is not set');
if (!userId) throw new Error('COMPOSIO_USER_ID is not set');

async function main() {
    const composio = new Composio({
        apiKey: composioApiKey as string,
        provider: new LangchainProvider()
    });

    const session = await composio.create(
        userId as string,
        {
            toolkits: ['netsuite']
        }
    );

    const url = session.mcp.url;
    
    const client = new MultiServerMCPClient({
        "netsuite-agent": {
            transport: "http",
            url: url,
            headers: {
                "x-api-key": process.env.COMPOSIO_API_KEY
            }
        }
    });
    
    const tools = await client.getTools();
  
    const agent = createAgent({ model: "gpt-5", tools });
    
    let conversationHistory: any[] = [];
    
    console.log("Chat started! Type 'exit' or 'quit' to end the conversation.\n");
    console.log("Ask any Netsuite related question or task to the agent.\n");
    
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
        prompt: 'You: '
    });

    rl.prompt();

    rl.on('line', async (userInput: string) => {
        const trimmedInput = userInput.trim();
        
        if (['exit', 'quit', 'bye'].includes(trimmedInput.toLowerCase())) {
            console.log("\nGoodbye!");
            rl.close();
            process.exit(0);
        }
        
        if (!trimmedInput) {
            rl.prompt();
            return;
        }
        
        conversationHistory.push({ role: "user", content: trimmedInput });
        console.log("\nAgent is thinking...\n");
        
        const response = await agent.invoke({ messages: conversationHistory });
        conversationHistory = response.messages;
        
        const finalResponse = response.messages[response.messages.length - 1]?.content;
        console.log(`Agent: ${finalResponse}\n`);
        
        rl.prompt();
    });

    rl.on('close', () => {
        console.log('\nSession ended.');
        process.exit(0);
    });
}

main().catch((err) => {
    console.error('Fatal error:', err);
    process.exit(1);
});

Conclusion

You've successfully built a LangChain agent that can interact with Netsuite through Composio's Tool Router.

Key features of this implementation:

  • Dynamic tool loading through Composio's Tool Router
  • Conversation history maintenance for context-aware responses
  • Async Python provides clean, efficient execution of agent workflows
You can extend this further by adding error handling, implementing specific business logic, or integrating additional Composio toolkits to create multi-app workflows.
TOOLS

Supported Tools

Every Netsuite action and event your agent gets out of the box.

Get Async Job Status

Retrieves the current status of an asynchronous NetSuite REST job.

Get Async Job Task

Retrieves the task reference (task ID and URL) for an asynchronous job in NetSuite.

Async Get Job Task Result

Tool to retrieve the payload result of a completed async task.

Create Customer

Creates a new customer record in NetSuite.

Create Customer Payment

Creates a customer payment record in NetSuite.

Create Employee

Creates a new employee record in NetSuite.

Create Invoice

Tool to create a new invoice record.

Create Item

Creates a new item record in NetSuite via REST API.

Create Journal Entry

Tool to create a new journal entry record.

Create JWT Client Assertion

Tool to build a JWT client assertion for NetSuite OAuth2 client credentials.

Create Purchase Order

Tool to create a new purchase order record.

Create Record

Creates a new NetSuite record of any type (customer, vendor, invoice, sales order, etc.

Create Sales Order

Tool to create a new sales order record in NetSuite.

Create Vendor

Creates a new vendor record in NetSuite.

Create Vendor Bill

Tool to create a new vendor bill record.

Delete Customer

Tool to delete a customer record by ID.

Delete Customer Payment

Delete a customer payment record from NetSuite by its ID.

Delete Employee

Deletes an employee record from NetSuite by its internal ID.

Delete Invoice

Tool to delete an invoice record by ID.

Delete Item

Tool to delete an item record by its type and ID.

Delete Item Fulfillment

Tool to delete an Item Fulfillment record.

Delete Item Receipt

Tool to delete an item receipt record by ID.

Delete Journal Entry

Tool to delete a journal entry record by ID.

Delete Purchase Order

Tool to delete a purchase order record by ID.

Delete Sales Order

Tool to delete a sales order by internal ID.

Delete Vendor Payment

Tool to delete a vendor payment record by ID.

Execute Dataset

Tool to execute a SuiteAnalytics dataset and return paged results.

Get Customer

Tool to retrieve a customer record by internal ID.

Get Customer Payment

Tool to retrieve a customer payment record by ID.

Get Data Center URLs

Tool to discover account-specific service domains.

Get Employee

Tool to retrieve an employee record by ID.

Get Governance Limits

Retrieve NetSuite account and integration concurrency governance limits.

Get Invoice

Tool to retrieve an invoice record by internal ID.

Get Item

Tool to retrieve an item record by internal ID.

Get Item Fulfillment

Tool to retrieve an item fulfillment record by internal ID.

Get Item Receipt

Tool to retrieve an item receipt record by internal ID.

Get Journal Entry

Tool to retrieve a journal entry by internal ID.

Get Purchase Order

Retrieves complete details of a purchase order by its internal ID using the NetSuite REST API.

Get Record Metadata

Retrieves the complete metadata schema for a NetSuite record type, including all field definitions, data types, constraints, and descriptions.

Get Reference Select Field

Retrieves the complete record referenced by a select-type field on a parent record.

Get Sales Order

Tool to retrieve a sales order record by internal ID.

Get Server Time

Tool to retrieve NetSuite server time in UTC.

Get Sublist Collection

Tool to retrieve a sublist collection from a parent record.

Get Sublist Line

Tool to retrieve a specific line from a sublist of a record.

Get Subrecord

Retrieves a specific subrecord from a parent NetSuite record.

Get Vendor

Tool to get a single vendor record by internal ID.

Get Vendor Bill

Retrieve a vendor bill record by its internal ID.

Get Vendor Payment

Retrieves a single vendor payment record by its internal ID from NetSuite.

List Customer Payments

Tool to list customer payment records.

List Datasets

Tool to list SuiteAnalytics Workbook datasets.

List Employees

Tool to list employee records.

List Integrations

Tool to list integration applications.

List Invoices

Tool to list invoice records.

List Item Fulfillments

Tool to list item fulfillment records.

List Item Receipts

Tool to list item receipt records.

List Journal Entries

Tool to list journal entry records.

List Metadata Catalog

Tool to list all record types and their metadata.

List Purchase Orders

Tool to list purchase order records.

List Records

Tool to list record instances.

List Sales Orders

Tool to list sales order records.

List Vendor Payments

Tool to list vendor payment records.

OAuth2 Authorize Account Domain

Tool to construct an OAuth2 authorization URL for a NetSuite account-specific domain.

OAuth2 Authorize System Domain

Initiates the OAuth2 authorization code flow using NetSuite's system domain endpoint.

Get OAuth2 JWKS Keys

Tool to retrieve OAuth2 JWKS public keys.

OAuth2 Logout

Tool to revoke an ID token and its associated access and refresh tokens.

Revoke OAuth2 Refresh Token

Revokes a NetSuite OAuth2 refresh token and all associated access tokens, immediately invalidating them.

Exchange OAuth2 Authorization Code for Tokens

Exchange an OAuth2 authorization code for access and refresh tokens using the NetSuite token endpoint.

OAuth2 Token Client Credentials

Tool to obtain an OAuth2 access token via client credentials grant.

OAuth2 Token Refresh

Tool to refresh an OAuth2 access token.

Run SuiteQL Query

Tool to execute a SuiteQL query.

Transform Record

Transform an existing NetSuite record into another record type (e.

Update Customer

Updates an existing NetSuite customer record using PATCH semantics - only fields included in the 'data' parameter are modified.

Update Customer Payment

Tool to update an existing customer payment by ID.

Update Employee

Tool to update an employee record by ID.

Update Invoice

Updates an existing NetSuite invoice record by ID using the PATCH method.

Update Item

Tool to update an item record by ID.

Update Item Fulfillment

Tool to update an Item Fulfillment record by ID.

Update Item Receipt

Tool to update an item receipt record by ID.

Update Journal Entry

Tool to update a journal entry record by ID.

Update Purchase Order

Tool to update a purchase order record by ID.

Update Sales Order

Updates an existing NetSuite sales order record by ID using PATCH semantics.

Update Vendor

Tool to update a vendor record by ID.

Update Vendor Bill

Tool to update a vendor bill record by ID.

Update Vendor Payment

Tool to update a vendor payment record by ID.

Upsert Record by External ID

Tool to create or update a record by external ID.

FAQ

Frequently asked questions

With a standalone Netsuite MCP server, the agents and LLMs can only access a fixed set of Netsuite tools tied to that server. However, with the Composio Tool Router, agents can dynamically load tools from Netsuite and many other apps based on the task at hand, all through a single MCP endpoint.

Yes, you can. LangChain fully supports MCP integration. You get structured tool calling, message history handling, and model orchestration while Tool Router takes care of discovering and serving the right Netsuite tools.

Yes, absolutely. You can configure which Netsuite scopes and actions are allowed when connecting your account to Composio. You can also bring your own OAuth credentials or API configuration so you keep full control over what the agent can do.

All sensitive data such as tokens, keys, and configuration is fully encrypted at rest and in transit. Composio is SOC 2 Type 2 compliant and follows strict security practices so your Netsuite data and credentials are handled as safely as possible.

Start with Netsuite.It takes 30 seconds.

Managed auth, hosted MCP servers, and every Netsuite tool your agent needs.Free to start.

Start building