Examples

Common Patterns

Real-world examples and patterns for using the Nuxt MCP module.

Overview

This page demonstrates common patterns and real-world examples for using the Nuxt MCP module.

Input Validation Tool

Validate user inputs like emails and URLs:

server/mcp/tools/validate-input.ts
import { z } from 'zod'

export default defineMcpTool({
  description: 'Validate common input formats like email and URL',
  inputSchema: {
    value: z.string().describe('Value to validate'),
    type: z.enum(['email', 'url']).describe('Type of validation'),
  },
  outputSchema: {
    isValid: z.boolean(),
    message: z.string(),
  },
  handler: async ({ value, type }) => {
    let isValid = false
    let message = ''

    if (type === 'email') {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
      isValid = emailRegex.test(value)
      message = isValid ? 'Valid email address' : 'Invalid email format'
    }
    else if (type === 'url') {
      try {
        new URL(value)
        isValid = true
        message = 'Valid URL'
      }
      catch {
        message = 'Invalid URL format'
      }
    }

    return {
      content: [{
        type: 'text',
        text: `${type.toUpperCase()}: ${value}\nResult: ${message}`,
      }],
      structuredContent: { isValid, message },
    }
  },
})

Generate Slug Tool

Generate URL-friendly slugs from titles:

server/mcp/tools/generate-slug.ts
import { z } from 'zod'

export default defineMcpTool({
  description: 'Generate a URL-friendly slug from a title',
  inputSchema: {
    title: z.string().describe('Title to convert to slug'),
    separator: z.enum(['-', '_']).default('-').describe('Word separator'),
  },
  outputSchema: {
    slug: z.string(),
  },
  handler: async ({ title, separator }) => {
    const slug = title
      .toLowerCase()
      .normalize('NFD')
      .replace(/[\u0300-\u036F]/g, '') // Remove accents
      .replace(/[^a-z0-9\s-]/g, '') // Remove special chars
      .trim()
      .replace(/\s+/g, separator) // Replace spaces
      .replace(new RegExp(`${separator}+`, 'g'), separator) // Remove duplicate separators

    return {
      content: [{
        type: 'text',
        text: slug,
      }],
      structuredContent: { slug },
    }
  },
})

Format Converter Tool

Convert between JSON and YAML formats:

server/mcp/tools/convert-format.ts
import { z } from 'zod'
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml'

export default defineMcpTool({
  description: 'Convert between JSON and YAML formats',
  inputSchema: {
    content: z.string().describe('Content to convert'),
    from: z.enum(['json', 'yaml']).describe('Source format'),
    to: z.enum(['json', 'yaml']).describe('Target format'),
  },
  handler: async ({ content, from, to }) => {
    try {
      // Parse input
      let data: unknown
      if (from === 'json') {
        data = JSON.parse(content)
      }
      else {
        data = parseYaml(content)
      }

      // Convert to target format
      let result: string
      if (to === 'json') {
        result = JSON.stringify(data, null, 2)
      }
      else {
        result = stringifyYaml(data)
      }

      return {
        content: [{
          type: 'text',
          text: result,
        }],
      }
    }
    catch (error) {
      return {
        content: [{
          type: 'text',
          text: `Error: ${error instanceof Error ? error.message : String(error)}`,
        }],
        isError: true,
      }
    }
  },
})

Health Check Tool

Check if an API or service is available:

server/mcp/tools/health-check.ts
import { z } from 'zod'

export default defineMcpTool({
  description: 'Check if a URL endpoint is reachable',
  inputSchema: {
    url: z.string().url().describe('URL to check'),
    timeout: z.number().default(5000).describe('Timeout in milliseconds'),
  },
  outputSchema: {
    status: z.enum(['healthy', 'unhealthy']),
    responseTime: z.number().optional(),
    statusCode: z.number().optional(),
  },
  handler: async ({ url, timeout }) => {
    const start = Date.now()

    try {
      const response = await $fetch.raw(url, {
        timeout,
        method: 'HEAD',
      })

      const responseTime = Date.now() - start

      return {
        content: [{
          type: 'text',
          text: `${url} is healthy (${responseTime}ms, status: ${response.status})`,
        }],
        structuredContent: {
          status: 'healthy' as const,
          responseTime,
          statusCode: response.status,
        },
      }
    }
    catch (error) {
      const responseTime = Date.now() - start

      return {
        content: [{
          type: 'text',
          text: `${url} is unhealthy (${responseTime}ms): ${error instanceof Error ? error.message : String(error)}`,
        }],
        structuredContent: {
          status: 'unhealthy' as const,
          responseTime,
        },
      }
    }
  },
})

Next Steps