# SMS MCP review alerts: live tests on Maps and app store reviews

> Live tests of review alert SMS: poll Google Maps, App Store and Google Play reviews, dedupe by review ID, avoid double charges, and compare SMS MCP costs.

- Canonical page: https://everyinfra.com/en/blog/sms-mcp-review-alerts-google-maps-app-reviews
- Published: 2026-11-14T04:18:00+08:00 · Fact-checked: 2026-11-14T04:15:00+08:00

On November 14, 2026, between 00:16 and 03:30 Singapore time, we polled four review sources about once an hour. Two were Google Maps listings, Joe's Pizza and the Los Angeles DMV. Two were DoorDash reviews on the App Store and on Google Play. We have 3 polls for Maps and Google Play, and 4 polls for the App Store.

The whole test made 21 charged calls for $0.029167 in total. 13 of them were polls. Three were place searches and 1 was a sample that we later replaced. The other 4 were the idempotency test, the MCP test, the MyChart comparison and the script run.

Only Google Play showed new reviews between polls. The newest App Store review was 28.8 to 31.9 hours old at poll time. We compared it with Apple's own public review feed, and the newest entry was the same. Joe's Pizza returned 20 reviews over 35.7 hours in poll 1, with a median gap of 0.61 hours, but also one gap of 9.75 hours. The next two polls, two hours in total, had no new reviews.

So set the schedule per source. Check a busy place every hour for about $1.00 a month per source. Check a quiet place or an app store once a day for about $0.042 a month.

Dedupe by review ID. The 297 overlapping rows across polls kept exactly the same review IDs. Send scheduled jobs through REST with an `Idempotency-Key`: a resend in the same hour replays and costs nothing more. SMS APIs have no idempotency key, so a local outbox must make sure each review causes one text only.

On the SMS side, TrueDialog launched an MCP server on November 10 that sends texts from Claude and ChatGPT. Twilio's own MCP server only searches documentation. We did not send real SMS, so every SMS step is a configuration example.

> **Key points**
>
> - Only Google Play had new reviews between polls, and App Store reviews matched Apple's public feed, so check apps daily.
> - Dedupe by review ID, not by timestamp: 297 overlapping rows kept the same IDs.
> - Each data call costs $0.001389, and scheduled jobs use REST with an `Idempotency-Key`, so a resend in the same hour replays at no charge.
> - SMS MCP: TrueDialog MCP (2026-11-10) sends with a dry run, while Twilio's own MCP server only searches docs.
> - DoorDash gets about 94 bad reviews a day by our estimate, so send at most one summary per hour.

![Illustration: on the left, a small shop with an awning and a phone each send out a stream of review cards with stars. The cards fall into a sieve in the middle. Most five-star cards drop into a grey tray below. Only one or two one-star and two-star cards turn teal, and a dotted line runs from the sieve to a phone on a counter on the right, which shows a teal chat bubble.](https://everyinfra.com/articles/sms-mcp-review-alerts-google-maps-app-reviews/img-explain.webp)

The alert does one job: it picks the few 1 and 2 star reviews out of a steady stream and turns them into one text on the owner's phone.

## The job: one text message when a bad review appears

The volume of 1 and 2 star reviews varies a lot. By our estimate, DoorDash gets about 94 a day across two stores. The Los Angeles DMV on Google Maps gets less than one a day.

Google Maps, the App Store and Google Play all send notices to owners. These notices go by email, in-app message or a developer console. A text reaches almost every phone and shows on the lock screen. It also costs money, needs a registered number and must follow carrier rules.

The job here is narrow. Check the newest reviews of chosen places and apps every hour or every day. When a new review has 1 or 2 stars, send one text to the person in charge. Send one text per review only, and pay one charge per check only.

The job has three parts. Part one reads reviews. It uses three EveryInfra capabilities, [`google_maps_reviews/reviews`](/google-maps-reviews-api/reviews), [`app_store/reviews`](/app-store-api/reviews) and [`google_play/reviews`](/google-play-api/reviews), and gets the newest 20 to 50 reviews.

Part two compares them with the reviews seen last time, keeps the new ones and filters by stars. Part three sends the text through an SMS MCP server or an SMS provider API. MCP is an open protocol that lets AI assistants call outside tools ([modelcontextprotocol.io](https://modelcontextprotocol.io/specification/2026-07-28)).

We ran parts one and two live on November 14, 2026. Part three needs an SMS account, a registered number and recipient consent. We did not send real texts, so part three is a configuration example based on the vendors' own pages and docs.

We chose four samples of very different size. Joe's Pizza Broadway near Times Square in New York is a busy shop with 27,620 reviews on Google Maps. The California DMV office on Hope Street in Los Angeles is a public service counter with 2,321 reviews and a 3.1 average. DoorDash stands for an app with many reviews, and we pulled it from both the App Store and Google Play.

The patient portal app MyChart stands for health care. We pulled it once as a cross-domain comparison. All of these places and apps are public. We never print reviewer names or photos.

| Sample | Platform and capability | Public info (read Nov 14) | Rows per call | Question it answers |
| --- | --- | --- | --- | --- |
| Joe's Pizza Broadway (New York) | `google_maps_reviews/reviews` | 27,620 reviews, 4.4 stars | 20 | Does a busy shop get new reviews every hour? |
| Los Angeles DMV (Hope St) | `google_maps_reviews/reviews` | 2,321 reviews, 3.1 stars | 20 | A public counter with many bad reviews but few reviews |
| DoorDash (App Store, US) | `app_store/reviews` | App ID 719972451 | 50 | How fresh is the store's "newest" list? |
| DoorDash (Google Play) | `google_play/reviews` | Package com.dd.doordash | 40 | How do two stores differ for one app? |
| MyChart (both stores, comparison) | `app_store/reviews`, `google_play/reviews` | App ID 382952264, package epic.mychart.android | 50 / 40 | Share of bad reviews for a health app |

![Animated flow with five stations from left to right. Station 1, a timer fires once per hour. Station 2, EveryInfra reads three review capabilities, and each request carries an idempotency key built from the source name and the hour. Station 3, a local table drops review IDs it has seen before. Station 4, new 1 or 2 star reviews go into an outbox table. Station 5, an SMS MCP server or SMS API sends the text, and the row is set to sending first. A teal dot moves along the five stations; at station 3 the grey old reviews stop and only one one-star card moves on.](https://everyinfra.com/articles/sms-mcp-review-alerts-google-maps-app-reviews/fig-01-alert-flow.en.light.svg)

## Which SMS MCP servers exist, and which ones can send

In Google autocomplete, "sms mcp" shows variants such as "sms mcp server", "claude sms mcp" and "sms api mcp" (Google autocomplete, read November 14, 2026). Three products carry the MCP name: one can send texts, one can only search documentation, and one runs on your own computer.

We picked one example of each from the vendors' own pages. The first is an MCP server that an SMS platform hosts. The second is a documentation search server from an SMS API company. The third is a local server from the same company's lab.

The first is TrueDialog, an enterprise SMS platform in Austin, Texas. It launched TrueDialog MCP on November 10, 2026. The press release says people and AI agents can send SMS and RCS messages and manage contacts. They do this from ChatGPT, Copilot, Claude, Gemini, Perplexity and other assistants.

It is listed in the ChatGPT app directory and the Microsoft Copilot connector catalog. Other assistants connect through [tdmcp.com](https://tdmcp.com/) ([PR Newswire release](https://www.prnewswire.com/news-releases/truedialog-launches-mcp-for-chatgpt-copilot-and-other-ai-assistants-302935019.html); product page at [truedialog.com/features/mcp](https://www.truedialog.com/features/mcp)). The release also says MCP access comes at TrueDialog's standard pricing with no separate MCP fee.

Sign-in uses OAuth 2.1. The client finds the authorization server at `auth.tdmcp.com`. The user signs in to their TrueDialog account in a browser, and the client gets only a short-lived token. Nobody pastes a key ([tdmcp.com setup](https://tdmcp.com/)). The endpoint is `https://connect.tdmcp.com`, and the same URL with `/mcp` also works.

The second is Twilio's own MCP server. It went into public beta on May 7, 2026 at `mcp.twilio.com/docs`. It needs no account and no sign-in ([Twilio blog](https://www.twilio.com/en-us/blog/developers/introducing-twilio-mcp-skills)).

It has two tools, `twilio__search` and `twilio__retrieve`, which search and fetch parameter docs for more than 1,800 endpoints. The docs say the server is read-only and does not call APIs for you ([Twilio MCP docs](https://www.twilio.com/docs/ai/mcp)). It can help a coding assistant write code that sends a Twilio text, but it cannot send one. The docs list tools that call APIs with OAuth under "next steps".

The third is the Twilio Labs package `@twilio-alpha/mcp`. You start it on your own computer with `npx` and pass your account SID and API key. It turns Twilio's public APIs into MCP tools, including SMS sending ([GitHub repo twilio-labs/mcp](https://github.com/twilio-labs/mcp)).

The last commit on GitHub is from July 7, 2025. The latest npm version, 0.7.0, came out the same day ([npm package page](https://registry.npmjs.org/@twilio-alpha/mcp)). The README warns against running community MCP servers next to the official ones. This stops an injection attack from reaching the tools of your Twilio account.

| Item | TrueDialog MCP | Twilio MCP (public beta) | @twilio-alpha/mcp (lab) |
| --- | --- | --- | --- |
| Launch or last update | Launched 2026-11-10 | Public beta 2026-05-07 | Last commit 2025-07-07 |
| Where it runs | Hosted, `connect.tdmcp.com` | Hosted, `mcp.twilio.com/docs` | Local, started with `npx` |
| Auth | OAuth 2.1, browser sign-in | None | SID and API key on the command line |
| Can it send SMS? | Yes, `send_sms` | No, docs only | Yes, through API tools |
| Dry run | `execute=false`, no send, no credits used | Not applicable | Not documented |
| Can it read replies? | No (outbound only) | Not applicable | Yes, through API tools |
| Price | TrueDialog plan, no extra MCP fee | Free | Twilio usage pricing |

The Microsoft Learn connector page lists ten tools and seven limits ([Microsoft Learn: TrueDialog MCP connector](https://learn.microsoft.com/en-us/connectors/truedialogmcp/)). Six tools only read and four write. Only `send_sms` reaches a phone.

`send_sms` defaults to `execute=true`. With `execute=false` it runs a dry run that sends nothing and uses no credits, but it still creates a campaign record. One call can take many recipients, so one sentence can send many texts.

The first known limit is "outbound only": the server cannot read replies or conversations. It does not support scheduled or recurring campaigns, and every send is immediate. Opt-out, 10DLC and TCPA duties stay with the account owner. The `force_opt_in` parameter can text contacts who opted out, and the page says to use it only with a lawful basis.

![Screenshot: the Known Issues and Limitations section of the TrueDialog MCP connector page on Microsoft Learn. A teal box marks the first item, Outbound only: the server sends messages but cannot read replies, inbound messages or conversations, so no tool can answer what a contact replied.](https://everyinfra.com/articles/sms-mcp-review-alerts-google-maps-app-reviews/img-shot-truedialog-outbound.webp)

The connector page says TrueDialog MCP is send-only. A review alert only sends, so this is fine. If the owner should reply by text to answer a review, you need a separate inbound webhook. [Microsoft Learn, TrueDialog MCP connector, read 2026-11-14](https://learn.microsoft.com/en-us/connectors/truedialogmcp/)

The Microsoft Learn page and tdmcp.com give different tool counts. The Learn page lists ten tools, including `report_issue`, which sends a problem report to TrueDialog support by email. The tools section on tdmcp.com lists nine tools, six read and three write, without `report_issue`.

The Learn page also mentions an optional `inbox_*` tool pack for conversational SMS threads. When that pack is on, `send_sms` maps to `inbox_sms_send`. tdmcp.com says such tools depend on the deployment, and `connect.tdmcp.com` lists only the nine. We have no TrueDialog account and could not count `tools/list` ourselves. We give both sources; trust the tool list you see after you connect.

A review alert needs three things: send, dry run, and a fixed sender number. TrueDialog MCP has all three. It cannot read replies, which does not matter for a one-way alert.

Twilio's own MCP server can only help you write code today. If you already use Twilio, let the scheduled script call its Messages API. Let the AI assistant write the summary.

## What the platforms already notify you about

Before you write a poller, check whether the platform's own notices can do the job. Only Google Business Profile pushes new reviews in real time, and only to the verified owner. Apple's notification list has no "new review" item. The Google Play API returns only the last week of reviews.

The Google Business Profile help page says owners can turn on alerts for new reviews and photos under "Customer activity". The alerts arrive by email, on Search and in the Maps app ([Google Business Profile Help: manage notifications](https://support.google.com/business/answer/7198436?hl=en)).

Developers can also push new review events to a Cloud Pub/Sub topic with the My Business Notifications API. The [setup guide](https://developers.google.com/my-business/content/notification-setup) was updated on 2026-08-28 (see also the [NotificationSetting reference](https://developers.google.com/my-business/reference/notifications/rest/v1/NotificationSetting)). You must own the Business Profile and set up Pub/Sub and OAuth in Google Cloud. For full review text you then call `accounts.locations.reviews.list` ([review data guide](https://developers.google.com/my-business/content/review-data)).

App Store Connect has seven kinds of user notification. Only "Developer Response" relates to reviews: it emails you when a user edits a review you already answered ([App Store Connect Help: user notifications](https://developer.apple.com/help/app-store-connect/reference/account-management/user-notifications/)). New reviews are not on the list.

For full reviews, a developer can call the Customer Reviews endpoint of the App Store Connect API. It filters by territory and rating and sorts by date ([Apple docs: Customer Reviews](https://developer.apple.com/documentation/appstoreconnectapi/customer-reviews)). The app must be in your developer account.

The Google Play Developer API "Reply to Reviews" endpoint lists and answers reviews. A page holds 10 reviews by default and 100 at most. The docs say it returns only reviews created or edited in the last week, and only reviews with text; rating-only reviews do not appear.

The read quota is 200 calls an hour ([Google Play Developer API: Reply to Reviews](https://developers.google.com/android-publisher/reply-to-reviews)). Older reviews come from a CSV download in Play Console.

| Platform | Official push for new reviews | Official read API | Own place or app only | What it means here |
| --- | --- | --- | --- | --- |
| Google Maps | Yes: email, Maps app, or Pub/Sub | Business Profile API, all reviews | Yes | Use the official push for your own shop; poll competitors, franchises and unclaimed places |
| Google Maps (Places API) | No | Up to 5 reviews per place | No | 5 is too few to spot new ones; see [BL-70](/blog/how-to-scrape-google-maps-reviews) |
| App Store | No new review alert, only "answered review edited" | App Store Connect API | Yes | Even your own app needs polling |
| Google Play | No | Last week only, text reviews only | Yes | Rating-only bad reviews are not in the official API |

If the places you watch are not in your own account, the official push does not help. A regional manager who watches franchise shops is one case. An agency that watches client shops is another. On the App Store, even your own app gets no new review push.

On Reddit, a user in r/smallbusiness asked how to monitor Google reviews for businesses they do not own. The replies say Google only lets you monitor your own ([Reddit r/smallbusiness thread](https://www.reddit.com/r/smallbusiness/comments/1ncsmez/google_reviews_monitoring/)). The Places API returns at most 5 reviews per place ([Places API Place Details](https://developers.google.com/maps/documentation/places/web-service/legacy/details)). That is too few to tell whether a review is new.

## Live polls: how often do new reviews show up?

We polled all four samples at three moments, 00:16 to 00:20, 01:19 to 01:20 and 02:19 to 02:20 Singapore time. At 03:20 we polled the App Store once more. The parameters were the same every time.

That window is 11 a.m. to 2 p.m. on November 13 in New York and 8 a.m. to 11 a.m. in Los Angeles. These shops and counters were open.

Each poll used `sort=newest` and took the newest 20 to 50 rows.

We stored each review's ID, stars and `posted_at`. Then we compared each poll with the earlier ones and counted new reviews and new 1 or 2 star reviews. Each row below is one successful live call, charged $0.001389.

| Sample | Poll (Singapore time) | Rows | New | New 1–2 star | Overlap with earlier polls |
| --- | --- | --- | --- | --- | --- |
| Joe's Pizza (Maps) | 1 · 00:19 | 20 | — | — | — |
| Joe's Pizza (Maps) | 2 · 01:19 | 20 | 0 | 0 | 20 |
| Joe's Pizza (Maps) | 3 · 02:19 | 20 | 0 | 0 | 20 |
| LA DMV (Maps) | 1 · 00:20 | 20 | — | — | — |
| LA DMV (Maps) | 2 · 01:19 | 20 | 0 | 0 | 20 |
| LA DMV (Maps) | 3 · 02:19 | 20 | 0 | 0 | 20 |
| DoorDash (App Store) | 1 · 00:16 | 50 | — | — | — |
| DoorDash (App Store) | 2 · 01:20 | 50 | 0 | 0 | 50 |
| DoorDash (App Store) | 3 · 02:20 | 50 | 0 | 0 | 50 |
| DoorDash (App Store) | 4 · 03:20 | 50 | 0 | 0 | 50 |
| DoorDash (Google Play) | 1 · 00:17 | 40 | — | — | — |
| DoorDash (Google Play) | 2 · 01:20 | 40 | 7 | 5 | 33 |
| DoorDash (Google Play) | 3 · 02:20 | 40 | 6 | 4 | 34 |

![Stacked horizontal bar chart of the star mix of all unique reviews per sample, each bar stacked to 100%, counts inside. Joe's Pizza (Maps), 20 reviews: 1 star 1, 2 stars 1, 3 stars 4, 4 stars 4, 5 stars 10. LA DMV (Maps), 20: 5, 1, 2, 4, 8. DoorDash (App Store), 50: 20, 7, 4, 1, 18. DoorDash (Google Play), 53: 24, 5, 2, 3, 19. MyChart (App Store), 50: 11, 4, 4, 1, 30. MyChart (Google Play), 40: 10, 3, 0, 2, 25. 1 and 2 star segments are teal. Conclusion: both DoorDash stores had more 1-star than 5-star reviews; half of Joe's Pizza was 5-star.](https://everyinfra.com/articles/sms-mcp-review-alerts-google-maps-app-reviews/fig-02-star-mix.en.light.svg)

Joe's Pizza returned 20 reviews in poll 1, from November 12, 2026 to November 13, 2026. They span 35.7 hours, and the median gap between two reviews is 0.61 hours. At that rate the shop gets about 12.8 reviews a day. The 20 reviews also contain two long gaps, one of 7.7 hours and one of 9.75 hours.

The next two polls returned the same 20 reviews. So there were no new reviews in the two hours that we watched. For a review alert, an hourly check usually returns the same reviews.

The LA DMV was quieter. Its 20 reviews run from October 20, 2026 to November 12, 2026, which is 551 hours, or 0.8 reviews a day. The median gap is 14.6 hours and the longest gap is 117.8 hours. All three polls were the same. A daily check is enough for a place like this. More checks only pay again for the same rows.

On the App Store, DoorDash returned the same 50 reviews in all 4 polls. The newest one was always posted at 2026-11-12T11:26:35Z (19:26 Singapore time on November 12). At poll time it was 28.8 hours old in poll 1 and 31.9 hours old in poll 4.

To tell whether this was the platform or a delay on our side, we read Apple's own public review feed at 01:21 Singapore time. This is the customerreviews RSS feed on `itunes.apple.com` for DoorDash in the US, sorted by most recent. Its first entry has `updated` 2026-11-12T04:26:35-07:00 and 1 star. In UTC that is the same moment and the same rating as the newest review in our response.

So Apple's own public "newest" list was also more than a day old at that moment. A faster poll cannot change that. The newest MyChart App Store review was at 19:35 Singapore time on November 12, only 9 minutes after DoorDash's.

On Google Play, poll 2 for DoorDash (01:20 on November 14, 2026) had 7 new reviews among 40, and 5 of them had 1 star. Poll 3 had 34 IDs from earlier polls and 6 new IDs. Three of the new reviews had 1 star and one had 2 stars.

The list is sorted by newest. In both polls the new reviews came first, ahead of all reviews we had seen before. So they were reviews that had just entered the "newest" list in that hour. Of the four sources, only Google Play had new reviews between every two polls.

![Scatter chart. The x axis runs in Singapore time from Nov 12 to early Nov 14. Four rows: Joe's Pizza (Maps), LA DMV (Maps), DoorDash (Google Play), DoorDash (App Store). Each dot is one review at its posted time. Grey dots came back in poll 1, and teal dots first appeared in later polls. Dashed vertical lines mark the three Joe's Pizza polls. Joe's Pizza dots spread from Nov 12 to the evening of Nov 13 with two empty stretches. The DMV has one dot after Nov 12. All App Store dots are before 19:26 on Nov 12. Google Play has a small run of teal dots near midnight on Nov 13, the 7 new reviews from poll 2. The 6 new reviews from poll 3 are not plotted. Conclusion: only Google Play had new reviews between polls.](https://everyinfra.com/articles/sms-mcp-review-alerts-google-maps-app-reviews/fig-03-new-reviews-timeline.en.light.svg)

![Stacked horizontal bar chart of new versus already-seen reviews in each poll. Joe's Pizza (Maps) poll 2: 0 new, 20 seen before; Joe's Pizza (Maps) poll 3: 0 new, 20 seen before; LA DMV (Maps) poll 2: 0 new, 20 seen before; LA DMV (Maps) poll 3: 0 new, 20 seen before; DoorDash (App Store) poll 2: 0 new, 50 seen before; DoorDash (App Store) poll 3: 0 new, 50 seen before; DoorDash (App Store) poll 4: 0 new, 50 seen before; DoorDash (Google Play) poll 2: 7 new, 33 seen before; DoorDash (Google Play) poll 3: 6 new, 34 seen before. Conclusion: most polls of the newest 20 to 50 rows were all repeats; only Google Play had new IDs each time.](https://everyinfra.com/articles/sms-mcp-review-alerts-google-maps-app-reviews/fig-06-poll-overlap.en.light.svg)

The polls overlapped on 297 rows in total (20+20+20+20+50+50+50+33+34). Every overlapping review kept exactly the same ID. No review came back with the same author, time and text under a new ID. On Google Play, the only pair with the same text and different IDs came from two different users who both wrote one word, "expensive". So the review ID is a safe dedupe key for all four sources.

A timestamp is a poor dedupe key for two reasons. First, authors edit reviews: the Google Play developer docs return "created or edited" reviews together. Second, reviews arrive late. Our post [BL-79](/blog/claude-managed-agents-nightly-review-monitoring) recorded a review whose `posted_at` was before the previous poll, yet the previous poll did not return it. A rule of "posted after the newest time I saw" would miss that review.

Only Google Play had new reviews within these hours; the two Maps places and the App Store had none. So the "new reviews per day" figures in the next section come from the gaps between neighboring `posted_at` values in a single response. They are estimates.

| Sample | Reviews used | Time span | Median gap | Longest gap |
| --- | --- | --- | --- | --- |
| Joe's Pizza (Maps) | 20 | 35.7 h | 0.61 h | 9.75 h |
| LA DMV (Maps) | 20 | 551.2 h | 14.63 h | 117.81 h |
| DoorDash (App Store) | 50 | 11.7 h | 0.11 h | 2.33 h |
| DoorDash (Google Play) | 47 | 15.2 h | 0.20 h | 2.45 h |
| MyChart (App Store) | 50 | 39.6 h | 0.35 h | 7.12 h |
| MyChart (Google Play) | 40 | 16.9 h | 0.29 h | 1.32 h |

The DoorDash (Google Play) row uses the 47 reviews from polls 1 and 2. The longest gap column shows that even a source with a median gap under one hour can go several hours without a new review. An hour with no new review is normal.

| Source type | New reviews in our polls | Suggested schedule | Reason |
| --- | --- | --- | --- |
| Busy place on Maps | 0 in 2 hours; about 12.8 a day from one response | Every hour while open | Reviews come in bursts; gaps reached 9.75 hours |
| Quiet counter on Maps | 0; about 0.8 a day | Once a day | Less than one review a day, so more checks return the same rows |
| App Store | 0 in 3 hours | Once a day | The "newest" list was 28.8 to 31.9 hours old, same as Apple's public feed |
| Google Play | 6 to 7 per poll | Once or twice a day, or an hourly summary | New reviews every poll, but half are 1 or 2 stars, so one text per review is too many |

## Two idempotency keys: one charge per hour, one text per review

Polling has two common accidents. One check is resent several times and charged several times. Or one bad review sends the owner several texts.

Both have the same cause. A script retries after a timeout, scheduled jobs overlap, or a process crashes and restarts. At the moment of the resend, the client does not know whether the first try worked. Both have the same fix. Give each logical action a stable name, and let the server or a local table do it once per name.

On the data side, EveryInfra's `POST /api/v1/social` accepts an `Idempotency-Key` header of 1 to 255 visible ASCII characters. Within 24 hours, the same request with the same key returns the first successful response. It does not run again and does not charge again.

The body carries `replayed: true` and the header carries `Idempotent-Replayed: true`. The same key with different parameters returns `409 idempotency_conflict` ([EveryInfra llms-full.txt, Retries and idempotency](https://api.everyinfra.com/llms-full.txt); the same header and error code are in [openapi.json](https://api.everyinfra.com/openapi.json)).

We build the key from the source name and the UTC hour, for example `alert:gmaps:la-dmv-hope-st:2026111316`. However many times the script reruns within that hour, it pays once. In the next hour the key changes and the script reads new reviews as usual. Send scheduled jobs and any call that retries on its own through this REST path. Our [API idempotency key tests](/blog/api-idempotency-key-ai-agent-retry) (BL-115) cover the other retry cases.

At 00:35:02 and 00:35:10 Singapore time we sent the same DMV request twice with the same key. The first call returned HTTP 200 with 10 reviews and cost $0.001389. The second returned HTTP 200 with the header `idempotent-replayed: true`, the body field `replayed: true` and the same 10 reviews.

Then we checked the account request log with the MCP tool `everyinfra_list_requests`. The first call had a charge record. The second added no new charge.

![Screenshot of a real EveryInfra response: the second google_maps_reviews/reviews request with the same idempotency key, Idempotency-Key bl146:gm:dmv-hope-st:2026111400, sent at 00:35:10 Singapore time, HTTP 200. Teal boxes mark two items: the response header idempotent-replayed true and the body field replayed true. Reviewer names are hidden and review text is cut short.](https://everyinfra.com/articles/sms-mcp-review-alerts-google-maps-app-reviews/img-shot-replay-response.webp)

The second request with the same key replays the first response, and the account log shows one charge. [Live EveryInfra response, 2026-11-14 00:35 SGT](https://api.everyinfra.com/api/v1/social)

The SMS side is different. In the Twilio Message resource docs ([Twilio Message resource](https://www.twilio.com/docs/messaging/api/message-resource), read November 14), the create parameters include no idempotency key. Two POSTs of the same text send two texts and cost twice. TrueDialog's `send_sms` shows no idempotency parameter on the connector page or on tdmcp.com, only the dry run switch. So "one text per review" must be enforced on your side.

We use a local outbox table keyed by source and review ID. A new review goes in with `INSERT OR IGNORE`. A key conflict means the review is already queued, so the script skips it.

Before sending, the script sets the status to `sending` and commits, and after sending it sets `sent`. If the process crashes during a send, that row stays at `sending`. The next run does not resend it, so a person can look at it.

Missing one text that a person can send by hand is better than three identical texts to the owner. Duplicate texts make people trust the alert less, and they cost more.

| Risk | Where it happens | Our defense | Test or source |
| --- | --- | --- | --- |
| One check charged twice | Data API retry after timeout, overlapping jobs | REST request with `Idempotency-Key` = source + UTC hour | Second call replayed, no new charge in the account log |
| One review alerted twice | Two polls return the same review | Local table dedupes by review ID | 297 overlapping rows, all IDs the same |
| One text sent twice | SMS APIs have no idempotency key; crash during send | Outbox, set `sending` before sending | Twilio create parameters have no idempotency key |
| A failed check read as "no new reviews" | API returns a retryable error and the script goes on | After 3 failed tries, raise; mark the poll as not checked and catch up on the next poll | [llms-full.txt](https://api.everyinfra.com/llms-full.txt) error fields `retryable` and `retry_after` |
| Charged for an empty result | `since` set to today with no new review today | Empty results are free | DMV `since=2026-11-13` returned 0 rows, $0 |

A failed check does not mean no new reviews. Mark that poll as not checked, leave the `seen` table alone, and check again on the next poll with a new key. Any missed review will be in the next newest 20. The script below follows this rule.

```text
# review_alert.py: run once an hour. DRY_RUN=1 prints the texts instead of sending them.
import hashlib, json, os, sqlite3, time, urllib.error, urllib.request
from datetime import datetime, timezone

API, KEY = "https://api.everyinfra.com/api/v1/social", os.environ["EVERYINFRA_API_KEY"]
DRY_RUN = os.environ.get("DRY_RUN") == "1"
LINK_BASE = os.environ.get("ALERT_LINK_BASE", "https://example.com")   # your own page that shows the review
DB = sqlite3.connect("review_alert.db")
DB.executescript("""
CREATE TABLE IF NOT EXISTS seen   (source TEXT, review_id TEXT, rating INT, posted_at TEXT, first_seen TEXT,
                                   PRIMARY KEY (source, review_id));
CREATE TABLE IF NOT EXISTS outbox (source TEXT, review_id TEXT, stars INT, status TEXT, created TEXT,
                                   PRIMARY KEY (source, review_id));""")
SOURCES = {"gmaps:la-dmv-hope-st": {"platform": "google_maps_reviews", "action": "reviews", "params": {
    "url": "https://www.google.com/maps/search/?api=1&query=Los%20Angeles%20DMV&query_place_id=ChIJAQOgfwrIwoARag3eO_IQ0oE",
    "sort": "newest", "limit": 20}}}
SHORT_NAME = {"gmaps:la-dmv-hope-st": "LA DMV Hope St"}             # ASCII only: keeps each text GSM-7

def call(source, body):
    key = f"alert:{source}:{datetime.now(timezone.utc):%Y%m%d%H}"      # same hour, same Idempotency-Key
    req = urllib.request.Request(API, json.dumps(body).encode(), method="POST", headers={
        "Authorization": f"Bearer {KEY}", "Content-Type": "application/json", "Idempotency-Key": key})
    for _ in range(3):
        try:
            with urllib.request.urlopen(req, timeout=100) as r:
                return json.load(r)
        except urllib.error.HTTPError as e:
            err = json.load(e).get("error", {})
            if e.code in (429, 502, 503, 504) or err.get("retryable"):
                time.sleep(int(err.get("retry_after") or 20)); continue   # same key on retry: charged once
            raise
    raise RuntimeError(f"{source}: no result after 3 tries")             # a failed check is not "no new reviews"

def review_key(r):   # review id first; fallback hash uses each platform's author field
    author = r.get("reviewer_name") or r.get("author_name") or r.get("author")
    return r.get("id") or hashlib.sha256(f"{author}|{r.get('posted_at')}|{r.get('text')}".encode()).hexdigest()

def link(source, rid=""):
    return f"{LINK_BASE}/r/{hashlib.sha256(f'{source}|{rid}'.encode()).hexdigest()[:6]}"

def run():
    now = datetime.now(timezone.utc).isoformat(timespec="seconds")
    for source, body in SOURCES.items():
        try:
            rows = call(source, body).get("results", [])
        except RuntimeError as e:                    # mark this hour "not checked"; seen stays as it was
            print(e); continue
        for r in rows:
            stars, rid = r.get("rating") or r.get("score"), review_key(r)
            if DB.execute("INSERT OR IGNORE INTO seen VALUES (?,?,?,?,?)",
                          (source, rid, stars, r.get("posted_at"), now)).rowcount == 0:
                continue                                                # seen before
            if stars is not None and stars <= 2:
                DB.execute("INSERT OR IGNORE INTO outbox VALUES (?,?,?,?,?)", (source, rid, stars, "pending", now))
        DB.commit()

def flush(send):     # one text per source per run; mark "sending" first so a crash never resends
    for (source,) in DB.execute("SELECT DISTINCT source FROM outbox WHERE status='pending'").fetchall():
        rows = DB.execute("SELECT review_id, stars FROM outbox WHERE source=? AND status='pending'", (source,)).fetchall()
        if len(rows) == 1:
            body = f"{rows[0][1]}-star review: {SHORT_NAME[source]} {link(source, rows[0][0])}"
        else:
            body = f"{len(rows)} new 1-2 star reviews: {SHORT_NAME[source]} {link(source)}"
        body.encode("ascii")                                            # raises if a non-GSM character slips in
        DB.execute("UPDATE outbox SET status='sending' WHERE source=? AND status='pending'", (source,)); DB.commit()
        send(body)
        DB.execute("UPDATE outbox SET status='sent' WHERE source=? AND status='sending'", (source,)); DB.commit()

def send_sms(body):
    raise NotImplementedError("connect your SMS provider here (Twilio Messages API or TrueDialog)")

if __name__ == "__main__":
    run(); flush(print if DRY_RUN else send_sms)
```

We ran the data part of the script live twice, at 00:37:20 and 00:37:31 Singapore time. The first run read 20 DMV reviews, all new. Six of them had 1 or 2 stars and went into the outbox, and the run cost $0.001389.

The second run was in the same UTC hour with the same key. The API replayed, the script found 0 new reviews, the outbox did not grow, and the account log showed no second charge.

The version above adds a `DRY_RUN` switch, a `flush()` that merges each source into one text per run, and an ASCII-only text template. We fed it the raw DMV response from poll 1 and ran it twice offline, with no API call. The first run printed one text, `6 new 1-2 star reviews: LA DMV Hope St https://example.com/r/2ff3c3`, which has 67 characters. The second run printed nothing. `send_sms()` is a stub for your own SMS provider.

## How many reviews are 1 or 2 stars, and how many texts per day?

Text volume depends on two things: how fast new reviews come, and how many of them have 1 or 2 stars. The table merges all polls and dedupes by review ID. "New reviews per day" comes from the `posted_at` span of each sample's newest rows, so it is an estimate. "1–2 star per day" multiplies the two columns. We pulled the two MyChart samples once, so their numbers come from one response.

| Sample | Unique reviews | 1–2 star | Share | New reviews per day (from posted_at) | 1–2 star per day (estimate) |
| --- | --- | --- | --- | --- | --- |
| Joe's Pizza (Maps) | 20 | 2 | 10.0% | 12.8 | 1.3 |
| LA DMV (Maps) | 20 | 6 | 30.0% | 0.8 | 0.2 |
| DoorDash (App Store) | 50 | 27 | 54.0% | 100.9 | 54.5 |
| DoorDash (Google Play) | 53 | 29 | 54.7% | 72.4 | 39.6 |
| MyChart (App Store) | 50 | 15 | 30.0% | 29.7 | 8.9 |
| MyChart (Google Play) | 40 | 13 | 32.5% | 55.4 | 18.0 |

![Horizontal bar chart of the share of 1 and 2 star reviews among unique reviews. Joe's Pizza (Maps) 10.0% (2/20); LA DMV (Maps) 30.0% (6/20); DoorDash (App Store) 54.0% (27/50); DoorDash (Google Play) 54.7% (29/53); MyChart (App Store) 30.0% (15/50); MyChart (Google Play) 32.5% (13/40). The DoorDash App Store bar is teal. Conclusion: with the same rule, about half of the delivery app's newest reviews were bad, and one in ten at the busy pizza shop.](https://everyinfra.com/articles/sms-mcp-review-alerts-google-maps-app-reviews/fig-04-low-star-share-bar.en.light.svg)

Does one poll give a biased share? The next table shows the 1 or 2 star share in each poll. The two Maps places and the App Store returned the same reviews each time, so their share did not move.

Google Play had new reviews every poll, and its share rose from 50.0% to 60.0%. In poll 3, 4 of the 6 new reviews had 1 or 2 stars. With three polls, this rise only shows that a few bad reviews in one hour can move the share by 7.5 points. It does not show that DoorDash's reputation got worse.

| Sample | Poll 1 | Poll 2 | Poll 3 | Poll 4 |
| --- | --- | --- | --- | --- |
| Joe's Pizza (Maps) | 2/20, 10.0% | 2/20, 10.0% | 2/20, 10.0% | — |
| LA DMV (Maps) | 6/20, 30.0% | 6/20, 30.0% | 6/20, 30.0% | — |
| DoorDash (App Store) | 27/50, 54.0% | 27/50, 54.0% | 27/50, 54.0% | 27/50, 54.0% |
| DoorDash (Google Play) | 20/40, 50.0% | 21/40, 52.5% | 24/40, 60.0% | — |

The star mix in fig-02 shows one more thing: reviews pile up at both ends. Both DoorDash stores had more 1-star than 5-star reviews (20 to 18 on the App Store, 24 to 19 on Google Play). Each store had only 5 reviews with 3 or 4 stars. On both MyChart stores, 5-star reviews were about 60% (30/50 and 25/40), and the bad reviews were mostly 1-star. Half of Joe's Pizza was 5-star, with one 1-star and one 2-star review.

For alert rules, this means the choice between "2 stars or less" and "1 star only" changes little. On DoorDash the difference is 12 reviews (7 + 5). On Joe's Pizza it is 1 review. So if the volume is too high, a stricter star filter helps only a little.

Joe's Pizza had only 2 reviews with 1 or 2 stars among 20, about 1.3 a day by our estimate. One text per review is fine there. The DMV's share was 30.0%, but it gets so few reviews that the estimate is 0.2 a day. About half of DoorDash's newest reviews had 1 or 2 stars in both stores. The estimate is about 94 a day for both stores together (54.5 + 39.6).

Nobody can read one text per review at that volume. Use one of two rules instead. Rule one is "at most one text per hour": if the hour had bad reviews, send one text such as "12 new 1-2 star reviews in the last hour" with a link to the full list. The `flush()` in the script above already merges each source into one text per run.

Rule two is "only above normal". Run with `DRY_RUN=1` for one week and count the median number of bad reviews per hour. Then text only when an hour has more than twice the median. That usually means an outage or a bad release. Neither rule changes the data cost; both change only the number of texts.

![Grouped horizontal bar chart of texts per month, log scale with each step 10x. Joe's Pizza (Maps) sends about 39 texts with one per review and 39 with at most one per hour. The LA DMV (Maps) sends about 6 either way. DoorDash, both stores, sends about 2,823 with one per review and at most 390 with one per opening hour, shown in teal. Conclusion: for quiet places both rules are the same; a large app must merge.](https://everyinfra.com/articles/sms-mcp-review-alerts-google-maps-app-reviews/fig-07-sms-volume-bar.en.light.svg)

Almost half of the Google Maps reviews had stars and no text: 9 of 20 for both Joe's Pizza and the DMV. Every app store review in our samples had text.

## The review alert SMS budget: 24 checks a day or one

Data pricing is simple. In the catalog, `google_maps_reviews/reviews`, `app_store/reviews`, `google_play/reviews` and `yelp/reviews` all cost $0.001389 per call. One call returns at most 100, 500, 200 and 10 reviews. You pay per call, not per review, and empty results are free (catalog read on November 14, 2026; see [pricing](/pricing)).

Our test made 21 charged calls. The account log shows $0.029167 in total, which equals 21 × $0.00138889. The replay with the same key and the two empty results were free.

| Plan | Calls per day | Data cost per day | Data cost per 30 days | Good for |
| --- | --- | --- | --- | --- |
| 1 source, once a day | 1 | $0.0014 | $0.042 | Quiet places such as a DMV counter |
| 1 source, every hour | 24 | $0.0333 | $1.00 | Busy shops that act the same day |
| 3 sources, once a day | 3 | $0.0042 | $0.125 | One app in two stores plus one place |
| 3 sources, every hour | 72 | $0.1000 | $3.00 | On-call alerts for a chain |
| 3 sources, every opening hour (9:00–21:00, 13 checks) | 39 | $0.0542 | $1.63 | Shops that want no texts at night |

![Horizontal bar chart of monthly data cost. One source once a day costs $0.042. One source every hour costs $1.00. Three sources once a day cost $0.125. Three sources every hour cost $3.00. For reference, a Twilio US local number costs $1.15 a month. Conclusion: hourly checks on one source cost less per month than one SMS number.](https://everyinfra.com/articles/sms-mcp-review-alerts-google-maps-app-reviews/fig-05-monthly-cost-bar.en.light.svg)

Compare "once a day" with "24 times a day" for each sample, and the difference is what you get to see. In the next table, "new reviews per check" is the estimated rate from the last section times the hours between two checks. It is capped by the rows one call returns. Above the cap, more reviews arrive between two checks than one call can return, so some are missed.

| Sample (rows per call) | Once a day: 30-day cost | Once a day: new per check | 24 a day: 30-day cost | 24 a day: new per check |
| --- | --- | --- | --- | --- |
| Joe's Pizza (20) | $0.042 | About 12.8, under 20 | $1.00 | About 0.5 |
| LA DMV (20) | $0.042 | About 0.8 | $1.00 | About 0.03 |
| DoorDash App Store (50) | $0.042 | About 100.9, over 50 | $1.00 | About 4.2 |
| DoorDash Google Play (40) | $0.042 | About 72.4, over 40 | $1.00 | About 3.0 |

For the DMV, the extra $0.96 for 24 checks a day buys almost nothing but repeats. For both DoorDash stores, a daily check misses more than half of the new reviews. Either check every hour, or check daily with `limit` at 200 or more (the App Store returns up to 500 and Google Play up to 200). Both cost $0.001389 per call.

Most of the total cost is on the SMS side. Three sources checked every hour cost $3.00 a month in data. The Twilio US pricing page says a text from a standard 10-digit number costs $0.0083 per segment. Carriers add a fee, for example $0.0035 per segment for AT&T and $0.0045 for T-Mobile.

A message that ends in a "failed" state costs a $0.001 processing fee ([Twilio US SMS pricing](https://www.twilio.com/en-us/sms/pricing/us); the page says "prices as of November 2026"). Numbers start at $1.15 a month ([Twilio phone number pricing](https://www.twilio.com/en-us/phone-numbers)).

Add the 10DLC brand fee of $4.50 one time, $15 vetting per campaign, and a monthly fee per campaign. With these list prices, a one-segment text costs about $0.0118 to $0.0128. Most of the money goes to the number, registration and monthly fees.

| Item | Twilio | TrueDialog |
| --- | --- | --- |
| Per text | $0.0083 per segment plus carrier fee | Included in plan (Small Business: 5,000 texts) |
| Number | US local number from $1.15 a month | Long code $9.99 a month |
| 10DLC | Brand $4.50 once, $15 vetting per campaign, plus monthly fee | Pricing page lists automatic 10DLC registration |
| Minimum monthly fee | None, pay as you go | $119 a month, annual contract |
| Send SMS through MCP | Its own MCP server only searches docs | Yes, no extra MCP fee |

TrueDialog sells monthly plans, in four tiers on its pricing page.

Small Business is $119 a month with 5,000 texts and $0.024 per extra text. Professional is $425 with 25,000 texts. Enterprise is $900 with 60,000 texts. Custom starts at $1,000 a month. All are annual contracts.

Carrier fees are extra. A long code costs $9.99 a month and a short code $799 a month ([TrueDialog pricing](https://www.truedialog.com/pricing/), read November 14). The press release says MCP has no extra fee, so a text sent through Claude costs the plan price.

By our estimate, a shop like Joe's Pizza sends about 39 alerts a month. That is less than 1% of the 5,000 texts in Small Business. A business that already uses TrueDialog for marketing texts can add the alerts to its current account.

| One shop, one month | Data cost | Texts (estimate) | SMS cost (Twilio, at $0.0128 a text) | Number | Total (without 10DLC fees) |
| --- | --- | --- | --- | --- | --- |
| Busy shop like Joe's Pizza, hourly | $1.00 | About 39 | $0.50 | $1.15 | $2.65 |
| Counter like the DMV, once a day | $0.042 | About 6 | $0.08 | $1.15 | $1.27 |
| Large app like DoorDash, two stores hourly, one text per review | $2.00 | About 2,823 | $36.13 | $1.15 | $39.28 |

Texts are the estimated 1 or 2 star reviews per day from the last section times 30, so they show the scale only. A large app that texts every review sends about 2,823 texts a month. With at most one text per opening hour it sends at most 390, about $4.99 at the same price per text.

## Compliance: 10DLC, opt-out words and the FCC rule that starts November 25

In the United States, application-to-person texts from an ordinary 10-digit number (10DLC) need a brand and campaign registration with The Campaign Registry. The Twilio help center lists three fees.

A Low Volume Standard brand costs $4.50 one time. Each campaign costs $15 for vetting and then a monthly fee ([Twilio Help Center: A2P 10DLC fees](https://help.twilio.com/articles/1260803965530-What-pricing-and-fees-are-associated-with-the-A2P-10DLC-service-)). The TrueDialog pricing page says it registers 10DLC for you, and its team helps with 10DLC and short code registration ([TrueDialog pricing](https://www.truedialog.com/pricing/)).

Opt-out comes next. The CTIA Messaging Principles and Best Practices name STOP as the standard opt-out keyword. They also ask senders to honor more than one opt-out method ([CTIA Messaging Principles and Best Practices, May 2023](https://api.ctia.org/wp-content/uploads/2023/05/230523-CTIA-Messaging-Principles-and-Best-Practices-FINAL.pdf)). The TrueDialog press release says the platform enforces opt-outs on its own ([PR Newswire release](https://www.prnewswire.com/news-releases/truedialog-launches-mcp-for-chatgpt-copilot-and-other-ai-assistants-302935019.html)).

The third item is the updated FCC rule on how people revoke consent.

The FCC adopted the changes on September 30, 2026, according to [Kelley Drye's summary](https://www.kelleydrye.com/viewpoints/blogs/ad-law-access/fcc-revises-tcpa-consent-revocation-rules-exclusive-opt-out-methods-category-specific-revocations-and-other-key-changes). The Federal Register published the rule on October 26, 2026, and it takes effect on November 25, 2026 ([Federal Register 2026-21821](https://www.federalregister.gov/documents/2026/10/26/2026-21821/enhancing-the-ability-of-consumers-to-control-the-robocalls)). The summary lists three points.

A sender can treat a revocation as limited to the category of informational messages that it answers. A sender can name one exclusive method for revocation. The exemption for financial fraud alerts is wider.

The FCC fact sheet from September 9 is also online ([FCC fact sheet PDF](https://docs.fcc.gov/public/attachments/DOC-424844A1.pdf)). These rules concern how recipients opt out and which messages must stop after that. Ask a lawyer which part applies to you. We only give the source text and the dates.

| Item | What to do | Fee or date | Source |
| --- | --- | --- | --- |
| 10DLC brand | Register the sender brand with The Campaign Registry | $4.50 one time for a Low Volume Standard brand | Twilio Help Center |
| Campaign vetting | Vet each campaign once | $15 each, then a monthly fee | Twilio Help Center |
| Minimum term | Campaigns have a three-month minimum, except political | Page updated 2026-09-16 | [Bandwidth Support](https://www.bandwidth.com/support/en/articles/12823086-10dlc-fees) |
| Opt-out keyword | Support STOP and more than one opt-out method | No fee | CTIA, May 2023 |
| FCC revocation rule | Check opt-out scope and the exclusive method | Published 2026-10-26, effective 2026-11-25 | Federal Register 2026-21821 |

## What goes into the text: 160 characters, never the full review

A standard US text is billed in segments of 160 characters. A longer text splits into two segments and costs two. The FAQ on the Twilio US pricing page says billing is per segment ([Twilio US SMS pricing](https://www.twilio.com/en-us/sms/pricing/us)).

The Twilio character limit page names characters outside GSM-7, such as an emoji, a Chinese character or a curly quote. One such character switches the whole message to UCS-2. Then one segment holds only 70 characters ([Twilio: How long can a message be?](https://www.twilio.com/docs/glossary/what-sms-character-limit)). So the alert holds three things only: the stars, the place or app, and a link. Write them in English with ASCII characters, as the script template does.

| In the text | Example | Characters | Note |
| --- | --- | --- | --- |
| Stars | 1-star | 6 | Write it in English; the star symbol "★" is not in GSM-7 and turns the whole text into UCS-2, 70 characters a segment |
| Place or app | LA DMV Hope St | 14 | Use an internal short name, never the reviewer's name |
| Link | https://example.com/r/2ff3c3 | 28 | Points to your own system, where the full review opens |
| Total (one review, with separators) | 1-star review: LA DMV Hope St https://example.com/r/2ff3c3 | 58 | Under 160 characters, billed as one segment |
| Total (hourly summary) | 6 new 1-2 star reviews: LA DMV Hope St https://example.com/r/2ff3c3 | 67 | The text that the offline run printed |
| Leave out | Review text, staff looks and counter numbers, details that identify a patient | — | Privacy, and harm to coworkers |

Among the 20 DMV reviews, 2 of the 6 bad reviews described staff in a way that identifies them. One named a security guard and one named the clerk at a numbered window, in harsh words. If you forward such text to a dozen staff phones, you broadcast an accusation against one coworker.

Health care has its own precedents. The HHS Office for Civil Rights (OCR) has published settlements with practices that disclosed patient information when they answered online reviews. On June 5, 2023, it announced a case in which a New Jersey psychiatric practice disclosed information about four patients in replies to Google reviews. The settlement was $30,000 ([HHS: Manasa Health Center settlement](https://www.hhs.gov/hipaa/for-professionals/compliance-enforcement/agreements/manasa/index.html); amount in the [HHS 2023 report](https://www.hhs.gov/sites/default/files/compliance-report-to-congress-2023.pdf)).

On December 14, 2022, HHS announced a case about a dental practice. It disclosed patient information in replies on social media ([HHS: New Vision Dental settlement](https://www.hhs.gov/hipaa/for-professionals/compliance-enforcement/agreements/new-vision/index.html); all agreements on the [HHS resolution agreements page](https://www.hhs.gov/hipaa/for-professionals/compliance-enforcement/agreements/index.html)). Both cases started with patient information in a reply to a review. A text alert is not a reply to a review. For how to handle a case, follow your organization's privacy policy and legal advice.

The FTC Consumer Reviews and Testimonials Rule, §465.7, prohibits unfounded legal threats, intimidation and false accusations used to suppress reviews. It also prohibits hiding reviews because of their rating ([16 CFR §465.7](https://www.ecfr.gov/current/title-16/chapter-I/subchapter-D/part-465); FTC Q&A at [Consumer Reviews and Testimonials Rule Q&A](https://www.ftc.gov/business-guidance/resources/consumer-reviews-testimonials-rule-questions-answers)).

## Another domain: community clinics and public service counters

The same method works for community clinics, outpatient desks, DMV offices and social service counters with almost no technical change. What changes is who gets the text, what it says, and how often someone looks. This section covers data methods only. It makes no medical judgment and is not legal or medical advice. Our two comparison samples are the DMV office on Hope Street in Los Angeles and MyChart. Many US health systems give the MyChart app to patients.

The DMV sample has few reviews but many bad ones. In the poll at 00:20 Singapore time on November 14, the newest 20 reviews had five 1-star and one 2-star, 30% in total. Their `posted_at` values run from October 20, 2026 to November 12, 2026, less than one a day.

Ten of them are from November 1, 2026 or later, and 5 of those 10 have stars only and no text. An hourly check makes no sense for a place like this. A daily check covers it for $0.001389 a day. The alert script must handle empty text; the template above leaves out the review text, so an empty text cannot break it.

The MyChart sample shows how app reviews differ from place reviews. On the App Store, 50 reviews had eleven 1-star and four 2-star, 30%. On Google Play, 40 reviews had ten 1-star and three 2-star, 32.5%.

All reviews in both stores had text. The 13 bad Google Play reviews average 96 characters, and bad App Store reviews often have a title. We sorted the 15 bad App Store reviews by keyword, and one review can match more than one group. Six mention messages or appointments, 2 mention sign-in or codes, and 2 mention an update. This kind of grouping belongs in a daily summary for the patient experience lead, not in one text per review for front-line staff.

Public bodies can compare this with two existing frameworks. The Agency for Healthcare Research and Quality (AHRQ) defines the CAHPS surveys as patient-reported measures of care experience. Its page separates "patient experience" from "patient satisfaction". It says open-ended comments help find safety issues ([AHRQ: What Is Patient Experience?](https://www.ahrq.gov/cahps/about-cahps/patient-experience/index.html); CAHPS home at [ahrq.gov/cahps](https://www.ahrq.gov/cahps/index.html); CMS page at [CMS: CAHPS](https://www.cms.gov/data-research/research/consumer-assessment-healthcare-providers-systems)).

For federal service counters, OMB Circular A-11 Section 280 applies to designated High Impact Service Providers. They run post-transaction feedback surveys and report the feedback to OMB every quarter. They also use it for improvement and "service recovery" ([A-11 Section 280 explainer](https://www.performance.gov/cx/a-11/)). Online reviews differ from these surveys. They are not sampled, not verified, and have no standard questions. Use them as an early signal, not as a replacement for a formal survey.

For the workflow, a clinic or counter can split alerts into two tiers. Tier one is a text to the person on duty only. It holds the stars, the place and a link, with no review text and no word that could identify a patient or condition. Tier two is a daily summary for the quality or experience lead, grouped by topic (wait time, appointments, attitude, system errors). A bad review that names a staff member goes to a supervisor to check first.

| Tier | Who gets it | Content | When |
| --- | --- | --- | --- |
| Tier one: text | One person on duty | Stars, place, link; no review text, no word that identifies a patient | At the next check after a new 1 or 2 star review |
| Tier two: daily summary | Quality or patient experience lead | Counts and summaries grouped by wait time, appointments, attitude, system errors | Once a day |
| Review that names staff | Supervisor | Review text and link, not broadcast | When it appears |

## Connect both sides through MCP (configuration example)

A scheduled script can run the whole flow on its own. An AI assistant adds value when it reads the bad review and writes one line for the owner. It can also decide whether to escalate to a regional manager.

Below, Claude connects to two remote MCP servers. EveryInfra looks up capabilities, checks billing and reads the new reviews that the script prepared. TrueDialog sends the text. We called EveryInfra's `tools/list` and `tools/call` live. We have no TrueDialog account, so that side is a configuration example from tdmcp.com and the Claude Help Center.

In the Claude desktop app or on claude.ai, open "Custom connectors" as the Claude Help Center describes. Add a remote MCP server by name and URL. The connection starts from Anthropic's cloud, so the server must be reachable from the public internet ([Claude Help Center: custom connectors](https://support.claude.com/en/articles/11175166-getting-started-with-custom-connectors-using-remote-mcp)).

For TrueDialog, enter `https://connect.tdmcp.com/`, click connect and sign in to TrueDialog in the browser. For EveryInfra, enter `https://api.everyinfra.com/mcp` and add your key as the [MCP setup page](/mcp-server) shows. In Claude Code, add a remote HTTP server with `claude mcp add --transport http` ([Claude Code MCP docs](https://code.claude.com/docs/en/mcp)). For scheduled runs, use the non-interactive `claude -p` ([Claude Code headless mode](https://code.claude.com/docs/en/headless)).

```text
{
  "mcpServers": {
    "everyinfra": {
      "type": "http",
      "url": "https://api.everyinfra.com/mcp",
      "headers": { "Authorization": "Bearer ${EVERYINFRA_API_KEY}" }
    },
    "truedialog": {
      "type": "http",
      "url": "https://connect.tdmcp.com/"
    }
  }
}
```

At 00:29 Singapore time we called EveryInfra's `tools/list` live. It returned 12 tools. The tool that reads reviews is `everyinfra_call_api`, with the annotations `readOnlyHint: false`, `destructiveHint: true` and `openWorldHint: true`, because it charges. `everyinfra_list_capabilities`, `everyinfra_get_job` and `everyinfra_list_requests` are all read-only. `everyinfra_call_api` takes four parameters: `platform`, `action`, `params` and `mode`.

Leave the hourly job to the script above, which uses REST with an `Idempotency-Key`. The AI assistant reads the new reviews that the script prepared, writes the summary and decides whether to escalate.

At 00:35 and 00:36 we called `google_play/reviews` twice through MCP. The first call used the wrong MyChart package name, `com.epic.mychart.android`. It returned 0 rows with no charge and the reason `empty_result_refunded`. With the correct `epic.mychart.android`, it returned 40 rows and cost $0.001389.

| Tool | From | Read-only | Job in this alert |
| --- | --- | --- | --- |
| `everyinfra_list_capabilities` | EveryInfra | Yes | Look up capabilities, parameters and prices, free |
| `everyinfra_call_api` | EveryInfra | No (charges) | Ad hoc check of one place; the hourly job uses REST with `Idempotency-Key` |
| `everyinfra_list_requests` | EveryInfra | Yes | Billing check: which calls were charged |
| `send_sms` | TrueDialog | No (sends texts) | Sends the alert; `execute=false` is a dry run (configuration example, not tested) |

```text
Run every hour from 9:00 to 21:00:
1. Read the rows with status pending in the outbox table of review_alert.db (the scheduled script writes them).
2. For each source, write one English text of 60 characters or less. No reviewer names, no staff looks, no counter numbers, ASCII only.
3. Call truedialog send_sms with execute=false first and show me what would be sent. Use execute=true only after I reply "send".
4. Send at most one text per source per hour.
```

Step 3, "dry run first, send after a person agrees", follows the connector page note that `send_sms` sends by default. The TrueDialog press release says developers can give an agent read-only tools. If you want an unattended hourly send, the agent calls `send_sms` directly. Then fix the recipient list in the prompt, and do not let the model look up contacts.

## How this guide differs from related posts

Our other posts do not cover the SMS channel or the hourly cost. [BL-88](/blog/claude-duet-shop-owner-google-maps-reviews) shows three small shops that use Claude Duet for a morning review report. It found that small shops had new reviews on only 4 to 8 of the last 90 days, so a daily look is enough.

[BL-79](/blog/claude-managed-agents-nightly-review-monitoring) runs Claude Managed Agents every night across Google, Yelp and Tripadvisor. It found a review whose `posted_at` was before the previous poll, yet the previous poll did not return it, so a time-only rule misses reviews. [BL-70](/blog/how-to-scrape-google-maps-reviews) compares ways to get Google Maps reviews, including the 5-review limit of the Places API.

[BL-115](/blog/api-idempotency-key-ai-agent-retry) tests every retry case for idempotency keys. For the tool choice side, see [data APIs and tool routing](/blog/data-api-and-tool-router-monid).

## Industry news

| Date | Event | What it means for review alert SMS | Source |
| --- | --- | --- | --- |
| 2026-11-10 | TrueDialog launches TrueDialog MCP | Add a connector to an assistant to send texts; number registration and opt-out still happen on the SMS platform | [PR Newswire](https://www.prnewswire.com/news-releases/truedialog-launches-mcp-for-chatgpt-copilot-and-other-ai-assistants-302935019.html) |
| 2026-10-28 | TikTok launches the Must Eat restaurant guide | Restaurants have one more review source to watch | [TikTok](https://usdsjv.tiktok.com/TikTok-Must-Eat) |
| 2026-10-26 | FCC consent revocation rule published, effective 2026-11-25 | Check your opt-out flow against the new rule | [Federal Register](https://www.federalregister.gov/documents/2026/10/26/2026-21821/enhancing-the-ability-of-consumers-to-control-the-robocalls) |
| 2026-09-16 | Bandwidth updates its 10DLC fee page | Campaign registration has a three-month minimum | [Bandwidth](https://www.bandwidth.com/support/en/articles/12823086-10dlc-fees) |
| 2026-07-28 | New MCP specification version | Remote MCP servers move closer to stateless APIs | [MCP changelog](https://modelcontextprotocol.io/specification/draft/changelog) |

On October 28, 2026, TikTok launched Must Eat, a restaurant guide in New York, Los Angeles and the San Francisco Bay Area. Users can rate and review restaurants in the app ([TikTok announcement](https://usdsjv.tiktok.com/TikTok-Must-Eat); [The Verge report](https://www.theverge.com/news/1020267/tiktok-viral-restaurant-recommendations-must-eat-yelp)). Restaurants now have one more review source, so keep room for more entries in the script's `SOURCES` table.

On July 28, 2026, the MCP specification released a new version that removes sessions and the initialization handshake. Remote servers now behave more like ordinary stateless APIs ([MCP specification changelog](https://modelcontextprotocol.io/specification/draft/changelog); [GitHub releases](https://github.com/modelcontextprotocol/modelcontextprotocol/releases)). tdmcp.com describes itself as a stateless proxy that stores no credentials, which fits that direction.

## Limits and caveats

| Limit | Effect | What to do |
| --- | --- | --- |
| A text only proves it was sent | You do not know whether the manager saw it | Ask for a reply keyword and log it with the SMS platform's webhook |
| The App Store "newest" list itself lags | Bad app reviews show up in the list a day or more later | Check app reviews once a day |
| `since=today` misses late reviews | A review written yesterday that appears today is filtered out | Set `since` to yesterday and dedupe by review ID |
| Small sample, short window | Texts per day are only a scale | Run with `DRY_RUN=1` for one week first |

The sample is small, so the results have limits. We tested 2 places and 2 apps (plus one MyChart poll) over about 3 hours, during the US Eastern morning and noon. The speed of new reviews and the share of bad ones change with the shop, the time of day, promotions and outages. Treat the texts-per-day numbers as a scale only. To set the schedule for your own shop, run with `DRY_RUN=1` for one week. Count how many rows enter the outbox each day.

## FAQ

**Can Claude send SMS? How do I connect an SMS MCP server?**

Claude does not send texts by itself. It needs an MCP server that can send. Per tdmcp.com, add `https://connect.tdmcp.com/` under "Custom connectors" in Claude and sign in to your TrueDialog account. Twilio's own MCP server only searches docs and cannot send. Question from Google autocomplete, "claude sms mcp" (read November 14, 2026).

**Google Business Profile already sends new review notices. Do I still need a review alert SMS?**

For a shop you own, start with Google's email and Maps app notices, or build your own alert from the Pub/Sub push. You need polling plus SMS when you want texts, a merged view of many shops, or places that are not in your account. Question from Google autocomplete, "google business review notifications" (read November 14, 2026).

**I got a text that says "review alert". How can I tell if it is a scam?**

Your own alert should always come from one registered number. It should hold only the stars, the place and a link to your own system, and it never asks for a password or a payment. Treat a text from an unknown number that says "you have a new bad review, log in here" as phishing. Question from Google autocomplete, "review alert sms scam" (read November 14, 2026).

**Does App Store Connect notify me about new reviews?**

Not according to the notification list in App Store Connect Help. The only review item is "Developer Response", an email when a user edits a review you answered. For new reviews, poll the Customer Reviews API or review data. Question from Google autocomplete, "app store connect review notifications" (read November 14, 2026).

**If the owner replies to the text, can that reply answer the review?**

Not with TrueDialog MCP: the first known limit on the Microsoft Learn connector page is that it sends only and cannot read replies or conversations. For this you need the SMS platform's inbound webhook to bring the reply into your own system. Then a person or a program answers the review on the platform. Question from Google autocomplete, "review alert sms auto reply" (read November 14, 2026).

**Can I monitor Google reviews for a business I do not own?**

Google's notices and the Business Profile API cover only businesses you manage, and the replies in the r/smallbusiness thread say the same. You can read public place reviews with `google_maps_reviews/reviews`, dedupe by review ID and build your own alert. Question from a [Reddit r/smallbusiness thread](https://www.reddit.com/r/smallbusiness/comments/1ncsmez/google_reviews_monitoring/).

## Get started

Step 1: create an API key in the EveryInfra console and put it in the environment variable `EVERYINFRA_API_KEY`. The free catalog `GET /api/v1/social/catalog` lists each capability's parameters, allowed values and `price_usd`. Follow the [quickstart](/docs#quickstart) to run your first request.

Step 2: use [`google_maps_reviews/search`](/google-maps-reviews-api/search) to find the places you want to watch, and copy the URL with `query_place_id` from the response. For apps, note the App Store numeric ID and the Google Play package name. See the [Google Maps reviews API](/google-maps-reviews-api), the [App Store API](/app-store-api) and the [Google Play API](/google-play-api). For Yelp listings, add [`yelp/reviews`](/yelp-api/reviews).

Step 3: put the script above in cron and run it with `DRY_RUN=1` for one week. Count how many rows enter the outbox each day.

Step 4: connect SMS. Replace `send_sms()` with the Twilio Messages API, or use TrueDialog's MCP server or API. Do a dry run first, then send for real. Prices follow the [pricing page](/pricing) and the catalog. To check that failures and empty results were not charged, see [failure refund reconciliation](/build/failure-refund-reconciliation).

## References

1. [Model Context Protocol, Specification 2026-07-28](https://modelcontextprotocol.io/specification/2026-07-28), read 2026-11-14
1. [TrueDialog MCP, tdmcp.com (setup, tools, security)](https://tdmcp.com/), read 2026-11-14
1. [PR Newswire, TrueDialog Launches MCP for ChatGPT, Copilot and Other AI Assistants, 2026-11-10](https://www.prnewswire.com/news-releases/truedialog-launches-mcp-for-chatgpt-copilot-and-other-ai-assistants-302935019.html), read 2026-11-14
1. [TrueDialog, MCP feature page](https://www.truedialog.com/features/mcp), read 2026-11-14
1. [Twilio Blog, Introducing Twilio MCP and skills, 2026-05-07](https://www.twilio.com/en-us/blog/developers/introducing-twilio-mcp-skills), read 2026-11-14
1. [Twilio Docs, Twilio MCP server](https://www.twilio.com/docs/ai/mcp), read 2026-11-14
1. [GitHub, twilio-labs/mcp](https://github.com/twilio-labs/mcp), read 2026-11-14
1. [npm registry, @twilio-alpha/mcp](https://registry.npmjs.org/@twilio-alpha/mcp), read 2026-11-14
1. [Microsoft Learn, TrueDialog MCP connector](https://learn.microsoft.com/en-us/connectors/truedialogmcp/), read 2026-11-14
1. [Google Business Profile Help, manage notifications](https://support.google.com/business/answer/7198436?hl=en), read 2026-11-14
1. [Google for Developers, Business Profile real-time notifications setup](https://developers.google.com/my-business/content/notification-setup), read 2026-11-14
1. [Google for Developers, My Business Notifications API: NotificationSetting](https://developers.google.com/my-business/reference/notifications/rest/v1/NotificationSetting), read 2026-11-14
1. [Google for Developers, Business Profile review data](https://developers.google.com/my-business/content/review-data), read 2026-11-14
1. [Apple, App Store Connect Help: user notifications](https://developer.apple.com/help/app-store-connect/reference/account-management/user-notifications/), read 2026-11-14
1. [Apple Developer Documentation, App Store Connect API: Customer Reviews](https://developer.apple.com/documentation/appstoreconnectapi/customer-reviews), read 2026-11-14
1. [Google for Developers, Google Play Developer API: Reply to Reviews](https://developers.google.com/android-publisher/reply-to-reviews), read 2026-11-14
1. [Reddit r/smallbusiness, Google reviews monitoring thread](https://www.reddit.com/r/smallbusiness/comments/1ncsmez/google_reviews_monitoring/), read 2026-11-14
1. [Google for Developers, Places API Place Details](https://developers.google.com/maps/documentation/places/web-service/legacy/details), read 2026-11-14
1. [EveryInfra, llms-full.txt (Retries and idempotency)](https://api.everyinfra.com/llms-full.txt), read 2026-11-14
1. [EveryInfra, OpenAPI specification](https://api.everyinfra.com/openapi.json), read 2026-11-14
1. [Twilio Docs, Message resource](https://www.twilio.com/docs/messaging/api/message-resource), read 2026-11-14
1. [Twilio, SMS pricing for the United States](https://www.twilio.com/en-us/sms/pricing/us), read 2026-11-14
1. [Twilio, phone number pricing](https://www.twilio.com/en-us/phone-numbers), read 2026-11-14
1. [TrueDialog, pricing](https://www.truedialog.com/pricing/), read 2026-11-14
1. [Twilio Help Center, A2P 10DLC pricing and fees](https://help.twilio.com/articles/1260803965530-What-pricing-and-fees-are-associated-with-the-A2P-10DLC-service-), read 2026-11-14
1. [CTIA, Messaging Principles and Best Practices, May 2023 (PDF)](https://api.ctia.org/wp-content/uploads/2023/05/230523-CTIA-Messaging-Principles-and-Best-Practices-FINAL.pdf), read 2026-11-14
1. [Kelley Drye, FCC revises TCPA consent revocation rules](https://www.kelleydrye.com/viewpoints/blogs/ad-law-access/fcc-revises-tcpa-consent-revocation-rules-exclusive-opt-out-methods-category-specific-revocations-and-other-key-changes), read 2026-11-14
1. [Federal Register 2026-21821, consent revocation rule, published 2026-10-26](https://www.federalregister.gov/documents/2026/10/26/2026-21821/enhancing-the-ability-of-consumers-to-control-the-robocalls), read 2026-11-14
1. [FCC, fact sheet DOC-424844A1, 2026-09-09 (PDF)](https://docs.fcc.gov/public/attachments/DOC-424844A1.pdf), read 2026-11-14
1. [Bandwidth Support, 10DLC fees (updated 2026-09-16)](https://www.bandwidth.com/support/en/articles/12823086-10dlc-fees), read 2026-11-14
1. [Twilio Docs, How long can a message be?](https://www.twilio.com/docs/glossary/what-sms-character-limit), read 2026-11-14
1. [HHS OCR, Manasa Health Center settlement, 2023-06-05](https://www.hhs.gov/hipaa/for-professionals/compliance-enforcement/agreements/manasa/index.html), read 2026-11-14
1. [HHS OCR, 2023 report to Congress on HIPAA compliance (PDF)](https://www.hhs.gov/sites/default/files/compliance-report-to-congress-2023.pdf), read 2026-11-14
1. [HHS OCR, New Vision Dental settlement, 2022-12-14](https://www.hhs.gov/hipaa/for-professionals/compliance-enforcement/agreements/new-vision/index.html), read 2026-11-14
1. [HHS OCR, resolution agreements](https://www.hhs.gov/hipaa/for-professionals/compliance-enforcement/agreements/index.html), read 2026-11-14
1. [eCFR, 16 CFR Part 465 (Consumer Reviews and Testimonials)](https://www.ecfr.gov/current/title-16/chapter-I/subchapter-D/part-465), read 2026-11-14
1. [FTC, Consumer Reviews and Testimonials Rule: Q&A](https://www.ftc.gov/business-guidance/resources/consumer-reviews-testimonials-rule-questions-answers), read 2026-11-14
1. [AHRQ, What Is Patient Experience?](https://www.ahrq.gov/cahps/about-cahps/patient-experience/index.html), read 2026-11-14
1. [AHRQ, CAHPS](https://www.ahrq.gov/cahps/index.html), read 2026-11-14
1. [CMS, Consumer Assessment of Healthcare Providers & Systems](https://www.cms.gov/data-research/research/consumer-assessment-healthcare-providers-systems), read 2026-11-14
1. [Performance.gov, A-11 Section 280 explainer](https://www.performance.gov/cx/a-11/), read 2026-11-14
1. [Claude Help Center, custom connectors using remote MCP](https://support.claude.com/en/articles/11175166-getting-started-with-custom-connectors-using-remote-mcp), read 2026-11-14
1. [Claude Code Docs, MCP](https://code.claude.com/docs/en/mcp), read 2026-11-14
1. [Claude Code Docs, run Claude Code programmatically](https://code.claude.com/docs/en/headless), read 2026-11-14
1. [TikTok, Must Eat announcement, 2026-10-28](https://usdsjv.tiktok.com/TikTok-Must-Eat), read 2026-11-14
1. [The Verge, TikTok Must Eat restaurant guide](https://www.theverge.com/news/1020267/tiktok-viral-restaurant-recommendations-must-eat-yelp), read 2026-11-14
1. [Model Context Protocol, specification changelog](https://modelcontextprotocol.io/specification/draft/changelog), read 2026-11-14
1. [GitHub, modelcontextprotocol releases](https://github.com/modelcontextprotocol/modelcontextprotocol/releases), read 2026-11-14
