Skip to main content
This page provides complete, runnable examples of SDK-embedded MCP servers for various use cases.

Calculator Server

A complete calculator with multiple operations.
calculator.ts
import { z } from 'zod';
import { tool, createSdkMcpServer, query } from '@qwen-code/sdk';

// Define calculator tools
const addTool = tool(
  'add',
  'Add two numbers together',
  {
    a: z.number().describe('First number'),
    b: z.number().describe('Second number'),
  },
  async (args) => ({
    content: [{
      type: 'text',
      text: `${args.a} + ${args.b} = ${args.a + args.b}`,
    }],
  })
);

const subtractTool = tool(
  'subtract',
  'Subtract second number from first',
  {
    a: z.number().describe('First number'),
    b: z.number().describe('Second number'),
  },
  async (args) => ({
    content: [{
      type: 'text',
      text: `${args.a} - ${args.b} = ${args.a - args.b}`,
    }],
  })
);

const multiplyTool = tool(
  'multiply',
  'Multiply two numbers',
  {
    a: z.number().describe('First number'),
    b: z.number().describe('Second number'),
  },
  async (args) => ({
    content: [{
      type: 'text',
      text: `${args.a} × ${args.b} = ${args.a * args.b}`,
    }],
  })
);

const divideTool = tool(
  'divide',
  'Divide first number by second',
  {
    a: z.number().describe('Numerator'),
    b: z.number().describe('Denominator (non-zero)'),
  },
  async (args) => {
    if (args.b === 0) {
      return {
        content: [{ type: 'text', text: 'Error: Division by zero' }],
        isError: true,
      };
    }
    return {
      content: [{
        type: 'text',
        text: `${args.a} ÷ ${args.b} = ${args.a / args.b}`,
      }],
    };
  }
);

// Create calculator server
const calculatorServer = createSdkMcpServer({
  name: 'calculator',
  version: '1.0.0',
  tools: [addTool, subtractTool, multiplyTool, divideTool],
});

// Use the calculator
async function main() {
  const result = query({
    prompt: 'Calculate (15 + 7) × 3 - 10',
    options: {
      permissionMode: 'yolo',
      mcpServers: {
        calculator: calculatorServer,
      },
    },
  });

  for await (const message of result) {
    if (message.type === 'assistant') {
      console.log('\nAssistant:', message.message.content);
    } else if (message.type === 'result') {
      console.log('\nFinal result:', message.result);
    }
  }
}

main().catch(console.error);

Weather API Server

Fetch real weather data using an external API.
weather.ts
import { z } from 'zod';
import { tool, createSdkMcpServer, query } from '@qwen-code/sdk';

const weatherTool = tool(
  'get_weather',
  'Get current weather for a city using OpenWeatherMap API',
  {
    city: z.string().describe('City name (e.g., "San Francisco")'),
    units: z.enum(['metric', 'imperial'])
      .default('metric')
      .describe('Temperature units'),
  },
  async (args) => {
    try {
      const apiKey = process.env.OPENWEATHER_API_KEY;
      if (!apiKey) {
        return {
          content: [{
            type: 'text',
            text: 'Error: OPENWEATHER_API_KEY not configured',
          }],
          isError: true,
        };
      }

      const url = `https://api.openweathermap.org/data/2.5/weather?` +
        `q=${encodeURIComponent(args.city)}` +
        `&units=${args.units}` +
        `&appid=${apiKey}`;

      const response = await fetch(url);
      
      if (!response.ok) {
        const error = await response.json();
        return {
          content: [{
            type: 'text',
            text: `Weather API error: ${error.message}`,
          }],
          isError: true,
        };
      }

      const data = await response.json();
      const temp = data.main.temp;
      const feelsLike = data.main.feels_like;
      const humidity = data.main.humidity;
      const description = data.weather[0].description;
      const unit = args.units === 'metric' ? '°C' : '°F';

      return {
        content: [{
          type: 'text',
          text: `Weather in ${args.city}:\n` +
            `${description}\n` +
            `Temperature: ${temp}${unit} (feels like ${feelsLike}${unit})\n` +
            `Humidity: ${humidity}%`,
        }],
      };
    } catch (error) {
      return {
        content: [{
          type: 'text',
          text: `Failed to fetch weather: ${error.message}`,
        }],
        isError: true,
      };
    }
  }
);

const weatherServer = createSdkMcpServer({
  name: 'weather',
  tools: [weatherTool],
});

async function main() {
  const result = query({
    prompt: 'What is the weather like in London and Tokyo?',
    options: {
      permissionMode: 'yolo',
      env: {
        OPENWEATHER_API_KEY: 'your-api-key-here',
      },
      mcpServers: {
        weather: weatherServer,
      },
    },
  });

  for await (const message of result) {
    if (message.type === 'assistant') {
      console.log(message.message.content);
    }
  }
}

main().catch(console.error);

File Storage Server

Manage files with create, read, and list operations.
file-storage.ts
import { z } from 'zod';
import { tool, createSdkMcpServer, query } from '@qwen-code/sdk';
import * as fs from 'fs/promises';
import * as path from 'path';

const STORAGE_DIR = './mcp-storage';

// Ensure storage directory exists
await fs.mkdir(STORAGE_DIR, { recursive: true });

const createFileTool = tool(
  'create_file',
  'Create a new file with content',
  {
    filename: z.string().describe('Name of the file'),
    content: z.string().describe('Content to write'),
  },
  async (args) => {
    try {
      const filePath = path.join(STORAGE_DIR, args.filename);
      await fs.writeFile(filePath, args.content, 'utf-8');
      
      return {
        content: [{
          type: 'text',
          text: `Created ${args.filename} (${args.content.length} bytes)`,
        }],
      };
    } catch (error) {
      return {
        content: [{ type: 'text', text: `Error: ${error.message}` }],
        isError: true,
      };
    }
  }
);

const readFileTool = tool(
  'read_file',
  'Read content from a file',
  {
    filename: z.string().describe('Name of the file to read'),
  },
  async (args) => {
    try {
      const filePath = path.join(STORAGE_DIR, args.filename);
      const content = await fs.readFile(filePath, 'utf-8');
      
      return {
        content: [{
          type: 'text',
          text: `Content of ${args.filename}:\n${content}`,
        }],
      };
    } catch (error) {
      return {
        content: [{ type: 'text', text: `Error: ${error.message}` }],
        isError: true,
      };
    }
  }
);

const listFilesTool = tool(
  'list_files',
  'List all files in storage',
  {},
  async () => {
    try {
      const files = await fs.readdir(STORAGE_DIR);
      
      if (files.length === 0) {
        return {
          content: [{ type: 'text', text: 'No files in storage' }],
        };
      }
      
      const fileInfo = await Promise.all(
        files.map(async (file) => {
          const stats = await fs.stat(path.join(STORAGE_DIR, file));
          return `- ${file} (${stats.size} bytes)`;
        })
      );
      
      return {
        content: [{
          type: 'text',
          text: `Files in storage:\n${fileInfo.join('\n')}`,
        }],
      };
    } catch (error) {
      return {
        content: [{ type: 'text', text: `Error: ${error.message}` }],
        isError: true,
      };
    }
  }
);

const fileServer = createSdkMcpServer({
  name: 'file-storage',
  tools: [createFileTool, readFileTool, listFilesTool],
});

async function main() {
  const result = query({
    prompt: 'Create a file called notes.txt with "Hello from MCP!", ' +
      'then list all files, and read it back',
    options: {
      permissionMode: 'yolo',
      mcpServers: {
        files: fileServer,
      },
    },
  });

  for await (const message of result) {
    if (message.type === 'assistant') {
      console.log(message.message.content);
    }
  }
}

main().catch(console.error);

Data Processing Server

Process and analyze data with multiple tools.
data-processing.ts
import { z } from 'zod';
import { tool, createSdkMcpServer, query } from '@qwen-code/sdk';

// In-memory data store
const dataStore = new Map<string, number[]>();

const storeDataTool = tool(
  'store_data',
  'Store a dataset with a name',
  {
    name: z.string().describe('Dataset name'),
    values: z.array(z.number()).describe('Array of numbers'),
  },
  async (args) => {
    dataStore.set(args.name, args.values);
    return {
      content: [{
        type: 'text',
        text: `Stored dataset '${args.name}' with ${args.values.length} values`,
      }],
    };
  }
);

const calculateStatsTool = tool(
  'calculate_stats',
  'Calculate statistics for a stored dataset',
  {
    name: z.string().describe('Dataset name'),
  },
  async (args) => {
    const values = dataStore.get(args.name);
    
    if (!values) {
      return {
        content: [{ type: 'text', text: `Dataset '${args.name}' not found` }],
        isError: true,
      };
    }
    
    const sum = values.reduce((a, b) => a + b, 0);
    const mean = sum / values.length;
    const min = Math.min(...values);
    const max = Math.max(...values);
    const variance = values.reduce((acc, val) => acc + Math.pow(val - mean, 2), 0) / values.length;
    const stdDev = Math.sqrt(variance);
    
    return {
      content: [{
        type: 'text',
        text: `Statistics for '${args.name}':\n` +
          `Count: ${values.length}\n` +
          `Sum: ${sum}\n` +
          `Mean: ${mean.toFixed(2)}\n` +
          `Min: ${min}\n` +
          `Max: ${max}\n` +
          `Std Dev: ${stdDev.toFixed(2)}`,
      }],
    };
  }
);

const listDatasetsTool = tool(
  'list_datasets',
  'List all stored datasets',
  {},
  async () => {
    if (dataStore.size === 0) {
      return {
        content: [{ type: 'text', text: 'No datasets stored' }],
      };
    }
    
    const datasets = Array.from(dataStore.entries())
      .map(([name, values]) => `- ${name} (${values.length} values)`);
    
    return {
      content: [{
        type: 'text',
        text: `Stored datasets:\n${datasets.join('\n')}`,
      }],
    };
  }
);

const dataServer = createSdkMcpServer({
  name: 'data-processor',
  tools: [storeDataTool, calculateStatsTool, listDatasetsTool],
});

async function main() {
  const result = query({
    prompt: 'Store a dataset called "temperatures" with values [72, 75, 68, 71, 74, 73], ' +
      'then calculate its statistics',
    options: {
      permissionMode: 'yolo',
      mcpServers: {
        data: dataServer,
      },
    },
  });

  for await (const message of result) {
    if (message.type === 'assistant') {
      console.log(message.message.content);
    }
  }
}

main().catch(console.error);

Multi-Server Application

Combine multiple specialized servers in one application.
multi-server.ts
import { z } from 'zod';
import { tool, createSdkMcpServer, query } from '@qwen-code/sdk';

// Math server
const mathServer = createSdkMcpServer({
  name: 'math',
  tools: [
    tool('add', 'Add numbers', {
      a: z.number(), b: z.number()
    }, async (args) => ({
      content: [{ type: 'text', text: String(args.a + args.b) }],
    })),
    tool('factorial', 'Calculate factorial', {
      n: z.number().int().min(0).max(20)
    }, async (args) => {
      let result = 1;
      for (let i = 2; i <= args.n; i++) {
        result *= i;
      }
      return {
        content: [{ type: 'text', text: `${args.n}! = ${result}` }],
      };
    }),
  ],
});

// Time server
const timeServer = createSdkMcpServer({
  name: 'time',
  tools: [
    tool('get_time', 'Get current time', {}, async () => ({
      content: [{ type: 'text', text: new Date().toISOString() }],
    })),
    tool('get_timestamp', 'Get Unix timestamp', {}, async () => ({
      content: [{ type: 'text', text: String(Date.now()) }],
    })),
  ],
});

// Random server
const randomServer = createSdkMcpServer({
  name: 'random',
  tools: [
    tool('random_number', 'Generate random number', {
      min: z.number().default(0),
      max: z.number().default(100),
    }, async (args) => {
      const num = Math.random() * (args.max - args.min) + args.min;
      return {
        content: [{ type: 'text', text: String(num.toFixed(2)) }],
      };
    }),
  ],
});

async function main() {
  const result = query({
    prompt: 'What time is it? Also, calculate 5 factorial and generate a random number between 1 and 10',
    options: {
      permissionMode: 'yolo',
      mcpServers: {
        math: mathServer,
        time: timeServer,
        random: randomServer,
      },
    },
  });

  for await (const message of result) {
    if (message.type === 'assistant') {
      console.log('\n', message.message.content);
    } else if (message.type === 'result') {
      console.log('\nCompleted in', message.duration_ms, 'ms');
    }
  }
}

main().catch(console.error);

Environment Configuration Server

Manage environment variables and configuration.
env-config.ts
import { z } from 'zod';
import { tool, createSdkMcpServer, query } from '@qwen-code/sdk';

const getEnvTool = tool(
  'get_env',
  'Get an environment variable value',
  {
    key: z.string().describe('Environment variable name'),
  },
  async (args) => {
    const value = process.env[args.key];
    if (value === undefined) {
      return {
        content: [{ type: 'text', text: `${args.key} is not set` }],
      };
    }
    return {
      content: [{ type: 'text', text: `${args.key} = ${value}` }],
    };
  }
);

const listEnvTool = tool(
  'list_env',
  'List all environment variables matching a pattern',
  {
    pattern: z.string().optional().describe('Pattern to match (case-insensitive)'),
  },
  async (args) => {
    const pattern = args.pattern?.toLowerCase();
    const vars = Object.keys(process.env)
      .filter(key => !pattern || key.toLowerCase().includes(pattern))
      .sort();
    
    if (vars.length === 0) {
      return {
        content: [{ type: 'text', text: 'No matching environment variables' }],
      };
    }
    
    return {
      content: [{
        type: 'text',
        text: `Environment variables${pattern ? ` matching '${pattern}'` : ''}:\n` +
          vars.map(key => `- ${key}`).join('\n'),
      }],
    };
  }
);

const envServer = createSdkMcpServer({
  name: 'environment',
  tools: [getEnvTool, listEnvTool],
});

async function main() {
  const result = query({
    prompt: 'List all PATH-related environment variables',
    options: {
      permissionMode: 'yolo',
      mcpServers: {
        env: envServer,
      },
    },
  });

  for await (const message of result) {
    if (message.type === 'assistant') {
      console.log(message.message.content);
    }
  }
}

main().catch(console.error);

Running the Examples

All examples can be run with:
npx tsx example-name.ts
Make sure to set any required environment variables (like OPENWEATHER_API_KEY for the weather example).

Next Steps

tool() Function

Learn how to create tools

createSdkMcpServer()

Create server instances

MCP Overview

Understand MCP integration

SDK Examples

More SDK examples

Build docs developers (and LLMs) love