evalstate's picture
download
raw
5.59 kB
import {} from 'express';
import {} from '../shared/constants.js';
import { createTransport } from './transport/transport-factory.js';
import { logger } from './utils/logger.js';
import { createServerFactory } from './mcp-server.js';
import { createProxyServerFactory } from './mcp-proxy.js';
import { McpApiClient } from './utils/mcp-api-client.js';
import { DEFAULT_SPACE_TOOLS } from '../shared/settings.js';
import { loadProxyToolsConfig } from './utils/proxy-tools-config.js';
export class Application {
serverFactory;
webServerInstance;
appInstance;
transport;
apiClient;
transportType;
webAppPort;
isDev;
constructor(options) {
this.transportType = options.transportType;
this.webAppPort = options.webAppPort;
this.webServerInstance = options.webServerInstance;
this.isDev = process.env.NODE_ENV === 'development';
const defaultHfToken = process.env.DEFAULT_HF_TOKEN;
const transportInfo = {
transport: this.transportType,
port: this.webAppPort,
defaultHfTokenSet: !!defaultHfToken,
hfTokenMasked: defaultHfToken ? maskToken(defaultHfToken) : undefined,
jsonResponseEnabled: this.transportType === 'streamableHttpJson',
externalApiMode: !!process.env.USER_CONFIG_API,
stdioClient: this.transportType === 'stdio' ? null : undefined,
};
const convertSpaceToolsToGradioEndpoints = (spaceTools) => {
return spaceTools.map((spaceTool) => ({
name: spaceTool.name,
subdomain: spaceTool.subdomain,
id: spaceTool._id,
emoji: spaceTool.emoji,
}));
};
const defaultGradioEndpoints = convertSpaceToolsToGradioEndpoints(DEFAULT_SPACE_TOOLS);
let apiClientConfig;
const userConfigApi = process.env.USER_CONFIG_API;
if (userConfigApi) {
apiClientConfig = {
type: 'external',
externalUrl: userConfigApi,
hfToken: process.env.DEFAULT_HF_TOKEN,
};
logger.info(`Using external API client with user config API: ${userConfigApi}`);
}
else {
apiClientConfig = options.apiClientConfig || {
type: 'polling',
baseUrl: `http://localhost:${String(this.webAppPort)}`,
pollInterval: 5000,
staticGradioEndpoints: defaultGradioEndpoints,
};
logger.info(`Using internal API client with user config API: ${apiClientConfig.baseUrl}}`);
}
this.apiClient = new McpApiClient(apiClientConfig, transportInfo);
const originalServerFactory = createServerFactory(this.webServerInstance, this.apiClient);
this.serverFactory = createProxyServerFactory(this.webServerInstance, this.apiClient, originalServerFactory);
this.appInstance = this.webServerInstance.getApp();
}
async start() {
await loadProxyToolsConfig();
const transportInfo = this.apiClient.getTransportInfo();
if (transportInfo) {
this.webServerInstance.setTransportInfo(transportInfo);
}
this.setupToolManagement();
this.webServerInstance.setupApiRoutes();
await this.startWebServer();
await this.initializeTransport();
await this.webServerInstance.setupStaticFiles(this.isDev);
await this.startToolManagement();
}
setupToolManagement() {
this.webServerInstance.initializeToolStates();
this.webServerInstance.setApiClient(this.apiClient);
}
async initializeTransport() {
if (this.transportType === 'unknown')
return;
try {
this.transport = createTransport(this.transportType, this.serverFactory, this.appInstance);
this.webServerInstance.setTransport(this.transport);
await this.transport.initialize({
port: this.webAppPort,
});
}
catch (error) {
logger.error({ error }, `Error initializing ${this.transportType} transport`);
throw error;
}
}
async startWebServer() {
await this.webServerInstance.start(this.webAppPort);
logger.info(`Server running at http://localhost:${String(this.webAppPort)}`);
logger.info({ transportType: this.transportType, mode: this.isDev ? 'development with HMR' : 'production' }, 'Server configuration');
if (this.isDev) {
logger.info('HMR is active - frontend changes will be automatically reflected in the browser');
logger.info("For server changes, use 'npm run dev:watch' to automatically rebuild and apply changes");
}
}
async startToolManagement() {
await this.apiClient.startPolling((toolId, enabled) => {
logger.debug(`Global tool ${toolId} ${enabled ? 'enabled' : 'disabled'}`);
});
}
async stop() {
this.apiClient.stopPolling();
if (this.transport?.shutdown) {
this.transport.shutdown();
}
logger.info('Shutting down web server...');
await this.webServerInstance.stop();
if (this.transport) {
await this.transport.cleanup();
}
}
getExpressApp() {
return this.appInstance;
}
}
function maskToken(token) {
if (!token || token.length <= 9)
return token;
return `${token.substring(0, 4)}...${token.substring(token.length - 5)}`;
}
//# sourceMappingURL=application.js.map

Xet Storage Details

Size:
5.59 kB
·
Xet hash:
e65a99464e352d15ad5e6ef8a17c10248738faecde689050ac26c50de5f2b132

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.