@dotmcp/tunnel 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/bin/dotmcp-tunnel.js +2 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +39 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +65 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +15 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +37 -0
- package/dist/logger.js.map +1 -0
- package/dist/process-manager.d.ts +22 -0
- package/dist/process-manager.d.ts.map +1 -0
- package/dist/process-manager.js +146 -0
- package/dist/process-manager.js.map +1 -0
- package/dist/relay-client.d.ts +33 -0
- package/dist/relay-client.d.ts.map +1 -0
- package/dist/relay-client.js +141 -0
- package/dist/relay-client.js.map +1 -0
- package/dist/tunnel.d.ts +21 -0
- package/dist/tunnel.d.ts.map +1 -0
- package/dist/tunnel.js +122 -0
- package/dist/tunnel.js.map +1 -0
- package/package.json +47 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tunnel Configuration Types and Validation
|
|
3
|
+
*/
|
|
4
|
+
export interface ServerConfig {
|
|
5
|
+
id: string;
|
|
6
|
+
command?: string;
|
|
7
|
+
args?: string[];
|
|
8
|
+
url?: string;
|
|
9
|
+
env?: Record<string, string>;
|
|
10
|
+
cwd?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface TunnelConfig {
|
|
13
|
+
key: string;
|
|
14
|
+
servers: ServerConfig[];
|
|
15
|
+
relay?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ValidationResult {
|
|
18
|
+
valid: boolean;
|
|
19
|
+
errors: string[];
|
|
20
|
+
}
|
|
21
|
+
export declare function validateConfig(config: TunnelConfig): ValidationResult;
|
|
22
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,gBAAgB,CA+BrE"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Tunnel Configuration Types and Validation
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.validateConfig = validateConfig;
|
|
7
|
+
function validateConfig(config) {
|
|
8
|
+
const errors = [];
|
|
9
|
+
if (!config.key) {
|
|
10
|
+
errors.push('Missing required field: key');
|
|
11
|
+
}
|
|
12
|
+
else if (!config.key.startsWith('dott_')) {
|
|
13
|
+
errors.push('Invalid key format: must start with "dott_"');
|
|
14
|
+
}
|
|
15
|
+
if (!config.servers || !Array.isArray(config.servers)) {
|
|
16
|
+
errors.push('Missing required field: servers (must be an array)');
|
|
17
|
+
}
|
|
18
|
+
else if (config.servers.length === 0) {
|
|
19
|
+
errors.push('At least one server must be configured');
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
config.servers.forEach((server, idx) => {
|
|
23
|
+
if (!server.id) {
|
|
24
|
+
errors.push(`Server ${idx}: missing required field: id`);
|
|
25
|
+
}
|
|
26
|
+
if (!server.command && !server.url) {
|
|
27
|
+
errors.push(`Server ${idx} (${server.id || 'unnamed'}): must specify either command or url`);
|
|
28
|
+
}
|
|
29
|
+
if (server.command && server.url) {
|
|
30
|
+
errors.push(`Server ${idx} (${server.id || 'unnamed'}): cannot specify both command and url`);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
valid: errors.length === 0,
|
|
36
|
+
errors
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAsBH,wCA+BC;AA/BD,SAAgB,cAAc,CAAC,MAAoB;IAC/C,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACd,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC/C,CAAC;SAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;IAC/D,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;IACtE,CAAC;SAAM,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IAC1D,CAAC;SAAM,CAAC;QACJ,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;YACnC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG,8BAA8B,CAAC,CAAC;YAC7D,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;gBACjC,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG,KAAK,MAAM,CAAC,EAAE,IAAI,SAAS,uCAAuC,CAAC,CAAC;YACjG,CAAC;YACD,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;gBAC/B,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG,KAAK,MAAM,CAAC,EAAE,IAAI,SAAS,wCAAwC,CAAC,CAAC;YAClG,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED,OAAO;QACH,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;QAC1B,MAAM;KACT,CAAC;AACN,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* dotMCP Tunnel - CLI Entry Point
|
|
4
|
+
*
|
|
5
|
+
* A daemon that connects local MCP servers to dotmcp.io
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
const commander_1 = require("commander");
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const yaml_1 = require("yaml");
|
|
11
|
+
const tunnel_1 = require("./tunnel");
|
|
12
|
+
const config_1 = require("./config");
|
|
13
|
+
const logger_1 = require("./logger");
|
|
14
|
+
const logger = new logger_1.Logger();
|
|
15
|
+
const program = new commander_1.Command();
|
|
16
|
+
program
|
|
17
|
+
.name('dotmcp-tunnel')
|
|
18
|
+
.description('Connect local MCP servers to dotmcp.io')
|
|
19
|
+
.version('1.0.0');
|
|
20
|
+
program
|
|
21
|
+
.option('-c, --config <path>', 'Path to config file', '~/.dotmcp/tunnel.yaml')
|
|
22
|
+
.option('-v, --verbose', 'Enable verbose logging')
|
|
23
|
+
.action(async (options) => {
|
|
24
|
+
const configPath = options.config.replace('~', process.env.HOME || '');
|
|
25
|
+
if (!(0, fs_1.existsSync)(configPath)) {
|
|
26
|
+
logger.error(`Config file not found: ${configPath}`);
|
|
27
|
+
logger.info('\nCreate a config file with the following format:');
|
|
28
|
+
logger.info(`
|
|
29
|
+
key: "dott_your_tunnel_key_here"
|
|
30
|
+
|
|
31
|
+
servers:
|
|
32
|
+
- id: "my-server"
|
|
33
|
+
command: "npx"
|
|
34
|
+
args: ["-y", "@modelcontextprotocol/server-everything"]
|
|
35
|
+
`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const configContent = (0, fs_1.readFileSync)(configPath, 'utf-8');
|
|
40
|
+
const config = (0, yaml_1.parse)(configContent);
|
|
41
|
+
const validation = (0, config_1.validateConfig)(config);
|
|
42
|
+
if (!validation.valid) {
|
|
43
|
+
logger.error('Invalid config:');
|
|
44
|
+
validation.errors.forEach(e => logger.error(` - ${e}`));
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
logger.info('Starting dotmcp-tunnel...');
|
|
48
|
+
const tunnel = new tunnel_1.Tunnel(config, logger, options.verbose || false);
|
|
49
|
+
// Handle shutdown signals
|
|
50
|
+
const shutdown = async () => {
|
|
51
|
+
logger.info('\nShutting down...');
|
|
52
|
+
await tunnel.stop();
|
|
53
|
+
process.exit(0);
|
|
54
|
+
};
|
|
55
|
+
process.on('SIGINT', shutdown);
|
|
56
|
+
process.on('SIGTERM', shutdown);
|
|
57
|
+
await tunnel.start();
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
logger.error(`Failed to start: ${error.message}`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
program.parse(process.argv);
|
|
65
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAEH,yCAAoC;AACpC,2BAA8C;AAC9C,+BAA0C;AAC1C,qCAAkC;AAClC,qCAAwD;AACxD,qCAAkC;AAElC,MAAM,MAAM,GAAG,IAAI,eAAM,EAAE,CAAC;AAE5B,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACF,IAAI,CAAC,eAAe,CAAC;KACrB,WAAW,CAAC,wCAAwC,CAAC;KACrD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,OAAO;KACF,MAAM,CAAC,qBAAqB,EAAE,qBAAqB,EAAE,uBAAuB,CAAC;KAC7E,MAAM,CAAC,eAAe,EAAE,wBAAwB,CAAC;KACjD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACtB,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAEvE,IAAI,CAAC,IAAA,eAAU,EAAC,UAAU,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,0BAA0B,UAAU,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;QACjE,MAAM,CAAC,IAAI,CAAC;;;;;;;CAOvB,CAAC,CAAC;QACS,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,IAAI,CAAC;QACD,MAAM,aAAa,GAAG,IAAA,iBAAY,EAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,MAAM,GAAiB,IAAA,YAAS,EAAC,aAAa,CAAC,CAAC;QAEtD,MAAM,UAAU,GAAG,IAAA,uBAAc,EAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YACpB,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAChC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;YACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QAEzC,MAAM,MAAM,GAAG,IAAI,eAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC,CAAC;QAEpE,0BAA0B;QAC1B,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;YACxB,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YAClC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC,CAAC;QAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAEhC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IAEzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,oBAAqB,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC,CAAC,CAAC;AAEP,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple Logger for Tunnel CLI
|
|
3
|
+
*/
|
|
4
|
+
export declare class Logger {
|
|
5
|
+
private verbose;
|
|
6
|
+
setVerbose(verbose: boolean): void;
|
|
7
|
+
info(message: string): void;
|
|
8
|
+
success(message: string): void;
|
|
9
|
+
error(message: string): void;
|
|
10
|
+
warn(message: string): void;
|
|
11
|
+
debug(message: string): void;
|
|
12
|
+
serverLog(serverId: string, message: string): void;
|
|
13
|
+
serverError(serverId: string, message: string): void;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,MAAM;IACf,OAAO,CAAC,OAAO,CAAS;IAExB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI9B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI5B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAM5B,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAIlD,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;CAGvD"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Simple Logger for Tunnel CLI
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Logger = void 0;
|
|
7
|
+
class Logger {
|
|
8
|
+
verbose = false;
|
|
9
|
+
setVerbose(verbose) {
|
|
10
|
+
this.verbose = verbose;
|
|
11
|
+
}
|
|
12
|
+
info(message) {
|
|
13
|
+
console.log(`[tunnel] ${message}`);
|
|
14
|
+
}
|
|
15
|
+
success(message) {
|
|
16
|
+
console.log(`[tunnel] ✓ ${message}`);
|
|
17
|
+
}
|
|
18
|
+
error(message) {
|
|
19
|
+
console.error(`[tunnel] ✗ ${message}`);
|
|
20
|
+
}
|
|
21
|
+
warn(message) {
|
|
22
|
+
console.warn(`[tunnel] ⚠ ${message}`);
|
|
23
|
+
}
|
|
24
|
+
debug(message) {
|
|
25
|
+
if (this.verbose) {
|
|
26
|
+
console.log(`[tunnel] [debug] ${message}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
serverLog(serverId, message) {
|
|
30
|
+
console.log(`[tunnel:${serverId}] ${message}`);
|
|
31
|
+
}
|
|
32
|
+
serverError(serverId, message) {
|
|
33
|
+
console.error(`[tunnel:${serverId}] ✗ ${message}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.Logger = Logger;
|
|
37
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,MAAa,MAAM;IACP,OAAO,GAAG,KAAK,CAAC;IAExB,UAAU,CAAC,OAAgB;QACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED,IAAI,CAAC,OAAe;QAChB,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,OAAe;QACnB,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,OAAe;QACjB,OAAO,CAAC,KAAK,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,CAAC,OAAe;QAChB,OAAO,CAAC,IAAI,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,OAAe;QACjB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;QAC/C,CAAC;IACL,CAAC;IAED,SAAS,CAAC,QAAgB,EAAE,OAAe;QACvC,OAAO,CAAC,GAAG,CAAC,WAAW,QAAQ,KAAK,OAAO,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,WAAW,CAAC,QAAgB,EAAE,OAAe;QACzC,OAAO,CAAC,KAAK,CAAC,WAAW,QAAQ,OAAO,OAAO,EAAE,CAAC,CAAC;IACvD,CAAC;CACJ;AApCD,wBAoCC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages spawning and communication with local MCP server processes via stdio.
|
|
5
|
+
*/
|
|
6
|
+
import { ServerConfig } from './config.js';
|
|
7
|
+
import { Logger } from './logger.js';
|
|
8
|
+
export declare class ProcessManager {
|
|
9
|
+
private config;
|
|
10
|
+
private logger;
|
|
11
|
+
private process;
|
|
12
|
+
private pendingRequests;
|
|
13
|
+
private buffer;
|
|
14
|
+
private running;
|
|
15
|
+
constructor(config: ServerConfig, logger: Logger);
|
|
16
|
+
start(): Promise<void>;
|
|
17
|
+
private handleStdout;
|
|
18
|
+
private handleResponse;
|
|
19
|
+
sendRequest(request: any): Promise<any>;
|
|
20
|
+
stop(): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=process-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-manager.d.ts","sourceRoot":"","sources":["../src/process-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,qBAAa,cAAc;IACvB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,eAAe,CAGR;IACf,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM;IAK1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAwD5B,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,cAAc;IAehB,WAAW,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IA+BvC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAuB9B"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Process Manager
|
|
4
|
+
*
|
|
5
|
+
* Manages spawning and communication with local MCP server processes via stdio.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.ProcessManager = void 0;
|
|
9
|
+
const child_process_1 = require("child_process");
|
|
10
|
+
class ProcessManager {
|
|
11
|
+
config;
|
|
12
|
+
logger;
|
|
13
|
+
process = null;
|
|
14
|
+
pendingRequests = new Map();
|
|
15
|
+
buffer = '';
|
|
16
|
+
running = false;
|
|
17
|
+
constructor(config, logger) {
|
|
18
|
+
this.config = config;
|
|
19
|
+
this.logger = logger;
|
|
20
|
+
}
|
|
21
|
+
async start() {
|
|
22
|
+
if (!this.config.command) {
|
|
23
|
+
throw new Error('No command specified');
|
|
24
|
+
}
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
this.logger.serverLog(this.config.id, `Starting: ${this.config.command} ${(this.config.args || []).join(' ')}`);
|
|
27
|
+
this.process = (0, child_process_1.spawn)(this.config.command, this.config.args || [], {
|
|
28
|
+
cwd: this.config.cwd,
|
|
29
|
+
env: { ...process.env, ...this.config.env },
|
|
30
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
31
|
+
});
|
|
32
|
+
this.running = true;
|
|
33
|
+
// Handle stdout (JSON-RPC responses from MCP server)
|
|
34
|
+
this.process.stdout?.on('data', (data) => {
|
|
35
|
+
this.handleStdout(data.toString());
|
|
36
|
+
});
|
|
37
|
+
// Handle stderr (logs from MCP server)
|
|
38
|
+
this.process.stderr?.on('data', (data) => {
|
|
39
|
+
const lines = data.toString().trim().split('\n');
|
|
40
|
+
lines.forEach((line) => {
|
|
41
|
+
this.logger.debug(`[${this.config.id}:stderr] ${line}`);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
this.process.on('error', (error) => {
|
|
45
|
+
this.logger.serverError(this.config.id, `Process error: ${error.message}`);
|
|
46
|
+
reject(error);
|
|
47
|
+
});
|
|
48
|
+
this.process.on('close', (code) => {
|
|
49
|
+
this.running = false;
|
|
50
|
+
if (code !== 0 && code !== null) {
|
|
51
|
+
this.logger.serverError(this.config.id, `Process exited with code ${code}`);
|
|
52
|
+
}
|
|
53
|
+
// Reject all pending requests
|
|
54
|
+
for (const [id, pending] of this.pendingRequests) {
|
|
55
|
+
pending.reject(new Error('Process terminated'));
|
|
56
|
+
}
|
|
57
|
+
this.pendingRequests.clear();
|
|
58
|
+
});
|
|
59
|
+
// Give the process a moment to start
|
|
60
|
+
setTimeout(() => {
|
|
61
|
+
if (this.running) {
|
|
62
|
+
resolve();
|
|
63
|
+
}
|
|
64
|
+
}, 500);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
handleStdout(data) {
|
|
68
|
+
this.buffer += data;
|
|
69
|
+
// Try to parse complete JSON-RPC messages (newline-delimited)
|
|
70
|
+
const lines = this.buffer.split('\n');
|
|
71
|
+
this.buffer = lines.pop() || '';
|
|
72
|
+
for (const line of lines) {
|
|
73
|
+
if (!line.trim())
|
|
74
|
+
continue;
|
|
75
|
+
try {
|
|
76
|
+
const message = JSON.parse(line);
|
|
77
|
+
this.handleResponse(message);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
this.logger.debug(`[${this.config.id}:stdout] ${line}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
handleResponse(message) {
|
|
85
|
+
if (message.id !== undefined) {
|
|
86
|
+
const pending = this.pendingRequests.get(message.id);
|
|
87
|
+
if (pending) {
|
|
88
|
+
this.pendingRequests.delete(message.id);
|
|
89
|
+
if (message.error) {
|
|
90
|
+
pending.reject(new Error(message.error.message || 'Unknown error'));
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
pending.resolve(message);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async sendRequest(request) {
|
|
99
|
+
if (!this.process || !this.running) {
|
|
100
|
+
throw new Error('Process not running');
|
|
101
|
+
}
|
|
102
|
+
return new Promise((resolve, reject) => {
|
|
103
|
+
const id = request.id;
|
|
104
|
+
// Set timeout for request
|
|
105
|
+
const timeout = setTimeout(() => {
|
|
106
|
+
this.pendingRequests.delete(id);
|
|
107
|
+
reject(new Error('Request timeout'));
|
|
108
|
+
}, 30000);
|
|
109
|
+
this.pendingRequests.set(id, {
|
|
110
|
+
resolve: (value) => {
|
|
111
|
+
clearTimeout(timeout);
|
|
112
|
+
resolve(value);
|
|
113
|
+
},
|
|
114
|
+
reject: (error) => {
|
|
115
|
+
clearTimeout(timeout);
|
|
116
|
+
reject(error);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
// Write request to stdin
|
|
120
|
+
const message = JSON.stringify(request) + '\n';
|
|
121
|
+
this.process.stdin?.write(message);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
async stop() {
|
|
125
|
+
if (this.process && this.running) {
|
|
126
|
+
this.logger.serverLog(this.config.id, 'Stopping process...');
|
|
127
|
+
// Try graceful shutdown first
|
|
128
|
+
this.process.kill('SIGTERM');
|
|
129
|
+
// Force kill after timeout
|
|
130
|
+
await new Promise((resolve) => {
|
|
131
|
+
const timeout = setTimeout(() => {
|
|
132
|
+
if (this.process && this.running) {
|
|
133
|
+
this.process.kill('SIGKILL');
|
|
134
|
+
}
|
|
135
|
+
resolve();
|
|
136
|
+
}, 5000);
|
|
137
|
+
this.process.on('close', () => {
|
|
138
|
+
clearTimeout(timeout);
|
|
139
|
+
resolve();
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
exports.ProcessManager = ProcessManager;
|
|
146
|
+
//# sourceMappingURL=process-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-manager.js","sourceRoot":"","sources":["../src/process-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Relay Client
|
|
3
|
+
*
|
|
4
|
+
* Manages WebSocket connection to dotmcp.io relay server.
|
|
5
|
+
* Handles reconnection, heartbeats, and request/response routing.
|
|
6
|
+
*/
|
|
7
|
+
import { Logger } from './logger';
|
|
8
|
+
export interface RelayClientOptions {
|
|
9
|
+
serverId: string;
|
|
10
|
+
relayUrl: string;
|
|
11
|
+
tunnelKey: string;
|
|
12
|
+
logger: Logger;
|
|
13
|
+
onRequest: (request: any) => Promise<any>;
|
|
14
|
+
}
|
|
15
|
+
export declare class RelayClient {
|
|
16
|
+
private options;
|
|
17
|
+
private ws;
|
|
18
|
+
private reconnectAttempts;
|
|
19
|
+
private maxReconnectAttempts;
|
|
20
|
+
private reconnectDelay;
|
|
21
|
+
private heartbeatInterval;
|
|
22
|
+
private connected;
|
|
23
|
+
private shuttingDown;
|
|
24
|
+
constructor(options: RelayClientOptions);
|
|
25
|
+
connect(): Promise<void>;
|
|
26
|
+
private handleMessage;
|
|
27
|
+
private send;
|
|
28
|
+
private startHeartbeat;
|
|
29
|
+
private stopHeartbeat;
|
|
30
|
+
private scheduleReconnect;
|
|
31
|
+
disconnect(): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=relay-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-client.d.ts","sourceRoot":"","sources":["../src/relay-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;CAC7C;AAED,qBAAa,WAAW;IACpB,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,oBAAoB,CAAM;IAClC,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAS;gBAEjB,OAAO,EAAE,kBAAkB;IAIjC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAsDhB,aAAa;IAiC3B,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,iBAAiB;IA0BnB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CASpC"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Relay Client
|
|
4
|
+
*
|
|
5
|
+
* Manages WebSocket connection to dotmcp.io relay server.
|
|
6
|
+
* Handles reconnection, heartbeats, and request/response routing.
|
|
7
|
+
*/
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.RelayClient = void 0;
|
|
13
|
+
// @ts-ignore - ws types will be installed at build time
|
|
14
|
+
const ws_1 = __importDefault(require("ws"));
|
|
15
|
+
class RelayClient {
|
|
16
|
+
options;
|
|
17
|
+
ws = null;
|
|
18
|
+
reconnectAttempts = 0;
|
|
19
|
+
maxReconnectAttempts = 10;
|
|
20
|
+
reconnectDelay = 1000;
|
|
21
|
+
heartbeatInterval = null;
|
|
22
|
+
connected = false;
|
|
23
|
+
shuttingDown = false;
|
|
24
|
+
constructor(options) {
|
|
25
|
+
this.options = options;
|
|
26
|
+
}
|
|
27
|
+
async connect() {
|
|
28
|
+
return new Promise((resolve, reject) => {
|
|
29
|
+
const url = `${this.options.relayUrl}/connect/${this.options.serverId}`;
|
|
30
|
+
this.options.logger.debug(`Connecting to ${url}`);
|
|
31
|
+
this.ws = new ws_1.default(url, {
|
|
32
|
+
headers: {
|
|
33
|
+
'X-Tunnel-Key': this.options.tunnelKey
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
this.ws.on('open', () => {
|
|
37
|
+
this.connected = true;
|
|
38
|
+
this.reconnectAttempts = 0;
|
|
39
|
+
this.startHeartbeat();
|
|
40
|
+
resolve();
|
|
41
|
+
});
|
|
42
|
+
this.ws.on('message', async (data) => {
|
|
43
|
+
try {
|
|
44
|
+
const message = JSON.parse(data.toString());
|
|
45
|
+
await this.handleMessage(message);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
this.options.logger.serverError(this.options.serverId, `Error handling message: ${error.message}`);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
this.ws.on('close', (code, reason) => {
|
|
52
|
+
this.options.logger.warn(`WebSocket closed: code=${code}, reason=${reason?.toString() || 'none'}, connected=${this.connected}`);
|
|
53
|
+
this.connected = false;
|
|
54
|
+
this.stopHeartbeat();
|
|
55
|
+
if (!this.shuttingDown) {
|
|
56
|
+
this.scheduleReconnect();
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
this.ws.on('error', (error) => {
|
|
60
|
+
this.options.logger.serverError(this.options.serverId, `WebSocket error: ${error.message}`);
|
|
61
|
+
if (!this.connected) {
|
|
62
|
+
reject(error);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
async handleMessage(message) {
|
|
68
|
+
switch (message.type) {
|
|
69
|
+
case 'connected':
|
|
70
|
+
this.options.logger.debug(`Connected with ID: ${message.connectionId}`);
|
|
71
|
+
break;
|
|
72
|
+
case 'heartbeat_ack':
|
|
73
|
+
this.options.logger.debug('Heartbeat acknowledged');
|
|
74
|
+
break;
|
|
75
|
+
case 'request':
|
|
76
|
+
// Forward request to local MCP server
|
|
77
|
+
try {
|
|
78
|
+
const response = await this.options.onRequest(message.payload);
|
|
79
|
+
this.send({
|
|
80
|
+
type: 'response',
|
|
81
|
+
requestId: message.requestId,
|
|
82
|
+
payload: response
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
this.send({
|
|
87
|
+
type: 'error',
|
|
88
|
+
requestId: message.requestId,
|
|
89
|
+
error: error.message
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
93
|
+
default:
|
|
94
|
+
this.options.logger.debug(`Unknown message type: ${message.type}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
send(message) {
|
|
98
|
+
if (this.ws && this.connected) {
|
|
99
|
+
this.ws.send(JSON.stringify(message));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
startHeartbeat() {
|
|
103
|
+
this.heartbeatInterval = setInterval(() => {
|
|
104
|
+
this.send({ type: 'heartbeat', timestamp: Date.now() });
|
|
105
|
+
}, 30000);
|
|
106
|
+
}
|
|
107
|
+
stopHeartbeat() {
|
|
108
|
+
if (this.heartbeatInterval) {
|
|
109
|
+
clearInterval(this.heartbeatInterval);
|
|
110
|
+
this.heartbeatInterval = null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
scheduleReconnect() {
|
|
114
|
+
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
115
|
+
this.options.logger.serverError(this.options.serverId, `Max reconnect attempts (${this.maxReconnectAttempts}) reached. Giving up.`);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts);
|
|
119
|
+
this.reconnectAttempts++;
|
|
120
|
+
this.options.logger.warn(`Connection lost. Reconnecting in ${delay / 1000}s (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
|
|
121
|
+
setTimeout(async () => {
|
|
122
|
+
try {
|
|
123
|
+
await this.connect();
|
|
124
|
+
this.options.logger.success(`Reconnected to relay`);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
// Will trigger another reconnect via close handler
|
|
128
|
+
}
|
|
129
|
+
}, delay);
|
|
130
|
+
}
|
|
131
|
+
async disconnect() {
|
|
132
|
+
this.shuttingDown = true;
|
|
133
|
+
this.stopHeartbeat();
|
|
134
|
+
if (this.ws) {
|
|
135
|
+
this.ws.close();
|
|
136
|
+
this.ws = null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
exports.RelayClient = RelayClient;
|
|
141
|
+
//# sourceMappingURL=relay-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-client.js","sourceRoot":"","sources":["../src/relay-client.ts"],"names":[],"mappings":"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"}
|
package/dist/tunnel.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main Tunnel Class
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates connections to relay and management of local MCP server processes.
|
|
5
|
+
*/
|
|
6
|
+
import { TunnelConfig } from './config';
|
|
7
|
+
import { Logger } from './logger';
|
|
8
|
+
export declare class Tunnel {
|
|
9
|
+
private config;
|
|
10
|
+
private logger;
|
|
11
|
+
private relayClients;
|
|
12
|
+
private processManagers;
|
|
13
|
+
private running;
|
|
14
|
+
private verbose;
|
|
15
|
+
constructor(config: TunnelConfig, logger: Logger, verbose?: boolean);
|
|
16
|
+
start(): Promise<void>;
|
|
17
|
+
private startServer;
|
|
18
|
+
private forwardToHttp;
|
|
19
|
+
stop(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=tunnel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../src/tunnel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAgB,MAAM,UAAU,CAAC;AAGtD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,qBAAa,MAAM;IACf,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAAuC;IAC3D,OAAO,CAAC,eAAe,CAA0C;IACjE,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAU;gBAEb,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,UAAQ;IAS3D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAyBd,WAAW;YAyCX,aAAa;IAcrB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CA0B9B"}
|
package/dist/tunnel.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Main Tunnel Class
|
|
4
|
+
*
|
|
5
|
+
* Orchestrates connections to relay and management of local MCP server processes.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.Tunnel = void 0;
|
|
9
|
+
const relay_client_1 = require("./relay-client");
|
|
10
|
+
const process_manager_1 = require("./process-manager");
|
|
11
|
+
class Tunnel {
|
|
12
|
+
config;
|
|
13
|
+
logger;
|
|
14
|
+
relayClients = new Map();
|
|
15
|
+
processManagers = new Map();
|
|
16
|
+
running = false;
|
|
17
|
+
verbose;
|
|
18
|
+
constructor(config, logger, verbose = false) {
|
|
19
|
+
this.config = config;
|
|
20
|
+
this.logger = logger;
|
|
21
|
+
this.verbose = verbose;
|
|
22
|
+
if (verbose) {
|
|
23
|
+
logger.setVerbose(true);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async start() {
|
|
27
|
+
this.running = true;
|
|
28
|
+
const relayUrl = this.config.relay || 'wss://relay.dotmcp.io';
|
|
29
|
+
this.logger.info(`Connecting ${this.config.servers.length} server(s) to ${relayUrl}`);
|
|
30
|
+
for (const serverConfig of this.config.servers) {
|
|
31
|
+
await this.startServer(serverConfig, relayUrl);
|
|
32
|
+
}
|
|
33
|
+
this.logger.success('All servers connected. Press Ctrl+C to stop.');
|
|
34
|
+
// Keep the process running
|
|
35
|
+
await new Promise((resolve) => {
|
|
36
|
+
const checkRunning = () => {
|
|
37
|
+
if (!this.running) {
|
|
38
|
+
resolve();
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
setTimeout(checkRunning, 1000);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
checkRunning();
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
async startServer(serverConfig, relayUrl) {
|
|
48
|
+
const { id } = serverConfig;
|
|
49
|
+
try {
|
|
50
|
+
// Start the local MCP server process (if command-based)
|
|
51
|
+
let processManager = null;
|
|
52
|
+
if (serverConfig.command) {
|
|
53
|
+
processManager = new process_manager_1.ProcessManager(serverConfig, this.logger);
|
|
54
|
+
this.processManagers.set(id, processManager);
|
|
55
|
+
await processManager.start();
|
|
56
|
+
}
|
|
57
|
+
// Create relay client for this server
|
|
58
|
+
const relayClient = new relay_client_1.RelayClient({
|
|
59
|
+
serverId: id,
|
|
60
|
+
relayUrl,
|
|
61
|
+
tunnelKey: this.config.key,
|
|
62
|
+
logger: this.logger,
|
|
63
|
+
onRequest: async (request) => {
|
|
64
|
+
// Forward request to local MCP server
|
|
65
|
+
if (processManager) {
|
|
66
|
+
return await processManager.sendRequest(request);
|
|
67
|
+
}
|
|
68
|
+
else if (serverConfig.url) {
|
|
69
|
+
// HTTP transport - forward to running server
|
|
70
|
+
return await this.forwardToHttp(serverConfig.url, request);
|
|
71
|
+
}
|
|
72
|
+
throw new Error('No transport configured');
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
this.relayClients.set(id, relayClient);
|
|
76
|
+
await relayClient.connect();
|
|
77
|
+
this.logger.success(`Server "${id}" connected`);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
this.logger.serverError(id, `Failed to start: ${error.message}`);
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async forwardToHttp(url, request) {
|
|
85
|
+
const response = await fetch(url, {
|
|
86
|
+
method: 'POST',
|
|
87
|
+
headers: { 'Content-Type': 'application/json' },
|
|
88
|
+
body: JSON.stringify(request)
|
|
89
|
+
});
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
92
|
+
}
|
|
93
|
+
return await response.json();
|
|
94
|
+
}
|
|
95
|
+
async stop() {
|
|
96
|
+
this.running = false;
|
|
97
|
+
this.logger.info('Stopping all connections...');
|
|
98
|
+
// Close relay connections
|
|
99
|
+
for (const [id, client] of this.relayClients) {
|
|
100
|
+
try {
|
|
101
|
+
await client.disconnect();
|
|
102
|
+
this.logger.debug(`Disconnected relay for ${id}`);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
this.logger.serverError(id, `Error disconnecting: ${error.message}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Stop local processes
|
|
109
|
+
for (const [id, manager] of this.processManagers) {
|
|
110
|
+
try {
|
|
111
|
+
await manager.stop();
|
|
112
|
+
this.logger.debug(`Stopped process for ${id}`);
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
this.logger.serverError(id, `Error stopping process: ${error.message}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
this.logger.success('Tunnel stopped');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.Tunnel = Tunnel;
|
|
122
|
+
//# sourceMappingURL=tunnel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel.js","sourceRoot":"","sources":["../src/tunnel.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dotmcp/tunnel",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI daemon to connect local MCP servers to dotmcp.io",
|
|
5
|
+
"author": "dotMCP <hello@dotmcp.io>",
|
|
6
|
+
"homepage": "https://dotmcp.io",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"mcp",
|
|
9
|
+
"tunnel",
|
|
10
|
+
"dotmcp",
|
|
11
|
+
"model-context-protocol"
|
|
12
|
+
],
|
|
13
|
+
"bin": {
|
|
14
|
+
"dotmcp-tunnel": "./bin/dotmcp-tunnel.js"
|
|
15
|
+
},
|
|
16
|
+
"main": "dist/index.js",
|
|
17
|
+
"types": "dist/index.d.ts",
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"dev": "ts-node src/index.ts",
|
|
21
|
+
"start": "node dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"commander": "^11.1.0",
|
|
25
|
+
"ws": "^8.14.2",
|
|
26
|
+
"yaml": "^2.3.4",
|
|
27
|
+
"chalk": "^5.3.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^20.10.0",
|
|
31
|
+
"@types/ws": "^8.5.10",
|
|
32
|
+
"typescript": "^5.3.2",
|
|
33
|
+
"ts-node": "^10.9.2"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18.0.0"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"bin"
|
|
41
|
+
],
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "https://github.com/dotmcp/tunnel"
|
|
45
|
+
},
|
|
46
|
+
"license": "BUSL-1.1"
|
|
47
|
+
}
|