Skip to content

MCP Connectors

This content is not available in your language yet.

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.

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.

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.

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.

These are real, current platform constraints. We’d rather you plan around them than discover them mid-integration.

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 argsTemplate at a bare "{{someVar}}" where someVar already 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 downstream llm node 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.

  • Workflow Overview — node/edge model, including tool and action node 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.