ultimate-mcp-server
Version:
The definitive all-in-one Model Context Protocol server for AI-assisted coding across 30+ platforms
233 lines • 7.49 kB
JavaScript
/**
* Platform-specific adapters for compatibility
*/
import { SUPPORTED_PLATFORMS } from './platform-detector.js';
export class PlatformAdapterFactory {
static adapters = new Map();
// Static initialization will be done after class definitions
static registerAdapter(adapter) {
this.adapters.set(adapter.platform, adapter);
}
static getAdapter(platform) {
return this.adapters.get(platform) || this.adapters.get('default');
}
}
// Platform-specific adapter implementations
class DefaultAdapter {
platform = 'default';
adaptStdioRequest(input) {
// Standard JSON-RPC format
return input;
}
adaptStdioResponse(response) {
return response;
}
adaptHttpRequest(req) {
return req.body;
}
adaptHttpResponse(response, res) {
res.json(response);
}
adaptSSEMessage(data) {
return `data: ${JSON.stringify(data)}\n\n`;
}
adaptWebSocketMessage(data) {
return JSON.stringify(data);
}
formatError(error) {
return {
error: {
code: -32603,
message: error.message,
data: {
stack: error.stack
}
}
};
}
}
class ClaudeDesktopAdapter extends DefaultAdapter {
platform = SUPPORTED_PLATFORMS.CLAUDE_DESKTOP;
adaptStdioRequest(input) {
// Claude Desktop sends requests in a specific format
if (typeof input === 'string') {
try {
return JSON.parse(input);
}
catch {
// If we can't parse it, create a basic request
return {
id: Date.now(),
method: 'unknown',
params: { input }
};
}
}
return input;
}
adaptStdioResponse(response) {
// Claude Desktop expects newline-delimited JSON
return JSON.stringify(response) + '\n';
}
formatError(error) {
// Claude Desktop expects specific error format
return {
jsonrpc: '2.0',
error: {
code: -32603,
message: error.message
}
};
}
}
class CursorAdapter extends DefaultAdapter {
platform = SUPPORTED_PLATFORMS.CURSOR;
async initialize() {
// Cursor-specific initialization
console.error('Initializing Cursor adapter...');
}
adaptHttpRequest(req) {
// Cursor may send additional headers
const request = req.body;
if (req.headers['x-cursor-session']) {
request._cursorSession = req.headers['x-cursor-session'];
}
return request;
}
async handleAuthentication(credentials) {
// Cursor-specific authentication
if (credentials.cursorToken) {
// Validate Cursor token
return true;
}
return false;
}
}
class WindsurfAdapter extends DefaultAdapter {
platform = SUPPORTED_PLATFORMS.WINDSURF;
adaptSSEMessage(data) {
// Windsurf expects SSE messages with specific event types
return `event: message\ndata: ${JSON.stringify(data)}\n\n`;
}
adaptHttpResponse(response, res) {
// Windsurf expects specific headers
res.setHeader('X-Windsurf-Compatible', 'true');
res.json(response);
}
}
class VSCodeAdapter extends DefaultAdapter {
platform = SUPPORTED_PLATFORMS.VSCODE;
adaptStdioRequest(input) {
// VSCode extension host might wrap requests
if (input.type === 'mcp-request' && input.payload) {
return input.payload;
}
return input;
}
handleEnvironmentVariables() {
// Filter VSCode-specific env vars
const env = { ...process.env };
const vscodeKeys = Object.keys(env).filter(key => key.startsWith('VSCODE_'));
const filtered = {};
for (const key of vscodeKeys) {
if (env[key]) {
filtered[key] = env[key];
}
}
return filtered;
}
}
class ClineAdapter extends DefaultAdapter {
platform = SUPPORTED_PLATFORMS.CLINE;
adaptHttpRequest(req) {
// Cline sends requests with specific structure
const { method, params, id } = req.body;
return {
jsonrpc: '2.0',
method,
params,
id: id || Date.now()
};
}
async handleFileAccess(path, operation) {
// Cline has specific file access restrictions
if (path.includes('node_modules') || path.includes('.git')) {
return false;
}
return true;
}
}
class BoltAIAdapter extends DefaultAdapter {
platform = SUPPORTED_PLATFORMS.BOLTAI;
adaptWebSocketMessage(data) {
// BoltAI expects WebSocket messages in specific format
return {
type: 'mcp-response',
timestamp: Date.now(),
data: data
};
}
async handleAuthentication(credentials) {
// BoltAI uses API key authentication
if (credentials.apiKey && credentials.apiKey.startsWith('bolt_')) {
return true;
}
return false;
}
}
class LibreChatAdapter extends DefaultAdapter {
platform = SUPPORTED_PLATFORMS.LIBRECHAT;
adaptSSEMessage(data) {
// LibreChat expects SSE with retry and id fields
const id = Date.now();
return `id: ${id}\nretry: 3000\ndata: ${JSON.stringify(data)}\n\n`;
}
adaptHttpResponse(response, res) {
// LibreChat expects CORS headers
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.json(response);
}
}
class BigAGIAdapter extends DefaultAdapter {
platform = SUPPORTED_PLATFORMS.BIGAGI;
adaptWebSocketMessage(data) {
// Big-AGI expects WebSocket messages with metadata
return {
protocol: 'mcp',
version: '1.0',
timestamp: new Date().toISOString(),
payload: data
};
}
formatError(error) {
// Big-AGI expects detailed error information
return {
error: {
type: 'MCPError',
code: error.name === 'ValidationError' ? -32602 : -32603,
message: error.message,
details: {
stack: error.stack,
timestamp: new Date().toISOString()
}
}
};
}
}
// Additional adapters for other platforms can be added here...
// Initialize adapters after all classes are defined
(() => {
PlatformAdapterFactory.registerAdapter(new ClaudeDesktopAdapter());
PlatformAdapterFactory.registerAdapter(new CursorAdapter());
PlatformAdapterFactory.registerAdapter(new WindsurfAdapter());
PlatformAdapterFactory.registerAdapter(new VSCodeAdapter());
PlatformAdapterFactory.registerAdapter(new ClineAdapter());
PlatformAdapterFactory.registerAdapter(new BoltAIAdapter());
PlatformAdapterFactory.registerAdapter(new LibreChatAdapter());
PlatformAdapterFactory.registerAdapter(new BigAGIAdapter());
PlatformAdapterFactory.registerAdapter(new DefaultAdapter());
})();
export { PlatformAdapterFactory as default };
//# sourceMappingURL=platform-adapter.js.map