@brutalist/mcp 0.7.0 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +22 -1
  2. package/dist/brutalist-server.d.ts +46 -16
  3. package/dist/brutalist-server.d.ts.map +1 -1
  4. package/dist/brutalist-server.js +223 -611
  5. package/dist/brutalist-server.js.map +1 -1
  6. package/dist/cli-agents.d.ts +11 -9
  7. package/dist/cli-agents.d.ts.map +1 -1
  8. package/dist/cli-agents.js +239 -155
  9. package/dist/cli-agents.js.map +1 -1
  10. package/dist/domains/argument-space.d.ts +9 -0
  11. package/dist/domains/argument-space.d.ts.map +1 -1
  12. package/dist/domains/argument-space.js +27 -20
  13. package/dist/domains/argument-space.js.map +1 -1
  14. package/dist/formatting/response-formatter.d.ts +43 -0
  15. package/dist/formatting/response-formatter.d.ts.map +1 -0
  16. package/dist/formatting/response-formatter.js +277 -0
  17. package/dist/formatting/response-formatter.js.map +1 -0
  18. package/dist/generators/tool-generator.d.ts.map +1 -1
  19. package/dist/generators/tool-generator.js +3 -1
  20. package/dist/generators/tool-generator.js.map +1 -1
  21. package/dist/handlers/tool-handler.d.ts +33 -0
  22. package/dist/handlers/tool-handler.d.ts.map +1 -0
  23. package/dist/handlers/tool-handler.js +299 -0
  24. package/dist/handlers/tool-handler.js.map +1 -0
  25. package/dist/registry/argument-spaces.js +17 -17
  26. package/dist/registry/argument-spaces.js.map +1 -1
  27. package/dist/transport/http-transport.d.ts +40 -0
  28. package/dist/transport/http-transport.d.ts.map +1 -0
  29. package/dist/transport/http-transport.js +182 -0
  30. package/dist/transport/http-transport.js.map +1 -0
  31. package/dist/types/tool-config.d.ts +3 -3
  32. package/dist/types/tool-config.js +2 -2
  33. package/dist/types/tool-config.js.map +1 -1
  34. package/dist/utils.d.ts +1 -1
  35. package/dist/utils.d.ts.map +1 -1
  36. package/dist/utils.js +13 -6
  37. package/dist/utils.js.map +1 -1
  38. package/package.json +1 -1
@@ -0,0 +1,299 @@
1
+ import { logger } from '../logger.js';
2
+ import { extractPaginationParams, parseCursor } from '../utils/pagination.js';
3
+ /**
4
+ * ToolHandler - Handles roast tool execution with caching and pagination
5
+ * Extracted from BrutalistServer to follow Single Responsibility Principle
6
+ */
7
+ export class ToolHandler {
8
+ cliOrchestrator;
9
+ responseCache;
10
+ formatter;
11
+ config;
12
+ activeSessions;
13
+ handleStreamingEvent;
14
+ handleProgressUpdate;
15
+ ensureSessionCapacity;
16
+ constructor(cliOrchestrator, responseCache, formatter, config, activeSessions, handleStreamingEvent, handleProgressUpdate, ensureSessionCapacity) {
17
+ this.cliOrchestrator = cliOrchestrator;
18
+ this.responseCache = responseCache;
19
+ this.formatter = formatter;
20
+ this.config = config;
21
+ this.activeSessions = activeSessions;
22
+ this.handleStreamingEvent = handleStreamingEvent;
23
+ this.handleProgressUpdate = handleProgressUpdate;
24
+ this.ensureSessionCapacity = ensureSessionCapacity;
25
+ }
26
+ /**
27
+ * Unified handler for all roast tools - DRY principle
28
+ */
29
+ async handleRoastTool(config, args, extra) {
30
+ try {
31
+ // CRITICAL: Prevent recursion - reject tool calls from brutalist-spawned subprocesses
32
+ if (process.env.BRUTALIST_SUBPROCESS === '1') {
33
+ logger.warn(`🚫 Rejecting tool call from brutalist subprocess (recursion prevented)`);
34
+ return {
35
+ content: [{
36
+ type: "text",
37
+ text: `ERROR: Brutalist MCP tools cannot be used from within a brutalist-spawned CLI subprocess (recursion prevented)`
38
+ }]
39
+ };
40
+ }
41
+ const progressToken = extra._meta?.progressToken;
42
+ // Extract session context for security
43
+ // IMPORTANT: Use consistent "anonymous" for all anonymous users to enable cache sharing
44
+ const sessionId = extra?.sessionId ||
45
+ extra?._meta?.sessionId ||
46
+ extra?.headers?.['mcp-session-id'] ||
47
+ 'anonymous'; // Consistent for cache sharing across pagination requests
48
+ const requestId = `${sessionId}-${Date.now()}-${Math.random().toString(36).substring(7)}`;
49
+ logger.debug(`🔐 Processing request with session: ${sessionId.substring(0, 8)}..., request: ${requestId.substring(0, 12)}...`);
50
+ // Track session activity
51
+ if (!this.activeSessions.has(sessionId)) {
52
+ this.ensureSessionCapacity(); // Ensure capacity before adding new session
53
+ this.activeSessions.set(sessionId, {
54
+ startTime: Date.now(),
55
+ requestCount: 0,
56
+ lastActivity: Date.now()
57
+ });
58
+ }
59
+ const sessionInfo = this.activeSessions.get(sessionId);
60
+ sessionInfo.requestCount++;
61
+ sessionInfo.lastActivity = Date.now();
62
+ logger.debug(`Tool execution: ${config.name}, primaryArgField=${config.primaryArgField}`);
63
+ logger.debug(`Args: ${JSON.stringify(args, null, 2)}`);
64
+ // Extract pagination parameters
65
+ const paginationParams = extractPaginationParams(args);
66
+ if (args.cursor) {
67
+ const cursorParams = parseCursor(args.cursor);
68
+ Object.assign(paginationParams, cursorParams);
69
+ }
70
+ // Determine if pagination was explicitly requested by the user
71
+ const explicitPaginationRequested = args.offset !== undefined ||
72
+ args.limit !== undefined ||
73
+ args.cursor !== undefined ||
74
+ args.context_id !== undefined;
75
+ logger.info(`🔧 DEBUG: explicitPaginationRequested=${explicitPaginationRequested}, offset=${args.offset}, limit=${args.limit}, cursor=${args.cursor}, context_id=${args.context_id}, resume=${args.resume}`);
76
+ // Validate resume flag requires context_id
77
+ if (args.resume && !args.context_id) {
78
+ throw new Error(`The 'resume' flag requires a 'context_id' from a previous response. ` +
79
+ `Run an initial analysis first, then use the returned context_id with resume: true.`);
80
+ }
81
+ // Check cache if context_id provided
82
+ // Two modes: PAGINATION (context_id alone) vs CONTINUATION (context_id + resume: true)
83
+ let conversationHistory;
84
+ let resumeFollowUpQuestion; // Store follow-up for conversation history
85
+ let resumeOriginalParams; // Original params for filesystem tools
86
+ if (args.context_id && !args.force_refresh) {
87
+ const cachedResponse = await this.responseCache.getByContextId(args.context_id, sessionId);
88
+ if (cachedResponse) {
89
+ logger.info(`🎯 Cache HIT for context_id: ${args.context_id}`);
90
+ if (args.resume === true) {
91
+ // CONVERSATION CONTINUATION: User explicitly wants to continue with history injection
92
+ const textContent = args.content || args.idea || args.architecture || args.research || args.product || args.security || args.infrastructure;
93
+ const primaryArg = textContent || args[config.primaryArgField];
94
+ if (!primaryArg || primaryArg.trim() === '') {
95
+ throw new Error(`Conversation continuation (resume: true) requires new content/prompt. ` +
96
+ `Provide your follow-up question or comment in the content field.`);
97
+ }
98
+ // Store the follow-up question for conversation history
99
+ resumeFollowUpQuestion = primaryArg;
100
+ // Store original request params (for filesystem tools that need original targetPath)
101
+ resumeOriginalParams = cachedResponse.requestParams;
102
+ logger.info(`💬 Conversation continuation - new prompt: "${primaryArg.substring(0, 50)}..."`);
103
+ conversationHistory = cachedResponse.conversationHistory || [];
104
+ // Fall through to execute new analysis with history
105
+ }
106
+ else {
107
+ // PAGINATION: Just retrieving previous response (no resume flag)
108
+ logger.info(`📖 Pagination request - returning cached response`);
109
+ const cachedResult = {
110
+ success: true,
111
+ responses: [{
112
+ agent: 'cached',
113
+ success: true,
114
+ output: cachedResponse.content,
115
+ executionTime: 0
116
+ }]
117
+ };
118
+ return this.formatter.formatToolResponse(cachedResult, args.verbose, paginationParams, args.context_id, explicitPaginationRequested);
119
+ }
120
+ }
121
+ else {
122
+ logger.warn(`❌ Cache MISS for context_id: ${args.context_id}, session: ${sessionId}`);
123
+ throw new Error(`Context ID "${args.context_id}" not found in cache. ` +
124
+ `It may have expired (2 hour TTL) or belong to a different session. ` +
125
+ `Remove context_id parameter to run a new analysis.`);
126
+ }
127
+ }
128
+ // Generate cache key for this request
129
+ const cacheKey = this.responseCache.generateCacheKey(config.cacheKeyFields.reduce((acc, field) => {
130
+ acc.tool = config.name;
131
+ if (args[field] !== undefined)
132
+ acc[field] = args[field];
133
+ return acc;
134
+ }, {}));
135
+ // Check if we have a cached result (unless forcing refresh)
136
+ if (!args.force_refresh) {
137
+ const cachedContent = await this.responseCache.get(cacheKey, sessionId);
138
+ if (cachedContent) {
139
+ // Get existing context_id or create new alias
140
+ const existingContextId = this.responseCache.findContextIdForKey(cacheKey);
141
+ const contextId = existingContextId
142
+ ? this.responseCache.createAlias(existingContextId, cacheKey)
143
+ : this.responseCache.generateContextId(cacheKey);
144
+ logger.info(`🎯 Cache hit for new request, using context_id: ${contextId}`);
145
+ const cachedResult = {
146
+ success: true,
147
+ responses: [{
148
+ agent: 'cached',
149
+ success: true,
150
+ output: cachedContent,
151
+ executionTime: 0
152
+ }]
153
+ };
154
+ return this.formatter.formatToolResponse(cachedResult, args.verbose, paginationParams, contextId, explicitPaginationRequested);
155
+ }
156
+ }
157
+ // Build context with custom builder if available
158
+ let context = config.contextBuilder ? config.contextBuilder(args) : args.context;
159
+ // Get the primary argument (targetPath, idea, architecture, etc.)
160
+ // For text-based tools, use content field; for filesystem tools, use primaryArgField
161
+ const textContent = args.content || args.idea || args.architecture || args.research || args.product || args.security || args.infrastructure;
162
+ let primaryArg = textContent || args[config.primaryArgField];
163
+ // For resume mode with filesystem tools, use original targetPath from cached params
164
+ // and inject the follow-up question into context instead
165
+ const filesystemTools = ['codebase', 'fileStructure', 'dependencies', 'gitHistory', 'testCoverage'];
166
+ if (resumeOriginalParams && filesystemTools.includes(config.analysisType)) {
167
+ // Use original targetPath for the CLI execution (needed for path validation)
168
+ const originalTargetPath = resumeOriginalParams.targetPath;
169
+ if (originalTargetPath) {
170
+ logger.info(`🔄 Resume mode: Using original targetPath="${originalTargetPath}" for filesystem tool`);
171
+ primaryArg = originalTargetPath;
172
+ // Also restore workingDirectory if available
173
+ if (resumeOriginalParams.workingDirectory) {
174
+ args.workingDirectory = resumeOriginalParams.workingDirectory;
175
+ }
176
+ }
177
+ }
178
+ // If we have conversation history, inject it into the context
179
+ if (conversationHistory && conversationHistory.length > 0) {
180
+ const conversationContext = conversationHistory.map(msg => {
181
+ const role = msg.role === 'user' ? 'User' : 'Assistant';
182
+ return `${role}: ${msg.content}`;
183
+ }).join('\n\n---\n\n');
184
+ // For resume mode, inject the follow-up question into the context
185
+ const followUpContent = resumeFollowUpQuestion || '';
186
+ const contextPrefix = `## Previous Conversation\n\n${conversationContext}\n\n---\n\n## New User Prompt\n\n${followUpContent}\n\n`;
187
+ context = contextPrefix + (context || '');
188
+ logger.info(`💬 Injected ${conversationHistory.length} previous messages into context`);
189
+ }
190
+ logger.debug(`Primary arg: ${config.primaryArgField}="${primaryArg}", analysisType="${config.analysisType}"`);
191
+ // Run the analysis
192
+ const result = await this.executeBrutalistAnalysis(config.analysisType, primaryArg, config.systemPrompt, context, args.workingDirectory, args.preferredCLI, args.verbose, args.models, progressToken, sessionId, requestId);
193
+ // Cache the result if successful
194
+ let contextId;
195
+ if (result.success && result.responses.length > 0) {
196
+ const fullContent = this.formatter.extractFullContent(result);
197
+ if (fullContent) {
198
+ const cacheData = config.cacheKeyFields.reduce((acc, field) => {
199
+ acc.tool = config.name;
200
+ if (args[field] !== undefined)
201
+ acc[field] = args[field];
202
+ return acc;
203
+ }, {});
204
+ // Build updated conversation history
205
+ // For resume mode, use the follow-up question; otherwise use primaryArg
206
+ const now = Date.now();
207
+ const userMessageContent = resumeFollowUpQuestion || primaryArg;
208
+ const updatedConversation = [
209
+ ...(conversationHistory || []),
210
+ { role: 'user', content: userMessageContent, timestamp: now },
211
+ { role: 'assistant', content: fullContent, timestamp: now }
212
+ ];
213
+ // If continuing a conversation (resume: true), update existing context_id
214
+ if (args.resume && args.context_id && conversationHistory) {
215
+ // Update existing cache entry with extended conversation
216
+ contextId = args.context_id;
217
+ await this.responseCache.updateByContextId(contextId, fullContent, updatedConversation, sessionId || 'anonymous');
218
+ logger.info(`✅ Updated conversation ${contextId} (now ${updatedConversation.length} messages)`);
219
+ }
220
+ else {
221
+ // New conversation - create new context_id
222
+ const { contextId: newId } = await this.responseCache.set(cacheData, fullContent, cacheKey, sessionId, requestId, updatedConversation);
223
+ contextId = newId;
224
+ logger.info(`✅ Cached new conversation with context ID: ${contextId} for session: ${sessionId?.substring(0, 8)}`);
225
+ }
226
+ }
227
+ }
228
+ return this.formatter.formatToolResponse(result, args.verbose, paginationParams, contextId, explicitPaginationRequested);
229
+ }
230
+ catch (error) {
231
+ return this.formatter.formatErrorResponse(error);
232
+ }
233
+ }
234
+ /**
235
+ * Execute brutalist analysis with CLI orchestrator
236
+ */
237
+ async executeBrutalistAnalysis(analysisType, primaryContent, systemPromptSpec, context, workingDirectory, preferredCLI, verbose, models, progressToken, sessionId, requestId) {
238
+ logger.info(`🏢 Starting brutalist analysis: ${analysisType}`);
239
+ logger.info(`🔧 DEBUG: preferredCLI=${preferredCLI}, primaryContent=${primaryContent}`);
240
+ logger.debug("Executing brutalist analysis", {
241
+ primaryContent,
242
+ analysisType,
243
+ systemPromptSpec,
244
+ workingDirectory,
245
+ preferredCLI
246
+ });
247
+ try {
248
+ // Get CLI context for execution summary
249
+ logger.info(`🔧 DEBUG: About to detect CLI context`);
250
+ await this.cliOrchestrator.detectCLIContext();
251
+ logger.info(`🔧 DEBUG: CLI context detected successfully`);
252
+ // Execute CLI agent analysis (single or multi-CLI based on preferences)
253
+ logger.info(`🔍 Executing brutalist analysis with timeout: ${this.config.defaultTimeout}ms`);
254
+ logger.info(`🔧 DEBUG: About to call cliOrchestrator.executeBrutalistAnalysis`);
255
+ const responses = await this.cliOrchestrator.executeBrutalistAnalysis(analysisType, primaryContent, systemPromptSpec, context, {
256
+ workingDirectory: workingDirectory || this.config.workingDirectory,
257
+ timeout: this.config.defaultTimeout,
258
+ preferredCLI,
259
+ analysisType: analysisType,
260
+ models,
261
+ onStreamingEvent: this.handleStreamingEvent,
262
+ progressToken,
263
+ onProgress: progressToken && sessionId ?
264
+ (progress, total, message) => this.handleProgressUpdate(progressToken, progress, total, message, sessionId) : undefined,
265
+ sessionId,
266
+ requestId
267
+ });
268
+ logger.info(`🔧 DEBUG: cliOrchestrator.executeBrutalistAnalysis returned ${responses.length} responses`);
269
+ const successfulResponses = responses.filter(r => r.success);
270
+ const totalExecutionTime = responses.reduce((sum, r) => sum + r.executionTime, 0);
271
+ logger.info(`📊 Analysis complete: ${successfulResponses.length}/${responses.length} CLIs successful (${totalExecutionTime}ms total)`);
272
+ logger.info(`🔧 DEBUG: About to synthesize feedback`);
273
+ const synthesis = this.cliOrchestrator.synthesizeBrutalistFeedback(responses, analysisType);
274
+ logger.info(`🔧 DEBUG: Synthesis length: ${synthesis.length} characters`);
275
+ const result = {
276
+ success: successfulResponses.length > 0,
277
+ responses,
278
+ synthesis,
279
+ analysisType,
280
+ targetPath: primaryContent,
281
+ executionSummary: {
282
+ totalCLIs: responses.length,
283
+ successfulCLIs: successfulResponses.length,
284
+ failedCLIs: responses.length - successfulResponses.length,
285
+ totalExecutionTime,
286
+ selectedCLI: responses.length === 1 ? responses[0].agent : undefined,
287
+ selectionMethod: responses.length === 1 ? responses[0].selectionMethod : 'multi-cli'
288
+ }
289
+ };
290
+ logger.info(`🔧 DEBUG: Returning result with success=${result.success}`);
291
+ return result;
292
+ }
293
+ catch (error) {
294
+ logger.error("Brutalist analysis execution failed", error);
295
+ throw error;
296
+ }
297
+ }
298
+ }
299
+ //# sourceMappingURL=tool-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-handler.js","sourceRoot":"","sources":["../../src/handlers/tool-handler.ts"],"names":[],"mappings":"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"}
@@ -27,8 +27,8 @@ export const ARGUMENT_SPACES = {
27
27
  name: 'Extended Text Input',
28
28
  base: FILESYSTEM_ARGUMENT_SPACE.base,
29
29
  domain: TEXT_INPUT_ARGUMENT_SPACE.domain.extend({
30
- resources: z.string().optional().describe("Available resources (budget, team, time, skills)"),
31
- timeline: z.string().optional().describe("Expected timeline or deadline")
30
+ resources: z.string().optional().describe("Available resources (budget, team, time)"),
31
+ timeline: z.string().optional().describe("Expected timeline")
32
32
  }),
33
33
  computed: (args) => ({
34
34
  workingDirectory: args.targetPath || '.',
@@ -41,9 +41,9 @@ export const ARGUMENT_SPACES = {
41
41
  name: 'Architecture Specific',
42
42
  base: FILESYSTEM_ARGUMENT_SPACE.base,
43
43
  domain: TEXT_INPUT_ARGUMENT_SPACE.domain.extend({
44
- scale: z.string().optional().describe("Expected scale/load (users, requests, data)"),
45
- constraints: z.string().optional().describe("Budget, timeline, or technical constraints"),
46
- deployment: z.string().optional().describe("Deployment environment and strategy")
44
+ scale: z.string().optional().describe("Expected scale/load"),
45
+ constraints: z.string().optional().describe("Technical/budget constraints"),
46
+ deployment: z.string().optional().describe("Deployment strategy")
47
47
  }),
48
48
  computed: (args) => ({
49
49
  workingDirectory: args.targetPath || '.',
@@ -57,9 +57,9 @@ export const ARGUMENT_SPACES = {
57
57
  name: 'Research Specific',
58
58
  base: FILESYSTEM_ARGUMENT_SPACE.base,
59
59
  domain: TEXT_INPUT_ARGUMENT_SPACE.domain.extend({
60
- field: z.string().optional().describe("Research field (ML, systems, theory, etc.)"),
61
- claims: z.string().optional().describe("Main claims or contributions"),
62
- data: z.string().optional().describe("Data sources, datasets, or experimental setup")
60
+ field: z.string().optional().describe("Research field"),
61
+ claims: z.string().optional().describe("Main claims"),
62
+ data: z.string().optional().describe("Data sources/setup")
63
63
  }),
64
64
  computed: (args) => ({
65
65
  workingDirectory: args.targetPath || '.',
@@ -73,9 +73,9 @@ export const ARGUMENT_SPACES = {
73
73
  name: 'Security Specific',
74
74
  base: FILESYSTEM_ARGUMENT_SPACE.base,
75
75
  domain: TEXT_INPUT_ARGUMENT_SPACE.domain.extend({
76
- assets: z.string().optional().describe("Critical assets or data to protect"),
77
- threatModel: z.string().optional().describe("Known threats or attack vectors to consider"),
78
- compliance: z.string().optional().describe("Compliance requirements (GDPR, HIPAA, etc.)")
76
+ assets: z.string().optional().describe("Critical assets to protect"),
77
+ threatModel: z.string().optional().describe("Known threats"),
78
+ compliance: z.string().optional().describe("Compliance requirements")
79
79
  }),
80
80
  computed: (args) => ({
81
81
  workingDirectory: args.targetPath || '.',
@@ -89,9 +89,9 @@ export const ARGUMENT_SPACES = {
89
89
  name: 'Product Specific',
90
90
  base: FILESYSTEM_ARGUMENT_SPACE.base,
91
91
  domain: TEXT_INPUT_ARGUMENT_SPACE.domain.extend({
92
- users: z.string().optional().describe("Target users or user personas"),
93
- competition: z.string().optional().describe("Competitive landscape or alternatives"),
94
- metrics: z.string().optional().describe("Success metrics or KPIs")
92
+ users: z.string().optional().describe("Target users"),
93
+ competition: z.string().optional().describe("Competitors"),
94
+ metrics: z.string().optional().describe("Success metrics")
95
95
  }),
96
96
  computed: (args) => ({
97
97
  workingDirectory: args.targetPath || '.',
@@ -105,9 +105,9 @@ export const ARGUMENT_SPACES = {
105
105
  name: 'Infrastructure Specific',
106
106
  base: FILESYSTEM_ARGUMENT_SPACE.base,
107
107
  domain: TEXT_INPUT_ARGUMENT_SPACE.domain.extend({
108
- scale: z.string().optional().describe("Expected scale and load patterns"),
109
- sla: z.string().optional().describe("SLA requirements or uptime targets"),
110
- budget: z.string().optional().describe("Infrastructure budget or cost constraints")
108
+ scale: z.string().optional().describe("Expected scale"),
109
+ sla: z.string().optional().describe("SLA/uptime targets"),
110
+ budget: z.string().optional().describe("Cost constraints")
111
111
  }),
112
112
  computed: (args) => ({
113
113
  workingDirectory: args.targetPath || '.',
@@ -1 +1 @@
1
- {"version":3,"file":"argument-spaces.js","sourceRoot":"","sources":["../../src/registry/argument-spaces.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"argument-spaces.js","sourceRoot":"","sources":["../../src/registry/argument-spaces.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
2
+ import { BrutalistServerConfig } from '../types/brutalist.js';
3
+ /**
4
+ * HttpTransport - Manages HTTP server and MCP transport
5
+ * Extracted from BrutalistServer to follow Single Responsibility Principle
6
+ */
7
+ export declare class HttpTransport {
8
+ private config;
9
+ private mcpRequestHandler;
10
+ private httpServer?;
11
+ private httpTransport?;
12
+ private actualPort?;
13
+ private shutdownHandler?;
14
+ constructor(config: BrutalistServerConfig, mcpRequestHandler: (transport: StreamableHTTPServerTransport) => void);
15
+ /**
16
+ * Start HTTP server with MCP transport
17
+ */
18
+ start(packageVersion: string): Promise<void>;
19
+ /**
20
+ * Stop the HTTP server gracefully
21
+ */
22
+ stop(): Promise<void>;
23
+ /**
24
+ * Get actual listening port (useful for tests)
25
+ */
26
+ getActualPort(): number | undefined;
27
+ /**
28
+ * Get HTTP transport instance
29
+ */
30
+ getTransport(): StreamableHTTPServerTransport | undefined;
31
+ /**
32
+ * Cleanup method for tests - remove event listeners
33
+ */
34
+ cleanup(): void;
35
+ /**
36
+ * Secure CORS implementation
37
+ */
38
+ private handleCORS;
39
+ }
40
+ //# sourceMappingURL=http-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-transport.d.ts","sourceRoot":"","sources":["../../src/transport/http-transport.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAGnG,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D;;;GAGG;AACH,qBAAa,aAAa;IAOtB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,iBAAiB;IAP3B,OAAO,CAAC,UAAU,CAAC,CAAM;IACzB,OAAO,CAAC,aAAa,CAAC,CAAgC;IACtD,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,eAAe,CAAC,CAAa;gBAG3B,MAAM,EAAE,qBAAqB,EAC7B,iBAAiB,EAAE,CAAC,SAAS,EAAE,6BAA6B,KAAK,IAAI;IAG/E;;OAEG;IACU,KAAK,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4EzD;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAalC;;OAEG;IACI,aAAa,IAAI,MAAM,GAAG,SAAS;IAI1C;;OAEG;IACI,YAAY,IAAI,6BAA6B,GAAG,SAAS;IAIhE;;OAEG;IACI,OAAO,IAAI,IAAI;IAOtB;;OAEG;IACH,OAAO,CAAC,UAAU;CAwDnB"}
@@ -0,0 +1,182 @@
1
+ import express from "express";
2
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
3
+ import { randomUUID } from "crypto";
4
+ import { logger } from '../logger.js';
5
+ /**
6
+ * HttpTransport - Manages HTTP server and MCP transport
7
+ * Extracted from BrutalistServer to follow Single Responsibility Principle
8
+ */
9
+ export class HttpTransport {
10
+ config;
11
+ mcpRequestHandler;
12
+ httpServer;
13
+ httpTransport;
14
+ actualPort;
15
+ shutdownHandler;
16
+ constructor(config, mcpRequestHandler) {
17
+ this.config = config;
18
+ this.mcpRequestHandler = mcpRequestHandler;
19
+ }
20
+ /**
21
+ * Start HTTP server with MCP transport
22
+ */
23
+ async start(packageVersion) {
24
+ logger.info(`Starting with HTTP streaming transport on port ${this.config.httpPort}`);
25
+ // Create HTTP transport with streaming support
26
+ this.httpTransport = new StreamableHTTPServerTransport({
27
+ sessionIdGenerator: () => randomUUID(),
28
+ enableJsonResponse: false, // Force SSE streaming
29
+ onsessioninitialized: (sessionId) => {
30
+ logger.info(`New session initialized: ${sessionId}`);
31
+ },
32
+ onsessionclosed: (sessionId) => {
33
+ logger.info(`Session closed: ${sessionId}`);
34
+ }
35
+ });
36
+ // Notify caller to connect MCP server to transport
37
+ this.mcpRequestHandler(this.httpTransport);
38
+ // Create Express app for HTTP handling
39
+ const app = express();
40
+ app.use(express.json({ limit: '10mb' })); // Add JSON size limit for security
41
+ // Apply CORS middleware
42
+ app.use((req, res, next) => {
43
+ this.handleCORS(req, res, next);
44
+ });
45
+ // Route all MCP requests through the transport
46
+ app.all('/mcp', async (req, res) => {
47
+ try {
48
+ await this.httpTransport.handleRequest(req, res, req.body);
49
+ }
50
+ catch (error) {
51
+ logger.error("HTTP request handling failed", error);
52
+ if (!res.headersSent) {
53
+ res.status(500).json({ error: 'Internal server error' });
54
+ }
55
+ }
56
+ });
57
+ // Health check endpoint
58
+ app.get('/health', (req, res) => {
59
+ res.json({ status: 'ok', transport: 'http-streaming', version: packageVersion });
60
+ });
61
+ // Start the HTTP server - bind to localhost only for security
62
+ const port = this.config.httpPort ?? 3000;
63
+ return new Promise((resolve, reject) => {
64
+ this.httpServer = app.listen(port, '127.0.0.1', () => {
65
+ const actualPort = this.httpServer.address()?.port || port;
66
+ this.actualPort = actualPort;
67
+ logger.info(`HTTP server listening on port ${actualPort}`);
68
+ logger.info(`MCP endpoint: http://localhost:${actualPort}/mcp`);
69
+ logger.info(`Health check: http://localhost:${actualPort}/health`);
70
+ resolve();
71
+ });
72
+ this.httpServer.on('error', (error) => {
73
+ logger.error('HTTP server failed to start', error);
74
+ reject(error);
75
+ });
76
+ // Handle graceful shutdown - avoid duplicate listeners
77
+ if (!this.shutdownHandler) {
78
+ this.shutdownHandler = () => {
79
+ logger.info('Received SIGTERM, shutting down gracefully');
80
+ this.httpServer?.close(() => {
81
+ logger.info('HTTP server closed');
82
+ process.exit(0);
83
+ });
84
+ };
85
+ process.on('SIGTERM', this.shutdownHandler);
86
+ }
87
+ });
88
+ }
89
+ /**
90
+ * Stop the HTTP server gracefully
91
+ */
92
+ async stop() {
93
+ if (this.httpServer) {
94
+ return new Promise((resolve) => {
95
+ this.httpServer.close(() => {
96
+ logger.info('HTTP server stopped');
97
+ this.httpServer = undefined;
98
+ this.actualPort = undefined;
99
+ resolve();
100
+ });
101
+ });
102
+ }
103
+ }
104
+ /**
105
+ * Get actual listening port (useful for tests)
106
+ */
107
+ getActualPort() {
108
+ return this.actualPort;
109
+ }
110
+ /**
111
+ * Get HTTP transport instance
112
+ */
113
+ getTransport() {
114
+ return this.httpTransport;
115
+ }
116
+ /**
117
+ * Cleanup method for tests - remove event listeners
118
+ */
119
+ cleanup() {
120
+ if (this.shutdownHandler) {
121
+ process.removeListener('SIGTERM', this.shutdownHandler);
122
+ this.shutdownHandler = undefined;
123
+ }
124
+ }
125
+ /**
126
+ * Secure CORS implementation
127
+ */
128
+ handleCORS(req, res, next) {
129
+ const origin = req.headers.origin;
130
+ const isProduction = process.env.NODE_ENV === 'production';
131
+ // Define safe default origins for development
132
+ const defaultDevOrigins = [
133
+ 'http://localhost:3000',
134
+ 'http://127.0.0.1:3000',
135
+ 'http://localhost:8080',
136
+ 'http://127.0.0.1:8080',
137
+ 'http://localhost:3001',
138
+ 'http://127.0.0.1:3001'
139
+ ];
140
+ // Get allowed origins from config or use defaults
141
+ const allowedOrigins = this.config.corsOrigins || defaultDevOrigins;
142
+ const allowWildcard = this.config.allowCORSWildcard === true && !isProduction;
143
+ // Determine if origin is allowed
144
+ let allowedOrigin = null;
145
+ if (allowWildcard) {
146
+ // Only in development with explicit opt-in
147
+ allowedOrigin = '*';
148
+ logger.warn("⚠️ Using wildcard CORS - only safe in development!");
149
+ }
150
+ else if (!origin) {
151
+ // No origin header (same-origin or direct server access)
152
+ allowedOrigin = defaultDevOrigins[0]; // Default fallback
153
+ }
154
+ else if (allowedOrigins.includes(origin)) {
155
+ // Explicitly allowed origin
156
+ allowedOrigin = origin;
157
+ }
158
+ else {
159
+ // Rejected origin
160
+ logger.warn(`🚫 CORS rejected origin: ${origin}`);
161
+ allowedOrigin = null;
162
+ }
163
+ // Set headers only if origin is allowed
164
+ if (allowedOrigin) {
165
+ res.header('Access-Control-Allow-Origin', allowedOrigin);
166
+ res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
167
+ res.header('Access-Control-Allow-Headers', 'Content-Type, Mcp-Session-Id');
168
+ res.header('Access-Control-Allow-Credentials', 'false'); // Explicit false
169
+ }
170
+ if (req.method === 'OPTIONS') {
171
+ if (allowedOrigin) {
172
+ res.sendStatus(200);
173
+ }
174
+ else {
175
+ res.sendStatus(403); // Forbidden for disallowed origins
176
+ }
177
+ return;
178
+ }
179
+ next();
180
+ }
181
+ }
182
+ //# sourceMappingURL=http-transport.js.map