Jaskaran Bhatia
BlogXLinkedIn

© 2026 Jaskaran Bhatia

Jaskaran Bhatia
BlogXLinkedIn

Contents

  1. Introduction
  2. the test that finds it
  3. three shapes the antipattern takes
  4. why now, and why not "just build a clean api for agents instead"
  5. what fixing it actually means, mechanically
Jaskaran BhatiaJuly 20265 min read

mcp is a very expensive linter for your api

how this new surface area highlights system design flaws

for years your frontend was the only client hitting your apis. that meant every gap between what the api actually did and what a "complete interaction" required, could quietly get patched by a human. a person sees an ambiguous state and clicks around. a person reads three fields and infers the fourth. a person notices than an error message doesn't quite make sense and just tries again. none of that shows up as a ticket, it shows up as "ux friction" if you're looking for it. in most cases it doesn't show up at all.

the moment you build an mcp server against the same backend, that tolerance is gone. an agent doesn't infer, it calls what's documented. if the api needs a fifth undocumented field the FE was quietly injecting, the tool call fails. if validation only exists in a FE component, the agent submits garbage straight through. if a button used to fire four apis in sequence and stitch the responses together, the agent either has to replicate that orchestration (bad), or it just falls flat.

none of this is new breakage. it's old breakage that finally has a witness.

the test that finds it

for any existing FE capability, ask: if a headless client hit the same api, would it get a complete, correct, submittable result with zero extra client side logic? if no, you've found a spot where business logic was living in the FE instead of the backend. this isn't an mcp specific test, it would've failed five years ago too, nobody was checking because nobody had a reason to.

three shapes the antipattern takes

transformation wearing a display costume. backend sends structured data, FE converts it to a human readable string--done. worked fine when FE was the only consumer. the moment an agent needs the same data, it hits a JSON wall by default. fix: the conversion logic has to get rebuilt somewhere the agent can reach, usually the backend. this was never presentation logic, it was transformation logic that happened to be implemented in the presentation layer.

validation as ux nicety instead of invariant. FE validation exists to give a person a fast, friendly nudge before a round trip. it was never supposed to be the enforcement layer, the backend was supposed to be the source of truth regardless of client. if it isn't, you don't have an "agent problem," you have a backend that's been trusting one client to behave itself for years, and just met a second client that doesn't.

orchestration with no name. an onclick that hits four endpoints and merges the responses is a composite action, it just never got named as one, it lived as handler code. an agent can't replicate a handler, it can only call tools. this one isn't really misplaced logic, it's a missing abstraction; the composite action needs to become a real backend endpoint, not just get relocated.

why now, and why not "just build a clean api for agents instead"

the tempting shortcut (and i've debated this with my team): leave the old mess alone, build a new, better packaged api specifically for mcp, point agents at that, don't touch FE. not great because all it does is add a second surface that eventually needs the same fixes, while the rot in the original api keeps aging undisturbed. now you're maintaining two things that disagree about what the "real" behavior is, and every future feature has to pick which one to extend. you haven't removed the duplication you started with (logic split across FE and BE)--you've relocated it (logic split across old api and new api) and chosen which copy gets to keep rotting.

the actual case for doing this now instead of later is boring but true: you just found every instance of this, for free, as a side effect of building the mcp server. you have the full list of "things that only ever worked because a human was in the loop." that context decays fast. six months out, nobody remembers why a field was FE only. they just know "don't touch it, agent breaks." fix it while you still know why it's broken, not after you've built a second api that's learned to route around it.

what fixing it actually means, mechanically

move transformation logic into one shared service layer that both FE and mcp call into, not two copies, and not mcp calling FE's endpoints as a shim (that just makes mcp inherit FE's shortcuts one hop removed). that's actually L3/top right in the predictability quadrant. promote FE validations to backend enforced constraints; FE can keep a copy for instant feedback, it's just not load bearing anymore. give composite actions a real backend identity, name the action, define its endpoint, let both clients call the named thing instead of one client hand assembling it from parts.

none of this is glamorous. it's mostly admitting the FE was doing three jobs (presentation, transformation, validation) and only one of them, presentation, actually belonged there. the other two were always backend jobs wearing a fe costume, because there was only ever one client around to notice.

© 2026 Jaskaran Bhatia