@mastra/code-sdk 1.0.3-alpha.0 → 1.1.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -0
- package/dist/acp/agent.js +155 -167
- package/dist/acp/agent.js.map +1 -1
- package/dist/acp/event-mapper.js +193 -168
- package/dist/acp/event-mapper.js.map +1 -1
- package/dist/acp/index.js +60 -49
- package/dist/acp/index.js.map +1 -1
- package/dist/acp/server.js +31 -30
- package/dist/acp/server.js.map +1 -1
- package/dist/acp.js +1 -4
- package/dist/agents/credential-resolver.js +40 -29
- package/dist/agents/credential-resolver.js.map +1 -1
- package/dist/agents/custom-provider-source.js +16 -9
- package/dist/agents/custom-provider-source.js.map +1 -1
- package/dist/agents/instructions.js +27 -36
- package/dist/agents/instructions.js.map +1 -1
- package/dist/agents/mastracode-gateway.js +355 -428
- package/dist/agents/mastracode-gateway.js.map +1 -1
- package/dist/agents/memory.js +87 -78
- package/dist/agents/memory.js.map +1 -1
- package/dist/agents/model.js +114 -119
- package/dist/agents/model.js.map +1 -1
- package/dist/agents/modes/build.js +12 -13
- package/dist/agents/modes/build.js.map +1 -1
- package/dist/agents/modes/explore.js +14 -13
- package/dist/agents/modes/explore.js.map +1 -1
- package/dist/agents/modes/plan.js +14 -15
- package/dist/agents/modes/plan.js.map +1 -1
- package/dist/agents/prompts/agent-instructions.js +78 -69
- package/dist/agents/prompts/agent-instructions.js.map +1 -1
- package/dist/agents/prompts/build.js +19 -16
- package/dist/agents/prompts/build.js.map +1 -1
- package/dist/agents/prompts/fast.js +8 -4
- package/dist/agents/prompts/fast.js.map +1 -1
- package/dist/agents/prompts/index.js +48 -47
- package/dist/agents/prompts/index.js.map +1 -1
- package/dist/agents/prompts/model.js +6 -5
- package/dist/agents/prompts/model.js.map +1 -1
- package/dist/agents/prompts/plan.js +20 -16
- package/dist/agents/prompts/plan.js.map +1 -1
- package/dist/agents/prompts/tool-guidance.js +77 -109
- package/dist/agents/prompts/tool-guidance.js.map +1 -1
- package/dist/agents/sandbox-filesystem.js +245 -259
- package/dist/agents/sandbox-filesystem.js.map +1 -1
- package/dist/agents/sandbox-reattach.js +9 -11
- package/dist/agents/sandbox-reattach.js.map +1 -1
- package/dist/agents/thread-caveman-state.js +92 -81
- package/dist/agents/thread-caveman-state.js.map +1 -1
- package/dist/agents/tool-availability.js +62 -80
- package/dist/agents/tool-availability.js.map +1 -1
- package/dist/agents/tools.js +99 -139
- package/dist/agents/tools.js.map +1 -1
- package/dist/agents/workspace.js +232 -225
- package/dist/agents/workspace.js.map +1 -1
- package/dist/analytics.js +139 -128
- package/dist/analytics.js.map +1 -1
- package/dist/auth/authorization-input.js +39 -25
- package/dist/auth/authorization-input.js.map +1 -1
- package/dist/auth/device-code.js +112 -80
- package/dist/auth/device-code.js.map +1 -1
- package/dist/auth/index.js +2 -9
- package/dist/auth/pkce.js +27 -16
- package/dist/auth/pkce.js.map +1 -1
- package/dist/auth/providers/anthropic.js +107 -93
- package/dist/auth/providers/anthropic.js.map +1 -1
- package/dist/auth/providers/github-copilot.js +304 -293
- package/dist/auth/providers/github-copilot.js.map +1 -1
- package/dist/auth/providers/openai-codex.js +442 -460
- package/dist/auth/providers/openai-codex.js.map +1 -1
- package/dist/auth/providers/xai.js +179 -145
- package/dist/auth/providers/xai.js.map +1 -1
- package/dist/auth/storage.js +182 -175
- package/dist/auth/storage.js.map +1 -1
- package/dist/auth/types.js +1 -1
- package/dist/clipboard/index.js +206 -172
- package/dist/clipboard/index.js.map +1 -1
- package/dist/constants.js +11 -16
- package/dist/constants.js.map +1 -1
- package/dist/error-classification.js +19 -11
- package/dist/error-classification.js.map +1 -1
- package/dist/evals/context-builder.js +145 -104
- package/dist/evals/context-builder.js.map +1 -1
- package/dist/evals/index.js +4 -7
- package/dist/evals/scorers/classify-command.js +62 -41
- package/dist/evals/scorers/classify-command.js.map +1 -1
- package/dist/evals/scorers/efficiency.js +239 -181
- package/dist/evals/scorers/efficiency.js.map +1 -1
- package/dist/evals/scorers/extract-tools.js +51 -47
- package/dist/evals/scorers/extract-tools.js.map +1 -1
- package/dist/evals/scorers/index.js +1 -5
- package/dist/evals/scorers/outcome.js +321 -212
- package/dist/evals/scorers/outcome.js.map +1 -1
- package/dist/goal-manager.js +266 -261
- package/dist/goal-manager.js.map +1 -1
- package/dist/goal-signal.js +14 -13
- package/dist/goal-signal.js.map +1 -1
- package/dist/headless/cli.js +153 -154
- package/dist/headless/cli.js.map +1 -1
- package/dist/headless/flags.js +180 -178
- package/dist/headless/flags.js.map +1 -1
- package/dist/headless/format.js +72 -71
- package/dist/headless/format.js.map +1 -1
- package/dist/headless/index.js +5 -31
- package/dist/headless/policy.js +35 -31
- package/dist/headless/policy.js.map +1 -1
- package/dist/headless/run-mc.js +332 -334
- package/dist/headless/run-mc.js.map +1 -1
- package/dist/headless/types.js +16 -7
- package/dist/headless/types.js.map +1 -1
- package/dist/hooks/config.js +56 -61
- package/dist/hooks/config.js.map +1 -1
- package/dist/hooks/executor.js +118 -116
- package/dist/hooks/executor.js.map +1 -1
- package/dist/hooks/index.js +4 -15
- package/dist/hooks/manager.js +221 -280
- package/dist/hooks/manager.js.map +1 -1
- package/dist/hooks/types.js +5 -4
- package/dist/hooks/types.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +632 -712
- package/dist/index.js.map +1 -1
- package/dist/ipc/ipc-reporter.js +19 -22
- package/dist/ipc/ipc-reporter.js.map +1 -1
- package/dist/lsp/client.js +248 -306
- package/dist/lsp/client.js.map +1 -1
- package/dist/lsp/index.js +1 -6
- package/dist/lsp/language.js +39 -43
- package/dist/lsp/language.js.map +1 -1
- package/dist/lsp/manager.js +78 -93
- package/dist/lsp/manager.js.map +1 -1
- package/dist/lsp/server.js +151 -120
- package/dist/lsp/server.js.map +1 -1
- package/dist/lsp/workspace.js +50 -47
- package/dist/lsp/workspace.js.map +1 -1
- package/dist/mcp/config.js +210 -199
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp/index.js +2 -9
- package/dist/mcp/manager.js +482 -475
- package/dist/mcp/manager.js.map +1 -1
- package/dist/mcp/types.js +1 -1
- package/dist/onboarding/custom-packs.js +14 -17
- package/dist/onboarding/custom-packs.js.map +1 -1
- package/dist/onboarding/custom-providers.js +22 -20
- package/dist/onboarding/custom-providers.js.map +1 -1
- package/dist/onboarding/index.d.ts +1 -1
- package/dist/onboarding/index.d.ts.map +1 -1
- package/dist/onboarding/index.js +3 -21
- package/dist/onboarding/om-settings.d.ts +5 -0
- package/dist/onboarding/om-settings.d.ts.map +1 -1
- package/dist/onboarding/om-settings.js +41 -20
- package/dist/onboarding/om-settings.js.map +1 -1
- package/dist/onboarding/packs.d.ts +4 -6
- package/dist/onboarding/packs.d.ts.map +1 -1
- package/dist/onboarding/packs.js +154 -105
- package/dist/onboarding/packs.js.map +1 -1
- package/dist/onboarding/settings.js +575 -517
- package/dist/onboarding/settings.js.map +1 -1
- package/dist/permissions.js +112 -99
- package/dist/permissions.js.map +1 -1
- package/dist/plugin.js +21 -23
- package/dist/plugin.js.map +1 -1
- package/dist/plugins/dependencies.js +64 -87
- package/dist/plugins/dependencies.js.map +1 -1
- package/dist/plugins/install.js +159 -169
- package/dist/plugins/install.js.map +1 -1
- package/dist/plugins/loader.js +170 -185
- package/dist/plugins/loader.js.map +1 -1
- package/dist/plugins/manager.js +374 -380
- package/dist/plugins/manager.js.map +1 -1
- package/dist/plugins/manifest.js +38 -63
- package/dist/plugins/manifest.js.map +1 -1
- package/dist/plugins/package-link.js +48 -64
- package/dist/plugins/package-link.js.map +1 -1
- package/dist/plugins/paths.js +18 -19
- package/dist/plugins/paths.js.map +1 -1
- package/dist/plugins/registry.js +97 -81
- package/dist/plugins/registry.js.map +1 -1
- package/dist/plugins/scaffold.js +62 -98
- package/dist/plugins/scaffold.js.map +1 -1
- package/dist/plugins/types.js +1 -1
- package/dist/processors/plan-rejection-abort.js +45 -44
- package/dist/processors/plan-rejection-abort.js.map +1 -1
- package/dist/providers/amazon-bedrock-gateway.js +134 -125
- package/dist/providers/amazon-bedrock-gateway.js.map +1 -1
- package/dist/providers/amazon-bedrock.js +68 -47
- package/dist/providers/amazon-bedrock.js.map +1 -1
- package/dist/providers/claude-max.js +153 -133
- package/dist/providers/claude-max.js.map +1 -1
- package/dist/providers/github-copilot.js +232 -230
- package/dist/providers/github-copilot.js.map +1 -1
- package/dist/providers/openai-codex.js +271 -260
- package/dist/providers/openai-codex.js.map +1 -1
- package/dist/providers/xai.js +57 -50
- package/dist/providers/xai.js.map +1 -1
- package/dist/schema.js +91 -89
- package/dist/schema.js.map +1 -1
- package/dist/theme-palette.js +18 -14
- package/dist/theme-palette.js.map +1 -1
- package/dist/tool-names.js +46 -37
- package/dist/tool-names.js.map +1 -1
- package/dist/tools/index.js +2 -8
- package/dist/tools/request-sandbox-access.js +71 -80
- package/dist/tools/request-sandbox-access.js.map +1 -1
- package/dist/tools/utils.js +26 -16
- package/dist/tools/utils.js.map +1 -1
- package/dist/tools/web-search.js +51 -55
- package/dist/tools/web-search.js.map +1 -1
- package/dist/utils/binaries.js +65 -61
- package/dist/utils/binaries.js.map +1 -1
- package/dist/utils/debug-log.js +51 -47
- package/dist/utils/debug-log.js.map +1 -1
- package/dist/utils/errors.js +157 -192
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/gateway-sync.js +49 -37
- package/dist/utils/gateway-sync.js.map +1 -1
- package/dist/utils/path-security.js +7 -6
- package/dist/utils/path-security.js.map +1 -1
- package/dist/utils/plan-diff.js +58 -39
- package/dist/utils/plan-diff.js.map +1 -1
- package/dist/utils/plans.js +92 -74
- package/dist/utils/plans.js.map +1 -1
- package/dist/utils/project.js +318 -256
- package/dist/utils/project.js.map +1 -1
- package/dist/utils/signals-pubsub.js +117 -99
- package/dist/utils/signals-pubsub.js.map +1 -1
- package/dist/utils/slash-command-loader.js +118 -154
- package/dist/utils/slash-command-loader.js.map +1 -1
- package/dist/utils/slash-command-processor.js +92 -83
- package/dist/utils/slash-command-processor.js.map +1 -1
- package/dist/utils/stdin-pipe.js +87 -63
- package/dist/utils/stdin-pipe.js.map +1 -1
- package/dist/utils/storage-factory.js +104 -84
- package/dist/utils/storage-factory.js.map +1 -1
- package/dist/utils/storage-maintenance.js +249 -211
- package/dist/utils/storage-maintenance.js.map +1 -1
- package/dist/utils/thread-lock.js +96 -92
- package/dist/utils/thread-lock.js.map +1 -1
- package/dist/utils/token-estimator.js +12 -12
- package/dist/utils/token-estimator.js.map +1 -1
- package/dist/utils/update-check.d.ts +1 -1
- package/dist/utils/update-check.js +341 -259
- package/dist/utils/update-check.js.map +1 -1
- package/dist/voice/stt-registry.js +131 -113
- package/dist/voice/stt-registry.js.map +1 -1
- package/package.json +11 -11
- package/dist/acp.js.map +0 -1
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/types.js.map +0 -1
- package/dist/evals/index.js.map +0 -1
- package/dist/evals/scorers/index.js.map +0 -1
- package/dist/headless/index.js.map +0 -1
- package/dist/hooks/index.js.map +0 -1
- package/dist/lsp/index.js.map +0 -1
- package/dist/mcp/index.js.map +0 -1
- package/dist/mcp/types.js.map +0 -1
- package/dist/onboarding/index.js.map +0 -1
- package/dist/plugins/types.js.map +0 -1
- package/dist/tools/index.js.map +0 -1
package/dist/mcp/manager.js
CHANGED
|
@@ -1,487 +1,494 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync } from "node:fs";
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
3
|
-
import { MCPClient, MCPOAuthClientProvider } from "@mastra/mcp";
|
|
4
1
|
import { DEFAULT_CONFIG_DIR } from "../constants.js";
|
|
5
2
|
import { getAppDataDir } from "../utils/project.js";
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
import { DEFAULT_OAUTH_REDIRECT_URL, getClaudeSettingsPath, getGlobalMcpPath, getProjectMcpPath, loadMcpConfig, resolveOAuthRedirectUrl } from "./config.js";
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "fs";
|
|
5
|
+
import { dirname, join } from "path";
|
|
6
|
+
import { MCPClient, MCPOAuthClientProvider } from "@mastra/mcp";
|
|
7
|
+
//#region src/mcp/manager.ts
|
|
8
|
+
/**
|
|
9
|
+
* MCP manager — orchestrates MCP server connections using MCPClient directly.
|
|
10
|
+
* Created once at startup, provides tools from connected MCP servers.
|
|
11
|
+
*/
|
|
12
|
+
const MASTRACODE_MCP_TIMEOUT_MS = 10080 * 60 * 1e3;
|
|
15
13
|
function getTransport(cfg) {
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
class FileOAuthStorage {
|
|
19
|
-
constructor(filePath) {
|
|
20
|
-
this.filePath = filePath;
|
|
21
|
-
}
|
|
22
|
-
filePath;
|
|
23
|
-
get(key) {
|
|
24
|
-
return this.read()[key];
|
|
25
|
-
}
|
|
26
|
-
set(key, value) {
|
|
27
|
-
const data = this.read();
|
|
28
|
-
data[key] = value;
|
|
29
|
-
this.write(data);
|
|
30
|
-
}
|
|
31
|
-
delete(key) {
|
|
32
|
-
const data = this.read();
|
|
33
|
-
delete data[key];
|
|
34
|
-
this.write(data);
|
|
35
|
-
}
|
|
36
|
-
read() {
|
|
37
|
-
if (!existsSync(this.filePath)) return {};
|
|
38
|
-
try {
|
|
39
|
-
return JSON.parse(readFileSync(this.filePath, "utf-8"));
|
|
40
|
-
} catch {
|
|
41
|
-
return {};
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
write(data) {
|
|
45
|
-
const dir = dirname(this.filePath);
|
|
46
|
-
if (!existsSync(dir)) {
|
|
47
|
-
mkdirSync(dir, { recursive: true, mode: 448 });
|
|
48
|
-
}
|
|
49
|
-
const tmpPath = `${this.filePath}.tmp`;
|
|
50
|
-
writeFileSync(tmpPath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
|
|
51
|
-
renameSync(tmpPath, this.filePath);
|
|
52
|
-
}
|
|
14
|
+
return "url" in cfg ? "http" : "stdio";
|
|
53
15
|
}
|
|
16
|
+
var FileOAuthStorage = class {
|
|
17
|
+
filePath;
|
|
18
|
+
constructor(filePath) {
|
|
19
|
+
this.filePath = filePath;
|
|
20
|
+
}
|
|
21
|
+
get(key) {
|
|
22
|
+
return this.read()[key];
|
|
23
|
+
}
|
|
24
|
+
set(key, value) {
|
|
25
|
+
const data = this.read();
|
|
26
|
+
data[key] = value;
|
|
27
|
+
this.write(data);
|
|
28
|
+
}
|
|
29
|
+
delete(key) {
|
|
30
|
+
const data = this.read();
|
|
31
|
+
delete data[key];
|
|
32
|
+
this.write(data);
|
|
33
|
+
}
|
|
34
|
+
read() {
|
|
35
|
+
if (!existsSync(this.filePath)) return {};
|
|
36
|
+
try {
|
|
37
|
+
return JSON.parse(readFileSync(this.filePath, "utf-8"));
|
|
38
|
+
} catch {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
write(data) {
|
|
43
|
+
const dir = dirname(this.filePath);
|
|
44
|
+
if (!existsSync(dir)) mkdirSync(dir, {
|
|
45
|
+
recursive: true,
|
|
46
|
+
mode: 448
|
|
47
|
+
});
|
|
48
|
+
const tmpPath = `${this.filePath}.tmp`;
|
|
49
|
+
writeFileSync(tmpPath, JSON.stringify(data, null, 2), {
|
|
50
|
+
encoding: "utf-8",
|
|
51
|
+
mode: 384
|
|
52
|
+
});
|
|
53
|
+
renameSync(tmpPath, this.filePath);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Zero-config OAuth defaults for servers with a bare `url` entry. Dynamic
|
|
58
|
+
* client registration provisions the client, so no `clientId` is needed.
|
|
59
|
+
*/
|
|
54
60
|
const DEFAULT_OAUTH_CONFIG = { redirectUrl: DEFAULT_OAUTH_REDIRECT_URL };
|
|
55
61
|
function getOAuthStoragePath(projectDir, name, cfg) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
const key = JSON.stringify({
|
|
63
|
+
projectDir,
|
|
64
|
+
name,
|
|
65
|
+
url: cfg.url,
|
|
66
|
+
redirectUrl: resolveOAuthRedirectUrl(cfg.oauth),
|
|
67
|
+
clientId: cfg.oauth?.clientId,
|
|
68
|
+
scopes: cfg.oauth?.scopes ?? []
|
|
69
|
+
});
|
|
70
|
+
return join(getAppDataDir(), "mcp-oauth", `${getStorageKeyFingerprint(key)}.json`);
|
|
65
71
|
}
|
|
66
72
|
function getStorageKeyFingerprint(value) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
let fingerprint = 14695981039346656037n;
|
|
74
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
75
|
+
fingerprint ^= BigInt(value.charCodeAt(i));
|
|
76
|
+
fingerprint = BigInt.asUintN(64, fingerprint * 1099511628211n);
|
|
77
|
+
}
|
|
78
|
+
return fingerprint.toString(16).padStart(16, "0");
|
|
73
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Create an MCP manager that wraps MCPClient with config-file discovery
|
|
82
|
+
* and per-server status tracking.
|
|
83
|
+
*/
|
|
74
84
|
function createMcpManager(projectDir, configDirName = DEFAULT_CONFIG_DIR, extraServers) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
return [...stderrLogs.get(name) ?? []];
|
|
481
|
-
}
|
|
482
|
-
};
|
|
85
|
+
/** Merge programmatic servers into a base config (highest priority). */
|
|
86
|
+
const applyExtraServers = (base) => {
|
|
87
|
+
if (!extraServers || Object.keys(extraServers).length === 0) return base;
|
|
88
|
+
return {
|
|
89
|
+
...base,
|
|
90
|
+
mcpServers: {
|
|
91
|
+
...base.mcpServers,
|
|
92
|
+
...extraServers
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
let config = applyExtraServers(loadMcpConfig(projectDir, configDirName));
|
|
97
|
+
let client = null;
|
|
98
|
+
let serverDefs = {};
|
|
99
|
+
let tools = {};
|
|
100
|
+
let serverStatuses = /* @__PURE__ */ new Map();
|
|
101
|
+
let stderrLogs = /* @__PURE__ */ new Map();
|
|
102
|
+
let initialized = false;
|
|
103
|
+
/** Per-server handlers that receive the OAuth authorization URL during authenticateServer(). */
|
|
104
|
+
const authUrlHandlers = /* @__PURE__ */ new Map();
|
|
105
|
+
/**
|
|
106
|
+
* Servers with an OAuth authorization flow currently in flight. Owned by the
|
|
107
|
+
* manager (not the TUI) so the state survives a `/mcp` selector being closed
|
|
108
|
+
* and reopened — the reopened selector reads it back off the server status and
|
|
109
|
+
* can still offer "Cancel authentication".
|
|
110
|
+
*/
|
|
111
|
+
const authenticatingServers = /* @__PURE__ */ new Set();
|
|
112
|
+
/**
|
|
113
|
+
* Servers whose in-flight authentication was cancelled by the caller. Set by
|
|
114
|
+
* cancelServerAuthentication() so the resolving authenticateServer() call can
|
|
115
|
+
* mark its failed status as a deliberate cancel rather than a genuine failure.
|
|
116
|
+
* This lives on the manager (not the TUI selector) so the signal survives the
|
|
117
|
+
* selector being closed and reopened mid-flow.
|
|
118
|
+
*/
|
|
119
|
+
const cancelledAuthServers = /* @__PURE__ */ new Set();
|
|
120
|
+
/** Overlay the manager-owned `authenticating` flag onto a status snapshot. */
|
|
121
|
+
const withAuthenticating = (status) => authenticatingServers.has(status.name) ? {
|
|
122
|
+
...status,
|
|
123
|
+
authenticating: true
|
|
124
|
+
} : status;
|
|
125
|
+
const MAX_STDERR_LINES = 200;
|
|
126
|
+
/** Hook into a server's stderr stream and buffer its output. */
|
|
127
|
+
function captureStderr(serverName) {
|
|
128
|
+
if (!client || typeof client.getServerStderr !== "function") return;
|
|
129
|
+
const stream = client.getServerStderr(serverName);
|
|
130
|
+
if (!stream) return;
|
|
131
|
+
let buffer = "";
|
|
132
|
+
const lines = stderrLogs.get(serverName) ?? [];
|
|
133
|
+
stderrLogs.set(serverName, lines);
|
|
134
|
+
stream.on("data", (chunk) => {
|
|
135
|
+
buffer += chunk.toString();
|
|
136
|
+
const parts = buffer.split("\n");
|
|
137
|
+
buffer = parts.pop();
|
|
138
|
+
for (const line of parts) if (line.trim()) {
|
|
139
|
+
lines.push(line);
|
|
140
|
+
if (lines.length > MAX_STDERR_LINES) lines.shift();
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
stream.on("end", () => {
|
|
144
|
+
if (buffer.trim()) {
|
|
145
|
+
lines.push(buffer);
|
|
146
|
+
if (lines.length > MAX_STDERR_LINES) lines.shift();
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
function createOAuthProvider(name, cfg) {
|
|
151
|
+
const oauth = cfg.oauth ?? (existsSync(getOAuthStoragePath(projectDir, name, cfg)) ? DEFAULT_OAUTH_CONFIG : void 0);
|
|
152
|
+
if (!oauth) return void 0;
|
|
153
|
+
const redirectUrl = resolveOAuthRedirectUrl(oauth);
|
|
154
|
+
return new MCPOAuthClientProvider({
|
|
155
|
+
redirectUrl,
|
|
156
|
+
clientMetadata: {
|
|
157
|
+
redirect_uris: [redirectUrl],
|
|
158
|
+
client_name: oauth.clientName ?? `Mastra Code MCP ${name}`,
|
|
159
|
+
grant_types: ["authorization_code", "refresh_token"],
|
|
160
|
+
response_types: ["code"],
|
|
161
|
+
...oauth.scopes?.length ? { scope: oauth.scopes.join(" ") } : {}
|
|
162
|
+
},
|
|
163
|
+
clientInformation: oauth.clientId ? {
|
|
164
|
+
client_id: oauth.clientId,
|
|
165
|
+
...oauth.clientSecret ? { client_secret: oauth.clientSecret } : {}
|
|
166
|
+
} : void 0,
|
|
167
|
+
storage: new FileOAuthStorage(getOAuthStoragePath(projectDir, name, cfg)),
|
|
168
|
+
onRedirectToAuthorization: (url) => {
|
|
169
|
+
authUrlHandlers.get(name)?.(url.toString());
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function buildServerDefs(servers) {
|
|
174
|
+
const defs = {};
|
|
175
|
+
for (const [name, cfg] of Object.entries(servers)) if ("url" in cfg) {
|
|
176
|
+
const httpCfg = cfg;
|
|
177
|
+
defs[name] = {
|
|
178
|
+
url: new URL(httpCfg.url),
|
|
179
|
+
requestInit: httpCfg.headers ? { headers: httpCfg.headers } : void 0,
|
|
180
|
+
authProvider: createOAuthProvider(name, httpCfg)
|
|
181
|
+
};
|
|
182
|
+
} else defs[name] = {
|
|
183
|
+
command: cfg.command,
|
|
184
|
+
args: cfg.args,
|
|
185
|
+
env: cfg.env,
|
|
186
|
+
stderr: "pipe"
|
|
187
|
+
};
|
|
188
|
+
return defs;
|
|
189
|
+
}
|
|
190
|
+
async function connectAndCollectTools() {
|
|
191
|
+
const servers = config.mcpServers;
|
|
192
|
+
if (!servers || Object.keys(servers).length === 0) return;
|
|
193
|
+
const serverNames = Object.keys(servers);
|
|
194
|
+
for (const name of serverNames) serverStatuses.set(name, {
|
|
195
|
+
name,
|
|
196
|
+
connected: false,
|
|
197
|
+
connecting: true,
|
|
198
|
+
toolCount: 0,
|
|
199
|
+
toolNames: [],
|
|
200
|
+
transport: getTransport(servers[name])
|
|
201
|
+
});
|
|
202
|
+
serverDefs = buildServerDefs(servers);
|
|
203
|
+
client = new MCPClient({
|
|
204
|
+
id: "mastra-code-mcp",
|
|
205
|
+
servers: serverDefs,
|
|
206
|
+
timeout: MASTRACODE_MCP_TIMEOUT_MS
|
|
207
|
+
});
|
|
208
|
+
try {
|
|
209
|
+
const { toolsets, errors } = await client.listToolsetsWithErrors();
|
|
210
|
+
const typedToolsets = toolsets;
|
|
211
|
+
for (const [serverName, serverTools] of Object.entries(typedToolsets)) for (const [toolName, toolConfig] of Object.entries(serverTools)) tools[`${serverName}_${toolName}`] = toolConfig;
|
|
212
|
+
for (const name of serverNames) {
|
|
213
|
+
const serverTools = typedToolsets[name];
|
|
214
|
+
if (serverTools && Object.keys(serverTools).length > 0) {
|
|
215
|
+
const toolNames = Object.keys(serverTools).map((t) => `${name}_${t}`);
|
|
216
|
+
serverStatuses.set(name, {
|
|
217
|
+
name,
|
|
218
|
+
connected: true,
|
|
219
|
+
toolCount: toolNames.length,
|
|
220
|
+
toolNames,
|
|
221
|
+
transport: getTransport(servers[name])
|
|
222
|
+
});
|
|
223
|
+
} else {
|
|
224
|
+
const error = errors[name] ?? "Failed to connect";
|
|
225
|
+
serverStatuses.set(name, {
|
|
226
|
+
name,
|
|
227
|
+
connected: false,
|
|
228
|
+
toolCount: 0,
|
|
229
|
+
toolNames: [],
|
|
230
|
+
transport: getTransport(servers[name]),
|
|
231
|
+
error,
|
|
232
|
+
...serverNeedsAuth(name, servers[name], error) ? { needsAuth: true } : {}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
for (const name of serverNames) captureStderr(name);
|
|
237
|
+
} catch (error) {
|
|
238
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
239
|
+
for (const name of serverNames) serverStatuses.set(name, {
|
|
240
|
+
name,
|
|
241
|
+
connected: false,
|
|
242
|
+
toolCount: 0,
|
|
243
|
+
toolNames: [],
|
|
244
|
+
transport: getTransport(servers[name]),
|
|
245
|
+
error: errMsg,
|
|
246
|
+
...serverNeedsAuth(name, servers[name], errMsg) ? { needsAuth: true } : {}
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Whether a failed HTTP server is blocked on OAuth authorization.
|
|
252
|
+
*
|
|
253
|
+
* Provider-backed servers report the exact state tracked by `@mastra/mcp`.
|
|
254
|
+
* Bare `url` entries carry no provider until the user authenticates, so the
|
|
255
|
+
* signal is a 401 in the connect error — surfaced either as the status text
|
|
256
|
+
* or as the RFC 6750 `invalid_token` bearer error code in the response body.
|
|
257
|
+
*/
|
|
258
|
+
function serverNeedsAuth(name, cfg, error) {
|
|
259
|
+
if (getTransport(cfg) !== "http") return false;
|
|
260
|
+
if (client?.getServerAuthState?.(name) === "needs-auth") return true;
|
|
261
|
+
if (serverDefs[name]?.authProvider) return false;
|
|
262
|
+
return error !== void 0 && /\b401\b|unauthorized|invalid_token/i.test(error);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Runs a single-server connect action (reconnect or authenticate), then
|
|
266
|
+
* refreshes that server's tools and status from the client.
|
|
267
|
+
*/
|
|
268
|
+
async function connectSingleServer(name, cfg, connect) {
|
|
269
|
+
const transport = getTransport(cfg);
|
|
270
|
+
const prefix = `${name}_`;
|
|
271
|
+
for (const key of Object.keys(tools)) if (key.startsWith(prefix)) delete tools[key];
|
|
272
|
+
stderrLogs.delete(name);
|
|
273
|
+
serverStatuses.set(name, {
|
|
274
|
+
name,
|
|
275
|
+
connected: false,
|
|
276
|
+
connecting: true,
|
|
277
|
+
toolCount: 0,
|
|
278
|
+
toolNames: [],
|
|
279
|
+
transport
|
|
280
|
+
});
|
|
281
|
+
try {
|
|
282
|
+
await connect();
|
|
283
|
+
captureStderr(name);
|
|
284
|
+
const { toolsets, errors } = await client.listToolsetsWithErrors();
|
|
285
|
+
const serverTools = toolsets[name];
|
|
286
|
+
const serverError = errors[name];
|
|
287
|
+
if (serverError) {
|
|
288
|
+
const status = {
|
|
289
|
+
name,
|
|
290
|
+
connected: false,
|
|
291
|
+
toolCount: 0,
|
|
292
|
+
toolNames: [],
|
|
293
|
+
transport,
|
|
294
|
+
error: serverError,
|
|
295
|
+
...serverNeedsAuth(name, cfg, serverError) ? { needsAuth: true } : {}
|
|
296
|
+
};
|
|
297
|
+
serverStatuses.set(name, status);
|
|
298
|
+
return status;
|
|
299
|
+
} else if (serverTools && Object.keys(serverTools).length > 0) {
|
|
300
|
+
const toolNames = Object.keys(serverTools).map((t) => `${name}_${t}`);
|
|
301
|
+
for (const [toolName, toolConfig] of Object.entries(serverTools)) tools[`${name}_${toolName}`] = toolConfig;
|
|
302
|
+
const status = {
|
|
303
|
+
name,
|
|
304
|
+
connected: true,
|
|
305
|
+
toolCount: toolNames.length,
|
|
306
|
+
toolNames,
|
|
307
|
+
transport
|
|
308
|
+
};
|
|
309
|
+
serverStatuses.set(name, status);
|
|
310
|
+
return status;
|
|
311
|
+
} else {
|
|
312
|
+
const status = {
|
|
313
|
+
name,
|
|
314
|
+
connected: false,
|
|
315
|
+
toolCount: 0,
|
|
316
|
+
toolNames: [],
|
|
317
|
+
transport,
|
|
318
|
+
error: "Failed to connect"
|
|
319
|
+
};
|
|
320
|
+
serverStatuses.set(name, status);
|
|
321
|
+
return status;
|
|
322
|
+
}
|
|
323
|
+
} catch (error) {
|
|
324
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
325
|
+
const status = {
|
|
326
|
+
name,
|
|
327
|
+
connected: false,
|
|
328
|
+
toolCount: 0,
|
|
329
|
+
toolNames: [],
|
|
330
|
+
transport,
|
|
331
|
+
error: errMsg,
|
|
332
|
+
...serverNeedsAuth(name, cfg, errMsg) ? { needsAuth: true } : {}
|
|
333
|
+
};
|
|
334
|
+
serverStatuses.set(name, status);
|
|
335
|
+
return status;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
async function disconnect() {
|
|
339
|
+
if (client) {
|
|
340
|
+
try {
|
|
341
|
+
await client.disconnect();
|
|
342
|
+
} catch {}
|
|
343
|
+
client = null;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return {
|
|
347
|
+
async init() {
|
|
348
|
+
if (initialized) return;
|
|
349
|
+
await connectAndCollectTools();
|
|
350
|
+
initialized = true;
|
|
351
|
+
},
|
|
352
|
+
async initInBackground() {
|
|
353
|
+
await this.init();
|
|
354
|
+
const statuses = Array.from(serverStatuses.values());
|
|
355
|
+
const connected = statuses.filter((s) => s.connected);
|
|
356
|
+
return {
|
|
357
|
+
connected,
|
|
358
|
+
failed: statuses.filter((s) => !s.connected),
|
|
359
|
+
skipped: [...config.skippedServers ?? []],
|
|
360
|
+
totalTools: connected.reduce((sum, s) => sum + s.toolCount, 0)
|
|
361
|
+
};
|
|
362
|
+
},
|
|
363
|
+
async reload() {
|
|
364
|
+
await disconnect();
|
|
365
|
+
config = applyExtraServers(loadMcpConfig(projectDir, configDirName));
|
|
366
|
+
tools = {};
|
|
367
|
+
serverStatuses = /* @__PURE__ */ new Map();
|
|
368
|
+
stderrLogs = /* @__PURE__ */ new Map();
|
|
369
|
+
initialized = false;
|
|
370
|
+
await connectAndCollectTools();
|
|
371
|
+
initialized = true;
|
|
372
|
+
},
|
|
373
|
+
async reconnectServer(name) {
|
|
374
|
+
const cfg = config.mcpServers?.[name];
|
|
375
|
+
if (!cfg) return {
|
|
376
|
+
name,
|
|
377
|
+
connected: false,
|
|
378
|
+
toolCount: 0,
|
|
379
|
+
toolNames: [],
|
|
380
|
+
transport: "stdio",
|
|
381
|
+
error: `Server "${name}" not found in config`
|
|
382
|
+
};
|
|
383
|
+
if (!client) return {
|
|
384
|
+
name,
|
|
385
|
+
connected: false,
|
|
386
|
+
toolCount: 0,
|
|
387
|
+
toolNames: [],
|
|
388
|
+
transport: getTransport(cfg),
|
|
389
|
+
error: "MCP client not initialized"
|
|
390
|
+
};
|
|
391
|
+
return connectSingleServer(name, cfg, () => client.reconnectServer(name));
|
|
392
|
+
},
|
|
393
|
+
async authenticateServer(name, options) {
|
|
394
|
+
const cfg = config.mcpServers?.[name];
|
|
395
|
+
if (!cfg) return {
|
|
396
|
+
name,
|
|
397
|
+
connected: false,
|
|
398
|
+
toolCount: 0,
|
|
399
|
+
toolNames: [],
|
|
400
|
+
transport: "stdio",
|
|
401
|
+
error: `Server "${name}" not found in config`
|
|
402
|
+
};
|
|
403
|
+
if (!client) return {
|
|
404
|
+
name,
|
|
405
|
+
connected: false,
|
|
406
|
+
toolCount: 0,
|
|
407
|
+
toolNames: [],
|
|
408
|
+
transport: getTransport(cfg),
|
|
409
|
+
error: "MCP client not initialized"
|
|
410
|
+
};
|
|
411
|
+
if (getTransport(cfg) !== "http") return {
|
|
412
|
+
name,
|
|
413
|
+
connected: false,
|
|
414
|
+
toolCount: 0,
|
|
415
|
+
toolNames: [],
|
|
416
|
+
transport: "stdio",
|
|
417
|
+
error: `Server "${name}" uses stdio transport, which does not support OAuth`
|
|
418
|
+
};
|
|
419
|
+
const def = serverDefs[name];
|
|
420
|
+
if (def?.url && !def.authProvider) def.authProvider = createOAuthProvider(name, {
|
|
421
|
+
...cfg,
|
|
422
|
+
oauth: DEFAULT_OAUTH_CONFIG
|
|
423
|
+
});
|
|
424
|
+
if (authenticatingServers.has(name)) {
|
|
425
|
+
const current = serverStatuses.get(name);
|
|
426
|
+
return {
|
|
427
|
+
name,
|
|
428
|
+
connected: current?.connected ?? false,
|
|
429
|
+
connecting: current?.connecting,
|
|
430
|
+
needsAuth: current?.needsAuth,
|
|
431
|
+
toolCount: current?.toolCount ?? 0,
|
|
432
|
+
toolNames: current?.toolNames ?? [],
|
|
433
|
+
transport: current?.transport ?? getTransport(cfg),
|
|
434
|
+
error: `Authentication for "${name}" is already in progress`
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
if (options?.onAuthorizationUrl) authUrlHandlers.set(name, options.onAuthorizationUrl);
|
|
438
|
+
authenticatingServers.add(name);
|
|
439
|
+
cancelledAuthServers.delete(name);
|
|
440
|
+
try {
|
|
441
|
+
const result = await connectSingleServer(name, cfg, () => client.authenticate(name, options?.timeoutMs === void 0 ? void 0 : { timeoutMs: options.timeoutMs }));
|
|
442
|
+
const finalStatus = cancelledAuthServers.has(name) && !result.connected ? {
|
|
443
|
+
...result,
|
|
444
|
+
cancelled: true
|
|
445
|
+
} : result;
|
|
446
|
+
serverStatuses.set(name, finalStatus);
|
|
447
|
+
return finalStatus;
|
|
448
|
+
} finally {
|
|
449
|
+
authUrlHandlers.delete(name);
|
|
450
|
+
authenticatingServers.delete(name);
|
|
451
|
+
cancelledAuthServers.delete(name);
|
|
452
|
+
}
|
|
453
|
+
},
|
|
454
|
+
async cancelServerAuthentication(name) {
|
|
455
|
+
if (!client) return false;
|
|
456
|
+
cancelledAuthServers.add(name);
|
|
457
|
+
const cancelled = await client.cancelAuthentication(name);
|
|
458
|
+
if (!cancelled) cancelledAuthServers.delete(name);
|
|
459
|
+
return cancelled;
|
|
460
|
+
},
|
|
461
|
+
disconnect,
|
|
462
|
+
getTools() {
|
|
463
|
+
return { ...tools };
|
|
464
|
+
},
|
|
465
|
+
hasServers() {
|
|
466
|
+
const hasConfigured = config.mcpServers !== void 0 && Object.keys(config.mcpServers).length > 0;
|
|
467
|
+
const hasSkipped = config.skippedServers !== void 0 && config.skippedServers.length > 0;
|
|
468
|
+
return hasConfigured || hasSkipped;
|
|
469
|
+
},
|
|
470
|
+
getServerStatuses() {
|
|
471
|
+
return Array.from(serverStatuses.values(), withAuthenticating);
|
|
472
|
+
},
|
|
473
|
+
getSkippedServers() {
|
|
474
|
+
return [...config.skippedServers ?? []];
|
|
475
|
+
},
|
|
476
|
+
getConfigPaths() {
|
|
477
|
+
return {
|
|
478
|
+
project: getProjectMcpPath(projectDir, configDirName),
|
|
479
|
+
global: getGlobalMcpPath(configDirName),
|
|
480
|
+
claude: getClaudeSettingsPath(projectDir)
|
|
481
|
+
};
|
|
482
|
+
},
|
|
483
|
+
getConfig() {
|
|
484
|
+
return config;
|
|
485
|
+
},
|
|
486
|
+
getServerLogs(name) {
|
|
487
|
+
return [...stderrLogs.get(name) ?? []];
|
|
488
|
+
}
|
|
489
|
+
};
|
|
483
490
|
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
491
|
+
//#endregion
|
|
492
|
+
export { createMcpManager };
|
|
493
|
+
|
|
487
494
|
//# sourceMappingURL=manager.js.map
|