blowback-context
Version:
MCP server that integrates with FE development server for Cursor
103 lines (97 loc) • 4.62 kB
JavaScript
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
import { McpServer }