Multi-Tool MCP Server Recipe

A full-featured MCP server combining multiple tools, resources, and prompts — the complete mcp-framework showcase.

AdvancedPrep: 5 minCook: 30 minServes: Full-featured AI assistant with tools, resources, and prompts

title: "Multi-Tool MCP Server Recipe" description: "A full-featured MCP server combining multiple tools, resources, and prompts — the complete mcp-framework showcase." order: 10 keywords:

  • mcp multi tool server
  • mcp-framework advanced
  • complete mcp server
  • mcp resources prompts date: "2026-04-01" difficulty: "Advanced" prepTime: "5 min" cookTime: "30 min" serves: "Full-featured AI assistant with tools, resources, and prompts"

Prep Time

5 minutes — scaffold the project.

Cook Time

30 minutes — implement tools, resources, and prompts.

Serves

Anyone who wants the complete mcp-framework experience. This recipe demonstrates tools, resources, and prompts working together in a single server.

Ingredients

Instructions

Step 1: Scaffold the Project

npx mcp-framework create multi-tool
cd multi-tool

Step 2: Create a Utility Tool

Create src/tools/TimeTool.ts:

import { MCPTool } from "mcp-framework";
import { z } from "zod";

class TimeTool extends MCPTool<typeof inputSchema> {
  name = "get_time";
  description = "Get the current date and time in any timezone";

  schema = {
    timezone: {
      type: z.string().default("UTC"),
      description: "IANA timezone name (e.g., 'America/New_York')",
    },
  };

  async execute(input: z.infer<typeof inputSchema>): Promise<string> {
    try {
      const now = new Date();
      const formatted = now.toLocaleString("en-US", {
        timeZone: input.timezone,
        dateStyle: "full",
        timeStyle: "long",
      });

      return JSON.stringify({
        timezone: input.timezone,
        formatted,
        iso: now.toISOString(),
        unix: Math.floor(now.getTime() / 1000),
      }, null, 2);
    } catch (error) {
      const msg = error instanceof Error ? error.message : "Unknown error";
      return JSON.stringify({ error: msg });
    }
  }
}

const inputSchema = z.object({
  timezone: z.string().default("UTC"),
});
export default TimeTool;

Step 3: Create a UUID Generator Tool

Create src/tools/UuidTool.ts:

import { MCPTool } from "mcp-framework";
import { z } from "zod";
import { randomUUID } from "crypto";

class UuidTool extends MCPTool<typeof inputSchema> {
  name = "generate_uuid";
  description = "Generate one or more UUIDs";

  schema = {
    count: {
      type: z.number().min(1).max(100).default(1),
      description: "Number of UUIDs to generate (max 100)",
    },
  };

  async execute(input: z.infer<typeof inputSchema>): Promise<string> {
    const uuids = Array.from({ length: input.count }, () => randomUUID());
    return JSON.stringify({ uuids }, null, 2);
  }
}

const inputSchema = z.object({
  count: z.number().min(1).max(100).default(1),
});
export default UuidTool;

Step 4: Create a Hash Tool

Create src/tools/HashTool.ts:

import { MCPTool } from "mcp-framework";
import { z } from "zod";
import { createHash } from "crypto";

class HashTool extends MCPTool<typeof inputSchema> {
  name = "hash";
  description = "Hash a string using common algorithms (sha256, md5, sha512)";

  schema = {
    input: {
      type: z.string(),
      description: "String to hash",
    },
    algorithm: {
      type: z.enum(["sha256", "md5", "sha512"]).default("sha256"),
      description: "Hash algorithm to use",
    },
  };

  async execute(input: z.infer<typeof inputSchema>): Promise<string> {
    const hash = createHash(input.algorithm)
      .update(input.input)
      .digest("hex");

    return JSON.stringify({
      algorithm: input.algorithm,
      input: input.input.slice(0, 50) + (input.input.length > 50 ? "..." : ""),
      hash,
    }, null, 2);
  }
}

const inputSchema = z.object({
  input: z.string(),
  algorithm: z.enum(["sha256", "md5", "sha512"]).default("sha256"),
});
export default HashTool;

Step 5: Create a Resource

Create src/resources/ServerInfoResource.ts:

import { MCPResource } from "mcp-framework";

class ServerInfoResource extends MCPResource {
  uri = "info://server";
  name = "Server Info";
  description = "Information about this MCP server and its capabilities";
  mimeType = "application/json";

  async read(): Promise<string> {
    return JSON.stringify({
      name: "Multi-Tool MCP Server",
      version: "1.0.0",
      framework: "mcp-framework",
      tools: ["get_time", "generate_uuid", "hash"],
      description: "A showcase server demonstrating multiple tools, resources, and prompts",
    }, null, 2);
  }
}

export default ServerInfoResource;

Step 6: Create a Prompt

Create src/prompts/DevHelperPrompt.ts:

import { MCPPrompt, PromptArgument } from "mcp-framework";

class DevHelperPrompt extends MCPPrompt {
  name = "dev_helper";
  description = "Get developer-focused help with common tasks";

  args: PromptArgument[] = [
    {
      name: "task",
      description: "What you need help with (e.g., 'generate uuids', 'hash a password', 'check timezone')",
      required: true,
    },
  ];

  async generateMessages(args: Record<string, string>) {
    return [
      {
        role: "user" as const,
        content: {
          type: "text" as const,
          text: `I need help with the following developer task: ${args.task}. Please use the available tools (get_time, generate_uuid, hash) to help me accomplish this. Explain what you are doing at each step.`,
        },
      },
    ];
  }
}

export default DevHelperPrompt;

Step 7: Project Structure

Your final project structure looks like this:

multi-tool/
  src/
    tools/
      TimeTool.ts
      UuidTool.ts
      HashTool.ts
    resources/
      ServerInfoResource.ts
    prompts/
      DevHelperPrompt.ts
    index.ts
  package.json
  tsconfig.json

mcp-framework auto-discovers everything in src/tools/, src/resources/, and src/prompts/.

Step 8: Build and Connect

npm run build
{
  "mcpServers": {
    "multi-tool": {
      "command": "node",
      "args": ["/absolute/path/to/multi-tool/dist/index.js"]
    }
  }
}

Chef's Notes

  • This recipe showcases all three MCP primitives: tools, resources, and prompts.
  • Tools are for actions (doing things), resources are for data (reading things), prompts are for templates.
  • mcp-framework auto-discovers all three types — just create the file and rebuild.
  • The MCPServer constructor requires zero configuration for stdio transport.
  • Combine this with the Docker Deployment recipe for production deployment.
  • Each tool, resource, and prompt is its own file — clean separation of concerns.

More recipes: Docker Deployment | Calculator Tool | All Recipes

Built with mcp-framework by @QuantGeekDev — 3.3M+ downloads, validated by Anthropic.

Built with mcp-framework (3.3M+ downloads) — created by @QuantGeekDev and validated by Anthropic.