Stop Building MCP Servers Like APIs

Most MCP servers fail because developers treat them like API wrappers. They’re not. They’re prompt engineering interfaces for stateless models—and that changes everything.

The Core Problem

LLMs are stateless. After each response, they lose all context from previous interactions. Yet most MCP servers assume the model remembers prior calls, creating fragmented workflows that break constantly.

Typical broken pattern:

1
2
3
4
Tool: authenticate() -> "Login successful"
Tool: list_tables() -> ["users", "orders", "products"]  
Tool: query_table("users") -> [user data]
Tool: export_results() -> "Export failed: no query context"

The model can’t maintain this workflow. Each tool call is a fresh start.

How Successful MCPs Work

Well-designed MCP servers like GitHub and Figma don’t chain operations—they provide complete, self-contained workflows.

Figma MCP approach:

  • create_design(requirements) - Handles auth + creation + returns complete result
  • analyze_layout(url) - Extracts all design data in one call
  • modify_component(url, changes) - Finds, modifies, and confirms changes

Each tool accomplishes a complete user intent, not a technical operation.

PostgreSQL MCP approach:

  • analyze_performance(connection, query) - Connects, analyzes, returns actionable insights
  • No separate auth, connection, or query tools needed

Three Design Principles

1. Make Each Tool Self-Contained

Every tool must work independently. Don’t assume the model “remembers” anything.

Bad: get_user_by_id(id) (requires prior authentication)
Good: get_user_data(connection_string, user_id) (self-contained)

2. Responses Are Prompts

Your tool responses guide the model’s next action. Don’t just return data—provide context and suggestions.

Bad response:

1
{"status": "error", "code": 422}

Good response:

1
2
3
4
5
{
  "error": "Index 'user_data' not found",
  "available_indices": ["customer_data", "product_catalog"],
  "suggestion": "Use correct index name or create new one with create_index tool"
}

3. Design for Intent, Not Operations

Group related functionality around what users actually want to accomplish.

API thinking: separate tools for auth, list, create, update, delete
MCP thinking: tools for “provision new user,” “audit permissions,” “migrate data”

The Aggregation Pattern

Instead of exposing granular operations, create tools that handle complete workflows:

mem0 MCP example:

  • remember_pattern(code_preference, context) - Stores with full context
  • apply_patterns(current_code) - Retrieves and applies relevant patterns
  • explain_preferences(scenario) - Shows reasoning for recommendations

Each tool handles a complete “cognitive” task.

Implementation Guide

  • Think prompts, not APIs - Every interaction extends the model’s prompt space
  • Be self-contained - Each tool must work independently
  • Teach through responses - Guide the model toward solutions
  • Group by intent - Tools should match user goals, not technical operations
  • Test across models - What works for Claude Opus might confuse Haiku
uname -a: Human 5.4.0-anxiety #1 SMP Coffee-Deprived x86_64 GNU/Paranoid
Built with Hugo
Theme Stack designed by Jimmy