Quickstart (JavaScript / TypeScript)
This guide gets you from zero to a working agent chat using only @kapaai/agent-core and plain JavaScript. No framework required.
Prerequisites
- An Agent integration set up in your Kapa dashboard (Integrations → Agent)
- A customer API key (from your Kapa dashboard → API Keys)
1. Install the package
- npm
- yarn
- pnpm
npm install @kapaai/agent-core
yarn add @kapaai/agent-core
pnpm add @kapaai/agent-core
2. Create a session endpoint
Same as the React quickstart. Create a server-side endpoint that proxies session creation. See Authentication for full details.
3. Build the chat
<div id="messages"></div>
<div id="streaming-indicator" style="display: none">Agent is thinking...</div>
<input id="input" type="text" placeholder="Ask a question..." />
<button id="send-btn">Send</button>
<button id="stop-btn" style="display: none">Stop</button>
<button id="new-chat-btn">New Chat</button>
import { Agent } from '@kapaai/agent-core';
const agent = new Agent({
projectId: 'your-project-id',
integrationId: 'your-integration-id',
model: 'kapa-agent-1.0',
tools: [],
context: {},
getSessionToken: async () => {
const res = await fetch('/api/session', { method: 'POST' });
if (!res.ok) throw new Error('Session failed');
return res.json();
},
onMessagesChange: (messages) => {
const container = document.getElementById('messages');
container.innerHTML = '';
for (const msg of messages) {
const el = document.createElement('div');
if (msg.role === 'user') {
el.textContent = msg.content;
el.className = 'user-message';
} else {
// Render each block (text or tool calls)
for (const block of msg.blocks) {
if (block.type === 'text' && block.content) {
const textEl = document.createElement('div');
textEl.textContent = block.content;
el.appendChild(textEl);
}
if (block.type === 'tool_calls') {
for (const tc of block.toolCalls) {
const toolEl = document.createElement('div');
toolEl.className = 'tool-card';
toolEl.textContent = `${tc.displayName || tc.name}: ${tc.status}`;
if (tc.result) {
toolEl.textContent += ` — ${JSON.stringify(tc.result)}`;
}
el.appendChild(toolEl);
}
}
}
}
container.appendChild(el);
}
container.scrollTop = container.scrollHeight;
},
onStreamingChange: (streaming) => {
document.getElementById('streaming-indicator').style.display =
streaming ? 'block' : 'none';
document.getElementById('send-btn').style.display =
streaming ? 'none' : 'block';
document.getElementById('stop-btn').style.display =
streaming ? 'block' : 'none';
},
});
// Wire up buttons
document.getElementById('send-btn').onclick = () => {
const input = document.getElementById('input');
const text = input.value.trim();
if (text) {
input.value = '';
agent.sendMessage(text);
}
};
document.getElementById('stop-btn').onclick = () => agent.stopGeneration();
document.getElementById('new-chat-btn').onclick = () => agent.resetConversation();
document.getElementById('input').onkeydown = (e) => {
if (e.key === 'Enter') document.getElementById('send-btn').click();
};
That's it. A working agent chat with plain JavaScript and DOM manipulation.
The tools array is empty, and it can stay that way. The agent already answers questions from your Kapa knowledge sources through built-in, server-side knowledge base search, and returns the source URLs it used. Custom tools are layered on top when you want the agent to take actions in your product. See Built-in tools.
Next steps
- Custom tools (Core). Add tools with execute functions and approval flow
- Building a UI. Patterns for rendering messages, tool cards, and approval buttons
- Authentication. Server-side session proxy details
For a complete runnable example with tools, markdown rendering, and approval flow, see the vanilla JS example in the examples repo.