@integsec/mcp-pentester-cli 1.0.3 → 1.0.5
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 +201 -12
- package/dist/index.js +54 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp-client.d.ts.map +1 -1
- package/dist/mcp-client.js +2 -2
- package/dist/mcp-client.js.map +1 -1
- package/dist/transport/http.d.ts +7 -2
- package/dist/transport/http.d.ts.map +1 -1
- package/dist/transport/http.js +57 -4
- package/dist/transport/http.js.map +1 -1
- package/dist/transport/websocket.d.ts +7 -2
- package/dist/transport/websocket.d.ts.map +1 -1
- package/dist/transport/websocket.js +95 -4
- package/dist/transport/websocket.js.map +1 -1
- package/dist/types.d.ts +18 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/tui.d.ts +11 -1
- package/dist/ui/tui.d.ts.map +1 -1
- package/dist/ui/tui.js +334 -2
- package/dist/ui/tui.js.map +1 -1
- package/examples/http-basic-auth-config.json +9 -0
- package/examples/http-bearer-auth-config.json +8 -0
- package/examples/https-bearer-proxy-config.json +17 -0
- package/examples/https-client-cert-config.json +11 -0
- package/examples/https-custom-headers-config.json +12 -0
- package/examples/websocket-bearer-auth-config.json +8 -0
- package/package.json +2 -2
|
@@ -1,23 +1,110 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
5
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
39
|
exports.WebSocketTransport = void 0;
|
|
7
40
|
const ws_1 = __importDefault(require("ws"));
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
8
42
|
const http_proxy_agent_1 = require("http-proxy-agent");
|
|
9
43
|
const https_proxy_agent_1 = require("https-proxy-agent");
|
|
10
44
|
const socks_proxy_agent_1 = require("socks-proxy-agent");
|
|
11
45
|
const base_1 = require("./base");
|
|
12
46
|
class WebSocketTransport extends base_1.Transport {
|
|
13
|
-
constructor(url, proxyConfig) {
|
|
47
|
+
constructor(url, proxyConfig, authConfig, certificateConfig, customHeaders) {
|
|
14
48
|
super();
|
|
15
49
|
this.url = url;
|
|
16
50
|
this.proxyConfig = proxyConfig;
|
|
51
|
+
this.authConfig = authConfig;
|
|
52
|
+
this.certificateConfig = certificateConfig;
|
|
53
|
+
this.authHeaders = {};
|
|
54
|
+
this.customHeaders = {};
|
|
55
|
+
this.customHeaders = customHeaders || {};
|
|
56
|
+
this.setupAuthHeaders();
|
|
17
57
|
this.setupAgent();
|
|
18
58
|
}
|
|
59
|
+
setupAuthHeaders() {
|
|
60
|
+
if (!this.authConfig) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
switch (this.authConfig.type) {
|
|
64
|
+
case 'bearer':
|
|
65
|
+
if (this.authConfig.token) {
|
|
66
|
+
this.authHeaders['Authorization'] = `Bearer ${this.authConfig.token}`;
|
|
67
|
+
}
|
|
68
|
+
break;
|
|
69
|
+
case 'basic':
|
|
70
|
+
if (this.authConfig.username && this.authConfig.password) {
|
|
71
|
+
const credentials = Buffer.from(`${this.authConfig.username}:${this.authConfig.password}`).toString('base64');
|
|
72
|
+
this.authHeaders['Authorization'] = `Basic ${credentials}`;
|
|
73
|
+
}
|
|
74
|
+
break;
|
|
75
|
+
case 'custom':
|
|
76
|
+
if (this.authConfig.headers) {
|
|
77
|
+
this.authHeaders = { ...this.authHeaders, ...this.authConfig.headers };
|
|
78
|
+
}
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
19
82
|
setupAgent() {
|
|
83
|
+
const agentOptions = {};
|
|
84
|
+
if (this.certificateConfig) {
|
|
85
|
+
if (this.certificateConfig.cert) {
|
|
86
|
+
agentOptions.cert = fs.readFileSync(this.certificateConfig.cert);
|
|
87
|
+
}
|
|
88
|
+
if (this.certificateConfig.key) {
|
|
89
|
+
agentOptions.key = fs.readFileSync(this.certificateConfig.key);
|
|
90
|
+
}
|
|
91
|
+
if (this.certificateConfig.ca) {
|
|
92
|
+
agentOptions.ca = fs.readFileSync(this.certificateConfig.ca);
|
|
93
|
+
}
|
|
94
|
+
if (this.certificateConfig.passphrase) {
|
|
95
|
+
agentOptions.passphrase = this.certificateConfig.passphrase;
|
|
96
|
+
}
|
|
97
|
+
if (this.certificateConfig.rejectUnauthorized !== undefined) {
|
|
98
|
+
agentOptions.rejectUnauthorized = this.certificateConfig.rejectUnauthorized;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
20
101
|
if (!this.proxyConfig) {
|
|
102
|
+
if (Object.keys(agentOptions).length > 0) {
|
|
103
|
+
const isSecure = this.url.startsWith('wss://');
|
|
104
|
+
if (isSecure) {
|
|
105
|
+
this.agent = new https_proxy_agent_1.HttpsProxyAgent('https://dummy', agentOptions);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
21
108
|
return;
|
|
22
109
|
}
|
|
23
110
|
const proxyAuth = this.proxyConfig.auth
|
|
@@ -26,16 +113,16 @@ class WebSocketTransport extends base_1.Transport {
|
|
|
26
113
|
const proxyProtocol = this.proxyConfig.protocol || 'http';
|
|
27
114
|
if (proxyProtocol === 'socks' || proxyProtocol === 'socks5') {
|
|
28
115
|
const proxyUrl = `socks5://${proxyAuth}${this.proxyConfig.host}:${this.proxyConfig.port}`;
|
|
29
|
-
this.agent = new socks_proxy_agent_1.SocksProxyAgent(proxyUrl);
|
|
116
|
+
this.agent = new socks_proxy_agent_1.SocksProxyAgent(proxyUrl, agentOptions);
|
|
30
117
|
}
|
|
31
118
|
else {
|
|
32
119
|
const proxyUrl = `${proxyProtocol}://${proxyAuth}${this.proxyConfig.host}:${this.proxyConfig.port}`;
|
|
33
120
|
const isSecure = this.url.startsWith('wss://');
|
|
34
121
|
if (isSecure) {
|
|
35
|
-
this.agent = new https_proxy_agent_1.HttpsProxyAgent(proxyUrl);
|
|
122
|
+
this.agent = new https_proxy_agent_1.HttpsProxyAgent(proxyUrl, agentOptions);
|
|
36
123
|
}
|
|
37
124
|
else {
|
|
38
|
-
this.agent = new http_proxy_agent_1.HttpProxyAgent(proxyUrl);
|
|
125
|
+
this.agent = new http_proxy_agent_1.HttpProxyAgent(proxyUrl, agentOptions);
|
|
39
126
|
}
|
|
40
127
|
}
|
|
41
128
|
}
|
|
@@ -45,6 +132,10 @@ class WebSocketTransport extends base_1.Transport {
|
|
|
45
132
|
if (this.agent) {
|
|
46
133
|
options.agent = this.agent;
|
|
47
134
|
}
|
|
135
|
+
const allHeaders = { ...this.customHeaders, ...this.authHeaders };
|
|
136
|
+
if (Object.keys(allHeaders).length > 0) {
|
|
137
|
+
options.headers = allHeaders;
|
|
138
|
+
}
|
|
48
139
|
this.ws = new ws_1.default(this.url, options);
|
|
49
140
|
this.ws.on('open', () => {
|
|
50
141
|
this.emit('connected');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../../src/transport/websocket.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../../src/transport/websocket.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -67,6 +67,21 @@ export interface MCPInitializeResult {
|
|
|
67
67
|
serverInfo: MCPImplementation;
|
|
68
68
|
}
|
|
69
69
|
export type TransportType = 'stdio' | 'http' | 'https' | 'ws' | 'wss';
|
|
70
|
+
export type AuthType = 'bearer' | 'basic' | 'custom';
|
|
71
|
+
export interface AuthConfig {
|
|
72
|
+
type: AuthType;
|
|
73
|
+
token?: string;
|
|
74
|
+
username?: string;
|
|
75
|
+
password?: string;
|
|
76
|
+
headers?: Record<string, string>;
|
|
77
|
+
}
|
|
78
|
+
export interface CertificateConfig {
|
|
79
|
+
cert?: string;
|
|
80
|
+
key?: string;
|
|
81
|
+
ca?: string;
|
|
82
|
+
passphrase?: string;
|
|
83
|
+
rejectUnauthorized?: boolean;
|
|
84
|
+
}
|
|
70
85
|
export interface TransportConfig {
|
|
71
86
|
type: TransportType;
|
|
72
87
|
url?: string;
|
|
@@ -74,6 +89,9 @@ export interface TransportConfig {
|
|
|
74
89
|
args?: string[];
|
|
75
90
|
env?: Record<string, string>;
|
|
76
91
|
proxy?: ProxyConfig;
|
|
92
|
+
auth?: AuthConfig;
|
|
93
|
+
certificate?: CertificateConfig;
|
|
94
|
+
headers?: Record<string, string>;
|
|
77
95
|
}
|
|
78
96
|
export interface ProxyConfig {
|
|
79
97
|
host: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,KAAK,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,KAAK,CAAC;IACf,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,GAAG,CAAC;CACZ;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,KAAK,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,GAAG,CAAC;CACd;AAGD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACjC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,KAAK,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE;QACN,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,CAAC;IACF,SAAS,CAAC,EAAE;QACV,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,CAAC;IACF,OAAO,CAAC,EAAE,EAAE,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,qBAAqB,CAAC;IACpC,UAAU,EAAE,iBAAiB,CAAC;CAC/B;AAGD,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,KAAK,CAAC;AAEtE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,aAAa,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/tui.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { MCPClient } from '../mcp-client';
|
|
2
|
+
import { TransportConfig } from '../types';
|
|
2
3
|
export declare class TUI {
|
|
3
4
|
private screen;
|
|
4
5
|
private layout;
|
|
5
6
|
private currentView;
|
|
6
7
|
private client?;
|
|
8
|
+
private currentConfig?;
|
|
7
9
|
private trafficLines;
|
|
8
10
|
private trafficPairs;
|
|
9
11
|
private activePanel;
|
|
@@ -14,7 +16,7 @@ export declare class TUI {
|
|
|
14
16
|
private showSplashScreen;
|
|
15
17
|
private createLayout;
|
|
16
18
|
private setupKeyBindings;
|
|
17
|
-
setClient(client: MCPClient): void;
|
|
19
|
+
setClient(client: MCPClient, config?: TransportConfig): void;
|
|
18
20
|
private updatePanelHighlight;
|
|
19
21
|
private showTools;
|
|
20
22
|
private showResources;
|
|
@@ -39,5 +41,13 @@ export declare class TUI {
|
|
|
39
41
|
private formatXML;
|
|
40
42
|
private formatForDisplay;
|
|
41
43
|
private showMessage;
|
|
44
|
+
private generateConfigFilename;
|
|
45
|
+
private configsAreEqual;
|
|
46
|
+
private findExistingConfig;
|
|
47
|
+
private saveConnectionConfig;
|
|
48
|
+
private getSavedConnections;
|
|
49
|
+
private getConnectionDisplayName;
|
|
50
|
+
private showSavedConnections;
|
|
51
|
+
private switchConnection;
|
|
42
52
|
}
|
|
43
53
|
//# sourceMappingURL=tui.d.ts.map
|
package/dist/ui/tui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../../src/ui/tui.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../../src/ui/tui.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAmC,eAAe,EAAE,MAAM,UAAU,CAAC;AAI5E,qBAAa,GAAG;IACd,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,MAAM,CAMZ;IAEF,OAAO,CAAC,WAAW,CAA0D;IAC7E,OAAO,CAAC,MAAM,CAAC,CAAY;IAC3B,OAAO,CAAC,aAAa,CAAC,CAAkB;IACxC,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,YAAY,CAAoE;IACxF,OAAO,CAAC,WAAW,CAA6C;IAChE,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,mBAAmB,CAAgF;IAC3G,OAAO,CAAC,cAAc,CAAS;;IAY/B,OAAO,CAAC,gBAAgB;IA6CxB,OAAO,CAAC,YAAY;IAkIpB,OAAO,CAAC,gBAAgB;IAkFxB,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,eAAe;IAwGrD,OAAO,CAAC,oBAAoB;IAoB5B,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,cAAc;IAmBtB,OAAO,CAAC,cAAc;IAmEtB,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,mBAAmB;IAgB3B,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,cAAc;IAQtB,MAAM;IAWA,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YA2B9B,mBAAmB;YAsCnB,WAAW;YA8BX,YAAY;YA2BZ,SAAS;YAqBT,iBAAiB;IAyE/B,OAAO,CAAC,SAAS;IAiCjB,OAAO,CAAC,gBAAgB;IA4CxB,OAAO,CAAC,WAAW;IAwEnB,OAAO,CAAC,sBAAsB;IAgE9B,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,kBAAkB;IA+B1B,OAAO,CAAC,oBAAoB;IAkD5B,OAAO,CAAC,mBAAmB;IA0C3B,OAAO,CAAC,wBAAwB;IAchC,OAAO,CAAC,oBAAoB;YAqEd,gBAAgB;CAqC/B"}
|
package/dist/ui/tui.js
CHANGED
|
@@ -1,10 +1,46 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
5
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
39
|
exports.TUI = void 0;
|
|
7
40
|
const blessed_1 = __importDefault(require("blessed"));
|
|
41
|
+
const mcp_client_1 = require("../mcp-client");
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
8
44
|
class TUI {
|
|
9
45
|
constructor() {
|
|
10
46
|
this.currentView = 'tools';
|
|
@@ -239,6 +275,10 @@ class TUI {
|
|
|
239
275
|
this.layout.traffic.focus();
|
|
240
276
|
this.screen.render();
|
|
241
277
|
});
|
|
278
|
+
// F6 - Show saved connections
|
|
279
|
+
this.screen.key(['f6'], () => {
|
|
280
|
+
this.showSavedConnections();
|
|
281
|
+
});
|
|
242
282
|
// Handle selection in main panel
|
|
243
283
|
this.layout.main.key(['enter'], async () => {
|
|
244
284
|
await this.handleMainSelection();
|
|
@@ -253,14 +293,21 @@ class TUI {
|
|
|
253
293
|
}
|
|
254
294
|
});
|
|
255
295
|
}
|
|
256
|
-
setClient(client) {
|
|
296
|
+
setClient(client, config) {
|
|
257
297
|
this.client = client;
|
|
298
|
+
if (config) {
|
|
299
|
+
this.currentConfig = config;
|
|
300
|
+
}
|
|
258
301
|
// Set up event handlers
|
|
259
302
|
client.on('connected', (result) => {
|
|
260
303
|
const serverName = result.serverInfo?.name || 'Unknown';
|
|
261
304
|
const serverVersion = result.serverInfo?.version || '?';
|
|
305
|
+
// Save connection config on successful connection
|
|
306
|
+
if (this.currentConfig) {
|
|
307
|
+
this.saveConnectionConfig(this.currentConfig, serverName);
|
|
308
|
+
}
|
|
262
309
|
this.layout.status.setContent(`{green-fg}Connected{/green-fg} to ${this.escapeBlessedTags(serverName)} v${serverVersion} | ` +
|
|
263
|
-
`{cyan-fg}F1{/cyan-fg}=Nav {cyan-fg}F2{/cyan-fg}=Content {cyan-fg}F3{/cyan-fg}=Traffic {cyan-fg}F4{/cyan-fg}=Close {cyan-fg}F5{/cyan-fg}=Refresh {cyan-fg}F10{/cyan-fg}=Quit | ` +
|
|
310
|
+
`{cyan-fg}F1{/cyan-fg}=Nav {cyan-fg}F2{/cyan-fg}=Content {cyan-fg}F3{/cyan-fg}=Traffic {cyan-fg}F4{/cyan-fg}=Close {cyan-fg}F5{/cyan-fg}=Refresh {cyan-fg}F6{/cyan-fg}=Connections {cyan-fg}F10{/cyan-fg}=Quit | ` +
|
|
264
311
|
`{bold}{cyan-fg}IntegSec{/cyan-fg}{/bold} {gray-fg}({green-fg}integsec.com{/green-fg}) - Need pentesting? Contact us!{/gray-fg}`);
|
|
265
312
|
this.updateCurrentView();
|
|
266
313
|
this.screen.render();
|
|
@@ -867,6 +914,291 @@ class TUI {
|
|
|
867
914
|
msg.focus();
|
|
868
915
|
this.screen.render();
|
|
869
916
|
}
|
|
917
|
+
generateConfigFilename(config, serverName) {
|
|
918
|
+
const parts = [];
|
|
919
|
+
// Add protocol/transport type
|
|
920
|
+
parts.push(config.type);
|
|
921
|
+
// Add connection details based on type
|
|
922
|
+
if (config.type === 'stdio' && config.command) {
|
|
923
|
+
// For stdio: protocol-command-arg1-arg2
|
|
924
|
+
parts.push(config.command.replace(/[^a-zA-Z0-9-_]/g, '_'));
|
|
925
|
+
if (config.args && config.args.length > 0) {
|
|
926
|
+
const firstArg = config.args[0].replace(/[^a-zA-Z0-9-_]/g, '_').substring(0, 20);
|
|
927
|
+
if (firstArg)
|
|
928
|
+
parts.push(firstArg);
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
else if (config.url) {
|
|
932
|
+
// For HTTP/WebSocket: protocol-hostname-port
|
|
933
|
+
try {
|
|
934
|
+
const url = new URL(config.url);
|
|
935
|
+
parts.push(url.hostname.replace(/[^a-zA-Z0-9-_]/g, '_'));
|
|
936
|
+
if (url.port) {
|
|
937
|
+
parts.push(`port${url.port}`);
|
|
938
|
+
}
|
|
939
|
+
if (url.pathname && url.pathname !== '/') {
|
|
940
|
+
const pathPart = url.pathname.replace(/[^a-zA-Z0-9-_]/g, '_').substring(0, 20);
|
|
941
|
+
if (pathPart)
|
|
942
|
+
parts.push(pathPart);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
catch {
|
|
946
|
+
// If URL parsing fails, use sanitized URL
|
|
947
|
+
const urlPart = config.url.replace(/[^a-zA-Z0-9-_]/g, '_').substring(0, 30);
|
|
948
|
+
if (urlPart)
|
|
949
|
+
parts.push(urlPart);
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
// Add proxy info if present
|
|
953
|
+
if (config.proxy) {
|
|
954
|
+
parts.push('proxy');
|
|
955
|
+
if (config.proxy.host) {
|
|
956
|
+
parts.push(config.proxy.host.replace(/[^a-zA-Z0-9-_]/g, '_'));
|
|
957
|
+
}
|
|
958
|
+
if (config.proxy.port) {
|
|
959
|
+
parts.push(`p${config.proxy.port}`);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
// Add auth info if present
|
|
963
|
+
if (config.auth) {
|
|
964
|
+
parts.push(config.auth.type || 'auth');
|
|
965
|
+
}
|
|
966
|
+
// Add server name (shortened)
|
|
967
|
+
const sanitizedServerName = serverName.replace(/[^a-zA-Z0-9-_]/g, '_').toLowerCase().substring(0, 20);
|
|
968
|
+
if (sanitizedServerName) {
|
|
969
|
+
parts.push(sanitizedServerName);
|
|
970
|
+
}
|
|
971
|
+
// Join parts and limit total length
|
|
972
|
+
let filename = parts.join('-');
|
|
973
|
+
if (filename.length > 100) {
|
|
974
|
+
filename = filename.substring(0, 100);
|
|
975
|
+
}
|
|
976
|
+
return `${filename}.mcp-connection.json`;
|
|
977
|
+
}
|
|
978
|
+
configsAreEqual(config1, config2) {
|
|
979
|
+
// Deep comparison of configs (excluding _saved metadata)
|
|
980
|
+
const normalize = (config) => {
|
|
981
|
+
const normalized = { ...config };
|
|
982
|
+
// Sort arrays for comparison
|
|
983
|
+
if (normalized.args) {
|
|
984
|
+
normalized.args = [...normalized.args].sort();
|
|
985
|
+
}
|
|
986
|
+
return JSON.stringify(normalized, Object.keys(normalized).sort());
|
|
987
|
+
};
|
|
988
|
+
return normalize(config1) === normalize(config2);
|
|
989
|
+
}
|
|
990
|
+
findExistingConfig(config) {
|
|
991
|
+
try {
|
|
992
|
+
const cwd = process.cwd();
|
|
993
|
+
const files = fs.readdirSync(cwd);
|
|
994
|
+
for (const file of files) {
|
|
995
|
+
if (file.endsWith('.mcp-connection.json')) {
|
|
996
|
+
try {
|
|
997
|
+
const filepath = path.join(cwd, file);
|
|
998
|
+
const content = fs.readFileSync(filepath, 'utf-8');
|
|
999
|
+
const savedConfig = JSON.parse(content);
|
|
1000
|
+
// Remove _saved metadata for comparison
|
|
1001
|
+
const { _saved, ...cleanConfig } = savedConfig;
|
|
1002
|
+
if (this.configsAreEqual(config, cleanConfig)) {
|
|
1003
|
+
return filepath;
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
catch {
|
|
1007
|
+
// Skip invalid files
|
|
1008
|
+
continue;
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
catch {
|
|
1014
|
+
// If directory read fails, return null
|
|
1015
|
+
}
|
|
1016
|
+
return null;
|
|
1017
|
+
}
|
|
1018
|
+
saveConnectionConfig(config, serverName) {
|
|
1019
|
+
try {
|
|
1020
|
+
// Check if identical config already exists
|
|
1021
|
+
const existingPath = this.findExistingConfig(config);
|
|
1022
|
+
if (existingPath) {
|
|
1023
|
+
// Update timestamp in existing file
|
|
1024
|
+
const content = fs.readFileSync(existingPath, 'utf-8');
|
|
1025
|
+
const existingConfig = JSON.parse(content);
|
|
1026
|
+
existingConfig._saved = {
|
|
1027
|
+
timestamp: new Date().toISOString(),
|
|
1028
|
+
serverName: serverName,
|
|
1029
|
+
};
|
|
1030
|
+
fs.writeFileSync(existingPath, JSON.stringify(existingConfig, null, 2), 'utf-8');
|
|
1031
|
+
this.addTrafficLine(`{yellow-fg}Connection updated:{/yellow-fg} ${path.basename(existingPath)} (no changes detected)`);
|
|
1032
|
+
this.screen.render();
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
// Generate descriptive filename
|
|
1036
|
+
const filename = this.generateConfigFilename(config, serverName);
|
|
1037
|
+
const cwd = process.cwd();
|
|
1038
|
+
const filepath = path.join(cwd, filename);
|
|
1039
|
+
// If file already exists with same name, append timestamp
|
|
1040
|
+
let finalFilepath = filepath;
|
|
1041
|
+
if (fs.existsSync(filepath)) {
|
|
1042
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
1043
|
+
const baseName = filename.replace('.mcp-connection.json', '');
|
|
1044
|
+
finalFilepath = path.join(cwd, `${baseName}-${timestamp}.mcp-connection.json`);
|
|
1045
|
+
}
|
|
1046
|
+
const configToSave = {
|
|
1047
|
+
...config,
|
|
1048
|
+
_saved: {
|
|
1049
|
+
timestamp: new Date().toISOString(),
|
|
1050
|
+
serverName: serverName,
|
|
1051
|
+
}
|
|
1052
|
+
};
|
|
1053
|
+
fs.writeFileSync(finalFilepath, JSON.stringify(configToSave, null, 2), 'utf-8');
|
|
1054
|
+
this.addTrafficLine(`{green-fg}Connection saved:{/green-fg} ${path.basename(finalFilepath)}`);
|
|
1055
|
+
this.screen.render();
|
|
1056
|
+
}
|
|
1057
|
+
catch (error) {
|
|
1058
|
+
this.addTrafficLine(`{red-fg}Failed to save connection:{/red-fg} ${error instanceof Error ? error.message : String(error)}`);
|
|
1059
|
+
this.screen.render();
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
getSavedConnections() {
|
|
1063
|
+
const connections = [];
|
|
1064
|
+
try {
|
|
1065
|
+
const cwd = process.cwd();
|
|
1066
|
+
const files = fs.readdirSync(cwd);
|
|
1067
|
+
for (const file of files) {
|
|
1068
|
+
if (file.endsWith('.mcp-connection.json')) {
|
|
1069
|
+
try {
|
|
1070
|
+
const filepath = path.join(cwd, file);
|
|
1071
|
+
const content = fs.readFileSync(filepath, 'utf-8');
|
|
1072
|
+
const config = JSON.parse(content);
|
|
1073
|
+
const serverName = config._saved?.serverName || this.getConnectionDisplayName(config);
|
|
1074
|
+
const timestamp = config._saved?.timestamp || new Date(fs.statSync(filepath).mtime).toISOString();
|
|
1075
|
+
// Remove _saved metadata for the actual config
|
|
1076
|
+
const { _saved, ...cleanConfig } = config;
|
|
1077
|
+
connections.push({
|
|
1078
|
+
filepath,
|
|
1079
|
+
config: cleanConfig,
|
|
1080
|
+
serverName,
|
|
1081
|
+
timestamp,
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
catch (error) {
|
|
1085
|
+
// Skip invalid files
|
|
1086
|
+
continue;
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
// Sort by timestamp, most recent first
|
|
1091
|
+
connections.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
|
1092
|
+
}
|
|
1093
|
+
catch (error) {
|
|
1094
|
+
// If directory read fails, return empty array
|
|
1095
|
+
}
|
|
1096
|
+
return connections;
|
|
1097
|
+
}
|
|
1098
|
+
getConnectionDisplayName(config) {
|
|
1099
|
+
if (config.type === 'stdio' && config.command) {
|
|
1100
|
+
return `${config.command} ${(config.args || []).slice(0, 2).join(' ')}`;
|
|
1101
|
+
}
|
|
1102
|
+
else if (config.url) {
|
|
1103
|
+
try {
|
|
1104
|
+
const url = new URL(config.url);
|
|
1105
|
+
return `${config.type}://${url.hostname}${url.port ? ':' + url.port : ''}`;
|
|
1106
|
+
}
|
|
1107
|
+
catch {
|
|
1108
|
+
return config.url;
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
return `${config.type} connection`;
|
|
1112
|
+
}
|
|
1113
|
+
showSavedConnections() {
|
|
1114
|
+
const connections = this.getSavedConnections();
|
|
1115
|
+
if (connections.length === 0) {
|
|
1116
|
+
this.showMessage('No Saved Connections', '{yellow-fg}No saved connections found in current directory.{/yellow-fg}\n\n' +
|
|
1117
|
+
'Connections are automatically saved when you successfully connect to a server.\n' +
|
|
1118
|
+
'Saved files use the extension: {cyan-fg}.mcp-connection.json{/cyan-fg}', 'yellow');
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
1121
|
+
const items = connections.map((conn, index) => {
|
|
1122
|
+
const date = new Date(conn.timestamp);
|
|
1123
|
+
const dateStr = date.toLocaleString();
|
|
1124
|
+
const filename = path.basename(conn.filepath, '.mcp-connection.json');
|
|
1125
|
+
// Show filename details if it contains useful info
|
|
1126
|
+
let displayName = conn.serverName;
|
|
1127
|
+
if (filename.length > 0 && filename !== conn.serverName.replace(/[^a-zA-Z0-9-_]/g, '_').toLowerCase()) {
|
|
1128
|
+
// Filename has more details, show both
|
|
1129
|
+
displayName = `${conn.serverName} - ${filename.substring(0, 40)}`;
|
|
1130
|
+
}
|
|
1131
|
+
return `${index + 1}. ${displayName}\n ${dateStr}`;
|
|
1132
|
+
});
|
|
1133
|
+
const list = blessed_1.default.list({
|
|
1134
|
+
parent: this.screen,
|
|
1135
|
+
top: 'center',
|
|
1136
|
+
left: 'center',
|
|
1137
|
+
width: '85%',
|
|
1138
|
+
height: Math.min(connections.length * 2 + 4, 20),
|
|
1139
|
+
border: {
|
|
1140
|
+
type: 'line',
|
|
1141
|
+
},
|
|
1142
|
+
style: {
|
|
1143
|
+
border: {
|
|
1144
|
+
fg: 'cyan',
|
|
1145
|
+
},
|
|
1146
|
+
selected: {
|
|
1147
|
+
bg: 'blue',
|
|
1148
|
+
},
|
|
1149
|
+
},
|
|
1150
|
+
keys: true,
|
|
1151
|
+
vi: true,
|
|
1152
|
+
items: items,
|
|
1153
|
+
label: ' Saved Connections (F4 to close, Enter to switch) ',
|
|
1154
|
+
});
|
|
1155
|
+
list.on('select', async (item, index) => {
|
|
1156
|
+
const selectedConnection = connections[index];
|
|
1157
|
+
list.destroy();
|
|
1158
|
+
this.screen.render();
|
|
1159
|
+
await this.switchConnection(selectedConnection.config, selectedConnection.filepath);
|
|
1160
|
+
});
|
|
1161
|
+
list.key(['escape', 'f4'], () => {
|
|
1162
|
+
list.destroy();
|
|
1163
|
+
this.screen.render();
|
|
1164
|
+
});
|
|
1165
|
+
list.focus();
|
|
1166
|
+
this.screen.render();
|
|
1167
|
+
}
|
|
1168
|
+
async switchConnection(config, filepath) {
|
|
1169
|
+
try {
|
|
1170
|
+
// Show loading message
|
|
1171
|
+
this.layout.status.setContent('{yellow-fg}Switching connection...{/yellow-fg}');
|
|
1172
|
+
this.screen.render();
|
|
1173
|
+
// Disconnect current client if exists
|
|
1174
|
+
if (this.client) {
|
|
1175
|
+
try {
|
|
1176
|
+
await this.client.disconnect();
|
|
1177
|
+
}
|
|
1178
|
+
catch {
|
|
1179
|
+
// Ignore disconnect errors
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
// Create new client with the saved config
|
|
1183
|
+
const newClient = new mcp_client_1.MCPClient(config);
|
|
1184
|
+
this.setClient(newClient, config);
|
|
1185
|
+
// Clear current state
|
|
1186
|
+
this.trafficLines = [];
|
|
1187
|
+
this.trafficPairs = [];
|
|
1188
|
+
this.layout.traffic.setContent('');
|
|
1189
|
+
this.layout.main.setItems([]);
|
|
1190
|
+
this.currentView = 'tools';
|
|
1191
|
+
// Connect
|
|
1192
|
+
await newClient.connect();
|
|
1193
|
+
this.addTrafficLine(`{green-fg}Switched to connection:{/green-fg} ${path.basename(filepath)}`);
|
|
1194
|
+
this.screen.render();
|
|
1195
|
+
}
|
|
1196
|
+
catch (error) {
|
|
1197
|
+
this.layout.status.setContent(`{red-fg}Failed to switch connection:{/red-fg} ${error instanceof Error ? error.message : String(error)}`);
|
|
1198
|
+
this.addTrafficLine(`{red-fg}Connection switch failed:{/red-fg} ${error instanceof Error ? error.message : String(error)}`);
|
|
1199
|
+
this.screen.render();
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
870
1202
|
}
|
|
871
1203
|
exports.TUI = TUI;
|
|
872
1204
|
//# sourceMappingURL=tui.js.map
|