Back to blog
·5 min read

Adding WhatsApp Tools to OpenAI Agents SDK and LangChain via MCP

Production agentic apps need to message humans. Here's how to wire WhatsApp into OpenAI Agents SDK and LangChain agents using the @gaviwhatsapp/mcp server.

openai agents sdklangchainwhatsappmcpai agents

If you're building production agentic apps in 2026, you're probably using one of these:

  • OpenAI Agents SDK — OpenAI's official Python framework for multi-agent workflows
  • LangChain / LangGraph — the most popular agent framework, supports both Python and TypeScript
  • CrewAI, AutoGen, Mastra — newer frameworks for multi-agent systems
  • Direct API integration — Anthropic API or OpenAI API with your own agent loop

All of these support MCP for tools — either natively or via adapters. That means a single MCP server like @gaviwhatsapp/mcp gives every framework the same WhatsApp toolkit, with no per-framework integration work.

This post shows the wiring for the two biggest: OpenAI Agents SDK and LangChain.

Why agents need WhatsApp

The most useful production agents do real work and close the loop with humans:

  • A customer support agent that answers WhatsApp messages, queries your DB, escalates to humans when needed
  • A lead-qualification agent that reaches out to new signups on WhatsApp, qualifies them, books a meeting
  • A monitoring agent that watches infrastructure and alerts on-call via WhatsApp
  • A fulfillment agent that texts customers at every step of an order
  • A booking agent for service businesses that confirms appointments and handles reschedules on WhatsApp

In every case, the agent's intelligence is mature; what was missing was the messaging channel. WhatsApp solves that — 3 billion users, 98% open rates within an hour.

Pattern A: OpenAI Agents SDK

The OpenAI Agents SDK has first-class MCP support. You wire up the WhatsApp MCP server once and any agent in your app can call its tools.

Setup

pip install openai-agents
npm install -g @gaviwhatsapp/mcp  # the MCP server (Node-based, runs via npx)

Define an agent with MCP tools

from agents import Agent, Runner
from agents.mcp import MCPServerStdio

# Connect to the Gavi WhatsApp MCP server
whatsapp_mcp = MCPServerStdio(
    name="gaviwhatsapp",
    params={
        "command": "npx",
        "args": ["@gaviwhatsapp/mcp", "--api-key", "gv_YOUR_KEY"],
    },
)

agent = Agent(
    name="SupportAgent",
    instructions=(
        "You are a customer support agent. When a user sends a WhatsApp, "
        "look up their order status if relevant, answer their question, "
        "and reply via the send_message tool."
    ),
    mcp_servers=[whatsapp_mcp],
)

# Run the agent on an incoming WhatsApp message
async def handle_incoming(phone: str, text: str):
    async with whatsapp_mcp:
        result = await Runner.run(
            agent,
            input=f"User {phone} said: {text}. Reply on WhatsApp.",
        )
        return result.final_output

The agent now has access to all WhatsApp tools (send_message, send_template, send_media, send_broadcast, list_templates, list_messages) automatically — you didn't define any of them in your code.

Multi-agent example

A common pattern: a router agent decides whether to hand off to a support agent (which has WhatsApp + DB access) or a sales agent (which has WhatsApp + CRM access):

sales_agent = Agent(
    name="Sales",
    instructions="You qualify leads and book demos. Reply via WhatsApp.",
    mcp_servers=[whatsapp_mcp, crm_mcp],
)

support_agent = Agent(
    name="Support",
    instructions="You resolve customer issues. Look up orders, escalate when needed.",
    mcp_servers=[whatsapp_mcp, db_mcp],
)

router = Agent(
    name="Router",
    instructions="Decide which agent should handle this message.",
    handoffs=[sales_agent, support_agent],
)

Pattern B: LangChain / LangGraph

LangChain supports MCP via the @langchain/mcp-adapters package (TypeScript) or langchain-mcp-adapters (Python). The adapter connects to an MCP server and exposes its tools as LangChain Tool objects.

TypeScript / LangGraph

npm install langchain @langchain/mcp-adapters @langchain/anthropic
import { MultiServerMCPClient } from '@langchain/mcp-adapters'
import { createReactAgent } from '@langchain/langgraph/prebuilt'
import { ChatAnthropic } from '@langchain/anthropic'

const mcpClient = new MultiServerMCPClient({
  gaviwhatsapp: {
    transport: 'stdio',
    command: 'npx',
    args: ['@gaviwhatsapp/mcp', '--api-key', 'gv_YOUR_KEY'],
  },
})

const tools = await mcpClient.getTools()

const agent = createReactAgent({
  llm: new ChatAnthropic({ model: 'claude-3-5-sonnet-latest' }),
  tools,
})

const result = await agent.invoke({
  messages: [
    { role: 'user', content: 'Send a WhatsApp to +919876543210 saying tests passed.' },
  ],
})

Python

pip install langchain langchain-mcp-adapters langchain-anthropic
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain.agents import create_agent
from langchain_anthropic import ChatAnthropic

client = MultiServerMCPClient({
    "gaviwhatsapp": {
        "transport": "stdio",
        "command": "npx",
        "args": ["@gaviwhatsapp/mcp", "--api-key", "gv_YOUR_KEY"],
    }
})

tools = await client.get_tools()
agent = create_agent(ChatAnthropic(model="claude-3-5-sonnet-latest"), tools)

result = await agent.ainvoke({
    "messages": [("user", "Send a WhatsApp to +919876543210 saying tests passed.")]
})

What tools the agent gets

ToolUse case
send_messageFree-form text within the 24-hour conversation window
send_templateMeta-approved template (cold messages, OTPs, transactional, marketing)
send_mediaImage, video, document, audio
send_broadcastTemplate send to many recipients with per-row variables
list_templatesDiscover approved templates
list_messagesRead message history with delivery status

These are exposed identically to every framework — the agent's framework-specific tool schema is auto-generated from MCP.

Production patterns worth knowing

1. Use templates for outbound

When your agent initiates a conversation (i.e. the user hasn't messaged your number in the last 24 hours), you must use a Meta-approved template. Create them in the Gavi dashboard and the agent can call send_template with the right name and variables.

2. Cap iterations

Bound the number of agent loops per user turn (typically 5-10) to prevent runaways and limit cost.

3. Memory

Store conversation history per phone number in Postgres / Redis. On each new inbound message, prepend the last N turns to the agent's input.

4. Webhook signature verification

Verify incoming WhatsApp webhook signatures before invoking your agent — this prevents abuse:

import { verifyWebhookSignature } from '@gaviwhatsapp/whatsapp'

if (!verifyWebhookSignature(body, signature, process.env.WEBHOOK_SECRET)) {
  return new Response('Invalid signature', { status: 401 })
}

5. Tool result handling

Some MCP tool calls return data the agent will use in subsequent steps (e.g. list_messages then send_message). Make sure your framework's MCP adapter feeds tool results back into the agent's context — both OpenAI Agents SDK and LangChain handle this automatically.

Other patterns we cover

Pricing

$9.99/mo flat from Gavi. No per-tool-call fee, no per-conversation fee, no markup on Meta's per-message charges (which go directly to your WhatsApp Business Account).


Try it: gaviventures.com · GitHub · npm

Ready to try Gavi WhatsApp?

Send WhatsApp messages from your code, AI agent, or CRM in under 5 minutes.