Connect AI agents and workflows to external APIs. Nango functions become callable tools — auth and execution are handled for you.
Nango makes it straightforward to give AI agents real-world capabilities. Your integration functions become tools that any LLM or agent framework can call, while Nango handles authentication, execution, retries, and observability.
Your users connect their accounts via Nango’s auth flow. Nango stores and refreshes credentials automatically.
2
Expose tools
Each Nango Action becomes a callable tool. You can use prebuilt templates or write your own — they run in Nango’s sandboxed runtime.
3
Call tools
Your agent invokes Nango-hosted Actions via nango.triggerAction() or through Nango’s MCP server. Nango authenticates each request and returns the result.
4
Observe and optimize
Every tool call is logged in Nango’s observability dashboard. Monitor performance, inspect errors, and track usage per connection.
Works with OpenAI Agents SDK, Anthropic SDK, Vercel AI SDK, LangChain, LlamaIndex, Mastra, Google SDK, and any framework that supports tool calling.
Managed auth
Nango handles OAuth, API keys, and token refresh. Surface connect links directly in your chat UI for user-driven authorization.
800+ prebuilt tools
Use prebuilt action templates for common tools across 700+ APIs, or write your own custom Actions for full control.
MCP-compatible
Expose all your integrations through Nango’s built-in MCP server. Also supports connecting to existing official MCP servers (Notion, Linear, etc.) with Nango’s auth.
The following example checks whether a user has authorized HubSpot, prompts them to connect if not, then lets the OpenAI model call the who_am_i tool via Nango:
import OpenAI from "openai";import { Nango } from "@nangohq/node";export async function runOpenAIAgent() { const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY! }); const nango = new Nango({ secretKey: process.env.NANGO_SECRET_KEY! }); const userId = "user1"; const integrationId = "hubspot"; // Step 1: Ensure the user is authorized const connections = await nango.listConnections({ integrationId, tags: { end_user_id: userId } }); let connectionId = connections.connections[0]?.connection_id; // Step 2: If not authorized, redirect to the auth flow if (!connectionId) { const session = await nango.createConnectSession({ allowed_integrations: [integrationId], tags: { end_user_id: userId } }); console.log(`Authorize at: ${session.data.connect_link}`); const connection = await nango.waitForConnection(integrationId, userId); connectionId = connection!.connection_id; } // Step 3: Send a prompt with tool definitions const response = await client.responses.create({ model: "gpt-5", input: "Using the who_am_i tool, provide the current user info.", tools: [ { type: "function", name: "who_am_i", description: "Get the current user info.", parameters: { type: "object", properties: {}, additionalProperties: false }, strict: true } ] }); const functionCall = response.output.find( (item) => item.type === "function_call" ) as any; if (functionCall?.name === "who_am_i") { // Step 4: Execute the tool via Nango const userInfo = await nango.triggerAction(integrationId, connectionId, "whoami"); console.log("HubSpot user info:", userInfo); }}
Let agents introspect available tools and their schemas automatically by calling the scripts config endpoint. Your model can then decide which tool to call without manual configuration.
Install the dependencies:
npm i @anthropic-ai/sdk @nangohq/node
The following example checks whether a user has authorized HubSpot, prompts them to connect if not, then lets Claude call the who_am_i tool via Nango:
import Anthropic from "@anthropic-ai/sdk";import { Nango } from "@nangohq/node";export async function runAnthropicAgent() { const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY! }); const nango = new Nango({ secretKey: process.env.NANGO_SECRET_KEY! }); const userId = "user1"; const integrationId = "hubspot"; // Step 1: Ensure the user is authorized const connections = await nango.listConnections({ integrationId, tags: { end_user_id: userId } }); let connectionId = connections.connections[0]?.connection_id; // Step 2: If not authorized, redirect to the auth flow if (!connectionId) { const session = await nango.createConnectSession({ allowed_integrations: [integrationId], tags: { end_user_id: userId } }); console.log(`Authorize at: ${session.data.connect_link}`); const connection = await nango.waitForConnection(integrationId, userId); connectionId = connection!.connection_id; } // Step 3: Send a prompt with tool definitions const message = await client.messages.create({ model: "claude-sonnet-4-5", max_tokens: 1024, messages: [ { role: "user", content: "Using the who_am_i tool, provide the current user info." } ], tools: [ { name: "who_am_i", description: "Get the current user info.", input_schema: { type: "object", properties: {}, required: [] } } ], tool_choice: { type: "auto" } }); const toolUse = message.content.find((c) => c.type === "tool_use"); if (toolUse && toolUse.type === "tool_use" && toolUse.name === "who_am_i") { // Step 4: Execute the tool via Nango const userInfo = await nango.triggerAction(integrationId, connectionId, "whoami"); console.log("HubSpot user info:", userInfo); }}
Let agents introspect available tools and their schemas automatically by calling the scripts config endpoint. Your model can then decide which tool to call without manual configuration.
Install the dependencies:
npm i ai @nangohq/node
Define a Nango-backed tool and pass it to the Vercel AI SDK’s generateText or streamText:
import { generateText, tool } from "ai";import { openai } from "@ai-sdk/openai";import { Nango } from "@nangohq/node";import { z } from "zod";const nango = new Nango({ secretKey: process.env.NANGO_SECRET_KEY! });const result = await generateText({ model: openai("gpt-4o"), prompt: "Get the current HubSpot user info.", tools: { who_am_i: tool({ description: "Get the current user info from HubSpot.", parameters: z.object({}), execute: async () => { return await nango.triggerAction("hubspot", "conn-user1", "whoami"); } }) }});console.log(result.text);
Install the dependencies:
npm i langchain @langchain/openai @nangohq/node
Wrap a Nango action as a LangChain DynamicTool:
import { ChatOpenAI } from "@langchain/openai";import { DynamicTool } from "langchain/tools";import { AgentExecutor, createOpenAIToolsAgent } from "langchain/agents";import { ChatPromptTemplate } from "@langchain/core/prompts";import { Nango } from "@nangohq/node";const nango = new Nango({ secretKey: process.env.NANGO_SECRET_KEY! });const whoAmITool = new DynamicTool({ name: "who_am_i", description: "Get the current user info from HubSpot.", func: async () => { const result = await nango.triggerAction("hubspot", "conn-user1", "whoami"); return JSON.stringify(result); }});const model = new ChatOpenAI({ model: "gpt-4o" });const prompt = ChatPromptTemplate.fromMessages([ ["system", "You are a helpful assistant."], ["human", "{input}"], ["placeholder", "{agent_scratchpad}"]]);const agent = await createOpenAIToolsAgent({ llm: model, tools: [whoAmITool], prompt });const executor = new AgentExecutor({ agent, tools: [whoAmITool] });const result = await executor.invoke({ input: "Who is the current HubSpot user?" });console.log(result.output);
Nango has a built-in MCP (Model Context Protocol) server that exposes all your integrations as MCP tools. Any MCP-compatible client — Claude Desktop, Cursor, or a custom agent — can connect to it.With the Nango MCP server you can:
Expose any Nango Action as an MCP tool automatically.
Connect to existing official MCP servers (Notion, Linear, etc.) using Nango’s managed auth.
Let users authorize APIs directly through your MCP-connected interface.
See the MCP server implementation guide for setup instructions, including how to generate a server URL scoped to a specific connection.
Nango manages all credential storage and refresh. For user-facing agents, you can embed an auth flow directly in your chat UI:
import { Nango } from "@nangohq/node";const nango = new Nango({ secretKey: process.env.NANGO_SECRET_KEY! });// Create a short-lived connect link for a specific userconst session = await nango.createConnectSession({ allowed_integrations: ["hubspot", "salesforce"], tags: { end_user_id: "user-123" }});// Send session.data.connect_link to your frontend// The user completes auth in the Connect UI// Then resume agent execution once connection is establishedconst connection = await nango.waitForConnection("hubspot", "user-123");
Once a connection exists, every triggerAction call uses that connection’s credentials automatically — no token management in your agent code.