MCP Connectors
Wetel supports two ways to give an agent access to external tools: MCP Connectors and Custom Actions. They solve overlapping problems, but they have different registration flows and different tradeoffs. This page covers MCP Connectors — for the simpler REST-endpoint path, see the “Custom Actions” section below and the workflow overview for how both are referenced from a workflow graph.
What is an MCP connector?
Section titled “What is an MCP connector?”The Model Context Protocol (MCP) is an open standard where a server exposes a list of tools — each with a name, description, and input schema — and a client calls them. If you already run an MCP server (for example, a resource-management server exposing check_availability and search_catalog tools), you register it with Wetel as an MCP Connector. Once registered, a workflow’s tool node can call any tool that server exposes.
Registering a connector requires dashboard access (a signed-in user JWT):
mutation CreateConnector { createMcpConnector( input: { name: "Library MCP Server" serverUrl: "https://mcp.example.com" apiKey: "sk-your-server-key" } ) { id name serverUrl }}Wetel stores serverUrl and swaps the raw apiKey you provide for an opaque, securely-stored credential reference — the key itself is never returned by the API again.
To confirm which tools a connector exposes before wiring it into a workflow, call listMcpTools:
query ListTools { listMcpTools(connectorId: 42) { name description inputSchema }}This is always a live call — Wetel opens a fresh connection to your server and asks it directly, every time. There’s no caching layer in front of it, so if a newly added tool isn’t showing up, the most likely cause is your own server (not yet redeployed, or the tool not registered in its tools/list handler) rather than anything on Wetel’s side.
Using a connector in a workflow
Section titled “Using a connector in a workflow”A tool node references a connector by its connectorId, along with the specific toolName to call and an argsTemplate — a Handlebars template that builds the JSON arguments from the current conversation context:
{ "id": "check_availability", "type": "tool", "label": "Check Room Availability", "config": { "connectorId": 42, "toolName": "check_room_availability", "outputVar": "availability_result", "argsTemplate": "{\"building\": \"Main Library\", \"query\": \"{{userMessage}}\"}", "timeoutMs": 10000 }}timeoutMs defaults to 10,000ms if omitted. See the workflow overview for the full node/edge model, and the MCP cookbook for worked examples of registering a server and wiring its tools end to end.
MCP Connector vs. Custom Action
Section titled “MCP Connector vs. Custom Action”Wetel also supports Custom Actions — a simpler registration for a single plain REST endpoint, with no MCP protocol involved:
mutation CreateAction { createCustomAction( input: { name: "Renew Loan" method: "POST" url: "https://api.example.com/renew-loan" bearerToken: "sk-your-service-key" } ) { id name url }}A workflow’s action node then references it by customActionId, using the same argsTemplate convention as tool nodes.
Use an MCP Connector when:
- You already run (or have access to) a live MCP server. You get automatic tool discovery and structured schema information for each tool.
Use a Custom Action when:
- You have a plain REST API and no MCP server. Don’t build an MCP wrapper just to satisfy Wetel — that’s unnecessary complexity. A Custom Action is simpler to operate and just as secure (outbound calls are validated against the same SSRF protections either way).
- You’re prototyping. Custom Actions are faster to set up; you can graduate to an MCP Connector later if you want richer tool discovery.
If your REST endpoint needs a credential shape other than a single bearer token (a custom header name, an API-key query parameter), there’s no generic-headers option on createCustomAction today — you’d need a small proxy of your own that accepts a bearer token and translates it to whatever your real API expects.
Responses must not be Brotli-compressed
Section titled “Responses must not be Brotli-compressed”Since 2026-10-23, Wetel asks your MCP server for gzip, deflate and refuses a Brotli (br) response, both when it lists tools and on every tool call; the failure names the refused encoding. If your server compresses with Brotli regardless of Accept-Encoding, disable Brotli for it. See Responses Wetel cannot read.
Known Limitations
Section titled “Known Limitations”These are real, current platform constraints. We’d rather you plan around them than discover them mid-integration.
argsTemplate has no schema awareness
Section titled “argsTemplate has no schema awareness”Nothing validates argsTemplate against the connector’s actual inputSchema — not when you save the workflow, not before the call is made. If the external MCP server later renames a field, adds a new required one, or you simply write argsTemplate slightly wrong, nothing catches it ahead of time. The mismatch only surfaces when the tool call actually fails at runtime, reported as a NodeFailedEvent on the session subscription (or in a dashboard-side workflowRun trace, if you have access to one — see Troubleshooting).
Practical guidance:
- Never point
argsTemplateat a bare"{{someVar}}"wheresomeVaralready holds a whole pre-serialized JSON string (for example, an LLM node instructed to output raw JSON). The templating engine escapes context values as plain scalars meant to sit inside quotes you’ve already written — pointing it at an already-JSON-shaped string double-escapes it and fails to parse on every call. Instead, have the upstream node extract plain scalar values into separate variables, and write the JSON structure yourself:"argsTemplate": "{\"query\": \"{{bookQuery}}\"}". - Splicing a variable-length array of values into a tool call isn’t directly supported today. If a tool argument accepts multiple selected values (say,
resourceType: string[]) and the user’s message names more than one, there’s no way to build that array from a single context variable — every upstream variable is raw text, not a parsed array, so block-helper iteration over it just walks characters, not elements. The workaround that needs no special support: branch into parallel single-value tool calls — one call per selected value, each using the already-reliable single-scalar pattern ("resourceType": ["{{resourceType}}"]) — then merge the results in a downstreamllmnode before phrasing the reply to the user.
MCP schema drift isn’t proactively detected
Section titled “MCP schema drift isn’t proactively detected”If a connected MCP server’s tool schema changes after you registered the connector — a field renamed, a new required argument added — nothing re-validates your existing argsTemplate against it or adapts automatically. A call-time check does exist and will surface a clearer error when a mismatch is hit, but there’s no scheduled or on-demand check that scans your connectors ahead of time and flags drift before a real user hits it. If you control the upstream MCP server, treat any schema change there as a breaking change on your side too, and re-run listMcpTools plus a manual test call after any such change, rather than assuming Wetel will catch it for you.
See also
Section titled “See also”- Workflow Overview — node/edge model, including
toolandactionnode configuration. - MCP Cookbook — worked examples of registering and calling an MCP server.
- Knowledge Base — the other major way to ground an agent’s responses, via retrieval instead of tool calls.
- Troubleshooting — general error reference, including tool/action failure signals.