@aexol/spectral 0.2.11 → 0.2.13
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/dist/mcp/proxy-modes.js +2 -7
- package/dist/mcp/server-manager.js +34 -33
- package/package.json +1 -1
package/dist/mcp/proxy-modes.js
CHANGED
|
@@ -24,13 +24,8 @@ async function attemptAutoAuth(state, serverName) {
|
|
|
24
24
|
return { status: "skipped" };
|
|
25
25
|
}
|
|
26
26
|
const oauthConfig = definition.oauth;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return {
|
|
30
|
-
status: "failed",
|
|
31
|
-
message: getAuthRequiredMessage(state, serverName, `Server "${serverName}" requires OAuth authentication. Run /mcp-auth ${serverName} in an interactive session.`),
|
|
32
|
-
};
|
|
33
|
-
}
|
|
27
|
+
// OAuth flow works even without TUI — open() uses the system browser and the
|
|
28
|
+
// callback server handles the redirect.
|
|
34
29
|
try {
|
|
35
30
|
await authenticate(serverName, definition.url, definition);
|
|
36
31
|
return { status: "success" };
|
|
@@ -43,33 +43,33 @@ export class McpServerManager {
|
|
|
43
43
|
async createConnection(name, definition) {
|
|
44
44
|
const client = this.createClient(name);
|
|
45
45
|
let transport;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
try {
|
|
47
|
+
if (definition.command) {
|
|
48
|
+
let command = definition.command;
|
|
49
|
+
let args = definition.args ?? [];
|
|
50
|
+
if (command === "npx" || command === "npm") {
|
|
51
|
+
const resolved = await resolveNpxBinary(command, args);
|
|
52
|
+
if (resolved) {
|
|
53
|
+
command = resolved.isJs ? "node" : resolved.binPath;
|
|
54
|
+
args = resolved.isJs ? [resolved.binPath, ...resolved.extraArgs] : resolved.extraArgs;
|
|
55
|
+
logger.debug(`${name} resolved to ${resolved.binPath} (skipping npm parent)`);
|
|
56
|
+
}
|
|
55
57
|
}
|
|
58
|
+
transport = new StdioClientTransport({
|
|
59
|
+
command,
|
|
60
|
+
args,
|
|
61
|
+
env: resolveEnv(definition.env),
|
|
62
|
+
cwd: resolveConfigPath(definition.cwd),
|
|
63
|
+
stderr: definition.debug ? "inherit" : "ignore",
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
else if (definition.url) {
|
|
67
|
+
// HTTP transport with fallback
|
|
68
|
+
transport = await this.createHttpTransport(definition, name);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
throw new Error(`Server ${name} has no command or url`);
|
|
56
72
|
}
|
|
57
|
-
transport = new StdioClientTransport({
|
|
58
|
-
command,
|
|
59
|
-
args,
|
|
60
|
-
env: resolveEnv(definition.env),
|
|
61
|
-
cwd: resolveConfigPath(definition.cwd),
|
|
62
|
-
stderr: definition.debug ? "inherit" : "ignore",
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
else if (definition.url) {
|
|
66
|
-
// HTTP transport with fallback
|
|
67
|
-
transport = await this.createHttpTransport(definition, name);
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
throw new Error(`Server ${name} has no command or url`);
|
|
71
|
-
}
|
|
72
|
-
try {
|
|
73
73
|
await client.connect(transport);
|
|
74
74
|
this.attachAdapterNotificationHandlers(name, client);
|
|
75
75
|
// Discover tools and resources
|
|
@@ -89,14 +89,17 @@ export class McpServerManager {
|
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
91
|
catch (error) {
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
await client.close().catch(() => { });
|
|
92
|
+
// Clean up client and transport on any error.
|
|
93
|
+
await client.close().catch(() => { });
|
|
94
|
+
if (transport) {
|
|
96
95
|
await transport.close().catch(() => { });
|
|
96
|
+
}
|
|
97
|
+
// Check for UnauthorizedError — server requires OAuth.
|
|
98
|
+
// This can fire from createHttpTransport probe or client.connect.
|
|
99
|
+
if (error instanceof UnauthorizedError && supportsOAuth(definition)) {
|
|
97
100
|
return {
|
|
98
101
|
client,
|
|
99
|
-
transport,
|
|
102
|
+
transport: transport,
|
|
100
103
|
definition,
|
|
101
104
|
tools: [],
|
|
102
105
|
resources: [],
|
|
@@ -105,9 +108,6 @@ export class McpServerManager {
|
|
|
105
108
|
status: "needs-auth",
|
|
106
109
|
};
|
|
107
110
|
}
|
|
108
|
-
// Clean up both client and transport on any error
|
|
109
|
-
await client.close().catch(() => { });
|
|
110
|
-
await transport.close().catch(() => { });
|
|
111
111
|
throw error;
|
|
112
112
|
}
|
|
113
113
|
}
|
|
@@ -140,6 +140,7 @@ export class McpServerManager {
|
|
|
140
140
|
clientId: definition.oauth?.clientId,
|
|
141
141
|
clientSecret: definition.oauth?.clientSecret,
|
|
142
142
|
scope: definition.oauth?.scope,
|
|
143
|
+
redirectUri: definition.oauth?.redirectUri,
|
|
143
144
|
};
|
|
144
145
|
authProvider = new McpOAuthProvider(serverName, definition.url, oauthConfig, {
|
|
145
146
|
onRedirect: async (_authUrl) => {
|