Voicent MCP Server
Voicent MCP server
Lets an AI agent use an on-premise Voicent Gateway: place calls and texts, run campaigns, check results, and read and update CRM records.
This is phase 1, covering the Simple Gateway API, the Campaign API and the CRM API. Anything that needs a product change, such as CRM search, comes in phase 2.
Requires Voicent Gateway 10.10.3 or later. On older versions, audio calls fail, Chinese text is lost when a request is saved, and apostrophes in customer fields are saved wrongly.
Voicent licenses: you need the Workflow license plus the Enterprise Edition of the product.
Tools
Single calls, texts and CRM tools are on by default, and campaigns are off. A tool that's turned off doesn't exist for the agent.
Setting | Tools |
Always on |
|
On unless |
|
On unless |
|
Off unless |
|
Not included yet: predictive dialer campaigns, scheduled or recurring campaigns, uploading files to a remote gateway, and searching, listing or deleting CRM records. Without search, the agent needs a record's ID, or a customer's phone number or email.
Related MCP server: OpenTool
Settings
Variable | Purpose |
| Gateway address. Default: |
|
|
| Limits single calls and texts to these comma-separated numbers. Default: any number |
|
|
|
|
| Folder that audio, import and export files must stay inside. File tools refuse to run without it |
| The gateway's Remote Connect Password, needed when the gateway isn't on this machine |
| Login name, if |
| Account ID ( |
| Request timeout. Default: 30000 |
File paths are read by the gateway, so file tools only work when this server runs on the gateway machine.
Safety
By default, the agent can call or text any number. To limit it, for example while testing, set
VOICENT_ALLOWED_NUMBERS. To turn calls and texts off, setVOICENT_ALLOW_CALLS=0.VOICENT_ALLOWED_NUMBERSdoes not apply to campaigns. A campaign contacts everyone on its list, so only turn onVOICENT_ALLOW_CAMPAIGNSwhere that's acceptable.List imports aren't limited like the CRM tools.
campaign_import_listcan update any column of matching contacts, including clearingDO_NOT_CALL, from a file inVOICENT_FILE_ROOT. Only put files there that you'd import yourself.CRM reads send customer records to your AI provider, and CRM writes change them. To turn the CRM tools off, set
VOICENT_ALLOW_CRM=0.Limits on CRM tools: only known fields can be read or changed. The agent can set
DO_NOT_CALLandDO_NOT_EMAILto yes, but only a person can clear them.crm_add_or_updateonly fills empty values unlessoverwriteis true. Notifications are plain text.Protect the gateway itself. These limits only apply to this server. The gateway is open from localhost and needs its Remote Connect Password from anywhere else. Set your own in Voicent App > Setup > Options > Control, because a remote login can deploy IVR apps and run SQL. Don't expose the port to untrusted networks. Some call flow pages have no password check.
Requests are built from a fixed set of fields. The server never sends
sqlor database fields,startvxmlorstarturl, orignorednc(this bypasses do-not-call).Phone numbers must be a single number in a strict format, which blocks the gateway's special values
dbquery,dialerandvcenter.
Run
Requires Deno.
deno task test # tests against a fake gateway; nothing is dialed
deno task start # run from source
deno task compile # build dist/voicent-mcp.exe, which runs without DenoConnect to Claude Code
Add this to .mcp.json:
{
"mcpServers": {
"voicent": {
"command": "C:\\voicent-mcp\\voicent-mcp.exe",
"env": {
"VOICENT_GATEWAY_URL": "http://localhost:8155"
}
}
}
}Before you connect: with this config, the agent can call or text any number, read CRM records, which go to your AI provider, and change them. Add settings to env to change that:
To | Add |
Limit calls and texts to certain numbers |
|
Turn calls and texts off |
|
Turn the CRM tools off |
|
Turn campaigns on |
|
Allow audio, import and export files |
|
The server repeats these warnings in its log each time it starts.
Differences from the developer docs
The server sends what the gateway actually reads, which differs from the developer docs in these places:
Email campaigns pass inline content as
msginfo(subject) andmsgbodywith nomsgtype. The docs describemsgtype=fileandmsgfilepath, which the gateway doesn't read.call_ivruses thestartappfield.Every request sends the password as
agent_password, withagent_usernamefor a user login. The docs usepasswdfor the Remote Connect Password, and the gateway accepts it under either name.
Known issues
Phone and email lookups can match the wrong record when there are duplicates. Use the record ID when you have it.
call_ivrcan't check that an app is outbound. It refuses names that aren't deployed. Use outbound apps only.An IVR app with no answering machine message can occasionally end as
failedwhen it reaches voicemail. Add the message to the app in IVR Studio.
License
This server is under the MIT License; see LICENSE. The Voicent software it connects to is licensed separately.
Available Tools
14 toolscall_audioCall and play audioADestructive
Place a real phone call that plays a WAV file (PCM 16-bit, 8 kHz, mono) inside the configured file folder. Returns a request ID.
| Name | Required | Description | Default |
|---|---|---|---|
| phone | Yes | One phone number, such as 650-555-0100. | |
| caller_id | No | Caller ID to use. It must already be set up in Voicent. | |
| audio_file | Yes | Full path to the WAV file. | |
| keep_record | No | Keep the record afterwards so its status can be checked. If false, it is deleted automatically. | |
| schedule_minutes | No | Do this many minutes from now. Leave out to do it right away. |
call_ivrCall and run an IVR appADestructive
Place a real phone call that runs an outbound app deployed from Voicent IVR Studio. Refuses a name that isn't deployed. Check call_status for the callee's responses. Returns a request ID.
| Name | Required | Description | Default |
|---|---|---|---|
| phone | Yes | One phone number, such as 650-555-0100. | |
| app_name | Yes | Name of the deployed outbound IVR app. | |
| caller_id | No | Caller ID to use. It must already be set up in Voicent. | |
| keep_record | No | Keep the record afterwards so its status can be checked. If false, it is deleted automatically. | |
| schedule_minutes | No | Do this many minutes from now. Leave out to do it right away. |
call_removeRemove a call recordADestructive
Delete a call or text record. If it hasn't been placed yet, this also cancels it.
| Name | Required | Description | Default |
|---|---|---|---|
| request_id | Yes | Request ID returned when the call or text was created. |
call_statusCheck call or text statusARead-only
Check a call or text created earlier. Status is in_progress, made, failed, retry, pending, mixed, waitresponse, waitagent or expired. Each attempt also lists times, the confirmation result and any recording. Wait a few seconds between checks.
| Name | Required | Description | Default |
|---|---|---|---|
| request_id | Yes | Request ID returned when the call or text was created. |
call_textCall and speak textBDestructive
Place a real phone call that speaks the given text using text-to-speech. Returns a request ID.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | What to say on the call. | |
| phone | Yes | One phone number, such as 650-555-0100. | |
| caller_id | No | Caller ID to use. It must already be set up in Voicent. | |
| keep_record | No | Keep the record afterwards so its status can be checked. If false, it is deleted automatically. | |
| schedule_minutes | No | Do this many minutes from now. Leave out to do it right away. |
campaign_statusCheck campaign statusBRead-only
Get a campaign's status and counts: made, live, machine, noanswer, linebusy, failed, dnc, optout and others.
| Name | Required | Description | Default |
|---|---|---|---|
| campaign_id | Yes | Campaign ID returned when the campaign was started. |
crm_add_noteAdd a note to a CRM recordB
Add a note to a customer, organization or potential record.
| Name | Required | Description | Default |
|---|---|---|---|
| note | Yes | Text of the note. | |
| No | Find a customer by email address. If there are duplicates, this can match the wrong record. | ||
| phone | No | Find a customer by phone number. If there are duplicates, this can match the wrong record. | |
| agent_id | No | ID of the agent to record as making this change. | |
| record_id | No | Record ID. Use this when you have it, because it always finds the right record. | |
| record_type | No | Type of record. Default: customer. | customer |
crm_add_or_updateAdd or update a CRM recordADestructive
Add a record, or update the customer it matches. An existing customer is matched by record_id, or else by phone number and email in the fields, and duplicates can match the wrong record. Only empty values are filled unless overwrite is true.
| Name | Required | Description | Default |
|---|---|---|---|
| fields | Yes | Field names and values, such as FIRST_NAME and CELL_PHONE. A customer needs a name, phone number or email. | |
| overwrite | No | Replace existing values, not just fill in empty ones. | |
| record_id | No | ID of the customer to update. Customers only. | |
| record_type | No | Type of record. Default: customer. | customer |
| match_email_first | No | Match an existing record by email before phone number. |
crm_get_fieldRead a CRM fieldARead-only
Read one field of a customer, organization or potential record. There is no search: you need the record ID, or a customer's phone number or email.
| Name | Required | Description | Default |
|---|---|---|---|
| No | Find a customer by email address. If there are duplicates, this can match the wrong record. | ||
| field | Yes | Field name, such as FIRST_NAME or CF_1. | |
| phone | No | Find a customer by phone number. If there are duplicates, this can match the wrong record. | |
| record_id | No | Record ID. Use this when you have it, because it always finds the right record. | |
| record_type | No | Type of record. Default: customer. | customer |
crm_notify_agentNotify a CRM agentA
Show a notification to an agent in the CRM. Plain text only. This doesn't contact a customer.
| Name | Required | Description | Default |
|---|---|---|---|
| body | Yes | Text of the notification. | |
| title | Yes | Title of the notification. | |
| agent_id | No | ID of the agent to notify. | |
| agent_name | No | Login name of the agent to notify. |
crm_schedule_callbackSchedule a CRM callbackB
Schedule a callback for an agent to make, or update one you already have the ID for. This doesn't place a call.
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | Schedule it at this time, such as 2026-11-07T09:30:00-08:00. | |
| done | No | Mark the callback as made. | |
| note | No | Note for the agent. | |
| agent | No | Login name of the agent who should make the callback. Required for a new callback. | |
| phone | No | Number to call back. | |
| extension | No | Phone extension. | |
| in_minutes | No | Schedule it this many minutes from now. | |
| callback_id | No | ID of an existing callback to update. | |
| customer_id | No | ID of the customer to call back. Required for a new callback. |
crm_set_fieldChange a CRM fieldADestructive
Change one field of a customer, organization or potential record. This replaces the current value. DO_NOT_CALL and DO_NOT_EMAIL can be set to yes, but not cleared.
| Name | Required | Description | Default |
|---|---|---|---|
| No | Find a customer by email address. If there are duplicates, this can match the wrong record. | ||
| field | Yes | Field name, such as JOB_TITLE or CF_1. | |
| phone | No | Find a customer by phone number. If there are duplicates, this can match the wrong record. | |
| value | Yes | New value. | |
| agent_id | No | ID of the agent to record as making this change. | |
| record_id | No | Record ID. Use this when you have it, because it always finds the right record. | |
| record_type | No | Type of record. Default: customer. | customer |
import_statusCheck list import statusARead-only
Check the progress of the current contact list import. Only the most recent import can be checked.
| Name | Required | Description | Default |
|---|---|---|---|
| list_id | No | The list ID returned when the import started. |
send_smsSend a text messageBDestructive
Send a real text message to one phone number. Returns a request ID.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The message to send. | |
| phone | Yes | One phone number, such as 650-555-0100. | |
| keep_record | No | Keep the record afterwards so its status can be checked. If false, it is deleted automatically. | |
| schedule_minutes | No | Do this many minutes from now. Leave out to do it right away. |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
14 tool updates
v0.1.0- First observed
call_audio - First observed
call_ivr - First observed
call_remove - First observed
call_status - First observed
call_text - First observed
campaign_status - First observed
crm_add_note - First observed
crm_add_or_update - First observed
crm_get_field - First observed
crm_notify_agent - First observed
crm_schedule_callback - First observed
crm_set_field - First observed
import_status - First observed
send_sms
TDQS
Scored across 14 tools
Tools are grouped into clear resource families (crm_*, call_*, *_status) and the three call placement tools are cleanly separated by medium (TTS, WAV, IVR app). The one soft boundary is crm_add_or_update (with overwrite) versus crm_set_field, since both can change an existing field value, but the descriptions largely disambiguate them.
Most tools follow a <group>_<object> pattern, and the crm_ family is consistently verb_noun (crm_get_field, crm_set_field, crm_add_note). However the call family flips ordering/noun-verb intent (call_status vs call_text/call_audio/call_ivr, plus campaign_status/import_status), so conventions are mixed though still readable.
14 tools sit comfortably in the well-scoped range and each maps to a distinct operation (field access, messaging, campaign/import monitoring, agent notifications). Nothing appears redundant or padding-like.
Core outbound actions and status checks are covered, but the surface has notable gaps: no CRM search or list (explicitly stated), no way to read more than one field at a time, no campaign creation/listing despite campaign_status, and DO_NOT_CALL/DO_NOT_EMAIL flags can be set but never cleared. Agents can work around some of these via record IDs, but discovery-heavy workflows will hit dead ends.
Maintenance
Related MCP Connectors
Let AI agents place real phone calls from your verified number, with transcripts and recordings.
Give any AI agent a phone: make and answer calls, get through phone menus, and send texts.
Give AI agents a phone layer for consent-based calls, transcripts, summaries, and outcomes.
Calls, leads, bookings, chats, outbound AI calls and Do Not Call for one Vocenya business.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables self-hosted AI gateway and agent control plane with governed MCP tools, virtual-key budgets, caching, and audit, supporting OpenAI, Anthropic, Gemini, MCP, and A2A protocols. It provides deterministic prompt enhancement and governed execution with a zero-credential first run.10Apache 2.0

OpenToolofficial
AlicenseNot gradedqualityCmaintenanceEnables AI agents to execute provider tools through a self-hostable gateway with scoped keys, permissions, and accounting reservations.Apache 2.0
A CallNode MCP serverofficial
AlicenseNot gradedqualityCmaintenanceLets an AI assistant read call and message history, send texts and picture messages, reach Phone Book contacts by name, and — once switched on — place calls run by a voice agent, all limited to the phone numbers the user ticks. Hosted remotely with OAuth sign-in, so nothing needs to be installed locally.MIT- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to prepare, authorize, and place real outbound phone calls through an Android SIM gateway, then retrieve recordings, full transcripts, contact memory, and scheduled callbacks. Also supports inbound reception instructions, reusable personalities, and live call management from a private dashboard.MIT