mirror of
https://github.com/samanhappy/mcphub.git
synced 2025-12-24 02:39:19 -05:00
feat: implement dynamic package versioning and refactor MCP server initialization (#104)
This commit is contained in:
@@ -40,7 +40,11 @@ const Header: React.FC<HeaderProps> = ({ onToggleSidebar }) => {
|
||||
|
||||
{/* Theme Switch and Version */}
|
||||
<div className="flex items-center space-x-4">
|
||||
<span className="text-sm text-gray-500 dark:text-gray-400">{import.meta.env.PACKAGE_VERSION}</span>
|
||||
<span className="text-sm text-gray-500 dark:text-gray-400">
|
||||
{import.meta.env.PACKAGE_VERSION === 'dev'
|
||||
? import.meta.env.PACKAGE_VERSION
|
||||
: `v${import.meta.env.PACKAGE_VERSION}`}
|
||||
</span>
|
||||
<a
|
||||
href="https://github.com/samanhappy/mcphub"
|
||||
target="_blank"
|
||||
|
||||
@@ -2,6 +2,7 @@ import dotenv from 'dotenv';
|
||||
import fs from 'fs';
|
||||
import { McpSettings } from '../types/index.js';
|
||||
import { getConfigFilePath } from '../utils/path.js';
|
||||
import { getPackageVersion } from '../utils/version.js';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
@@ -10,7 +11,7 @@ const defaultConfig = {
|
||||
initTimeout: process.env.INIT_TIMEOUT || 300000,
|
||||
timeout: process.env.REQUEST_TIMEOUT || 60000,
|
||||
mcpHubName: 'mcphub',
|
||||
mcpHubVersion: '0.0.1',
|
||||
mcpHubVersion: getPackageVersion(),
|
||||
};
|
||||
|
||||
export const getSettingsPath = (): string => {
|
||||
|
||||
@@ -3,7 +3,7 @@ import config from './config/index.js';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import fs from 'fs';
|
||||
import { initMcpServer } from './services/mcpService.js';
|
||||
import { initUpstreamServers } from './services/mcpService.js';
|
||||
import { initMiddlewares } from './middlewares/index.js';
|
||||
import { initRoutes } from './routes/index.js';
|
||||
import {
|
||||
@@ -37,7 +37,7 @@ export class AppServer {
|
||||
initRoutes(this.app);
|
||||
console.log('Server initialized successfully');
|
||||
|
||||
initMcpServer(config.mcpHubName, config.mcpHubVersion)
|
||||
initUpstreamServers()
|
||||
.then(() => {
|
||||
console.log('MCP server initialized successfully');
|
||||
this.app.get('/sse/:group?', (req, res) => handleSseConnection(req, res));
|
||||
|
||||
@@ -12,17 +12,18 @@ import { getServersInGroup } from './groupService.js';
|
||||
|
||||
const servers: { [sessionId: string]: Server } = {};
|
||||
|
||||
export const initMcpServer = async (name: string, version: string): Promise<void> => {
|
||||
export const initUpstreamServers = async (): Promise<void> => {
|
||||
await registerAllTools(true);
|
||||
};
|
||||
|
||||
export const getMcpServer = (sessionId?: string): Server => {
|
||||
export const getMcpServer = (sessionId?: string, group?: string): Server => {
|
||||
if (!sessionId) {
|
||||
return createMcpServer(config.mcpHubName, config.mcpHubVersion);
|
||||
return createMcpServer(config.mcpHubName, config.mcpHubVersion, group);
|
||||
}
|
||||
|
||||
if (!servers[sessionId]) {
|
||||
const server = createMcpServer(config.mcpHubName, config.mcpHubVersion);
|
||||
const serverGroup = group || getGroup(sessionId);
|
||||
const server = createMcpServer(config.mcpHubName, config.mcpHubVersion, serverGroup);
|
||||
servers[sessionId] = server;
|
||||
} else {
|
||||
console.log(`MCP server already exists for sessionId: ${sessionId}`);
|
||||
@@ -417,8 +418,24 @@ const handleCallToolRequest = async (request: any, extra: any) => {
|
||||
};
|
||||
|
||||
// Create McpServer instance
|
||||
export const createMcpServer = (name: string, version: string): Server => {
|
||||
const server = new Server({ name, version }, { capabilities: { tools: {} } });
|
||||
export const createMcpServer = (name: string, version: string, group?: string): Server => {
|
||||
// Determine server name based on routing type
|
||||
let serverName = name;
|
||||
|
||||
if (group) {
|
||||
// Check if it's a group or a single server
|
||||
const serversInGroup = getServersInGroup(group);
|
||||
if (!serversInGroup || serversInGroup.length === 0) {
|
||||
// Single server routing
|
||||
serverName = `${name}_${group}`;
|
||||
} else {
|
||||
// Group routing
|
||||
serverName = `${name}_${group}_group`;
|
||||
}
|
||||
}
|
||||
// If no group, use default name (global routing)
|
||||
|
||||
const server = new Server({ name: serverName, version }, { capabilities: { tools: {} } });
|
||||
server.setRequestHandler(ListToolsRequestSchema, handleListToolsRequest);
|
||||
server.setRequestHandler(CallToolRequestSchema, handleCallToolRequest);
|
||||
return server;
|
||||
|
||||
@@ -70,7 +70,7 @@ export const handleSseConnection = async (req: Request, res: Response): Promise<
|
||||
console.log(
|
||||
`New SSE connection established: ${transport.sessionId} with group: ${group || 'global'}`,
|
||||
);
|
||||
await getMcpServer(transport.sessionId).connect(transport);
|
||||
await getMcpServer(transport.sessionId, group).connect(transport);
|
||||
};
|
||||
|
||||
export const handleSseMessage = async (req: Request, res: Response): Promise<void> => {
|
||||
@@ -135,7 +135,7 @@ export const handleMcpPostRequest = async (req: Request, res: Response): Promise
|
||||
};
|
||||
|
||||
console.log(`MCP connection established: ${transport.sessionId}`);
|
||||
await getMcpServer(transport.sessionId).connect(transport);
|
||||
await getMcpServer(transport.sessionId, group).connect(transport);
|
||||
} else {
|
||||
res.status(400).json({
|
||||
jsonrpc: '2.0',
|
||||
|
||||
23
src/utils/version.ts
Normal file
23
src/utils/version.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
// Get the directory name in ESM
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
/**
|
||||
* Gets the package version from package.json
|
||||
* @returns The version string from package.json, or 'dev' if not found
|
||||
*/
|
||||
export const getPackageVersion = (): string => {
|
||||
try {
|
||||
const packageJsonPath = path.resolve(__dirname, '../../package.json');
|
||||
const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf8');
|
||||
const packageJson = JSON.parse(packageJsonContent);
|
||||
return packageJson.version || 'dev';
|
||||
} catch (error) {
|
||||
console.error('Error reading package version:', error);
|
||||
return 'dev';
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user