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