mcp-quiz-server
Version:
🧠 AI-Powered Quiz Management via Model Context Protocol (MCP) - Create, manage, and take quizzes directly from VS Code, Claude, and other AI agents.
233 lines (232 loc) • 8.83 kB
JavaScript
;
/**
* @moduleName: Transport Factory - Multi-Protocol Support
* @version: 2.0.0
* @since: 2025-07-25
* @lastUpdated: 2025-07-25
* @projectSummary: Enhanced MCP Quiz Server - Transport Factory and Registry
* @techStack: TypeScript, Factory Pattern, Transport Abstraction, MCP Protocol
* @dependency: All transport implementations
* @interModuleDependency: ./transport-abstraction, ./stdio-transport, ./sse-transport, ./http-transport
* @requirementsTraceability:
* {@link Requirements.REQ_MCP_001} (JSON-RPC 2.0 MCP Protocol)
* @briefDescription: Factory and registry for creating and managing multiple transport protocols
* @methods: createTransport, detectTransport, registerTransport, getAvailableTransports
* @contributors: GitHub Copilot, Transport Architecture Team
* @examples:
* - Auto-detect transport based on environment
* - Create multiple transports for hybrid deployments
* - Register custom transport protocols
* @vulnerabilitiesAssessment: Transport validation, configuration security, protocol isolation
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransportAutoDetection = exports.getDefaultTransport = exports.getSupportedTransports = exports.detectTransport = exports.createTransport = exports.transportFactory = exports.MCPTransportFactory = void 0;
const stdio_transport_1 = require("./stdio-transport");
const transport_abstraction_1 = require("./transport-abstraction");
/**
* Comprehensive transport factory implementation
*/
class MCPTransportFactory {
constructor() {
this.registrations = new Map();
this.registerBuiltInTransports();
}
/**
* Create a transport instance
*/
createTransport(type, config) {
const registration = this.registrations.get(type);
if (!registration) {
throw new Error(`Transport type '${type}' is not registered`);
}
if (!registration.supported) {
throw new Error(`Transport type '${type}' is not supported in this environment`);
}
// Validate configuration
if (config && !transport_abstraction_1.TransportUtils.validateConfig(type, config)) {
throw new Error(`Invalid configuration for transport type '${type}'`);
}
try {
return new registration.constructor(config);
}
catch (error) {
throw new Error(`Failed to create transport '${type}': ${error}`);
}
}
/**
* Get all supported transport types
*/
getSupportedTransports() {
return Array.from(this.registrations.values())
.filter(reg => reg.supported)
.map(reg => reg.type);
}
/**
* Detect optimal transport for given context
*/
detectTransport(context) {
const optimalType = transport_abstraction_1.TransportUtils.detectOptimalTransport(context);
// Verify the detected transport is supported
const registration = this.registrations.get(optimalType);
if (registration && registration.supported) {
return optimalType;
}
// Fall back to first available transport
const fallback = this.getSupportedTransports()[0];
return fallback || null;
}
/**
* Register a custom transport
*/
registerTransport(type, constructor, description, isDefault = false) {
this.registrations.set(type, {
type,
constructor,
description,
isDefault,
supported: true,
});
console.log(`🔌 Registered transport: ${type} - ${description}`);
}
/**
* Get available transports with metadata
*/
getAvailableTransports() {
return Array.from(this.registrations.values()).map(reg => ({
type: reg.type,
description: reg.description,
isDefault: reg.isDefault,
supported: reg.supported,
}));
}
/**
* Check if a transport type is supported
*/
isSupported(type) {
const registration = this.registrations.get(type);
return registration ? registration.supported : false;
}
/**
* Get default transport for current environment
*/
getDefaultTransport() {
// Check for explicitly marked default
for (const [type, registration] of this.registrations) {
if (registration.isDefault && registration.supported) {
return type;
}
}
// Fall back to first supported transport
const supported = this.getSupportedTransports();
return supported.length > 0 ? supported[0] : null;
}
/**
* Create multiple transports for hybrid deployment
*/
createMultipleTransports(configs) {
const transports = [];
for (const { type, config } of configs) {
try {
const transport = this.createTransport(type, config);
transports.push(transport);
}
catch (error) {
console.error(`Failed to create transport ${type}:`, error);
}
}
return transports;
}
/**
* Register built-in transport implementations
*/
registerBuiltInTransports() {
// STDIO Transport (VS Code, local development)
this.registrations.set(transport_abstraction_1.TransportType.STDIO, {
type: transport_abstraction_1.TransportType.STDIO,
constructor: stdio_transport_1.StdioTransport,
description: 'Standard Input/Output transport for VS Code integration',
isDefault: this.isNodeEnvironment() && !this.isBrowserEnvironment(),
supported: this.isNodeEnvironment(),
});
console.log(`🏭 Registered ${this.registrations.size} transport types`);
}
/**
* Environment detection helpers
*/
isNodeEnvironment() {
return (typeof process !== 'undefined' &&
typeof process.versions !== 'undefined' &&
typeof process.versions.node === 'string');
}
isBrowserEnvironment() {
return typeof window !== 'undefined' && typeof document !== 'undefined';
}
}
exports.MCPTransportFactory = MCPTransportFactory;
/**
* Global transport factory instance
*/
exports.transportFactory = new MCPTransportFactory();
/**
* Convenience functions
*/
const createTransport = (type, config) => exports.transportFactory.createTransport(type, config);
exports.createTransport = createTransport;
const detectTransport = (context) => exports.transportFactory.detectTransport(context);
exports.detectTransport = detectTransport;
const getSupportedTransports = () => exports.transportFactory.getSupportedTransports();
exports.getSupportedTransports = getSupportedTransports;
const getDefaultTransport = () => exports.transportFactory.getDefaultTransport();
exports.getDefaultTransport = getDefaultTransport;
/**
* Auto-detection utility
*/
class TransportAutoDetection {
/**
* Detect environment and return optimal transport configuration
*/
static detectEnvironment() {
let environment = 'unknown';
// Detect VS Code environment
if (typeof process !== 'undefined' && process.env.VSCODE_PID) {
environment = 'vscode';
}
// Detect Node.js environment
else if (typeof process !== 'undefined' && process.versions && process.versions.node) {
environment = 'node';
}
// Detect browser environment
else if (typeof window !== 'undefined') {
environment = 'browser';
}
const context = {
environment,
capabilities: [],
};
return {
environment,
recommendedTransport: exports.transportFactory.detectTransport(context),
availableTransports: exports.transportFactory.getSupportedTransports(),
};
}
/**
* Create transport for current environment with optimal configuration
*/
static createOptimalTransport(config) {
const detection = this.detectEnvironment();
if (!detection.recommendedTransport) {
console.warn('⚠️ No suitable transport detected for current environment');
return null;
}
try {
const transport = exports.transportFactory.createTransport(detection.recommendedTransport, config);
console.log(`🎯 Created optimal transport: ${detection.recommendedTransport} for ${detection.environment} environment`);
return transport;
}
catch (error) {
console.error('❌ Failed to create optimal transport:', error);
return null;
}
}
}
exports.TransportAutoDetection = TransportAutoDetection;