AI Providers for 3CX Programmable Extensions
Introduction
3CX Programmable Extensions let developers create AI agents that handle live calls through the 3CX Phone System.
3CX Agentic Call Control is a set of ready-made code examples for building those AI agents. Each example connects a Programmable Extension to a realtime AI provider such as OpenAI, xAI, Gemini or Qwen, and makes the relevant 3CX call-control functions available to the agent.
This guide shows how to choose OpenAI, xAI, Gemini or Qwen, configure the matching example with your 3CX and provider credentials, start it, and make a test call.
Before You Start
Download and extract the 3CX Agentic Call Control source code. All four examples are included in the same package.
Choose OpenAI, xAI, Google Gemini or Alibaba Cloud Qwen, then use the example folder and configuration values for that provider.
- A 3CX administrator with access to Admin > Integrations > API who can create a Service Principal.
- Node.js 20+ installed. Yarn 4 is bundled with the repository.
- An API key with access to the realtime service for the AI provider you choose.
- A working 3CX extension, such as the Web Client, mobile app or desk phone, to place a test call to the AI agent.
Get the Examples
After downloading the 3CX Agentic Call Control source code, go to the main folder; this contains package.json, examples and packages.
In the examples folder you will find the relevant provider specific agentic call control code:
- examples/openai-realtime
- examples/xai-realtime
- examples/gemini-realtime
- examples/alibaba-qwen-realtime
Inside every one of the example folders you’ll find and have to copy config.yaml.example and rename the copy to config.yaml. Keep config.yaml.example unchanged so you can return to the original example settings if needed.
The config.yaml file contains the PBX connection and provider settings that allow the programmable extension code to work.
Create a 3CX Service Principal
In the PBX, open Admin > Integrations > API and select Add a Service Principal.
- Enter a Client ID e.g: “assistant”.
- Enable "Enable access to the 3CX Call Control API for this application".
- If you want system-wide contact search & presence checking capabilities for the agent, you’ll also need to enable: “Enable access to the 3CX Configuration API (XAPI) for this application. Set department & role according to what you want the agent’s capabilities to be.
- Save the 3CX API key in a secure location.
Choose a Provider and Configure config.yaml
OpenAI
- In config.yaml, enter:
- appId: Client ID from the PBX Integrations > API > Client ID
- appSecret: Service Principal PBX API key from Integrations > API > Generate API Key
- pbxBase: PBX address
- openaiApiKey: OpenAI API key from OpenAI API Keys
Install the dependencies and start the OpenAI example:
yarn install
yarn start:openai
A successful OpenAI startup log includes:
openai-realtime starting
3CX PBX: https://your-pbx.3cx.eu:5001
OpenAI model: <configured model>
OpenAI voice: <configured voice>
Agent profile: receptionist (role: receptionist)
SDK connected (auth + WebSocket + state)
[MCP] connected to https://your-pbx.3cx.eu:5001/mcp
MCP tools (1/8):
✗ list_peers: List internal numbers of any type (extensions, queues, ring groups, IVRs, etc.). Supports filtering by name, number, or type.
✗ get_server_time: Get the current server time in UTC and local timezone.
✗ get_edit_url: Get a clickable link to open a DN (extension, queue, ring group, IVR, trunk, etc.) in the management UI editor.
✗ find_extension: Find a contact by exact extension number
✗ control_participant: Control an active call participant: drop, answer, divert, routeto, or transferto.
✗ find_by_email: Find a contact by email address
✗ list_crm_contacts: Search for contacts in CRM (Customer Relationship Management) system
✓ list_phonebook: Search for contacts in the phonebook by name, number, email, or company
[CallStore] initialized (OpenAI Realtime mode)
All systems ready (OpenAI Realtime mode)
xAI
- In config.yaml, enter:
- appId: Client ID from the PBX Integrations > API > Client ID
- appSecret: Service Principal PBX API key from Integrations > API > Generate API Key
- pbxBase: PBX address
- xaiApiKey: xAI API key from console.x.ai
Install the dependencies and start the xAI example:
yarn install
yarn start:xai
A successful xAI startup log includes:
xai-realtime starting
3CX PBX: https://your-pbx.3cx.eu:5001
Agent profile: receptionist (role: receptionist)
xAI Voice: tara
SDK connected (auth + WebSocket + state)
[MCP] connected to https://your-pbx.3cx.eu:5001/mcp
MCP tools (1/8):
✓ list_phonebook: Search for contacts in the phonebook by name, number, email, or company
✗ control_participant: Control an active call participant: drop, answer, divert, routeto, or transferto.
✗ list_peers: List internal numbers of any type (extensions, queues, ring groups, IVRs, etc.). Supports filtering by name, number, or type.
✗ get_server_time: Get the current server time in UTC and local timezone.
✗ find_by_email: Find a contact by email address
✗ list_crm_contacts: Search for contacts in CRM (Customer Relationship Management) system
✗ get_edit_url: Get a clickable link to open a DN (extension, queue, ring group, IVR, trunk, etc.) in the management UI editor.
✗ find_extension: Find a contact by exact extension number
[CallStore] initialized (xAI realtime mode)
All systems ready (xAI realtime mode)
Gemini
- In config.yaml, enter:
- appId: Client ID from the PBX Integrations > API > Client ID
- appSecret: Service Principal PBX API key from Integrations > API > Generate API Key
- pbxBase: PBX address
- geminiApiKey: Google AI Studio API key from Google AI Studio
Install the dependencies and start the Gemini example:
yarn install
yarn start:gemini
A successful Gemini startup log includes:
agentic-call-control starting
3CX PBX: https://your-pbx.3cx.eu:5001
Gemini Voice: Kore
Agent profile: receptionist (role: receptionist)
SDK connected (auth + WebSocket + state)
[MCP] connected to https://your-pbx.3cx.eu:5001/mcp
MCP tools (1/8):
✓ list_phonebook: Search for contacts in the phonebook by name, number, email, or company
✗ control_participant: Control an active call participant: drop, answer, divert, routeto, or transferto.
✗ list_peers: List internal numbers of any type (extensions, queues, ring groups, IVRs, etc.). Supports filtering by name, number, or type.
✗ get_server_time: Get the current server time in UTC and local timezone.
✗ find_by_email: Find a contact by email address
✗ list_crm_contacts: Search for contacts in CRM (Customer Relationship Management) system
✗ get_edit_url: Get a clickable link to open a DN (extension, queue, ring group, IVR, trunk, etc.) in the management UI editor.
✗ find_extension: Find a contact by exact extension number
[CallStore] initialized (Gemini Live mode)
All systems ready (Gemini Live mode)
Qwen
- In config.yaml, enter:
- appId: Client ID from the PBX Integrations > API > Client ID
- appSecret: Service Principal PBX API key from Integrations > API > Generate API Key
- pbxBase: PBX address
- dashscopeApiKey: Alibaba Cloud DashScope API key from Alibaba Cloud DashScope API key
- dashscopeBaseUrl: Use https://dashscope-intl.aliyuncs.com for an international/Singapore key, or https://dashscope.aliyuncs.com for a mainland China key.
Install the dependencies and start the Qwen example:
yarn install
yarn start:alibaba-qwen
A successful Qwen startup log includes:
alibaba-qwen-realtime starting
3CX PBX: https://your-pbx.3cx.eu:5001
DashScope: https://dashscope-intl.aliyuncs.com
Model: qwen3.5-omni-plus-realtime
Voice: Tina
Agent profile: receptionist_en (role: receptionist)
SDK connected (auth + WebSocket + state)
[McpManager] connected to https://your-pbx.3cx.eu:5001/mcp
MCP tools (1/8):
✓ list_phonebook: Search for contacts in the phonebook by name, number, email, or company
✗ control_participant: Control an active call participant: drop, answer, divert, routeto, or transferto.
✗ list_peers: List internal numbers of any type (extensions, queues, ring groups, IVRs, etc.). Supports filtering by name, number, or type.
✗ get_server_time: Get the current server time in UTC and local timezone.
✗ find_by_email: Find a contact by email address
✗ list_crm_contacts: Search for contacts in CRM (Customer Relationship Management) system
✗ get_edit_url: Get a clickable link to open a DN (extension, queue, ring group, IVR, trunk, etc.) in the management UI editor.
✗ find_extension: Find a contact by exact extension number
[CallStore] initialized (Qwen Omni realtime)
All systems ready (Qwen realtime mode)
Test the Agent
Use a test extension. For transfer testing, use a second internal test extension. From the main 3CX Agentic Call Control folder, run the command for the provider you configured:
- OpenAI: yarn start:openai
- xAI: yarn start:xai
- Gemini: yarn start:gemini
- Qwen: yarn start:alibaba-qwen
Wait for the terminal to show the PBX connection and ready state.
- Call the Service Principal Client ID (appId) from the test extension. E.g you dial the literal “assistant” Client ID to connect to the agent.
- Confirm that the agent answers, plays its greeting and responds to you.
- Test an extension lookup or ask it to drop the call for you.
- Check the terminal output for errors.
Customize the Agent
Use config.yaml to change the greeting and provider-specific settings. To change the default behavior, edit agents/receptionist.yaml or add another profile in agents/. If you add customMcpServers, list the exact tool names under mcpTools in that agent profile. Restart the agent after every configuration change and make another test call.
See also
- 3CX Agentic Call Control
- 3CX Call Control API
- 3CX Configuration API
- Call Control API Endpoint Specification
Last Update
This document was last updated on 28 August 2026
https://www.3cx.com/docs/agentic-call-control-ai-providers/