The Problem: AI That Doesn’t Know Your Rules
Picture this: You’ve spent months crafting the perfect architecture. Your team has debated, documented, and agreed upon coding standards. You have Architecture Decision Records (ADRs) that capture the “why” behind every major choice. You’ve established patterns, anti-patterns, and guardrails.
Then GitHub Copilot suggests code that violates every principle you hold dear.
It’s not Copilot’s fault. It’s a brilliant tool trained on millions of repositories, but it doesn’t know your rules. It doesn’t understand that your team prefers pragmatic DDD over primitive obsession. It hasn’t read your ADR about why you chose vertical slice architecture over traditional layering. It doesn’t know you’re building with .NET 10 LTS, not some random framework from 2018.
TL;DR - Awesome MCP Server here, run it, learn it, love it…
The fundamental problem: AI coding assistants are incredibly powerful, but they’re context-blind to your organizational standards.
And let’s be honest… Those ADRs are nice and stuff, but often developers don’t even read further than the title
Enter the Model Context Protocol (MCP)
The Model Context Protocol, introduced by Anthropic, is a game-changer. Think of it as a standardized way for AI assistants to access external knowledge sources. Instead of relying solely on their training data, AI tools can now query specialized servers that provide domain-specific context.
An MCP Server acts as a knowledge bridge between your organizational wisdom and AI assistants. It’s not just a documentation repository—it’s an active participant in the development process.
What Makes MCP Different?
Traditional approaches to keeping AI “on track” fall into a few categories:
-
Prompt Engineering: Crafting elaborate system prompts that try to capture all your rules
- Problem: Prompts hit token limits quickly and become maintenance nightmares
-
RAG (Retrieval-Augmented Generation): Embedding documents and retrieving relevant chunks
- Problem: Generic similarity search often misses nuanced architectural decisions
-
Fine-tuning: Training a custom model on your codebase
- Problem: Expensive, time-consuming, and becomes stale quickly
MCP servers offer a fourth way: Structured, queryable, real-time access to your living documentation. They combine the best aspects of all three approaches while avoiding their pitfalls.
The HexMaster Coding Guidelines MCP Server: A Case Study
Let me walk you through how we built an MCP Server that transforms architectural guidelines into AI-consumable knowledge.
The Architecture
Our server is elegantly simple but powerful:
The Tech Stack
We built this with .NET 10 LTS for several strategic reasons:
- Long-term Support: Three years of support means stability for your standards
- Performance: Native AOT compilation potential for blazing-fast responses
- C# 14: Modern language features for clean, maintainable code
- Cross-platform: Runs anywhere—Windows, Linux, macOS, containers
The server is distributed as a .NET Global Tool:
dotnet tool install --global HexMaster.CodingGuidelines.McpServer
One command, and developers have instant access to organizational knowledge.
The Document Structure
We organize guidance into four categories:
1. Architecture Decision Records (ADRs)
Immutable historical context about why decisions were made:
# ADR 0001: Adopt .NET 10 LTS as Target Framework
Date: 2025-11-12
Status: Accepted
## Context
We need a stable, modern platform for our microservices...
## Decision
We will adopt .NET 10 (LTS) as our standard framework...
## Consequences
- 3 years of support until 2028
- Access to C# 14 features
- Performance improvements over .NET 8...
2. Design Documents
Deep dives into architectural patterns:
# Modular Solution Structure
How to organize multi-project solutions with Aspire...
## Structure
Aspire/
Company.Product.AppHost/
Company.Product.ServiceDefaults/
Inventory/
Company.Product.Inventory/
Company.Product.Inventory.Abstractions/
Company.Product.Inventory.Data.SqlServer/
Company.Product.Inventory.Tests/
3. Recommendations
Prescriptive guidance on specific topics:
# Pragmatic Domain-Driven Design
## Value Objects Decision Matrix
CREATE value objects for:
- Multi-field concepts (Address, Money, DateRange)
- Types with interdependent validation
- Complex format requirements (Email, PhoneNumber)
DON'T create value objects for:
- Simple IDs (UserId, OrderId)
- Single primitives without complex rules
- Framework-provided types (DateTime, Guid)
4. Structure Templates
Scaffolding examples for new projects:
# API Service Structure
src/
Company.Product.Api/
Controllers/
Middleware/
Program.cs
Company.Product.Domain/
Entities/
ValueObjects/
DomainEvents/
Company.Product.Application/
Commands/
Queries/
Behaviors/
The Query Interface
The MCP Server exposes several powerful operations:
// List all documents in a category
mcp.tools.list_documents({ category: "adrs" })
// Returns: Array of ADR metadata with IDs, titles, statuses
// Search across all documents
mcp.tools.search_documents({
query: "value objects",
category: "recommendations"
})
// Returns: Ranked results with relevance scores
// Get full document content
mcp.tools.get_document({ documentId: "adr-0001" })
// Returns: Complete markdown with metadata
Real-World Impact: Before and After
Before: The Wild West
Developer: “Copilot, create a user repository”
Copilot generates:
public class UserRepository
{
private readonly DbContext _context;
public User GetById(int id)
{
return _context.Users.Find(id);
}
public void Save(User user)
{
_context.Users.Add(user);
_context.SaveChanges();
}
}
Problems:
- Synchronous database calls (violates async-all-the-way principle)
- No interface (violates hexagonal architecture ports)
- Returning tracked entities (leaks EF Core concerns)
- No cancellation token support
- Primitive
intID instead of domain type
After: MCP-Guided Development
Developer: “Copilot, create a user repository following our architecture guidelines”
Copilot (after querying MCP Server):
// Consulted: ADR-0005 (Hexagonal Architecture)
// Consulted: Recommendation "Repository Pattern"
// Consulted: ADR-0008 (Async Guidelines)
namespace Company.Product.Users.Domain;
// Port definition (belongs in domain)
public interface IUserRepository
{
Task<User?> GetByIdAsync(UserId id, CancellationToken cancellationToken);
Task<IReadOnlyList<User>> SearchAsync(UserSearchCriteria criteria, CancellationToken cancellationToken);
Task SaveAsync(User user, CancellationToken cancellationToken);
}
// Adapter implementation (belongs in infrastructure)
namespace Company.Product.Users.Data.SqlServer;
public sealed class UserRepository : IUserRepository
{
private readonly ApplicationDbContext _context;
private readonly ILogger<UserRepository> _logger;
public UserRepository(ApplicationDbContext context, ILogger<UserRepository> logger)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task<User?> GetByIdAsync(UserId id, CancellationToken cancellationToken)
{
var entity = await _context.Users
.AsNoTracking() // No tracking leak
.FirstOrDefaultAsync(u => u.Id == id.Value, cancellationToken);
return entity?.ToDomainModel(); // Map to domain type
}
public async Task SaveAsync(User user, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(user);
// Validate before persisting
if (!user.IsValid())
throw new DomainException("Cannot save invalid user");
var entity = UserEntity.FromDomainModel(user);
_context.Users.Add(entity);
await _context.SaveChangesAsync(cancellationToken); // Async with cancellation
_logger.LogInformation("User {UserId} saved successfully", user.Id);
}
}
The difference:
- Async all the way with cancellation tokens
- Interface in domain, implementation in infrastructure (proper hexagonal architecture)
- No EF Core leakage (AsNoTracking, domain model mapping)
- Guard clauses and validation
- Structured logging
- Proper error handling
All because Copilot could query the MCP Server and understand your architectural principles.
The Business Value: Speed WITHOUT Chaos
Faster Onboarding
Traditional approach: New developer spends weeks reading confluence docs, asking senior devs questions, making mistakes, getting corrected in PR reviews.
With MCP Server: New developer’s AI assistant already knows the rules. Their first PR follows established patterns. Senior devs review for business logic, not architectural violations.
Result: Onboarding time reduced from weeks to days.
Consistent Quality
The problem: Different developers interpret guidelines differently. Some read the docs, some don’t. Code reviews become teaching sessions.
With MCP Server: Every developer’s AI assistant provides the same guidance. Patterns emerge consistently. PRs focus on problem-solving, not pattern correction.
Result: Higher code quality, less review overhead.
Living Documentation
Traditional docs: Written once, forgotten, become stale, lose trust.
MCP-connected docs: Actively queried by AI tools. When docs are wrong, developers notice immediately because Copilot gives bad advice. Docs stay accurate because they’re actually used.
Result: Documentation becomes a living, valued asset.
Architectural Guardrails
The fear: “AI will generate code that violates our architecture.”
The reality with MCP: AI generates code that follows your architecture because it has direct access to your architectural decisions.
Result: Confidence in AI-assisted development.
The Caching Strategy
Documents don’t change frequently, so we cache aggressively:
public class FileSystemDocumentCatalog : IDocumentCatalog
{
private readonly string _rootPath;
private readonly IMemoryCache _cache;
private static readonly TimeSpan CacheDuration = TimeSpan.FromMinutes(5);
public async Task<DocumentDto?> GetByIdAsync(string documentId, CancellationToken ct)
{
var cacheKey = $"doc:{documentId}";
if (_cache.TryGetValue(cacheKey, out DocumentDto? cached))
return cached;
var document = await LoadDocumentAsync(documentId, ct);
_cache.Set(cacheKey, document, CacheDuration);
return document;
}
}
Implementation Patterns: Making It Work in Your Organization
To use my MCP Server, you need to install the tool as a .NET Tool using the following commands. And to integrate it in VS Code, add some configuration to a mcp.json file in the .vscode folder in the root of your project.
# Install once per developer
dotnet tool install --global HexMaster.CodingGuidelines.McpServer
# Configure in VS Code settings
{
"servers": {
"hexmaster-design-guidelines": {
"type": "stdio",
"command": "hexmaster-codingguidelines-mcpserver",
"args": []
}
}
}
Now please note if you do this, you are working with my ADRs and my guidelines, which isn’t nessecarily what you’re looking for so please, use this for your convenience to learn, don’t implement it one on one accepting my guidelines (unless when you agree with them obviously ;).
Beyond Code Generation: The Broader Vision
1. Interactive Architecture Guidance
Developer: "How should I structure a new microservice?"
AI (via MCP):
"Based on ADR-0012 and the 'Modular Solution Structure' design doc:
1. Create an Aspire folder with AppHost and ServiceDefaults
2. Create a domain folder: /Inventory
3. Inside, create:
- Company.Product.Inventory (core library)
- Company.Product.Inventory.Abstractions (DTOs/interfaces)
- Company.Product.Inventory.Api (HTTP interface)
- Company.Product.Inventory.Data.SqlServer (persistence)
- Company.Product.Inventory.Tests (xUnit tests)
Would you like me to scaffold this structure?"
2. Documentation Drift Detection
// Analyze codebase, compare to guidelines
var driftReport = await AnalyzeArchitecturalDrift();
if (driftReport.Violations.Any())
{
// Generate PR to update docs or refactor code
}
3. Training and Onboarding
New developers can literally ask questions:
"Why do we use vertical slices instead of traditional layering?"
// AI queries MCP server, returns ADR with full context
Multi-Language Support
Beyond .NET, supporting your entire stack:
/docs/
csharp/ # .NET guidelines
typescript/ # Frontend guidelines
python/ # Data pipeline guidelines
terraform/ # Infrastructure as Code guidelines
The Philosophy: Teaching Machines to Follow Your Path
Here’s the profound shift: We’re not just writing code anymore. We’re teaching AI assistants how to write code our way.
The traditional software development process:
- Make architectural decisions
- Document them
- Hope developers read and follow them
- Correct violations in code review
The MCP-enhanced process:
- Make architectural decisions
- Encode them in machine-queryable format
- AI assistants learn and apply them automatically
- Review becomes about refinement, not correction
It’s not about replacing human judgment—it’s about scaling human wisdom.
Conclusion: The Competitive Advantage
In 2025, every development team has access to powerful AI coding assistants. The competitive advantage isn’t in having AI—it’s in directing AI.
MCP Servers are that direction mechanism. They transform your hard-won architectural knowledge from passive documentation into active intelligence that guides every line of code.
The teams that master this, that build robust MCP servers with thoughtful guidelines, will move faster, more consistently, and with higher quality than those who let AI run wild.
The question isn’t whether AI will help you code. It’s whether AI will code the way YOU want.
MCP Servers give you that control.
Here is an example MCP Server that I used for testing. It is very opinionated, so you may want to change some ADRs or guidelines here and there, but it works! And it works like a charm. Feel free to spint it up if you like ;)
Last modified on 2025-11-16