Skip to main content
Glama
soprano-mcp

Soprano Connect MCP Server

by soprano-mcp

Soprano Connect MCP Server

Listed on mcpservers.org

Soprano Connect MCP Server enables you to build AI agents that can communicate, engage customers, and manage communications workflows through Soprano Connect — a global Communications Platform as a Service (CPaaS) — using the Model Context Protocol (MCP).

The Soprano Connect MCP Server enables AI assistants, copilots, autonomous agents, and enterprise applications to securely interact with Soprano Connect's global CPaaS platform. Using natural language, AI agents can send messages, manage customer data, administer accounts, and orchestrate communications across multiple channels in a controlled, enterprise-grade environment.

No complex API integrations. No custom middleware. Simply connect your MCP-compatible AI client and start building intelligent communications workflows — connect any MCP-compatible client (Claude, VS Code Copilot, Cursor, etc.) to the Soprano MCP server and let your agent send messages and check delivery status across multiple channels, all through natural language.

💡 Why Soprano MCP?

Soprano Connect MCP transforms communications capabilities into AI-native tools that can be consumed directly by AI agents. With Soprano MCP, AI agents can:

  • Send omnichannel communications across all channels supported by Soprano Connect platform

  • Manage contacts and customer contact lists

  • Query messaging history and delivery status

  • Automate customer engagement workflows

  • Build AI-powered communications use cases without custom integration code

  • Operate within an enterprise-grade security and governance framework

Related MCP server: Infobip

🛠️ Key Features

  • Send communications through any channel supported by Soprano Connect such as SMS, RCS, WhatsApp, Viber, Email, Voice, Mobile Push

  • Rich content per channel — WhatsApp (media, interactive buttons/lists, templates, location, reactions), RCS (rich cards, carousels, suggestions), Voice (text-to-speech, pre-recorded audio, Call Control Objects), Push Notification

  • Batch and broadcast sending, plus single/batch message status lookups

  • WhatsApp Business (WABA) template listing, and media upload/delete

  • Pluggable upstream (Soprano) authentication — API Key, OAuth2 (client credentials), Basic, Legacy OAuth2, and a session-cookie outlier for WABA templates — selected per request, credentials supplied by the caller and never stored server-side

📋 Prerequisites

  • A Soprano Design Connect API account, provisioned with a license for each channel you want to use

  • Python 3.12+ and uv — only needed for the stdio transport (running the server locally as a subprocess). Connecting to an already-deployed streamable HTTP server needs no local Python install at all

  • AI agent or application with MCP client support

Each tool/channel is only available if your Soprano account is subscribed to and provisioned for the corresponding service. Features outside your current subscription must be enabled via Soprano's onboarding or account management process before use.

Table of Contents


🔌 Transports

The Soprano MCP server supports both of the transports defined by the MCP spec — unlike a hosted multi-tenant service, you run it yourself (locally or deployed), so there's a single endpoint/process rather than one per channel.

Streamable HTTP

Supports streamable HTTP transport for remote/deployable use (e.g. behind an ALB, Lambda Function URL, or API Gateway). Point your MCP client at the server's /mcp endpoint, replacing <mems-mcp-server-url> with wherever you've deployed it (or http://127.0.0.1:8000 if running locally).

If the server has Client Authentication (MCP_CLIENT_AUTH_MODE=oauth2.1) enabled with the Layer 2 fallback turned on — the recommended setup for hosted deployments — no X-Soprano-* headers are needed at all:

{
  "servers": {
    "mems-mcp (http)": {
      "type": "http",
      "url": "<mems-mcp-server-url>/mcp"
    }
  }
}

Your MCP client will redirect you through an OAuth login/consent page, where you enter your Soprano Connect API ID and API KEY — that's the only credential you need to supply. The server uses it both to authenticate you (Layer 1) and, via the Layer 2 fallback, to authenticate its own calls to Soprano on your behalf, so per-request headers become unnecessary.

Otherwise (MCP_CLIENT_AUTH_MODE=none, or you want to pass different Soprano credentials per request regardless), supply Layer 2 credentials explicitly via X-Soprano-* headers instead:

{
  "servers": {
    "mems-mcp (http)": {
      "type": "http",
      "url": "<mems-mcp-server-url>/mcp",
      "headers": {
        "X-Soprano-Auth-Method": "api_key",
        "X-Soprano-Api-Id": "${input:soprano-api-id}",
        "X-Soprano-Api-Key": "${input:soprano-api-key}"
      }
    }
  }
}

X-Soprano-Domain-Url can usually be left out: if the server's own public hostname follows the mcp- naming convention (e.g. mcp-aus.sopranodesign.com), it derives your Soprano domain automatically by stripping that prefix (https://aus.sopranodesign.com). Set the header explicitly only if your deployment doesn't follow that convention, or to target a different domain than the one implied by the hostname.

The X-Soprano-* headers above are for the api_key method — swap them for any of the other supported auth methods (see Authentication below) by using the matching header set instead:

// oauth2 (client credentials)
"headers": {
  "X-Soprano-Auth-Method": "oauth2",
  "X-Soprano-Client-Id": "${input:soprano-client-id}",
  "X-Soprano-Client-Secret": "${input:soprano-client-secret}"
}
// basic
"headers": {
  "X-Soprano-Auth-Method": "basic",
  "X-Soprano-Username": "${input:soprano-username}",
  "X-Soprano-Password": "${input:soprano-password}"
}
// legacy_oauth2
"headers": {
  "X-Soprano-Auth-Method": "legacy_oauth2",
  "X-Soprano-Username": "${input:soprano-username}",
  "X-Soprano-Password": "${input:soprano-password}"
}

The legacy sse transport (append the server's --transport sse flag, endpoint /sse) is also available for MCP clients that don't yet support streamable HTTP.

stdio

For local use (e.g. launched as a subprocess by VS Code, Claude Desktop, etc.), run with --transport stdio. Since stdio has no HTTP headers, Soprano credentials are supplied via SOPRANO_* environment variables instead:

{
  "servers": {
    "mems-mcp (stdio)": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--directory", "${workspaceFolder}", "mems-mcp", "--transport", "stdio"],
      "env": {
        "SOPRANO_DOMAIN_URL": "https://aus.sopranodesign.com",
        "SOPRANO_AUTH_METHOD": "api_key",
        "SOPRANO_API_ID": "${input:soprano-api-id}",
        "SOPRANO_API_KEY": "${input:soprano-api-key}"
      }
    }
  }
}

Same as above, swap the env block for any other auth method:

// oauth2 (client credentials)
"env": {
  "SOPRANO_DOMAIN_URL": "https://aus.sopranodesign.com",
  "SOPRANO_AUTH_METHOD": "oauth2",
  "SOPRANO_CLIENT_ID": "${input:soprano-client-id}",
  "SOPRANO_CLIENT_SECRET": "${input:soprano-client-secret}"
}
// basic
"env": {
  "SOPRANO_DOMAIN_URL": "https://aus.sopranodesign.com",
  "SOPRANO_AUTH_METHOD": "basic",
  "SOPRANO_USERNAME": "${input:soprano-username}",
  "SOPRANO_PASSWORD": "${input:soprano-password}"
}
// legacy_oauth2
"env": {
  "SOPRANO_DOMAIN_URL": "https://aus.sopranodesign.com",
  "SOPRANO_AUTH_METHOD": "legacy_oauth2",
  "SOPRANO_USERNAME": "${input:soprano-username}",
  "SOPRANO_PASSWORD": "${input:soprano-password}"
}

✉️ Messaging Channels

All channels are exposed through one generic send_message tool (channel parameter selects the target) rather than one MCP server per channel — this keeps the tool surface (and token footprint) small while still giving access to every channel-specific rich content type the Connect API supports.

Channel

channel value

Rich content supported

SMS

sms

Plain text only

WhatsApp

whatsapp

Media (image/video/document/audio), interactive buttons/lists, pre-approved templates, location, reactions, context (replies)

RCS

rcs

Rich cards, carousels, suggested replies/actions, media

Email

email

Plain text, CC/BCC

Voice

voice

Text-to-speech, pre-recorded audio file, Call Control Objects

Viber

viber

Plain text (rich content not documented by the Connect API guide — use the extra passthrough field)

Mobile Push Notification

pushnotification

Title + body

Anything not covered by a typed parameter can be sent via send_message's extra field, merged verbatim into the outgoing Connect API payload.

🧰 Available Tools

Tool

Description

Maps to

send_message

Send a single real-time message on any supported channel (SMS, WhatsApp, RCS, Email, Voice, Viber, Push).Example prompt: "Send a WhatsApp message to +33612345678 letting them know their order has shipped."

POST /cgpapi/messages/{channel}

get_message_status

Check the delivery status of a single previously-sent message.Example prompt: "What's the delivery status of SMS message 123456?"

GET /cgpapi/messages/{channel}/{id}

send_batch

Send multiple messages (optionally across different channels) in one call.Example prompt: "Send this appointment reminder as SMS to these 20 customers."

POST /cgpapi/batch/messages

get_batch_status

Check delivery status for multiple SMS messages at once.Example prompt: "Check the delivery status of these 10 SMS message IDs."

POST /cgpapi/batch/messages/status

send_broadcast

Send a broadcast SMS order to lists, contacts, and/or groups.Example prompt: "Broadcast a storm warning SMS to everyone in the 'North Region' contact list."

POST /cgpapi/broadcast/sms

list_whatsapp_templates

List approved WhatsApp Business (WABA) message templates.Example prompt: "What WhatsApp templates do we have approved for order confirmations?"

GET /cgpapi/waba/templates

upload_whatsapp_media

Upload media (image/video/document/audio) for use in WhatsApp messages.Example prompt: "Upload this product image so I can send it via WhatsApp."

POST /cgpapi/waba/media/{source}

delete_whatsapp_media

Delete previously uploaded WhatsApp media.Example prompt: "Delete the WhatsApp media file we just uploaded."

DELETE /cgpapi/waba/media/{id}

🤖 Agent Permission and Access Control

Every tool is annotated with MCP's standard tool annotations (readOnlyHint, destructiveHint, openWorldHint) so a client can apply governance before invoking it — e.g. send_message/send_batch/send_broadcast/upload_whatsapp_media are non-read-only and reach an open world (real message delivery/spend), and delete_whatsapp_media is additionally flagged destructive. Since sending messages has real-world cost and reputational impact, apply your MCP client/host's permission controls (confirmation prompts, allow-lists, scoped credentials) to these tools rather than granting an agent unrestricted access — see the MCP spec's own implementation considerations for guidance.

🔐 Authentication

Soprano credentials are supplied per request, never stored server-side or cached between calls. How you supply them depends on transport (HTTP headers for streamable-http/sse, environment variables for stdio):

Auth method

stdio env vars

HTTP headers

API Key

SOPRANO_AUTH_METHOD=api_key, SOPRANO_API_ID, SOPRANO_API_KEY

X-Soprano-Auth-Method: api_key, X-Soprano-Api-Id, X-Soprano-Api-Key

OAuth2 (client credentials)

SOPRANO_AUTH_METHOD=oauth2, SOPRANO_CLIENT_ID, SOPRANO_CLIENT_SECRET

X-Soprano-Auth-Method: oauth2, X-Soprano-Client-Id, X-Soprano-Client-Secret

Basic

SOPRANO_AUTH_METHOD=basic, SOPRANO_USERNAME, SOPRANO_PASSWORD

X-Soprano-Auth-Method: basic, X-Soprano-Username, X-Soprano-Password

Legacy OAuth2

SOPRANO_AUTH_METHOD=legacy_oauth2, SOPRANO_USERNAME, SOPRANO_PASSWORD

X-Soprano-Auth-Method: legacy_oauth2, X-Soprano-Username, X-Soprano-Password

Session cookie (list_whatsapp_templates only)

SOPRANO_AUTH_METHOD=session_cookie, SOPRANO_SESSION_COOKIE

X-Soprano-Auth-Method: session_cookie, X-Soprano-Session-Cookie

Both transports also require the target domain — SOPRANO_DOMAIN_URL (stdio) or X-Soprano-Domain-Url (HTTP), e.g. https://aus.sopranodesign.com. For streamable-http/sse, this header can be omitted if the server's own public hostname follows the mcp- naming convention (e.g. mcp-aus.sopranodesign.com) — the domain is then derived automatically by stripping that prefix.

🔒 Client Authentication (optional)

Everything above is Layer 2 (this server → Soprano). Independently, you can also require authentication on incoming MCP requests (Layer 1 — client → this server), off by default:

Env var

Required

Description

MCP_CLIENT_AUTH_MODE

—

none (default) or oauth2.1

MCP_OAUTH_ISSUER_URL

if oauth2.1

Your Authorization Server's issuer URL(s) — comma-separated if this deployment fronts multiple domains. With the built-in self-hosted AS, this is derived automatically per-request from the caller's own Host header and can be left unset.

MCP_OAUTH_AUDIENCE

if oauth2.1

Expected token aud claim(s), comma-separated — same per-request derivation as above with the self-hosted AS.

MCP_OAUTH_RESOURCE_SERVER_URL

if oauth2.1

This server's own public URL — fallback default when a request's Host doesn't match any configured domain.

MCP_OAUTH_JWKS_URI

optional

Defaults to {issuer}/.well-known/jwks.json

MCP_OAUTH_REQUIRED_SCOPES

optional

Comma-separated required scopes

Works with any standards-compliant OAuth2/OIDC Authorization Server (Auth0, Okta, Cognito, ...).

Built-in self-hosted Authorization Server

Some MCP clients (confirmed: Zendesk Agent) require a full interactive OAuth 2.0 Authorization Code + consent flow rather than just bearer-token verification. Rather than standing up a separate IdP, this server can act as its own Authorization Server, using the caller's Connect API ID/API KEY as their identity — the routes below are always mounted, and become useful once MCP_CLIENT_AUTH_MODE=oauth2.1 points MCP_OAUTH_ISSUER_URL at this same deployment:

  • GET/POST /oauth/authorize — login+consent form, validating the API ID/API KEY against the Connect API domain derived from the request's own Host header (if it follows the mcp- convention), falling back to MEMS_CONNECT_API_URL otherwise

  • POST /oauth/token — authorization_code (+ PKCE), client_credentials, and refresh_token grants

  • POST /oauth/register — RFC 7591 Dynamic Client Registration; always registers a public (PKCE-secured) client, no client_secret issued

  • GET /.well-known/oauth-authorization-server / GET /.well-known/jwks.json — RFC 8414/7517 discovery metadata

Most MCP clients discover required scopes automatically from that metadata. If yours doesn't, check its scopes_supported list at {your-deployment-url}/.well-known/oauth-authorization-server and configure them manually in the client.

Env var

Required

Description

MEMS_CONNECT_API_URL

Yes

Fallback Connect API domain, used when a request's Host doesn't derive one via the mcp- convention (e.g. multiple domains fronted by one deployment)

MCP_OAUTH_SIGNING_KEY (or MCP_OAUTH_SIGNING_KEY_SECRET_ARN for an AWS Secrets Manager ARN)

Recommended

PEM RSA private key used to sign issued JWTs; an ephemeral key is generated (with a warning) if neither is set — fine for a single local process only

MCP_OAUTH_CLIENTS_TABLE / _CODES_TABLE / _CONSENTS_TABLE / _AUDIT_TABLE / _REFRESH_TOKENS_TABLE

optional

DynamoDB table names backing client/code/consent/audit/refresh-token storage (default to mems-mcp-oauth-*) — requires AWS credentials for boto3

MCP_OAUTH_LAYER2_FALLBACK / MCP_OAUTH_LAYER2_CREDENTIALS_TABLE

optional

Lets clients that can't send X-Soprano-* headers reuse the Connect identity they authenticated with at Layer 1 for Layer 2 calls too (opt-in; caches the real API KEY server-side, TTL-bounded)

🚀 Installation & Running

git clone https://github.com/soprano-mcp/mcp.git
cd mcp
uv sync

# stdio (local subprocess, e.g. launched by an MCP client config)
uv run mems-mcp --transport stdio

# streamable-http (remote/deployable)
uv run mems-mcp --transport streamable-http
# host/port: MEMS_MCP_HOST (default 127.0.0.1), MEMS_MCP_PORT (default 8000)

🛠️ Troubleshooting

Authentication issues

  • Confirm the X-Soprano-* headers (or SOPRANO_* env vars) match one of the 5 supported auth methods exactly, including the domain URL.

  • list_whatsapp_templates is the one outlier requiring session_cookie auth — every other tool accepts the other 4 methods.

Message delivery issues

  • Make sure the recipient's destination is valid for the channel (a phone number for SMS/WhatsApp/RCS/Voice/Viber, an email address for Email).

  • Check get_message_status (or get_batch_status for SMS) — a successful send_message response only means Soprano accepted the request (ENROUTE), not that it was delivered.

  • Some channels/accounts require an explicit license/provisioning on the Soprano side (e.g. Viber client connection) — a clean auth/payload but a licensing-style error back from the API means checking with Soprano support.

Other issues

  • Errors from the Connect API are surfaced via the tool's error text (Soprano's errorDescription field). For deeper HTTP-level detail, see the Connect API guide's response/error format documentation.

🤝 Contributing

Issues and pull requests are welcome on the repository.

📄 License

MIT

Available Tools

8 tools
delete_whatsapp_mediaB
Destructive

Delete previously uploaded WhatsApp media from Facebook.

Maps to DELETE {domain_url}/cgpapi/waba/media/{media_id}.

ParametersJSON Schema
NameRequiredDescriptionDefault
media_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, so irreversibility is covered. The description adds the actual HTTP route, which is useful, but says nothing about whether deletion is permanent, idempotent, or fails silently on an unknown media_id.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short lines, action stated first, endpoint second. Nothing is padded, though the raw endpoint line is developer-facing and only partially earns its place for an agent.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The presence of an output schema removes the need to describe return values, and the annotations cover the safety profile. Still missing is the practical context of obtaining the media_id and the permanence of deletion, which matters for a destructive one-arg tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for the single parameter, and the description only indirectly hints at its meaning by embedding '{media_id}' in the endpoint template. It never states the identifier's origin or format, so it adds marginal meaning over the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Delete previously uploaded WhatsApp media') plus the backing endpoint, so the action is unambiguous. It distinguishes itself from the sibling upload_whatsapp_media by implication only; it never names the counterpart operation or other siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance, no when-not-to-use, and no mention of where a media_id comes from (presumably the upload_whatsapp_media response). The agent is left to infer the full lifecycle from sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_batch_statusA
Read-only

Query the status of multiple messages at once.

Maps to POST {domain_url}/cgpapi/batch/messages/status. Each item is {"id": <message id>, "message_type": "SMS"} (currently only SMS is supported by this Connect API endpoint).

ParametersJSON Schema
NameRequiredDescriptionDefault
itemsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds the upstream endpoint mapping and the supported message_type constraint, but says nothing about batch size limits, partial-failure behavior, or rate limits for a bulk query.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose, followed by endpoint mapping and the critical item format in two short sentences with no filler. The endpoint line is slightly extraneous but serves as a lead-in to the payload shape.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described. Combined with readOnlyHint, the description covers the essentials an agent needs (batch scope, item schema, SMS-only constraint); only batch-size and error-semantics details are absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and the single `items` parameter is an untyped object array, so the description carries the burden — and it does: it gives the exact item shape `{"id": <message id>, "message_type": "SMS"}` and notes SMS is the only supported type. It does not state whether the array size is bounded, but the core structure is fully supplied.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Query the status of multiple messages at once') and the batching scope distinguishes it from the single-message sibling get_message_status. It stops short of naming that sibling explicitly, so the differentiation is implied rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'multiple messages at once' implies the batch use case versus the single-message alternative, but no explicit when-to-use, when-not-to-use, or named alternative (get_message_status / send_batch) is given. Usage is inferable but not guided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_message_statusB
Read-only

Query the status of a single previously-sent message.

Maps to GET {domain_url}/cgpapi/messages/{channel}/{message_id}.

ParametersJSON Schema
NameRequiredDescriptionDefault
channelYes
message_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds the concrete REST endpoint, which helps the agent understand the underlying call, but says nothing about error behavior for unknown message ids or throttling. A 3 is appropriate given annotations carry the safety profile.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short lines, the purpose is front-loaded and the endpoint mapping follows as supporting detail. No filler and nothing redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is a simple single-item read, annotations cover the safety profile, and an output schema exists so return values need not be described. The description supplies the endpoint and parameter placement, leaving only minor gaps around failure cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It partly does: placing {channel} and {message_id} in the URL path clarifies that both are path segments, which the bare schema does not convey. It still gives no format hint for message_id or note that the channel enum values come from the path vocabulary.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Query the status of a single previously-sent message'), and the word 'single' implicitly separates it from the sibling get_batch_status. However, it never names that sibling, so the differentiation requires the agent to infer it from wording rather than being told.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'previously-sent' hints that the message must already exist, but there is no explicit when-to-use, no when-not-to-use, and no routing to alternatives such as get_batch_status for batch lookups. The agent gets no guidance on choosing this tool over its siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_whatsapp_templatesA
Read-only

List approved WhatsApp Business (WABA) message templates.

Maps to GET {domain_url}/cgpapi/waba/templates. Templates with the same name but different languages appear as separate objects (name, language, languageName, category, components, status).

Auth outlier: unlike every other tool, this endpoint requires a portal session cookie rather than one of the 4 standard auth methods - set X-Soprano-Auth-Method: session_cookie and X-Soprano-Session-Cookie: <JSESSIONID value> (or SOPRANO_AUTH_METHOD/SOPRANO_SESSION_COOKIE over stdio).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint/openWorldHint annotations, the description discloses that templates with the same name but different languages appear as separate objects, and flags a genuine auth outlier requiring a portal session cookie with exact header names and env-var equivalents. This is exactly the operational context an agent cannot get from annotations or schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose, then endpoint mapping, then the auth caveat. Information-dense with little waste; the auth paragraph is longer than ideal but each clause (header names, env-var fallback) is load-bearing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, yet the description enumerates the return fields and explains the language-duplication semantics. Combined with the explicit auth instructions, an agent has everything needed to call and interpret this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has zero parameters, so the baseline is 4. The description lists the fields present on each returned object (name, language, languageName, category, components, status), which adds useful shape information even though there are no inputs to document.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (approved WABA message templates) plus the endpoint it maps to. The sibling set is entirely send/media operations, so an agent can immediately distinguish this read-only template-listing tool from the others.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The purpose implies the usage context (browsing approved templates, presumably before sending), but there is no explicit when-to-use guidance, no prerequisites stated, and no alternatives named. Adequate but leaves the agent to infer the scenario.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

send_batchA

Send multiple messages in a single batch call.

Maps to POST {domain_url}/cgpapi/batch/messages. Each item in messages follows the same shape as send_message's payload fields, e.g. {"channel": "sms", "destination": "...", "text": "..."}.

ParametersJSON Schema
NameRequiredDescriptionDefault
messagesYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, openWorldHint=true, and destructiveHint=false, but the description adds no behavioral context beyond the endpoint path and payload shape. It omits batch limits, partial-failure behavior, ordering, rate limits, auth requirements, and atomicity — all important for a batch send tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three short sentences, front-loaded with the core action and followed by the endpoint and payload detail. Every sentence contributes directly to correct invocation, with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value details are appropriately omitted, and the payload shape is referenced. However, for an open-world batch-send operation, the description lacks key operational context such as batch size limits, error handling, and how to track the resulting batch.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the schema itself provides almost no semantic detail for the messages array. The description compensates well by explaining that each item follows send_message's payload fields and gives a concrete example with channel, destination, and text, though it does not document every possible field.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource — 'Send multiple messages in a single batch call' — and clearly distinguishes the batch operation from the singular send_message sibling. An agent can identify the tool's purpose and scope without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'multiple messages in a single batch call' implies the intended use case versus send_message, but it does not explicitly state when to choose this tool over send_message, send_broadcast, or get_batch_status. The guidance is implied rather than spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

send_broadcastB

Send a broadcast SMS order to lists, contacts and/or groups.

Maps to POST {domain_url}/cgpapi/broadcast/sms. endpoints is a list of {"type": <int>, "id": <int>} references (list/contact/group). Ad-hoc mobile-only destinations require at least 250 entries.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
endpointsYes
batch_sizeNo
registeredNo
sleep_durationNo
max_destinationsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false and openWorldHint=true, so the write/external-call profile is covered. The description usefully adds the underlying endpoint (POST .../broadcast/sms) and the shape of `endpoints` references, but says nothing about batching, throttling (sleep_duration/batch_size implications), or what happens to partially failed sends.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short, front-loaded sentences with no filler; the action comes first and the constraints follow. The embedded API path is slightly noisy but is the kind of detail that aids mapping to the backend.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and the endpoint structure is covered. However, with six parameters at 0% schema coverage and four of them unexplained — including pacing controls like batch_size and sleep_duration — the definition is not complete enough to invoke the tool confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and only one of six parameters (`endpoints`) is explained, including its {type, id} reference shape. `text`, `batch_size`, `registered`, `sleep_duration` and `max_destinations` are entirely undocumented in both schema and description, so the description does not compensate for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Send a broadcast SMS order') plus the target types (lists, contacts, groups), so the resource is unambiguous. It does not, however, differentiate itself from siblings like send_message or send_batch, leaving the agent to infer when a broadcast is preferable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives one concrete usage constraint — ad-hoc mobile-only destinations require at least 250 entries — which implicitly tells the agent when this tool is and isn't viable. But there is no guidance on choosing between this and send_message/send_batch, and no prerequisites or exclusions are stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

send_messageA

Send a single real-time message via the Soprano Connect API.

Maps to POST {domain_url}/cgpapi/messages/{channel}. Returns the created message summary (id, destination, status). destination may be a comma separated list of up to 250 recipients. Either text, template_name, or one of the channel-specific rich content objects below must be provided.

  • rcs: RCS-only. Provide exactly one of text, media, rich_card ({"rich_card": {"cards": [{"title": ..., "media": {"file_url": ...}, "suggestions": [{"text": ..., "postback_data": ...}]}]}}). Overrides text/template_name when present.

  • whatsapp: {"type": "image"|"video"|"document"|"audio", "image": {"url": ..., "caption": ...}} for media; {"type": "text", "text": {"body": ...}}; {"type": "interactive", "interactive": {"type": "button"|"list", "body": {"text": ...}, "action": {...}}}; {"type": "template", "template": {"name": ..., "language": ...}}; {"type": "location"|"reaction"|"context", ...}.

  • voice: {"text2voice": {"password": ..., "language": "en-AU", ...}}, or {"call_control_object": {"id": ...}}, or {"audio": {"url": ...}}.

  • push_notification: {"notification": {"title": ..., "body": ...}}.

extra is a passthrough dict merged verbatim into the outgoing JSON payload, for anything not covered by the parameters above (e.g. Viber, which has no documented rich-content schema in the Connect API guide). See the "Payload Parameters" section of the Connect API guide for full field details.

ParametersJSON Schema
NameRequiredDescriptionDefault
rcsNo
textNo
extraNo
voiceNo
sourceNo
channelYes
subjectNo
email_ccNo
reply_toNo
whatsappNo
email_bccNo
key_valuesNo
registeredNo
destinationYes
reply_to_tonNo
template_nameNo
launch_timestampNo
client_message_idNo
push_notificationNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (readOnlyHint=false, destructiveHint=false, openWorldHint=true). The description goes beyond them usefully: it discloses the REST mapping, that it returns the created message summary, the 250-recipient cap, the mutual-exclusion/override behavior of rich content ('Overrides text/template_name when present'), and that extra is merged verbatim. It omits auth requirements and rate limits, but adds substantive non-obvious behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action, endpoint, and return in the first two sentences, then organizes channel-specific payload schemas as bullets. It is long but dense and mostly earns its length; the inline nested JSON examples are wordy given no output/param schema help.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values needn't be explained, and the description covers the main content paths. However, for a 19-parameter tool with 0% schema coverage, roughly half the parameters go undocumented, and it defers to an external 'Payload Parameters' section an agent may not have.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for 19 parameters, so the description must carry the burden. It documents the major content-bearing params (text, template_name, rcs, whatsapp, voice, push_notification, extra) and the destination comma-list semantics, but leaves roughly ten params (source, subject, email_cc, email_bcc, reply_to, reply_to_ton, key_values, registered, launch_timestamp, client_message_id) completely unexplained. Partial compensation only.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Send a single real-time message via the Soprano Connect API'), names the concrete endpoint (POST /cgpapi/messages/{channel}), and the word 'single' implicitly delineates it from send_batch and send_broadcast siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context that this sends one message and that either text, template_name, or a channel-specific rich object must be supplied, plus per-channel selection rules (e.g. rcs is RCS-only, push_notification needs a notification object). It stops short of explicitly stating when to choose this over send_batch/send_broadcast, so it is clear but not fully routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

upload_whatsapp_mediaA

Upload media to Facebook for use in WhatsApp messages.

Maps to POST {domain_url}/cgpapi/waba/media/{source} (multipart upload). source is the WhatsApp sender number the media is uploaded against. file_content_base64 is the file's raw bytes, base64-encoded. Uses the connection's normal auth method (no session cookie needed here - that's only required by list_whatsapp_templates).

ParametersJSON Schema
NameRequiredDescriptionDefault
sourceYes
filenameYes
content_typeYes
file_content_base64Yes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false and destructiveHint=false, so the safety profile is covered. The description adds real value beyond that: the exact endpoint, that it is a multipart upload, and that it uses the connection's normal auth rather than a session cookie. It omits what is created/returned, but an output schema exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Compact and front-loaded: the purpose leads, followed by endpoint/path, then the two non-obvious parameter facts and the auth note. No padding, though the parenthetical about session cookies is more detail than most callers need.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be described, and annotations cover the safety profile. The description supplies endpoint, transport, auth behavior and the two ambiguous parameters, leaving only `filename`/`content_type` semantics implicit, which are largely self-evident.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry parameter meaning, and it covers only two of four: `source` (the sender number the media is uploaded against) and `file_content_base64` (raw bytes, base64-encoded). `filename` and `content_type` are left entirely to inference, so the compensation is partial.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb+resource ('Upload media to Facebook for use in WhatsApp messages') and even cites the underlying endpoint, so the agent knows exactly what operation it is. It does not contrast itself against the close sibling delete_whatsapp_media or clarify the upload/send pipeline, so it stops short of 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the auth note distinguishes this tool from list_whatsapp_templates, which is a partial when-to-use signal. There is no statement of when to call this versus send_message/send_broadcast, nor prerequisites such as a media ID being needed for later sends.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 8 tool updatesv0.1.0
    • First observeddelete_whatsapp_media
    • First observedget_batch_status
    • First observedget_message_status
    • First observedlist_whatsapp_templates
    • First observedsend_batch
    • First observedsend_broadcast
    • First observedsend_message
    • First observedupload_whatsapp_media

TDQS

A3.7/5.0

Scored across 8 tools

Disambiguation4/5

Tools are mostly distinct: send_message (single), send_batch (multiple in one call), and send_broadcast (SMS to lists/groups) have different scopes, and status tools are clearly paired. Minor potential confusion between send_batch and send_broadcast for bulk SMS, but descriptions differentiate well.

Naming Consistency5/5

All tool names follow a consistent verb_noun or verb_noun_status snake_case pattern (e.g., send_message, get_message_status, upload_whatsapp_media). No mixed conventions or vague verbs.

Tool Count5/5

Eight tools are well-scoped for a messaging API, covering single/batch/broadcast sends, status queries, and WhatsApp-specific templates and media operations without redundancy.

Completeness4/5

Core messaging lifecycle is covered (send, status, batch, broadcast, WhatsApp media/templates). Minor gaps exist: no tools for managing contacts/lists/groups referenced by send_broadcast, and no dedicated broadcast status query.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Infobip MCP Servers let you build AI agents to interact with the Infobip platform through the Model Context Protocol (MCP). Connect to Infobip and enable your agents to perform actions, such as sending messages over channels like SMS, WhatsApp, or Viber, or managing customer data in a controlled, pr
    35
    MIT
  • F
    license
    A
    quality
    Not graded
    maintenance
    An MCP server for interacting with Saptiva AI's suite of models, offering capabilities such as chat completions, chain-of-thought reasoning, and OCR. It enables users to generate semantic embeddings, access specialized prompts, and manage AI-driven workflows through a standardized interface.
    7
    -