npm package: @makeyouragent/sdk
Description: Official Node.js SDK for Make Your Agent (MYA) — build AI-powered agents with knowledge bases, tool execution, and a drop-in chat widget
Author: FireInBelly
Latest version: 0.2.1

# @makeyouragent/sdk

Official Node.js SDK for [Make Your Agent](https://makeyouragent.ai) — build AI-powered agents with knowledge bases, tool execution, and a drop-in chat widget.

## Install

```bash
npm install @makeyouragent/sdk
```

## Quick Start

### 1. Set up the server proxy (your backend)

The SDK proxies browser requests through your backend so the API key stays secret.

```js
import { createProxyHandler } from '@makeyouragent/sdk/server';

const handler = createProxyHandler({
  apiKey: 'mya_live_...',   // your secret API key
  pathPrefix: '/mya',       // strip this prefix before forwarding
});

// Express
app.all('/mya/*', (req, res) => handler(req, res));

// Fastify
fastify.all('/mya/*', (req, reply) => handler(req, reply));

// Hono / Cloudflare Workers
app.all('/mya/*', (c) => handler(c.req.raw));

// Raw Node.js
http.createServer(handler).listen(3000);
```

### 2. Add the chat widget (your frontend)

One line to embed a fully functional chat UI:

```html
<div id="chat" style="width: 400px; height: 600px;"></div>
<script type="module">
  import { MakeYourAgentWidget } from '@makeyouragent/sdk/client';

  MakeYourAgentWidget.init({
    baseUrl: '/mya',
    agentId: 'your-agent-id',
    container: '#chat',
  });
</script>
```

That's it. Your users can now chat with your AI agent.

## Architecture

```
Browser (Widget or custom UI)
  |-- fetch('/mya/...') --> Your backend (proxy handler injects API key)
                              |-- --> api.makeyouragent.ai (service-mya)
```

The API key never leaves your server. The browser talks to your backend, which proxies to MYA.

## Server Module

For backend operations — managing agents, knowledge bases, and direct API calls.

```js
import { MakeYourAgentServer } from '@makeyouragent/sdk/server';

const mya = new MakeYourAgentServer({
  apiKey: 'mya_live_...',
});

// Create an agent
const agent = await mya.agents.create({
  name: 'Support Bot',
  systemPrompt: 'You are a helpful support agent.',
});

// Chat (non-streaming)
const response = await mya.chat.send(agent.id, {
  message: 'What can you help me with?',
});

// Chat (streaming)
const stream = mya.chat.stream(agent.id, { message: 'Hello' });
for await (const chunk of stream) {
  process.stdout.write(chunk.delta);
}

// Knowledge bases
const kb = await mya.knowledgeBases.create(agent.id, {
  name: 'Product Docs',
  sourceType: 'MARKDOWN',
});
await mya.knowledgeBases.import(agent.id, kb.id, {
  content: '# Getting Started\n\nWelcome to our product...',
  title: 'Getting Started Guide',
});

// File uploads
await mya.files.upload(agent.id, pdfBuffer, { filename: 'manual.pdf' });

// Raw request (for endpoints not covered by resource classes)
const response = await mya.request('/api/agents/agent-id/conversations/conv-id', {
  method: 'GET',
});
const data = await response.json();
```

## Client Module

For browser-side usage — either the headless client or the drop-in widget.

### Headless Client (custom UI)

```js
import { MakeYourAgentClient } from '@makeyouragent/sdk/client';

const client = new MakeYourAgentClient({ baseUrl: '/mya' });

// List agents
const agents = await client.agents.list();

// Chat with inline file upload (SDK handles upload automatically)
const stream = client.chat.stream('agent-id', {
  message: 'Summarize this document',
  files: [fileBlob],
});

for await (const chunk of stream) {
  updateUI(chunk.delta);
}
```

### Widget (drop-in UI)

```js
import { MakeYourAgentWidget } from '@makeyouragent/sdk/client';

// Embedded mode (fills container)
MakeYourAgentWidget.init({
  baseUrl: '/mya',
  agentId: 'agent-id',
  container: '#chat',
  mode: 'embedded',
});

// Floating mode (chat bubble in corner)
MakeYourAgentWidget.init({
  baseUrl: '/mya',
  agentId: 'agent-id',
  container: 'body',
  mode: 'floating',
  theme: {
    primaryColor: '#6366f1',
    position: 'bottom-right',
  },
});
```

#### Widget Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `baseUrl` | `string` | -- | URL to your proxy endpoint (required) |
| `agentId` | `string` | -- | Agent ID to chat with (required) |
| `container` | `string \| HTMLElement` | -- | CSS selector or DOM element (required) |
| `mode` | `'embedded' \| 'floating' \| 'fullscreen'` | `'embedded'` | Display mode |
| `theme.primaryColor` | `string` | `'#6366f1'` | Primary brand color |
| `theme.fontFamily` | `string` | System font stack | Font family |
| `theme.borderRadius` | `string` | `'12px'` | Border radius |
| `theme.position` | `'bottom-right' \| 'bottom-left'` | `'bottom-right'` | Floating bubble position |
| `labels.placeholder` | `string` | `'Type a message...'` | Input placeholder text |
| `labels.title` | `string` | `'Chat'` | Header title |
| `allowFileUpload` | `boolean` | `true` | Show file upload button |
| `allowImageUpload` | `boolean` | `true` | Show image upload button |
| `onMessage` | `(msg: ChatResponse) => void` | -- | Callback after each response |

## Streaming

Both server and client modules support streaming with two patterns:

```js
// Async iterator
const stream = mya.chat.stream(agentId, { message: 'Hello' });
for await (const chunk of stream) {
  console.log(chunk.delta);
}
const finalResponse = await stream.finalResponse();

// Callbacks
mya.chat.stream(agentId, { message: 'Hello' }, {
  onChunk: (chunk) => console.log(chunk.delta),
  onDone: (response) => console.log('Done:', response),
  onError: (err) => console.error(err),
});
```

## Configuration

### MakeYourAgentServer

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `apiKey` | `string` | -- | Your MYA API key (required) |
| `baseUrl` | `string` | `'https://api.makeyouragent.ai'` | API base URL |
| `timeout` | `number` | `30000` | Request timeout in ms |
| `maxRetries` | `number` | `3` | Max retries on 5xx errors |

### createProxyHandler

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `apiKey` | `string` | -- | Your MYA API key (required) |
| `baseUrl` | `string` | `'https://api.makeyouragent.ai'` | API base URL |
| `pathPrefix` | `string` | `''` | Path prefix to strip before forwarding |

### MakeYourAgentClient

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `baseUrl` | `string` | -- | URL to your proxy endpoint (required) |

## Important: Tool Callback Timing

If your agent uses OpenAPI tools that call back to your server (e.g. to fetch user data), MYA executes these callbacks **during** the `chat.send()` call — not after it returns.

This means any auth context your callback endpoint needs must be set up **before** calling `chat.send()`:

```js
// CORRECT: store session before the chat call
await storeSession(userId, authToken);
const response = await mya.chat.send(agentId, { message });

// WRONG: storing after — tool callbacks will fail with 401
const response = await mya.chat.send(agentId, { message });
await storeSession(userId, authToken); // too late!
```

## Requirements

- Node.js 18+ (uses native `fetch`)
- Zero runtime dependencies