mcpflare 0.2.1
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/CHANGELOG.md +68 -0
- package/LICENSE +22 -0
- package/README.md +371 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +1617 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +19 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/mcp-handler.d.ts +34 -0
- package/dist/server/mcp-handler.d.ts.map +1 -0
- package/dist/server/mcp-handler.js +1524 -0
- package/dist/server/mcp-handler.js.map +1 -0
- package/dist/server/metrics-collector.d.ts +30 -0
- package/dist/server/metrics-collector.d.ts.map +1 -0
- package/dist/server/metrics-collector.js +85 -0
- package/dist/server/metrics-collector.js.map +1 -0
- package/dist/server/schema-converter.d.ts +9 -0
- package/dist/server/schema-converter.d.ts.map +1 -0
- package/dist/server/schema-converter.js +82 -0
- package/dist/server/schema-converter.js.map +1 -0
- package/dist/server/worker-manager.d.ts +48 -0
- package/dist/server/worker-manager.d.ts.map +1 -0
- package/dist/server/worker-manager.js +1746 -0
- package/dist/server/worker-manager.js.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/mcp.d.ts +495 -0
- package/dist/types/mcp.d.ts.map +1 -0
- package/dist/types/mcp.js +80 -0
- package/dist/types/mcp.js.map +1 -0
- package/dist/types/worker.d.ts +35 -0
- package/dist/types/worker.d.ts.map +1 -0
- package/dist/types/worker.js +2 -0
- package/dist/types/worker.js.map +1 -0
- package/dist/utils/config-manager.d.ts +64 -0
- package/dist/utils/config-manager.d.ts.map +1 -0
- package/dist/utils/config-manager.js +556 -0
- package/dist/utils/config-manager.js.map +1 -0
- package/dist/utils/env-selector.d.ts +4 -0
- package/dist/utils/env-selector.d.ts.map +1 -0
- package/dist/utils/env-selector.js +127 -0
- package/dist/utils/env-selector.js.map +1 -0
- package/dist/utils/errors.d.ts +19 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +37 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/logger.d.ts +4 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +27 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/mcp-registry.d.ts +108 -0
- package/dist/utils/mcp-registry.d.ts.map +1 -0
- package/dist/utils/mcp-registry.js +298 -0
- package/dist/utils/mcp-registry.js.map +1 -0
- package/dist/utils/progress-indicator.d.ts +14 -0
- package/dist/utils/progress-indicator.d.ts.map +1 -0
- package/dist/utils/progress-indicator.js +82 -0
- package/dist/utils/progress-indicator.js.map +1 -0
- package/dist/utils/settings-manager.d.ts +19 -0
- package/dist/utils/settings-manager.d.ts.map +1 -0
- package/dist/utils/settings-manager.js +78 -0
- package/dist/utils/settings-manager.js.map +1 -0
- package/dist/utils/token-calculator.d.ts +34 -0
- package/dist/utils/token-calculator.d.ts.map +1 -0
- package/dist/utils/token-calculator.js +167 -0
- package/dist/utils/token-calculator.js.map +1 -0
- package/dist/utils/validation.d.ts +4 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +36 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/utils/wrangler-formatter.d.ts +37 -0
- package/dist/utils/wrangler-formatter.d.ts.map +1 -0
- package/dist/utils/wrangler-formatter.js +302 -0
- package/dist/utils/wrangler-formatter.js.map +1 -0
- package/dist/worker/runtime.d.ts +34 -0
- package/dist/worker/runtime.d.ts.map +1 -0
- package/dist/worker/runtime.js +166 -0
- package/dist/worker/runtime.js.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
export function getEnvVarsFromFile() {
|
|
4
|
+
const envPath = join(process.cwd(), '.env');
|
|
5
|
+
if (!existsSync(envPath)) {
|
|
6
|
+
return {};
|
|
7
|
+
}
|
|
8
|
+
const content = readFileSync(envPath, 'utf-8');
|
|
9
|
+
const envVars = {};
|
|
10
|
+
const lines = content.split('\n');
|
|
11
|
+
for (const line of lines) {
|
|
12
|
+
const trimmed = line.trim();
|
|
13
|
+
if (!trimmed || trimmed.startsWith('#')) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
const match = trimmed.match(/^([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/);
|
|
17
|
+
if (match) {
|
|
18
|
+
const key = match[1];
|
|
19
|
+
let value = match[2];
|
|
20
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
21
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
22
|
+
value = value.slice(1, -1);
|
|
23
|
+
}
|
|
24
|
+
envVars[key] = value;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return envVars;
|
|
28
|
+
}
|
|
29
|
+
export async function selectEnvVarsInteractively(rl) {
|
|
30
|
+
const envVars = getEnvVarsFromFile();
|
|
31
|
+
const envVarKeys = Object.keys(envVars).sort();
|
|
32
|
+
const selected = {};
|
|
33
|
+
if (envVarKeys.length > 0) {
|
|
34
|
+
console.log('\n📋 Available environment variables from .env file:');
|
|
35
|
+
envVarKeys.forEach((key, index) => {
|
|
36
|
+
const value = envVars[key];
|
|
37
|
+
const masked = value.length > 8
|
|
38
|
+
? `${value.substring(0, 4)}...${value.substring(value.length - 4)}`
|
|
39
|
+
: '***';
|
|
40
|
+
const alreadySelected = selected[key] ? ' ✓' : '';
|
|
41
|
+
console.log(` ${index + 1}. ${key} = ${masked}${alreadySelected}`);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.log('\n⚠️ No environment variables found in .env file.');
|
|
46
|
+
const placeholder = '${' + 'VAR_NAME' + '}';
|
|
47
|
+
console.log(` You can still enter env vars manually or use ${placeholder} syntax.`);
|
|
48
|
+
}
|
|
49
|
+
console.log('\n💡 Options:');
|
|
50
|
+
console.log(` - Enter a number (1-${envVarKeys.length}) to select an env var`);
|
|
51
|
+
console.log(' - Enter "done" when finished');
|
|
52
|
+
console.log(' - Enter "skip" to skip env vars');
|
|
53
|
+
console.log(' - Enter "manual" to enter env vars as JSON\n');
|
|
54
|
+
while (true) {
|
|
55
|
+
const remaining = envVarKeys.filter((k) => !selected[k]);
|
|
56
|
+
if (remaining.length === 0) {
|
|
57
|
+
console.log('\n✅ All environment variables have been selected.');
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
if (remaining.length < envVarKeys.length) {
|
|
61
|
+
console.log('\n📋 Remaining environment variables:');
|
|
62
|
+
remaining.forEach((key) => {
|
|
63
|
+
const originalIndex = envVarKeys.indexOf(key) + 1;
|
|
64
|
+
const value = envVars[key];
|
|
65
|
+
const masked = value.length > 8
|
|
66
|
+
? `${value.substring(0, 4)}...${value.substring(value.length - 4)}`
|
|
67
|
+
: '***';
|
|
68
|
+
console.log(` ${originalIndex}. ${key} = ${masked}`);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const input = await new Promise((resolve) => {
|
|
72
|
+
rl.question('Select env var by number (or "done"/"skip"/"manual"): ', resolve);
|
|
73
|
+
});
|
|
74
|
+
const trimmed = input.trim();
|
|
75
|
+
const trimmedLower = trimmed.toLowerCase();
|
|
76
|
+
if (trimmedLower === 'done') {
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
if (trimmedLower === 'skip') {
|
|
80
|
+
return {};
|
|
81
|
+
}
|
|
82
|
+
if (trimmedLower === 'manual') {
|
|
83
|
+
const manualInput = await new Promise((resolve) => {
|
|
84
|
+
rl.question('Environment variables as JSON (or press Enter for none): ', resolve);
|
|
85
|
+
});
|
|
86
|
+
if (manualInput.trim()) {
|
|
87
|
+
try {
|
|
88
|
+
const parsed = JSON.parse(manualInput.trim());
|
|
89
|
+
const result = {};
|
|
90
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
91
|
+
if (typeof value === 'string' && !value.startsWith('${')) {
|
|
92
|
+
if (envVars[key]) {
|
|
93
|
+
result[key] = `\${${key}}`;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
result[key] = value;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
result[key] = value;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
catch (_error) {
|
|
106
|
+
console.error('❌ Invalid JSON. Please try again.');
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return {};
|
|
111
|
+
}
|
|
112
|
+
const num = parseInt(trimmed, 10);
|
|
113
|
+
if (Number.isNaN(num) || num < 1 || num > envVarKeys.length) {
|
|
114
|
+
console.log(`❌ Invalid number. Please enter a number between 1 and ${envVarKeys.length}, or "done"/"skip"/"manual".\n`);
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const key = envVarKeys[num - 1];
|
|
118
|
+
if (selected[key]) {
|
|
119
|
+
console.log(`⚠️ ${key} is already selected.`);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
selected[key] = `\${${key}}`;
|
|
123
|
+
console.log(`✅ Added: ${key} = \${${key}}`);
|
|
124
|
+
}
|
|
125
|
+
return selected;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=env-selector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-selector.js","sourceRoot":"","sources":["../../src/utils/env-selector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare class MCPIsolateError extends Error {
|
|
2
|
+
code: string;
|
|
3
|
+
statusCode: number;
|
|
4
|
+
details?: unknown | undefined;
|
|
5
|
+
constructor(message: string, code: string, statusCode?: number, details?: unknown | undefined);
|
|
6
|
+
}
|
|
7
|
+
export declare class ValidationError extends MCPIsolateError {
|
|
8
|
+
constructor(message: string, details?: unknown);
|
|
9
|
+
}
|
|
10
|
+
export declare class WorkerError extends MCPIsolateError {
|
|
11
|
+
constructor(message: string, details?: unknown);
|
|
12
|
+
}
|
|
13
|
+
export declare class MCPConnectionError extends MCPIsolateError {
|
|
14
|
+
constructor(message: string, details?: unknown);
|
|
15
|
+
}
|
|
16
|
+
export declare class SecurityError extends MCPIsolateError {
|
|
17
|
+
constructor(message: string, details?: unknown);
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,eAAgB,SAAQ,KAAK;IAG/B,IAAI,EAAE,MAAM;IACZ,UAAU,EAAE,MAAM;IAClB,OAAO,CAAC,EAAE,OAAO;gBAHxB,OAAO,EAAE,MAAM,EACR,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,MAAY,EACxB,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,eAAgB,SAAQ,eAAe;gBACtC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO;CAI/C;AAED,qBAAa,WAAY,SAAQ,eAAe;gBAClC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO;CAI/C;AAED,qBAAa,kBAAmB,SAAQ,eAAe;gBACzC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO;CAI/C;AAED,qBAAa,aAAc,SAAQ,eAAe;gBACpC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO;CAI/C"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export class MCPIsolateError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
statusCode;
|
|
4
|
+
details;
|
|
5
|
+
constructor(message, code, statusCode = 500, details) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.statusCode = statusCode;
|
|
9
|
+
this.details = details;
|
|
10
|
+
this.name = 'MCPIsolateError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export class ValidationError extends MCPIsolateError {
|
|
14
|
+
constructor(message, details) {
|
|
15
|
+
super(message, 'VALIDATION_ERROR', 400, details);
|
|
16
|
+
this.name = 'ValidationError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class WorkerError extends MCPIsolateError {
|
|
20
|
+
constructor(message, details) {
|
|
21
|
+
super(message, 'WORKER_ERROR', 500, details);
|
|
22
|
+
this.name = 'WorkerError';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export class MCPConnectionError extends MCPIsolateError {
|
|
26
|
+
constructor(message, details) {
|
|
27
|
+
super(message, 'MCP_CONNECTION_ERROR', 502, details);
|
|
28
|
+
this.name = 'MCPConnectionError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export class SecurityError extends MCPIsolateError {
|
|
32
|
+
constructor(message, details) {
|
|
33
|
+
super(message, 'SECURITY_ERROR', 403, details);
|
|
34
|
+
this.name = 'SecurityError';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAG/B;IACA;IACA;IAJT,YACE,OAAe,EACR,IAAY,EACZ,aAAqB,GAAG,EACxB,OAAiB;QAExB,KAAK,CAAC,OAAO,CAAC,CAAA;QAJP,SAAI,GAAJ,IAAI,CAAQ;QACZ,eAAU,GAAV,UAAU,CAAc;QACxB,YAAO,GAAP,OAAO,CAAU;QAGxB,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAA;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,eAAe;IAClD,YAAY,OAAe,EAAE,OAAiB;QAC5C,KAAK,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;QAChD,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAA;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,WAAY,SAAQ,eAAe;IAC9C,YAAY,OAAe,EAAE,OAAiB;QAC5C,KAAK,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;QAC5C,IAAI,CAAC,IAAI,GAAG,aAAa,CAAA;IAC3B,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,eAAe;IACrD,YAAY,OAAe,EAAE,OAAiB;QAC5C,KAAK,CAAC,OAAO,EAAE,sBAAsB,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;QACpD,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAA;IAClC,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,eAAe;IAChD,YAAY,OAAe,EAAE,OAAiB;QAC5C,KAAK,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;QAC9C,IAAI,CAAC,IAAI,GAAG,eAAe,CAAA;IAC7B,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AAgCvB,QAAA,IAAI,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;AAmBvB,eAAe,MAAM,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import pino from 'pino';
|
|
2
|
+
import pinoPrettyModule from 'pino-pretty';
|
|
3
|
+
const pinoPretty = pinoPrettyModule;
|
|
4
|
+
const isCLIMode = process.argv[1]?.includes('cli') || process.env.CLI_MODE === 'true';
|
|
5
|
+
const isTestEnv = process.env.NODE_ENV === 'test' ||
|
|
6
|
+
process.env.VITEST === 'true' ||
|
|
7
|
+
process.argv[1]?.includes('vitest');
|
|
8
|
+
const defaultLevel = isTestEnv ? 'silent' : isCLIMode ? 'warn' : 'info';
|
|
9
|
+
const isDevMode = process.env.NODE_ENV !== 'production' && !isTestEnv;
|
|
10
|
+
const loggerConfig = {
|
|
11
|
+
level: process.env.LOG_LEVEL || defaultLevel,
|
|
12
|
+
};
|
|
13
|
+
const isTTY = process.stderr.isTTY === true;
|
|
14
|
+
let logger;
|
|
15
|
+
if (isDevMode) {
|
|
16
|
+
logger = pino(loggerConfig, pinoPretty({
|
|
17
|
+
destination: process.stderr,
|
|
18
|
+
colorize: isTTY,
|
|
19
|
+
translateTime: 'HH:MM:ss.l',
|
|
20
|
+
ignore: 'pid,hostname',
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
logger = pino(loggerConfig, process.stderr);
|
|
25
|
+
}
|
|
26
|
+
export default logger;
|
|
27
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,gBAAgB,MAAM,aAAa,CAAA;AAI1C,MAAM,UAAU,GACd,gBAA8D,CAAA;AAIhE,MAAM,SAAS,GACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAA;AAErE,MAAM,SAAS,GACb,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM;IAC/B,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM;IAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAA;AACrC,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAA;AAGvE,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,IAAI,CAAC,SAAS,CAAA;AAIrE,MAAM,YAAY,GAAuB;IACvC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,YAAY;CAC7C,CAAA;AAKD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAA;AAC3C,IAAI,MAAmB,CAAA;AAEvB,IAAI,SAAS,EAAE,CAAC;IAGd,MAAM,GAAG,IAAI,CACX,YAAY,EACZ,UAAU,CAAC;QACT,WAAW,EAAE,OAAO,CAAC,MAAM;QAC3B,QAAQ,EAAE,KAAK;QACf,aAAa,EAAE,YAAY;QAC3B,MAAM,EAAE,cAAc;KACvB,CAAC,CACH,CAAA;AACH,CAAC;KAAM,CAAC;IAEN,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;AAC7C,CAAC;AAED,eAAe,MAAM,CAAA"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
export interface NetworkConfig {
|
|
2
|
+
enabled: boolean;
|
|
3
|
+
allowlist: string[];
|
|
4
|
+
allowLocalhost: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface FileSystemConfig {
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
readPaths: string[];
|
|
9
|
+
writePaths: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface ResourceLimits {
|
|
12
|
+
maxExecutionTimeMs: number;
|
|
13
|
+
maxMemoryMB: number;
|
|
14
|
+
maxMCPCalls: number;
|
|
15
|
+
}
|
|
16
|
+
export interface MCPSecurityConfigStored {
|
|
17
|
+
id: string;
|
|
18
|
+
mcpName: string;
|
|
19
|
+
network: NetworkConfig;
|
|
20
|
+
fileSystem: FileSystemConfig;
|
|
21
|
+
resourceLimits: ResourceLimits;
|
|
22
|
+
lastModified: string;
|
|
23
|
+
}
|
|
24
|
+
export interface MCPSecurityConfig extends MCPSecurityConfigStored {
|
|
25
|
+
isGuarded: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface MCPSchemaCacheEntry {
|
|
28
|
+
mcpName: string;
|
|
29
|
+
configHash: string;
|
|
30
|
+
tools: unknown[];
|
|
31
|
+
prompts?: unknown[];
|
|
32
|
+
toolNames: string[];
|
|
33
|
+
promptNames?: string[];
|
|
34
|
+
toolCount: number;
|
|
35
|
+
promptCount?: number;
|
|
36
|
+
typescriptApi?: string;
|
|
37
|
+
cachedAt: string;
|
|
38
|
+
}
|
|
39
|
+
export interface MCPSchemaCache {
|
|
40
|
+
[cacheKey: string]: MCPSchemaCacheEntry;
|
|
41
|
+
}
|
|
42
|
+
export interface MCPflareSettingsStored {
|
|
43
|
+
enabled: boolean;
|
|
44
|
+
defaults: Omit<MCPSecurityConfigStored, 'id' | 'mcpName' | 'lastModified'>;
|
|
45
|
+
mcpConfigs: MCPSecurityConfigStored[];
|
|
46
|
+
tokenMetricsCache?: Record<string, {
|
|
47
|
+
toolCount: number;
|
|
48
|
+
schemaChars: number;
|
|
49
|
+
estimatedTokens: number;
|
|
50
|
+
assessedAt: string;
|
|
51
|
+
}>;
|
|
52
|
+
mcpSchemaCache?: MCPSchemaCache;
|
|
53
|
+
}
|
|
54
|
+
export interface MCPflareSettings {
|
|
55
|
+
enabled: boolean;
|
|
56
|
+
defaults: Omit<MCPSecurityConfig, 'id' | 'mcpName' | 'isGuarded' | 'lastModified'>;
|
|
57
|
+
mcpConfigs: MCPSecurityConfig[];
|
|
58
|
+
tokenMetricsCache?: Record<string, {
|
|
59
|
+
toolCount: number;
|
|
60
|
+
schemaChars: number;
|
|
61
|
+
estimatedTokens: number;
|
|
62
|
+
assessedAt: string;
|
|
63
|
+
}>;
|
|
64
|
+
mcpSchemaCache?: MCPSchemaCache;
|
|
65
|
+
}
|
|
66
|
+
export interface WorkerIsolationConfig {
|
|
67
|
+
mcpName: string;
|
|
68
|
+
isGuarded: boolean;
|
|
69
|
+
outbound: {
|
|
70
|
+
allowedHosts: string[] | null;
|
|
71
|
+
allowLocalhost: boolean;
|
|
72
|
+
};
|
|
73
|
+
fileSystem: {
|
|
74
|
+
enabled: boolean;
|
|
75
|
+
readPaths: string[];
|
|
76
|
+
writePaths: string[];
|
|
77
|
+
};
|
|
78
|
+
limits: {
|
|
79
|
+
cpuMs: number;
|
|
80
|
+
memoryMB: number;
|
|
81
|
+
subrequests: number;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
declare function isMCPflareedInIDEConfig(mcpName: string): boolean;
|
|
85
|
+
export declare function getSettingsPath(): string;
|
|
86
|
+
export declare function loadSettings(): MCPflareSettings;
|
|
87
|
+
export declare function saveSettings(settings: MCPflareSettings): void;
|
|
88
|
+
export declare function toWorkerIsolationConfig(config: MCPSecurityConfig): WorkerIsolationConfig;
|
|
89
|
+
export declare function getIsolationConfigForMCP(mcpName: string): WorkerIsolationConfig | undefined;
|
|
90
|
+
export declare function getAllGuardedMCPs(): Map<string, WorkerIsolationConfig>;
|
|
91
|
+
export declare function isMCPflareed(mcpName: string): boolean;
|
|
92
|
+
export declare function createDefaultConfig(mcpName: string): MCPSecurityConfig;
|
|
93
|
+
export declare function upsertMCPConfig(config: MCPSecurityConfig): void;
|
|
94
|
+
export declare function removeMCPConfig(mcpName: string): void;
|
|
95
|
+
export declare function cleanupTokenMetricsCache(): {
|
|
96
|
+
removed: string[];
|
|
97
|
+
};
|
|
98
|
+
export declare function getCachedSchema(mcpName: string, configHash: string): MCPSchemaCacheEntry | null;
|
|
99
|
+
export declare function saveCachedSchema(entry: MCPSchemaCacheEntry): void;
|
|
100
|
+
export declare function cleanupSchemaCache(): {
|
|
101
|
+
removed: string[];
|
|
102
|
+
};
|
|
103
|
+
export declare function clearMCPSchemaCache(mcpName: string): {
|
|
104
|
+
removed: string[];
|
|
105
|
+
success: boolean;
|
|
106
|
+
};
|
|
107
|
+
export { isMCPflareedInIDEConfig as isGuardedInIDEConfig };
|
|
108
|
+
//# sourceMappingURL=mcp-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-registry.d.ts","sourceRoot":"","sources":["../../src/utils/mcp-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { ConfigManager } from './config-manager.js';
|
|
5
|
+
import logger from './logger.js';
|
|
6
|
+
const DEFAULT_SECURITY_CONFIG = {
|
|
7
|
+
network: {
|
|
8
|
+
enabled: false,
|
|
9
|
+
allowlist: [],
|
|
10
|
+
allowLocalhost: false,
|
|
11
|
+
},
|
|
12
|
+
fileSystem: {
|
|
13
|
+
enabled: false,
|
|
14
|
+
readPaths: [],
|
|
15
|
+
writePaths: [],
|
|
16
|
+
},
|
|
17
|
+
resourceLimits: {
|
|
18
|
+
maxExecutionTimeMs: 30000,
|
|
19
|
+
maxMemoryMB: 128,
|
|
20
|
+
maxMCPCalls: 100,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
const DEFAULT_SETTINGS_STORED = {
|
|
24
|
+
enabled: true,
|
|
25
|
+
defaults: DEFAULT_SECURITY_CONFIG,
|
|
26
|
+
mcpConfigs: [],
|
|
27
|
+
};
|
|
28
|
+
let configManagerInstance = null;
|
|
29
|
+
function getConfigManager() {
|
|
30
|
+
if (!configManagerInstance) {
|
|
31
|
+
configManagerInstance = new ConfigManager();
|
|
32
|
+
}
|
|
33
|
+
return configManagerInstance;
|
|
34
|
+
}
|
|
35
|
+
function isMCPflareedInIDEConfig(mcpName) {
|
|
36
|
+
const configManager = getConfigManager();
|
|
37
|
+
return configManager.isMCPDisabled(mcpName);
|
|
38
|
+
}
|
|
39
|
+
function hydrateConfig(storedConfig) {
|
|
40
|
+
return {
|
|
41
|
+
...storedConfig,
|
|
42
|
+
isGuarded: isMCPflareedInIDEConfig(storedConfig.mcpName),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function dehydrateConfig(config) {
|
|
46
|
+
const { isGuarded: _, ...stored } = config;
|
|
47
|
+
return stored;
|
|
48
|
+
}
|
|
49
|
+
export function getSettingsPath() {
|
|
50
|
+
const configDir = join(homedir(), '.mcpflare');
|
|
51
|
+
if (!existsSync(configDir)) {
|
|
52
|
+
mkdirSync(configDir, { recursive: true });
|
|
53
|
+
}
|
|
54
|
+
return join(configDir, 'settings.json');
|
|
55
|
+
}
|
|
56
|
+
export function loadSettings() {
|
|
57
|
+
const settingsPath = getSettingsPath();
|
|
58
|
+
if (!existsSync(settingsPath)) {
|
|
59
|
+
logger.debug({ settingsPath }, 'No MCPflare settings file found, using defaults');
|
|
60
|
+
return {
|
|
61
|
+
...DEFAULT_SETTINGS_STORED,
|
|
62
|
+
mcpConfigs: [],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
const content = readFileSync(settingsPath, 'utf-8');
|
|
67
|
+
const storedSettings = JSON.parse(content);
|
|
68
|
+
const hydratedConfigs = storedSettings.mcpConfigs.map(hydrateConfig);
|
|
69
|
+
const settings = {
|
|
70
|
+
...storedSettings,
|
|
71
|
+
mcpConfigs: hydratedConfigs,
|
|
72
|
+
};
|
|
73
|
+
logger.debug({ settingsPath, mcpCount: settings.mcpConfigs.length }, 'Loaded MCPflare settings');
|
|
74
|
+
return settings;
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
logger.warn({ error, settingsPath }, 'Failed to load MCPflare settings, using defaults');
|
|
78
|
+
return {
|
|
79
|
+
...DEFAULT_SETTINGS_STORED,
|
|
80
|
+
mcpConfigs: [],
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export function saveSettings(settings) {
|
|
85
|
+
const settingsPath = getSettingsPath();
|
|
86
|
+
try {
|
|
87
|
+
const storedSettings = {
|
|
88
|
+
enabled: settings.enabled,
|
|
89
|
+
defaults: settings.defaults,
|
|
90
|
+
mcpConfigs: settings.mcpConfigs.map(dehydrateConfig),
|
|
91
|
+
tokenMetricsCache: settings.tokenMetricsCache,
|
|
92
|
+
mcpSchemaCache: settings.mcpSchemaCache,
|
|
93
|
+
};
|
|
94
|
+
writeFileSync(settingsPath, JSON.stringify(storedSettings, null, 2));
|
|
95
|
+
logger.debug({ settingsPath }, 'Saved MCPflare settings');
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
logger.error({ error, settingsPath }, 'Failed to save MCPflare settings');
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export function toWorkerIsolationConfig(config) {
|
|
103
|
+
return {
|
|
104
|
+
mcpName: config.mcpName,
|
|
105
|
+
isGuarded: config.isGuarded,
|
|
106
|
+
outbound: {
|
|
107
|
+
allowedHosts: config.network.enabled && config.network.allowlist.length > 0
|
|
108
|
+
? config.network.allowlist
|
|
109
|
+
: null,
|
|
110
|
+
allowLocalhost: config.network.enabled && config.network.allowLocalhost,
|
|
111
|
+
},
|
|
112
|
+
fileSystem: {
|
|
113
|
+
enabled: config.fileSystem.enabled,
|
|
114
|
+
readPaths: config.fileSystem.readPaths,
|
|
115
|
+
writePaths: config.fileSystem.writePaths,
|
|
116
|
+
},
|
|
117
|
+
limits: {
|
|
118
|
+
cpuMs: config.resourceLimits.maxExecutionTimeMs,
|
|
119
|
+
memoryMB: config.resourceLimits.maxMemoryMB,
|
|
120
|
+
subrequests: config.resourceLimits.maxMCPCalls,
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
export function getIsolationConfigForMCP(mcpName) {
|
|
125
|
+
const settings = loadSettings();
|
|
126
|
+
if (!settings.enabled) {
|
|
127
|
+
logger.debug({ mcpName }, 'MCPflare is globally disabled');
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
const isGuarded = isMCPflareedInIDEConfig(mcpName);
|
|
131
|
+
if (!isGuarded) {
|
|
132
|
+
logger.debug({ mcpName }, 'MCP is not guarded (not in _mcpflare_disabled)');
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
const config = settings.mcpConfigs.find((c) => c.mcpName === mcpName);
|
|
136
|
+
if (!config) {
|
|
137
|
+
logger.debug({ mcpName }, 'No MCPflare config found for guarded MCP, using defaults');
|
|
138
|
+
const defaultConfig = {
|
|
139
|
+
id: `config-${mcpName}-default`,
|
|
140
|
+
mcpName,
|
|
141
|
+
isGuarded: true,
|
|
142
|
+
...settings.defaults,
|
|
143
|
+
lastModified: new Date().toISOString(),
|
|
144
|
+
};
|
|
145
|
+
return toWorkerIsolationConfig(defaultConfig);
|
|
146
|
+
}
|
|
147
|
+
return toWorkerIsolationConfig(config);
|
|
148
|
+
}
|
|
149
|
+
export function getAllGuardedMCPs() {
|
|
150
|
+
const settings = loadSettings();
|
|
151
|
+
const configs = new Map();
|
|
152
|
+
if (!settings.enabled) {
|
|
153
|
+
return configs;
|
|
154
|
+
}
|
|
155
|
+
const configManager = getConfigManager();
|
|
156
|
+
const disabledMCPs = configManager.getDisabledMCPs();
|
|
157
|
+
for (const mcpName of disabledMCPs) {
|
|
158
|
+
const config = settings.mcpConfigs.find((c) => c.mcpName === mcpName);
|
|
159
|
+
if (config) {
|
|
160
|
+
configs.set(mcpName, toWorkerIsolationConfig(config));
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
const defaultConfig = {
|
|
164
|
+
id: `config-${mcpName}-default`,
|
|
165
|
+
mcpName,
|
|
166
|
+
isGuarded: true,
|
|
167
|
+
...settings.defaults,
|
|
168
|
+
lastModified: new Date().toISOString(),
|
|
169
|
+
};
|
|
170
|
+
configs.set(mcpName, toWorkerIsolationConfig(defaultConfig));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
logger.debug({ count: configs.size }, 'Loaded guarded MCP configurations');
|
|
174
|
+
return configs;
|
|
175
|
+
}
|
|
176
|
+
export function isMCPflareed(mcpName) {
|
|
177
|
+
const settings = loadSettings();
|
|
178
|
+
if (!settings.enabled) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
return isMCPflareedInIDEConfig(mcpName);
|
|
182
|
+
}
|
|
183
|
+
export function createDefaultConfig(mcpName) {
|
|
184
|
+
const settings = loadSettings();
|
|
185
|
+
return {
|
|
186
|
+
id: `config-${mcpName}-${Date.now()}`,
|
|
187
|
+
mcpName,
|
|
188
|
+
isGuarded: isMCPflareedInIDEConfig(mcpName),
|
|
189
|
+
...settings.defaults,
|
|
190
|
+
lastModified: new Date().toISOString(),
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
export function upsertMCPConfig(config) {
|
|
194
|
+
const settings = loadSettings();
|
|
195
|
+
const existingIndex = settings.mcpConfigs.findIndex((c) => c.mcpName === config.mcpName);
|
|
196
|
+
if (existingIndex >= 0) {
|
|
197
|
+
settings.mcpConfigs[existingIndex] = config;
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
settings.mcpConfigs.push(config);
|
|
201
|
+
}
|
|
202
|
+
saveSettings(settings);
|
|
203
|
+
const actualGuarded = isMCPflareedInIDEConfig(config.mcpName);
|
|
204
|
+
logger.info({ mcpName: config.mcpName, isGuarded: actualGuarded }, 'Updated MCP configuration');
|
|
205
|
+
}
|
|
206
|
+
export function removeMCPConfig(mcpName) {
|
|
207
|
+
const settings = loadSettings();
|
|
208
|
+
settings.mcpConfigs = settings.mcpConfigs.filter((c) => c.mcpName !== mcpName);
|
|
209
|
+
if (settings.tokenMetricsCache?.[mcpName]) {
|
|
210
|
+
delete settings.tokenMetricsCache[mcpName];
|
|
211
|
+
}
|
|
212
|
+
saveSettings(settings);
|
|
213
|
+
logger.info({ mcpName }, 'Removed MCP configuration');
|
|
214
|
+
}
|
|
215
|
+
export function cleanupTokenMetricsCache() {
|
|
216
|
+
const settings = loadSettings();
|
|
217
|
+
const configManager = getConfigManager();
|
|
218
|
+
const allMCPs = configManager.getAllConfiguredMCPs();
|
|
219
|
+
const removed = [];
|
|
220
|
+
if (settings.tokenMetricsCache) {
|
|
221
|
+
for (const mcpName of Object.keys(settings.tokenMetricsCache)) {
|
|
222
|
+
if (!allMCPs[mcpName]) {
|
|
223
|
+
delete settings.tokenMetricsCache[mcpName];
|
|
224
|
+
removed.push(mcpName);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (removed.length > 0) {
|
|
228
|
+
saveSettings(settings);
|
|
229
|
+
logger.info({ removed }, 'Cleaned up stale token metrics cache entries');
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return { removed };
|
|
233
|
+
}
|
|
234
|
+
export function getCachedSchema(mcpName, configHash) {
|
|
235
|
+
const settings = loadSettings();
|
|
236
|
+
const cacheKey = `${mcpName}:${configHash}`;
|
|
237
|
+
return settings.mcpSchemaCache?.[cacheKey] || null;
|
|
238
|
+
}
|
|
239
|
+
export function saveCachedSchema(entry) {
|
|
240
|
+
const settings = loadSettings();
|
|
241
|
+
const cacheKey = `${entry.mcpName}:${entry.configHash}`;
|
|
242
|
+
if (!settings.mcpSchemaCache) {
|
|
243
|
+
settings.mcpSchemaCache = {};
|
|
244
|
+
}
|
|
245
|
+
settings.mcpSchemaCache[cacheKey] = entry;
|
|
246
|
+
saveSettings(settings);
|
|
247
|
+
logger.debug({ mcpName: entry.mcpName, cacheKey, toolCount: entry.toolCount }, 'Saved MCP schema to persistent cache');
|
|
248
|
+
}
|
|
249
|
+
export function cleanupSchemaCache() {
|
|
250
|
+
const settings = loadSettings();
|
|
251
|
+
const configManager = getConfigManager();
|
|
252
|
+
const allMCPs = configManager.getAllConfiguredMCPs() || {};
|
|
253
|
+
const removed = [];
|
|
254
|
+
if (settings.mcpSchemaCache) {
|
|
255
|
+
for (const cacheKey of Object.keys(settings.mcpSchemaCache)) {
|
|
256
|
+
const [mcpName] = cacheKey.split(':');
|
|
257
|
+
const mcpConfig = allMCPs[mcpName];
|
|
258
|
+
if (!mcpConfig) {
|
|
259
|
+
delete settings.mcpSchemaCache[cacheKey];
|
|
260
|
+
removed.push(cacheKey);
|
|
261
|
+
logger.debug({ cacheKey }, 'Removed schema cache entry for deleted MCP');
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (removed.length > 0) {
|
|
265
|
+
saveSettings(settings);
|
|
266
|
+
logger.info({ removed }, 'Cleaned up stale schema cache entries');
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return { removed };
|
|
270
|
+
}
|
|
271
|
+
export function clearMCPSchemaCache(mcpName) {
|
|
272
|
+
const settings = loadSettings();
|
|
273
|
+
const removed = [];
|
|
274
|
+
if (settings.mcpSchemaCache) {
|
|
275
|
+
for (const cacheKey of Object.keys(settings.mcpSchemaCache)) {
|
|
276
|
+
if (cacheKey.startsWith(`${mcpName}:`)) {
|
|
277
|
+
delete settings.mcpSchemaCache[cacheKey];
|
|
278
|
+
removed.push(cacheKey);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (removed.length > 0) {
|
|
282
|
+
try {
|
|
283
|
+
saveSettings(settings);
|
|
284
|
+
logger.info({ mcpName, removed }, 'Cleared schema cache entries for MCP - will re-fetch tools on next connection');
|
|
285
|
+
}
|
|
286
|
+
catch (error) {
|
|
287
|
+
logger.error({ error, mcpName, removed }, 'Failed to persist schema cache clear for MCP');
|
|
288
|
+
return { removed, success: false };
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
logger.debug({ mcpName }, 'No schema cache entries found for MCP');
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return { removed, success: true };
|
|
296
|
+
}
|
|
297
|
+
export { isMCPflareedInIDEConfig as isGuardedInIDEConfig };
|
|
298
|
+
//# sourceMappingURL=mcp-registry.js.map
|