Step-by-step guide showing how an MCP client discovers messaging capabilities, plans execution, sends an SMS and tracks delivery using the official MCP Inspector.
HN user
Bridgexapi
Building programmable infrastructure for messaging systems and EVM execution intelligence.
I run GrapheneOS now 2 year :) always working fine
Not found
useful, especially for async teams
one thing though: a lot of “bad questions” come from systems giving incomplete signals
200 OK no errors in logs
but the actual failure happens after the request (timing, retries, downstream)
so people aren’t asking poorly they’re asking from incomplete signals
one thing that always felt off to me is how much focus goes into how access is granted and rotated, and much less into what actually happens after that access is used
even with short-lived or well-scoped credentials, the behavior behind them can still be pretty opaque depending on the system
so you reduce risk on access, but what happens after can still be hard to reason about or observe
everything says success in logs but the result happens later and can be completely different
had cases where messages were accepted instantly but delivered much later or not at all
wonder how others deal with this gap
this is exactly where it gets tricky
once you give something the ability to send messages or trigger actions, it’s not just read access anymore, it’s execution on your behalf
it looks simple from the outside, but there’s usually a lot of hidden behavior underneath (routing, timing, provider handling, etc)
so the question becomes less about access and more about how controlled and observable that execution actually is
curious if you’re thinking about exposing that layer, or keeping it abstracted away
yeah fair, a lot of this exists in different forms already
for me it wasn’t really about the idea itself, more how often this still trips you up in real systems
things look identical at the API level, same response, same logs, but the actual outcome drifts depending on what happens after
that’s the part that kept biting me in production, so tried to break that down a bit more concretely
been running into this a few times in production
api returns success, everything looks fine, but the actual result happens later and sometimes doesn’t match what you expect
especially with async stuff, queues, external providers, timing between systems
wrote this to try and map out what’s actually happening between “request handled” and the final outcome
curious how others think about it
i don’t think this is really about 200 vs 202
even if you return 202 + pending, you still have the same issue underneath the outcome depends on work that happens outside the request
queues, retries, third party stuff, timing between systems
you can model it nicer in the api, but you still don’t really control when or if things actually finish the way you expect
that’s been the tricky part for me in production not the status code, but the gap between “request handled” and “did the thing actually happen”
yeah fair
200 is correct at the protocol level, no argument there.
I think where it gets confusing is that people treat it as “done”, while in a lot of real systems it just means the request got accepted and handed off.
after that it’s queues, providers, retries, all kinds of stuff you don’t really see.
so you end up with “success” at the API layer but still inconsistent outcomes.
that’s mostly what I’ve been running into in production.
curious how others think about that.
Fair point.
This came from debugging a few production cases where everything looked fine at the API level, but delivery still varied depending on downstream handling.
Probably should’ve made that less abstract and more concrete.
At low volume everything looks fine. Requests return 200, delivery seems consistent.
Once traffic goes up, that starts breaking. Same request, same setup, different results.
Some messages are instant, some delayed, some just never show up.
Nothing in the API response explains why.
This is where messaging stops being a simple API call.
At low volume everything looks fine. Requests return 200, delivery seems consistent.
Once traffic goes up, that starts breaking. Same request, same setup, different results.
Some messages are instant, some delayed, some just never show up.
Nothing in the API response explains why.
This is where messaging stops being a simple API call.
The part that confused me was that everything looked correct on our side, but behavior still changed between requests.
Feels like there’s a whole execution layer you don’t see unless you instrument it yourself.
Even if they check for impersonation, it doesn’t change what the app actually does once you interact with it
One thing I find interesting about the GIL is how it mirrors a pattern you see in a lot of systems: the abstraction suggests parallelism, but the actual execution layer enforces a single path at critical points.
You end up debugging “why isn’t this scaling” while the real constraint isn’t visible at the API level. I’ve seen similar behavior in networked systems where things look nondeterministic, but are actually shaped by a hidden execution bottleneck underneath.
Yeah that makes sense, especially at that scale.
What you’re describing is kind of what I keep running into too — people don’t really try to understand delivery, they just design around the fact that it’s unreliable.
Longer lead times, retries, fallback channels, etc.
Which works, but it also means the actual behavior stays a black box.
Did you ever notice differences between providers or routes, or was it basically opaque the whole time?
That’s fair, I agree SMS isn’t great for 2FA.
I think what’s interesting is that a lot of systems still rely on it anyway (reach, fallback, onboarding), but treat it like it’s deterministic.
In practice, I’ve seen more issues from unpredictability than just security — timing, routing behavior, stuff you can’t really see.
So even if teams accept the trade-offs, they still don’t really understand how delivery behaves.
Have you seen similar issues in systems that still use SMS as fallback?
One thing I’m still trying to understand better:
How do people debug delivery issues today when timing is inconsistent?
Most tools seem to expose status, but not execution.
Curious how others approach this in production systems.
After working on SMS delivery systems, one thing stood out:
Most APIs expose sending, but hide execution.
You submit a message and get "delivered" back, but everything that actually determines behavior is hidden: routing, timing, execution path.
This becomes a real problem in systems like OTP, fraud alerts or transactional messaging, where timing matters more than delivery itself.
The same request can behave differently across executions, but without visibility into routing, you can’t explain or control it.
This post breaks down why that happens and what control actually means at the infrastructure level.
If you missed our first blog on SMS delivery mechanics, check it out here: The anatomy of SMS delivery: from request to carrier: https://blog.bridgexapi.io/the-anatomy-of-sms-delivery-from-...
Small addition:
One thing this post does not fully cover is that delivery behavior is not just "success vs failure".
Different routes can behave differently under load, especially in terms of latency and delivery timing.
This is something most APIs do not expose at all.
A follow-up focused purely on delivery tracking and timing behavior would probably make sense.
Interesting approach.
One thing that often gets overlooked in SMS systems is how much behavior depends on routing decisions underneath.
Most APIs abstract that layer, which makes debugging delivery issues very difficult in practice.