Skip to main content
Glama
index.ts19.6 kB
#!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, Tool, ListPromptsRequestSchema, GetPromptRequestSchema, PromptMessage, } from "@modelcontextprotocol/sdk/types.js"; import { randomBytes, randomInt, randomUUID } from "crypto"; /** * State-of-the-art Random Number Generator MCP Server * * This server provides cryptographically secure random number generation * capabilities through the Model Context Protocol (MCP). */ class RandomNumberGeneratorServer { private server: Server; constructor() { this.server = new Server( { name: "pluggedin-random-number-generator-mcp", version: "1.0.0", }, { capabilities: { tools: {}, prompts: {}, }, } ); this.setupToolHandlers(); this.setupPromptHandlers(); this.setupErrorHandling(); } private setupToolHandlers(): void { // List available tools this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "generate_random_integer", description: "Generate cryptographically secure random integers within a specified range", inputSchema: { type: "object", properties: { min: { type: "integer", description: "Minimum value (inclusive)", default: 0, }, max: { type: "integer", description: "Maximum value (inclusive)", default: 100, }, count: { type: "integer", description: "Number of random integers to generate", default: 1, minimum: 1, maximum: 1000, }, }, required: [], }, }, { name: "generate_random_float", description: "Generate cryptographically secure random floating-point numbers", inputSchema: { type: "object", properties: { min: { type: "number", description: "Minimum value (inclusive)", default: 0.0, }, max: { type: "number", description: "Maximum value (exclusive)", default: 1.0, }, count: { type: "integer", description: "Number of random floats to generate", default: 1, minimum: 1, maximum: 1000, }, precision: { type: "integer", description: "Number of decimal places to round to", default: 6, minimum: 1, maximum: 15, }, }, required: [], }, }, { name: "generate_random_bytes", description: "Generate cryptographically secure random bytes", inputSchema: { type: "object", properties: { length: { type: "integer", description: "Number of random bytes to generate", default: 32, minimum: 1, maximum: 1024, }, encoding: { type: "string", description: "Output encoding format", enum: ["hex", "base64", "binary"], default: "hex", }, }, required: [], }, }, { name: "generate_uuid", description: "Generate a cryptographically secure UUID (v4)", inputSchema: { type: "object", properties: { count: { type: "integer", description: "Number of UUIDs to generate", default: 1, minimum: 1, maximum: 100, }, format: { type: "string", description: "UUID format", enum: ["standard", "compact"], default: "standard", }, }, required: [], }, }, { name: "generate_random_string", description: "Generate a cryptographically secure random string", inputSchema: { type: "object", properties: { length: { type: "integer", description: "Length of the random string", default: 16, minimum: 1, maximum: 256, }, charset: { type: "string", description: "Character set to use", enum: ["alphanumeric", "alphabetic", "numeric", "hex", "base64", "ascii_printable"], default: "alphanumeric", }, count: { type: "integer", description: "Number of random strings to generate", default: 1, minimum: 1, maximum: 100, }, }, required: [], }, }, { name: "generate_random_choice", description: "Randomly select items from a given list using cryptographically secure randomness", inputSchema: { type: "object", properties: { choices: { type: "array", description: "Array of items to choose from", items: { type: "string", }, minItems: 1, }, count: { type: "integer", description: "Number of items to select", default: 1, minimum: 1, }, allow_duplicates: { type: "boolean", description: "Whether to allow duplicate selections", default: true, }, }, required: ["choices"], }, }, { name: "generate_random_boolean", description: "Generate cryptographically secure random boolean values", inputSchema: { type: "object", properties: { count: { type: "integer", description: "Number of random booleans to generate", default: 1, minimum: 1, maximum: 1000, }, probability: { type: "number", description: "Probability of true (0.0 to 1.0)", default: 0.5, minimum: 0.0, maximum: 1.0, }, }, required: [], }, }, ] as Tool[], }; }); // Handle tool calls this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { switch (name) { case "generate_random_integer": return await this.generateRandomInteger(args); case "generate_random_float": return await this.generateRandomFloat(args); case "generate_random_bytes": return await this.generateRandomBytes(args); case "generate_uuid": return await this.generateUUID(args); case "generate_random_string": return await this.generateRandomString(args); case "generate_random_choice": return await this.generateRandomChoice(args); case "generate_random_boolean": return await this.generateRandomBoolean(args); default: throw new Error(`Unknown tool: ${name}`); } } catch (error) { return { content: [ { type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } }); } private setupPromptHandlers(): void { // List available prompts this.server.setRequestHandler(ListPromptsRequestSchema, async () => { return { prompts: [ { name: "generate_random", description: "Help me generate random values using cryptographically secure methods", arguments: [ { name: "type", description: "Type of random value needed (integer, float, uuid, string, bytes, choice, boolean)", required: false, }, { name: "requirements", description: "Specific requirements for the random generation", required: false, }, ], }, ], }; }); // Get specific prompt this.server.setRequestHandler(GetPromptRequestSchema, async (request) => { const { name, arguments: args } = request.params; if (name === "generate_random") { const type = args?.type || "any"; const requirements = args?.requirements || ""; const messages: PromptMessage[] = [ { role: "user", content: { type: "text", text: `I need to generate random values. ${requirements ? `Requirements: ${requirements}` : ""} ${type !== "any" ? `Type: ${type}` : ""}`, }, }, { role: "assistant", content: { type: "text", text: `I'll help you generate cryptographically secure random values. As an AI, I cannot generate truly random numbers myself, but I have access to a cryptographically secure random number generator through MCP tools. Available random generation tools: 1. **generate_random_integer** - Generate random integers within a range 2. **generate_random_float** - Generate random floating-point numbers 3. **generate_random_bytes** - Generate random bytes (hex/base64/buffer) 4. **generate_uuid** - Generate UUID v4 identifiers 5. **generate_random_string** - Generate random strings with custom character sets 6. **generate_random_choice** - Make random selections from arrays 7. **generate_random_boolean** - Generate random booleans with probability control All randomness is generated using Node.js's crypto module, which provides cryptographically strong pseudo-random data suitable for security-sensitive applications. What type of random value would you like me to generate?`, }, }, ]; return { messages, }; } throw new Error(`Unknown prompt: ${name}`); }); } private async generateRandomInteger(args: any) { const min = args.min ?? 0; const max = args.max ?? 100; const count = args.count ?? 1; if (min > max) { throw new Error("Minimum value cannot be greater than maximum value"); } if (count < 1 || count > 1000) { throw new Error("Count must be between 1 and 1000"); } const results: number[] = []; for (let i = 0; i < count; i++) { // Use Node.js crypto.randomInt for cryptographically secure random integers results.push(randomInt(min, max + 1)); } return { content: [ { type: "text", text: JSON.stringify({ type: "random_integers", values: results, parameters: { min, max, count }, timestamp: new Date().toISOString(), }, null, 2), }, ], }; } private async generateRandomFloat(args: any) { const min = args.min ?? 0.0; const max = args.max ?? 1.0; const count = args.count ?? 1; const precision = args.precision ?? 6; if (min >= max) { throw new Error("Minimum value must be less than maximum value"); } if (count < 1 || count > 1000) { throw new Error("Count must be between 1 and 1000"); } if (precision < 1 || precision > 15) { throw new Error("Precision must be between 1 and 15"); } const results: number[] = []; for (let i = 0; i < count; i++) { // Generate cryptographically secure random float const randomBuffer = randomBytes(4); const randomValue = randomBuffer.readUInt32BE(0) / 0xFFFFFFFF; const scaledValue = min + (randomValue * (max - min)); results.push(parseFloat(scaledValue.toFixed(precision))); } return { content: [ { type: "text", text: JSON.stringify({ type: "random_floats", values: results, parameters: { min, max, count, precision }, timestamp: new Date().toISOString(), }, null, 2), }, ], }; } private async generateRandomBytes(args: any) { const length = args.length ?? 32; const encoding = args.encoding ?? "hex"; if (length < 1 || length > 1024) { throw new Error("Length must be between 1 and 1024"); } const bytes = randomBytes(length); let result: string; switch (encoding) { case "hex": result = bytes.toString("hex"); break; case "base64": result = bytes.toString("base64"); break; case "binary": result = bytes.toString("binary"); break; default: throw new Error("Invalid encoding. Must be 'hex', 'base64', or 'binary'"); } return { content: [ { type: "text", text: JSON.stringify({ type: "random_bytes", value: result, parameters: { length, encoding }, timestamp: new Date().toISOString(), }, null, 2), }, ], }; } private async generateUUID(args: any) { const count = args.count ?? 1; const format = args.format ?? "standard"; if (count < 1 || count > 100) { throw new Error("Count must be between 1 and 100"); } const results: string[] = []; for (let i = 0; i < count; i++) { const uuid = randomUUID(); results.push(format === "compact" ? uuid.replace(/-/g, "") : uuid); } return { content: [ { type: "text", text: JSON.stringify({ type: "uuids", values: results, parameters: { count, format }, timestamp: new Date().toISOString(), }, null, 2), }, ], }; } private async generateRandomString(args: any) { const length = args.length ?? 16; const charset = args.charset ?? "alphanumeric"; const count = args.count ?? 1; if (length < 1 || length > 256) { throw new Error("Length must be between 1 and 256"); } if (count < 1 || count > 100) { throw new Error("Count must be between 1 and 100"); } const charsets = { alphanumeric: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", alphabetic: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", numeric: "0123456789", hex: "0123456789abcdef", base64: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", ascii_printable: "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", }; const chars = charsets[charset as keyof typeof charsets]; if (!chars) { throw new Error(`Invalid charset: ${charset}`); } const results: string[] = []; for (let i = 0; i < count; i++) { let result = ""; for (let j = 0; j < length; j++) { const randomIndex = randomInt(0, chars.length); result += chars[randomIndex]; } results.push(result); } return { content: [ { type: "text", text: JSON.stringify({ type: "random_strings", values: results, parameters: { length, charset, count }, timestamp: new Date().toISOString(), }, null, 2), }, ], }; } private async generateRandomChoice(args: any) { const choices = args.choices; const count = args.count ?? 1; const allowDuplicates = args.allow_duplicates ?? true; if (!Array.isArray(choices) || choices.length === 0) { throw new Error("Choices must be a non-empty array"); } if (count < 1) { throw new Error("Count must be at least 1"); } if (!allowDuplicates && count > choices.length) { throw new Error("Count cannot exceed choices length when duplicates are not allowed"); } const results: string[] = []; const availableChoices = [...choices]; for (let i = 0; i < count; i++) { const randomIndex = randomInt(0, availableChoices.length); const selected = availableChoices[randomIndex]; results.push(selected); if (!allowDuplicates) { availableChoices.splice(randomIndex, 1); } } return { content: [ { type: "text", text: JSON.stringify({ type: "random_choices", values: results, parameters: { choices, count, allow_duplicates: allowDuplicates }, timestamp: new Date().toISOString(), }, null, 2), }, ], }; } private async generateRandomBoolean(args: any) { const count = args.count ?? 1; const probability = args.probability ?? 0.5; if (count < 1 || count > 1000) { throw new Error("Count must be between 1 and 1000"); } if (probability < 0.0 || probability > 1.0) { throw new Error("Probability must be between 0.0 and 1.0"); } const results: boolean[] = []; for (let i = 0; i < count; i++) { const randomBuffer = randomBytes(4); const randomValue = randomBuffer.readUInt32BE(0) / 0xFFFFFFFF; results.push(randomValue < probability); } return { content: [ { type: "text", text: JSON.stringify({ type: "random_booleans", values: results, parameters: { count, probability }, timestamp: new Date().toISOString(), }, null, 2), }, ], }; } private setupErrorHandling(): void { this.server.onerror = (error) => { console.error("[MCP Error]", error); }; process.on("SIGINT", async () => { await this.server.close(); process.exit(0); }); } async run(): Promise<void> { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error("Plugged.in Random Number Generator MCP Server running on stdio"); } } // Start the server if (require.main === module) { const server = new RandomNumberGeneratorServer(); server.run().catch((error) => { console.error("Failed to start server:", error); process.exit(1); }); } export default RandomNumberGeneratorServer;

Implementation Reference

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/VeriTeknik/pluggedin-random-number-generator-mcp'

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