Skip to main content
Glama
mario-andreschak

MCP Windows Desktop Automation

server.ts3.48 kB
/** * MCP Server configuration for Windows Desktop Automation */ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { WebSocket, WebSocketServer, RawData } from 'ws'; import { createServer as createHttpServer, IncomingMessage, Server as HttpServer } from 'http'; import { log } from '../utils/logger/logger'; import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'; import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js'; /** * Custom WebSocket transport for MCP */ class WebSocketServerTransport implements Transport { private ws: WebSocket | null = null; sessionId?: string; constructor(ws: WebSocket) { this.ws = ws; this.sessionId = Math.random().toString(36).substring(2, 15); ws.on('message', (data: RawData) => { try { const message = JSON.parse(data.toString()) as JSONRPCMessage; this.onmessage?.(message); } catch (error) { this.onerror?.(new Error(`Failed to parse message: ${error}`)); } }); ws.on('close', () => { this.ws = null; this.onclose?.(); }); ws.on('error', (error: Error) => { this.onerror?.(error); }); } onclose?: () => void; onerror?: (error: Error) => void; onmessage?: (message: JSONRPCMessage) => void; async start(): Promise<void> { log.info('WebSocket transport started'); } async send(message: JSONRPCMessage): Promise<void> { if (!this.ws) { throw new Error('WebSocket not connected'); } return new Promise((resolve, reject) => { this.ws!.send(JSON.stringify(message), (error?: Error) => { if (error) { reject(error); } else { resolve(); } }); }); } async close(): Promise<void> { if (this.ws) { this.ws.close(); this.ws = null; } } } /** * Server configuration options */ export interface ServerConfig { name: string; version: string; transport: 'stdio' | 'websocket'; port?: number; } /** * Create and configure an MCP server */ export async function setupServer(config: ServerConfig): Promise<{ server: McpServer; httpServer?: HttpServer; }> { // Create the MCP server const server = new McpServer({ name: config.name, version: config.version }, { capabilities: { tools: {}, resources: { subscribe: true, listChanged: true }, prompts: { listChanged: true } } }); // Configure the transport if (config.transport === 'stdio') { log.info('Using stdio transport'); const transport = new StdioServerTransport(); await server.connect(transport); return { server }; } else if (config.transport === 'websocket') { log.info(`Using WebSocket transport on port ${config.port}`); // Create HTTP server const httpServer = createHttpServer(); const wss = new WebSocketServer({ server: httpServer }); // Handle WebSocket connections wss.on('connection', async (ws: WebSocket) => { log.info('New WebSocket connection'); const transport = new WebSocketServerTransport(ws); await server.connect(transport); }); // Start HTTP server httpServer.listen(config.port || 3000); return { server, httpServer }; } else { throw new Error(`Unsupported transport: ${config.transport}`); } }

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/mario-andreschak/mcp-windows-desktop-automation'

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