How to Build an AI Chatbot in JavaScript
A JavaScript AI chatbot needs a model API call, a conversation history that grows with each turn, and controlled access to any tools you give it. Here is how to build each part in Node.js.
Updated 4 min read
A JavaScript AI chatbot is a Node.js program that calls a model API, keeps a record of the conversation so each turn has context, and optionally calls tools when the model requests them. The core loop is short. What separates a useful chatbot from a brittle one is how it manages state, handles errors, and controls what the model can do. A tool like fenbs can supply project-level rules and progress to a chatbot that connects over MCP, so the assistant starts each session already knowing the context.
What you need before writing the first line
You need a Node.js environment (version 20 or later works well), an API key for the model provider you choose (OpenAI, Anthropic, and others all expose a chat completions-style endpoint), and a basic understanding of how a messages array works. Every call to a chat completions API sends the full conversation history, not just the latest message. The model uses that history to generate a response in context.
The conversation loop
The messages array starts with a system message that sets the assistant's role and any standing rules. Each user turn appends a { role: "user", content: "..." } object. Each model response appends a { role: "assistant", content: "..." } object. The next call sends the full updated array.
import OpenAI from 'openai';
import * as readline from 'readline/promises';
const client = new OpenAI(); // reads OPENAI_API_KEY from env
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
const messages = [{ role: 'system', content: 'You are a helpful assistant.' }];
while (true) {
const input = await rl.question('You: ');
if (!input.trim()) continue;
messages.push({ role: 'user', content: input });
const response = await client.chat.completions.create({
model: 'gpt-4o-mini',
messages,
});
const reply = response.choices[0].message.content;
messages.push({ role: 'assistant', content: reply });
console.log('Assistant:', reply);
}This is a single-session chatbot. The history grows until the program exits. If you want history to persist across restarts, serialize the messages array to a file or database and load it at startup.
Adding tool calls
Tool calls let the model request an action your code performs. You define a tool with a name, a description, and a JSON schema for its parameters. The model decides when to call it. Your code runs the function, appends the result, and calls the API again.
Keep tool definitions narrow. A tool that can read a file is safer than a tool that can read any path on disk. A tool that can look up a customer record is safer than a tool that can modify it. Never give the model write access to something it does not need to write to complete its task.
Handling errors and edge cases
Model API calls can fail with rate-limit errors, network timeouts, or unexpected response shapes. Wrap each API call in a try-catch. For rate limits, a simple exponential backoff loop is usually enough for a development chatbot. In production, use a queue or a dedicated rate-limit library.
- Cap the messages array length to stay within the model's context window: truncate the oldest non-system messages when the count gets large.
- Validate tool call arguments before executing the function, even if the model generated them.
- Log tool calls and results during development so you can see exactly what the model requested.
- Return a clear error string from a failed tool call rather than throwing, so the model can report the failure to the user.
Testing your chatbot before connecting it to a frontend
Before wiring a JavaScript chatbot into a web interface or external service, test the conversation loop directly in Node.js. Run it interactively and step through a series of messages that cover the scenarios you care about: a normal question, an empty input, a message that triggers a tool call, and a very long message that approaches the context window limit. A chatbot that works on the happy path may fail silently on edge cases you will not notice until a user finds them.
Write unit tests for each tool function. The model can return arguments in formats you did not anticipate. A tool function that validates its inputs and returns a clear error string on bad arguments is easier to debug than one that throws or silently produces a wrong result. Test tool functions in isolation with mock arguments before connecting them to the API call loop.
Adding persistent project context with an MCP client
MCP (Model Context Protocol) is a standard way for an AI app to call an outside tool at runtime. If you add an MCP client to your JavaScript chatbot, it can connect to fenbs and read project rules, current tasks, and progress at the start of a session. The model then works with that context in memory.
Building an MCP client is a separate step beyond this article. The how-to-build-an-ai-agent guide covers tool integration in more depth. For language-specific builds in Java and PHP, the same conversation loop pattern applies with different HTTP client libraries.
Give your chatbot shared project context
If you are building a chatbot for a project your team works on, connect a supported AI tool to fenbs and let it read the project context before each session. Decisions and rules appear first, so the assistant knows the constraints without you restating them. Save progress before each session ends so the next run continues from Where we left off.
Create a free accountFree for one person · No credit card · Works with Claude, ChatGPT, Cursor and more
How to do this with fenbs
- Create a free account and add a project for the product you are building.
- Add the decisions that govern the chatbot's behavior as Decisions and rules: which tools it may call, what it must not do, the tone rules.
- Add tasks for each feature or conversation flow you are building. Note the current status and what was checked last.
- Connect a supported AI tool from Integrations. At the start of the session it reads the rules and current tasks.
- When you finish a session, ask the assistant to save its progress on each task so the next run knows where to start.
fenbs does not host or run your chatbot. It is the shared record that tells any connected AI tool what the project is, what has been decided, and where things stand.