Skip to main content
Glama
dasheck0

Face Generator MCP Server

generate_face

Generate realistic human face images that don't represent real people. Save images to specified directories with customizable dimensions, shapes, and batch generation options.

Instructions

Generate and save a human face image

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
outputDirYesDirectory to save the image
fileNameNoOptional file name (defaults to timestamp)1767357705977.png
countNoNumber of images to generate (default: 1)
widthNoWidth of the image in pixels (default: 256)
heightNoHeight of the image in pixels (default: 256)
shapeNoImage shape (square|circle|rounded, default: square)square
borderRadiusNoBorder radius for rounded shape (default: 32)
returnImageContentNoReturn image as base64 encoded content instead of file path (default: false)

Implementation Reference

  • The CallToolRequestSchema handler implements the generate_face tool: validates name, parses arguments, fetches random face images from https://thispersondoesnotexist.com, processes with Sharp (resize, shape masking), saves to outputDir, optionally returns base64 ImageContent.
    this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
      if (request.params.name !== 'generate_face') {
        throw new Error(`Unknown tool: ${request.params.name}`);
      }
    
      interface GenerateFaceArgs {
        outputDir: string;
        fileName?: string;
        count?: number;
        width?: number;
        height?: number;
        shape?: string;
        borderRadius?: number;
        returnImageContent?: boolean;
      }
      
      if (!request.params.arguments) {
        throw new Error('Arguments are required');
      }
      
      const args = request.params.arguments as unknown as GenerateFaceArgs;
      const { 
        outputDir, 
        fileName = `${Date.now()}.jpg`,
        count = 1,
        width = 256,
        height = 256,
        returnImageContent = false
      } = args;
    
      try {
        // Create directory if it doesn't exist
        if (!fs.existsSync(outputDir)) {
          fs.mkdirSync(outputDir, { recursive: true });
        }
    
        const sharp = (await import('sharp')).default;
        const results = [];
        const imageContents: ImageContent[] = [];
    
        for (let i = 0; i < count; i++) {
          // Fetch image
          const response = await axios.get('https://thispersondoesnotexist.com', {
            responseType: 'arraybuffer',
          });
    
          // Process image
          let image = sharp(response.data)
            .resize(width, height);
    
          // Apply shape transformations
          switch (args.shape || 'square') {
            case 'circle':
              const radius = Math.min(width, height) / 2;
              const circleShape = Buffer.from(
                `<svg><circle cx="${radius}" cy="${radius}" r="${radius}" fill="white" /></svg>`
              );
              image = image.composite([{
                input: circleShape,
                blend: 'dest-in'
              }]);
              break;
    
            case 'rounded':
              const borderRadius = args.borderRadius || 32;
              const roundedShape = Buffer.from(
                `<svg><rect width="${width}" height="${height}" rx="${borderRadius}" ry="${borderRadius}" fill="white" /></svg>`
              );
              image = image.composite([{
                input: roundedShape,
                blend: 'dest-in'
              }]);
              break;
          }
    
          const imageBuffer = await image.png().toBuffer();
          const base64Image = imageBuffer.toString('base64');
    
          // Generate unique filename if multiple images
          // Ensure .png extension
          const baseName = fileName.replace(/\.(jpg|jpeg|png)$/i, '');
          const finalFileName = count > 1
            ? `${baseName}_${i}.png`
            : `${baseName}.png`;
    
          // Save image
          const filePath = path.join(outputDir, finalFileName);
          await fs.promises.writeFile(filePath, imageBuffer);
    
          if (returnImageContent) {
            imageContents.push({
              type: 'image',
              mimeType: 'image/png',
              data: base64Image,
            });
          }
    
          results.push(filePath);
        }
    
        const content = returnImageContent
          ? imageContents
          : [
              {
                type: 'text',
                text: `Generated ${count} face image(s):\n${results.join('\n')}`,
              },
            ];
    
        return {
          content,
        };
      } catch (error) {
        console.error(error);
        let errorCode = ErrorCode.InternalError;
        let errorMessage = 'Unknown error occurred';
    
        if (error instanceof axios.AxiosError) {
          if (error.code === 'ENOTFOUND') {
            errorCode = ErrorCode.MethodNotFound;
            errorMessage = 'Failed to fetch image from thispersondoesnotexist.com: Network error.';
          } else {
            errorCode = ErrorCode.InternalError;
            errorMessage = `Failed to fetch image: ${error.message}`;
          }
        } else if (error instanceof Error) {
          errorMessage = error.message;
          if (error.message.includes('ENOSPC')) {
            errorCode = ErrorCode.InternalError;
            errorMessage = 'No space left on device.';
          } else if (error.message.includes('EEXIST')) {
            errorCode = ErrorCode.InternalError;
            errorMessage = 'File already exists.';
          } else if (error.message.includes('ENOENT')) {
            errorCode = ErrorCode.InternalError;
            errorMessage = 'No such file or directory.';
          } else if (error.message.includes('Invalid width')) {
            errorCode = ErrorCode.InvalidParams;
            errorMessage = 'Invalid width parameter.';
          } else if (error.message.includes('Invalid height')) {
            errorCode = ErrorCode.InvalidParams;
            errorMessage = 'Invalid height parameter.';
          } else if (error.message.includes('Input buffer contains unsupported image format')) {
            errorCode = ErrorCode.InvalidParams;
            errorMessage = 'Unsupported image format.';
          }
        } else {
          errorMessage = String(error);
        }
    
        const result: CallToolResult = {
          content: [
            {
              type: 'text',
              text: `Error generating face: ${errorMessage}`,
            },
          ],
          isError: true,
        };
        return result;
      }
    });
  • TypeScript interface defining the input arguments for generate_face tool, matching the inputSchema.
    interface GenerateFaceArgs {
      outputDir: string;
      fileName?: string;
      count?: number;
      width?: number;
      height?: number;
      shape?: string;
      borderRadius?: number;
      returnImageContent?: boolean;
    }
  • src/index.ts:37-94 (registration)
    Tool registration in ListToolsRequestSchema response, defining name, description, and detailed inputSchema for validation.
    {
      name: 'generate_face',
      description: 'Generate and save a human face image',
      inputSchema: {
        type: 'object',
        properties: {
          outputDir: {
            type: 'string',
            description: 'Directory to save the image',
          },
          fileName: {
            type: 'string',
            description: 'Optional file name (defaults to timestamp)',
            default: `${Date.now()}.png`,
          },
          count: {
            type: 'number',
            description: 'Number of images to generate (default: 1)',
            default: 1,
            minimum: 1,
            maximum: 10
          },
          width: {
            type: 'number',
            description: 'Width of the image in pixels (default: 256)',
            default: 256,
            minimum: 64,
            maximum: 1024
          },
          height: {
            type: 'number',
            description: 'Height of the image in pixels (default: 256)',
            default: 256,
            minimum: 64,
            maximum: 1024
          },
          shape: {
            type: 'string',
            description: 'Image shape (square|circle|rounded, default: square)',
            default: 'square',
            enum: ['square', 'circle', 'rounded']
          },
          borderRadius: {
            type: 'number',
            description: 'Border radius for rounded shape (default: 32)',
            default: 32,
            minimum: 0,
            maximum: 512
          },
          returnImageContent: {
            type: 'boolean',
            description: 'Return image as base64 encoded content instead of file path (default: false)',
            default: false
          }
        },
        required: ['outputDir'],
      },
    },
  • JSON schema for generate_face tool inputs, used for validation in tool listing.
    inputSchema: {
      type: 'object',
      properties: {
        outputDir: {
          type: 'string',
          description: 'Directory to save the image',
        },
        fileName: {
          type: 'string',
          description: 'Optional file name (defaults to timestamp)',
          default: `${Date.now()}.png`,
        },
        count: {
          type: 'number',
          description: 'Number of images to generate (default: 1)',
          default: 1,
          minimum: 1,
          maximum: 10
        },
        width: {
          type: 'number',
          description: 'Width of the image in pixels (default: 256)',
          default: 256,
          minimum: 64,
          maximum: 1024
        },
        height: {
          type: 'number',
          description: 'Height of the image in pixels (default: 256)',
          default: 256,
          minimum: 64,
          maximum: 1024
        },
        shape: {
          type: 'string',
          description: 'Image shape (square|circle|rounded, default: square)',
          default: 'square',
          enum: ['square', 'circle', 'rounded']
        },
        borderRadius: {
          type: 'number',
          description: 'Border radius for rounded shape (default: 32)',
          default: 32,
          minimum: 0,
          maximum: 512
        },
        returnImageContent: {
          type: 'boolean',
          description: 'Return image as base64 encoded content instead of file path (default: false)',
          default: false
        }
      },
      required: ['outputDir'],
Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dasheck0/face-generator'

If you have feedback or need assistance with the MCP directory API, please join our Discord server