@atlasharness/atlascode 0.1.75 → 0.1.77
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/cli.js +108 -9
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -167950,7 +167950,7 @@ var init_hooks3 = __esm(() => {
|
|
|
167950
167950
|
});
|
|
167951
167951
|
|
|
167952
167952
|
// src/tui/services/mcp/types.ts
|
|
167953
|
-
var ConfigScopeSchema3, TransportSchema2, McpStdioServerConfigSchema3, McpXaaConfigSchema2, McpOAuthConfigSchema2, McpSSEServerConfigSchema3, McpSSEIDEServerConfigSchema, McpWebSocketIDEServerConfigSchema, McpHTTPServerConfigSchema2, McpWebSocketServerConfigSchema2, McpSdkServerConfigSchema2, McpServerConfigSchema2, McpJsonConfigSchema2;
|
|
167953
|
+
var ConfigScopeSchema3, TransportSchema2, McpStdioServerConfigSchema3, McpXaaConfigSchema2, McpOauthGatedMarkerSchema, McpOAuthConfigSchema2, McpSSEServerConfigSchema3, McpSSEIDEServerConfigSchema, McpWebSocketIDEServerConfigSchema, McpHTTPServerConfigSchema2, McpWebSocketServerConfigSchema2, McpSdkServerConfigSchema2, McpServerConfigSchema2, McpJsonConfigSchema2;
|
|
167954
167954
|
var init_types9 = __esm(() => {
|
|
167955
167955
|
init_v4();
|
|
167956
167956
|
ConfigScopeSchema3 = lazySchema2(() => _enum([
|
|
@@ -167970,6 +167970,7 @@ var init_types9 = __esm(() => {
|
|
|
167970
167970
|
env: record(string2(), string2()).optional()
|
|
167971
167971
|
}));
|
|
167972
167972
|
McpXaaConfigSchema2 = lazySchema2(() => boolean2());
|
|
167973
|
+
McpOauthGatedMarkerSchema = lazySchema2(() => boolean2().optional());
|
|
167973
167974
|
McpOAuthConfigSchema2 = lazySchema2(() => object({
|
|
167974
167975
|
clientId: string2().optional(),
|
|
167975
167976
|
callbackPort: number2().int().positive().optional(),
|
|
@@ -167986,7 +167987,8 @@ var init_types9 = __esm(() => {
|
|
|
167986
167987
|
url: string2(),
|
|
167987
167988
|
headers: record(string2(), string2()).optional(),
|
|
167988
167989
|
headersHelper: string2().optional(),
|
|
167989
|
-
oauth: McpOAuthConfigSchema2().optional()
|
|
167990
|
+
oauth: McpOAuthConfigSchema2().optional(),
|
|
167991
|
+
oauthGated: McpOauthGatedMarkerSchema()
|
|
167990
167992
|
}));
|
|
167991
167993
|
McpSSEIDEServerConfigSchema = lazySchema2(() => object({
|
|
167992
167994
|
type: literal("sse-ide"),
|
|
@@ -168006,7 +168008,8 @@ var init_types9 = __esm(() => {
|
|
|
168006
168008
|
url: string2(),
|
|
168007
168009
|
headers: record(string2(), string2()).optional(),
|
|
168008
168010
|
headersHelper: string2().optional(),
|
|
168009
|
-
oauth: McpOAuthConfigSchema2().optional()
|
|
168011
|
+
oauth: McpOAuthConfigSchema2().optional(),
|
|
168012
|
+
oauthGated: McpOauthGatedMarkerSchema()
|
|
168010
168013
|
}));
|
|
168011
168014
|
McpWebSocketServerConfigSchema2 = lazySchema2(() => object({
|
|
168012
168015
|
type: literal("ws"),
|
|
@@ -193121,6 +193124,63 @@ var init_oauthPort = __esm(() => {
|
|
|
193121
193124
|
REDIRECT_PORT_RANGE = getPlatform3() === "windows" ? { min: 39152, max: 49151 } : { min: 49152, max: 65535 };
|
|
193122
193125
|
});
|
|
193123
193126
|
|
|
193127
|
+
// src/tui/services/mcp/oauthScopeGate.ts
|
|
193128
|
+
function parseMcpOauthTrustedServersEnv(raw) {
|
|
193129
|
+
if (raw === undefined || raw === null) {
|
|
193130
|
+
return new Set;
|
|
193131
|
+
}
|
|
193132
|
+
const names = new Set;
|
|
193133
|
+
for (const part of raw.split(",")) {
|
|
193134
|
+
const name = part.trim().toLowerCase();
|
|
193135
|
+
if (name !== "") {
|
|
193136
|
+
names.add(name);
|
|
193137
|
+
}
|
|
193138
|
+
}
|
|
193139
|
+
return names;
|
|
193140
|
+
}
|
|
193141
|
+
function getMcpOauthTrustedServers() {
|
|
193142
|
+
return parseMcpOauthTrustedServersEnv(process.env[MCP_OAUTH_TRUSTED_SERVERS_ENV]);
|
|
193143
|
+
}
|
|
193144
|
+
function isMcpOauthUntrustedScope(scope, pluginSource) {
|
|
193145
|
+
if (scope === "project") {
|
|
193146
|
+
return true;
|
|
193147
|
+
}
|
|
193148
|
+
return scope === "dynamic" && pluginSource !== undefined;
|
|
193149
|
+
}
|
|
193150
|
+
function isMcpOauthBlockGated(serverName, scope, pluginSource, allowlist = getMcpOauthTrustedServers()) {
|
|
193151
|
+
if (!isMcpOauthUntrustedScope(scope, pluginSource)) {
|
|
193152
|
+
return false;
|
|
193153
|
+
}
|
|
193154
|
+
return !allowlist.has(serverName.toLowerCase());
|
|
193155
|
+
}
|
|
193156
|
+
function applyMcpOauthScopeGate(serverName, server) {
|
|
193157
|
+
if (server.type !== "sse" && server.type !== "http") {
|
|
193158
|
+
return server;
|
|
193159
|
+
}
|
|
193160
|
+
const remote = server;
|
|
193161
|
+
if (remote.oauth === undefined) {
|
|
193162
|
+
return server;
|
|
193163
|
+
}
|
|
193164
|
+
if (!isMcpOauthBlockGated(serverName, server.scope, server.pluginSource)) {
|
|
193165
|
+
return server;
|
|
193166
|
+
}
|
|
193167
|
+
const { oauth: _gatedOAuth, ...rest } = remote;
|
|
193168
|
+
return { ...rest, oauthGated: true };
|
|
193169
|
+
}
|
|
193170
|
+
function isMcpOauthDisplayGated(serverName, config) {
|
|
193171
|
+
if (config.oauthGated === true) {
|
|
193172
|
+
return true;
|
|
193173
|
+
}
|
|
193174
|
+
if (config.oauth === undefined || config.oauth === null) {
|
|
193175
|
+
return false;
|
|
193176
|
+
}
|
|
193177
|
+
return isMcpOauthBlockGated(serverName, config.scope, config.pluginSource);
|
|
193178
|
+
}
|
|
193179
|
+
function mcpOauthGatedMessage(serverName) {
|
|
193180
|
+
return `MCP server "${serverName}" 的 oauth 块为 untrusted scope(project/plugin 来源),` + `操作者 allowlist 后启用:将 server 名加入 env ${MCP_OAUTH_TRUSTED_SERVERS_ENV}(逗号分隔)后重启。` + `当前该 oauth 块整体视为缺席,不发起 OAuth 流。`;
|
|
193181
|
+
}
|
|
193182
|
+
var MCP_OAUTH_TRUSTED_SERVERS_ENV = "ATLAS_MCP_OAUTH_TRUSTED_SERVERS";
|
|
193183
|
+
|
|
193124
193184
|
// src/tui/services/mcp/envExpansion.ts
|
|
193125
193185
|
function expandEnvVarsInString2(value) {
|
|
193126
193186
|
const missingVars = [];
|
|
@@ -193482,7 +193542,7 @@ function addScopeToServers(servers, scope) {
|
|
|
193482
193542
|
}
|
|
193483
193543
|
const scopedServers = {};
|
|
193484
193544
|
for (const [name, config] of Object.entries(servers)) {
|
|
193485
|
-
scopedServers[name] = { ...config, scope };
|
|
193545
|
+
scopedServers[name] = applyMcpOauthScopeGate(name, { ...config, scope });
|
|
193486
193546
|
}
|
|
193487
193547
|
return scopedServers;
|
|
193488
193548
|
}
|
|
@@ -194169,7 +194229,7 @@ async function getMcpConfigs(dynamicServers = {}, extraDedupTargets = Promise.re
|
|
|
194169
194229
|
if (!isMcpServerAllowedByPolicy(name, serverConfig)) {
|
|
194170
194230
|
continue;
|
|
194171
194231
|
}
|
|
194172
|
-
filtered[name] = serverConfig;
|
|
194232
|
+
filtered[name] = applyMcpOauthScopeGate(name, serverConfig);
|
|
194173
194233
|
}
|
|
194174
194234
|
return { servers: filtered, errors: mcpErrors };
|
|
194175
194235
|
}
|
|
@@ -195538,6 +195598,9 @@ async function performMCPXaaAuth(serverName, serverConfig, onAuthorizationUrl, a
|
|
|
195538
195598
|
}
|
|
195539
195599
|
}
|
|
195540
195600
|
async function performMCPOAuthFlow(serverName, serverConfig, onAuthorizationUrl, abortSignal, options) {
|
|
195601
|
+
if (isMcpOauthDisplayGated(serverName, serverConfig)) {
|
|
195602
|
+
throw new Error(mcpOauthGatedMessage(serverName));
|
|
195603
|
+
}
|
|
195541
195604
|
if (serverConfig.oauth?.xaa) {
|
|
195542
195605
|
if (!isXaaEnabled()) {
|
|
195543
195606
|
throw new Error(`XAA is not enabled (set ATLAS_ENABLE_XAA=1). Remove 'oauth.xaa' from server '${serverName}' to use the standard consent flow.`);
|
|
@@ -196568,6 +196631,14 @@ function createMcpAuthTool(serverName, config) {
|
|
|
196568
196631
|
}
|
|
196569
196632
|
};
|
|
196570
196633
|
}
|
|
196634
|
+
if (isMcpOauthDisplayGated(serverName, config)) {
|
|
196635
|
+
return {
|
|
196636
|
+
data: {
|
|
196637
|
+
status: "error",
|
|
196638
|
+
message: mcpOauthGatedMessage(serverName)
|
|
196639
|
+
}
|
|
196640
|
+
};
|
|
196641
|
+
}
|
|
196571
196642
|
const sseOrHttpConfig = config;
|
|
196572
196643
|
let resolveAuthUrl;
|
|
196573
196644
|
const authUrlPromise = new Promise((resolve) => {
|
|
@@ -368265,6 +368336,10 @@ function MCPListPanel(t0) {
|
|
|
368265
368336
|
statusIcon = color("error", theme)(figures_default.cross);
|
|
368266
368337
|
statusText = "failed";
|
|
368267
368338
|
}
|
|
368339
|
+
if (server_3.oauthGated === true) {
|
|
368340
|
+
statusIcon = color("warning", theme)(figures_default.triangleUpOutline);
|
|
368341
|
+
statusText = "oauth gated (untrusted scope) — operator allowlist to enable: " + MCP_OAUTH_TRUSTED_SERVERS_ENV;
|
|
368342
|
+
}
|
|
368268
368343
|
}
|
|
368269
368344
|
}
|
|
368270
368345
|
}
|
|
@@ -369738,6 +369813,7 @@ function MCPRemoteServerMenu({
|
|
|
369738
369813
|
}
|
|
369739
369814
|
}, []);
|
|
369740
369815
|
const isEffectivelyAuthenticated = server.isAuthenticated || server.client.type === "connected" && serverToolsCount > 0;
|
|
369816
|
+
const isOauthGated = server.config ? isMcpOauthDisplayGated(server.name, server.config) : false;
|
|
369741
369817
|
const reconnectMcpServer = useMcpReconnect();
|
|
369742
369818
|
useKeybinding("confirm:no", () => {
|
|
369743
369819
|
authAbortControllerRef.current?.abort();
|
|
@@ -370089,7 +370165,13 @@ function MCPRemoteServerMenu({
|
|
|
370089
370165
|
bold: true,
|
|
370090
370166
|
children: "Auth: "
|
|
370091
370167
|
}, undefined, false, undefined, this),
|
|
370092
|
-
|
|
370168
|
+
isOauthGated ? /* @__PURE__ */ jsx_dev_runtime193.jsxDEV(ThemedText, {
|
|
370169
|
+
children: [
|
|
370170
|
+
color("warning", theme)(figures_default.triangleUpOutline),
|
|
370171
|
+
" oauth gated (untrusted scope) — operator allowlist to enable: ",
|
|
370172
|
+
MCP_OAUTH_TRUSTED_SERVERS_ENV
|
|
370173
|
+
]
|
|
370174
|
+
}, undefined, true, undefined, this) : isEffectivelyAuthenticated ? /* @__PURE__ */ jsx_dev_runtime193.jsxDEV(ThemedText, {
|
|
370093
370175
|
children: [
|
|
370094
370176
|
color("success", theme)(figures_default.tick),
|
|
370095
370177
|
" authenticated"
|
|
@@ -371111,6 +371193,7 @@ function MCPSettings(t0) {
|
|
|
371111
371193
|
...baseInfo,
|
|
371112
371194
|
transport: "sse",
|
|
371113
371195
|
isAuthenticated,
|
|
371196
|
+
oauthGated: isMcpOauthDisplayGated(client_0.name, client_0.config),
|
|
371114
371197
|
config: client_0.config
|
|
371115
371198
|
};
|
|
371116
371199
|
} else {
|
|
@@ -371119,6 +371202,7 @@ function MCPSettings(t0) {
|
|
|
371119
371202
|
...baseInfo,
|
|
371120
371203
|
transport: "http",
|
|
371121
371204
|
isAuthenticated,
|
|
371205
|
+
oauthGated: isMcpOauthDisplayGated(client_0.name, client_0.config),
|
|
371122
371206
|
config: client_0.config
|
|
371123
371207
|
};
|
|
371124
371208
|
} else {
|
|
@@ -434365,8 +434449,19 @@ function withoutMcpOauthCimdVars(env) {
|
|
|
434365
434449
|
}
|
|
434366
434450
|
return out;
|
|
434367
434451
|
}
|
|
434452
|
+
function withoutMcpOauthTrustedServersVars(env) {
|
|
434453
|
+
if (!env)
|
|
434454
|
+
return {};
|
|
434455
|
+
const out = {};
|
|
434456
|
+
for (const [key, value] of Object.entries(env)) {
|
|
434457
|
+
if (key.toUpperCase() !== MCP_OAUTH_TRUSTED_SERVERS_ENV) {
|
|
434458
|
+
out[key] = value;
|
|
434459
|
+
}
|
|
434460
|
+
}
|
|
434461
|
+
return out;
|
|
434462
|
+
}
|
|
434368
434463
|
function filterSettingsEnv(env) {
|
|
434369
|
-
return withoutCcdSpawnEnvKeys(withoutMcpOauthCimdVars(withoutHostManagedProviderVars(withoutSSHTunnelVars(env))));
|
|
434464
|
+
return withoutCcdSpawnEnvKeys(withoutMcpOauthTrustedServersVars(withoutMcpOauthCimdVars(withoutHostManagedProviderVars(withoutSSHTunnelVars(env)))));
|
|
434370
434465
|
}
|
|
434371
434466
|
function applySafeConfigEnvironmentVariables2() {
|
|
434372
434467
|
if (ccdSpawnEnvKeys === undefined) {
|
|
@@ -489999,7 +490094,9 @@ async function mcpGetHandler2(name) {
|
|
|
489999
490094
|
console.log(` ${key}: ${value}`);
|
|
490000
490095
|
}
|
|
490001
490096
|
}
|
|
490002
|
-
if (
|
|
490097
|
+
if (isMcpOauthDisplayGated(name, server)) {
|
|
490098
|
+
console.log(` OAuth: gated (untrusted scope) — operator allowlist to enable: ${MCP_OAUTH_TRUSTED_SERVERS_ENV}`);
|
|
490099
|
+
} else if (server.oauth?.clientId || server.oauth?.callbackPort || server.oauth?.clientMetadataUrl) {
|
|
490003
490100
|
const parts = [];
|
|
490004
490101
|
if (server.oauth.clientId) {
|
|
490005
490102
|
parts.push("client_id configured");
|
|
@@ -490022,7 +490119,9 @@ async function mcpGetHandler2(name) {
|
|
|
490022
490119
|
console.log(` ${key}: ${value}`);
|
|
490023
490120
|
}
|
|
490024
490121
|
}
|
|
490025
|
-
if (
|
|
490122
|
+
if (isMcpOauthDisplayGated(name, server)) {
|
|
490123
|
+
console.log(` OAuth: gated (untrusted scope) — operator allowlist to enable: ${MCP_OAUTH_TRUSTED_SERVERS_ENV}`);
|
|
490124
|
+
} else if (server.oauth?.clientId || server.oauth?.callbackPort || server.oauth?.clientMetadataUrl) {
|
|
490026
490125
|
const parts = [];
|
|
490027
490126
|
if (server.oauth.clientId) {
|
|
490028
490127
|
parts.push("client_id configured");
|
package/package.json
CHANGED