Skip to content

Portal MCP Server

Connect an MCP client — Claude Code, Claude Desktop, or anything else that speaks the protocol — to your QVOICE Platform account and let it read and change the account's configuration in plain language.

Ask it "which personas do we have and on what extensions?" and it answers from your account. Ask it to change an AI agent's greeting and it changes it, through the same path the portal uses.

Note

This is a different surface from the MCP Server an AI agent uses while it is on a call. That one offers the tools a call needs — transfer, hang up, look up a contact. This one offers the tools an administrator needs, and neither is offered the other's.

Connect

https://{{ domain }}:9443/api/v2/mcp/portal

Transport is HTTP Streamable. Authenticate with an API key:

Header Description
X-API-Key An API key created in your account

A bearer token works too (Authorization: Bearer <jwt>), which is what a browser-based client uses. Either way the account is resolved on the server — from the key's own record, or from the token — so a client cannot ask about an account it was not issued for.

Working on a sub-account

A partner whose key belongs to a parent account can act on one of its children by naming it:

Header Description
X-Account-ID The account to work on, if the key's account is above it

Naming an account the key has no claim to is refused. This is the same check that guards every other endpoint, so what a key can reach here is exactly what it can reach through the API.

Claude Code

claude mcp add --transport http --scope user qvoice-portal \
  https://{{ domain }}:9443/api/v2/mcp/portal \
  -H "X-API-Key: YOUR_API_KEY"

--scope user makes it available in every project; leave it out to add it only where you run the command.

Any other client

Point it at the URL above with the X-API-Key header. Most clients take a JSON block:

{
  "mcpServers": {
    "qvoice-portal": {
      "type": "http",
      "url": "https://{{ domain }}:9443/api/v2/mcp/portal",
      "headers": { "X-API-Key": "YOUR_API_KEY" }
    }
  }
}

See API Key Authentication to create the key.

Warning

The key is the scope: it decides which accounts the client may see and change — its own, and any beneath it. Give each person their own; sharing one shares everything it reaches. An administrator's key is required, because these tools do what an administrator does in the portal.

Tools

Reading the account

Tool Answers
get_account_info Name, timezone, features, basic configuration
list_users / get_user Users, their extensions and status
list_queues / get_queue Queues and how they are configured
list_devices Phones, optionally for one user
list_callflows Call routing
list_agents / get_agent_states Contact centre agents and what they are doing now

AI personas

Tool Does
list_personas Every persona: name, job, extension, conversation shape
get_persona One in full — prompt, greeting, voice, extension, gate flow
create_persona Creates one, with an extension and the routing that makes it answer
update_persona Changes prompt, greeting, voice, extension or conversation shape

Creating a persona

Four things are required: a name, the job it does, a description, and the prompt that tells it how to behave.

Create a persona called Front Desk that answers our main line, greets
callers in English, finds out who is calling and why, and offers to take
a message when it cannot help.

The persona comes back with an extension already assigned and its inbound routing in place — it can take a call the moment it exists. Name an extension yourself and it is used, unless another callflow already answers it, in which case the request is refused rather than taking the number away from whatever has it.

Note

The greeting is spoken as written. Write the sentence the caller should hear — "Thanks for calling Acme, how can I help?" — not an instruction like "greet the caller warmly", which is what the caller would hear read out.

Changing a persona

Only the fields you name are changed; everything else is left alone. Changing a voice does not mean restating the prompt.

Change the Front Desk greeting to "Thanks for calling Acme, how can I help?"

A change made here is the same change the portal makes: the persona's inbound routing is rebuilt to match, and the same rules apply — an extension another callflow already answers is refused, with a message naming what holds it.

Conversation shape

A persona runs a call one of two ways:

Shape The call is
legacy One prompt, for the whole conversation
gate_runtime A graph of stages, each with its own prompt and its own tools

The second is what stops a stage being talked into something it has no business doing: a stage that has no reason to transfer a call is not given the tool to transfer one. Draw the graph in the portal, or pass it as JSON to update_persona. A flow that will not parse, or that names no entry stage, is refused rather than saved for a call to fail on.

Reading a persona returns the flow summarised — its entry stage and the stages in it — because a flow runs to thousands of characters and its shape is usually what you want. Ask for the document itself with include_gate_flow.

What it will not do

  • Take an account it was not given. The account comes from the key or the token, and an X-Account-ID is honoured only when the account tree allows it — never on the client's word alone.
  • Touch a live call. Transferring and hanging up belong to the agent's surface; this one is not offered them.
  • Work without an administrator. These tools do what an administrator does in the portal, and the same permission is required.