@brutalist/mcp 0.8.1 → 1.0.0
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.
- package/README.md +34 -7
- package/dist/brutalist-server.d.ts +55 -16
- package/dist/brutalist-server.d.ts.map +1 -1
- package/dist/brutalist-server.js +550 -732
- package/dist/brutalist-server.js.map +1 -1
- package/dist/cli-agents.d.ts +9 -7
- package/dist/cli-agents.d.ts.map +1 -1
- package/dist/cli-agents.js +290 -202
- package/dist/cli-agents.js.map +1 -1
- package/dist/domains/argument-space.d.ts +12 -3
- package/dist/domains/argument-space.d.ts.map +1 -1
- package/dist/domains/argument-space.js +30 -23
- package/dist/domains/argument-space.js.map +1 -1
- package/dist/domains/critique-domain.d.ts +12 -0
- package/dist/domains/critique-domain.d.ts.map +1 -1
- package/dist/domains/critique-domain.js +12 -1
- package/dist/domains/critique-domain.js.map +1 -1
- package/dist/formatting/response-formatter.d.ts +43 -0
- package/dist/formatting/response-formatter.d.ts.map +1 -0
- package/dist/formatting/response-formatter.js +277 -0
- package/dist/formatting/response-formatter.js.map +1 -0
- package/dist/generators/tool-generator.d.ts.map +1 -1
- package/dist/generators/tool-generator.js +8 -6
- package/dist/generators/tool-generator.js.map +1 -1
- package/dist/handlers/tool-handler.d.ts +33 -0
- package/dist/handlers/tool-handler.d.ts.map +1 -0
- package/dist/handlers/tool-handler.js +307 -0
- package/dist/handlers/tool-handler.js.map +1 -0
- package/dist/registry/argument-spaces.js +17 -17
- package/dist/registry/argument-spaces.js.map +1 -1
- package/dist/registry/domains.d.ts +10 -0
- package/dist/registry/domains.d.ts.map +1 -1
- package/dist/registry/domains.js +153 -11
- package/dist/registry/domains.js.map +1 -1
- package/dist/system-prompts.d.ts +8 -0
- package/dist/system-prompts.d.ts.map +1 -0
- package/dist/system-prompts.js +596 -0
- package/dist/system-prompts.js.map +1 -0
- package/dist/tool-definitions.d.ts +20 -1
- package/dist/tool-definitions.d.ts.map +1 -1
- package/dist/tool-definitions.js +42 -213
- package/dist/tool-definitions.js.map +1 -1
- package/dist/tool-router.d.ts +12 -0
- package/dist/tool-router.d.ts.map +1 -0
- package/dist/tool-router.js +59 -0
- package/dist/tool-router.js.map +1 -0
- package/dist/transport/http-transport.d.ts +40 -0
- package/dist/transport/http-transport.d.ts.map +1 -0
- package/dist/transport/http-transport.js +182 -0
- package/dist/transport/http-transport.js.map +1 -0
- package/dist/types/brutalist.d.ts +1 -0
- package/dist/types/brutalist.d.ts.map +1 -1
- package/dist/types/tool-config.d.ts +4 -3
- package/dist/types/tool-config.d.ts.map +1 -1
- package/dist/types/tool-config.js +7 -6
- package/dist/types/tool-config.js.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +13 -6
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
package/dist/tool-definitions.js
CHANGED
|
@@ -1,217 +1,46 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { generateAllToolConfigs, getDomain, generateToolConfig, DOMAINS } from './registry/domains.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Tool configurations - now generated from the domain registry.
|
|
4
|
+
* This maintains backwards compatibility while eliminating duplication.
|
|
5
|
+
*
|
|
6
|
+
* LAZY LOADING: Configs are generated on first access and cached.
|
|
4
7
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
},
|
|
14
|
-
cacheKeyFields: ['targetPath', 'context', 'models', 'preferredCLI'],
|
|
15
|
-
primaryArgField: 'targetPath'
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
name: "roast_file_structure",
|
|
19
|
-
description: "Deploy brutal AI critics to systematically destroy your file organization. These agents will navigate your actual directory structure and expose every organizational disaster, naming convention failure, and structural nightmare that makes your codebase unmaintainable.",
|
|
20
|
-
analysisType: "fileStructure",
|
|
21
|
-
systemPrompt: "You are a brutal file organization critic. IMPORTANT: You have READ-ONLY access to the filesystem. You can read directory structures and file names but MUST NOT modify, move, rename, or delete anything. Every poorly named file, every misplaced module, every violation of separation of concerns is a personal insult. Find the chaos in this file structure and explain why it will cause maintenance nightmares.",
|
|
22
|
-
schemaExtensions: {
|
|
23
|
-
targetPath: z.string().describe("Directory path to analyze"),
|
|
24
|
-
depth: z.number().optional().describe("Maximum directory depth to analyze (default: 3)")
|
|
25
|
-
},
|
|
26
|
-
cacheKeyFields: ['targetPath', 'depth', 'context'],
|
|
27
|
-
primaryArgField: 'targetPath',
|
|
28
|
-
contextBuilder: (args) => `Project structure analysis (depth: ${args.depth || 3}). ${args.context || ''}`
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
name: "roast_dependencies",
|
|
32
|
-
description: "Deploy brutal AI critics to systematically destroy your dependency management. These agents will read your actual package files, analyze version conflicts, and expose every security vulnerability and compatibility nightmare in your dependency tree.",
|
|
33
|
-
analysisType: "dependencies",
|
|
34
|
-
systemPrompt: "You are a dependency management nightmare detector. IMPORTANT: You have READ-ONLY filesystem access. You can read package files and analyze dependencies but MUST NOT modify, install, or update any packages. Find every security vulnerability, version conflict, unmaintained package, and bloated dependency. Explain why this dependency tree will collapse in production.",
|
|
35
|
-
schemaExtensions: {
|
|
36
|
-
targetPath: z.string().describe("Path to package file (package.json, requirements.txt, Cargo.toml, etc.)"),
|
|
37
|
-
includeDevDeps: z.boolean().optional().describe("Include development dependencies in analysis (default: true)")
|
|
38
|
-
},
|
|
39
|
-
cacheKeyFields: ['targetPath', 'includeDevDeps', 'context'],
|
|
40
|
-
primaryArgField: 'targetPath',
|
|
41
|
-
contextBuilder: (args) => `Dependency analysis${args.includeDevDeps === false ? ' (production only)' : ''}. ${args.context || ''}`
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
name: "roast_git_history",
|
|
45
|
-
description: "Deploy brutal AI critics to systematically destroy your git history and development practices. These agents will analyze your actual commit history, branching strategy, and code evolution to expose every workflow disaster and collaboration nightmare.",
|
|
46
|
-
analysisType: "gitHistory",
|
|
47
|
-
systemPrompt: "You are a git history forensics expert who has seen every version control disaster. IMPORTANT: You have READ-ONLY access to the git repository. You can read commit history, branches, and logs but MUST NOT commit, push, merge, or modify the repository. Find the terrible commit messages, the force pushes, the merge conflicts, the development workflow failures. Explain why this git history shows a team in chaos.",
|
|
48
|
-
schemaExtensions: {
|
|
49
|
-
targetPath: z.string().describe("Git repository path to analyze"),
|
|
50
|
-
commitRange: z.string().optional().describe("Commit range to analyze (e.g., 'HEAD~10..HEAD', default: last 20 commits)")
|
|
51
|
-
},
|
|
52
|
-
cacheKeyFields: ['targetPath', 'commitRange', 'context'],
|
|
53
|
-
primaryArgField: 'targetPath',
|
|
54
|
-
contextBuilder: (args) => `Git history analysis${args.commitRange ? ` for ${args.commitRange}` : ' (last 20 commits)'}. ${args.context || ''}`
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
name: "roast_test_coverage",
|
|
58
|
-
description: "Deploy brutal AI critics to systematically destroy your testing strategy. These agents will analyze your actual test files, run coverage reports, and expose every testing gap and quality assurance nightmare that will let bugs slip into production.",
|
|
59
|
-
analysisType: "testCoverage",
|
|
60
|
-
systemPrompt: "You are a QA engineer who has seen production disasters caused by inadequate testing. IMPORTANT: You have READ-ONLY filesystem access. You can read test files and analyze coverage but MUST NOT run tests, modify test files, or execute any code. Find the untested code paths, the missing edge cases, the brittle tests, the false confidence. Explain why this testing strategy guarantees production failures.",
|
|
61
|
-
schemaExtensions: {
|
|
62
|
-
targetPath: z.string().describe("Path to test directory or test configuration file"),
|
|
63
|
-
runCoverage: z.boolean().optional().describe("Attempt to run coverage analysis (default: true)")
|
|
64
|
-
},
|
|
65
|
-
cacheKeyFields: ['targetPath', 'runCoverage', 'context'],
|
|
66
|
-
primaryArgField: 'targetPath',
|
|
67
|
-
contextBuilder: (args) => `Test coverage analysis${args.runCoverage === false ? ' (static analysis only)' : ''}. ${args.context || ''}`
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
name: "roast_idea",
|
|
71
|
-
description: "Deploy brutal AI critics to systematically destroy ANY idea - business, technical, creative, or otherwise. These critics understand the gap between imagination and reality, finding where your concept will encounter the immovable forces of the world. They are harsh about delusions but wise about what might actually survive.",
|
|
72
|
-
analysisType: "idea",
|
|
73
|
-
systemPrompt: "You are a brutal reality-checker who has watched a thousand startups die and brilliant ideas fail. Find every flaw in feasibility, every market delusion, every technical impossibility, every human factor that will kill this idea. After destroying it, grudgingly admit what tiny kernel might actually work.",
|
|
74
|
-
schemaExtensions: {
|
|
75
|
-
idea: z.string().describe("ANY idea to analyze and demolish - business, technical, creative, or otherwise"),
|
|
76
|
-
targetPath: z.string().describe("Directory context for CLI execution (can be '.' for current directory)"),
|
|
77
|
-
resources: z.string().optional().describe("Available resources (budget, team, time, skills)"),
|
|
78
|
-
timeline: z.string().optional().describe("Expected timeline or deadline")
|
|
79
|
-
},
|
|
80
|
-
cacheKeyFields: ['idea', 'targetPath', 'resources', 'timeline', 'context'],
|
|
81
|
-
primaryArgField: 'idea',
|
|
82
|
-
contextBuilder: (args) => {
|
|
83
|
-
let ctx = args.context || '';
|
|
84
|
-
if (args.resources)
|
|
85
|
-
ctx += ` Resources: ${args.resources}.`;
|
|
86
|
-
if (args.timeline)
|
|
87
|
-
ctx += ` Timeline: ${args.timeline}.`;
|
|
88
|
-
return ctx.trim();
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
name: "roast_architecture",
|
|
93
|
-
description: "Deploy brutal AI critics to systematically destroy your system architecture. These critics have watched elegant designs collapse under real load, identifying every bottleneck, cost explosion, and scaling failure that will destroy your system. They are ruthless about why this won't survive production.",
|
|
94
|
-
analysisType: "architecture",
|
|
95
|
-
systemPrompt: "You are an architect who has watched beautiful systems die under load. Find every single point of failure, every scaling bottleneck, every cost explosion, every complexity trap. Explain why this architecture will crumble when it meets reality.",
|
|
96
|
-
schemaExtensions: {
|
|
97
|
-
architecture: z.string().describe("Architecture description, diagram, or design document"),
|
|
98
|
-
targetPath: z.string().describe("Directory context for CLI execution (can be '.' for current directory)"),
|
|
99
|
-
scale: z.string().optional().describe("Expected scale/load (users, requests, data)"),
|
|
100
|
-
constraints: z.string().optional().describe("Budget, timeline, or technical constraints"),
|
|
101
|
-
deployment: z.string().optional().describe("Deployment environment and strategy")
|
|
102
|
-
},
|
|
103
|
-
cacheKeyFields: ['architecture', 'targetPath', 'scale', 'constraints', 'deployment', 'context'],
|
|
104
|
-
primaryArgField: 'architecture',
|
|
105
|
-
contextBuilder: (args) => {
|
|
106
|
-
let ctx = args.context || '';
|
|
107
|
-
if (args.scale)
|
|
108
|
-
ctx += ` Scale: ${args.scale}.`;
|
|
109
|
-
if (args.constraints)
|
|
110
|
-
ctx += ` Constraints: ${args.constraints}.`;
|
|
111
|
-
if (args.deployment)
|
|
112
|
-
ctx += ` Deployment: ${args.deployment}.`;
|
|
113
|
-
return ctx.trim();
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
name: "roast_research",
|
|
118
|
-
description: "Deploy brutal AI critics to systematically demolish your research methodology. These critics are supremely jaded peer reviewers who have rejected thousands of papers and watched countless studies fail to replicate. They find every statistical flaw, sampling bias, and reproducibility nightmare.",
|
|
119
|
-
analysisType: "research",
|
|
120
|
-
systemPrompt: "You are the harshest peer reviewer in academia. Find every methodological flaw, every statistical error, every sampling bias, every p-hacking attempt, every reproducibility crisis waiting to happen. Demolish this research with the fury of someone who has seen too much bad science.",
|
|
121
|
-
schemaExtensions: {
|
|
122
|
-
research: z.string().describe("Research description, methodology, or paper draft"),
|
|
123
|
-
targetPath: z.string().describe("Directory context for CLI execution (can be '.' for current directory)"),
|
|
124
|
-
field: z.string().optional().describe("Research field (ML, systems, theory, etc.)"),
|
|
125
|
-
claims: z.string().optional().describe("Main claims or contributions"),
|
|
126
|
-
data: z.string().optional().describe("Data sources, datasets, or experimental setup")
|
|
127
|
-
},
|
|
128
|
-
cacheKeyFields: ['research', 'targetPath', 'field', 'claims', 'data', 'context'],
|
|
129
|
-
primaryArgField: 'research',
|
|
130
|
-
contextBuilder: (args) => {
|
|
131
|
-
let ctx = args.context || '';
|
|
132
|
-
if (args.field)
|
|
133
|
-
ctx += ` Field: ${args.field}.`;
|
|
134
|
-
if (args.claims)
|
|
135
|
-
ctx += ` Claims: ${args.claims}.`;
|
|
136
|
-
if (args.data)
|
|
137
|
-
ctx += ` Data: ${args.data}.`;
|
|
138
|
-
return ctx.trim();
|
|
139
|
-
}
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
name: "roast_security",
|
|
143
|
-
description: "Deploy brutal AI critics to systematically annihilate your security design. These critics are battle-hardened penetration testers who find every authentication bypass, injection vulnerability, privilege escalation path, and social engineering opportunity that real attackers will exploit.",
|
|
144
|
-
analysisType: "security",
|
|
145
|
-
systemPrompt: "You are a penetration tester who has broken into everything. Find every authentication weakness, every injection point, every privilege escalation, every side channel, every social engineering vector. Explain how attackers will destroy this system.",
|
|
146
|
-
schemaExtensions: {
|
|
147
|
-
system: z.string().describe("System, application, or security design to analyze"),
|
|
148
|
-
targetPath: z.string().describe("Directory context for CLI execution (can be '.' for current directory)"),
|
|
149
|
-
assets: z.string().optional().describe("Critical assets or data to protect"),
|
|
150
|
-
threatModel: z.string().optional().describe("Known threats or attack vectors to consider"),
|
|
151
|
-
compliance: z.string().optional().describe("Compliance requirements (GDPR, HIPAA, etc.)")
|
|
152
|
-
},
|
|
153
|
-
cacheKeyFields: ['system', 'targetPath', 'assets', 'threatModel', 'compliance', 'context'],
|
|
154
|
-
primaryArgField: 'system',
|
|
155
|
-
contextBuilder: (args) => {
|
|
156
|
-
let ctx = args.context || '';
|
|
157
|
-
if (args.assets)
|
|
158
|
-
ctx += ` Assets: ${args.assets}.`;
|
|
159
|
-
if (args.threatModel)
|
|
160
|
-
ctx += ` Threats: ${args.threatModel}.`;
|
|
161
|
-
if (args.compliance)
|
|
162
|
-
ctx += ` Compliance: ${args.compliance}.`;
|
|
163
|
-
return ctx.trim();
|
|
164
|
-
}
|
|
165
|
-
},
|
|
166
|
-
{
|
|
167
|
-
name: "roast_product",
|
|
168
|
-
description: "Deploy brutal AI critics to systematically eviscerate your product concept. These critics are product veterans who understand why users really abandon things, finding every usability disaster, adoption barrier, and workflow failure that will drive users away in seconds.",
|
|
169
|
-
analysisType: "product",
|
|
170
|
-
systemPrompt: "You are a product critic who has watched thousands of products die. Find every UX disaster, every adoption barrier, every workflow failure, every assumption about user behavior that is wrong. Explain why users will abandon this in seconds.",
|
|
171
|
-
schemaExtensions: {
|
|
172
|
-
product: z.string().describe("Product description, features, or user experience to analyze"),
|
|
173
|
-
targetPath: z.string().describe("Directory context for CLI execution (can be '.' for current directory)"),
|
|
174
|
-
users: z.string().optional().describe("Target users or user personas"),
|
|
175
|
-
competition: z.string().optional().describe("Competitive landscape or alternatives"),
|
|
176
|
-
metrics: z.string().optional().describe("Success metrics or KPIs")
|
|
177
|
-
},
|
|
178
|
-
cacheKeyFields: ['product', 'targetPath', 'users', 'competition', 'metrics', 'context'],
|
|
179
|
-
primaryArgField: 'product',
|
|
180
|
-
contextBuilder: (args) => {
|
|
181
|
-
let ctx = args.context || '';
|
|
182
|
-
if (args.users)
|
|
183
|
-
ctx += ` Users: ${args.users}.`;
|
|
184
|
-
if (args.competition)
|
|
185
|
-
ctx += ` Competition: ${args.competition}.`;
|
|
186
|
-
if (args.metrics)
|
|
187
|
-
ctx += ` Metrics: ${args.metrics}.`;
|
|
188
|
-
return ctx.trim();
|
|
189
|
-
}
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
name: "roast_infrastructure",
|
|
193
|
-
description: "Deploy brutal AI critics to systematically obliterate your infrastructure design. These critics are grizzled site reliability engineers who find every single point of failure, scaling bottleneck, and operational nightmare that will cause outages when you least expect them.",
|
|
194
|
-
analysisType: "infrastructure",
|
|
195
|
-
systemPrompt: "You are an SRE who has been paged at 3 AM too many times. Find every single point of failure, every missing redundancy, every scaling cliff, every operational nightmare. Explain why this infrastructure will fail catastrophically.",
|
|
196
|
-
schemaExtensions: {
|
|
197
|
-
infrastructure: z.string().describe("Infrastructure setup, deployment strategy, or operations plan"),
|
|
198
|
-
targetPath: z.string().describe("Directory context for CLI execution (can be '.' for current directory)"),
|
|
199
|
-
scale: z.string().optional().describe("Expected scale and load patterns"),
|
|
200
|
-
sla: z.string().optional().describe("SLA requirements or uptime targets"),
|
|
201
|
-
budget: z.string().optional().describe("Infrastructure budget or cost constraints")
|
|
202
|
-
},
|
|
203
|
-
cacheKeyFields: ['infrastructure', 'targetPath', 'scale', 'sla', 'budget', 'context'],
|
|
204
|
-
primaryArgField: 'infrastructure',
|
|
205
|
-
contextBuilder: (args) => {
|
|
206
|
-
let ctx = args.context || '';
|
|
207
|
-
if (args.scale)
|
|
208
|
-
ctx += ` Scale: ${args.scale}.`;
|
|
209
|
-
if (args.sla)
|
|
210
|
-
ctx += ` SLA: ${args.sla}.`;
|
|
211
|
-
if (args.budget)
|
|
212
|
-
ctx += ` Budget: ${args.budget}.`;
|
|
213
|
-
return ctx.trim();
|
|
214
|
-
}
|
|
8
|
+
let _cachedToolConfigs = null;
|
|
9
|
+
/**
|
|
10
|
+
* Get all tool configurations.
|
|
11
|
+
* Uses lazy loading - configs are generated on first access and cached.
|
|
12
|
+
*/
|
|
13
|
+
export function getToolConfigs() {
|
|
14
|
+
if (!_cachedToolConfigs) {
|
|
15
|
+
_cachedToolConfigs = generateAllToolConfigs();
|
|
215
16
|
}
|
|
216
|
-
|
|
17
|
+
return _cachedToolConfigs;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get a single tool configuration by domain ID (e.g., 'codebase', 'security').
|
|
21
|
+
* More efficient when you only need one tool.
|
|
22
|
+
*/
|
|
23
|
+
export function getToolConfigByDomain(domainId) {
|
|
24
|
+
const domain = getDomain(domainId);
|
|
25
|
+
if (!domain)
|
|
26
|
+
return undefined;
|
|
27
|
+
return generateToolConfig(domain);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get available domain IDs.
|
|
31
|
+
*/
|
|
32
|
+
export function getAvailableDomains() {
|
|
33
|
+
return Object.values(DOMAINS).map(d => d.id);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Clear cached configs (for testing or dynamic reload).
|
|
37
|
+
*/
|
|
38
|
+
export function clearToolConfigCache() {
|
|
39
|
+
_cachedToolConfigs = null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* @deprecated Use getToolConfigs() for lazy loading.
|
|
43
|
+
* This eager export is kept for backwards compatibility.
|
|
44
|
+
*/
|
|
45
|
+
export const TOOL_CONFIGS = generateAllToolConfigs();
|
|
217
46
|
//# sourceMappingURL=tool-definitions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-definitions.js","sourceRoot":"","sources":["../src/tool-definitions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"tool-definitions.js","sourceRoot":"","sources":["../src/tool-definitions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGvG;;;;;GAKG;AACH,IAAI,kBAAkB,GAAwB,IAAI,CAAC;AAEnD;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,kBAAkB,GAAG,sBAAsB,EAAE,CAAC;IAChD,CAAC;IACD,OAAO,kBAAkB,CAAC;AAC5B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAgB;IACpD,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,kBAAkB,GAAG,IAAI,CAAC;AAC5B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,sBAAsB,EAAE,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ToolConfig } from './types/tool-config.js';
|
|
2
|
+
/**
|
|
3
|
+
* Filter tools by intent string.
|
|
4
|
+
* Returns top 3 most relevant tools, or all tools if no intent provided.
|
|
5
|
+
*/
|
|
6
|
+
export declare function filterToolsByIntent(intent?: string): ToolConfig[];
|
|
7
|
+
/**
|
|
8
|
+
* Get domain IDs that match an intent.
|
|
9
|
+
* Useful for logging and debugging.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getMatchingDomainIds(intent: string): string[];
|
|
12
|
+
//# sourceMappingURL=tool-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-router.d.ts","sourceRoot":"","sources":["../src/tool-router.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA6BpD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE,CA2BjE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAG7D"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { DOMAINS, generateToolConfig } from './registry/domains.js';
|
|
2
|
+
import { getToolConfigs } from './tool-definitions.js';
|
|
3
|
+
/**
|
|
4
|
+
* Calculate relevance score for a domain based on intent keywords
|
|
5
|
+
*/
|
|
6
|
+
function calculateRelevance(domain, intentWords) {
|
|
7
|
+
let score = 0;
|
|
8
|
+
// Check keywords
|
|
9
|
+
for (const keyword of domain.keywords) {
|
|
10
|
+
for (const word of intentWords) {
|
|
11
|
+
if (keyword.includes(word) || word.includes(keyword)) {
|
|
12
|
+
score += 2; // Strong match
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
// Check domain name and description
|
|
17
|
+
const domainText = `${domain.name} ${domain.description}`.toLowerCase();
|
|
18
|
+
for (const word of intentWords) {
|
|
19
|
+
if (domainText.includes(word)) {
|
|
20
|
+
score += 1; // Weak match
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return score;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Filter tools by intent string.
|
|
27
|
+
* Returns top 3 most relevant tools, or all tools if no intent provided.
|
|
28
|
+
*/
|
|
29
|
+
export function filterToolsByIntent(intent) {
|
|
30
|
+
if (!intent || intent.trim() === '') {
|
|
31
|
+
return getToolConfigs();
|
|
32
|
+
}
|
|
33
|
+
const intentLower = intent.toLowerCase();
|
|
34
|
+
const intentWords = intentLower.split(/\s+/).filter(w => w.length > 2);
|
|
35
|
+
// Score each domain
|
|
36
|
+
const scored = Object.values(DOMAINS).map(domain => ({
|
|
37
|
+
domain,
|
|
38
|
+
score: calculateRelevance(domain, intentWords)
|
|
39
|
+
}));
|
|
40
|
+
// Sort by score descending
|
|
41
|
+
scored.sort((a, b) => b.score - a.score);
|
|
42
|
+
// Take top 3 with score > 0, or return all if no matches
|
|
43
|
+
const topMatches = scored.filter(s => s.score > 0).slice(0, 3);
|
|
44
|
+
if (topMatches.length === 0) {
|
|
45
|
+
// No matches - return all tools
|
|
46
|
+
return getToolConfigs();
|
|
47
|
+
}
|
|
48
|
+
// Generate configs for matched domains
|
|
49
|
+
return topMatches.map(s => generateToolConfig(s.domain));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get domain IDs that match an intent.
|
|
53
|
+
* Useful for logging and debugging.
|
|
54
|
+
*/
|
|
55
|
+
export function getMatchingDomainIds(intent) {
|
|
56
|
+
const filtered = filterToolsByIntent(intent);
|
|
57
|
+
return filtered.map(t => t.name.replace('roast_', ''));
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=tool-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-router.js","sourceRoot":"","sources":["../src/tool-router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAa,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE/E,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD;;GAEG;AACH,SAAS,kBAAkB,CAAC,MAA4C,EAAE,WAAqB;IAC7F,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,iBAAiB;IACjB,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACtC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACrD,KAAK,IAAI,CAAC,CAAC,CAAC,eAAe;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IAED,oCAAoC;IACpC,MAAM,UAAU,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,CAAC;IACxE,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,KAAK,IAAI,CAAC,CAAC,CAAC,aAAa;QAC3B,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAe;IACjD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACpC,OAAO,cAAc,EAAE,CAAC;IAC1B,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACzC,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEvE,oBAAoB;IACpB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACnD,MAAM;QACN,KAAK,EAAE,kBAAkB,CAAC,MAAM,EAAE,WAAW,CAAC;KAC/C,CAAC,CAAC,CAAC;IAEJ,2BAA2B;IAC3B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAEzC,yDAAyD;IACzD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAE/D,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,gCAAgC;QAChC,OAAO,cAAc,EAAE,CAAC;IAC1B,CAAC;IAED,uCAAuC;IACvC,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC7C,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC"}
|
|
@@ -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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-transport.js","sourceRoot":"","sources":["../../src/transport/http-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brutalist.d.ts","sourceRoot":"","sources":["../../src/types/brutalist.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"brutalist.d.ts","sourceRoot":"","sources":["../../src/types/brutalist.ts"],"names":[],"mappings":"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"}
|