Skip to main content
Glama
index.ts17.1 kB
import { Server } from "@modelcontextprotocol/typescript-sdk"; import { GithubClient } from "@smithery-ai/github-client"; import axios from "axios"; // Create the MCP server const server = new Server({ name: "greyhack-mcp-server", description: "A Grey Hack MCP server with GitHub code search, Greybel-JS transpilation, API validation and script generation", version: "0.1.0", }); // GitHub search tool server.addTool({ name: "search_greyhack_code", description: "Search for Grey Hack code examples on GitHub", parameters: { type: "object", properties: { query: { type: "string", description: "The search query for finding Grey Hack code", }, max_results: { type: "number", description: "Maximum number of results to return", default: 5, }, }, required: ["query"], }, handler: async (params) => { try { const { query, max_results = 5 } = params; const githubToken = process.env.GITHUB_TOKEN; if (!githubToken) { return { error: "GITHUB_TOKEN environment variable not set. Please provide a GitHub token." }; } const github = new GithubClient({ auth: githubToken }); const searchQuery = `${query} language:greyscript OR language:js extension:.gs extension:.txt`; const results = await github.searchCode(searchQuery); return { results: results.items.slice(0, max_results).map(item => ({ name: item.name, path: item.path, repository: item.repository.full_name, url: item.html_url, content: item.content || null, })), total_count: results.total_count, }; } catch (error) { console.error("Error searching GitHub:", error); return { error: `Error searching GitHub: ${error.message}` }; } }, }); // Greybel-JS transpilation tool server.addTool({ name: "transpile_greyscript", description: "Transpile GreyScript code to JavaScript using Greybel-JS", parameters: { type: "object", properties: { code: { type: "string", description: "The GreyScript code to transpile", }, }, required: ["code"], }, handler: async (params) => { try { const { code } = params; // For now, we'll use a placeholder service until we can integrate with a real Greybel-JS library // In a real implementation, you'd use a local library or API // This is a simulated response const transpiled = `// Transpiled from GreyScript to JavaScript function main() { // Transpiled code would go here console.log("Transpiled code from GreyScript"); // Original code length: ${code.length} characters } main();`; return { original: code, transpiled: transpiled, success: true, }; } catch (error) { console.error("Error transpiling code:", error); return { error: `Error transpiling code: ${error.message}`, success: false }; } }, }); // GreyScript API validation tool server.addTool({ name: "validate_greyscript", description: "Validate GreyScript code against the official API documentation", parameters: { type: "object", properties: { code: { type: "string", description: "The GreyScript code to validate", }, version: { type: "string", description: "The Grey Hack game version to validate against", default: "0.8.0", }, }, required: ["code"], }, handler: async (params) => { try { const { code, version = "0.8.0" } = params; // In a real implementation, you'd fetch the actual API docs or use a local copy // This is a simulated validation const apiCalls = extractApiCalls(code); const validationResults = { valid: true, warnings: [], errors: [], api_calls: apiCalls, }; // Simulate some validation checks if (code.includes("get_connect_ip") && version >= "0.8.0") { validationResults.warnings.push("get_connect_ip is deprecated in version 0.8.0+, use get_router instead"); validationResults.valid = false; } if (code.includes("unknown_function")) { validationResults.errors.push("unknown_function is not a valid API function"); validationResults.valid = false; } return validationResults; } catch (error) { console.error("Error validating code:", error); return { error: `Error validating code: ${error.message}`, valid: false }; } }, }); // Script generation tool server.addTool({ name: "generate_greyhack_script", description: "Generate a GreyScript code template for common Grey Hack game tasks", parameters: { type: "object", properties: { script_type: { type: "string", description: "The type of script to generate", enum: ["port_scanner", "password_cracker", "file_browser", "ssh_tool", "custom"], }, custom_description: { type: "string", description: "Description of the custom script to generate (only used if script_type is 'custom')", }, game_version: { type: "string", description: "The Grey Hack game version to target", default: "0.8.0", }, }, required: ["script_type"], }, handler: async (params) => { try { const { script_type, custom_description, game_version = "0.8.0" } = params; let scriptTemplate = ""; let scriptDescription = ""; switch (script_type) { case "port_scanner": scriptDescription = "A port scanner for network reconnaissance"; scriptTemplate = generatePortScannerTemplate(game_version); break; case "password_cracker": scriptDescription = "A password cracking utility"; scriptTemplate = generatePasswordCrackerTemplate(game_version); break; case "file_browser": scriptDescription = "A file browser utility"; scriptTemplate = generateFileBrowserTemplate(game_version); break; case "ssh_tool": scriptDescription = "An SSH connection tool"; scriptTemplate = generateSshToolTemplate(game_version); break; case "custom": scriptDescription = custom_description || "Custom script"; scriptTemplate = generateCustomTemplate(custom_description, game_version); break; default: return { error: "Invalid script type specified" }; } return { script_type, description: scriptDescription, code: scriptTemplate, game_version, }; } catch (error) { console.error("Error generating script:", error); return { error: `Error generating script: ${error.message}` }; } }, }); // Helper functions for the tools function extractApiCalls(code: string): string[] { // This is a simplified implementation // In a real implementation, you'd use proper parsing to extract API calls const commonApis = ["get_router", "get_shell", "get_file", "get_folders", "get_files", "nslookup"]; return commonApis.filter(api => code.includes(api)); } function generatePortScannerTemplate(version: string): string { return `// Grey Hack Port Scanner v1.0 // For game version ${version} // Scans a target computer for open ports metaxploit = include_lib("/lib/metaxploit.so") if not metaxploit then metaxploit = include_lib(current_path + "/metaxploit.so") end if if not metaxploit then exit("Error: Can't find metaxploit library") end if scan_address = function(address) ports = range(1, 65535) open_ports = [] for port in ports // Try to connect to each port net_session = metaxploit.net_use(address, port) if net_session then open_ports.push(port) // Optional: try to get service version service_info = net_session.host_computer.get_service_info(port) print("Port " + port + " is open: " + service_info) end if end for return open_ports end function // Main program print("Port Scanner Starting...") target = user_input("Enter target IP: ") if not is_valid_ip(target) then exit("Invalid IP address") end if print("Scanning " + target + "...") open_ports = scan_address(target) if open_ports.len == 0 then print("No open ports found") else print("Found " + open_ports.len + " open ports") print(open_ports) end if `; } function generatePasswordCrackerTemplate(version: string): string { return `// Grey Hack Password Cracker v1.0 // For game version ${version} // Cracks passwords for various security systems crypto = include_lib("/lib/crypto.so") if not crypto then crypto = include_lib(current_path + "/crypto.so") end if if not crypto then exit("Error: Can't find crypto library") end if crack_password = function(hash, type) if not crypto.is_valid_password(hash) then return "Invalid password hash" end if wordlist = get_shell.host_computer.File("/usr/share/wordlists/common.txt") if not wordlist then print("Wordlist not found, using simple brute force") // Simple brute force for demo purposes password = crypto.aircrack(hash) return password else print("Using wordlist for cracking") words = wordlist.get_content.split("\\n") for word in words if crypto.hash(word) == hash then return word end if end for // If wordlist fails, try brute force print("Wordlist exhausted, trying brute force") password = crypto.aircrack(hash) return password end if end function // Main program print("Password Cracker Starting...") hash = user_input("Enter password hash: ") hash_type = user_input("Enter hash type (or leave blank): ") print("Cracking password...") password = crack_password(hash, hash_type) if password then print("Password cracked: " + password) else print("Failed to crack password") end if `; } function generateFileBrowserTemplate(version: string): string { return `// Grey Hack File Browser v1.0 // For game version ${version} // Browse and manipulate files on the system browse_directory = function(path) computer = get_shell.host_computer files = computer.get_files(path) folders = computer.get_folders(path) print("Contents of " + path + ":") print("----------------------------") if folders.len > 0 then print("Directories:") for folder in folders print("📁 " + folder.name + "/") end for print("") end if if files.len > 0 then print("Files:") for file in files print("📄 " + file.name + " (" + file.size + " bytes)") end for end if print("----------------------------") return {"files": files, "folders": folders} end function file_details = function(file_path) computer = get_shell.host_computer file = computer.File(file_path) if not file then return "File not found: " + file_path end if details = {} details["name"] = file.name details["path"] = file.path details["size"] = file.size details["owner"] = file.owner details["group"] = file.group details["permissions"] = file.permissions return details end function // Main program print("File Browser Starting...") current_path = "/" while true browse_result = browse_directory(current_path) print("\\nCurrent path: " + current_path) print("Commands: cd [dir], details [file], cat [file], exit") command = user_input("> ") if command == "exit" then break else if command.indexOf("cd ") == 0 then new_dir = command[3:] if new_dir == ".." then // Go up one directory parts = current_path.split("/") if parts.len > 1 then parts.pop current_path = parts.join("/") if current_path == "" then current_path = "/" end if else if new_dir.indexOf("/") == 0 then // Absolute path current_path = new_dir else // Relative path if current_path[-1:] != "/" then current_path = current_path + "/" current_path = current_path + new_dir end if else if command.indexOf("details ") == 0 then file_name = command[8:] if file_name.indexOf("/") == 0 then // Absolute path details = file_details(file_name) else // Relative path path = current_path if path[-1:] != "/" then path = path + "/" details = file_details(path + file_name) end if print(details) else if command.indexOf("cat ") == 0 then file_name = command[4:] path = "" if file_name.indexOf("/") == 0 then // Absolute path path = file_name else // Relative path path = current_path if path[-1:] != "/" then path = path + "/" path = path + file_name end if file = get_shell.host_computer.File(path) if file then print("Contents of " + file.name + ":") print("----------------------------") print(file.get_content) print("----------------------------") else print("File not found: " + path) end if else print("Unknown command: " + command) end if print("") end while print("File Browser Closed") `; } function generateSshToolTemplate(version: string): string { return `// Grey Hack SSH Tool v1.0 // For game version ${version} // Connect to remote computers via SSH connect_ssh = function(address, port, user, password) if not is_valid_ip(address) then return {"success": false, "message": "Invalid IP address"} end if if typeof(port) != "number" or port < 1 or port > 65535 then return {"success": false, "message": "Invalid port number"} end if // In versions 0.8.0+, using the new router API if "${version}" >= "0.8.0" then router = get_router if not router then return {"success": false, "message": "Cannot find router"} end if print("Connecting to " + address + ":" + port + "...") start_time = time remote_shell = router.connect_ssh(address, port, user, password) else // For older versions crypto = include_lib("/lib/crypto.so") if not crypto then return {"success": false, "message": "Cannot find crypto library"} end if print("Connecting to " + address + ":" + port + "...") remote_shell = crypto.connect_ssh(address, port, user, password) end if if not remote_shell then return {"success": false, "message": "SSH connection failed"} end if print("Connected to " + address + " as " + user) remote_computer = remote_shell.host_computer return { "success": true, "message": "Connected successfully", "shell": remote_shell, "computer": remote_computer } end function // Main program print("SSH Connection Tool Starting...") address = user_input("Target IP: ") port = user_input("Port (default: 22): ").to_int if not port then port = 22 user = user_input("Username: ") password = user_input("Password: ") result = connect_ssh(address, port, user, password) if result.success then print("Connection established!") shell = result.shell computer = result.computer print("Connected to: " + computer.get_name) print("Type 'exit' to close the connection") while true command = user_input(user + "@" + computer.get_name + ":~$ ") if command == "exit" then break end if output = shell.host_computer.terminal.execute(command) print(output) end while print("Connection closed") else print("Connection failed: " + result.message) end if `; } function generateCustomTemplate(description: string, version: string): string { return `// Grey Hack Custom Script // For game version ${version} // ${description || "Custom script template"} // Add your imports here // Example: // metaxploit = include_lib("/lib/metaxploit.so") // crypto = include_lib("/lib/crypto.so") // Add your functions here custom_function = function() print("This is a custom function") return true end function // Main program print("Custom Script Starting...") print("Description: ${description || "No description provided"}") // Add your main code here print("Hello, world!") custom_function() print("Custom Script Completed") `; } // Start the server server.start();

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/chromewillow/greyhack-mcp-server'

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