Connecting a voice agent to your calendar and CRM
A voice agent that cannot touch your systems is a very polite answering machine. The moment it can check a calendar, create a contact or look up an order, it starts doing work. There are three ways to connect it, and they solve different problems: tools the agent calls during the conversation, MCP servers that offer many tools at once, and webhooks that tell your systems what happened afterwards.
Three connections, three directions
Think of the agent as a colleague on the phone.
An HTTP tool is something the colleague can do while talking: "let me check what's free on Thursday". The agent decides to call it, fills in the parameters from the conversation, waits for the answer, and carries on. You define each tool yourself: a name, a description, typed parameters, and the HTTP request to make.
An MCP server is a box of tools someone else has already built. You give the agent the server's address and it discovers what is inside: calendar, CRM, ticketing, whatever the server offers. Good when a vendor or your own team already runs one.
A webhook points the other way. The agent does not call it; NordTell posts to your server when something happens: call.started, call.answered, call.ended, call.completed, plus lead and agent events. This is how a call's summary, outcome and collected fields land in your CRM without anyone typing. If your calendar already has a ready-made connection in the agent editor, use that first; the tools below are for everything else.
A calendar tool, step by step
Booking needs two tools, not one: check availability, then book. Splitting them keeps the agent honest, because it can only say "booked" after the second tool has returned success. Here is a check-availability tool the way you would define it. The shape is what matters; the field labels in your editor may differ slightly.
name: check_availability
description: Returns free slots for one day. Call this before offering
any time to the caller. If nothing is free, offer the
next day. Do not invent times.
method: GET
endpoint: https://api.example.com/slots?date={{date}}&service={{service}}
headers: Authorization: Bearer YOUR_TOKEN
parameters:
date (string, required) The day, as YYYY-MM-DD.
service (string, required) One of: consultation, follow_up.
The booking tool is the same idea with POST, a body template such as {"start": "{{start}}", "name": "{{name}}", "phone": "{{phone}}"}, and a description that says plainly: "Call this to actually book. Never tell the caller it is booked until this returns success."
Two rules for the endpoint on your side. Answer fast: the caller waits in silence while the tool runs, so keep it well under a couple of seconds. And return short, plain results ("Free: 09:00, 10:30, 14:00") rather than a page of JSON. The agent has to read the result and speak it.
One more thing: the description is the real interface. The parameter types stop bad input, but the description decides whether the tool is used at all, and when. Write it for a smart new employee. "Gets slots" is bad. "Returns free appointment slots for one day. Use it whenever the caller asks for a time." is good. An agent with ten vaguely described tools picks the wrong one; the same agent with three well-described tools rarely does.
CRM: write after the call, not during
It is tempting to have the agent update the CRM live. Usually it is better to let the call finish and act on the call.completed webhook. You get the whole picture at once: transcript, summary, outcome, the fields the agent collected, and the minutes used. Your handler creates or updates the contact, logs the call, and sets the next step.
Verify the signature before you trust the payload. Each delivery is signed with your endpoint's secret using HMAC-SHA256 and sent in an X-Webhook-Signature header as "sha256=β¦". Compute the same over the raw body and compare. Make the handler idempotent too: use the call's id as the key, so a retried delivery does not create two contacts.
Live tools during the call are still right for the things the caller needs an answer to now: "is my order shipped", "is Thursday free". Everything else can wait five seconds. The speed-to-lead playbook is a complete example of this pattern: API in, webhook out.
Testing the whole chain
Test in the browser with a microphone before a number is attached. Ask for a slot you know is taken and listen for the refusal. Ask to book and check that the row appears in your calendar before the agent says so. Then pull the plug on your endpoint and see what the agent says when the tool times out. It should apologise and offer a person, not pretend. Finally, read your server log for the test call and check every parameter the agent filled in; a wrong date format is the classic bug. A fuller list is in our test plan, and the reasons this discipline matters are in stopping a voice agent from bluffing.
Where NordTell fits
NordTell agents call your own HTTP tools with typed parameters, connect to any MCP server, and use built-ins for transfer, end call, SMS and the current time. Webhooks for call, lead and agent events are signed with your secret, and the REST API takes an X-API-Key header with scoped keys. The agent never says "booked" before the calendar tool has confirmed.