Building Scalable Angular Apps with MCP Architecture

sunny gsunny g
3 min read

When we start building Angular apps, it’s easy to mix UI logic, state management, and business rules inside components. Over time, this creates "fat components" that are hard to test and maintain.

To solve this, let’s explore the MCP (Model–Component–Presenter) architecture — a clean way to organize Angular applications.


🔹 What is MCP?

MCP stands for:

  • Model → Represents your domain data and state. (Entities, DTOs, interfaces)

  • Component → Handles view logic only (Angular templates + bindings).

  • Presenter → Orchestrates application/business logic, talks to services, and prepares data for the component.

This separation helps us:

  • Keep Angular components thin (focused on UI)

  • Make business logic testable without Angular

  • Reuse logic across different UIs


🔹 Folder Structure

Here’s how MCP might look in an Angular feature:

/products
  /domain       → Models (Product, Category, etc.)
  /ui           → Angular components
  /presenter    → Presenter classes/services
  /infrastructure → API services (HttpClient)

🔹 Step 1: Define the Model

Your domain model represents your core data.

// products/domain/product.ts
export interface Product {
  id: string;
  name: string;
  price: number;
  inStock: boolean;
}

🔹 Step 2: Create a Presenter

The presenter prepares data for the component and handles interactions.

// products/presenter/product.presenter.ts
import { Injectable, signal } from '@angular/core';
import { Product } from '../domain/product';
import { ProductService } from '../infrastructure/product.service';

@Injectable()
export class ProductPresenter {
  products = signal<Product[]>([]);
  loading = signal(false);

  constructor(private productService: ProductService) {}

  loadProducts() {
    this.loading.set(true);
    this.productService.getProducts().subscribe({
      next: (data) => this.products.set(data),
      complete: () => this.loading.set(false),
    });
  }
}

🔹 Step 3: Component (UI Only)

The component is now clean: it binds signals from the presenter and delegates actions back.

// products/ui/product-list.component.ts
import { Component, inject } from '@angular/core';
import { ProductPresenter } from '../presenter/product.presenter';

@Component({
  selector: 'app-product-list',
  template: `
    <h2>Products</h2>
    <div *ngIf="presenter.loading()">Loading...</div>
    <ul>
      <li *ngFor="let p of presenter.products()">
        {{ p.name }} - ${{ p.price }}
      </li>
    </ul>
    <button (click)="presenter.loadProducts()">Reload</button>
  `,
  providers: [ProductPresenter]
})
export class ProductListComponent {
  presenter = inject(ProductPresenter);
}

🔹 Step 4: Infrastructure Layer

The service connects to the backend.

// products/infrastructure/product.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Product } from '../domain/product';

@Injectable({ providedIn: 'root' })
export class ProductService {
  private api = '/api/products';

  constructor(private http: HttpClient) {}

  getProducts(): Observable<Product[]> {
    return this.http.get<Product[]>(this.api);
  }
}

🔹 Benefits of MCP in Angular

Separation of concerns – Components are UI-only.
Testability – Presenter logic can be unit-tested without Angular rendering.
Reusability – Presenters can be reused across components (e.g., web + mobile).
Maintainability – Larger teams can work independently on UI, domain, and logic.


🔹 Final Thoughts

MCP is not a replacement for Angular’s architecture — it’s a discipline to keep your components thin and testable.

If your Angular app is growing and you’re noticing “God components” full of API calls, state management, and business rules — introducing MCP could be the architecture shift you need.

0
Subscribe to my newsletter

Read articles from sunny g directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

sunny g
sunny g

I am a full-stack developer with 8+ years of experience, passionate about the JavaScript ecosystem. I have a bachelor's degree in computer science. I am most skilled and passionate about Angular and React. I am able to provide meaningful contributions to the design, installation, testing, and maintenance of any type of software system. I like to challenge myself in new roles. I have built and successfully delivered applications in multiple domains. In my free time, I like to write blogs related to software development. I have the pleasure of working on exciting projects across industries. The applications that I developed were scalable, deployable, and maintainable. I have a vision of providing cutting-edge web solutions and services to enterprises. Developed zero-to-one products.