MCP Isn’t Broken – It’s Your Server Design, Not the Protocol

The article argues that the recent hype around Skills and the criticism of MCP stem from a mindset problem: developers treat MCP like a REST API wrapper, leading to poor server designs, and it offers six concrete design principles to build agent‑friendly MCP services.

AI Engineering
AI Engineering
AI Engineering
MCP Isn’t Broken – It’s Your Server Design, Not the Protocol

In the AI community, Skills is being praised while the MCP protocol is being disparaged, but the author claims the protocol itself is fine and the real issue lies in how developers design their MCP servers.

Protocol vs. Design Misconception

Many developers wrap MCP as a simple REST API, ignoring that REST is built for human developers while MCP is an interface for autonomous agents. Applying REST thinking to MCP forces agents to repeatedly parse schemas, increasing latency and cost.

Human Developers vs. Agents: Design Differences

Discovery cost : Humans pay a cheap one‑time doc read; agents pay an expensive per‑request schema parse.

Composability : Humans can combine multiple endpoints in one step; agents must perform multi‑step tool calls, slowing execution.

Flexibility : Humans enjoy many options; agents face added complexity that can cause hallucinations.

Because agents must re‑parse tool descriptions on every call, a design that requires many round‑trips quickly becomes inefficient.

Order‑Tracking Example

Bad MCP design exposes three separate tools:

get_user_by_email()
list_orders(user_id)
get_order_status(order_id)

This forces the agent to make three round‑trips and store intermediate results.

Good MCP design exposes a single tool: track_latest_order(email) The server handles all coordination and returns a final message such as "Order #12345 shipped via FedEx, arriving Thursday" in one call, eliminating unnecessary latency.

Six Practical Design Principles

1. Result‑oriented, not operation‑oriented

Do not expose low‑level API operations as tools. Design tools around the agent’s goal and perform orchestration on the server side.

2. Flatten parameters

Avoid nested dictionaries. Example of a poor design: def search_orders(filters: dict) Improved design with explicit, typed arguments:

def search_orders(email: str, status: Literal["pending", "shipped", "delivered"] = "pending", limit: int = 10)

3. Documentation as instructions

When to use the tool (e.g., "use when user asks for order status").

How to format parameters (e.g., "email must be lowercase").

What to return (e.g., "return order ID and current status").

Error messages should be actionable strings rather than Python exceptions, e.g., "User not found. Try searching by email."

4. Curate tools carefully

Limit each server to 5‑15 tools.

One server, one responsibility.

Remove unused tools.

Separate roles (admin vs. user).

5. Discoverable naming

Use the pattern {service}_{action}_{resource}, such as slack_send_message, linear_list_issues, sentry_get_error_details. Avoid generic names like create_issue or send_message that can clash across services.

6. Paginate large data

Support a limit parameter (default 20‑50 records).

Return pagination metadata: has_more, next_offset, total_count.

Never load all results into memory at once.

Skills vs. MCP: Not a Competition

Skills answer “when to use which tool” and provide progressive loading, workflow guidance, and local execution.

MCP answers “how to call tools reliably” and offers a standardized interface, parameter validation, typed responses, and error handling.

Both are complementary: in enterprise settings, MCP servers expose service capabilities, while Skills teach agents how to combine those capabilities into concrete workflows.

Gmail Practical: Two Designs

Traditional REST mindset (bad) :

# 读邮件要2个工具 + 理解复杂嵌套
 def messages_list(query: str, max_results: int) -> dict
 def messages_get(message_id: str, format: str) -> dict

# 发邮件要构造base64编码的MIME
 def messages_send(message: {"raw": str}) -> dict

Agent‑first design (good):

# 简单直接
 def gmail_search(query: str, limit: int = 10) -> list
 def gmail_read(message_id: str) -> dict
 def gmail_send(to: List[str], subject: str, body: str) -> dict

Core Question: Who Is the UI For?

The author’s central claim: MCP is the user interface for agents, not merely infrastructure. When building an MCP server, ask:

What goal does this tool serve?

Can the agent obtain all needed information in a single call?

Are the parameters clear and unambiguous?

Do error messages help the agent self‑correct?

Skills are popular because they were designed for agents from the start. MCP is criticized because many treat it as a REST wrapper. With the right mindset, MCP servers can be excellent.

Final reflection: AI tooling cycles bring hype and new concepts, but lasting value comes from solid implementation, first‑principles thinking, and designs that truly serve the agent’s needs.

MCPprompt engineeringapi-designAgent designSkillsAI tooling
AI Engineering
Written by

AI Engineering

Focused on cutting‑edge product and technology information and practical experience sharing in the AI field (large models, MLOps/LLMOps, AI application development, AI infrastructure).

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.