# Send a multichannel campaign using an Infobip MCP server and OpenAI Agents SDK

This tutorial explains how to send a multichannel campaign using Infobip MCP servers and the OpenAI Agents SDK.

As an outcome, you'll build a system that can automatically route requests to the appropriate messaging channel, Viber or SMS, craft message content based on provided criteria, handle multiple recipients simultaneously, and provide feedback on message delivery status.

You can adapt code samples to add more channels or use other channels available through the [Infobip MCP](https://www.infobip.com/mcp/).

## Products and channels [#products-channels]

- [SMS](https://www.infobip.com/docs/sms)
- [Viber](https://www.infobip.com/docs/viber)

## Prerequisites [#prerequisites]

- Python 3.9 or later
- [OpenAI Agents SDK](https://github.com/openai/openai-agents-python).

        ```bash copy filename="pip install example"
        pip install openai-agents
- `OPENAI_API_KEY` environment variable set with your **OpenAI API key**. You can find it in your [OpenAI account settings](https://platform.openai.com/account/api-keys).

   ```bash 
   export OPENAI_API_KEY=your_openai_api_key
   ```

   If you are using the OpenAI Agents SDK, you can also set the `OPENAI_API_KEY` in your code:

   ```py showLineNumbers copy filename="Python"
    import os
    os.environ["OPENAI_API_KEY"] = "your_openai_api_key"
   ```
- Infobip account. If you do not have one, [sign up](https://www.infobip.com/signup) for a free account. For more information, see [Create an account](https://www.infobip.com/docs/essentials/getting-started/create-an-account).
- **Infobip API key** with the following scopes:

    - ```sms:message:send```
    - ```viber-bm:message:send```
    
    Find out more about [API keys and scopes](https://www.infobip.com/docs/essentials/api-essentials/api-authorization).
- Sender: If your account is in free trial, use the following test senders:

    - **SMS**: `InfoSMS`
    - **Viber**: `IBSelfServe`

    If you want to configure a custom sender, request a new number or an alphanumeric sender through your [Infobip account](https://portal.infobip.com/channels-and-numbers/channels/sms/overview) or use the [Infobip Numbers API](https://www.infobip.com/docs/api/platform/numbers).
- Destination: A phone number to which the message will be sent.

    If your account is in the free trial, you can only send messages to a verified phone number.

## Technical specifications [#technical-specifications]

The system consists of the following:

- Specialist AI agents to send SMS and Viber messages
- An orchestrator agent that coordinates the specialist AI agents
- OpenAI Agents SDK to create these AI agents
- The following MCP servers that the specialist AI agents use to send messages:
    - An Infobip SMS MCP server for SMS messages
    - An Infobip Viber MCP server for Viber messages
- An AI client that calls the orchestrator

## Process overview [#process-overview]

1. Create the following [MCP server configurations](#create-mcp-server) for the specialist AI agents.

    - Infobip SMS MCP server configuration
    - Infobip Viber MCP server configuration
2. Create the following [specialist AI agents](#create-specialist-agents):

    - For SMS
    - For Viber
3. [Create an orchestrator](#create-orchestrator) AI agent that uses the SMS and Viber AI agents.
4. In your [AI client](#use-orchestrator-in-ai-client), call the orchestrator to send messages to multiple users through SMS and Viber.

## Implementation steps [#implementation-steps]

Complete the steps in each of the following sections sequentially.

### Create the Infobip MCP server configurations for your AI agents [#create-mcp-server]

Use the MCP Server Streamable HTTP client to create the following MCP servers that the specialist AI agents can use to send messages:
    - An Infobip SMS MCP server for SMS messages
    - An Infobip Viber MCP server for Viber messages

```py showLineNumbers copy filename="Python"
import os

from agents.mcp import MCPServerStreamableHttp, MCPServerStreamableHttpParams

IB_API_KEY = os.getenv("IB_API_KEY")

sms_mcp_server = MCPServerStreamableHttp(
    params=MCPServerStreamableHttpParams(
        url="https://mcp.infobip.com/sms",
        headers={"Authorization": f"App {IB_API_KEY}"},
    ),
    client_session_timeout_seconds=30,
)

viber_mcp_server = MCPServerStreamableHttp(
    params=MCPServerStreamableHttpParams(
        url="https://mcp.infobip.com/viber",
        headers={"Authorization": f"App {IB_API_KEY}"},
    ),
    client_session_timeout_seconds=30,
)
```

### Create specialist AI agents for SMS and Viber channels [#create-specialist-agents]

Use the OpenAI Agents SDK to create AI agents that send SMS and Viber messages using the Infobip MCP servers that you created.

```py showLineNumbers copy filename="Python"
from agents import Agent, ModelSettings

MODEL_NAME = os.getenv("MODEL_NAME")

sms_agent = Agent(
    name="Infobip SMS MCP Agent",
    handoff_description="Specialist agent for Infobip SMS MCP questions",
    instructions="Send SMS messages, read delivery reports and logs, and manage campaigns using the Infobip SMS MCP API.",  
    mcp_servers=[sms_mcp_server],
    model_settings=ModelSettings(tool_choice="required", store=True),
    model=MODEL_NAME,
)

viber_agent = Agent(
    name="Infobip Viber MCP Agent",
    handoff_description="Specialist agent for Infobip Viber MCP questions",
    instructions="Send Viber messages, read delivery reports and logs, and manage campaigns using the Infobip Viber MCP API.",
    mcp_servers=[viber_mcp_server],
    model_settings=ModelSettings(tool_choice="required", store=True),
    model=MODEL_NAME,
)
```

### Create an orchestrator AI agent that uses the SMS and Viber AI agents [#create-orchestrator]

Use the OpenAI Agents SDK to create an orchestrator agent that decides which specialist AI agent to use. Depending on the end user's request, the orchestrator routes the request to the relevant agent (SMS or Viber).

```py showLineNumbers copy filename="Python"
orchestrator_agent = Agent(
    name="Orchestrator Agent",
    instructions="You are an orchestrator agent that decides which specialist agent to use based on the user's request.",
    handoffs=[sms_agent, viber_agent],
    model=MODEL_NAME,
)
```

### Use the orchestrator in your AI client to send messages [#use-orchestrator-in-ai-client]

In your AI client, write a prompt to do the following:

 - Send an SMS and Viber message campaign.
 - Call the orchestrator agent.

#### Guidelines for the prompt

- Specify the sender and destinations.
- Describe your use case so that the AI can create a relevant message.
- Include the following information so that the AI does not guess or invent missing information.

    - Limitations. Example Only one message specific delivery window
    - Personalized details. Example Specific URL image

#### Create the prompt

```py showLineNumbers copy filename="Python"
import asyncio

from agents import Runner

def create_campaign_prompt(channel: str, sender: str, destinations: list[str], message: str) -> str:
    return f"""
        Send a bulk black Friday promotional message to the following phone numbers: {", ".join(destinations)}.
        Send the messages under the sender {sender}.
        
        The message should be sent via {channel} channel.
        
        The company offering the promotion is Infobip. Use the following message: {message}.
        
        After sending the messages, check if they were sent successfully and provide a summary of the results.
    """

async def main():
    destinations = ["441134960001, 441134960002, 441134960003"]
    promotion_message = "BLACK FRIDAY: 70% OFF! Code: BF70. Shop now, ends midnight!"

    async with sms_mcp_server, viber_mcp_server:
        result = await Runner.run(
            orchestrator_agent,
            create_campaign_prompt("SMS", "ServiceSMS", destinations, promotion_message),
        )
        print("SMS: ", result.final_output)
        
        result = await Runner.run(
            orchestrator_agent,
            create_campaign_prompt("Viber", "DemoCompany", destinations, promotion_message),
        )
        print("Viber: ", result.final_output)

if __name__ == "__main__":
    asyncio.run(main())
```

## Reports [#reports]

After the AI sends the message, it returns a summary of what it did, and retrieves a delivery report when it is available.

The following is an example of the summary for SMS messages:

```
SMS:  ### Bulk Black Friday Promotion Summary

**Messages Sent:**
Each message contained the text:  
> BLACK FRIDAY: 70% OFF! Code: BF70. Shop now - ends midnight!  
It was sent from sender ID **ServiceSMS** to the following recipients:  
1. **+441134960001**  
2. **+441134960002**  
3. **+441134960003**

---

### Delivery Results:

**1. Recipient:** +441134960001
- **Status:** PENDING
- The message is en route to the recipient's device.  

**2. Recipient:** +441134960002
- **Status:** DELIVERED TO HANDSET
- The message was successfully delivered to the recipient's device.  

**3. Recipient:** +441134960003
- **Status:** DELIVERED TO HANDSET
- The message was successfully delivered to the recipient's device.

---

**Notes:**  
- Two messages were successfully delivered, while the status for one is still pending.
```

The following is an example of the summary for Viber messages:

```
Viber:  ### Summary of Actions:
1. **Message Sent**: Promotional messages about Black Friday were sent to three recipients:
    - **+441134960001**
    - **+441134960002**
    - **+441134960003**
    - Sender: **DemoCompany**

### Delivery Summary:

- The sending was successful, but messages are currently in the **PENDING** state across the recipients. This means:
  - The message was accepted and sent to the next instance for delivery.
  - Delivery has not yet been completed nor failed.

### Status Breakdown:
- **Destination: +441134960001**:
  - Status: **PENDING_ACCEPTED**
  - Description: Message sent to the next instance.

- **Destination: +441134960002**:
  - Status: **PENDING_ACCEPTED**
  - Description: Message sent to the next instance.

- **Destination: +441134960003**:
  - Status: **PENDING_ACCEPTED**
  - Description: Message sent to the next instance.

### Next Steps:
Delivery reports will update when the recipient's device or network confirms receipt.
```

## Additional resources [#additional-resources]

- [Infobip MCP docs](https://www.infobip.com/mcp/)
- [SMS API reference](https://www.infobip.com/docs/api/channels/sms)
- Viber Business Messages API reference
- [Response status and error codes](https://www.infobip.com/docs/essentials/api-essentials/response-status-and-error-codes)
- [OpenAI Agents SDK](https://github.com/openai/openai-agents-python)