mcpField
M
mcp-server-design

mcp-server-design

github.com/xmcp-devDevelopment077 installsUpdated 37w ago
Repository

About mcp-server-design

A skill for designing MCP servers around how LLM agents reason. It helps server developers shape task-oriented tools while reducing selection effort and unnecessary steps.

Key features

  1. 01Design tools around tasks
  2. 02Control tool count and granularity
  3. 03Name tools by purpose
  4. 04Provide actionable context
  5. 05Use evaluations to guide additions

Use cases

  1. 01Plan an MCP server's tool set
  2. 02Combine operations often used together
  3. 03Review tool names and descriptions

MCP support

The skill offers principles for designing MCP servers and their tools for LLM agents, rather than mechanically wrapping API endpoints.

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/xmcp-dev/skills --skill mcp-server-design

After installing, type/mcp-server-designin Claude Code to confirm it loaded.

Bundled filesreferences/design-principles.md

Details

From the project README

MCP Server Design

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.

Core Philosophy

Design for Agents, Not Automation

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
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

Tool Design Principles

1. Purpose-Built Tools Over Generic Wrappers

Anti-pattern: Wrapping every API endpoint as a tool

// 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

// 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

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
3. Name Tools for Purpose, Not Implementation

Tool names guide LLM behavior. The name should describe the task, not the mechanism.

Instead of...Use...
post-slack-messagenotify-team
run-sql-queryanalyze-data
call-api-endpointcheck-service-status
4. Shape Tools Like Tasks

For complex flows, one tool per task beats one tool per step.

Anti-pattern: Breaking deployment into atomic operations

// 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

// 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)
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
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

Resources

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.

Comments

Markdown supported