@kpritam/gremlin-mcp
Version:
A Gremlin MCP server that allows for fetching status, schema, and querying using Gremlin for any Gremlin-compatible graph database (TypeScript implementation).
105 lines • 3.98 kB
JavaScript
/**
* Gremlin MCP Server implementation using TypeScript.
*/
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { logger } from './logger.js';
import { GremlinClient } from './gremlin/client.js';
import { config } from './config.js';
import { registerAllHandlers } from './handlers/index.js';
/**
* Main function to run the MCP server.
*/
async function main() {
logger.info('🚀 Starting Gremlin MCP Server...', {
service: 'gremlin-mcp',
version: config.serverVersion,
gremlinEndpoint: `${config.gremlinHost}:${config.gremlinPort}`,
logLevel: config.logLevel,
});
// Initialize the server
const server = new McpServer({
name: config.serverName,
version: config.serverVersion,
});
logger.info('✅ MCP Server instance created', { service: 'gremlin-mcp' });
// Gremlin client factory function
let gremlinClient;
async function getGremlinClient() {
if (!gremlinClient) {
gremlinClient = new GremlinClient({
host: config.gremlinHost,
port: config.gremlinPort,
traversalSource: config.gremlinTraversalSource,
useSSL: config.gremlinUseSSL,
username: config.gremlinUsername,
password: config.gremlinPassword,
idleTimeoutSeconds: config.gremlinIdleTimeout,
enumDiscoveryEnabled: config.gremlinEnumDiscoveryEnabled,
enumCardinalityThreshold: config.gremlinEnumCardinalityThreshold,
enumPropertyBlacklist: config.gremlinEnumPropertyBlacklist,
includeSampleValues: config.gremlinSchemaIncludeSampleValues,
maxEnumValues: config.gremlinSchemaMaxEnumValues,
includeCounts: config.gremlinSchemaIncludeCounts,
});
await gremlinClient.initialize();
logger.info('Gremlin client initialized successfully');
}
return gremlinClient;
}
// Register all handlers
registerAllHandlers(server, getGremlinClient);
// Graceful shutdown
const shutdown = async (signal) => {
logger.info(`Received ${signal}. Shutting down...`);
if (gremlinClient) {
await gremlinClient.close();
}
process.exit(0);
};
// Handle cleanup on exit
process.on('SIGINT', async () => {
await shutdown('SIGINT');
});
process.on('SIGTERM', async () => {
await shutdown('SIGTERM');
});
try {
logger.info('🔌 Creating STDIO transport...', { service: 'gremlin-mcp' });
const transport = new StdioServerTransport();
logger.info('🔗 Connecting server to transport...', { service: 'gremlin-mcp' });
await server.connect(transport);
logger.info('✅ Gremlin MCP Server started successfully', {
service: 'gremlin-mcp',
pid: process.pid,
ready: true,
});
}
catch (error) {
logger.error('❌ Failed to start server', {
service: 'gremlin-mcp',
error: error instanceof Error ? error.message : String(error),
stack: error instanceof Error ? error.stack : undefined,
});
process.exit(1);
}
}
// Add startup logging before anything else
console.info('🎬 Gremlin MCP Server executable started');
console.info('📋 Process info:', {
pid: process.pid,
nodeVersion: process.versions.node,
platform: process.platform,
argv: process.argv,
cwd: process.cwd(),
});
main().catch(error => {
logger.error('❌ Unhandled error in main', {
service: 'gremlin-mcp',
error: error instanceof Error ? error.message : String(error),
stack: error instanceof Error ? error.stack : undefined,
});
process.exit(1);
});
//# sourceMappingURL=server.js.map