Files
claude-task-master/mcp-server/src/index.js
Ralph Khreish dc811eb45e feat: create tm-core and apps/cli (#1093)
- add typescript
- add npm workspaces
2025-09-17 22:00:34 +02:00

140 lines
3.2 KiB
JavaScript

import { FastMCP } from 'fastmcp';
import path from 'path';
import dotenv from 'dotenv';
import { fileURLToPath } from 'url';
import fs from 'fs';
import logger from './logger.js';
import { registerTaskMasterTools } from './tools/index.js';
import ProviderRegistry from '../../src/provider-registry/index.js';
import { MCPProvider } from './providers/mcp-provider.js';
import packageJson from '../../package.json' with { type: 'json' };
// Load environment variables
dotenv.config();
// Constants
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
/**
* Main MCP server class that integrates with Task Master
*/
class TaskMasterMCPServer {
constructor() {
this.options = {
name: 'Task Master MCP Server',
version: packageJson.version
};
this.server = new FastMCP(this.options);
this.initialized = false;
// Bind methods
this.init = this.init.bind(this);
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
// Setup logging
this.logger = logger;
}
/**
* Initialize the MCP server with necessary tools and routes
*/
async init() {
if (this.initialized) return;
// Pass the manager instance to the tool registration function
registerTaskMasterTools(this.server, this.asyncManager);
this.initialized = true;
return this;
}
/**
* Start the MCP server
*/
async start() {
if (!this.initialized) {
await this.init();
}
this.server.on('connect', (event) => {
event.session.server.sendLoggingMessage({
data: {
context: event.session.context,
message: `MCP Server connected: ${event.session.name}`
},
level: 'info'
});
this.registerRemoteProvider(event.session);
});
// Start the FastMCP server with increased timeout
await this.server.start({
transportType: 'stdio',
timeout: 120000 // 2 minutes timeout (in milliseconds)
});
return this;
}
/**
* Register both MCP providers with the provider registry
*/
registerRemoteProvider(session) {
// Check if the server has at least one session
if (session) {
// Make sure session has required capabilities
if (!session.clientCapabilities || !session.clientCapabilities.sampling) {
session.server.sendLoggingMessage({
data: {
context: session.context,
message: `MCP session missing required sampling capabilities, providers not registered`
},
level: 'info'
});
return;
}
// Register MCP provider with the Provider Registry
// Register the unified MCP provider
const mcpProvider = new MCPProvider();
mcpProvider.setSession(session);
// Register provider with the registry
const providerRegistry = ProviderRegistry.getInstance();
providerRegistry.registerProvider('mcp', mcpProvider);
session.server.sendLoggingMessage({
data: {
context: session.context,
message: `MCP Server connected`
},
level: 'info'
});
} else {
session.server.sendLoggingMessage({
data: {
context: session.context,
message: `No MCP sessions available, providers not registered`
},
level: 'warn'
});
}
}
/**
* Stop the MCP server
*/
async stop() {
if (this.server) {
await this.server.stop();
}
}
}
export default TaskMasterMCPServer;