docs/platform/build-with-ai/agent-toolkit.mdx
The @novu/agent-toolkit package lets you expose Novu notification workflows as tools for LLM agents. It works with OpenAI, LangChain, and Vercel AI SDK.
The toolkit automatically discovers your Novu workflows and converts them into strongly-typed tools that an LLM can invoke, letting your AI agent send notifications, manage subscriber preferences, and trigger any workflow you've built in Novu.
<Note> The Agent Toolkit is a code-level SDK for embedding Novu tools inside your own AI agents. For giving AI coding assistants (Claude Code, Cursor, Copilot) context about Novu, see [Agent Skills](/platform/build-with-ai/skills). For connecting AI tools to Novu via the Model Context Protocol, see [MCP](/platform/build-with-ai/mcp). </Note>npm install @novu/agent-toolkit
Then install the peer dependency for the AI framework you use:
| Framework | Peer Dependency | Import Path |
|---|---|---|
| OpenAI | openai >= 4.0.0 | @novu/agent-toolkit/openai |
| LangChain | @langchain/core >= 0.2.0 | @novu/agent-toolkit/langchain |
| Vercel AI SDK | ai >= 6.0.0 | @novu/agent-toolkit/ai-sdk |
import { createNovuAgentToolkit } from '@novu/agent-toolkit/openai';
import OpenAI from 'openai';
const openai = new OpenAI();
const toolkit = await createNovuAgentToolkit({
secretKey: process.env.NOVU_SECRET_KEY,
subscriberId: 'user-123',
});
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Send a welcome email to user-123' }],
tools: toolkit.tools,
});
for (const toolCall of response.choices[0].message.tool_calls ?? []) {
const result = await toolkit.handleToolCall(toolCall);
console.log(result);
}
Every adapter's createNovuAgentToolkit accepts a NovuToolkitConfig object:
type NovuToolkitConfig = {
secretKey: string;
subscriberId: string;
backendUrl?: string;
workflows?: {
tags?: string[];
workflowIds?: string[];
};
};
| Option | Required | Description |
|---|---|---|
secretKey | Yes | Your Novu API secret key from dashboard.novu.co/settings/api-keys. |
subscriberId | Yes | Default subscriber ID used when triggering workflows. |
backendUrl | No | Custom Novu API URL (defaults to Novu Cloud). |
workflows.tags | No | Filter discovered workflows by tags. |
workflows.workflowIds | No | Restrict discovered workflows to specific IDs. |
Each adapter exposes a createNovuAgentToolkit function that returns tools in the native format for that framework.
const toolkit = await createNovuAgentToolkit({ secretKey: process.env.NOVU_SECRET_KEY, subscriberId: 'user-123', });
// toolkit.tools — OpenAI function tool definitions // toolkit.handleToolCall — execute a tool call and return a tool message
```typescript title="Full example"
import { createNovuAgentToolkit } from '@novu/agent-toolkit/openai';
import OpenAI from 'openai';
const openai = new OpenAI();
const toolkit = await createNovuAgentToolkit({
secretKey: process.env.NOVU_SECRET_KEY,
subscriberId: 'user-123',
});
const messages = [
{ role: 'user', content: 'Send a welcome email to user-123' },
];
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages,
tools: toolkit.tools,
});
const assistantMessage = response.choices[0].message;
messages.push(assistantMessage);
for (const toolCall of response.choices[0].message.tool_calls ?? []) {
const result = await toolkit.handleToolCall(toolCall);
messages.push(result);
}
The returned toolkit provides:
tools — Array of OpenAI-compatible function tool definitions.handleToolCall(toolCall) — Executes a tool call and returns a \{ role: 'tool', tool_call_id, content \} message ready to append to the conversation.const toolkit = await createNovuAgentToolkit({ secretKey: process.env.NOVU_SECRET_KEY, subscriberId: 'user-123', });
// toolkit.tools — DynamicStructuredTool[] ready for LangChain agents
```typescript title="Full example"
import { createNovuAgentToolkit } from '@novu/agent-toolkit/langchain';
import { ChatOpenAI } from '@langchain/openai';
import { AgentExecutor, createOpenAIFunctionsAgent } from 'langchain/agents';
const toolkit = await createNovuAgentToolkit({
secretKey: process.env.NOVU_SECRET_KEY,
subscriberId: 'user-123',
});
const llm = new ChatOpenAI({ model: 'gpt-4o' });
// Pass toolkit.tools directly to agent creation
const agent = await createOpenAIFunctionsAgent({
llm,
tools: toolkit.tools,
prompt: yourPrompt,
});
const executor = new AgentExecutor({ agent, tools: toolkit.tools });
const result = await executor.invoke({ input: 'Notify user-123 about their order' });
The returned toolkit provides:
tools — Array of DynamicStructuredTool instances that can be passed directly to LangChain agents or executors.const toolkit = await createNovuAgentToolkit({ secretKey: process.env.NOVU_SECRET_KEY, subscriberId: 'user-123', });
// toolkit.tools — ToolSet compatible with generateText / streamText
```typescript title="Full example"
import { createNovuAgentToolkit } from '@novu/agent-toolkit/ai-sdk';
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
const toolkit = await createNovuAgentToolkit({
secretKey: process.env.NOVU_SECRET_KEY,
subscriberId: 'user-123',
});
const { text } = await generateText({
model: openai('gpt-4o'),
tools: toolkit.tools,
prompt: 'Send a welcome email to user-123',
});
The returned toolkit provides:
tools — A ToolSet object that can be passed to generateText, streamText, or other Vercel AI SDK functions.The toolkit ships with two built-in tools that are always available regardless of which workflows you have configured.
trigger_workflowTriggers any Novu workflow by its identifier. Use this as a generic entry point to send notifications.
| Parameter | Type | Required | Description |
|---|---|---|---|
workflowId | string | Yes | The workflow identifier to trigger. |
payload | Record<string, unknown> | No | Data passed to the workflow for rendering notification content. |
overrides | Record<string, unknown> | No | Provider-specific configuration overrides. |
subscriberId | string | No | Target subscriber (defaults to configured subscriberId). |
transactionId | string | No | Unique key for deduplication. |
update_preferencesUpdates notification channel preferences for a subscriber, either globally or for a specific workflow.
| Parameter | Type | Required | Description |
|---|---|---|---|
workflowId | string | No | Scope to a specific workflow. Omit for global preferences. |
channels | object | No | Channel toggles: email, sms, push, inApp, chat. |
subscriberId | string | No | Target subscriber (defaults to configured subscriberId). |
On initialization the toolkit fetches your Novu workflows and creates a dedicated tool for each one. These tools are named trigger_<workflow_id> (with hyphens replaced by underscores) and include the workflow's payload schema so the LLM knows exactly what data to provide.
Filter which workflows are exposed using the workflows config option:
const toolkit = await createNovuAgentToolkit({
secretKey: process.env.NOVU_SECRET_KEY,
subscriberId: 'user-123',
workflows: {
tags: ['ai-agent'],
workflowIds: ['welcome-email', 'order-confirmation'],
},
});
For example, if you have a workflow with ID welcome-email, the toolkit generates a trigger_welcome_email tool whose parameter schema matches the workflow's payloadSchema. The LLM sees a purpose-built tool instead of a generic trigger, which improves accuracy and reduces prompt engineering.
The @novu/agent-toolkit package is part of the Novu monorepo on the next branch.
packages/agent-toolkit/
├── src/
│ ├── index.ts # Main entry point
│ ├── core/ # Core toolkit classes and types
│ │ ├── novu-toolkit.ts # NovuToolkit class (initialization, workflow discovery)
│ │ ├── novu-tool.ts # NovuTool factory function
│ │ └── types.ts # NovuToolkitConfig, NovuToolDefinition types
│ ├── tools/ # Built-in tool definitions
│ │ ├── trigger-workflow.ts
│ │ ├── preferences.ts
│ │ └── workflows-as-tools.ts # Dynamic workflow-to-tool conversion
│ ├── openai/ # OpenAI adapter
│ ├── langchain/ # LangChain adapter
│ └── ai-sdk/ # Vercel AI SDK adapter
├── package.json
├── tsconfig.json
└── tsup.config.ts
| Import Path | Description |
|---|---|
@novu/agent-toolkit | Core NovuToolkit class, NovuTool factory, and types. |
@novu/agent-toolkit/openai | OpenAI adapter with createNovuAgentToolkit. |
@novu/agent-toolkit/langchain | LangChain adapter with createNovuAgentToolkit. |
@novu/agent-toolkit/ai-sdk | Vercel AI SDK adapter with createNovuAgentToolkit. |
@novu/agent-toolkit/core | Core classes and types (for building custom adapters). |