The endpoint
The Connect an AI assistant panel in Configurations → Integrations → REST API shows that
address ready to copy, once the workspace has a key with MCP access. It shows the platform
address above for every workspace, including one whose people reach DMLY on an agency’s own
domain. Connecting over OAuth uses the same address and needs nothing minted first, so if that
is your route, the panel never appears and you do not need it: the address above is the whole
thing you give the client.
What the server can do
Tools are task-shaped, not one-per-endpoint, and responses are trimmed for a model’s context rather than mirroring REST payloads. Every one of the 37 is listed in the tools reference; this is the shape of the surface. Workspace. An orientation snapshot: business name, timezone, which channels are connected and whether each can actually send right now, contact usage, open conversations, today’s bookings. A client is told to call this first. Contacts and CRM. Search people by name, phone, email, handle, tag, saved segment or lifecycle stage; pull one contact’s full picture (tags, custom fields, reachable channels, recent notes, upcoming bookings, unpaid invoices). Writing adds contacts, corrects details, applies and removes tags, writes internal notes, and moves someone between lead, client, inactive and archived. Conversations. Triage the inbox by open/done, unread or platform, and read a thread as a transcript. Writing assigns a conversation to a teammate or marks it handled. Messaging. Send a freeform reply on whichever channel the contact last spoke on, or send one of the workspace’s Meta-approved WhatsApp templates when the 24-hour window has closed. Appointments. Find open slots for a service (the same availability engine the booking page uses, so notice periods, buffers, time off and the connected calendar all apply), list the diary, then book, reschedule or cancel. Finance. List invoices and what is still owed, summarise revenue for a period, create a draft invoice, deliver it to the client on WhatsApp, and record money already received. Broadcasts. Work out exactly who a broadcast would reach and freeze that audience, then queue it for a human to approve. Nothing goes out from here (see below). Automations. List flows and quick automations with their trigger, channel and run counts, inspect individual runs to see why one failed or parked, and switch an automation on or off.MCP or the REST API?
Both hit the same platform and the same workspace-scoped data, and both accept admly_ key;
MCP also accepts an OAuth sign-in, which the REST API does not. They are built for different
callers.
Use the REST API when you know the exact sequence of calls. Use MCP when you want a model to
work it out. Nothing stops you doing both from the same workspace with two different keys.
The safety model
This is the part worth reading before you connect an agent to a real workspace. The workspace comes from the credential, never from a tool argument. No tool accepts a workspace id. With an API key, the key is the workspace, and it also remembers the member who generated it: removing that teammate from the workspace stops the key reaching/mcp at all (every
request answers 403), though the same key keeps working on the REST
API, so revoking the key is the one lever that stops both. With OAuth, the
workspace is chosen by a human on the consent screen and recorded against that (user, client)
pairing; a token whose pairing has no recorded consent is refused rather than defaulted to the
user’s first workspace, and membership is re-checked on every request, so someone removed from
a workspace loses access without anyone having to delete the connection.
What a connection may do depends on how it authenticated, and either way the limit is
enforced by tools not existing. A tool a connection is not entitled to is never registered:
it is absent from tools/list, and calling it by name anyway answers not found, because the
server resolves a call through the same eligibility check as the listing. The model has no send
button to reach for and cannot be talked into finding one.
- An API key carries
mcp:read,mcp:write, or neither. Keys minted before MCP existed carry neither and stay REST-only.mcp:readregisters up to 16 tools,mcp:writeup to all 37 and implies read. The scope is a ceiling rather than the whole story: a key generated in DMLY records the member who generated it, and on this path it resolves that member’s dashboard permissions too, so it can never reach a tool they could not use themselves. Their role is read live on every request, so narrowing it narrows the key on its next call. Most keys are generated by an owner or an admin, who hold every permission, and for those the scope really is the only limit; a key generated by a custom role is bounded by that role as well. - An OAuth connection carries a single scope,
mcp:use, and that scope authorises nothing on its own; the team role is the whole gate. The connection acts as the person who approved it and gets exactly the tools their role grants in the dashboard: an owner or admin gets all 37, a plain member gets 33 (everything except the four team-diary appointment tools), a viewer gets 15 reads, a custom role gets what is ticked for it. A connection cannot reach a tool its owner’s role does not grant, and narrowing someone’s role narrows their connection with it. See What an OAuth connection may do.
That extends to customer PII: if the acting member’s role withholds
contacts.view_phone
or contacts.view_email, phone numbers and email addresses come back masked over MCP too,
just as they are in the contact list, the inbox and the mobile app. This applies on both paths:
over OAuth the acting member is the person who connected, and on a key it is the member who
generated it. Masking covers the contact a write tool echoes back as well, so create_contact
and update_contact cannot be used to read a withheld number out. The
REST API is the exception: the same key masks nothing there.submit_broadcast does not send. It creates the
broadcast marked as requiring approval, returns sent: false, and says so. Somebody with
permission has to approve it in the DMLY dashboard before anyone is messaged. That flag is
not an input the model can set. The audience is the exact recipient list frozen by
preview_broadcast, so it cannot drift between the preview a human read and the send.
Outbound messages are budgeted, and metered where they actually leave. Every message an
AI-initiated call causes is counted at the send chokepoint, not in the tool, so the
confirmation that goes out when the model books an appointment, and the three messages an
automation fires off the back of a tag, all count too. There is an hourly send cap and a
rolling 24-hour cap on distinct people reached, per workspace. Past either one, sends are
refused with a message naming the limit and telling the user to finish from the dashboard.
Customer text is fenced. Message bodies, notes, custom-field values and captured flow
answers arrive wrapped in an <untrusted_customer_content> tag, and the server’s instructions
tell the model to report what is inside it, never to follow it.
Writes are audited. Every write is recorded against the workspace’s audit log as
mcp.<tool name>. Over OAuth the row is attributed to the person who connected. On a key nobody
is signed in, so Who reads System, and nothing shown on the row identifies the key or the
member whose permissions it resolved. What names the client is the mcp.session_started row
written when it connected, so read that alongside the writes that follow it. See Audit
log.
Plan gating and availability
The MCP server is a plan feature, and a plan that doesn’t set it either way is treated as including it. A workspace whose plan explicitly excludes it gets403 on every request with
Your plan does not include the MCP server. This is not one of the rows in the Change
subscription plan panel, so you cannot confirm it there: if you need to know before buying,
ask whoever sells you DMLY, or your agency for a sub-account. See
What a plan governs.
DMLY can also take the MCP server offline fleet-wide during an incident, without revoking
anyone’s key. That returns 503 with The MCP server is currently unavailable. It is not
something you have done wrong, and it clears on its own.
Integrating MCP clients
Sign in with OAuth or mint a scoped key, then read the failure responses.
MCP tools reference
All 37 tools and 4 resources, with arguments, key scope and team permission.
REST API
The full endpoint surface for your own integrations.
Connect Claude
The same server, explained for the person running the business.

