@ankimcp/anki-mcp-server 0.18.0 → 0.18.4-tunnel
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/ankimcp.js +10 -1
- package/dist/app-config.service.d.ts +22 -0
- package/dist/app-config.service.js +79 -0
- package/dist/app-config.service.js.map +1 -0
- package/dist/app.module.d.ts +4 -2
- package/dist/app.module.js +99 -11
- package/dist/app.module.js.map +1 -1
- package/dist/bootstrap.d.ts +6 -1
- package/dist/bootstrap.js +7 -2
- package/dist/bootstrap.js.map +1 -1
- package/dist/cli/__tests__/cli-output.manual.d.ts +2 -0
- package/dist/cli/__tests__/cli-output.manual.js +13 -0
- package/dist/cli/__tests__/cli-output.manual.js.map +1 -0
- package/dist/cli/cli-output.d.ts +20 -0
- package/dist/cli/cli-output.js +69 -0
- package/dist/cli/cli-output.js.map +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +18 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +20 -6
- package/dist/cli.js.map +1 -1
- package/dist/config/config.factory.d.ts +13 -0
- package/dist/config/config.factory.js +32 -0
- package/dist/config/config.factory.js.map +1 -0
- package/dist/config/config.schema.d.ts +33 -0
- package/dist/config/config.schema.js +58 -0
- package/dist/config/config.schema.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.js +11 -0
- package/dist/config/index.js.map +1 -0
- package/dist/http/guards/origin-validation.guard.d.ts +1 -0
- package/dist/http/guards/origin-validation.guard.js +5 -3
- package/dist/http/guards/origin-validation.guard.js.map +1 -1
- package/dist/main-http.js +20 -10
- package/dist/main-http.js.map +1 -1
- package/dist/main-stdio.js +9 -9
- package/dist/main-stdio.js.map +1 -1
- package/dist/main-tunnel.d.ts +1 -0
- package/dist/main-tunnel.js +26 -0
- package/dist/main-tunnel.js.map +1 -0
- package/dist/mcp/primitives/essential/index.d.ts +1 -0
- package/dist/mcp/primitives/essential/index.js +8 -1
- package/dist/mcp/primitives/essential/index.js.map +1 -1
- package/dist/mcp/primitives/essential/tools/add-note.tool.d.ts +1 -1
- package/dist/mcp/primitives/essential/tools/collection-stats/collection-stats.tool.js +66 -36
- package/dist/mcp/primitives/essential/tools/collection-stats/collection-stats.tool.js.map +1 -1
- package/dist/mcp/primitives/essential/tools/deck-stats.tool.js +25 -8
- package/dist/mcp/primitives/essential/tools/deck-stats.tool.js.map +1 -1
- package/dist/mcp/primitives/essential/tools/deckActions/actions/deckStats.action.js +14 -7
- package/dist/mcp/primitives/essential/tools/deckActions/actions/deckStats.action.js.map +1 -1
- package/dist/mcp/primitives/essential/tools/model-field-names.tool.js +1 -1
- package/dist/mcp/primitives/essential/tools/model-field-names.tool.js.map +1 -1
- package/dist/mcp/primitives/gui/index.d.ts +1 -0
- package/dist/mcp/primitives/gui/index.js +8 -1
- package/dist/mcp/primitives/gui/index.js.map +1 -1
- package/dist/mcp/utils/deck-hierarchy.utils.d.ts +3 -0
- package/dist/mcp/utils/deck-hierarchy.utils.js +21 -0
- package/dist/mcp/utils/deck-hierarchy.utils.js.map +1 -0
- package/dist/services/ngrok.service.d.ts +1 -0
- package/dist/services/ngrok.service.js +5 -3
- package/dist/services/ngrok.service.js.map +1 -1
- package/dist/test-fixtures/mock-data.d.ts +8 -0
- package/dist/test-fixtures/mock-data.js +8 -0
- package/dist/test-fixtures/mock-data.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/tunnel/commands/index.d.ts +3 -0
- package/dist/tunnel/commands/index.js +10 -0
- package/dist/tunnel/commands/index.js.map +1 -0
- package/dist/tunnel/commands/login.command.d.ts +1 -0
- package/dist/tunnel/commands/login.command.js +108 -0
- package/dist/tunnel/commands/login.command.js.map +1 -0
- package/dist/tunnel/commands/logout.command.d.ts +1 -0
- package/dist/tunnel/commands/logout.command.js +26 -0
- package/dist/tunnel/commands/logout.command.js.map +1 -0
- package/dist/tunnel/commands/tunnel.command.d.ts +1 -0
- package/dist/tunnel/commands/tunnel.command.js +185 -0
- package/dist/tunnel/commands/tunnel.command.js.map +1 -0
- package/dist/tunnel/credentials.service.d.ts +23 -0
- package/dist/tunnel/credentials.service.js +152 -0
- package/dist/tunnel/credentials.service.js.map +1 -0
- package/dist/tunnel/device-flow.service.d.ts +46 -0
- package/dist/tunnel/device-flow.service.js +237 -0
- package/dist/tunnel/device-flow.service.js.map +1 -0
- package/dist/tunnel/in-memory.transport.d.ts +14 -0
- package/dist/tunnel/in-memory.transport.js +63 -0
- package/dist/tunnel/in-memory.transport.js.map +1 -0
- package/dist/tunnel/index.d.ts +6 -0
- package/dist/tunnel/index.js +31 -0
- package/dist/tunnel/index.js.map +1 -0
- package/dist/tunnel/tunnel-mcp.service.d.ts +15 -0
- package/dist/tunnel/tunnel-mcp.service.js +100 -0
- package/dist/tunnel/tunnel-mcp.service.js.map +1 -0
- package/dist/tunnel/tunnel.client.d.ts +60 -0
- package/dist/tunnel/tunnel.client.js +386 -0
- package/dist/tunnel/tunnel.client.js.map +1 -0
- package/dist/tunnel/tunnel.protocol.d.ts +68 -0
- package/dist/tunnel/tunnel.protocol.js +26 -0
- package/dist/tunnel/tunnel.protocol.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +21 -0
- package/dist/version.js.map +1 -0
- package/package.json +7 -2
- package/dist/anki-config.service.d.ts +0 -11
- package/dist/anki-config.service.js +0 -46
- package/dist/anki-config.service.js.map +0 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleTunnel = exports.handleLogout = exports.handleLogin = void 0;
|
|
4
|
+
var login_command_1 = require("./login.command");
|
|
5
|
+
Object.defineProperty(exports, "handleLogin", { enumerable: true, get: function () { return login_command_1.handleLogin; } });
|
|
6
|
+
var logout_command_1 = require("./logout.command");
|
|
7
|
+
Object.defineProperty(exports, "handleLogout", { enumerable: true, get: function () { return logout_command_1.handleLogout; } });
|
|
8
|
+
var tunnel_command_1 = require("./tunnel.command");
|
|
9
|
+
Object.defineProperty(exports, "handleTunnel", { enumerable: true, get: function () { return tunnel_command_1.handleTunnel; } });
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tunnel/commands/index.ts"],"names":[],"mappings":";;;AAAA,iDAA8C;AAArC,4GAAA,WAAW,OAAA;AACpB,mDAAgD;AAAvC,8GAAA,YAAY,OAAA;AACrB,mDAAgD;AAAvC,8GAAA,YAAY,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function handleLogin(tunnelUrl?: string): Promise<void>;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleLogin = handleLogin;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const util_1 = require("util");
|
|
6
|
+
const tunnel_1 = require("..");
|
|
7
|
+
const tunnel_2 = require("..");
|
|
8
|
+
const app_config_service_1 = require("../../app-config.service");
|
|
9
|
+
const config_1 = require("../../config");
|
|
10
|
+
const cli_output_1 = require("../../cli/cli-output");
|
|
11
|
+
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
12
|
+
async function openBrowser(url) {
|
|
13
|
+
const platform = process.platform;
|
|
14
|
+
try {
|
|
15
|
+
let command;
|
|
16
|
+
switch (platform) {
|
|
17
|
+
case "darwin":
|
|
18
|
+
command = `open "${url}"`;
|
|
19
|
+
break;
|
|
20
|
+
case "win32":
|
|
21
|
+
command = `start "${url}"`;
|
|
22
|
+
break;
|
|
23
|
+
default:
|
|
24
|
+
command = `xdg-open "${url}"`;
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
await execAsync(command);
|
|
28
|
+
}
|
|
29
|
+
catch (_error) {
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function startSpinner(message) {
|
|
33
|
+
const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
34
|
+
let i = 0;
|
|
35
|
+
const interval = setInterval(() => {
|
|
36
|
+
process.stdout.write(`\r${frames[i]} ${message}`);
|
|
37
|
+
i = (i + 1) % frames.length;
|
|
38
|
+
}, 80);
|
|
39
|
+
return () => {
|
|
40
|
+
clearInterval(interval);
|
|
41
|
+
process.stdout.write("\r");
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
async function handleLogin(tunnelUrl) {
|
|
45
|
+
const credentialsService = new tunnel_1.CredentialsService();
|
|
46
|
+
const validatedConfig = (0, config_1.loadValidatedConfig)({ tunnel: tunnelUrl });
|
|
47
|
+
const appConfigService = new app_config_service_1.AppConfigService(validatedConfig);
|
|
48
|
+
const deviceFlowService = new tunnel_2.DeviceFlowService(appConfigService);
|
|
49
|
+
cli_output_1.cli.blank();
|
|
50
|
+
try {
|
|
51
|
+
const deviceCode = await deviceFlowService.requestDeviceCode();
|
|
52
|
+
cli_output_1.cli.info("Opening browser for authentication...");
|
|
53
|
+
cli_output_1.cli.info(`If browser doesn't open, visit: ${deviceCode.verification_uri}`);
|
|
54
|
+
cli_output_1.cli.info(`Enter code: ${deviceCode.user_code}`);
|
|
55
|
+
cli_output_1.cli.blank();
|
|
56
|
+
const urlToOpen = deviceCode.verification_uri_complete || deviceCode.verification_uri;
|
|
57
|
+
await openBrowser(urlToOpen);
|
|
58
|
+
const stopSpinner = startSpinner("Waiting for authentication...");
|
|
59
|
+
let tokenResponse;
|
|
60
|
+
try {
|
|
61
|
+
tokenResponse = await deviceFlowService.pollForToken(deviceCode.device_code, deviceCode.interval, deviceCode.expires_in);
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
stopSpinner();
|
|
65
|
+
}
|
|
66
|
+
cli_output_1.cli.success("Authentication successful");
|
|
67
|
+
cli_output_1.cli.blank();
|
|
68
|
+
const expiresAt = new Date(Date.now() + tokenResponse.expires_in * 1000).toISOString();
|
|
69
|
+
const credentials = {
|
|
70
|
+
access_token: tokenResponse.access_token,
|
|
71
|
+
refresh_token: tokenResponse.refresh_token,
|
|
72
|
+
expires_at: expiresAt,
|
|
73
|
+
user: tokenResponse.user,
|
|
74
|
+
};
|
|
75
|
+
await credentialsService.saveCredentials(credentials);
|
|
76
|
+
cli_output_1.cli.info(`Logged in as: ${tokenResponse.user.email}`);
|
|
77
|
+
cli_output_1.cli.info(`Tier: ${tokenResponse.user.tier}`);
|
|
78
|
+
cli_output_1.cli.info(`Credentials saved to ${credentialsService.getCredentialsPath()}`);
|
|
79
|
+
cli_output_1.cli.blank();
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
if (error instanceof tunnel_2.DeviceFlowError) {
|
|
83
|
+
cli_output_1.cli.blank();
|
|
84
|
+
switch (error.code) {
|
|
85
|
+
case "expired_token":
|
|
86
|
+
cli_output_1.cli.error("Authentication timed out. Please try again with 'ankimcp --login'");
|
|
87
|
+
break;
|
|
88
|
+
case "access_denied":
|
|
89
|
+
cli_output_1.cli.error("Authentication was denied. Please try again with 'ankimcp --login'");
|
|
90
|
+
break;
|
|
91
|
+
case "network_error":
|
|
92
|
+
case "timeout":
|
|
93
|
+
cli_output_1.cli.error("Failed to connect to auth server. Check your internet connection.");
|
|
94
|
+
break;
|
|
95
|
+
default:
|
|
96
|
+
cli_output_1.cli.error(`Authentication failed: ${error.message}`);
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
cli_output_1.cli.blank();
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
cli_output_1.cli.blank();
|
|
103
|
+
cli_output_1.cli.error(`Login failed: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined);
|
|
104
|
+
cli_output_1.cli.blank();
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=login.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.command.js","sourceRoot":"","sources":["../../../src/tunnel/commands/login.command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function handleLogout(): Promise<void>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleLogout = handleLogout;
|
|
4
|
+
const credentials_service_1 = require("../credentials.service");
|
|
5
|
+
const cli_output_1 = require("../../cli/cli-output");
|
|
6
|
+
async function handleLogout() {
|
|
7
|
+
const credentialsService = new credentials_service_1.CredentialsService();
|
|
8
|
+
const hasCredentials = await credentialsService.hasCredentials();
|
|
9
|
+
if (!hasCredentials) {
|
|
10
|
+
cli_output_1.cli.blank();
|
|
11
|
+
cli_output_1.cli.info("Not logged in. Nothing to do.");
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
await credentialsService.clearCredentials();
|
|
16
|
+
cli_output_1.cli.blank();
|
|
17
|
+
cli_output_1.cli.success("Logged out successfully.");
|
|
18
|
+
cli_output_1.cli.info(`Credentials removed from ${credentialsService.getCredentialsPath()}`);
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
cli_output_1.cli.blank();
|
|
22
|
+
cli_output_1.cli.error(`Failed to remove credentials: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=logout.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.command.js","sourceRoot":"","sources":["../../../src/tunnel/commands/logout.command.ts"],"names":[],"mappings":";;AAoBA,oCA6BC;AAjDD,gEAA4D;AAC5D,qDAAuC;AAmBhC,KAAK,UAAU,YAAY;IAChC,MAAM,kBAAkB,GAAG,IAAI,wCAAkB,EAAE,CAAC;IAGpD,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC,cAAc,EAAE,CAAC;IAEjE,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,gBAAG,CAAC,KAAK,EAAE,CAAC;QACZ,gBAAG,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IAGD,IAAI,CAAC;QACH,MAAM,kBAAkB,CAAC,gBAAgB,EAAE,CAAC;QAE5C,gBAAG,CAAC,KAAK,EAAE,CAAC;QACZ,gBAAG,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;QACxC,gBAAG,CAAC,IAAI,CACN,4BAA4B,kBAAkB,CAAC,kBAAkB,EAAE,EAAE,CACtE,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,gBAAG,CAAC,KAAK,EAAE,CAAC;QACZ,gBAAG,CAAC,KAAK,CACP,iCAAiC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EACzF,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAC3C,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function handleTunnel(tunnelUrl?: string, debug?: boolean, readOnly?: boolean): Promise<void>;
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleTunnel = handleTunnel;
|
|
4
|
+
const core_1 = require("@nestjs/core");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const app_module_1 = require("../../app.module");
|
|
7
|
+
const tunnel_1 = require("..");
|
|
8
|
+
const tunnel_2 = require("..");
|
|
9
|
+
const tunnel_3 = require("..");
|
|
10
|
+
const tunnel_4 = require("..");
|
|
11
|
+
const tunnel_mcp_service_1 = require("../tunnel-mcp.service");
|
|
12
|
+
const app_config_service_1 = require("../../app-config.service");
|
|
13
|
+
const config_1 = require("../../config");
|
|
14
|
+
const cli_output_1 = require("../../cli/cli-output");
|
|
15
|
+
const bootstrap_1 = require("../../bootstrap");
|
|
16
|
+
function startSpinner(message) {
|
|
17
|
+
const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
18
|
+
let i = 0;
|
|
19
|
+
const interval = setInterval(() => {
|
|
20
|
+
process.stdout.write(`\r${frames[i]} ${message}`);
|
|
21
|
+
i = (i + 1) % frames.length;
|
|
22
|
+
}, 80);
|
|
23
|
+
return () => {
|
|
24
|
+
clearInterval(interval);
|
|
25
|
+
process.stdout.write("\r");
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function displayBox(title, url) {
|
|
29
|
+
cli_output_1.cli.box(title, url);
|
|
30
|
+
}
|
|
31
|
+
function formatConnectionError(error, tunnelUrl) {
|
|
32
|
+
const url = tunnelUrl || tunnel_4.TUNNEL_DEFAULTS.URL;
|
|
33
|
+
if (error instanceof tunnel_3.TunnelClientError && error.originalError) {
|
|
34
|
+
const origError = error.originalError;
|
|
35
|
+
if (origError.code === "ECONNREFUSED") {
|
|
36
|
+
return `Cannot connect to tunnel server at ${url}
|
|
37
|
+
Make sure the tunnel server is running.`;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (error instanceof Error) {
|
|
41
|
+
if (error.message.includes("ECONNREFUSED") ||
|
|
42
|
+
error.message.includes("connect ECONNREFUSED")) {
|
|
43
|
+
return `Cannot connect to tunnel server at ${url}
|
|
44
|
+
Make sure the tunnel server is running.`;
|
|
45
|
+
}
|
|
46
|
+
if (error.message.includes("timeout") ||
|
|
47
|
+
error.message.includes("Connection timeout")) {
|
|
48
|
+
return `Connection timeout to ${url}
|
|
49
|
+
The tunnel server may be unavailable or slow to respond.`;
|
|
50
|
+
}
|
|
51
|
+
if (error.message.includes("Unauthorized") ||
|
|
52
|
+
error.message.includes("401")) {
|
|
53
|
+
return `Authentication failed
|
|
54
|
+
Your credentials may be invalid. Try: ankimcp --logout && ankimcp --login`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
58
|
+
return `Failed to connect: ${message}`;
|
|
59
|
+
}
|
|
60
|
+
async function handleTunnel(tunnelUrl, debug, readOnly) {
|
|
61
|
+
(0, cli_output_1.setDebugMode)(debug || false);
|
|
62
|
+
const credentialsService = new tunnel_1.CredentialsService();
|
|
63
|
+
const validatedConfig = (0, config_1.loadValidatedConfig)({ debug, readOnly });
|
|
64
|
+
const appConfigService = new app_config_service_1.AppConfigService(validatedConfig);
|
|
65
|
+
const deviceFlowService = new tunnel_2.DeviceFlowService(appConfigService);
|
|
66
|
+
cli_output_1.cli.blank();
|
|
67
|
+
try {
|
|
68
|
+
const credentials = await credentialsService.loadCredentials();
|
|
69
|
+
if (!credentials) {
|
|
70
|
+
cli_output_1.cli.error("Not logged in. Run: ankimcp --login");
|
|
71
|
+
cli_output_1.cli.blank();
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
const stopSpinner = startSpinner("Starting MCP service...");
|
|
75
|
+
let app;
|
|
76
|
+
let tunnelMcpService;
|
|
77
|
+
const logLevel = debug ? "debug" : "info";
|
|
78
|
+
const pinoLogger = (0, bootstrap_1.createPinoLogger)(bootstrap_1.LOG_DESTINATION.STDERR, logLevel);
|
|
79
|
+
const loggerService = (0, bootstrap_1.createLoggerService)(pinoLogger);
|
|
80
|
+
if (debug) {
|
|
81
|
+
common_1.Logger.overrideLogger(["log", "error", "warn", "debug", "verbose"]);
|
|
82
|
+
}
|
|
83
|
+
common_1.Logger.overrideLogger(loggerService);
|
|
84
|
+
try {
|
|
85
|
+
app = await core_1.NestFactory.createApplicationContext(app_module_1.AppModule.forTunnel({ debug, readOnly }), {
|
|
86
|
+
logger: loggerService,
|
|
87
|
+
});
|
|
88
|
+
tunnelMcpService = app.get(tunnel_mcp_service_1.TunnelMcpService);
|
|
89
|
+
stopSpinner();
|
|
90
|
+
cli_output_1.cli.success("MCP service ready");
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
stopSpinner();
|
|
94
|
+
cli_output_1.cli.error(`Failed to start MCP service: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined);
|
|
95
|
+
cli_output_1.cli.blank();
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
cli_output_1.cli.blank();
|
|
99
|
+
const mcpHandler = {
|
|
100
|
+
async handle(request) {
|
|
101
|
+
const responseBody = await tunnelMcpService.handleRequest(request.body);
|
|
102
|
+
return {
|
|
103
|
+
status: 200,
|
|
104
|
+
headers: { "content-type": "application/json" },
|
|
105
|
+
body: responseBody,
|
|
106
|
+
};
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
const effectiveTunnelUrl = tunnelUrl || validatedConfig.tunnel.serverUrl;
|
|
110
|
+
const tunnelClient = new tunnel_3.TunnelClient(mcpHandler, credentialsService, deviceFlowService, effectiveTunnelUrl);
|
|
111
|
+
tunnelClient.on("error", (error) => {
|
|
112
|
+
if (error instanceof tunnel_3.TunnelClientError &&
|
|
113
|
+
error.code === "session_expired") {
|
|
114
|
+
cli_output_1.cli.blank();
|
|
115
|
+
cli_output_1.cli.error(error.message);
|
|
116
|
+
tunnelClient.disconnect();
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
if (tunnelClient.isConnected()) {
|
|
120
|
+
cli_output_1.cli.error(`Tunnel error: ${error.message}`, error);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
const connectSpinner = startSpinner("Connecting to tunnel service...");
|
|
124
|
+
let publicUrl;
|
|
125
|
+
try {
|
|
126
|
+
publicUrl = await tunnelClient.connect(tunnelUrl);
|
|
127
|
+
connectSpinner();
|
|
128
|
+
cli_output_1.cli.success("Tunnel established");
|
|
129
|
+
cli_output_1.cli.blank();
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
connectSpinner();
|
|
133
|
+
if (error instanceof tunnel_3.TunnelClientError &&
|
|
134
|
+
error.code === "session_expired") {
|
|
135
|
+
cli_output_1.cli.blank();
|
|
136
|
+
cli_output_1.cli.error(error.message);
|
|
137
|
+
await app.close();
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
const errorMessage = formatConnectionError(error, tunnelUrl);
|
|
141
|
+
cli_output_1.cli.error(errorMessage, error instanceof Error ? error : undefined);
|
|
142
|
+
cli_output_1.cli.blank();
|
|
143
|
+
await app.close();
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
displayBox("🚇 Tunnel URL", publicUrl);
|
|
147
|
+
cli_output_1.cli.blank();
|
|
148
|
+
cli_output_1.cli.info("Tunnel is active. Press Ctrl+C to disconnect.");
|
|
149
|
+
cli_output_1.cli.blank();
|
|
150
|
+
const logger = new common_1.Logger("TunnelCommand");
|
|
151
|
+
tunnelClient.on("request", (requestId, request) => {
|
|
152
|
+
logger.log(`Request ${requestId}: ${request.method} ${request.path}`);
|
|
153
|
+
});
|
|
154
|
+
tunnelClient.on("url_changed", (oldUrl, newUrl) => {
|
|
155
|
+
cli_output_1.cli.blank();
|
|
156
|
+
cli_output_1.cli.info(`🔄 Tunnel URL changed:`);
|
|
157
|
+
cli_output_1.cli.info(` Old: ${oldUrl}`);
|
|
158
|
+
cli_output_1.cli.info(` New: ${newUrl}`);
|
|
159
|
+
cli_output_1.cli.blank();
|
|
160
|
+
});
|
|
161
|
+
tunnelClient.on("disconnected", (code, reason) => {
|
|
162
|
+
cli_output_1.cli.blank();
|
|
163
|
+
cli_output_1.cli.error(`Tunnel disconnected (code ${code}): ${reason}`);
|
|
164
|
+
cli_output_1.cli.blank();
|
|
165
|
+
});
|
|
166
|
+
const shutdown = async () => {
|
|
167
|
+
cli_output_1.cli.blank();
|
|
168
|
+
cli_output_1.cli.info("Shutting down...");
|
|
169
|
+
tunnelClient.disconnect();
|
|
170
|
+
await app.close();
|
|
171
|
+
cli_output_1.cli.success("Tunnel closed");
|
|
172
|
+
cli_output_1.cli.blank();
|
|
173
|
+
process.exit(0);
|
|
174
|
+
};
|
|
175
|
+
process.on("SIGINT", shutdown);
|
|
176
|
+
process.on("SIGTERM", shutdown);
|
|
177
|
+
await new Promise(() => { });
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
cli_output_1.cli.error(`Tunnel failed: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined);
|
|
181
|
+
cli_output_1.cli.blank();
|
|
182
|
+
process.exit(1);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=tunnel.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel.command.js","sourceRoot":"","sources":["../../../src/tunnel/commands/tunnel.command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface TunnelCredentials {
|
|
2
|
+
access_token: string;
|
|
3
|
+
refresh_token: string;
|
|
4
|
+
expires_at: string;
|
|
5
|
+
user: {
|
|
6
|
+
id: string;
|
|
7
|
+
email: string;
|
|
8
|
+
tier: "free" | "paid";
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export declare class CredentialsService {
|
|
12
|
+
private readonly logger;
|
|
13
|
+
private static readonly CREDENTIALS_DIR;
|
|
14
|
+
private static readonly CREDENTIALS_FILE;
|
|
15
|
+
getCredentialsPath(): string;
|
|
16
|
+
saveCredentials(credentials: TunnelCredentials): Promise<void>;
|
|
17
|
+
loadCredentials(): Promise<TunnelCredentials | null>;
|
|
18
|
+
clearCredentials(): Promise<void>;
|
|
19
|
+
hasCredentials(): Promise<boolean>;
|
|
20
|
+
isTokenExpired(credentials: TunnelCredentials): boolean;
|
|
21
|
+
private ensureCredentialsDirectory;
|
|
22
|
+
private validateCredentials;
|
|
23
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CredentialsService = void 0;
|
|
4
|
+
const promises_1 = require("fs/promises");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const os_1 = require("os");
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const common_1 = require("@nestjs/common");
|
|
9
|
+
class CredentialsService {
|
|
10
|
+
logger = new common_1.Logger(CredentialsService.name);
|
|
11
|
+
static CREDENTIALS_DIR = (0, path_1.join)((0, os_1.homedir)(), ".ankimcp");
|
|
12
|
+
static CREDENTIALS_FILE = (0, path_1.join)(CredentialsService.CREDENTIALS_DIR, "credentials.json");
|
|
13
|
+
getCredentialsPath() {
|
|
14
|
+
return CredentialsService.CREDENTIALS_FILE;
|
|
15
|
+
}
|
|
16
|
+
async saveCredentials(credentials) {
|
|
17
|
+
try {
|
|
18
|
+
await this.ensureCredentialsDirectory();
|
|
19
|
+
const content = JSON.stringify(credentials, null, 2);
|
|
20
|
+
await (0, promises_1.writeFile)(CredentialsService.CREDENTIALS_FILE, content, {
|
|
21
|
+
encoding: "utf-8",
|
|
22
|
+
mode: 0o600,
|
|
23
|
+
});
|
|
24
|
+
await (0, promises_1.chmod)(CredentialsService.CREDENTIALS_FILE, 0o600);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
throw new Error(`Failed to save credentials to ${CredentialsService.CREDENTIALS_FILE}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async loadCredentials() {
|
|
31
|
+
try {
|
|
32
|
+
await (0, promises_1.access)(CredentialsService.CREDENTIALS_FILE, fs_1.constants.F_OK | fs_1.constants.R_OK);
|
|
33
|
+
const content = await (0, promises_1.readFile)(CredentialsService.CREDENTIALS_FILE, {
|
|
34
|
+
encoding: "utf-8",
|
|
35
|
+
});
|
|
36
|
+
const credentials = JSON.parse(content);
|
|
37
|
+
const validation = this.validateCredentials(credentials);
|
|
38
|
+
if (!validation.valid) {
|
|
39
|
+
this.logger.warn(`Corrupted credentials file at ${CredentialsService.CREDENTIALS_FILE}:`);
|
|
40
|
+
validation.errors.forEach((error) => {
|
|
41
|
+
this.logger.warn(` - ${error}`);
|
|
42
|
+
});
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
return credentials;
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
if (error.code === "ENOENT") {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
this.logger.warn(`Failed to load credentials from ${CredentialsService.CREDENTIALS_FILE}: ${error instanceof Error ? error.message : String(error)}`);
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async clearCredentials() {
|
|
56
|
+
try {
|
|
57
|
+
await (0, promises_1.unlink)(CredentialsService.CREDENTIALS_FILE);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error.code !== "ENOENT") {
|
|
61
|
+
throw new Error(`Failed to delete credentials file: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async hasCredentials() {
|
|
66
|
+
try {
|
|
67
|
+
await (0, promises_1.access)(CredentialsService.CREDENTIALS_FILE, fs_1.constants.F_OK);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
isTokenExpired(credentials) {
|
|
75
|
+
const expiresAt = new Date(credentials.expires_at).getTime();
|
|
76
|
+
const now = Date.now();
|
|
77
|
+
const bufferMs = 60 * 1000;
|
|
78
|
+
return now >= expiresAt - bufferMs;
|
|
79
|
+
}
|
|
80
|
+
async ensureCredentialsDirectory() {
|
|
81
|
+
try {
|
|
82
|
+
await (0, promises_1.access)(CredentialsService.CREDENTIALS_DIR, fs_1.constants.F_OK);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
if (error.code === "ENOENT") {
|
|
86
|
+
await (0, promises_1.mkdir)(CredentialsService.CREDENTIALS_DIR, {
|
|
87
|
+
recursive: true,
|
|
88
|
+
mode: 0o700,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
validateCredentials(obj) {
|
|
97
|
+
const errors = [];
|
|
98
|
+
if (!obj || typeof obj !== "object") {
|
|
99
|
+
errors.push("Credentials must be an object");
|
|
100
|
+
return { valid: false, errors };
|
|
101
|
+
}
|
|
102
|
+
const creds = obj;
|
|
103
|
+
if (!("access_token" in creds)) {
|
|
104
|
+
errors.push("Missing field: access_token");
|
|
105
|
+
}
|
|
106
|
+
else if (typeof creds.access_token !== "string") {
|
|
107
|
+
errors.push(`Invalid type for access_token: expected string, got ${typeof creds.access_token}`);
|
|
108
|
+
}
|
|
109
|
+
if (!("refresh_token" in creds)) {
|
|
110
|
+
errors.push("Missing field: refresh_token");
|
|
111
|
+
}
|
|
112
|
+
else if (typeof creds.refresh_token !== "string") {
|
|
113
|
+
errors.push(`Invalid type for refresh_token: expected string, got ${typeof creds.refresh_token}`);
|
|
114
|
+
}
|
|
115
|
+
if (!("expires_at" in creds)) {
|
|
116
|
+
errors.push("Missing field: expires_at");
|
|
117
|
+
}
|
|
118
|
+
else if (typeof creds.expires_at !== "string") {
|
|
119
|
+
errors.push(`Invalid type for expires_at: expected string, got ${typeof creds.expires_at}`);
|
|
120
|
+
}
|
|
121
|
+
if (!("user" in creds)) {
|
|
122
|
+
errors.push("Missing field: user");
|
|
123
|
+
}
|
|
124
|
+
else if (!creds.user || typeof creds.user !== "object") {
|
|
125
|
+
errors.push(`Invalid type for user: expected object, got ${typeof creds.user}`);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
const user = creds.user;
|
|
129
|
+
if (!("id" in user)) {
|
|
130
|
+
errors.push("Missing field: user.id");
|
|
131
|
+
}
|
|
132
|
+
else if (typeof user.id !== "string") {
|
|
133
|
+
errors.push(`Invalid type for user.id: expected string, got ${typeof user.id}`);
|
|
134
|
+
}
|
|
135
|
+
if (!("email" in user)) {
|
|
136
|
+
errors.push("Missing field: user.email");
|
|
137
|
+
}
|
|
138
|
+
else if (typeof user.email !== "string") {
|
|
139
|
+
errors.push(`Invalid type for user.email: expected string, got ${typeof user.email}`);
|
|
140
|
+
}
|
|
141
|
+
if (!("tier" in user)) {
|
|
142
|
+
errors.push("Missing field: user.tier");
|
|
143
|
+
}
|
|
144
|
+
else if (user.tier !== "free" && user.tier !== "paid") {
|
|
145
|
+
errors.push(`Invalid tier value: expected 'free' or 'paid', got '${String(user.tier)}'`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return { valid: errors.length === 0, errors };
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
exports.CredentialsService = CredentialsService;
|
|
152
|
+
//# sourceMappingURL=credentials.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.service.js","sourceRoot":"","sources":["../../src/tunnel/credentials.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { AppConfigService } from "../app-config.service";
|
|
2
|
+
export interface DeviceCodeResponse {
|
|
3
|
+
device_code: string;
|
|
4
|
+
user_code: string;
|
|
5
|
+
verification_uri: string;
|
|
6
|
+
verification_uri_complete?: string;
|
|
7
|
+
expires_in: number;
|
|
8
|
+
interval: number;
|
|
9
|
+
}
|
|
10
|
+
export interface TokenResponse {
|
|
11
|
+
access_token: string;
|
|
12
|
+
token_type: string;
|
|
13
|
+
expires_in: number;
|
|
14
|
+
refresh_token: string;
|
|
15
|
+
user: {
|
|
16
|
+
id: string;
|
|
17
|
+
email: string;
|
|
18
|
+
tier: "free" | "paid";
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export interface DeviceFlowErrorResponse {
|
|
22
|
+
error: "authorization_pending" | "slow_down" | "expired_token" | "access_denied" | string;
|
|
23
|
+
error_description?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare class DeviceFlowError extends Error {
|
|
26
|
+
readonly code: string;
|
|
27
|
+
readonly description?: string | undefined;
|
|
28
|
+
constructor(message: string, code: string, description?: string | undefined);
|
|
29
|
+
}
|
|
30
|
+
export declare class DeviceFlowService {
|
|
31
|
+
private readonly config;
|
|
32
|
+
private readonly client;
|
|
33
|
+
private readonly logger;
|
|
34
|
+
private readonly deviceEndpoint;
|
|
35
|
+
private readonly tokenEndpoint;
|
|
36
|
+
constructor(config: AppConfigService);
|
|
37
|
+
requestDeviceCode(): Promise<DeviceCodeResponse>;
|
|
38
|
+
pollForToken(deviceCode: string, interval: number, expiresIn: number): Promise<TokenResponse>;
|
|
39
|
+
refreshToken(refreshToken: string): Promise<TokenResponse>;
|
|
40
|
+
private sleep;
|
|
41
|
+
private handleError;
|
|
42
|
+
getConfig(): {
|
|
43
|
+
tunnelUrl: string;
|
|
44
|
+
clientId: string;
|
|
45
|
+
};
|
|
46
|
+
}
|