Skip to content

MVA vs MVC: The Paradigm Shift

MVC was designed for a consumer that navigates by sight. MVA was designed for a consumer that navigates by understanding.

This page provides a formal, layer-by-layer comparison between MVC and MVA. The goal is not to criticize MVC — it has served brilliantly for four decades. The goal is to demonstrate why a new architecture is required when the consumer changes from human to AI agent.


The Architectural Comparison

text
              MVC                                    MVA
┌─────────────────────────┐          ┌─────────────────────────┐
│                          │          │                          │
│  MODEL                   │          │  MODEL                   │
│  ORM / Database Schema   │          │  Zod Schema (.strict())  │
│  ─────────────────────   │          │  ─────────────────────   │
│  Defines data shape.     │          │  Defines data shape      │
│  No output filtering.    │          │  AND acts as security    │
│                          │          │  boundary. Rejects       │
│                          │          │  undeclared fields.      │
│                          │          │                          │
├──────────────────────────┤          ├──────────────────────────┤
│                          │          │                          │
│  VIEW                    │          │  VIEW (Presenter)        │
│  HTML / CSS / Templates  │          │  Perception Layer        │
│  ─────────────────────   │          │  ─────────────────────   │
│  Visual rendering for    │          │  Structured data with    │
│  human eyes. Layout,     │          │  domain rules, charts,   │
│  typography, colors.     │          │  affordances, guardrails │
│  Tool-level (per page).  │          │  Domain-level (per       │
│                          │          │  entity). Reused across  │
│                          │          │  all tools.              │
│                          │          │                          │
├──────────────────────────┤          ├──────────────────────────┤
│                          │          │                          │
│  CONTROLLER              │          │  AGENT                   │
│  HTTP Handler            │          │  LLM Runtime             │
│  ─────────────────────   │          │  ─────────────────────   │
│  Receives HTTP requests. │          │  Autonomous consumer.    │
│  Routes to business      │          │  Receives structured     │
│  logic. Returns a View.  │          │  perception package.     │
│  Human initiates.        │          │  Acts without human      │
│                          │          │  intervention.           │
│                          │          │                          │
└──────────────────────────┘          └──────────────────────────┘

Layer-by-Layer Analysis

The Model Layer

In MVC, the Model represents the data and business rules of the application. It is typically an ORM entity (ActiveRecord, Prisma, Eloquent) that maps directly to database tables. The Model validates input — ensuring the database receives well-formed data.

In MVA, the Model serves a dual purpose. It validates input (as in MVC), but it also acts as an output security boundary. The Zod schema with .strict() (applied by the developer) ensures that only declared fields reach the agent. The framework also auto-applies .strict() on input validation schemas. This is a fundamental inversion:

AspectMVC ModelMVA Model
Primary roleData persistence and input validationData validation and output filtering
Security directionInbound (protects the database)Inbound and outbound (protects the agent)
Unknown fieldsPassed through silentlyRejected with actionable errors
ScopeApplication-wide (shared schema)Application-wide (shared schema)
ImplementationORM schema (Prisma, Eloquent)Zod schema with .strict()
typescript
// MVC Model — protects the database
const User = prisma.defineModel({
    id: String,
    name: String,
    email: String,
    password_hash: String,  // Exists in the model, may leak to the view
    tenant_id: String,       // Internal field, may leak to the view
});

// MVA Model — protects the database AND the agent
const userSchema = z.object({
    id: z.string(),
    name: z.string(),
    email: z.string().email(),
    // password_hash → not declared → rejected by .strict()
    // tenant_id    → not declared → rejected by .strict()
}).strict();

The View Layer

This is where the paradigm shift is most visible. In MVC, the View is a visual rendering layer — it produces HTML, CSS, and JavaScript for human eyes. It is tool-level: each controller action has its own view template.

In MVA, the View is a perception layer — the Presenter. It does not produce visual output. It produces a Structured Perception Package: data + rules + UI blocks + affordances + guardrails. It is domain-level: each domain entity has one Presenter shared across all tools.

AspectMVC ViewMVA View (Presenter)
ConsumerHuman eyes (browser)AI agent (LLM context)
Output formatHTML/CSS/JavaScriptStructured Perception Package (text blocks)
ScopeTool-level (one view per action)Domain-level (one Presenter per entity)
ReusabilityLow — views are coupled to specific pagesHigh — Presenter reused across all tools
Domain contextImplicit (humans infer meaning)Explicit (rules travel with data)
Next actionsLinks, buttons, forms.suggestActions() — typed affordances
Data limitsPagination UI (next/prev buttons).agentLimit() + teaching blocks
VisualizationsClient-side rendering (Chart.js, etc.)Server-side rendering (.uiBlocks())
SecurityView templates selectively render fieldsSchema .strict() rejects undeclared fields
CompositionPartials, includes, slots.embed() — nested Presenter composition
typescript
// MVC View — blade.php template (tool-level)
// resources/views/invoices/show.blade.php
// {{ $invoice->amount_cents / 100 }}  ← domain rule encoded in the template
// <a href="/billing/pay/{{ $invoice->id }}">Pay</a>  ← affordance as a link

// MVA View — Presenter (domain-level)
const InvoicePresenter = createPresenter('Invoice')
    .schema(invoiceSchema)
    .systemRules(['amount_cents is in CENTS. Divide by 100.'])      // domain rule travels with data
    .suggestActions((inv) => inv.status === 'pending'
        ? [{ tool: 'billing.pay', reason: 'Process payment' }]     // affordance as typed hint
        : []);

The Key Insight

In MVC, domain knowledge is scattered across view templates. In MVA, domain knowledge is centralized in the Presenter and automatically attached to every response. This is why MVA eliminates perception inconsistency — the rules can't diverge because they live in one place.

The Controller / Agent Layer

In MVC, the Controller is a passive request handler. It receives HTTP requests from the human-initiated browser, orchestrates business logic, and returns a View. The Controller does not act autonomously — it responds to explicit user actions.

In MVA, the Agent replaces the Controller as the consumer. But the Agent is not a passive request handler. It is an autonomous consumer that:

  1. Receives the Structured Perception Package
  2. Interprets the data using the attached rules
  3. Decides the next action using the affordances
  4. Executes that action without human intervention
  5. Repeats until the goal is achieved
AspectMVC ControllerMVA Agent
NaturePassive request handlerAutonomous decision-maker
InitiationHuman clicks a link or submits a formAgent decides what to call next
RoutingURL-based (/invoices/:id)Tool-based (billing.get_invoice)
Decision makingNone — delegates to business logicPlans and executes multi-step workflows
Error handlingRenders error page for humanSelf-corrects using error recovery hints
Feedback loopHuman reads → thinks → actsAgent perceives → reasons → acts
StateSession-basedStateless (context window)

The Responsibility Shift

The deepest change in MVA is not the renaming of layers. It is the shift of responsibility from the consumer to the interface.

In MVC: The Consumer Does the Work

The MVC View provides minimal context. The human consumer is expected to:

  • Infer meaning from field names and layout (amount_cents → "probably cents")
  • Navigate by clicking links and buttons
  • Remember domain rules from training or documentation
  • Judge what's sensitive and what's not
  • Decide what to do next based on experience

This works because humans are extraordinary at inference and adaptation.

In MVA: The Interface Does the Work

The MVA Presenter provides maximum context. The AI agent receives:

  • Explicit interpretation via system rules — no inference needed
  • Explicit affordances via action suggestions — no navigation needed
  • JIT domain rules via Context Tree-Shaking — no memorization needed
  • Strict schema validation — no judgment about sensitive fields needed
  • Data-driven next actions — no experience-based decision making needed

This is necessary because AI agents are terrible at inference and have zero domain experience.

text
MVC Responsibility Distribution:          MVA Responsibility Distribution:
┌────────────┐                            ┌────────────┐
│   Interface │  20% of the work          │   Interface │  90% of the work
│   (View)    │  Layout, colors, basic    │  (Presenter)│  Validation, rules,
│             │  HTML structure            │             │  affordances, guardrails,
│             │                            │             │  UI blocks, composition
└──────┬─────┘                            └──────┬─────┘
       │                                         │
       ▼                                         ▼
┌────────────┐                            ┌────────────┐
│  Consumer   │  80% of the work          │  Consumer   │  10% of the work
│  (Human)    │  Interpretation, domain   │  (Agent)    │  Follow rules,
│             │  knowledge, navigation,   │             │  execute affordances,
│             │  security judgment,        │             │  render UI blocks
│             │  next-action decisions     │             │
└────────────┘                            └────────────┘

When MVC Still Makes Sense

MVA does not replace MVC universally. It replaces MVC for a specific consumer class.

ScenarioArchitecture
Web dashboard for human usersMVC — humans can interpret visual layouts
Mobile app with UI componentsMVC/MVVM — visual components bind to state
AI agent accessing domain data via MCPMVA — agents need structured perception
CLI tool for developersMVC — developers interpret text output
API consumed by both humans and agentsMVC + MVA — dual-interface (see below)

The Dual-Interface Pattern

Modern products increasingly need both architectures simultaneously:

typescript
// Shared domain model
const invoiceSchema = z.object({
    id: z.string(),
    amount_cents: z.number(),
    status: z.enum(['paid', 'pending', 'overdue']),
});

// MVC: Human-facing API (returns raw data for React/Vue frontend)
app.get('/api/invoices/:id', async (req, res) => {
    const invoice = await db.invoices.findUnique(req.params.id);
    res.json(invoice);  // Frontend renders with React components
});

// MVA: Agent-facing API (returns structured perception package)
const billing = defineTool<AppContext>('billing', {
    actions: {
        get_invoice: {
            returns: InvoicePresenter,  // ← Perception layer
            params: { id: 'string' },
            handler: async (ctx, args) => ctx.db.invoices.findUnique(args.id),
        },
    },
});

Both serve the same business data. Both use the same database. But they serve fundamentally different consumers through fundamentally different architectural patterns.


Historical Precedent

Architectural paradigm shifts follow a pattern: a new consumer class emerges, and the existing architecture cannot serve it well.

EraConsumer ChangeOld ArchitectureNew Architecture
1970sMainframe → Personal ComputerMonolithic batch processingEvent-driven UI
1990sDesktop → Web BrowserDesktop GUIMVC (web)
2010sBrowser → Mobile + SPAServer-rendered MVCMVVM, REST, GraphQL
2025Human → AI AgentMVC, REST, RPCMVA

Each shift was driven by the same principle: the existing architecture assumed a consumer that no longer exists. MVC assumed a human browser. MVA assumes an autonomous AI agent. The pattern repeats.


Summary

DimensionMVCMVA
Designed forHuman consumersAI agent consumers
View producesHTML/CSS for visual renderingStructured Perception Package for LLM context
View scopeTool-level (per page)Domain-level (per entity)
Domain contextImplicit (humans infer)Explicit (rules travel with data)
Next actionsLinks and buttonsTyped affordances with semantic reasons
Data limitsPagination UICognitive guardrails with teaching blocks
SecurityView selectively rendersSchema rejects undeclared fields
ResponsibilityConsumer does 80% of interpretationInterface provides 90% of context

Continue Reading