UNPKG

blowback-context

Version:

MCP server that integrates with FE development server for Cursor

103 lines (97 loc) 4.62 kB
#!/usr/bin/env node import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { z } from 'zod'; import { closeScreenshotDB } from './db/screenshot-db.js'; import { registerPrompt } from './prompt/init.js'; import { registerScreenshotResource } from './resources/screenshot.js'; import { registerBrowserTools } from './tools/browser-tools.js'; import { registerBrowserManagerTools } from './tools/browser-manager-tools.js'; import { registerHMRTools } from './tools/hmr-tools.js'; import { Logger } from './utils/logger.js'; /** * Initializes the server, registers tools, and starts communication with clients using stdio transport */ async function main() { try { // Reference objects for state management // Using object references so values can be updated from other modules const browserRef = { current: null }; const pageRef = { current: null }; // Array to store recent HMR events const lastHMREvents = []; // Create MCP server instance const server = new McpServer({ name: 'blowback-context', version: '0.4.0', description: 'Connects to frontend development server to track changes in your project and provide real-time feedback on the results.', capabilities: { tools: {}, resources: {} } }); registerPrompt(server); server.tool('how-to-use', 'Description of how to use the server', { section: z.enum(['checkpoint', 'hmr']).describe('Section to describe'), }, ({ section }) => { switch (section) { case 'checkpoint': return { content: [ { type: 'text', text: ` You can use checkpoint features by inserting '<meta name="__mcp_checkpoint" data-id="">' into the head to create a named snapshot of the current state. The data-id attribute is a unique identifier for the checkpoint. Console logs generated in the browser while a checkpoint is active are tagged with the checkpoint ID and can be queried individually. Note: Since hot reload is triggered when files are saved, carefully consider the sequence between meta tag changes and the changes you want to observe. Make sure to set the checkpoint meta tag before making the changes you want to track.` } ] }; case 'hmr': return { content: [ { type: 'text', text: ` If the HMR connection is established with the client, the server will automatically gather HMR events and provide them to the client. You can read the HMR events using the 'get-hmr-events' tool. The HMR connection is optional. If your development environment does not support HMR, you cannot read HMR events, but you can still check the results of file modifications by using 'execute-browser-commands' to refresh the page.` } ] }; default: return { content: [ { type: 'text', text: 'Invalid section' } ] }; } }); // Register new context manager tools const contextManager = registerBrowserManagerTools(server); // Register tools and resources registerHMRTools(server, lastHMREvents); const screenshotHelpers = registerScreenshotResource(server, browserRef, pageRef); registerBrowserTools(server, contextManager, lastHMREvents, screenshotHelpers); // Set up stdio transport and connect const transport = new StdioServerTransport(); await server.connect(transport); Logger.info('Blowback Context Server running on stdio transport'); // Clean up resources on exit process.on('exit', () => { if (browserRef.current) { browserRef.current.close().catch(error => { Logger.error('Error closing browser:', error); }); } // Close database connection closeScreenshotDB(); }); } catch (error) { Logger.error('Fatal error in main():', error); process.exit(1); } } // Execute main function main().catch(error => { Logger.error('Unhandled promise rejection in main():', error); process.exit(1); }); //# sourceMappingURL=index.js.map