mcp-server-design

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

MCP Server Design

MCP服务器设计

Overview

概述

This skill provides best practices for designing MCP (Model Context Protocol) servers that work effectively with LLM agents. The key insight: design for agents, not automation. LLMs are human-like thinkers, not API consumers.
本技能提供了设计可与LLM Agent高效协作的MCP(Model Context Protocol)服务器的最佳实践。核心思路是:为Agent设计,而非为自动化设计。LLM是类人类的思考者,而非API消费者。

Core Philosophy

核心理念

Design for Agents, Not Automation

为Agent设计,而非为自动化设计

Traditional API design optimizes for programmatic access with granular endpoints. MCP tool design should optimize for how LLMs think and reason:
  • LLMs are human-like thinkers: They understand intent, context, and purpose
  • Tools should be tasks, not endpoints: Shape tools around what users want to accomplish
  • Reduce cognitive load: Fewer, more purposeful tools beat many granular ones
传统API设计针对程序化访问进行优化,采用细粒度端点。MCP工具设计则应围绕LLM的思考和推理方式进行优化:
  • LLM是类人类思考者:它们理解意图、上下文和目标
  • 工具应围绕任务构建,而非端点:根据用户想要完成的任务来打造工具
  • 降低认知负荷:少量、目标明确的工具优于大量细粒度工具

The Three Pillars

三大支柱

  1. Give everything ready: Provide complete, actionable information
  2. Reduce effort: Minimize steps needed to accomplish tasks
  3. Reduce paths: Limit decision branches the LLM must navigate
  1. 万事俱备:提供完整、可执行的信息
  2. 减少工作量:将完成任务所需的步骤降至最少
  3. 精简路径:限制LLM必须导航的决策分支

Tool Design Principles

工具设计原则

1. Purpose-Built Tools Over Generic Wrappers

1. 专用工具优先,而非通用包装器

Anti-pattern: Wrapping every API endpoint as a tool
typescript
// Bad: Generic database tools
// src/tools/run-sql.ts
// src/tools/list-tables.ts
// src/tools/describe-table.ts
Best practice: Design tools around user tasks
typescript
// Good: Task-oriented tools
// src/tools/prepare-database-migration.ts
import { z } from "zod";
import type { ToolMetadata } from "xmcp";

export const schema = {
  description: z.string().describe("What database changes are needed"),
};

export const metadata: ToolMetadata = {
  name: "prepare-database-migration",
  description: "Design a database change with safety checks and reviewed migration plan",
};

// src/tools/analyze-slow-queries.ts
// src/tools/create-backup.ts
反模式:将每个API端点都包装为工具
typescript
// Bad: Generic database tools
// src/tools/run-sql.ts
// src/tools/list-tables.ts
// src/tools/describe-table.ts
最佳实践:围绕用户任务设计工具
typescript
// Good: Task-oriented tools
// src/tools/prepare-database-migration.ts
import { z } from "zod";
import type { ToolMetadata } from "xmcp";

export const schema = {
  description: z.string().describe("What database changes are needed"),
};

export const metadata: ToolMetadata = {
  name: "prepare-database-migration",
  description: "Design a database change with safety checks and reviewed migration plan",
};

// src/tools/analyze-slow-queries.ts
// src/tools/create-backup.ts

2. Minimize Tool Count

2. 最小化工具数量

LLMs struggle with long tool lists. Each additional tool:
  • Increases selection confusion
  • Adds tokens to every request
  • Dilutes the purpose of each tool
Guidelines:
  • Start with 5-10 core tools
  • Add tools only when evals show they're needed
  • Combine related operations when sensible
LLM在面对过长的工具列表时会遇到困难。每新增一个工具都会:
  • 增加选择困惑
  • 为每个请求添加额外的Token
  • 削弱每个工具的目标性
指导原则
  • 从5-10个核心工具开始
  • 仅当评估显示确实需要时再添加工具
  • 合理合并相关操作

3. Name Tools for Purpose, Not Implementation

3. 工具命名应体现目标,而非实现方式

Tool names guide LLM behavior. The name should describe the task, not the mechanism.
Instead of...Use...
post-slack-message
notify-team
run-sql-query
analyze-data
call-api-endpoint
check-service-status
工具名称会引导LLM的行为。名称应描述任务,而非实现机制。
避免使用...建议使用...
post-slack-message
notify-team
run-sql-query
analyze-data
call-api-endpoint
check-service-status

4. Shape Tools Like Tasks

4. 工具应贴合任务流程

For complex flows, one tool per task beats one tool per step.
Anti-pattern: Breaking deployment into atomic operations
typescript
// Bad: Too many granular tools
// src/tools/create-branch.ts
// src/tools/commit-changes.ts
// src/tools/push-branch.ts
// src/tools/create-pr.ts
// src/tools/run-tests.ts
// src/tools/merge-pr.ts
Best practice: Single tool for the complete task
typescript
// src/tools/deploy-changes.ts
import { z } from "zod";
import type { ToolMetadata } from "xmcp";

export const schema = {
  description: z.string().describe("What changes are being deployed"),
  runTests: z.boolean().default(true).describe("Run test suite first"),
  autoMerge: z.boolean().default(false).describe("Auto-merge after tests pass"),
};

export const metadata: ToolMetadata = {
  name: "deploy-changes",
  description: "Deploy current changes through the complete workflow",
};

export default function deployChanges({ description, runTests, autoMerge }) {
  // Handles: branch creation, commit, push, PR, tests, merge
}
对于复杂流程,单个工具处理完整任务优于拆分多个工具处理单个步骤。
反模式:将部署拆分为原子操作
typescript
// Bad: Too many granular tools
// src/tools/create-branch.ts
// src/tools/commit-changes.ts
// src/tools/push-branch.ts
// src/tools/create-pr.ts
// src/tools/run-tests.ts
// src/tools/merge-pr.ts
最佳实践:单个工具处理完整任务
typescript
// src/tools/deploy-changes.ts
import { z } from "zod";
import type { ToolMetadata } from "xmcp";

export const schema = {
  description: z.string().describe("What changes are being deployed"),
  runTests: z.boolean().default(true).describe("Run test suite first"),
  autoMerge: z.boolean().default(false).describe("Auto-merge after tests pass"),
};

export const metadata: ToolMetadata = {
  name: "deploy-changes",
  description: "Deploy current changes through the complete workflow",
};

export default function deployChanges({ description, runTests, autoMerge }) {
  // Handles: branch creation, commit, push, PR, tests, merge
}

Decision Framework

决策框架

When to Create a New Tool

何时创建新工具

Create a new tool when:
  • Users frequently ask for this specific capability
  • The task has clear boundaries and purpose
  • Existing tools can't accomplish it cleanly
  • Evals show the LLM selects incorrect tools for this task
Don't create a new tool when:
  • An existing tool can handle it with minor parameter changes
  • It duplicates functionality (combine instead)
  • It's a rare edge case (handle with existing tools + guidance)
在以下场景下创建新工具:
  • 用户频繁请求该特定功能
  • 任务具有明确的边界和目标
  • 现有工具无法干净利落地完成该任务
  • 评估显示LLM在处理该任务时会选择错误的工具
在以下场景下请勿创建新工具:
  • 现有工具只需修改少量参数即可处理该任务
  • 功能重复(应合并而非新增)
  • 属于罕见的边缘情况(可通过现有工具+指导来处理)

When to Combine Operations

何时合并操作

Combine multiple operations into one tool when:
  • They're almost always used together
  • The intermediate results aren't useful alone
  • Splitting them creates unnecessary decision points
Keep operations separate when:
  • Users need granular control
  • Intermediate results have standalone value
  • Combining would create an overly complex tool
在以下场景下将多个操作合并为一个工具:
  • 这些操作几乎总是一起使用
  • 中间结果单独使用时无意义
  • 拆分操作会产生不必要的决策点
在以下场景下保持操作独立:
  • 用户需要细粒度控制
  • 中间结果具有独立价值
  • 合并会导致工具过于复杂

Balancing Granularity

粒度平衡

Granular ToolsCombined Tools
More flexibilitySimpler mental model
Higher selection burdenClearer intent
Risk of misuseLess customizable
细粒度工具合并后的工具
灵活性更高心智模型更简单
选择负担更重意图更清晰
存在误用风险可定制性更低

Quick Reference

快速参考

Tool Design Checklist

工具设计检查清单

  • Named for purpose, not implementation
  • Description explains when to use it
  • Parameters have clear descriptions
  • Response includes next steps or context
  • Tested with actual LLM requests
  • 命名体现目标,而非实现方式
  • 描述说明适用场景
  • 参数具有清晰的描述
  • 响应包含后续步骤或上下文
  • 已通过实际LLM请求测试

Red Flags

危险信号

  • More than 15 tools in a single server
  • Tools named after HTTP methods or endpoints
  • Generic tools that "can do anything"
  • Tools that require multiple calls for a single task
  • 单个服务器中的工具数量超过15个
  • 工具以HTTP方法或端点命名
  • 宣称“无所不能”的通用工具
  • 完成单个任务需要多次调用的工具

Resources

资源

references/

references/

  • design-principles.md
    - Extended examples, anti-patterns, and real-world case studies
For deeper exploration of these concepts, read the design principles reference document.
  • design-principles.md
    - 扩展示例、反模式和真实世界案例研究
如需深入探索这些概念,请阅读设计原则参考文档。