From 5214d52cd5ac3cfb20d27fde1ce3a90a8876f127 Mon Sep 17 00:00:00 2001 From: prpeh Date: Sat, 12 Apr 2025 17:13:35 +0700 Subject: [PATCH] feat: add HTTP transport support and smithery configuration --- smithery.yaml | 32 ++++++++++++++++++++++++ src/index.ts | 68 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 smithery.yaml diff --git a/smithery.yaml b/smithery.yaml new file mode 100644 index 0000000..a6d6fe7 --- /dev/null +++ b/smithery.yaml @@ -0,0 +1,32 @@ +type: stdio +configSchema: + type: object + properties: + httpServer: + type: boolean + description: Whether to run the server in HTTP mode + default: false + port: + type: integer + description: Port number for HTTP server + default: 3000 + additionalProperties: false + +commandFunction: | + function(config) { + const args = []; + const env = {}; + + if (config.httpServer) { + env.HTTP_SERVER = 'true'; + if (config.port) { + env.PORT = config.port.toString(); + } + } + + return { + command: 'node', + args: ['dist/index.js'], + env: env + }; + } \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 98b34fd..5667910 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,7 @@ import { import dotenv from 'dotenv'; import { DatabaseService } from './core/database-service'; import { KnowledgeTools } from './core/knowledge-tools'; +import http from 'http'; // Load environment variables dotenv.config(); @@ -60,15 +61,76 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { } }); +// Custom HTTP transport implementation +class HttpTransport { + private server: http.Server; + private port: number; + + constructor(port: number) { + this.port = port; + this.server = http.createServer(this.handleRequest.bind(this)); + } + + private async handleRequest(req: http.IncomingMessage, res: http.ServerResponse) { + if (req.method === 'POST' && req.url === '/') { + let body = ''; + req.on('data', chunk => body += chunk); + req.on('end', async () => { + try { + const request = JSON.parse(body); + let response; + if (request.method === 'listTools') { + response = { tools: knowledgeTools.getTools() }; + } else if (request.method === 'callTool') { + const { name, arguments: args } = request.params; + const tool = knowledgeTools.getTools().find(t => t.name === name); + if (!tool) { + throw new Error(`Unknown tool: ${name}`); + } + response = { content: [{ type: "text", text: JSON.stringify(await tool.handler(args)) }] }; + } else { + throw new Error('Unsupported method'); + } + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify(response)); + } catch (error: unknown) { + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + res.writeHead(500, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ error: errorMessage })); + } + }); + } else { + res.writeHead(404); + res.end(); + } + } + + async start() { + return new Promise((resolve) => { + this.server.listen(this.port, () => { + console.log(`HTTP server listening on port ${this.port}`); + resolve(); + }); + }); + } +} + // Server startup async function runServer() { // Initialize the database service await dbService.initialize(); - const transport = new StdioServerTransport(); - await server.connect(transport); + const useHttp = process.env.HTTP_SERVER === 'true'; - console.log("Knowledge Management Tools Server started successfully"); + if (useHttp) { + const port = process.env.PORT ? parseInt(process.env.PORT) : 3000; + const httpTransport = new HttpTransport(port); + await httpTransport.start(); + } else { + const transport = new StdioServerTransport(); + await server.connect(transport); + console.log("Knowledge Management Tools Server started successfully using Stdio transport"); + } } runServer().catch((error) => {