@executor-js/plugin-mcp 1.4.31 → 1.4.32

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.
@@ -5,6 +5,7 @@ import {
5
5
  MCP_OAUTH_CLIENT_ID_SLOT,
6
6
  MCP_OAUTH_CLIENT_SECRET_SLOT,
7
7
  MCP_OAUTH_CONNECTION_SLOT,
8
+ McpAuthRequiredError,
8
9
  McpConfiguredValueInput,
9
10
  McpConnectionAuthInput,
10
11
  McpConnectionError,
@@ -18,7 +19,7 @@ import {
18
19
  SecretBackedValue,
19
20
  mcpHeaderSlot,
20
21
  mcpQueryParamSlot
21
- } from "./chunk-3TGDWTNE.js";
22
+ } from "./chunk-6OYEXHU3.js";
22
23
 
23
24
  // src/sdk/binding-store.ts
24
25
  import { Effect, Option, Predicate, Schema } from "effect";
@@ -152,10 +153,13 @@ import {
152
153
  Schema as Schema5,
153
154
  ScopedCache as ScopedCache2
154
155
  } from "effect";
156
+ import { CallToolResultSchema } from "@modelcontextprotocol/sdk/types.js";
157
+ import * as z from "zod/v4";
155
158
  import {
156
159
  ScopeId,
157
160
  SourceDetectionResult,
158
161
  ToolResult,
162
+ authToolFailure,
159
163
  defaultSourceInstallScopeId,
160
164
  definePlugin,
161
165
  tool,
@@ -221,7 +225,7 @@ var createMcpConnector = (input) => {
221
225
  }
222
226
  return Effect2.gen(function* () {
223
227
  const { createStdioTransport } = yield* Effect2.tryPromise({
224
- try: () => import("./stdio-connector-MDW6PW36.js"),
228
+ try: () => import("./stdio-connector-AA5S6UUJ.js"),
225
229
  catch: () => new McpConnectionError({
226
230
  transport: "stdio",
227
231
  message: "Failed to load stdio transport module"
@@ -843,6 +847,26 @@ var mcpToolFailure = (code, message, details) => ToolResult.fail({
843
847
  message,
844
848
  ...details === void 0 ? {} : { details }
845
849
  });
850
+ var mcpAuthToolFailure = (failure) => authToolFailure({
851
+ code: failure.code,
852
+ message: failure.message,
853
+ source: { id: failure.sourceId, scope: failure.sourceScope },
854
+ credential: {
855
+ kind: failure.credentialKind,
856
+ ...failure.credentialLabel ? { label: failure.credentialLabel } : {},
857
+ ...failure.slotKey ? { slotKey: failure.slotKey } : {},
858
+ ...failure.secretId ? { secretId: failure.secretId } : {},
859
+ ...failure.connectionId ? { connectionId: failure.connectionId } : {}
860
+ },
861
+ ...failure.status !== void 0 ? { status: failure.status } : {},
862
+ ...failure.details !== void 0 ? {
863
+ upstream: {
864
+ ...failure.status !== void 0 ? { status: failure.status } : {},
865
+ details: failure.details
866
+ }
867
+ } : {},
868
+ recovery: { configureSourceTool: "executor.mcp.configureSource" }
869
+ });
846
870
  var McpAddSourceInputStandardSchema = schemaToStaticToolSchema(McpAddSourceInputSchema);
847
871
  var McpAddSourceOutputStandardSchema = schemaToStaticToolSchema(McpAddSourceOutputSchema);
848
872
  var McpProbeEndpointInputStandardSchema = schemaToStaticToolSchema(McpProbeEndpointInputSchema);
@@ -882,6 +906,19 @@ var normalizeNamespace = (config) => config.namespace ?? deriveMcpNamespace({
882
906
  endpoint: config.transport === "remote" ? config.endpoint : void 0,
883
907
  command: config.transport === "stdio" ? config.command : void 0
884
908
  });
909
+ var McpCallToolResultJsonSchema = z.toJSONSchema(CallToolResultSchema);
910
+ var mcpCallToolResultOutputSchema = (structuredContentSchema) => {
911
+ const defaultStructuredContentSchema = McpCallToolResultJsonSchema.properties?.structuredContent ?? {};
912
+ return {
913
+ ...McpCallToolResultJsonSchema,
914
+ properties: {
915
+ ...McpCallToolResultJsonSchema.properties,
916
+ structuredContent: structuredContentSchema === void 0 ? defaultStructuredContentSchema : structuredContentSchema,
917
+ isError: { const: false }
918
+ },
919
+ required: structuredContentSchema === void 0 ? ["content"] : ["content", "structuredContent"]
920
+ };
921
+ };
885
922
  var toBinding = (entry) => McpToolBinding.make({
886
923
  toolId: entry.toolId,
887
924
  toolName: entry.toolName,
@@ -1105,21 +1142,34 @@ var resolveMcpBindingValueMap = (ctx, values, params) => Effect6.gen(function* (
1105
1142
  value.slot
1106
1143
  );
1107
1144
  if (binding?.value.kind === "secret") {
1108
- const secret = yield* ctx.secrets.getAtScope(binding.value.secretId, binding.scopeId).pipe(
1145
+ const secretBinding = binding.value;
1146
+ const secret = yield* ctx.secrets.getAtScope(secretBinding.secretId, binding.scopeId).pipe(
1109
1147
  Effect6.catchTag(
1110
1148
  "SecretOwnedByConnectionError",
1111
1149
  () => Effect6.fail(
1112
- new McpConnectionError({
1113
- transport: "remote",
1150
+ new McpAuthRequiredError({
1151
+ code: "credential_secret_missing",
1152
+ sourceId: params.sourceId,
1153
+ sourceScope: params.sourceScope,
1154
+ credentialKind: "secret",
1155
+ credentialLabel: name,
1156
+ slotKey: value.slot,
1157
+ secretId: String(secretBinding.secretId),
1114
1158
  message: `Failed to resolve secret for ${params.missingLabel} "${name}"`
1115
1159
  })
1116
1160
  )
1117
1161
  )
1118
1162
  );
1119
1163
  if (secret === null) {
1120
- return yield* new McpConnectionError({
1121
- transport: "remote",
1122
- message: `Missing secret "${binding.value.secretId}" for ${params.missingLabel} "${name}"`
1164
+ return yield* new McpAuthRequiredError({
1165
+ code: "credential_secret_missing",
1166
+ sourceId: params.sourceId,
1167
+ sourceScope: params.sourceScope,
1168
+ credentialKind: "secret",
1169
+ credentialLabel: name,
1170
+ slotKey: value.slot,
1171
+ secretId: String(secretBinding.secretId),
1172
+ message: `Missing secret "${secretBinding.secretId}" for ${params.missingLabel} "${name}"`
1123
1173
  });
1124
1174
  }
1125
1175
  resolved[name] = value.prefix ? `${value.prefix}${secret}` : secret;
@@ -1129,8 +1179,13 @@ var resolveMcpBindingValueMap = (ctx, values, params) => Effect6.gen(function* (
1129
1179
  resolved[name] = value.prefix ? `${value.prefix}${binding.value.text}` : binding.value.text;
1130
1180
  continue;
1131
1181
  }
1132
- return yield* new McpConnectionError({
1133
- transport: "remote",
1182
+ return yield* new McpAuthRequiredError({
1183
+ code: "credential_binding_missing",
1184
+ sourceId: params.sourceId,
1185
+ sourceScope: params.sourceScope,
1186
+ credentialKind: "secret",
1187
+ credentialLabel: name,
1188
+ slotKey: value.slot,
1134
1189
  message: `Missing binding for ${params.missingLabel} "${name}"`
1135
1190
  });
1136
1191
  }
@@ -1192,20 +1247,33 @@ var resolveMcpHeaderAuth = (ctx, sourceId, sourceScope, auth) => Effect6.gen(fun
1192
1247
  if (auth.kind !== "header") return {};
1193
1248
  const binding = yield* resolveMcpSourceBinding(ctx, sourceId, sourceScope, auth.secretSlot);
1194
1249
  if (binding?.value.kind === "secret") {
1195
- const secret = yield* ctx.secrets.getAtScope(binding.value.secretId, binding.scopeId).pipe(
1250
+ const secretBinding = binding.value;
1251
+ const secret = yield* ctx.secrets.getAtScope(secretBinding.secretId, binding.scopeId).pipe(
1196
1252
  Effect6.catchTag(
1197
1253
  "SecretOwnedByConnectionError",
1198
1254
  () => Effect6.fail(
1199
- new McpConnectionError({
1200
- transport: "remote",
1255
+ new McpAuthRequiredError({
1256
+ code: "credential_secret_missing",
1257
+ sourceId,
1258
+ sourceScope,
1259
+ credentialKind: "secret",
1260
+ credentialLabel: auth.headerName,
1261
+ slotKey: auth.secretSlot,
1262
+ secretId: String(secretBinding.secretId),
1201
1263
  message: `Failed to resolve header auth binding "${auth.secretSlot}"`
1202
1264
  })
1203
1265
  )
1204
1266
  )
1205
1267
  );
1206
1268
  if (secret === null) {
1207
- return yield* new McpConnectionError({
1208
- transport: "remote",
1269
+ return yield* new McpAuthRequiredError({
1270
+ code: "credential_secret_missing",
1271
+ sourceId,
1272
+ sourceScope,
1273
+ credentialKind: "secret",
1274
+ credentialLabel: auth.headerName,
1275
+ slotKey: auth.secretSlot,
1276
+ secretId: String(secretBinding.secretId),
1209
1277
  message: `Missing secret for header auth binding "${auth.secretSlot}"`
1210
1278
  });
1211
1279
  }
@@ -1216,8 +1284,13 @@ var resolveMcpHeaderAuth = (ctx, sourceId, sourceScope, auth) => Effect6.gen(fun
1216
1284
  [auth.headerName]: auth.prefix ? `${auth.prefix}${binding.value.text}` : binding.value.text
1217
1285
  };
1218
1286
  }
1219
- return yield* new McpConnectionError({
1220
- transport: "remote",
1287
+ return yield* new McpAuthRequiredError({
1288
+ code: "credential_binding_missing",
1289
+ sourceId,
1290
+ sourceScope,
1291
+ credentialKind: "secret",
1292
+ credentialLabel: auth.headerName,
1293
+ slotKey: auth.secretSlot,
1221
1294
  message: `Missing header auth binding "${auth.secretSlot}"`
1222
1295
  });
1223
1296
  });
@@ -1225,19 +1298,80 @@ var resolveMcpStoredOauthProvider = (ctx, sourceId, sourceScope, auth) => Effect
1225
1298
  if (auth.kind !== "oauth2") return void 0;
1226
1299
  const binding = yield* resolveMcpSourceBinding(ctx, sourceId, sourceScope, auth.connectionSlot);
1227
1300
  if (binding?.value.kind !== "connection") {
1228
- return yield* new McpConnectionError({
1229
- transport: "remote",
1301
+ return yield* new McpAuthRequiredError({
1302
+ code: "oauth_connection_missing",
1303
+ sourceId,
1304
+ sourceScope,
1305
+ credentialKind: "connection",
1306
+ credentialLabel: "OAuth sign-in",
1307
+ slotKey: auth.connectionSlot,
1230
1308
  message: `Missing OAuth connection binding for MCP source "${sourceId}"`
1231
1309
  });
1232
1310
  }
1233
1311
  const connectionId = binding.value.connectionId;
1234
1312
  const accessToken = yield* ctx.connections.accessTokenAtScope(connectionId, binding.scopeId).pipe(
1235
- Effect6.mapError(
1236
- ({ message }) => new McpConnectionError({
1237
- transport: "remote",
1238
- message: `Failed to resolve OAuth connection "${connectionId}": ${message}`
1239
- })
1240
- )
1313
+ Effect6.catchTags({
1314
+ ConnectionReauthRequiredError: ({ message, connectionId: failedConnectionId }) => Effect6.fail(
1315
+ new McpAuthRequiredError({
1316
+ code: "oauth_reauth_required",
1317
+ sourceId,
1318
+ sourceScope,
1319
+ credentialKind: "oauth",
1320
+ credentialLabel: "OAuth sign-in",
1321
+ slotKey: auth.connectionSlot,
1322
+ connectionId: String(failedConnectionId),
1323
+ message: `OAuth connection "${failedConnectionId}" needs re-authentication: ${message}`
1324
+ })
1325
+ ),
1326
+ ConnectionNotFoundError: ({ connectionId: failedConnectionId }) => Effect6.fail(
1327
+ new McpAuthRequiredError({
1328
+ code: "oauth_connection_missing",
1329
+ sourceId,
1330
+ sourceScope,
1331
+ credentialKind: "connection",
1332
+ credentialLabel: "OAuth sign-in",
1333
+ slotKey: auth.connectionSlot,
1334
+ connectionId: String(failedConnectionId),
1335
+ message: `OAuth connection "${failedConnectionId}" was not found for MCP source "${sourceId}"`
1336
+ })
1337
+ ),
1338
+ ConnectionProviderNotRegisteredError: ({ provider }) => Effect6.fail(
1339
+ new McpAuthRequiredError({
1340
+ code: "oauth_connection_failed",
1341
+ sourceId,
1342
+ sourceScope,
1343
+ credentialKind: "oauth",
1344
+ credentialLabel: "OAuth sign-in",
1345
+ slotKey: auth.connectionSlot,
1346
+ connectionId: String(connectionId),
1347
+ message: `OAuth provider "${provider}" is not registered`
1348
+ })
1349
+ ),
1350
+ ConnectionRefreshNotSupportedError: ({ provider, connectionId: failedConnectionId }) => Effect6.fail(
1351
+ new McpAuthRequiredError({
1352
+ code: "oauth_connection_failed",
1353
+ sourceId,
1354
+ sourceScope,
1355
+ credentialKind: "oauth",
1356
+ credentialLabel: "OAuth sign-in",
1357
+ slotKey: auth.connectionSlot,
1358
+ connectionId: String(failedConnectionId),
1359
+ message: `OAuth provider "${provider}" cannot refresh connection "${failedConnectionId}"`
1360
+ })
1361
+ ),
1362
+ ConnectionRefreshError: ({ message, connectionId: failedConnectionId }) => Effect6.fail(
1363
+ new McpAuthRequiredError({
1364
+ code: "oauth_connection_failed",
1365
+ sourceId,
1366
+ sourceScope,
1367
+ credentialKind: "oauth",
1368
+ credentialLabel: "OAuth sign-in",
1369
+ slotKey: auth.connectionSlot,
1370
+ connectionId: String(failedConnectionId),
1371
+ message: `OAuth connection "${failedConnectionId}" refresh failed: ${message}`
1372
+ })
1373
+ )
1374
+ })
1241
1375
  );
1242
1376
  return makeOAuthProvider(accessToken);
1243
1377
  });
@@ -1610,6 +1744,12 @@ var mcpPlugin = definePlugin((options) => {
1610
1744
  })
1611
1745
  );
1612
1746
  if (Result.isFailure(resolved) && sd.transport === "stdio") {
1747
+ if (Predicate3.isTagged(resolved.failure, "McpAuthRequiredError")) {
1748
+ return yield* new McpConnectionError({
1749
+ transport: sd.transport,
1750
+ message: resolved.failure.message
1751
+ });
1752
+ }
1613
1753
  return yield* Effect6.fail(resolved.failure);
1614
1754
  }
1615
1755
  const discovery = Result.isSuccess(resolved) ? yield* discoverTools(createMcpConnector(resolved.success)).pipe(
@@ -1657,7 +1797,7 @@ var mcpPlugin = definePlugin((options) => {
1657
1797
  name: e.toolId,
1658
1798
  description: e.description ?? `MCP tool: ${e.toolName}`,
1659
1799
  inputSchema: e.inputSchema,
1660
- outputSchema: e.outputSchema
1800
+ outputSchema: mcpCallToolResultOutputSchema(e.outputSchema)
1661
1801
  }))
1662
1802
  });
1663
1803
  if (initialRemote && initialBindings.length > 0) {
@@ -1690,6 +1830,12 @@ var mcpPlugin = definePlugin((options) => {
1690
1830
  yield* configFile.upsertSource(toMcpConfigEntry(namespace, sourceName, config)).pipe(Effect6.withSpan("mcp.plugin.config_file.upsert"));
1691
1831
  }
1692
1832
  if (Result.isFailure(discovery)) {
1833
+ if (Predicate3.isTagged(discovery.failure, "McpAuthRequiredError")) {
1834
+ return yield* new McpConnectionError({
1835
+ transport: sd.transport,
1836
+ message: discovery.failure.message
1837
+ });
1838
+ }
1693
1839
  return yield* Effect6.fail(discovery.failure);
1694
1840
  }
1695
1841
  return { toolCount: manifest.tools.length, namespace };
@@ -1735,6 +1881,10 @@ var mcpPlugin = definePlugin((options) => {
1735
1881
  });
1736
1882
  }
1737
1883
  const ci = yield* resolveConnectorInput(namespace, scope, sd, ctx, allowStdio).pipe(
1884
+ Effect6.catchTag(
1885
+ "McpAuthRequiredError",
1886
+ ({ message }) => Effect6.fail(new McpConnectionError({ transport: sd.transport, message }))
1887
+ ),
1738
1888
  Effect6.withSpan("mcp.plugin.resolve_connector", {
1739
1889
  attributes: {
1740
1890
  "mcp.source.namespace": namespace,
@@ -1780,7 +1930,7 @@ var mcpPlugin = definePlugin((options) => {
1780
1930
  name: e.toolId,
1781
1931
  description: e.description ?? `MCP tool: ${e.toolName}`,
1782
1932
  inputSchema: e.inputSchema,
1783
- outputSchema: e.outputSchema
1933
+ outputSchema: mcpCallToolResultOutputSchema(e.outputSchema)
1784
1934
  }))
1785
1935
  });
1786
1936
  })
@@ -2101,6 +2251,10 @@ var mcpPlugin = definePlugin((options) => {
2101
2251
  }
2102
2252
  return ToolResult.ok(raw);
2103
2253
  }).pipe(
2254
+ Effect6.catchTag(
2255
+ "McpAuthRequiredError",
2256
+ (error) => Effect6.succeed(mcpAuthToolFailure(error))
2257
+ ),
2104
2258
  Effect6.withSpan("mcp.plugin.invoke_tool", {
2105
2259
  attributes: {
2106
2260
  "mcp.tool.name": toolRow.id,
@@ -2234,4 +2388,4 @@ export {
2234
2388
  makeMcpStore,
2235
2389
  mcpPlugin
2236
2390
  };
2237
- //# sourceMappingURL=chunk-H5PLTEMB.js.map
2391
+ //# sourceMappingURL=chunk-LEGVPKYH.js.map