DEV Community

sirius-zuo
sirius-zuo

Posted on

How I Built an MCP Server That Helps AI Coding Agents Apply Design Patterns Correctly

Giving AI agents precise structural constraints and anti-pattern warnings so they generate maintainable code instead of "works but smells" implementations.

The explosion of AI coding agents — Claude Code, Cursor, GitHub Copilot, Windsurf, and others — has dramatically increased developer velocity. Yet a common frustration remains: these agents excel at producing code that works, but often ignore long-term maintainability, proper separation of concerns, and established design patterns.

They might embed algorithm logic directly in a Context class, rely on large switch statements for behavior switching, or introduce tight coupling where a clean abstraction would serve better. The result is technical debt that builds faster than teams can address it.

To tackle this, I created two complementary open-source projects:

  • design-pattern-skill: An agentic skill that reviews design documents or existing codebases and recommends where and how design patterns should be applied.
  • design-pattern-mcp: A lightweight MCP (Model Context Protocol) server that supplies token-efficient structural templates, constraints, and anti-pattern guards during code generation.

Together, they close the loop: the skill identifies opportunities for better architecture, while the MCP server ensures the agent implements patterns correctly from the start.

Why This Matters in the Age of MCP

MCP is rapidly becoming the standardized way for AI agents to discover and call external tools securely. While many MCP servers focus on data access (files, GitHub repos, databases), I wanted one dedicated to software engineering best practices.

The key challenge: when an AI agent follows recommendations from a review, it still needs reliable guidance to implement patterns without wasting context window tokens or introducing subtle mistakes.

This MCP server addresses that by enforcing two strict design constraints:

  • Token efficiency — Responses stay compact (50–100 tokens for suggestions, 300–500 for templates).
  • Precision — Only structural rules, components, constraints, anti-patterns, and language-specific notes. No lengthy tutorials or prose.

The server is agent-only and runs locally via stdio — no network exposure required.

The Two Core Tools

The MCP server exposes exactly two tools that AI coding agents can discover and call automatically.

1. suggest_pattern(description: string, category?: string)

Use this when the agent recognizes a problem but isn't sure which pattern fits.

Example scenario: Supporting multiple interchangeable payment methods (credit card, PayPal, crypto) that can be swapped at runtime.

The agent calls the tool and receives a short ranked list:

[
  {
    "name": "Strategy",
    "category": "behavioral",
    "rationale": "Multiple interchangeable algorithms selected at runtime",
    "confidence": 0.85
  },
  {
    "name": "Decorator",
    "category": "structural",
    "rationale": "Add responsibilities dynamically",
    "confidence": 0.45
  }
]
Enter fullscreen mode Exit fullscreen mode

Matching uses fast keyword scoring against each pattern’s trigger phrases — no extra LLM call needed.

2. get_template(pattern: string, language: string)

Once the agent chooses “Strategy”, it calls this tool with the desired language (e.g., “typescript”, “go”, “java”, “python”, “rust”, or “generic”).

The response is clean plain text, focused, and compact:

textPattern: Strategy
Language: typescript

COMPONENTS:
- Context: holds a Strategy reference and delegates execution
- Strategy: defines the algorithm contract (often 1 method)
- ConcreteStrategy: implements one specific variant

CONSTRAINTS:
- Context must NOT contain any algorithm logic
- Strategy interface must remain narrow (1-2 methods max)
- Selection of concrete strategy belongs to the caller

ANTI-PATTERNS:
- Embedding if/else or switch statements inside Context
- Using any/unknown instead of a typed contract
- Sharing mutable state between ConcreteStrategy instances

TYPESCRIPT-SPECIFIC NOTES:
- For single-method stateless strategies, prefer function types
- Leverage structural typing — no explicit 'implements' required

EXAMPLE STRUCTURE:
typescript
type Sorter = (data: number[]) => number[];

class SortContext {
  constructor(private strategy: Sorter) {}
  run(data: number[]): number[] {
    return this.strategy(data);
  }
}
Enter fullscreen mode Exit fullscreen mode

The agent then uses this guidance as grounding context while writing the payment service — resulting in cleaner, more intentional code.

Architecture & Design Choices

The server is deliberately lightweight and fast:

  • Templates are stored as Markdown files with YAML frontmatter (templates/<category>/<pattern-name>.md).
  • At startup, the loader parses all files and builds in-memory indexes for O(1) lookups.
  • suggest_pattern performs simple keyword scoring.
  • get_template extracts only the requested language section and formats it compactly.

No heavy dependencies. No disk I/O during queries. Implementing a couple of patterns in one session typically costs under 1000 tokens total — a small price for significantly better architecture.

The companion design-pattern-skill works in the opposite direction. It analyzes design docs or code and produces a structured report covering:

  • Patterns currently in use (and how well they’re applied)
  • Recommended patterns with priority and impact
  • Detailed suggestions including trade-offs
  • Observed anti-patterns

It supports 35+ patterns and works across multiple AI tools (Claude Code, Cursor, Copilot, etc.) via simple file-based installation.

Pattern Coverage

Both projects cover a broad set:

  • Creational (GoF): Abstract Factory, Builder, Factory Method, Prototype, Singleton
  • Structural (GoF): Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy
  • Behavioral (GoF): Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor
  • Modern: Repository, Dependency Injection, Circuit Breaker, CQRS, Event Sourcing, Pub/Sub, Retry/Backoff, Saga
  • Architectural: Clean Architecture, Hexagonal, Layered, Microservices, MVC/MVP/MVVM, Event-Driven, Pipe and Filter

Language-specific notes make the guidance practical and idiomatic (Go interfaces, TypeScript function types, Rust traits, etc.).

How to Get Started

For the MCP server (design-pattern-mcp)

  1. git clone https://github.com/sirius-zuo/design-pattern-mcp.git
  2. cd design-pattern-mcp
  3. npm install && npm run build
  4. Register the server in your AI tool’s config (detailed instructions for Claude Code, Cursor, Copilot, and Windsurf are in the README).

For the review skill (design-pattern-skill)

Installation varies by platform — copy the skill folder for Claude, add rules for Cursor, or reference files for Copilot/Aider. Full steps are in the repo.

Both are MIT-licensed and easy to extend. Adding new patterns or language variants is straightforward thanks to the Markdown template format.

Looking Ahead

This is an early but functional foundation. Future possibilities include deeper integration between the skill and MCP server, more language support, or additional tools for refactoring guidance.

I’m sharing these projects because the MCP ecosystem is growing quickly, and we need more tools that focus on code quality and sustainable architecture — not just data retrieval.

If you’ve struggled with AI-generated code that “works” but creates maintenance headaches due to poor pattern usage, I’d love your feedback. Which patterns do you wish agents handled better? What improvements would make these tools more useful for your workflow?

Check them out and feel free to star, open issues, or send PRs:


Top comments (0)