<?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: Dmytro Shevchenko</title>
    <description>The latest articles on DEV Community by Dmytro Shevchenko (@dmytro_shevchenko_eecc3e2).</description>
    <link>https://dev.to/dmytro_shevchenko_eecc3e2</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%2F4182247%2F7038a18a-437f-4e8e-a0f9-54757ff88afa.jpg</url>
      <title>DEV Community: Dmytro Shevchenko</title>
      <link>https://dev.to/dmytro_shevchenko_eecc3e2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dmytro_shevchenko_eecc3e2"/>
    <language>en</language>
    <item>
      <title>Using MCP for a support handoff</title>
      <dc:creator>Dmytro Shevchenko</dc:creator>
      <pubDate>Sat, 24 Oct 2026 10:38:11 +0000</pubDate>
      <link>https://dev.to/dmytro_shevchenko_eecc3e2/using-mcp-for-a-support-handoff-4552</link>
      <guid>https://dev.to/dmytro_shevchenko_eecc3e2/using-mcp-for-a-support-handoff-4552</guid>
      <description>&lt;p&gt;Before I pick up a question about an order, I'd want to see what we've told the customer so far. I wouldn't want to ask the customer for something they've already sent. The message in front of me might be their second or third attempt to get an answer. I'd want the assistant to read back a little, too.&lt;/p&gt;

&lt;p&gt;I work on DobroDesk, where an AI client can use MCP (Model Context Protocol) to call support tools. With that client &lt;a href="https://dobrodesk.com/help/connect-mcp-client-and-revoke-access" rel="noopener noreferrer"&gt;connected to the workspace&lt;/a&gt;, I could ask: "Find the open conversation about order 8142, read the messages and suggest someone to take over." I've made up the order for this example.&lt;/p&gt;

&lt;p&gt;The latest message might say "Any news?" I'd need to go back further to understand that. The timeline can flag that older messages may exist outside the recent window it returns. It also flags text that's been shortened. I can get more of an individual message by ID.&lt;/p&gt;

&lt;p&gt;An order number would help me find the right conversation. I'd look through the open ones in the Orders Inbox with &lt;code&gt;search_conversations&lt;/code&gt;. Search only gives me metadata, so this isn't yet the assistant reading what the customer said. I'd have to allow message reading separately, even if I already had the ID of the message I wanted.&lt;/p&gt;

&lt;p&gt;I might have a colleague in mind, but I'd still check the choices returned by &lt;code&gt;list_assignment_targets&lt;/code&gt;. Those are people who can receive this conversation in its current Inbox. I might need the next page before I found the person I had in mind, so I'd use the cursor from that result. I could compare their availability and capacity there. They don't tell me whether Lena has dealt with the order before. That's something I would have to establish myself.&lt;/p&gt;

&lt;p&gt;Before any of this is written, I would check the conversation and who I'm giving it to. In this example that's Lena. In this proposed client flow, the assistant would have to wait for my confirmation before calling &lt;code&gt;assign_conversation&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I might lose the response after the assignment has been made. I'd keep the original request and its &lt;code&gt;idempotencyKey&lt;/code&gt;. That's the request I'd send again. Getting a timeout wouldn't be a reason to make a new key and start another assignment. If the first request finished and left a saved result, I get that result back. Otherwise, I can't yet tell Lena that the handoff is done.&lt;/p&gt;

&lt;p&gt;I'd be connecting the assistant as one teammate, not as the whole company. The assistant can only do what that teammate's role and the OAuth grant allow. DobroDesk also lets the owner limit the member, the application and that member's use of the application. All of them have to allow the action. The teammate doesn't get a new Brand or Inbox just by connecting an assistant.&lt;/p&gt;

&lt;p&gt;I'd leave customer details and internal notes out of this job. I'd have to give it permission to read each of those separately. I don't have to allow either just to let the assistant read the messages in this conversation. Every time it calls a tool, DobroDesk checks what that teammate and the application are allowed to do.&lt;/p&gt;

&lt;p&gt;If I revoke this teammate's access to the application, its current grants stop working. They could connect it again later, though, if the policies still allow that. To prevent that as well, I'd block reconnect for the same teammate and application. I don't have to block everybody else's connection to deal with this one.&lt;/p&gt;

&lt;p&gt;I wouldn't use the reconnect switch on its own to cut off access. A grant that already exists can still work. I'd revoke those grants as well, for this teammate and application. If I allow them to reconnect later, they'll need to give consent again. The policies still have to allow it then.&lt;/p&gt;

&lt;p&gt;AI helped with the writing and revisions here. This order and these colleagues are fictional, and this is a proposed workflow.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>security</category>
      <category>ai</category>
    </item>
    <item>
      <title>Keeping drafts and pending messages in a mobile support SDK</title>
      <dc:creator>Dmytro Shevchenko</dc:creator>
      <pubDate>Wed, 14 Oct 2026 06:22:15 +0000</pubDate>
      <link>https://dev.to/dmytro_shevchenko_eecc3e2/keeping-drafts-and-pending-messages-in-a-mobile-support-sdk-5c0m</link>
      <guid>https://dev.to/dmytro_shevchenko_eecc3e2/keeping-drafts-and-pending-messages-in-a-mobile-support-sdk-5c0m</guid>
      <description>&lt;p&gt;The order number I need might be on another screen. If I'm halfway through a support message, I'd like to go and find it, then come back to what I was writing. I wouldn't expect the draft to disappear because I pressed Back. I'd still be signed in, after all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leaving the chat
&lt;/h2&gt;

&lt;p&gt;With DobroDesk, I can hide the view or unmount it and keep the signed session, draft and pending outbox. Hide also releases keyboard focus. I'd still need to type on the screen I'm going to, so the hidden chat has to let go of the keyboard. The customer can carry on with what they came to do.&lt;/p&gt;

&lt;p&gt;The draft I want to come back to is mine. If somebody else signs in on the phone, I'd expect it to be gone. I wouldn't want them to open chat and find my message waiting to go out. That's why the host has to clear this state on signout and before it gives the SDK a &lt;a href="https://dobrodesk.com/developers/guides/identity" rel="noopener noreferrer"&gt;different customer's identity&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdobrodesk.com%2Fsdk%2Fios-chat-light-en.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdobrodesk.com%2Fsdk%2Fios-chat-light-en.webp" alt="DobroDesk native iOS support conversation with an order lookup example and a full message composer" width="320" height="694"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdobrodesk.com%2Fsdk%2Fandroid-chat-light-en.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdobrodesk.com%2Fsdk%2Fandroid-chat-light-en.webp" alt="DobroDesk native Android support conversation with a full message composer" width="320" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  When the response doesn't come back
&lt;/h2&gt;

&lt;p&gt;I could have one message on the server and no message ID on my phone. If I try again, I'd still want it to be the same message. I might only have lost the response to the first attempt. I'd keep the request key from that first attempt. A new one could add another copy of my message.&lt;/p&gt;

&lt;p&gt;I might have started with "Where is my order?" and be writing "Thanks, I found it" by the time the retry runs. I wouldn't want it to send the second text in place of the first. DobroDesk saves the first request before sending it, with its body, original timestamp and request key. That's what the outbox gives back to a retry.&lt;/p&gt;

&lt;p&gt;So I retry with the saved values. For 24 hours after acceptance, the server can replay the stored response for a retry with the same saved values. A different body with that key gets a conflict. A day later, the message is still part of the conversation. It's the stored response that has expired.&lt;/p&gt;

&lt;p&gt;The client unit test fails a send, restores the session in a new client and flushes the same outbox. It compares the two serialized request bodies. They're equal. An item saved for another account isn't flushed. Both clients use the same in-memory store, though.&lt;/p&gt;

&lt;h2&gt;
  
  
  Returning after the app quits
&lt;/h2&gt;

&lt;p&gt;Keeping a request while a screen is closed tells me very little about what happens when the app quits. I need it to be there after the process has ended. Native integrations provide &lt;a href="https://dobrodesk.com/developers/guides/offline" rel="noopener noreferrer"&gt;durable storage&lt;/a&gt; for that. If I use the headless client, I have to provide the store myself. I would test quitting and relaunching the app.&lt;/p&gt;

&lt;p&gt;I'm coming back to the same conversation as the same customer. The token I had before might have expired by now, so I'd get a valid one before retrying. I'd leave the saved request as it was while renewing that access. The app needs to be active for the retry.&lt;/p&gt;

&lt;p&gt;I'd look at the actual conversation, too. Getting the same request back out of storage wouldn't tell me if the server added it twice. I'd let it accept the message and then drop the response. After quitting and reopening the app, I'd retry that saved request within 24 hours. I should find one copy of the message in the conversation.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>flutter</category>
      <category>mobile</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Why we build DobroDesk on Cloudflare Workers</title>
      <dc:creator>Dmytro Shevchenko</dc:creator>
      <pubDate>Tue, 13 Oct 2026 13:02:37 +0000</pubDate>
      <link>https://dev.to/dmytro_shevchenko_eecc3e2/building-conversation-first-support-on-cloudflare-1e3j</link>
      <guid>https://dev.to/dmytro_shevchenko_eecc3e2/building-conversation-first-support-on-cloudflare-1e3j</guid>
      <description>&lt;p&gt;DobroDesk puts email, website chat and in-app support in shared inboxes. A teammate can read the history, see the customer details and take over from AI when needed.&lt;/p&gt;

&lt;p&gt;We build it on Cloudflare. Here is how that works when a customer asks for a booking and then needs help from the team.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/-TJ3llFlfvs" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  A booking request in chat
&lt;/h2&gt;

&lt;p&gt;A customer asks to book a consultation. With a booking provider connected and the action configured, DobroDesk can collect the service, date and time, check availability and show a proposed slot. The customer confirms before the booking is completed.&lt;/p&gt;

&lt;p&gt;Sometimes the request changes halfway through. The customer may need a different service, or the provider may fail to return an answer. A teammate can then take over with the details already collected in the conversation.&lt;/p&gt;

&lt;p&gt;That handoff matters. The customer should not have to explain the request again, and the teammate needs to know what was tried and what still needs attention.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fejsrbgunk1zbarxrlhiz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fejsrbgunk1zbarxrlhiz.jpg" alt="A customer reviews the service, date and time in the full DobroDesk widget before confirming a booking." width="372" height="692"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the messages go
&lt;/h2&gt;

&lt;p&gt;A booking request has more than a few chat messages. There is a customer, a conversation history and the result of the action. We keep that support data in the workspace's Durable Object, using SQLite.&lt;/p&gt;

&lt;p&gt;D1 holds shared account and routing information. R2 stores files, including email attachments. This keeps the conversation data together without putting large files in the same database.&lt;/p&gt;

&lt;p&gt;Some work continues after a message arrives. An email needs parsing, a reply needs sending and a failed delivery may need another attempt. We use Cloudflare Queues for those jobs. A customer can send a message while the service handles the next steps in the background.&lt;/p&gt;

&lt;p&gt;Retries need care too. Receiving a provider event twice should not create two conversations, and retrying a reply should not send it twice. Those are the kinds of cases we check when changing the flow.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI and the team share the conversation
&lt;/h2&gt;

&lt;p&gt;AI can prepare a reply for review or answer routine questions automatically when the workspace enables that mode. It uses the knowledge and rules the team has configured.&lt;/p&gt;

&lt;p&gt;Sensitive or uncertain requests go to a person. The booking action follows the same approach: it can complete the configured steps after confirmation, while a teammate handles the cases that need a decision.&lt;/p&gt;

&lt;p&gt;For the support team, the useful part is seeing the messages, customer details and action results together. They can continue the conversation from that point.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn6dumsvkp0y4qa9b02wa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn6dumsvkp0y4qa9b02wa.jpg" alt="DobroDesk shows an AI draft, two sources and a required human review for a payment question." width="800" height="1051"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Updating the product while chats are open
&lt;/h2&gt;

&lt;p&gt;A customer may leave a chat open while we release an update. We keep versioned widget files and support the previous running version so an active conversation can continue. We also check restored sessions and conversation history during releases.&lt;/p&gt;

&lt;p&gt;The Mobile SDK brings native support screens to iOS and Android, with packages for Flutter, React Native, Capacitor and NativeScript. Version 0.2.0 is published. Teams can add support to their app and handle the incoming conversations in DobroDesk.&lt;/p&gt;

&lt;p&gt;We have also been improving conversation loading and switching in the inbox. We focus on everyday steps, such as opening a conversation and moving to the next one.&lt;/p&gt;

&lt;p&gt;You can try the &lt;a href="https://dobrodesk.com/demo" rel="noopener noreferrer"&gt;interactive demo&lt;/a&gt;. The &lt;a href="https://dobrodesk.com/developers" rel="noopener noreferrer"&gt;SDK guides&lt;/a&gt; cover installation and configuration when you are ready to add support to an app.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>webdev</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
