Skip to main content
Glama
index.ts11.2 kB
#!/usr/bin/env node /** * FiveM Plugin Development MCP Server * * This MCP server provides tools for FiveM plugin development including: * - Plugin management (ensure, stop, restart) * - Server log monitoring * - RCON command execution */ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import { FiveMServerManager } from './managers/server-manager.js'; import { getFiveMConfig, hasAutoConnectConfig } from './config/environment.js'; import { ToolHandlers } from './handlers/tool-handlers.js'; // Global server manager instance let serverManager: FiveMServerManager | null = null; /** * Create an MCP server with capabilities for FiveM plugin development */ const server = new Server( { name: "mcp-fivem", version: "0.3.0", }, { capabilities: { resources: {}, tools: {}, prompts: {}, }, } ); /** * Handler for listing available resources */ server.setRequestHandler(ListResourcesRequestSchema, async () => { const resources = [ { uri: "fivem://logs/recent", mimeType: "text/plain", name: "Recent Logs", description: "Recent server operation logs" }, { uri: "fivem://console/info", mimeType: "text/plain", name: "Console Information", description: "Server console information via log files" } ]; return { resources }; }); /** * Handler for reading resource contents */ server.setRequestHandler(ReadResourceRequestSchema, async (request) => { if (!serverManager) { throw new Error("Server manager not initialized. Please connect to server first."); } const url = new URL(request.params.uri); try { let content = ""; switch (url.pathname) { case "/logs/recent": content = serverManager.getLogs().join('\n'); break; case "/console/info": content = await serverManager.getConsoleLogs(); break; default: throw new Error(`Unknown resource: ${url.pathname}`); } return { contents: [{ uri: request.params.uri, mimeType: "text/plain", text: content }] }; } catch (error) { throw new Error(`Failed to read resource: ${error instanceof Error ? error.message : 'Unknown error'}`); } }); /** * Handler that lists available tools */ server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "fivem_plugin_manage", description: "Manage FiveM plugins (ensure/stop/restart/refresh)", inputSchema: { type: "object", properties: { action: { type: "string", enum: ["ensure", "stop", "restart", "refresh"], description: "Action to perform: ensure/stop/restart plugin, or refresh resources" }, plugin_name: { type: "string", description: "Name of the plugin (required for ensure/stop/restart, not required for refresh)" } }, required: ["action"] } }, { name: "fivem_command_execute", description: "Execute FiveM commands on server or client side", inputSchema: { type: "object", properties: { mode: { type: "string", enum: ["server", "client"], description: "Execution mode: 'server' for server-side command execution, 'client' for client-side command execution" }, command: { type: "string", description: "Command to execute" }, player_id: { type: "number", description: "Target player ID (optional for client mode - if not provided, executes on all clients)" } }, required: ["mode", "command"] } }, { name: "fivem_rcon_execute", description: "Execute direct RCON commands (low-level server management)", inputSchema: { type: "object", properties: { command: { type: "string", description: "RCON command to execute directly" } }, required: ["command"] } }, { name: "fivem_event_trigger", description: "Trigger FiveM events (server/client) via mcp-bridge plugin", inputSchema: { type: "object", properties: { type: { type: "string", enum: ["server", "client"], description: "Event type: server or client" }, event_name: { type: "string", description: "Name of the event to trigger" }, player_id: { type: "number", description: "Target player ID (required for client events)" }, args: { type: "string", description: "JSON string of arguments to pass to the event (optional)" } }, required: ["type", "event_name"] } }, { name: "fivem_player_get", description: "Get player information (list/info) via mcp-bridge plugin", inputSchema: { type: "object", properties: { action: { type: "string", enum: ["list", "info"], description: "Action: list for all players, info for specific player" }, player_id: { type: "number", description: "Player ID (required for info action)" } }, required: ["action"] } }, { name: "fivem_logs_get", description: "Get FiveM logs from various sources", inputSchema: { type: "object", properties: { source: { type: "string", enum: ["server", "server_plugin", "client", "client_plugin"], description: "Log source: server, server_plugin, client, or client_plugin" }, lines: { type: "number", description: "Number of lines to retrieve (default varies by source)" }, plugin_name: { type: "string", description: "Specific plugin name to filter logs for (optional, for plugin logs)" } }, required: ["source"] } }, { name: "fivem_system_manage", description: "Manage FiveM system operations (health/clear)", inputSchema: { type: "object", properties: { action: { type: "string", enum: ["health", "clear"], description: "System action: health check or clear logs" } }, required: ["action"] } } ], }; }); /** * Handler that executes a tool */ server.setRequestHandler(CallToolRequestSchema, async (request) => { try { switch (request.params.name) { case "fivem_plugin_manage": if (!serverManager) { throw new Error("Server manager not initialized. Server connection failed during startup."); } return await ToolHandlers.pluginManage(request.params.arguments, serverManager); case "fivem_command_execute": if (!serverManager) { throw new Error("Server manager not initialized. Server connection failed during startup."); } return await ToolHandlers.commandExecute(request.params.arguments, serverManager); case "fivem_rcon_execute": if (!serverManager) { throw new Error("Server manager not initialized. Server connection failed during startup."); } return await ToolHandlers.rconExecute(request.params.arguments, serverManager); case "fivem_event_trigger": if (!serverManager) { throw new Error("Server manager not initialized. Server connection failed during startup."); } return await ToolHandlers.eventTrigger(request.params.arguments, serverManager); case "fivem_player_get": if (!serverManager) { throw new Error("Server manager not initialized. Server connection failed during startup."); } return await ToolHandlers.playerGet(request.params.arguments, serverManager); case "fivem_logs_get": if (!serverManager) { throw new Error("Server manager not initialized. Server connection failed during startup."); } return await ToolHandlers.logsGet(request.params.arguments, serverManager); case "fivem_system_manage": if (!serverManager) { throw new Error("Server manager not initialized. Server connection failed during startup."); } return await ToolHandlers.systemManage(request.params.arguments, serverManager); default: throw new Error(`Tool not found: ${request.params.name}`); } } catch (error) { const errorContent = `Tool execution failed: ${error instanceof Error ? error.message : 'Unknown error'}`; return { content: [{ type: "text", text: errorContent }] }; } }); /** * Initializes the server manager with auto-connect configuration if available. */ async function autoConnect(): Promise<void> { if (hasAutoConnectConfig()) { const envConfig = getFiveMConfig(); console.error("Auto-connecting to server using environment variables..."); try { const newServerManager = new FiveMServerManager( envConfig.host, envConfig.port, envConfig.password, envConfig.logsDir, envConfig.clientLogsDir ); await newServerManager.connect(); serverManager = newServerManager; console.error(`Successfully connected to FiveM server at ${envConfig.host}:${envConfig.port}`); // Simple startup confirmation console.error(`MCP FiveM server connected to ${envConfig.host}:${envConfig.port}`); } catch (error) { const errorMsg = `Auto-connect failed: ${error instanceof Error ? error.message : 'Unknown error'}`; console.error(errorMsg); throw new Error(`Failed to connect to FiveM server during startup: ${errorMsg}`); } } else { console.error("MCP FiveM server requires environment variables for auto-connection."); console.error("Please set RCON_ADDRESS, RCON_PORT, and RCON_PASSWORD environment variables."); throw new Error("Required environment variables not found. Cannot start without server connection."); } } /** * Main function */ async function main() { await autoConnect(); const transport = new StdioServerTransport(); await server.connect(transport); console.error("MCP server started and listening on stdio"); } main().catch(err => { console.error(err); process.exit(1); });

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/eeharumt/fivem-mcp'

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