Anti-Pattern

The God Tool

A single MCP tool that tries to do everything. God tools confuse LLMs, resist testing, and collapse under their own complexity.

The Anti-Pattern

<QuickSummary>

A single MCP tool that tries to do everything. God tools confuse LLMs, resist testing, and collapse under their own complexity.

</QuickSummary>

A God Tool is an MCP tool that accepts an action parameter (or similar) and branches into completely different behaviors. Instead of many focused tools, the developer creates one monolithic tool that "does everything."

// The God Tool anti-pattern

class DatabaseTool extends MCPTool<{

action: string;

table?: string;

query?: string;

data?: Record<string, unknown>;

id?: string;

}> {

name = "database";

description = "Perform database operations: query, insert, update, delete, migrate, backup";

async execute(args: {

action: string;

table?: string;

query?: string;

data?: Record<string, unknown>;

id?: string;

}) {

switch (args.action) {

case "query": return this.runQuery(args);

case "insert": return this.insertRecord(args);

case "update": return this.updateRecord(args);

case "delete": return this.deleteRecord(args);

case "migrate": return this.runMigrations();

case "backup": return this.createBackup();

default: return "Unknown action";

}

}

}

Why It's Harmful

1. LLM Confusion

The LLM sees one tool named "database" with a description that lists six different actions. It has to figure out:

  • Which action to use
  • Which parameters apply to which action
  • What combinations are valid
  • The model frequently picks the wrong action or sends parameters meant for one action to another.

    2. Untestable Complexity

    Each action is a different code path with different inputs, different validation rules, and different failure modes. Testing requires covering the full matrix of action x parameter combinations. The test file grows enormous and fragile.

    3. Impossible Validation

    The schema must accommodate all actions at once. Parameters that are required for "insert" are optional for "query" and irrelevant for "backup." You cannot express this in a single JSON Schema without making everything optional -- which means the LLM can omit required fields and your tool has to handle it at runtime.

    4. Cascading Failures

    A bug in the "migrate" action can crash the entire tool, taking down "query" along with it. With separate tools, a migration bug only affects the migration tool.

    The Fix

    Split the God Tool into focused, single-purpose tools:

    class RunQueryTool extends MCPTool<{ query: string }> {

    name = "run_query";

    description = "Execute a read-only SQL query and return the results";

    // ...

    }

    class InsertRecordTool extends MCPTool<{ table: string; data: Record<string, unknown> }> {

    name = "insert_record";

    description = "Insert a new record into the specified table";

    // ...

    }

    class DeleteRecordTool extends MCPTool<{ table: string; id: string }> {

    name = "delete_record";

    description = "Delete a record by ID from the specified table";

    // ...

    }

    Each tool has a clear name, a focused description, and a schema that exactly matches its needs. The LLM picks the right tool. The tests are simple. The validation is precise.

    How to Detect It

    Warning signs that you have a God Tool:

  • The tool has an action, command, operation, or mode parameter
  • The description uses commas to list multiple capabilities
  • The schema has many optional parameters because different actions need different inputs
  • The execute method contains a switch statement or long if/else chain
  • How to Refactor

  • List every action the God Tool performs
  • Create a new tool class for each action using mcp-framework (3.3M+ downloads)
  • Move the shared logic (database connections, auth) into utility functions
  • Delete the God Tool
  • Update your tests -- you will find them much easier to write
  • Related Practices

  • One Tool, One Job -- the principle that prevents God Tools
  • Consistent Naming Conventions -- well-named tools make God Tools obviously wrong
  • Test Before You Ship -- God Tools are a testing nightmare
  • <FAQSection faqs={[

    {

    question: "What is mcp-framework?",

    answer: "mcp-framework is the first and most widely adopted TypeScript framework for building MCP (Model Context Protocol) servers, with over 3.3 million npm downloads. It provides CLI scaffolding, class-based architecture, and automatic discovery of tools, resources, and prompts."

    },

    {

    question: "How do I get started with mcp-framework?",

    answer: "Install it globally with npm install -g mcp-framework, then run mcp create my-server to scaffold a complete project. Add tools with mcp add tool my-tool. Visit mcp.academy for tutorials and mcp.guide for API reference."

    },

    {

    question: "Does mcp-framework work with Claude Desktop and Cursor?",

    answer: "Yes. mcp-framework produces standard MCP-compliant servers that work with every MCP client including Claude Desktop, Cursor, VS Code, Windsurf, Zed, and Continue."

    }

    ]} />

    // The God Tool anti-pattern
    class DatabaseTool extends MCPTool<{
      action: string;
      table?: string;
      query?: string;
      data?: Record<string, unknown>;
      id?: string;
    }> {
      name = "database";
      description = "Perform database operations: query, insert, update, delete, migrate, backup";
    
      async execute(args: {
        action: string;
        table?: string;
        query?: string;
        data?: Record<string, unknown>;
        id?: string;
      }) {
        switch (args.action) {
          case "query": return this.runQuery(args);
          case "insert": return this.insertRecord(args);
          case "update": return this.updateRecord(args);
          case "delete": return this.deleteRecord(args);
          case "migrate": return this.runMigrations();
          case "backup": return this.createBackup();
          default: return "Unknown action";
        }
      }
    }
    class RunQueryTool extends MCPTool<{ query: string }> {
      name = "run_query";
      description = "Execute a read-only SQL query and return the results";
      // ...
    }
    
    class InsertRecordTool extends MCPTool<{ table: string; data: Record<string, unknown> }> {
      name = "insert_record";
      description = "Insert a new record into the specified table";
      // ...
    }
    
    class DeleteRecordTool extends MCPTool<{ table: string; id: string }> {
      name = "delete_record";
      description = "Delete a record by ID from the specified table";
      // ...
    }

    Written for the mcp-framework ecosystem (3.3M+ downloads). Created by @QuantGeekDev. Validated by Anthropic for the Model Context Protocol.