<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dialog Brain</title>
    <description>The latest articles on DEV Community by Dialog Brain (@dialogbrain).</description>
    <link>https://dev.to/dialogbrain</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4104153%2Fd605cd82-26c7-48fe-aabd-1f01469fc643.png</url>
      <title>DEV Community: Dialog Brain</title>
      <link>https://dev.to/dialogbrain</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dialogbrain"/>
    <language>en</language>
    <item>
      <title>How to stop your AI chatbot making up answers</title>
      <dc:creator>Dialog Brain</dc:creator>
      <pubDate>Tue, 27 Oct 2026 08:30:00 +0000</pubDate>
      <link>https://dev.to/dialogbrain/how-to-stop-your-ai-chatbot-making-up-answers-26ak</link>
      <guid>https://dev.to/dialogbrain/how-to-stop-your-ai-chatbot-making-up-answers-26ak</guid>
      <description>&lt;p&gt;&lt;em&gt;A chatbot makes up answers when a customer asks something nobody taught it, and however carefully you teach an AI agent about your business, customers will ask it something you never wrote down. What matters is what happens next: whether it guesses, or tells you, and whether you find out once, or never.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Every agent meets a question it was never taught
&lt;/h2&gt;

&lt;p&gt;You wrote down your prices, your hours, your delivery zones. Then on day two someone asks whether you deliver on Sundays, whether they can bring a dog, whether you take card payments over the phone. None of it is in the instructions, because nobody thinks of everything in advance.&lt;/p&gt;

&lt;p&gt;An agent in that position can do one of two things. It can guess, and a confident wrong answer about a price or an opening time is worse than no answer. Or it can say it will check with the team. The second is right, but on its own it leaves you nothing: the same question arrives next week, and the week after, and you only notice when a customer complains.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turning “I don’t know” into a list you can act on
&lt;/h2&gt;

&lt;p&gt;DialogBrain closes that loop. When the agent cannot find the answer in your knowledge base, it is told not to guess but to answer the customer the way your instructions say, and it also notes the question for you.&lt;/p&gt;

&lt;p&gt;Those notes go into one list in your workspace. Customers ask the same thing in many ways, “how much is shipping?”, “is delivery free?”, “what does it cost to deliver to my area?”, so questions that mean the same thing are gathered into one row with a count beside it. The row asked forty times sits at the top; the one-off question sits at the bottom. You see at a glance which missing answer costs you the most replies.&lt;/p&gt;

&lt;p&gt;Questions that only look alike are kept apart. “When do you open?” and “when do you close?” use nearly the same words and need different answers, so they stay separate rows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Answer once, in your own words
&lt;/h2&gt;

&lt;p&gt;Opening a row shows how customers actually phrased it and links to each conversation. You write a short title and the answer, and save it. From that moment it is part of your knowledge base: the next customer who asks, in whatever words and whichever language, gets your answer from the agent.&lt;/p&gt;

&lt;p&gt;Nothing is sent to the people who already asked, the answer is for everyone after them. And the title is yours, not a copy of a customer’s message, so a name, a phone number or anything else someone typed never ends up in the material your agent reads.&lt;/p&gt;

&lt;p&gt;If a question keeps coming back after you answered it, the list says so: the answer is there, but the agent did not connect it to the way people ask. Rewording the question, and the answer, if needed, in the customers’ own words usually fixes it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The agent now finds your documents in a busy inbox
&lt;/h2&gt;

&lt;p&gt;While building this we found a second reason agents sometimes said “I don’t know”: the answer was in a document the owner had uploaded, and the agent still did not see it.&lt;/p&gt;

&lt;p&gt;When an agent looks something up, it searches your documents and your past conversations together. In a workspace with years of chats, those conversations are thousands of short messages, and many of them sound a little like any question, “are you open today?”, “what time?”. They crowded the one handbook page with the real answer out of the search before it was ever weighed.&lt;/p&gt;

&lt;p&gt;Now documents and conversations are searched separately, and your documents are always given room in what the agent reads. The handbook page is found again, and so is every answer you add from the list of unanswered questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it takes from you
&lt;/h2&gt;

&lt;p&gt;About five minutes a week. Open the list, answer the two or three rows at the top, hide the ones that are not about your business. After a few weeks the list is short and your agent answers most of what customers ask on its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions and answers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why does my AI chatbot say “I don’t know” when the answer is in my documents?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Often because years of short chat messages crowded your documents out of its search, so the page with the answer was never read. DialogBrain now searches documents and conversations separately and always gives your documents room, so that page is found again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will the AI agent make up an answer it does not know?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is instructed not to: when your knowledge base has no answer, it notes the question for you and replies the way your instructions say. But it can only fall back well if you tell it how, add one line to its instructions, for example: “If you don’t know, say a colleague will reply shortly.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I have to answer every question?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Answer the ones at the top of the list, they cover most of what customers ask. Hide the ones that are not about your business, and they stop coming back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does the customer who asked get my answer?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not automatically. The answer goes into your knowledge base for everyone who asks after that. If someone is still waiting, the list links to their conversation so you can reply yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it work in other languages?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. Questions asked in different languages about the same thing are grouped together, and the agent answers each customer in the language they wrote in.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://dialogbrain.com/articles/ai-agent-unanswered-questions" rel="noopener noreferrer"&gt;dialogbrain.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chatbot</category>
      <category>rag</category>
      <category>llm</category>
    </item>
    <item>
      <title>Giving an AI agent its own IP address</title>
      <dc:creator>Dialog Brain</dc:creator>
      <pubDate>Sun, 25 Oct 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/dialogbrain/giving-an-ai-agent-its-own-ip-address-36b5</link>
      <guid>https://dev.to/dialogbrain/giving-an-ai-agent-its-own-ip-address-36b5</guid>
      <description>&lt;p&gt;&lt;em&gt;An agent that logs into sites on your behalf arrives from a datacenter, and the sites can tell. You can now hand it your own WireGuard, OpenVPN or residential proxy, for the whole workspace, or for one identity at a time.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem is the address, not the agent
&lt;/h2&gt;

&lt;p&gt;An AI agent that works in a browser does everything a person does, opens a site, signs in, clicks, reads, replies. What it cannot do by itself is arrive from a plausible place. It arrives from a cloud provider’s address range, which any consumer site can look up in a public database, and which no ordinary customer of that site has ever used.&lt;/p&gt;

&lt;p&gt;That single fact produces most of the friction people blame on automation being "detected". Extra verification on login. A sign-in that works from your laptop and fails from the agent. Two accounts that should have nothing to do with each other treated as one, because both were reached from the same address.&lt;/p&gt;

&lt;p&gt;None of that is about how convincingly the agent behaves. It is about where it came from, and it is fixed in one place rather than by making the agent act more human.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bring your own exit
&lt;/h2&gt;

&lt;p&gt;A workspace can now leave the network in one of three ways: directly, through a residential proxy you supply, or through a VPN profile you upload, WireGuard or OpenVPN, whichever your provider gives you.&lt;/p&gt;

&lt;p&gt;You paste the provider’s config as-is. It is encrypted with a key scoped to your workspace, and no endpoint returns it, the form is empty when you reopen it because there is genuinely nothing to show, including to you.&lt;/p&gt;

&lt;p&gt;Configs are checked against an allowlist rather than trusted. WireGuard’s PostUp and PreUp, and their OpenVPN equivalents, run shell commands on the machine that loads them; a config carrying one is refused, naming the directive it tripped on. That is a deliberate refusal of a real capability, not a parser limitation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Interface]&lt;/span&gt;
&lt;span class="py"&gt;PrivateKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;from your provider&amp;gt;&lt;/span&gt;
&lt;span class="py"&gt;Address&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;10.66.66.2/32&lt;/span&gt;
&lt;span class="py"&gt;DNS&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;1.1.1.1&lt;/span&gt;
&lt;span class="py"&gt;MTU&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;1280&lt;/span&gt;

&lt;span class="nn"&gt;[Peer]&lt;/span&gt;
&lt;span class="py"&gt;PublicKey&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;from your provider&amp;gt;&lt;/span&gt;
&lt;span class="py"&gt;AllowedIPs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;0.0.0.0/0&lt;/span&gt;
&lt;span class="py"&gt;Endpoint&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;frankfurt.example-vpn.com:51820&lt;/span&gt;

&lt;span class="c"&gt;# Paste the file as your provider shipped it.
# PostUp / PreUp lines are refused, not run: they
# execute shell, and nothing here needs them.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  One exit per account, not one per company
&lt;/h2&gt;

&lt;p&gt;The interesting setting is not the workspace default, it is the override on a single browser identity. Each identity can take its own VPN profile, so the account you keep in Frankfurt is reached from Frankfurt and the one in Amsterdam from Amsterdam, while everything else goes direct.&lt;/p&gt;

&lt;p&gt;That is the difference between "our company uses a VPN" and "these two accounts have never shared an address". For anyone running more than one presence on the same platform, the second is the only version that means anything.&lt;/p&gt;

&lt;p&gt;The resolution order is short, and its middle step is the one people get wrong: an identity with no setting inherits the workspace default. It does not mean direct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;the identity's own setting
  ↓  (unset, which means inherit, never "direct")
the workspace default
  ↓  (unset)
direct

# At every step, if the chosen exit cannot be produced,
# the request FAILS. It never quietly falls back to ours.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  It covers the API calls too
&lt;/h2&gt;

&lt;p&gt;A browser session is the visible half. The other half is every outbound call your workspace makes to a third-party API: OAuth token exchange and refresh, connection tests, API-spec discovery, the MCP transport an assistant speaks over, and the tool calls themselves.&lt;/p&gt;

&lt;p&gt;Those requests reach the same provider the browser session does. Leaving them on a datacenter address would both expose the address you are paying to hide and break any provider that ties a session to the IP that created it, the token minted from one place, used from another.&lt;/p&gt;

&lt;p&gt;One boundary is worth stating plainly, because it is the opposite of what people assume: an integration bound to a browser identity for its cookies still takes its network path from the workspace default. Cookies from the identity, IP from the workspace.&lt;/p&gt;

&lt;h2&gt;
  
  
  It fails closed
&lt;/h2&gt;

&lt;p&gt;If the chosen exit cannot be produced, the tunnel will not come up, the proxy is switched off, the selected profile was deleted, the request fails. There is no quiet fallback to our address.&lt;/p&gt;

&lt;p&gt;This is the part worth insisting on. A silent fallback is the worst possible behaviour: it puts the datacenter address on the wire for exactly the workspace that is paying not to be there, at exactly the moment nobody is watching, and you find out from the other end, from the account that got flagged.&lt;/p&gt;

&lt;p&gt;So a broken exit is loud. The card says so while collapsed, the status pill in the header turns red at any screen width, and a test that has never run reads as unproven rather than green. Green means a live test went out through that exact tunnel and came back with an address.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a tunnel costs you
&lt;/h2&gt;

&lt;p&gt;Nothing while idle. A tunnel is started when something needs it and shut down after about fifteen minutes of quiet, so there is no permanent connection to pay for and no stale tunnel left holding a route. The first request after a gap waits for the tunnel to come up, measured at about four seconds.&lt;/p&gt;

&lt;p&gt;A word on free VPNs, since it is the first thing people try: they work for confirming the feature does what it says, and they are a poor production exit. Every user shares one address, so the sites you care about have already rate-limited it, and you do not get to choose a country. A dedicated exit exists precisely to not be shared.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions and answers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does this hide that an AI agent is doing the work?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No, and it is not meant to. It changes where the traffic comes from, not what the agent does or discloses. What it removes is a mismatch that has nothing to do with the work: a real account, operated on your behalf, arriving from an address no customer would ever use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WireGuard or OpenVPN?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Both work; paste whichever your provider gives you. WireGuard connects faster and its config is a dozen lines, which is why most providers now lead with it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use a different country per account?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, that is what the per-identity override is for. Upload one profile per exit, then point each browser identity at the one it should use. A workspace holds up to five profiles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens to my running browser sessions when I switch?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They are rebuilt against the new exit rather than kept on the old one, the exit is part of what makes a pooled session reusable, so changing it retires the session instead of leaving it running on the address you just stopped using. Allow about a minute: the resolver caches the answer for that long, so a session already in flight can finish on the old exit before the new one takes over.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who can change it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Only a workspace owner. Members see the current state; the public viewer tier sees none of it. Changing where an entire workspace appears from is not a setting to leave open to everyone who can read the inbox.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://dialogbrain.com/articles/ai-agent-own-ip-address" rel="noopener noreferrer"&gt;dialogbrain.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>networking</category>
      <category>proxy</category>
      <category>automation</category>
    </item>
    <item>
      <title>respond.io vs SleekFlow vs Wati: what each one charges for, and where each one stops</title>
      <dc:creator>Dialog Brain</dc:creator>
      <pubDate>Fri, 23 Oct 2026 08:59:07 +0000</pubDate>
      <link>https://dev.to/dialogbrain/respondio-vs-sleekflow-vs-wati-what-each-one-charges-for-and-where-each-one-stops-pln</link>
      <guid>https://dev.to/dialogbrain/respondio-vs-sleekflow-vs-wati-what-each-one-charges-for-and-where-each-one-stops-pln</guid>
      <description>&lt;p&gt;Most comparisons of WhatsApp inbox tools list features in a grid and stop there. The grid hides the part that decides the bill: what each product counts. One counts seats and active contacts, one counts channels, one sells the AI agent as an add-on. This post walks through respond.io, SleekFlow and Wati on the questions that usually come up when a small team picks one, using their public pricing and help pages as of October 2026.&lt;/p&gt;

&lt;p&gt;Disclosure: I work on DialogBrain, which competes with all three. I'll say where each of them fits better than we do.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you pay for
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;respond.io&lt;/strong&gt; is built around tiers: Starter $99, Growth $199, Advanced $349 a month ($79, $159 and $279 billed yearly). Each tier comes with a set number of users and monthly active contacts, and WhatsApp fees are on top. The trial is 7 days.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SleekFlow&lt;/strong&gt; prices by region. On its ASEAN page, Pro is US$99 a month with 3 seats, 1,000 active contacts and 3 channels; Premium is US$299 with 10 seats and 10 channels; an extra seat is US$30. The WhatsApp Business Platform adds US$10 a month per number plus conversation rates. Also a 7-day trial.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wati&lt;/strong&gt; has Growth, Pro and Business. Growth has 3 users and no way to add more; Pro and Business have 5, with extra seats at $24 and $69 a month. Message fees follow Wati's rate card.&lt;/p&gt;

&lt;p&gt;The thing to check before you compare prices: which limit will you hit first? A team of two with heavy inbound traffic hits active contact limits. A shop selling on WhatsApp, Instagram, Telegram and a website chat hits a 3-channel cap. A team of four on Wati Growth hits the seat limit, because Growth has none to add.&lt;/p&gt;

&lt;h2&gt;
  
  
  The AI agent: included or an upgrade?
&lt;/h2&gt;

&lt;p&gt;This is where the three differ most.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;respond.io: AI Agents start on Growth. Starter has none.&lt;/li&gt;
&lt;li&gt;SleekFlow: AI agents from Pro; AI agents that call your integrations from Premium.&lt;/li&gt;
&lt;li&gt;Wati: the agent is called Astra. Not on Growth, a separately priced add-on on Pro, included on Business.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the reason you are shopping is "we want an AI agent to answer the first message at 3 a.m.", the entry plan of each of these will not do it, and the real starting price is one tier up.&lt;/p&gt;

&lt;h2&gt;
  
  
  WhatsApp: API only
&lt;/h2&gt;

&lt;p&gt;All three are built on the official WhatsApp Business Platform (the API). That is the right route for template broadcasts and click-to-WhatsApp ads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Telegram
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;respond.io: bots created through BotFather only. Its help center says a Telegram Business account cannot be added.&lt;/li&gt;
&lt;li&gt;SleekFlow: one bot, created through BotFather.&lt;/li&gt;
&lt;li&gt;Wati: Telegram is not among its channels.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your customers write to a person on Telegram (common in Eastern Europe, the Middle East and parts of Asia), none of the three connects that account. A bot is a different contact with no history.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calls
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;respond.io lists calls, AI voice calls and call transcripts on its pricing page.&lt;/li&gt;
&lt;li&gt;SleekFlow lists VoIP calls and local number hosting as not available at the moment.&lt;/li&gt;
&lt;li&gt;Wati supports WhatsApp Business Calling, answered by Astra and handed to the team.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  API and automation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;respond.io: developer API and Zapier or Make from Growth; webhooks and HTTP requests in workflows from Advanced.&lt;/li&gt;
&lt;li&gt;SleekFlow: webhooks and HTTP requests in flows from Premium; Shopify, HubSpot and Salesforce integrations depending on the plan.&lt;/li&gt;
&lt;li&gt;Wati: no webhooks on Growth, limited on Pro, extensive on Business.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where each one fits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;respond.io&lt;/strong&gt; fits large teams that run on broadcasts and deep workflow automation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SleekFlow&lt;/strong&gt; fits commerce teams in Asia that want Shopify and CRM integrations and click-to-chat ads out of the box.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wati&lt;/strong&gt; fits a team whose whole business is WhatsApp marketing: click-to-WhatsApp ads, broadcasts and a Shopify store.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where DialogBrain is different
&lt;/h2&gt;

&lt;p&gt;Since I work on it, here is the short version, and you can check it against the tables linked below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Priced per connected channel: $20 a month per channel, $5 per extra teammate (the owner's seat is free), AI usage paid as used. No tiers, so nothing is held back for a higher plan. 14 days free, no card.&lt;/li&gt;
&lt;li&gt;The AI agent is on every account and every channel, answering from your website and files and handing the chat to a person when it is unsure.&lt;/li&gt;
&lt;li&gt;WhatsApp either way: link the number you already use by QR, with its chats and groups, or connect a Business API number. Both can sit side by side.&lt;/li&gt;
&lt;li&gt;Telegram as your own account, with real chats, groups and calls, or as a bot.&lt;/li&gt;
&lt;li&gt;The same agent answers calls on Twilio or Telnyx numbers, Telegram and WhatsApp, and joins Google Meet or Microsoft Teams to write the transcript.&lt;/li&gt;
&lt;li&gt;REST API, webhooks and a hosted MCP server on every account.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Side-by-side tables with the sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dialogbrain.com/respond-io-alternative" rel="noopener noreferrer"&gt;DialogBrain vs respond.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dialogbrain.com/sleekflow-alternative" rel="noopener noreferrer"&gt;DialogBrain vs SleekFlow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dialogbrain.com/wati-alternative" rel="noopener noreferrer"&gt;DialogBrain vs Wati&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If what you need is an agent on the phone line rather than the chat, there is a separate page on the &lt;a href="https://dialogbrain.com/ai-phone-agent" rel="noopener noreferrer"&gt;AI phone agent&lt;/a&gt;, and for a support desk across channels, the &lt;a href="https://dialogbrain.com/ai-customer-support-agent" rel="noopener noreferrer"&gt;AI customer support agent&lt;/a&gt;. For a shop that wants one chat on the site and in messengers: &lt;a href="https://dialogbrain.com/live-chat-for-online-store" rel="noopener noreferrer"&gt;live chat for an online store&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Prices change, and SleekFlow's vary by region. If you spot something out of date, say so in the comments and I will correct it.&lt;/p&gt;

</description>
      <category>whatsapp</category>
      <category>customersupport</category>
      <category>saas</category>
      <category>ai</category>
    </item>
    <item>
      <title>How to connect WhatsApp, Telegram and email through ChatGPT or Claude</title>
      <dc:creator>Dialog Brain</dc:creator>
      <pubDate>Thu, 22 Oct 2026 09:30:00 +0000</pubDate>
      <link>https://dev.to/dialogbrain/how-to-connect-whatsapp-telegram-and-email-through-chatgpt-or-claude-4a5f</link>
      <guid>https://dev.to/dialogbrain/how-to-connect-whatsapp-telegram-and-email-through-chatgpt-or-claude-4a5f</guid>
      <description>&lt;p&gt;&lt;em&gt;Connecting your channels no longer means finding your way around settings. Tell ChatGPT, Claude or Claude Code what you use and it sets it up: it connects what can be connected from the chat, and for the rest it sends you a link straight to the right screen.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ask for it the way you would ask a colleague
&lt;/h2&gt;

&lt;p&gt;DialogBrain puts your WhatsApp, Telegram, Instagram, email and website chat into one inbox, with an AI agent that answers customers. Until now, setting that up meant a sign-up wizard and a settings page.&lt;/p&gt;

&lt;p&gt;If you already spend your day in an AI assistant, you can now do it from there. You do not need to know where anything is in DialogBrain, you describe what you want, and the assistant does the settings and tells you when it is done.&lt;/p&gt;

&lt;p&gt;These are ordinary requests it understands, and you can paste them as they are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connect my WhatsApp and my work email.

Put a chat widget on example.com. Only allow my domain
and keep replies as drafts I approve.

Create an agent that answers customers on WhatsApp and
the website chat. Never promise prices, say a colleague
will confirm. Test it before it answers anyone.

Where did we lose leads this week?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Connect your assistant once
&lt;/h2&gt;

&lt;p&gt;In Claude open Settings → Connectors; in ChatGPT open Plugins → Add → Add custom MCP server, which the free plan has too. Add DialogBrain with the address below and sign in with your DialogBrain account. There is no key or password to paste into the chat, and the assistant can do only what your own account can do.&lt;/p&gt;

&lt;p&gt;In Claude Code, install the DialogBrain plugin with two commands and type /mcp to sign in. The plugin comes with ready-made step-by-step instructions for the common jobs, connecting a channel, the website chat, an agent, the task board and a weekly lead report, so Claude Code knows what to do without being told each step.&lt;/p&gt;

&lt;p&gt;The home page and the first screen after sign-up have a "Set it up from your AI tool" block that shows the exact line for your assistant, including Codex, Cursor and Gemini CLI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://api.dialogbrain.com/mcp/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;claude plugin marketplace add saloprj/dialogbrain-claude-plugin
claude plugin install dialogbrain@dialogbrain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  WhatsApp and Telegram: a link to the exact screen
&lt;/h2&gt;

&lt;p&gt;Connecting WhatsApp means scanning a QR code with the phone that owns the number, the same way you link WhatsApp Web. No assistant should do that for you, so it does not try. It sends you a link that opens DialogBrain directly on the WhatsApp step; if you are not signed in, you sign in first and land in the same place. You scan the code, and the chats start arriving.&lt;/p&gt;

&lt;p&gt;Telegram, Instagram, Facebook Messenger and a Google mailbox work the same way: a link, then a scan or a sign-in with that service. Your WhatsApp session and your Google password never pass through a chat window, if an assistant ever asks you for them, do not give them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Email and a Telegram bot: done from the chat
&lt;/h2&gt;

&lt;p&gt;A mailbox at any provider other than Google is connected right in the conversation. The assistant asks for the address, an app password and your provider's mail server names, connects the mailbox and tells you when email is arriving. Use an app password rather than your normal one, you create it in your email settings and can revoke it at any time.&lt;/p&gt;

&lt;p&gt;If your email is Gmail or Google Workspace, say so, and you get the Google sign-in link instead.&lt;/p&gt;

&lt;p&gt;A Telegram bot is connected the same way: create the bot with &lt;a class="mentioned-user" href="https://dev.to/botfather"&gt;@botfather&lt;/a&gt;, give the assistant the token it shows you, and the bot is live in your inbox.&lt;/p&gt;

&lt;h2&gt;
  
  
  A chat on your website and an agent that answers
&lt;/h2&gt;

&lt;p&gt;Ask for the website chat and the assistant creates it, restricts it to your domain and gives you two lines of code to paste before the closing  tag, or into the footer box of WordPress, Shopify or Wix.&lt;/p&gt;

&lt;p&gt;Ask for an agent and tell it what matters: what you sell, the questions people ask most, what it must never promise, and when a person should take over. The assistant writes the agent's instructions from that; ask it to test the agent and it tries a sample question and shows you the answer before the agent talks to anyone. Replies wait as drafts until you are happy to let it answer on its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  When something is blocked, it tells you why
&lt;/h2&gt;

&lt;p&gt;A colleague with view-only access who asks their assistant to connect a channel is told they do not have permission, and nothing changes. If your workspace needs a payment method before another channel can be added, the assistant or the connect screen tells you, with a link to the billing page. These are the same rules as in the app, the assistant never gets around them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions and answers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can ChatGPT connect to WhatsApp?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, through DialogBrain. Add DialogBrain as a connector in ChatGPT and ask it to connect your WhatsApp. It sends you a link to the WhatsApp step; you scan the QR code with your phone once, and from then on ChatGPT can read your WhatsApp conversations through your DialogBrain inbox and, on ChatGPT plans that let connectors take actions, reply to them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can Claude answer my customers on WhatsApp and Telegram?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Claude can set up an AI agent in DialogBrain that answers customers on WhatsApp, Telegram, Instagram, email and your website chat. You decide whether replies go out on their own or wait as drafts for your approval.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it safe to give my email password to ChatGPT or Claude?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Give an app password, never your main password. Email providers create app passwords for exactly this, and you can revoke one at any time. For Gmail and Google Workspace, use the Google sign-in link instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need Claude Code or any technical skills?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. ChatGPT and Claude on the web work fine: you add one address in their connector settings and ask in plain words. Claude Code gets a plugin with ready-made instructions, which helps if you already use it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which channels can I connect this way?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;WhatsApp, Telegram, Instagram, Facebook Messenger, email, a Telegram bot and a chat on your website all arrive in the same DialogBrain inbox. YouTube and phone numbers for voice calls can be connected too, but they need your own Google Cloud or Twilio/Telnyx account, and the link opens a short setup wizard.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://dialogbrain.com/articles/connect-whatsapp-telegram-email-through-chatgpt-or-claude" rel="noopener noreferrer"&gt;dialogbrain.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>chatgpt</category>
      <category>claude</category>
      <category>mcp</category>
      <category>whatsapp</category>
    </item>
    <item>
      <title>Telegram voice via MTProto: what the Bot API cannot do</title>
      <dc:creator>Dialog Brain</dc:creator>
      <pubDate>Tue, 20 Oct 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/dialogbrain/telegram-voice-via-mtproto-what-the-bot-api-cannot-do-39n1</link>
      <guid>https://dev.to/dialogbrain/telegram-voice-via-mtproto-what-the-bot-api-cannot-do-39n1</guid>
      <description>&lt;p&gt;&lt;em&gt;Bots cannot place, answer or join a Telegram call. This is the layer that can, the constraints it puts on you, and the three audio rules we learned from calls that went out sounding wrong.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bot API has no voice calls at all
&lt;/h2&gt;

&lt;p&gt;This is usually discovered late, after the bot is built and someone asks it to ring a customer. The Bot API can send a voice message and a video note, recordings, files with a play button. It has no method to place a call, no method to answer one, and no way to join a group voice chat.&lt;/p&gt;

&lt;p&gt;No token scope changes that. Calls are not a permission a bot can be granted; they live on a different protocol layer entirely.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# There is no such method. Not "restricted", not "beta": absent.&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://api.telegram.org/bot&lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;/getMe"&lt;/span&gt;           &lt;span class="c"&gt;# works&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://api.telegram.org/bot&lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;/sendVoice"&lt;/span&gt;       &lt;span class="c"&gt;# a voice *file*&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://api.telegram.org/bot&lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;/startCall"&lt;/span&gt;       &lt;span class="c"&gt;# 404: no such method&lt;/span&gt;

&lt;span class="c"&gt;# The Bot API surface has sendVoice and sendVideoNote: recordings.&lt;/span&gt;
&lt;span class="c"&gt;# Placing, answering or joining a live call is not part of it.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  MTProto is a user account, not a bot
&lt;/h2&gt;

&lt;p&gt;Telegram calls run over MTProto, the protocol the real clients speak. To take part, software has to sign in as a user account, the same way the desktop app does: phone number, login code, session. That has consequences worth deciding on before you build.&lt;/p&gt;

&lt;p&gt;The caller sees a person, not a bot: your account name is what rings. The account is subject to the ordinary rules of a Telegram account, including the ones about automation. And an account is a single physical line, which brings the first constraint.&lt;/p&gt;

&lt;h2&gt;
  
  
  One call at a time, and no ringing callback
&lt;/h2&gt;

&lt;p&gt;MTProto allows exactly one 1:1 call per account at a time. A second outbound call while the first is up is refused by Telegram itself, so a system that dials on demand needs either a pool of accounts or a queue, and it needs to know which account is busy before it tries.&lt;/p&gt;

&lt;p&gt;The subtler constraint is that there is no pre-pickup event. Nothing tells you "it is ringing" and then "they answered". You learn the call connected because the playback call returns normally instead of raising, and every failure mode arrives as a different exception: declined, busy, rang out, cancelled mid-ring. If your product needs an "answered" timestamp, for billing, for a follow-up, for an answering-machine rule, that return is the only edge you get.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# MTProto gives no "ringing → answered" callback. You learn the callee
# picked up because the play call returns instead of raising.
&lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;pytgcalls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;play&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chat_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;audio_stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;# returns == answered
&lt;/span&gt;    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/internal/voice/call-answered&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;call_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;call_id&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;CallDeclined&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                                &lt;span class="c1"&gt;# they pressed decline
&lt;/span&gt;    &lt;span class="n"&gt;outcome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;declined&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;CallBusy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                                    &lt;span class="c1"&gt;# already on a call
&lt;/span&gt;    &lt;span class="n"&gt;outcome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;busy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;TimedOutAnswer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                              &lt;span class="c1"&gt;# rang out
&lt;/span&gt;    &lt;span class="n"&gt;outcome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;no_answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;CallDiscarded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                               &lt;span class="c1"&gt;# cancelled mid-ring
&lt;/span&gt;    &lt;span class="n"&gt;outcome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cancelled&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Group voice chats are a different animal
&lt;/h2&gt;

&lt;p&gt;A group voice chat is not a 1:1 call with more people. The agent joins as a named, visible participant, hears each speaker separately, and can speak into the room. That is what makes an assistant in a team call useful: it can attribute what was said to who said it, answer when addressed, and translate for one participant without translating for everyone.&lt;/p&gt;

&lt;p&gt;It is also why an account already sitting in a group call will busy-decline personal calls: to Telegram it is on a line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bridging the audio is where it actually gets hard
&lt;/h2&gt;

&lt;p&gt;Getting into the call is a week. Sounding right is the rest. Our agent lives in a media room; the call lives on Telegram; something has to carry frames between them. We wrote that bridge four times, Telegram, WhatsApp, Twilio, the browser, and fixed the same three defects in each, once per channel, before we made the rules shared.&lt;/p&gt;

&lt;p&gt;Route by participant identity, never by "everything that is not me is the agent". A bridge that assumes the rest of the room is one speaker will happily interleave a human operator with the agent the moment somebody takes over a call. We shipped exactly that: the operator sounded rasping for four months.&lt;/p&gt;

&lt;p&gt;Let exactly one browser publisher through, latest wins. Two tabs overlap for a second on every take-over; consuming both corrupts shared resampler state and produces audio nobody can debug from a log.&lt;/p&gt;

&lt;p&gt;Mix several sources sample-wise with int16 saturation, never by concatenating into one queue. This is the one that passes every unit test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Rule 3, the one that sounds fine in tests and wrong on a call.
# Two sources are summed sample-wise with int16 saturation, never
# concatenated into one queue: a 10 ms interleave is audible as crackle
# even when one of the two sources is pure silence.
&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;audioop&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tts_chunk&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;audioop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rms&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;        &lt;span class="c1"&gt;# silence: return the chunk as is
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tts_chunk&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tts_chunk&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;      &lt;span class="c1"&gt;# never mix mismatched lengths
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tts_chunk&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;audioop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tts_chunk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;audioop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mul&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gain&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  And the rates will get you
&lt;/h2&gt;

&lt;p&gt;Telegram audio is 48 kHz; agent rooms commonly run at 16 kHz. Every boundary needs a resampler, and, the part that is easy to miss, the amount you push per tick has to equal the amount of time that tick represents.&lt;/p&gt;

&lt;p&gt;We once fed a bridge 10 ms of audio every 20 ms. Nothing errored. Every log line was healthy, the room state was healthy, the transcript was fine. The voice trembled, and only a person listening could say so. Feed rate is not something you can assert in a unit test; put a real ear on the call before you ship one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pytgcalls speaks 48 kHz. The agent room runs at 16 kHz.
# Resample at the boundary, and push exactly one tick's worth per tick:
#   48000 samples/s * 0.020 s * 2 bytes = 1920 bytes per 20 ms
#
# Push 960 bytes on a 20 ms tick and the caller hears a trembling,
# warbling voice: you are feeding at half real time. We shipped that
# bug once and only an ear caught it: every log line looked healthy.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Or do none of this
&lt;/h2&gt;

&lt;p&gt;All of the above is why we sell it. Connect a Telegram account once, then a call is one request: the agent dials, greets, holds the conversation, and the transcript lands in the same conversation as your text history with that contact.&lt;/p&gt;

&lt;p&gt;The same endpoint reaches a group voice chat with an &lt;a class="mentioned-user" href="https://dev.to/name"&gt;@name&lt;/a&gt;, a WhatsApp number, a phone number in E.164 or a Google Meet link, the target string decides the channel.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.dialogbrain.com/v1/calls &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-API-Key: &lt;/span&gt;&lt;span class="nv"&gt;$DIALOGBRAIN_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Idempotency-Key: call-9f21c7"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "agent_id": 118,
    "target": "telegram:123456789",
    "greeting": "Hi, this is the assistant calling about your order."
  }'&lt;/span&gt;

&lt;span class="c"&gt;# 202 Accepted&lt;/span&gt;
&lt;span class="c"&gt;# {"call_id":"7a6d…","status":"dialing","channel":"telegram",&lt;/span&gt;
&lt;span class="c"&gt;#  "target":"telegram:123456789","thread_id":6808472}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Questions and answers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can a Telegram bot make or answer voice calls?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. The Bot API has no call methods at all, it can send voice messages and video notes, which are recordings. Live calls require an account speaking MTProto, the protocol the regular Telegram clients use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is MTProto and why is it needed for calls?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MTProto is Telegram’s own client protocol. Voice calls, group voice chats and their media negotiation live there, not in the HTTP Bot API, so participating means signing in as a user account rather than as a bot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How many Telegram calls can one account handle at once?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One 1:1 call at a time. Telegram refuses a second concurrent call on the same account, so concurrency needs several accounts or a queue, and the dispatcher has to know which account is busy before dialling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you detect that the callee picked up?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is no pre-pickup callback. The playback call returning normally is the answer signal; declined, busy, rang out and cancelled each arrive as a distinct exception instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can an AI agent join a Telegram group voice chat?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. It joins as a named participant, hears speakers individually, can answer when addressed and can translate the conversation live. An account in a group call will busy-decline personal calls while it is there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I have to build the MTProto side myself?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. DialogBrain connects your Telegram account and exposes calls as one API request: POST /v1/calls with an agent id and a target such as telegram:123456789 for a person or &lt;a class="mentioned-user" href="https://dev.to/group"&gt;@group&lt;/a&gt; for a group voice chat.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://dialogbrain.com/articles/telegram-voice-mtproto" rel="noopener noreferrer"&gt;dialogbrain.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>telegram</category>
      <category>voip</category>
      <category>python</category>
      <category>ai</category>
    </item>
    <item>
      <title>How to get WhatsApp and Telegram messages in Claude Code</title>
      <dc:creator>Dialog Brain</dc:creator>
      <pubDate>Sun, 18 Oct 2026 08:00:00 +0000</pubDate>
      <link>https://dev.to/dialogbrain/how-to-get-whatsapp-and-telegram-messages-in-claude-code-4ho1</link>
      <guid>https://dev.to/dialogbrain/how-to-get-whatsapp-and-telegram-messages-in-claude-code-4ho1</guid>
      <description>&lt;p&gt;&lt;em&gt;If you already spend the day in Claude Code, the conversations that matter can come to you there. A customer writes on WhatsApp, Telegram or email, and a second later the message is in your open session: Claude reads the chat, looks at who this person is, and shows you a reply to send, or tells you none is needed.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens when a message arrives
&lt;/h2&gt;

&lt;p&gt;DialogBrain keeps your WhatsApp, Telegram, Instagram, email and website chat in one inbox. Normally an AI agent inside DialogBrain answers there. With this set up, you pick some conversations and hand them to your own Claude Code session instead.&lt;/p&gt;

&lt;p&gt;When a message in one of those conversations comes in, DialogBrain pushes it into the session that is open on your computer. It is not a notification to go and look somewhere else. The message, the chat it belongs to and the instructions for what to do with it arrive in the session itself, and Claude starts on them straight away.&lt;/p&gt;

&lt;p&gt;Claude can open the whole conversation, the contact and their history on other channels, because the DialogBrain tools are already in the session. When it answers, the reply goes back into the same WhatsApp or Telegram chat, from the same number the customer wrote to.&lt;/p&gt;

&lt;p&gt;Nothing runs inside DialogBrain to make this happen: no model, no intermediate agent, no charge per message. The thinking is done by Claude Code, on the Claude plan you already pay for.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we use it ourselves
&lt;/h2&gt;

&lt;p&gt;One conversation that matters. A hotel owner from Thailand filled in our ad form, answered our first message and asked what it costs per month. We pinned that WhatsApp chat to our Claude Code session. Every time he writes, the message shows up in the session with a suggested answer. We change a word if needed and say "send". Our agents keep handling every other chat as before.&lt;/p&gt;

&lt;p&gt;A reply we are waiting for. When a deal hinges on one person getting back to us, the chat with that person wakes the session. Claude reads the answer against everything said earlier and tells us what changed and what to do next, instead of us checking the phone every hour.&lt;/p&gt;

&lt;p&gt;A new lead worth a closer look. Our intake agent answers every lead within seconds. For the ones that deserve more thought, an agent can put a task on the board addressed to our desktop session: research the company, suggest an approach. The task board keeps the status and the history.&lt;/p&gt;

&lt;p&gt;What we do not do is send the whole inbox to the session. At a hundred conversations a day that is a hundred interruptions. Pick the chats, people or events that are rare enough to deserve your attention.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;p&gt;Claude Code signed in with a claude.ai account or an Anthropic Console key. Channels, the Claude Code feature this is built on, are in research preview. On Pro and Max accounts they work without anything to switch on. On Team and Enterprise plans an owner first has to enable them under claude.ai → Admin settings → Claude Code → Channels.&lt;/p&gt;

&lt;p&gt;Node.js 20 or newer on your computer. Claude Code installed as a standalone app does not bring one with it, so check with node --version first.&lt;/p&gt;

&lt;p&gt;A DialogBrain workspace with the channels you want connected. The 14-day trial is enough to set everything up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1. Install the plugin
&lt;/h2&gt;

&lt;p&gt;Install the DialogBrain plugin in Claude Code and type /mcp to sign in. The plugin adds the DialogBrain tools, the step-by-step skills and the channel that carries the messages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;claude plugin marketplace add saloprj/dialogbrain-claude-plugin
claude plugin install dialogbrain@dialogbrain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2. Give it a key and a name for this computer
&lt;/h2&gt;

&lt;p&gt;Create an API key in DialogBrain under Settings → Developer, and put it in a small file together with a name for this computer. The name is how DialogBrain knows which session a conversation goes to, so use one you will recognise, such as office-laptop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# ~/.claude/channels/dialogbrain/.env
&lt;/span&gt;&lt;span class="n"&gt;DIALOGBRAIN_TOKEN&lt;/span&gt;=&amp;lt;&lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;Settings&lt;/span&gt; → &lt;span class="n"&gt;Developer&lt;/span&gt;&amp;gt;
&lt;span class="n"&gt;DIALOGBRAIN_CHANNEL_NAME&lt;/span&gt;=&lt;span class="n"&gt;office&lt;/span&gt;-&lt;span class="n"&gt;laptop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3. Start Claude Code with the channel on
&lt;/h2&gt;

&lt;p&gt;Start Claude Code with the channel switched on. Claude Code only lets messages into a session that was started with a flag naming the channel. It reads the flag at start, so an open session has to be restarted, and every new session needs the flag again. A shell alias saves typing it.&lt;/p&gt;

&lt;p&gt;The flag has "dangerously" in its name because during the research preview Claude Code only approves channels from Anthropic's own list, and the DialogBrain channel is not on it yet. The flag tells Claude Code you are choosing to load it anyway. If your company manages Claude Code for you, an admin can instead add the DialogBrain plugin to the approved channels in managed settings, and then the shorter claude --channels plugin:dialogbrain@dialogbrain is enough.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;claude --dangerously-load-development-channels plugin:dialogbrain@dialogbrain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4. Say which messages should reach you
&lt;/h2&gt;

&lt;p&gt;Tell Claude which messages should reach you, in plain words. The plugin knows how to set it up: it creates a "Claude Code" agent in your workspace and a rule for the chat, person, keyword or channel you named, pointed at this computer. To check the connection, ask which Claude Code sessions are connected, and your computer's name should be in the answer.&lt;/p&gt;

&lt;p&gt;You can also do it in the DialogBrain app: New AI Agent → the Claude Code card, then add a trigger with the chats you want. With one computer connected, that is all it needs. Choosing a specific computer when several are connected is done from Claude Code for now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Wake me here when the hotel lead from Thailand writes
on WhatsApp. Show me the message and a suggested
reply, and don't send anything until I say so.

Which of my Claude Code sessions are connected?

Stop waking me for that chat.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Who presses send
&lt;/h2&gt;

&lt;p&gt;Claude answers the customer by calling the DialogBrain send tool, and that message goes out straight away. It is not held as a draft in DialogBrain. Your control is Claude Code itself: unless you have told it to skip permission prompts, it asks you before every send. Keep that prompt on for customer conversations, or tell Claude in the rule to only suggest a reply.&lt;/p&gt;

&lt;p&gt;If Claude decides no reply is needed, for example the message is just "ok, thanks", it simply does not send anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  When a message does not arrive
&lt;/h2&gt;

&lt;p&gt;The session has to be open. Messages are pushed only to a session that is running at that moment. Nothing is saved and replayed later, so what arrives while Claude Code is closed stays in the DialogBrain inbox and is not delivered to the session.&lt;/p&gt;

&lt;p&gt;The session has to have been started with the flag. Without it Claude Code quietly drops what arrives, and the plugin's tools keep working as if nothing were wrong.&lt;/p&gt;

&lt;p&gt;After you edit the settings file, restart Claude Code. The file is read once, when the session starts.&lt;/p&gt;

&lt;p&gt;If the computer slept or the connection dropped, type /mcp and reconnect the DialogBrain channel. Then ask again which sessions are connected.&lt;/p&gt;

&lt;p&gt;With two Claude Code windows open, give each a different name, and say in the rule which one should receive the chat. If you do not, DialogBrain delivers to neither rather than making both do the same work.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you cannot switch channels on
&lt;/h2&gt;

&lt;p&gt;You still have two options that need no channel. An agent can message you on Telegram or WhatsApp when the event you care about happens, and you open the conversation from there. Or it can put a task on the DialogBrain board, which you can pick up from any assistant, including ChatGPT or Claude on your phone.&lt;/p&gt;

&lt;p&gt;More on channels: &lt;a href="https://code.claude.com/docs/en/channels" rel="noopener noreferrer"&gt;Claude Code channels documentation&lt;/a&gt;. The plugin, its skills and the channel code: &lt;a href="https://github.com/saloprj/dialogbrain-claude-plugin" rel="noopener noreferrer"&gt;dialogbrain-claude-plugin on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions and answers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can Claude Code receive WhatsApp messages?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, through DialogBrain. Connect WhatsApp to DialogBrain, install the DialogBrain plugin in Claude Code and start it with the channel switched on. Messages from the chats you pick then arrive in your open session, and Claude can reply in the same WhatsApp chat.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it cost anything per message?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not inside DialogBrain. No model runs there for these messages; the work happens in Claude Code, on your Claude plan. You pay DialogBrain for the channels as usual.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does Claude Code have to be open?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. Messages are pushed only to a session that is running. If you want it around the clock, keep a session running on a computer that stays on, or leave those chats to an agent inside DialogBrain, which works without your computer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will Claude answer my customers on its own?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Only if you let it. Claude Code asks you before each send unless you have turned permission prompts off. You can also tell it in the rule to only suggest replies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it work with Telegram, Instagram and email too?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. The rule is about conversations in your DialogBrain inbox, so it works for any channel connected there: WhatsApp, Telegram, Instagram, Facebook Messenger, email, LINE and the chat on your website.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is the "dangerously" flag safe?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It lets a channel that is not on Anthropic's approved list send messages into your session. Here that channel is the DialogBrain plugin you installed yourself, and it only delivers messages from your own workspace. If your company manages Claude Code, ask an admin to approve the plugin instead, and you will not need the flag.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://dialogbrain.com/articles/whatsapp-telegram-messages-in-claude-code" rel="noopener noreferrer"&gt;dialogbrain.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>mcp</category>
      <category>whatsapp</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to publish an MCP server in the Claude connectors directory</title>
      <dc:creator>Dialog Brain</dc:creator>
      <pubDate>Thu, 15 Oct 2026 07:58:41 +0000</pubDate>
      <link>https://dev.to/dialogbrain/how-to-publish-an-mcp-server-in-the-claude-connectors-directory-2oek</link>
      <guid>https://dev.to/dialogbrain/how-to-publish-an-mcp-server-in-the-claude-connectors-directory-2oek</guid>
      <description>&lt;p&gt;&lt;em&gt;On 30 September 2026 we submitted DialogBrain to Anthropic's connectors directory and it went live the same day. This is what the portal asks for, which rules quietly hold a submission, and why running every one of your own tools before you submit is the step that actually pays.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What a listing is, and what it is not
&lt;/h2&gt;

&lt;p&gt;A connector listing puts your remote MCP server in the directory people browse inside Claude. They add it in one click, sign in with your OAuth, and your tools are in their conversation. It is not a plugin: a plugin is a bundle of skills and configuration that comes from a GitHub repository and is a separate submission. If you have both, you submit both.&lt;/p&gt;

&lt;p&gt;The listing is published as a Community connector by default. An automated policy scan runs first; some submissions also get a human reviewer. Ours went from submitted to approved to published inside a day, but the portal says review can take weeks, so do not plan a launch around a date.&lt;/p&gt;

&lt;p&gt;Everything below follows the portal at &lt;a href="https://claude.ai/directory/manage" rel="noopener noreferrer"&gt;claude.ai/directory/manage&lt;/a&gt;, which any paid Claude plan can open.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decide which tools you are submitting
&lt;/h2&gt;

&lt;p&gt;This is the decision that matters, and it comes before the form. A reviewer reads every tool your listing exposes. Our full MCP catalogue carries raw SQL, a Python sandbox, an Android device farm and browser-session capture, all legitimate for the engineers who connect it themselves, and all wrong for a listing anyone can install. OpenAI had already rejected exactly that surface for the same reason.&lt;/p&gt;

&lt;p&gt;So the server answers on two paths. The full catalogue stays where it was; a second path serves a curated set: read and answer conversations, search, contacts, tasks, notes, reminders, knowledge, agent drafts, call transcripts. The paths cannot be merged, because the resource value a client reads back from the protected-resource document has to be the URL it registered: one shared path breaks one of the two listings.&lt;/p&gt;

&lt;p&gt;If your server was built for your own users, assume you will need this split. It is a dozen lines and it is the difference between a listing a reviewer can approve and a conversation about why you expose a SQL console.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# One tool set, one path per directory. The resource a client reads back
# must be the URL it registered, so the paths cannot be merged.
&lt;/span&gt;&lt;span class="n"&gt;PROFILES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;directory&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DIRECTORY_TOOLS&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;PROFILE_PATHS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/mcp/chatgpt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;directory&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/mcp/claude-directory&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;directory&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Check the four things the portal reads automatically
&lt;/h2&gt;

&lt;p&gt;Remote and reachable over HTTPS. A local server cannot be submitted on its own; it belongs in a plugin.&lt;/p&gt;

&lt;p&gt;OAuth 2.0 with dynamic client registration, or no authentication at all for public data. The portal detects which you have. Ours advertises a registration endpoint in /.well-known/oauth-authorization-server, and the 401 your server returns without a token has to point at the protected-resource document for the exact path being submitted.&lt;/p&gt;

&lt;p&gt;Every tool carries a title and the applicable readOnlyHint or destructiveHint. The portal flags the ones that do not, and a wrong label is a common rejection: anything that sends or deletes is destructive, anything that writes is not read-only.&lt;/p&gt;

&lt;p&gt;Documentation URL, privacy policy URL, support contact and an icon. All four are public links a reviewer will open.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.dialogbrain.com/mcp/claude-directory &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{}'&lt;/span&gt;

&lt;span class="c"&gt;# HTTP/2 401&lt;/span&gt;
&lt;span class="c"&gt;# www-authenticate: Bearer error="invalid_token",&lt;/span&gt;
&lt;span class="c"&gt;#   resource_metadata="https://api.dialogbrain.com/&lt;/span&gt;
&lt;span class="c"&gt;#   .well-known/oauth-protected-resource/mcp/claude-directory"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Run every tool before you submit: this is where the bugs are
&lt;/h2&gt;

&lt;p&gt;The portal asks you to confirm you have run each tool, and it is tempting to tick that box because the tools obviously work. We ran them instead: added the server as a custom connector in Claude, signed in as the reviewer account, and asked Claude to call each tool in turn and report the result. It took twenty minutes and found three real defects, two of which had been shipped for weeks.&lt;/p&gt;

&lt;p&gt;A read tool that answered "agent_id is required. Pass it as a parameter when calling from MCP." A person asking "what reminders are set?" has no agent id and cannot get one, so that tool could not answer for anyone connecting over MCP. It had been in our ChatGPT listing since September.&lt;/p&gt;

&lt;p&gt;A tool whose error message pointed at another tool the listing did not expose: files.read refuses a binary file and tells you to use files.get_base64, which was outside the curated set. The advice led nowhere and a customer's photo could not be opened.&lt;/p&gt;

&lt;p&gt;A tool that reported success for work it had not done: removing a tag that was never on the conversation answered success: true, indistinguishable from a real removal.&lt;/p&gt;

&lt;p&gt;None of these would have been caught by a reviewer in the first five minutes, and all three would have been found by a user in the first week. Twenty minutes of your own time is a cheap way to not learn about them from a stranger.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Call each of these tools exactly once, in order, and do not ask me
anything in between: workspace_current, channels_list, search_threads,
contacts_find, messages_read_history, tasks_create, tasks_update,
notes_save, reminder_set, reminder_list, reminder_cancel, files_read.
Then print one line per tool: the name, OK or FAILED, and for a failure
the exact error text.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The ten steps, and what each one actually wants
&lt;/h2&gt;

&lt;p&gt;Connection. Paste the URL and authorise. The portal reads your tool list live. If your server hides tools for channels a workspace has not connected, the count here is what that account can see, not your full set: say so in the notes rather than letting a reviewer wonder.&lt;/p&gt;

&lt;p&gt;Tools. Your tools and their annotations, synced from the live connection. Anything flagged here is fixed on your server, not in the form.&lt;/p&gt;

&lt;p&gt;Listing. Name, slug, a one-liner up to 200 characters, a description up to 2,000, categories, documentation, privacy, support, icon. The slug is permanent once published: ours is dialogbrain, and that is the one field you cannot take back.&lt;/p&gt;

&lt;p&gt;Use cases. Three things people will do, each with an example prompt, plus what they need before connecting, and whether the connector reads, writes, or both.&lt;/p&gt;

&lt;p&gt;Company, Authentication, Data handling. Company name and a contact a reviewer can reach; the authentication mode, which is detected; and whether the API is your own, whether personal health data is involved, whether any content is sponsored.&lt;/p&gt;

&lt;p&gt;Test &amp;amp; launch. Access instructions detailed enough for a reviewer to connect and run the tools: the URL, real credentials for a populated account, and what to try. Say plainly which tools reach real people: ours deliver messages to actual customers, so the instructions ask reviewers to read and not send.&lt;/p&gt;

&lt;p&gt;Compliance. Seven acknowledgements, including prompt injection and conversation-data collection. Read them. If your product stores other people's private messages, as an inbox does, say so in the notes instead of hoping the checkbox covers it.&lt;/p&gt;

&lt;p&gt;Review and submit. A summary and the button.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two traps worth knowing
&lt;/h2&gt;

&lt;p&gt;Reconnecting the server resets fields you already filled. We reconnected on the Connection step to pick up two newly added tools, and the portal silently put the listing name and slug back to the auto-derived api.dialogbrain.com and api-dialogbrain-com. The slug is permanent after publishing. Check the Listing step again after any reconnect.&lt;/p&gt;

&lt;p&gt;A draft lives in the browser tab. The form says "Draft saved in this tab". Leave that tab and the draft is not in your submissions list; come back to the same tab and it is still there, on the step you left. Do not close it.&lt;/p&gt;

&lt;h2&gt;
  
  
  After it is live
&lt;/h2&gt;

&lt;p&gt;The listing appears in the directory within about an hour, with Community and New badges. Health, rank and usage start about a day after the first calls.&lt;/p&gt;

&lt;p&gt;Edits after publishing go through review before they replace what is live, so the listing you publish is the one people see for a while. Edits before publishing send the submission back to draft for another review, which is why, if you are staring at an approved submission and a small copy change, publish first and edit after.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions and answers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Do I need a separate submission for a plugin?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. A connector is one remote MCP server submitted by URL. A plugin is a bundle of skills, commands and MCP configuration read from a GitHub repository, submitted as "Plugin bundle". If your plugin references a server you run, submit the server as a connector too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I submit while another submission is in review?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. Unlike Meta's app review, the portal is open for new submissions at any time, and an organisation can create up to ten in 24 hours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens if a tool fails while a reviewer is testing?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It becomes a question you answer by email, and the listing waits. That is the argument for running every tool yourself first: a failure you find is a commit, a failure a reviewer finds is a week.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does the listing cost anything?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Any paid Claude plan can submit, and a Community listing is free. What it costs you is the work of making the tool surface defensible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I change the name or slug later?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The name follows the listing and can be edited through review. The slug is permanent once the listing is published, so decide it before you press publish.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://dialogbrain.com/articles/publish-mcp-server-claude-directory" rel="noopener noreferrer"&gt;dialogbrain.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>claude</category>
      <category>ai</category>
      <category>api</category>
    </item>
    <item>
      <title>The call transfer that reported success and rang nobody</title>
      <dc:creator>Dialog Brain</dc:creator>
      <pubDate>Wed, 02 Sep 2026 04:21:46 +0000</pubDate>
      <link>https://dev.to/dialogbrain/the-call-transfer-that-reported-success-and-rang-nobody-1c01</link>
      <guid>https://dev.to/dialogbrain/the-call-transfer-that-reported-success-and-rang-nobody-1c01</guid>
      <description>&lt;p&gt;Our voice agents can hand a live phone call to a human. Getting there took two rewrites, and the first one shipped without ever delivering a single call — while our own logs said it worked. This is what the feature does now, and what the failure taught us.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the caller hears
&lt;/h2&gt;

&lt;p&gt;Someone asks to speak to a person, or the agent decides the question is not its own: a complaint, a payment, something outside its instructions. The agent says one short line, and from there the caller hears real ringing — the second number is being dialled.&lt;/p&gt;

&lt;p&gt;When the phone is answered, the agent goes quiet. Two people are on the line and nothing else is on it with them. If nobody answers, nothing happens: the caller stays with the agent, which knows the dial failed and can offer a callback or take a message.&lt;/p&gt;

&lt;h2&gt;
  
  
  The route a transfer takes
&lt;/h2&gt;

&lt;p&gt;A transfer here is not "hand the line to the carrier". It is a second call, dialled into the same conversation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Is the number on the agent's approved list?&lt;/strong&gt; If not, refused — and the agent is still on the line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is this a phone call at all?&lt;/strong&gt; A messenger chat or a web voice widget has no second line to connect.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dial the second number into the same call.&lt;/strong&gt; The caller hears ringing; the agent is still there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Did they pick up within 45 seconds?&lt;/strong&gt; If not, the dial is cancelled and the caller stays with the agent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;They picked up&lt;/strong&gt; — the agent loses the right to speak, and the two of them talk.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both gates sit &lt;em&gt;before&lt;/em&gt; anything is dialled, so a refusal never costs the caller a single ring. The pickup fork is the only place where a call becomes a transferred one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not SIP REFER
&lt;/h2&gt;

&lt;p&gt;Telephony has a cheaper way: a &lt;code&gt;REFER&lt;/code&gt;, after which the carrier connects the two parties itself and you leave the call — the minutes stop flowing through you.&lt;/p&gt;

&lt;p&gt;We built that first. It never delivered a call. Telnyx answered every REFER with &lt;code&gt;200 OK&lt;/code&gt; and did nothing: no progress NOTIFY, no ring at the destination. Meanwhile our own bookkeeping recorded &lt;code&gt;outcome = transferred&lt;/code&gt;, so the dashboards were green while the caller was simply dropped.&lt;/p&gt;

&lt;p&gt;The documentation explains it. REFER-based external transfer on a SIP trunk requires an &lt;strong&gt;active inbound call to your own number&lt;/strong&gt; to match against, plus a &lt;code&gt;Diversion&lt;/code&gt; header carrying that number. We were sending REFER on calls &lt;em&gt;we&lt;/em&gt; originated — the one shape it cannot work on. And LiveKit's &lt;code&gt;TransferSIPParticipant&lt;/code&gt; has no field for a custom header, so the requirement is unreachable from there anyway.&lt;/p&gt;

&lt;p&gt;Two other explanations were tested and disproved rather than assumed: enabling third-party call control on the connection changed nothing, and neither did a &lt;code&gt;sip:&lt;/code&gt; URI instead of &lt;code&gt;tel:&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three things measurement changed
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Presence in the room is not a pickup signal.&lt;/strong&gt; The dialled participant appears in the media room the moment dialling starts — measured at 310 ms, with no call at the destination. Only &lt;code&gt;wait_until_answered&lt;/code&gt; tells you a human lifted the handset.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Removing the agent takes the call with it.&lt;/strong&gt; Measured in isolation on a live call: &lt;code&gt;RemoveParticipant&lt;/code&gt;, and within five seconds the room was empty, carrier leg included. The room does not outlive its agent job. So the agent is silenced, not removed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Silencing alone is not enough.&lt;/strong&gt; Revoking publish stops the agent being &lt;em&gt;heard&lt;/em&gt;. Its job keeps running: nine seconds after one handover it composed and "spoke" a line that went into the call history, while it carried on transcribing two people who had just been handed to each other. It now gets an explicit stand-down.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest cost
&lt;/h2&gt;

&lt;p&gt;Bridging means the conversation runs over our media path, and minutes are billed on both legs — exactly what a REFER avoids. In exchange it works identically on inbound and outbound calls, on any carrier, with nothing to configure on the telephony side.&lt;/p&gt;

&lt;p&gt;If your logs can say "transferred" without anyone's phone ringing, that is the bug worth looking for first.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://dialogbrain.com/articles/call-transfer-to-human" rel="noopener noreferrer"&gt;dialogbrain.com&lt;/a&gt;, where the same piece has a flow diagram.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>webdev</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
