#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from '@modelcontextprotocol/sdk/types.js';
import { CannyClient } from './client/canny.js';
import { CONFIG } from './config/config.js';
import { tools } from './tools/index.js';
import { validateEnvironment } from './utils/validation.js';
class CannyMCPServer {
server;
cannyClient;
constructor() {
console.error('π§ Constructing CannyMCPServer...');
this.server = new Server({
name: 'canny-mcp-server',
version: '1.0.0',
}, {
capabilities: {
tools: {},
},
});
console.error('β
MCP Server instance created');
// Validate environment and initialize client
console.error('π Validating environment...');
const validation = validateEnvironment();
if (!validation.isValid) {
console.error('β Environment validation failed:', validation.errors);
throw new Error(`Configuration error: ${validation.errors.join(', ')}`);
}
console.error('β
Environment validation passed');
console.error('π§ Initializing Canny client...');
this.cannyClient = new CannyClient(CONFIG.apiKey, CONFIG.baseUrl);
console.error('β
Canny client initialized');
console.error('π§ Setting up tool handlers...');
this.setupToolHandlers();
console.error('β
Tool handlers configured');
}
setupToolHandlers() {
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: tools.map(tool => ({
name: tool.name,
description: tool.description,
inputSchema: tool.inputSchema,
})),
}));
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
const tool = tools.find(t => t.name === name);
if (!tool) {
throw new McpError(ErrorCode.MethodNotFound, `Tool "${name}" not found`);
}
try {
const result = await tool.handler(args, this.cannyClient);
return {
content: [
{
type: 'text',
text: typeof result === 'string' ? result : JSON.stringify(result, null, 2),
},
],
};
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
throw new McpError(ErrorCode.InternalError, `Tool execution failed: ${errorMessage}`);
}
});
}
async run() {
console.error('π§ Setting up transport...');
const transport = new StdioServerTransport();
console.error('β
Transport created');
console.error('π Connecting server to transport...');
await this.server.connect(transport);
console.error('π Canny MCP Server running on stdio');
}
}
// Start the server
async function main() {
try {
console.error('π Starting Canny MCP Server...');
const server = new CannyMCPServer();
console.error('β
Server instance created successfully');
await server.run();
console.error('β
Server.run() completed');
}
catch (error) {
console.error('π₯ Failed to start Canny MCP Server:', error);
console.error('π Stack trace:', error instanceof Error ? error.stack : 'No stack trace');
process.exit(1);
}
}
if (import.meta.url === `file://${process.argv[1]}`) {
main().catch((error) => {
console.error('Unhandled error:', error);
process.exit(1);
});
}
export { CannyMCPServer };
//# sourceMappingURL=server.js.map