MCP servers
Connect your own MCP servers so the AI agent can use their tools — quote prices, look up orders, trigger actions — during a conversation.
The AI agent answers from your knowledge base out of the box. MCP servers let it go further: when you connect a server that speaks the Model Context Protocol (MCP), the agent can call your tools mid-conversation — to read live data or take an action in your own systems — and use the result in its reply. This is how you give the agent abilities Chatasist doesn't ship natively, without us building each one.
MCP servers are an Enterprise feature. On other plans the MCP servers page shows an upgrade prompt. (For surfacing a single customer's records — order, booking, subscription — see Resources & MCP, which uses the same protocol for a narrower, per-customer-record job.)
What you can do with it#
Anything you can expose as a tool, the agent can use. Common examples:
A get_shipping_price tool that takes origin, weight, and destination and returns a
number from your own rate engine — so "how much?" questions get a real answer instead
of a ticket.
A get_order_status tool that takes a tracking code and returns the current status and
ETA from your fulfillment system.
An is_in_stock tool that answers "do you have X?" against your live inventory.
A cancel_order or book_slot tool that performs a real operation in your system when
the customer asks (guarded by whatever rules your server enforces).
The agent decides whether to call a tool based on the customer's message — it only calls one when it clearly fits, and it never invents a result if the call fails.
How it works#
Chatasist acts as the MCP client; you host the MCP server. Nothing about your data is imported or stored — the agent reads it on demand.
You connect a server
You register your server's HTTPS URL (and any auth headers it needs) on the MCP servers page.
Chatasist discovers your tools
Chatasist asks your server which tools it offers and reads each tool's name and description. That list is what the agent "sees."
The agent calls a tool when relevant
During a conversation, if the customer's request matches one of your tools, the agent calls it with the arguments it inferred, waits for the result, and weaves it into the reply in the customer's language.
Failures degrade safely
If your server is unreachable, errors, or returns nothing, the agent does not fabricate an answer — it tells the customer it couldn't complete that and offers to open a support ticket.
Connect an MCP server#
Open the MCP servers page
In the sidebar, under Integrations, open MCP servers and click Add server.
Fill in the connection
- Name — a label for your reference.
- Server URL — the public HTTPS endpoint of your MCP server.
- Auth headers (optional) — any headers your server requires (for example an
Authorizationtoken). Stored encrypted and sent only to your server.
Enable and save
Toggle Enabled and save. Chatasist fetches the server's tool list and makes those tools available to the agent automatically — there's nothing to wire per tool.
Test the connection
Press Test — on a saved server, or right in the form before you save. Chatasist makes
a live tools/list call from its own servers and shows you what came back: connected,
with the tools it found, or exactly why it couldn't (unreachable, an HTTP error, or a
response that isn't an MCP endpoint). This is the fastest way to confirm the URL, the
token, and your allow-listing are all right, without waiting for a real conversation.
Test in a conversation
Send a message on an AI-enabled channel that should trigger one of your tools and check the reply. If the tool didn't fire, see Troubleshooting below.
What your server must implement#
Your server needs to answer two standard MCP calls over JSON-RPC. You don't have to build these by hand — most MCP server frameworks provide them — but here's the contract Chatasist relies on.
1. List your tools — Chatasist calls tools/list; your server returns the tools it
offers, each with a name, a description, and an input schema:
{
"tools": [
{
"name": "get_shipping_price",
"description": "Quote a shipping price. Args: origin (country), weight_grams (int), destination (city).",
"inputSchema": {
"type": "object",
"properties": {
"origin": { "type": "string" },
"weight_grams": { "type": "integer" },
"destination": { "type": "string" }
},
"required": ["origin", "weight_grams", "destination"]
}
}
]
}
2. Run a tool — when the agent decides to use a tool, Chatasist calls tools/call
with the tool name and an arguments object. Your server returns a text result:
{
"content": [
{ "type": "text", "text": "5 kg from China to Baku = 40.40 AZN (pickup)." }
]
}
The agent paraphrases that text into its reply. Return a clear, self-contained sentence —
the agent reads the text, not your internal fields.
Respond quickly. Chatasist waits only a few seconds for your server (roughly 8 seconds per call); if it's slower, the agent treats it as a failure and falls back to suggesting a support ticket. Keep tool calls fast and idempotent where you can.
Write tool descriptions the agent can act on#
The agent picks a tool from its name and description alone, so those are your real control surface:
- Say what it's for and when to use it — "Quote a shipping price when the customer asks how much delivery costs," not just "pricing."
- List the arguments and their format — names, types, units (grams vs. kg), and example values. The agent fills arguments from the conversation, so be explicit.
- Keep each tool focused — one job per tool beats one tool with a dozen modes.
Headers we send with every call#
Alongside the credential you configured, each tools/call carries what Chatasist knows
about who is asking:
| Header | What it is |
|---|---|
X-Customer-Token | The opaque token your storefront or mobile app handed the widget, relayed unchanged — or a token your own verify tool returned earlier (see Confirming who the customer is). Absent when there is neither. |
X-Customer-Channel | The messaging platform the customer is writing from: instagram, facebook, whatsapp or telegram. Not sent for the website widget. |
X-Customer-Channel-Id | That platform's own id for the sender — the Instagram or Messenger user id, the WhatsApp number, the Telegram chat id. The platform signs it, so it is the same account every time. |
X-User-Country | Two-letter ISO code for where the visitor is browsing from, e.g. AZ. Absent when it could not be resolved. |
Treat a missing header as "unknown" rather than falling back to a default — an unauthenticated customer and a customer from an unknown country are both real cases.
Confirming who the customer is#
Chatasist never decides that a customer is who they say they are — your server does. There are three ways to tell it, and they can be combined.
1. A signed-in customer on your website or in your app. Mint a short-lived token for
the logged-in customer on your side and hand it to Chatasist: to the website widget as
customerToken (how), or to the Flutter SDK (1.6.0 or later) through
customerTokenProvider or setCustomerToken. It arrives on every call as
X-Customer-Token. Refresh it before it expires — the Flutter SDK's provider does that for
you. If your server rejects it
with HTTP 401, Chatasist repeats that call once without the token, so your public tools
keep working and the customer can still confirm by code.
2. A confirmation code, for channels with no login. On Instagram, Messenger, WhatsApp and Telegram there is no session to carry. Offer two tools — one that sends a one-time code to the customer's email or phone, and one that checks it — and have your account tools answer an unconfirmed caller with a tool error that says so. The agent then asks the customer's permission, sends the code, and checks what they read back.
3. Remembering it. So the customer is not asked again on their next message, return a reusable credential from your verify tool as JSON. Chatasist keeps it encrypted and sends it back for you:
| Your verify tool returns | What Chatasist does on later calls |
|---|---|
customer_token (optionally header) | Sends it as that header — X-Customer-Token unless you name another. |
verification_code | Passes it as a verification_code argument to the tools that report an unconfirmed customer. |
Add expires_in (seconds) or expires_at to say how long it is good for. Without either,
a customer_token is kept until your server rejects it, and a verification_code for 24
hours. If one response returns both, expires_in and expires_at describe the code; give the
token its own lifetime with customer_token_expires_in or customer_token_expires_at, or leave
them out to keep it until you reject it.
A customer_token is never shown to the AI agent or kept in the conversation: Chatasist stores
it encrypted and adds it to your calls itself. When your server stops accepting it, answer 401 (for a token) or a tool error saying
the customer is no longer confirmed. Chatasist then drops it and asks the customer to confirm
again.
{ "customer_token": "…", "header": "X-Customer-Token", "expires_in": 1800 }
On a messaging platform the confirmation is remembered for that platform account, across conversations, for as long as you allow. In the website widget it is remembered for that one conversation only. Your team can see and end these links on the customer's profile (see Confirmed accounts).
Link an Instagram or WhatsApp account permanently. After a successful code check, return a
customer_token with no expiry that stands for this customer. Chatasist stores it encrypted
and sends it as X-Customer-Token on every later call from that account, so the customer
confirms only once. To end the link, for example after a password change, answer 401 to
that token. For extra safety, tie the token to the X-Customer-Channel and
X-Customer-Channel-Id it was issued for, and reject it from any other account.
For a login that lasts, bind the account on your side. After a successful code check, store
that X-Customer-Channel + X-Customer-Channel-Id belongs to that customer. On later
calls carrying the same pair you can treat the caller as confirmed without a code, for as
long as you choose. Those headers only ever come from Chatasist's servers alongside your
own credential, and the id is the one the platform itself reports.
Personal details in tool results#
Fields that identify a person, such as names, phone numbers, emails, addresses and the recipient, are removed from a tool's JSON result before the agent sees it. Someone who only knows an order number sees its status and dates, not who it belongs to.
They are kept when your server answered a call that carried the customer's confirmation:
- a signed-in customer's token that your server accepted, or
- the
verification_codeyour verify tool returned, passed to a tool that declares averification_codeargument in its input schema (or that refused the call without it).
A public tool that does not take the code, such as order tracking, never shows these details. Make sure a tool that accepts the confirmation returns only records that belong to that customer.
Showing products as cards#
When a tool returns products, the agent draws them as cards rather than writing them out as a list — a picture, the name, the price, and a tap that opens the product page. It uses whatever each channel supports: a scrollable carousel on Messenger and Instagram, a photo with a link button on Telegram, a captioned photo on WhatsApp, and cards in the website widget.
To get the most out of this, return per product:
- An image URL — without one there is no picture to lead with.
- A link to the product page — Chatasist will not build one from a slug or an id, and a card whose link it cannot trace back to your data is shown without one rather than sending the customer to a page that may not exist.
- The price, and when the item is discounted, the pre-discount price and the saving. The agent passes these through as you state them and never works a discount out itself.
When a call fails or finds nothing#
The agent is instructed to never guess. In each of these cases it tells the customer plainly and offers to open a support ticket:
- Unreachable / timeout — your server didn't respond in time.
- Error response — your server returned an error. The agent says it could not check right now; it does not tell the customer their order or record was not found.
- No useful result — the call succeeded but returned no text.
- No matching tool — none of your tools fit the request.
Security#
- You control access. The agent can only call the tools your server exposes, using the auth headers you set.
- Header values are write-only. After saving, Chatasist shows which header names are set but never displays their values again.
- On-demand only. Tools are called during a conversation when relevant — there's no background polling of your server.
- Public HTTPS only. Server URLs must resolve to public addresses; internal or private addresses are rejected.
- Enforce your own rules. Treat every call as untrusted input — validate arguments and apply your own authorization for any tool that takes an action.
Disable or remove a server at any time to immediately stop the agent from using its tools.
Troubleshooting#
The agent isn't calling my tool.
- Confirm the server is Enabled and reachable at a public HTTPS URL.
- Check that
tools/listreturns the tool with a clear description — a vague description is the most common reason the agent skips a tool. - Make sure the conversation is on an AI-enabled channel and the customer's message actually matches what the tool does.
- The tool list is cached briefly after connecting; give it a moment and resend.

