🐺 Initial commit - Lupul Augmentat MCP Server

- MCP server cu stdio transport pentru performanță maximă
- Tool-uri pentru file operations, HTTP requests, system commands
- Suport NATS pentru comunicare inter-module
- Configurare nginx cu API key auth și SSL
- Arhitectură modulară și extensibilă

🤖 Generated with Claude Code
This commit is contained in:
Claude (Lupul Augmentat)
2025-10-09 06:24:58 +02:00
commit 475f89af74
59 changed files with 12827 additions and 0 deletions

View File

@@ -0,0 +1,172 @@
import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
import * as http from 'http';
import * as https from 'https';
import jwt from 'jsonwebtoken';
import { createLogger } from '../utils/logger';
import { config } from '../config';
const logger = createLogger('HttpServerTransport');
export class HttpServerTransport implements Transport {
private server?: http.Server | https.Server;
private connections: Set<http.ServerResponse> = new Set();
onclose?: () => void;
onerror?: (error: Error) => void;
onmessage?: (message: JSONRPCMessage) => void;
constructor(
private host: string,
private port: number,
private options?: https.ServerOptions
) {}
async start(): Promise<void> {
return new Promise((resolve, reject) => {
const requestHandler = async (req: http.IncomingMessage, res: http.ServerResponse) => {
// CORS headers
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
if (req.method === 'OPTIONS') {
res.writeHead(200);
res.end();
return;
}
if (req.method !== 'POST') {
res.writeHead(405);
res.end('Method Not Allowed');
return;
}
// Check authentication if enabled
if (config.security.authEnabled) {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
res.writeHead(401, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
jsonrpc: '2.0',
error: { code: -32001, message: 'Unauthorized: Missing or invalid authorization header' },
id: null
}));
return;
}
const token = authHeader.substring(7);
try {
const decoded = jwt.verify(token, config.security.jwtSecret) as any;
// Token is valid, continue processing
logger.debug({ userId: decoded.id }, 'Authenticated request');
} catch (error) {
res.writeHead(401, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
jsonrpc: '2.0',
error: { code: -32001, message: 'Unauthorized: Invalid token' },
id: null
}));
return;
}
}
let body = '';
req.on('data', chunk => body += chunk);
req.on('end', async () => {
try {
const message = JSON.parse(body) as JSONRPCMessage;
logger.debug({ message }, 'Received JSON-RPC message');
// Store response for sending reply
this.connections.add(res);
// Pass message to handler
if (this.onmessage) {
this.onmessage(message);
}
// Wait for response (simplified - in production would use message correlation)
setTimeout(() => {
if (!res.headersSent) {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end('{}');
}
this.connections.delete(res);
}, 30000); // 30 second timeout
} catch (error) {
logger.error({ error }, 'Failed to parse JSON-RPC message');
res.writeHead(400);
res.end('Invalid JSON-RPC message');
this.connections.delete(res);
}
});
};
if (this.options) {
this.server = https.createServer(this.options, requestHandler);
} else {
this.server = http.createServer(requestHandler);
}
this.server.listen(this.port, this.host, () => {
logger.info({ host: this.host, port: this.port }, 'HTTP transport started');
resolve();
});
this.server.on('error', (error) => {
logger.error({ error }, 'Server error');
if (this.onerror) {
this.onerror(error);
}
reject(error);
});
});
}
async send(message: JSONRPCMessage): Promise<void> {
// Send response to the most recent connection that matches the message ID
const messageStr = JSON.stringify(message);
for (const res of this.connections) {
if (!res.headersSent) {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(messageStr);
this.connections.delete(res);
logger.debug({ message }, 'Sent JSON-RPC response');
return;
}
}
logger.warn({ message }, 'No active connection to send response');
}
async close(): Promise<void> {
return new Promise((resolve) => {
if (this.server) {
// Close all active connections
for (const res of this.connections) {
if (!res.headersSent) {
res.writeHead(503);
res.end('Server shutting down');
}
}
this.connections.clear();
this.server.close(() => {
logger.info('HTTP transport closed');
if (this.onclose) {
this.onclose();
}
resolve();
});
} else {
resolve();
}
});
}
}