@executor-js/plugin-mcp 1.5.21 → 1.5.23

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.
@@ -36,8 +36,9 @@ export declare const mcpHttpPlugin: import("@executor-js/sdk/core").ConfiguredPl
36
36
  }, import("../sdk").McpConnectionError, never>;
37
37
  addServer: (input: import("../promise").McpServerInput) => import("effect/Effect").Effect<{
38
38
  slug: string;
39
- }, import("@executor-js/sdk/core").StorageFailure | import("@executor-js/sdk/core").IntegrationAlreadyExistsError, never>;
39
+ }, import("@executor-js/sdk/core").StorageFailure | import("@executor-js/sdk/core").IntegrationAlreadyExistsError | import("../sdk").McpConnectionError, never>;
40
40
  removeServer: (slug: string) => import("effect/Effect").Effect<void, import("@executor-js/sdk/core").StorageFailure, never>;
41
+ reconcileStdioConnections: () => import("effect/Effect").Effect<void, import("@executor-js/sdk/core").StorageFailure, never>;
41
42
  getServer: (slug: string) => import("effect/Effect").Effect<import("@executor-js/sdk/core").IntegrationRecord | null, import("@executor-js/sdk/core").StorageFailure, never>;
42
43
  configureServer: (slug: string, config: import("../sdk").McpIntegrationConfig) => import("effect/Effect").Effect<void, import("@executor-js/sdk/core").StorageFailure, never>;
43
44
  configureAuth: (slug: string, input: import("../sdk/plugin").McpConfigureAuthInput) => import("effect/Effect").Effect<readonly ({
@@ -57,6 +58,10 @@ export declare const mcpHttpPlugin: import("@executor-js/sdk/core").ConfiguredPl
57
58
  } | {
58
59
  readonly slug: string;
59
60
  readonly kind: "oauth2";
61
+ } | {
62
+ readonly slug: string;
63
+ readonly kind: "stdio_env";
64
+ readonly vars: readonly string[];
60
65
  })[], import("@executor-js/sdk/core").StorageFailure, never>;
61
66
  }, {}, McpPluginOptions, typeof McpExtensionService, import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").ApiGroup<"executor", "mcp">, never, import("effect/unstable/http/HttpRouter").Request<"Requires", McpExtensionService>>, import("effect/unstable/httpapi/HttpApiGroup").HttpApiGroup<"mcp", import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"probeEndpoint", "POST", "/mcp/probe", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
62
67
  readonly endpoint: import("effect/Schema").String;
@@ -115,6 +120,7 @@ export declare const mcpHttpPlugin: import("@executor-js/sdk/core").ConfiguredPl
115
120
  readonly description: import("effect/Schema").optional<import("effect/Schema").String>;
116
121
  readonly command: import("effect/Schema").String;
117
122
  readonly args: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").String>>;
123
+ readonly envVars: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").String>>;
118
124
  readonly env: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").String>>;
119
125
  readonly cwd: import("effect/Schema").optional<import("effect/Schema").String>;
120
126
  readonly slug: import("effect/Schema").optional<import("effect/Schema").String>;
@@ -155,6 +161,10 @@ export declare const mcpHttpPlugin: import("@executor-js/sdk/core").ConfiguredPl
155
161
  }>, import("effect/Schema").Struct<{
156
162
  readonly slug: import("effect/Schema").String;
157
163
  readonly kind: import("effect/Schema").Literal<"oauth2">;
164
+ }>, import("effect/Schema").Struct<{
165
+ readonly slug: import("effect/Schema").String;
166
+ readonly kind: import("effect/Schema").Literal<"stdio_env">;
167
+ readonly vars: import("effect/Schema").$Array<import("effect/Schema").String>;
158
168
  }>]>>;
159
169
  }>, import("effect/Schema").Struct<{
160
170
  readonly transport: import("effect/Schema").Literal<"stdio">;
@@ -162,6 +172,28 @@ export declare const mcpHttpPlugin: import("@executor-js/sdk/core").ConfiguredPl
162
172
  readonly args: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").String>>;
163
173
  readonly env: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").String>>;
164
174
  readonly cwd: import("effect/Schema").optional<import("effect/Schema").String>;
175
+ readonly authenticationTemplate: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").Union<readonly [import("effect/Schema").Struct<{
176
+ readonly slug: import("effect/Schema").String;
177
+ readonly kind: import("effect/Schema").Literal<"none">;
178
+ }>, import("effect/Schema").Struct<{
179
+ readonly slug: import("effect/Schema").String;
180
+ readonly kind: import("effect/Schema").Literal<"apikey">;
181
+ readonly label: import("effect/Schema").optional<import("effect/Schema").String>;
182
+ readonly placements: import("effect/Schema").$Array<import("effect/Schema").Struct<{
183
+ readonly carrier: import("effect/Schema").Literals<readonly ["header", "query"]>;
184
+ readonly name: import("effect/Schema").String;
185
+ readonly prefix: import("effect/Schema").optional<import("effect/Schema").String>;
186
+ readonly variable: import("effect/Schema").optional<import("effect/Schema").String>;
187
+ readonly literal: import("effect/Schema").optional<import("effect/Schema").String>;
188
+ }>>;
189
+ }>, import("effect/Schema").Struct<{
190
+ readonly slug: import("effect/Schema").String;
191
+ readonly kind: import("effect/Schema").Literal<"oauth2">;
192
+ }>, import("effect/Schema").Struct<{
193
+ readonly slug: import("effect/Schema").String;
194
+ readonly kind: import("effect/Schema").Literal<"stdio_env">;
195
+ readonly vars: import("effect/Schema").$Array<import("effect/Schema").String>;
196
+ }>]>>>;
165
197
  }>]>;
166
198
  }>>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("@executor-js/api").InternalError | typeof import("../sdk").McpConnectionError | typeof import("../sdk").McpToolDiscoveryError>, never, never> | import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"configureServer", "POST", "/mcp/servers/:slug/config", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<import("effect/Schema").Struct<{
167
199
  slug: import("effect/Schema").brand<import("effect/Schema").String, "IntegrationSlug">;
@@ -189,6 +221,10 @@ export declare const mcpHttpPlugin: import("@executor-js/sdk/core").ConfiguredPl
189
221
  }>, import("effect/Schema").Struct<{
190
222
  readonly slug: import("effect/Schema").String;
191
223
  readonly kind: import("effect/Schema").Literal<"oauth2">;
224
+ }>, import("effect/Schema").Struct<{
225
+ readonly slug: import("effect/Schema").String;
226
+ readonly kind: import("effect/Schema").Literal<"stdio_env">;
227
+ readonly vars: import("effect/Schema").$Array<import("effect/Schema").String>;
192
228
  }>]>>;
193
229
  }>, import("effect/Schema").Struct<{
194
230
  readonly transport: import("effect/Schema").Literal<"stdio">;
@@ -196,6 +232,28 @@ export declare const mcpHttpPlugin: import("@executor-js/sdk/core").ConfiguredPl
196
232
  readonly args: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").String>>;
197
233
  readonly env: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").String>>;
198
234
  readonly cwd: import("effect/Schema").optional<import("effect/Schema").String>;
235
+ readonly authenticationTemplate: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").Union<readonly [import("effect/Schema").Struct<{
236
+ readonly slug: import("effect/Schema").String;
237
+ readonly kind: import("effect/Schema").Literal<"none">;
238
+ }>, import("effect/Schema").Struct<{
239
+ readonly slug: import("effect/Schema").String;
240
+ readonly kind: import("effect/Schema").Literal<"apikey">;
241
+ readonly label: import("effect/Schema").optional<import("effect/Schema").String>;
242
+ readonly placements: import("effect/Schema").$Array<import("effect/Schema").Struct<{
243
+ readonly carrier: import("effect/Schema").Literals<readonly ["header", "query"]>;
244
+ readonly name: import("effect/Schema").String;
245
+ readonly prefix: import("effect/Schema").optional<import("effect/Schema").String>;
246
+ readonly variable: import("effect/Schema").optional<import("effect/Schema").String>;
247
+ readonly literal: import("effect/Schema").optional<import("effect/Schema").String>;
248
+ }>>;
249
+ }>, import("effect/Schema").Struct<{
250
+ readonly slug: import("effect/Schema").String;
251
+ readonly kind: import("effect/Schema").Literal<"oauth2">;
252
+ }>, import("effect/Schema").Struct<{
253
+ readonly slug: import("effect/Schema").String;
254
+ readonly kind: import("effect/Schema").Literal<"stdio_env">;
255
+ readonly vars: import("effect/Schema").$Array<import("effect/Schema").String>;
256
+ }>]>>>;
199
257
  }>]>;
200
258
  }>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
201
259
  readonly config: import("effect/Schema").Union<readonly [import("effect/Schema").Struct<{
@@ -221,6 +279,10 @@ export declare const mcpHttpPlugin: import("@executor-js/sdk/core").ConfiguredPl
221
279
  }>, import("effect/Schema").Struct<{
222
280
  readonly slug: import("effect/Schema").String;
223
281
  readonly kind: import("effect/Schema").Literal<"oauth2">;
282
+ }>, import("effect/Schema").Struct<{
283
+ readonly slug: import("effect/Schema").String;
284
+ readonly kind: import("effect/Schema").Literal<"stdio_env">;
285
+ readonly vars: import("effect/Schema").$Array<import("effect/Schema").String>;
224
286
  }>]>>;
225
287
  }>, import("effect/Schema").Struct<{
226
288
  readonly transport: import("effect/Schema").Literal<"stdio">;
@@ -228,6 +290,28 @@ export declare const mcpHttpPlugin: import("@executor-js/sdk/core").ConfiguredPl
228
290
  readonly args: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").String>>;
229
291
  readonly env: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").String>>;
230
292
  readonly cwd: import("effect/Schema").optional<import("effect/Schema").String>;
293
+ readonly authenticationTemplate: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").Union<readonly [import("effect/Schema").Struct<{
294
+ readonly slug: import("effect/Schema").String;
295
+ readonly kind: import("effect/Schema").Literal<"none">;
296
+ }>, import("effect/Schema").Struct<{
297
+ readonly slug: import("effect/Schema").String;
298
+ readonly kind: import("effect/Schema").Literal<"apikey">;
299
+ readonly label: import("effect/Schema").optional<import("effect/Schema").String>;
300
+ readonly placements: import("effect/Schema").$Array<import("effect/Schema").Struct<{
301
+ readonly carrier: import("effect/Schema").Literals<readonly ["header", "query"]>;
302
+ readonly name: import("effect/Schema").String;
303
+ readonly prefix: import("effect/Schema").optional<import("effect/Schema").String>;
304
+ readonly variable: import("effect/Schema").optional<import("effect/Schema").String>;
305
+ readonly literal: import("effect/Schema").optional<import("effect/Schema").String>;
306
+ }>>;
307
+ }>, import("effect/Schema").Struct<{
308
+ readonly slug: import("effect/Schema").String;
309
+ readonly kind: import("effect/Schema").Literal<"oauth2">;
310
+ }>, import("effect/Schema").Struct<{
311
+ readonly slug: import("effect/Schema").String;
312
+ readonly kind: import("effect/Schema").Literal<"stdio_env">;
313
+ readonly vars: import("effect/Schema").$Array<import("effect/Schema").String>;
314
+ }>]>>>;
231
315
  }>]>;
232
316
  }>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("@executor-js/api").InternalError | typeof import("../sdk").McpConnectionError | typeof import("../sdk").McpToolDiscoveryError>, never, never> | import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"configureAuth", "POST", "/mcp/servers/:slug/auth", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<import("effect/Schema").Struct<{
233
317
  slug: import("effect/Schema").brand<import("effect/Schema").String, "IntegrationSlug">;
@@ -270,5 +354,9 @@ export declare const mcpHttpPlugin: import("@executor-js/sdk/core").ConfiguredPl
270
354
  }>, import("effect/Schema").Struct<{
271
355
  readonly slug: import("effect/Schema").String;
272
356
  readonly kind: import("effect/Schema").Literal<"oauth2">;
357
+ }>, import("effect/Schema").Struct<{
358
+ readonly slug: import("effect/Schema").String;
359
+ readonly kind: import("effect/Schema").Literal<"stdio_env">;
360
+ readonly vars: import("effect/Schema").$Array<import("effect/Schema").String>;
273
361
  }>]>>;
274
362
  }>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("@executor-js/api").InternalError | typeof import("../sdk").McpConnectionError | typeof import("../sdk").McpToolDiscoveryError>, never, never>, false>>;
@@ -5,7 +5,7 @@ import {
5
5
  McpConnectionError,
6
6
  McpIntegrationConfig,
7
7
  McpToolDiscoveryError
8
- } from "./chunk-4V3H3DDH.js";
8
+ } from "./chunk-OCDAATE3.js";
9
9
 
10
10
  // src/react/atoms.ts
11
11
  import { ReactivityKey } from "@executor-js/react/api/reactivity-keys";
@@ -50,6 +50,10 @@ var AddStdioServerPayload = Schema.Struct({
50
50
  description: Schema.optional(Schema.String),
51
51
  command: Schema.String,
52
52
  args: Schema.optional(Schema.Array(Schema.String)),
53
+ /** Declare the secret env vars this server needs, by name. Their values are
54
+ * supplied as the connection's secrets (the connect step), not here. */
55
+ envVars: Schema.optional(Schema.Array(Schema.String)),
56
+ /** One-shot secret env values (programmatic). The UI sends `envVars`. */
53
57
  env: Schema.optional(StringMap),
54
58
  cwd: Schema.optional(Schema.String),
55
59
  slug: Schema.optional(Schema.String)
@@ -174,6 +178,18 @@ import {
174
178
  wirePlacementsFromEditor
175
179
  } from "@executor-js/react/lib/shared-auth-method-codec";
176
180
  import { wireAuthInputFromShared } from "@executor-js/react/lib/shared-auth-method-codec";
181
+ var stdioEnvAuthMethod = (method) => ({
182
+ id: method.slug,
183
+ label: "Environment variables",
184
+ kind: "apikey",
185
+ source: "spec",
186
+ template: AuthTemplateSlug.make(method.slug),
187
+ placements: method.vars.map((name) => ({ carrier: "env", name, prefix: "", variable: name }))
188
+ });
189
+ var stdioEnvEditorValue = (method) => ({
190
+ kind: "apikey",
191
+ placements: method.vars.map((name) => ({ carrier: "env", name, prefix: "", variable: name }))
192
+ });
177
193
  var mcpWireAuthInput = (method) => wireAuthInputFromShared(method);
178
194
  var oauthAuthMethod = (slug, endpoint) => ({
179
195
  id: slug,
@@ -194,11 +210,13 @@ function editorValueFromMcpAuthMethod(method) {
194
210
  if (method.kind === "oauth2") {
195
211
  return { kind: "oauth", authorizationUrl: "", tokenUrl: "", scopes: [] };
196
212
  }
213
+ if (method.kind === "stdio_env") return stdioEnvEditorValue(method);
197
214
  return editorValueFromSharedMethod(method);
198
215
  }
199
216
  function authMethodsFromConfig(methods, endpoint) {
200
217
  return methods.map((method) => {
201
218
  if (method.kind === "oauth2") return oauthAuthMethod(method.slug, endpoint);
219
+ if (method.kind === "stdio_env") return stdioEnvAuthMethod(method);
202
220
  return authMethodFromSharedTemplate(method);
203
221
  });
204
222
  }
@@ -219,4 +237,4 @@ export {
219
237
  authMethodsFromConfig,
220
238
  mcpAuthMethodInputsFromPlacements
221
239
  };
222
- //# sourceMappingURL=chunk-AMC5G2HJ.js.map
240
+ //# sourceMappingURL=chunk-N6NNZDXN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react/atoms.ts","../src/react/client.ts","../src/api/group.ts","../src/react/auth-method-config.ts"],"sourcesContent":["import type { IntegrationSlug } from \"@executor-js/sdk/shared\";\nimport { ReactivityKey } from \"@executor-js/react/api/reactivity-keys\";\nimport { McpClient } from \"./client\";\n\n// ---------------------------------------------------------------------------\n// Query atoms (v2)\n//\n// An MCP server is an integration. `getServer` reads the integration row's\n// opaque config (transport, endpoint, auth template). Credentials are separate\n// owner-scoped connections, created through the core connections / oauth surface\n// — there is no per-server credential binding to read here anymore.\n// ---------------------------------------------------------------------------\n\nexport const mcpServerAtom = (slug: IntegrationSlug) =>\n McpClient.query(\"mcp\", \"getServer\", {\n params: { slug },\n timeToLive: \"15 seconds\",\n reactivityKeys: [ReactivityKey.integrations, ReactivityKey.tools],\n });\n\n// ---------------------------------------------------------------------------\n// Mutation atoms\n// ---------------------------------------------------------------------------\n\nexport const probeMcpEndpoint = McpClient.mutation(\"mcp\", \"probeEndpoint\");\nexport const addMcpServer = McpClient.mutation(\"mcp\", \"addServer\");\nexport const removeMcpServer = McpClient.mutation(\"mcp\", \"removeServer\");\nexport const configureMcpServer = McpClient.mutation(\"mcp\", \"configureServer\");\n// Merge-append auth methods onto an integration's `authenticationTemplate`.\nexport const configureMcpAuth = McpClient.mutation(\"mcp\", \"configureAuth\");\n","import { createPluginAtomClient } from \"@executor-js/sdk/client\";\nimport {\n getExecutorOrganizationHeaders,\n getExecutorApiBaseUrl,\n getExecutorServerAuthorizationHeader,\n} from \"@executor-js/react/api/server-connection\";\nimport { McpGroup } from \"../api/group\";\n\nexport const McpClient = createPluginAtomClient(McpGroup, {\n baseUrl: getExecutorApiBaseUrl,\n authorizationHeader: getExecutorServerAuthorizationHeader,\n headers: getExecutorOrganizationHeaders,\n});\n","import { HttpApiEndpoint, HttpApiGroup } from \"effect/unstable/httpapi\";\nimport { Schema } from \"effect\";\nimport {\n IntegrationSlug,\n InternalError,\n IntegrationAlreadyExistsError,\n} from \"@executor-js/sdk/shared\";\n\nimport { McpConnectionError, McpToolDiscoveryError } from \"../sdk/errors\";\nimport {\n McpAuthMethod,\n McpAuthMethodInput,\n McpAuthShorthand,\n McpIntegrationConfig,\n} from \"../sdk/types\";\n\n// ---------------------------------------------------------------------------\n// Params\n// ---------------------------------------------------------------------------\n\nconst SlugParams = { slug: IntegrationSlug };\n\nconst StringMap = Schema.Record(Schema.String, Schema.String);\n\n// ---------------------------------------------------------------------------\n// Add server — discriminated union on transport. An MCP server is registered\n// as an integration; connections (credentials) are created separately through\n// the core connections / oauth surface.\n// ---------------------------------------------------------------------------\n\nconst AddRemoteServerPayload = Schema.Struct({\n transport: Schema.optional(Schema.Literal(\"remote\")),\n name: Schema.String,\n /** Agent-visible catalog description. Defaults to the display name. */\n description: Schema.optional(Schema.String),\n endpoint: Schema.String,\n remoteTransport: Schema.optional(Schema.Literals([\"streamable-http\", \"sse\", \"auto\"])),\n slug: Schema.optional(Schema.String),\n queryParams: Schema.optional(StringMap),\n headers: Schema.optional(StringMap),\n /** Declared auth methods a connection can be applied through. */\n authenticationTemplate: Schema.optional(Schema.Array(McpAuthMethodInput)),\n /** Single-method shorthand (legacy callers); ignored when\n * `authenticationTemplate` is present. */\n auth: Schema.optional(McpAuthShorthand),\n});\n\nconst AddStdioServerPayload = Schema.Struct({\n transport: Schema.Literal(\"stdio\"),\n name: Schema.String,\n description: Schema.optional(Schema.String),\n command: Schema.String,\n args: Schema.optional(Schema.Array(Schema.String)),\n /** Declare the secret env vars this server needs, by name. Their values are\n * supplied as the connection's secrets (the connect step), not here. */\n envVars: Schema.optional(Schema.Array(Schema.String)),\n /** One-shot secret env values (programmatic). The UI sends `envVars`. */\n env: Schema.optional(StringMap),\n cwd: Schema.optional(Schema.String),\n slug: Schema.optional(Schema.String),\n});\n\nconst AddServerPayload = Schema.Union([AddRemoteServerPayload, AddStdioServerPayload]);\n\nconst ProbeEndpointPayload = Schema.Struct({\n endpoint: Schema.String,\n headers: Schema.optional(StringMap),\n queryParams: Schema.optional(StringMap),\n});\n\nconst ProbeEndpointResponse = Schema.Struct({\n connected: Schema.Boolean,\n requiresAuthentication: Schema.Boolean,\n requiresOAuth: Schema.Boolean,\n supportsDynamicRegistration: Schema.Boolean,\n name: Schema.String,\n slug: Schema.String,\n toolCount: Schema.NullOr(Schema.Number),\n serverName: Schema.NullOr(Schema.String),\n /** Server `instructions` from initialize — prefills the description field. */\n instructions: Schema.NullOr(Schema.String),\n});\n\n// ---------------------------------------------------------------------------\n// Responses\n// ---------------------------------------------------------------------------\n\nconst AddServerResponse = Schema.Struct({\n slug: Schema.String,\n});\n\nconst RemoveServerResponse = Schema.Struct({\n removed: Schema.Boolean,\n});\n\nconst ConfigureServerPayload = Schema.Struct({\n config: McpIntegrationConfig,\n});\n\nconst ConfigureServerResponse = Schema.Struct({\n config: McpIntegrationConfig,\n});\n\n// The configureAuth payload/response — custom auth methods to merge-append\n// onto the integration's `authenticationTemplate` (or `replace` the set).\n// Mirrors the GraphQL/OpenAPI configure endpoints.\nconst ConfigureAuthPayload = Schema.Struct({\n authenticationTemplate: Schema.Array(McpAuthMethodInput),\n mode: Schema.optional(Schema.Literals([\"merge\", \"replace\"])),\n});\n\nconst ConfigureAuthResponse = Schema.Struct({\n authenticationTemplate: Schema.Array(McpAuthMethod),\n});\n\nconst GetServerResponse = Schema.NullOr(\n Schema.Struct({\n slug: IntegrationSlug,\n description: Schema.String,\n kind: Schema.String,\n canRemove: Schema.Boolean,\n canRefresh: Schema.Boolean,\n config: McpIntegrationConfig,\n }),\n);\n\n// ---------------------------------------------------------------------------\n// Group\n//\n// Integrations are tenant-level (no scope segment); plugin domain errors carry\n// their own `HttpApiSchema` status (4xx). `InternalError` is the shared opaque\n// 500 translated at the HTTP edge.\n// ---------------------------------------------------------------------------\n\nexport const McpGroup = HttpApiGroup.make(\"mcp\")\n .add(\n HttpApiEndpoint.post(\"probeEndpoint\", \"/mcp/probe\", {\n payload: ProbeEndpointPayload,\n success: ProbeEndpointResponse,\n error: [InternalError, McpConnectionError, McpToolDiscoveryError],\n }),\n )\n .add(\n HttpApiEndpoint.post(\"addServer\", \"/mcp/servers\", {\n payload: AddServerPayload,\n success: AddServerResponse,\n error: [\n InternalError,\n McpConnectionError,\n McpToolDiscoveryError,\n IntegrationAlreadyExistsError,\n ],\n }),\n )\n .add(\n HttpApiEndpoint.delete(\"removeServer\", \"/mcp/servers/:slug\", {\n params: SlugParams,\n success: RemoveServerResponse,\n error: [InternalError, McpConnectionError, McpToolDiscoveryError],\n }),\n )\n .add(\n HttpApiEndpoint.get(\"getServer\", \"/mcp/servers/:slug\", {\n params: SlugParams,\n success: GetServerResponse,\n error: [InternalError, McpConnectionError, McpToolDiscoveryError],\n }),\n )\n .add(\n HttpApiEndpoint.post(\"configureServer\", \"/mcp/servers/:slug/config\", {\n params: SlugParams,\n payload: ConfigureServerPayload,\n success: ConfigureServerResponse,\n error: [InternalError, McpConnectionError, McpToolDiscoveryError],\n }),\n )\n .add(\n HttpApiEndpoint.post(\"configureAuth\", \"/mcp/servers/:slug/auth\", {\n params: SlugParams,\n payload: ConfigureAuthPayload,\n success: ConfigureAuthResponse,\n error: [InternalError, McpConnectionError, McpToolDiscoveryError],\n }),\n );\n","// ---------------------------------------------------------------------------\n// MCP ↔ generic auth-method converters — a thin oauth adapter over the shared\n// codec (`@executor-js/react/lib/shared-auth-method-codec`). The apikey/none\n// paths (multi-placement, multi-variable) live in the shared codec; MCP only\n// contributes its oauth flavor: endpoint-less methods whose metadata is\n// discovered at connect time (`discoveryUrl` = the MCP endpoint).\n// ---------------------------------------------------------------------------\n\nimport { AuthTemplateSlug } from \"@executor-js/sdk/shared\";\nimport type { AuthTemplateEditorValue } from \"@executor-js/react/components/auth-template-editor\";\nimport type { AuthMethod, Placement } from \"@executor-js/react/lib/auth-placements\";\nimport {\n authMethodFromSharedTemplate,\n editorValueFromSharedMethod,\n sharedMethodInputFromEditorValue,\n wirePlacementsFromEditor,\n} from \"@executor-js/react/lib/shared-auth-method-codec\";\n\nimport { wireAuthInputFromShared } from \"@executor-js/react/lib/shared-auth-method-codec\";\nimport type {\n McpAuthMethod,\n McpAuthMethodInput,\n McpCanonicalAuthMethodInput,\n McpStdioEnvMethod,\n} from \"../sdk/types\";\n\n/** Stdio env method → generic hub `AuthMethod`: one `env`-carrier placement per\n * declared var, so the account form collects one secret per env var. Mirrors\n * the server's `describeMcpAuthMethods`. */\nconst stdioEnvAuthMethod = (method: McpStdioEnvMethod): AuthMethod => ({\n id: method.slug,\n label: \"Environment variables\",\n kind: \"apikey\",\n source: \"spec\",\n template: AuthTemplateSlug.make(method.slug),\n placements: method.vars.map((name) => ({ carrier: \"env\", name, prefix: \"\", variable: name })),\n});\n\n/** Stdio env method → editor value (apikey over env placements). */\nconst stdioEnvEditorValue = (method: McpStdioEnvMethod): AuthTemplateEditorValue => ({\n kind: \"apikey\",\n placements: method.vars.map((name) => ({ carrier: \"env\", name, prefix: \"\", variable: name })),\n});\n\n/** Serialize a canonical method into the wire input union (apikey → the\n * request-shaped dialect; none/oauth2 pass through). */\nexport const mcpWireAuthInput = (\n method: McpAuthMethod | McpCanonicalAuthMethodInput,\n): McpAuthMethodInput => wireAuthInputFromShared(method) as McpAuthMethodInput;\n\nconst oauthAuthMethod = (slug: string, endpoint: string): AuthMethod => ({\n id: slug,\n label: \"OAuth\",\n kind: \"oauth\",\n source: slug.startsWith(\"custom_\") ? \"custom\" : \"spec\",\n template: AuthTemplateSlug.make(slug),\n placements: [],\n oauth: { discoveryUrl: endpoint, supportsDynamicRegistration: true },\n});\n\n/** Convert a generic editor value into one MCP auth-method input (no slug —\n * the backend assigns carrier-derived slugs). An apikey value keeps every\n * named placement (headers and query params mix freely); one with no usable\n * placement falls back to `none`. */\nexport function mcpAuthMethodInputFromEditorValue(\n value: AuthTemplateEditorValue,\n): McpCanonicalAuthMethodInput {\n if (value.kind === \"oauth\") return { kind: \"oauth2\" };\n return (sharedMethodInputFromEditorValue(value) ?? {\n kind: \"none\",\n }) as McpCanonicalAuthMethodInput;\n}\n\n/** Convert one stored MCP method into the generic editor value. */\nexport function editorValueFromMcpAuthMethod(method: McpAuthMethod): AuthTemplateEditorValue {\n if (method.kind === \"oauth2\") {\n return { kind: \"oauth\", authorizationUrl: \"\", tokenUrl: \"\", scopes: [] };\n }\n if (method.kind === \"stdio_env\") return stdioEnvEditorValue(method);\n return editorValueFromSharedMethod(method);\n}\n\n/** Project the stored methods into the generic `AuthMethod[]` the hub renders.\n * Mirrors the server's `describeMcpAuthMethods`; `custom_` slugs mark\n * user-created methods (removable from the hub). `endpoint` feeds the oauth\n * method's probe-at-connect `discoveryUrl`. */\nexport function authMethodsFromConfig(\n methods: readonly McpAuthMethod[],\n endpoint: string,\n): AuthMethod[] {\n return methods.map((method: McpAuthMethod): AuthMethod => {\n if (method.kind === \"oauth2\") return oauthAuthMethod(method.slug, endpoint);\n if (method.kind === \"stdio_env\") return stdioEnvAuthMethod(method);\n return authMethodFromSharedTemplate(method);\n });\n}\n\n/** Build the MCP method input for a custom method from generic placements —\n * ONE method carrying every named placement (header + query mix in a single\n * method; each placement renders from its own input variable, or shares one).\n * Empty when no placement is usable. */\nexport function mcpAuthMethodInputsFromPlacements(\n placements: readonly Placement[],\n): McpCanonicalAuthMethodInput[] {\n const wire = wirePlacementsFromEditor(placements);\n if (wire.length === 0) return [];\n return [{ kind: \"apikey\", placements: wire }];\n}\n"],"mappings":"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","names":[]}
@@ -49,7 +49,17 @@ var McpOAuthMethod = Schema2.Struct({
49
49
  slug: Schema2.String,
50
50
  kind: Schema2.Literal("oauth2")
51
51
  });
52
- var McpAuthMethod = Schema2.Union([NoneAuthMethod, ApiKeyAuthMethod, McpOAuthMethod]);
52
+ var McpStdioEnvMethod = Schema2.Struct({
53
+ slug: Schema2.String,
54
+ kind: Schema2.Literal("stdio_env"),
55
+ vars: Schema2.Array(Schema2.String)
56
+ });
57
+ var McpAuthMethod = Schema2.Union([
58
+ NoneAuthMethod,
59
+ ApiKeyAuthMethod,
60
+ McpOAuthMethod,
61
+ McpStdioEnvMethod
62
+ ]);
53
63
  var McpAuthShorthand = Schema2.Union([
54
64
  Schema2.Struct({ kind: Schema2.Literal("none") }),
55
65
  Schema2.Struct({
@@ -123,10 +133,20 @@ var McpStdioIntegrationConfig = Schema2.Struct({
123
133
  command: Schema2.String,
124
134
  /** Arguments to the command */
125
135
  args: Schema2.optional(Schema2.Array(Schema2.String)),
126
- /** Environment variables */
136
+ /** Static, non-credential environment variables injected verbatim into the
137
+ * subprocess. Secret env (API keys / tokens) is NOT stored here — it is
138
+ * declared as a `stdio_env` method in `authenticationTemplate` and its
139
+ * values live on the connection. Optional + legacy: pre-revamp stdio
140
+ * integrations stored their (then-plaintext) env here, so it stays
141
+ * decodable. */
127
142
  env: Schema2.optional(StringMap),
128
143
  /** Working directory */
129
- cwd: Schema2.optional(Schema2.String)
144
+ cwd: Schema2.optional(Schema2.String),
145
+ /** Declared auth methods — a single `stdio_env` method naming the secret env
146
+ * vars, or `none`. A connection's `template` picks one by slug, exactly as
147
+ * for remote servers. Optional so pre-revamp stdio configs (which had no
148
+ * methods) still decode; absence is treated as no declared secret env. */
149
+ authenticationTemplate: Schema2.optional(Schema2.Array(McpAuthMethod))
130
150
  });
131
151
  var McpIntegrationConfig = Schema2.Union([
132
152
  McpRemoteIntegrationConfig,
@@ -173,4 +193,4 @@ export {
173
193
  McpToolAnnotations,
174
194
  McpToolBinding
175
195
  };
176
- //# sourceMappingURL=chunk-4V3H3DDH.js.map
196
+ //# sourceMappingURL=chunk-OCDAATE3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sdk/errors.ts","../src/sdk/types.ts"],"sourcesContent":["// MCP plugin tagged errors. API-facing errors carry `HttpApiSchema`\n// annotations so they can be `.addError(...)` directly on the API group.\n\nimport { Data, Schema } from \"effect\";\n\nexport class McpConnectionError extends Schema.TaggedErrorClass<McpConnectionError>()(\n \"McpConnectionError\",\n {\n transport: Schema.String,\n message: Schema.String,\n },\n { httpApiStatus: 400 },\n) {}\n\nexport class McpToolDiscoveryError extends Schema.TaggedErrorClass<McpToolDiscoveryError>()(\n \"McpToolDiscoveryError\",\n {\n stage: Schema.Literals([\"connect\", \"list_tools\"]),\n message: Schema.String,\n },\n { httpApiStatus: 400 },\n) {}\n\n// Internal only: core wraps non-auth failures as ToolInvocationError.cause, so\n// this must carry only sanitized invocation metadata. Raw SDK causes can contain\n// upstream bodies/challenges and should not leave the invoke catch block.\nexport class McpInvocationError extends Data.TaggedError(\"McpInvocationError\")<{\n readonly toolName: string;\n readonly message: string;\n readonly status?: number;\n}> {}\n\nexport class McpOAuthReauthorizationRequired extends Data.TaggedError(\n \"McpOAuthReauthorizationRequired\",\n)<{\n readonly message: string;\n}> {}\n\nexport class McpOAuthError extends Schema.TaggedErrorClass<McpOAuthError>()(\n \"McpOAuthError\",\n {\n message: Schema.String,\n },\n { httpApiStatus: 400 },\n) {}\n","import { Effect, Option, Schema } from \"effect\";\nimport {\n ApiKeyAuthMethod,\n ApiKeyAuthTemplate,\n NoneAuthMethod,\n apiKeyMethodFromAuthTemplate,\n isApiKeyAuthTemplate,\n normalizeAuthMethodSlugs,\n} from \"@executor-js/sdk/http-auth\";\n\n// ---------------------------------------------------------------------------\n// MCP plugin v2 data model.\n//\n// An MCP integration is one server. Its `config` blob (opaque to core, stored\n// on the integration row) carries everything needed to dial the server plus\n// the declared auth methods describing how a connection's resolved credential\n// values are applied to the request. A connection IS the credential: at\n// execute time core resolves the connection's values through its provider\n// (refreshing OAuth tokens), and the plugin renders them onto the request per\n// the method the connection binds (D11).\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Transport / remote transport\n// ---------------------------------------------------------------------------\n\nexport const McpRemoteTransport = Schema.Literals([\"streamable-http\", \"sse\", \"auto\"]);\nexport type McpRemoteTransport = typeof McpRemoteTransport.Type;\n\n/** All transport types (used in the connector layer) */\nexport const McpTransport = Schema.Literals([\"streamable-http\", \"sse\", \"stdio\", \"auto\"]);\nexport type McpTransport = typeof McpTransport.Type;\n\n// ---------------------------------------------------------------------------\n// Auth methods — the shared placements vocabulary (`@executor-js/sdk/http-auth`)\n// plus MCP's own oauth variant. An integration declares zero or more methods,\n// each with a stable `slug` a connection binds against (`connection.template`),\n// mirroring the OpenAPI/GraphQL `authenticationTemplate` arrays.\n//\n// none — no credential (open server)\n// apikey — render the connection's values through the method's header/query\n// placements (one credential input per distinct placement\n// `variable`; servers like ui.sh authenticate via a `?token=`\n// query placement, and a method may mix carriers — e.g. a bearer\n// header plus a team-id query param)\n// oauth2 — the value is an OAuth access token, applied as a Bearer header\n// via the MCP SDK's OAuthClientProvider. MCP oauth carries no\n// stored endpoints: metadata is discovered live at connect time.\n// ---------------------------------------------------------------------------\n\nexport const McpOAuthMethod = Schema.Struct({\n slug: Schema.String,\n kind: Schema.Literal(\"oauth2\"),\n});\nexport type McpOAuthMethod = typeof McpOAuthMethod.Type;\n\n/** Stdio env credential: the named environment variables a stdio server needs\n * (often API keys / tokens). A connection supplies one secret value per `var`,\n * keyed by the var name; at launch the connector injects them into the\n * subprocess env. The VALUES live in the secret store as the connection's\n * inputs, never in this config blob — that is the \"properly store auth\" half\n * of the stdio model, mirroring how remote apikey methods keep their secrets\n * on the connection rather than the integration. */\nexport const McpStdioEnvMethod = Schema.Struct({\n slug: Schema.String,\n kind: Schema.Literal(\"stdio_env\"),\n vars: Schema.Array(Schema.String),\n});\nexport type McpStdioEnvMethod = typeof McpStdioEnvMethod.Type;\n\nexport const McpAuthMethod = Schema.Union([\n NoneAuthMethod,\n ApiKeyAuthMethod,\n McpOAuthMethod,\n McpStdioEnvMethod,\n]);\nexport type McpAuthMethod = typeof McpAuthMethod.Type;\n\n/** Single-method `auth` shorthand on `addServer` — agent convenience for the\n * common cases. Normalized into `authenticationTemplate` at the boundary;\n * never stored. */\nexport const McpAuthShorthand = Schema.Union([\n Schema.Struct({ kind: Schema.Literal(\"none\") }),\n Schema.Struct({\n kind: Schema.Literal(\"header\"),\n headerName: Schema.String,\n prefix: Schema.optional(Schema.String),\n }),\n Schema.Struct({ kind: Schema.Literal(\"oauth2\") }),\n]);\nexport type McpAuthShorthand = typeof McpAuthShorthand.Type;\n\n/** Expand the `auth` shorthand into a declared method. Slugs match what the\n * shorthand has always produced (`none` / `header` / `oauth2`) so existing\n * connections bound to them keep matching. */\nexport const mcpAuthMethodFromShorthand = (auth: McpAuthShorthand): McpAuthMethod => {\n if (auth.kind === \"header\") {\n return {\n slug: \"header\",\n kind: \"apikey\",\n placements: [\n {\n carrier: \"header\",\n name: auth.headerName,\n ...(auth.prefix !== undefined ? { prefix: auth.prefix } : {}),\n },\n ],\n };\n }\n return { slug: auth.kind, kind: auth.kind };\n};\n\n/** Input variant of `McpAuthMethod` — callers (UI, agents) may omit the slug;\n * `normalizeMcpAuthMethods` backfills it. */\nexport const McpAuthMethodInput = Schema.Union([\n Schema.Struct({ slug: Schema.optional(Schema.String), kind: Schema.Literal(\"none\") }),\n Schema.Struct({ slug: Schema.optional(Schema.String), kind: Schema.Literal(\"oauth2\") }),\n // Credential methods are authored request-shaped — the ONE apikey input\n // dialect: `{ type: \"apiKey\", headers: { Authorization: [\"Bearer \",\n // variable(\"token\")] }, queryParams: { … } }`. Stored configs and the\n // catalog read as canonical placements; `apiKeyAuthTemplateFromMethod`\n // serializes them back for read-modify-write flows.\n ApiKeyAuthTemplate,\n]);\nexport type McpAuthMethodInput = typeof McpAuthMethodInput.Type;\n\n/** The expansion target: input arms with the dialect resolved to canonical\n * placements (slug still optional — backfill is a separate pass). */\nexport type McpCanonicalAuthMethodInput =\n | Exclude<McpAuthMethodInput, ApiKeyAuthTemplate>\n | (Omit<ApiKeyAuthMethod, \"slug\"> & { readonly slug?: string });\n\n/** The default slug for a slug-less input method. Carrier-derived for the\n * single-placement apikey cases (`header` / `query`) — the slugs those\n * methods have always had — so the shorthand, UI, and migration paths all\n * converge on the same names. */\nconst defaultMcpAuthSlug = (method: McpCanonicalAuthMethodInput): string => {\n if (method.kind !== \"apikey\") return method.kind;\n if (method.placements.length === 1) {\n return method.placements[0]!.carrier === \"header\" ? \"header\" : \"query\";\n }\n return \"apikey\";\n};\n\n/** Expand request-shaped dialect entries into canonical placements; canonical\n * entries pass through. Slug backfill is the caller's concern\n * (`normalizeMcpAuthMethods` for declare flows, `mergeAuthTemplates` for the\n * custom-method merge). */\nexport const expandMcpAuthMethodInputs = (\n methods: readonly McpAuthMethodInput[],\n): readonly McpCanonicalAuthMethodInput[] =>\n methods.map(\n (method): McpCanonicalAuthMethodInput =>\n isApiKeyAuthTemplate(method)\n ? (apiKeyMethodFromAuthTemplate(method) as McpCanonicalAuthMethodInput)\n : (method as McpCanonicalAuthMethodInput),\n );\n\n/** Assign each method a stable slug: a caller-provided one wins, otherwise a\n * kind/carrier-derived default, suffixed `_2`, `_3`, … on collision. The\n * request-shaped dialect is expanded to canonical placements first. */\nexport const normalizeMcpAuthMethods = (\n methods: readonly McpAuthMethodInput[],\n): readonly McpAuthMethod[] =>\n normalizeAuthMethodSlugs(\n expandMcpAuthMethodInputs(methods),\n defaultMcpAuthSlug,\n ) as readonly McpAuthMethod[];\n\n// ---------------------------------------------------------------------------\n// Integration config — the opaque blob stored on the integration row. A\n// discriminated union on transport.\n// ---------------------------------------------------------------------------\n\nconst StringMap = Schema.Record(Schema.String, Schema.String);\n\nexport const McpRemoteIntegrationConfig = Schema.Struct({\n transport: Schema.Literal(\"remote\"),\n /** The MCP server endpoint URL */\n endpoint: Schema.String,\n /** Transport preference for this remote server */\n remoteTransport: McpRemoteTransport.pipe(\n Schema.optionalKey,\n Schema.withConstructorDefault(Effect.succeed(\"auto\" as const)),\n ),\n /** Static query params appended to the endpoint URL (non-credential) */\n queryParams: Schema.optional(StringMap),\n /** Static headers sent on every request (non-credential) */\n headers: Schema.optional(StringMap),\n /** Declared auth methods — how a connection's values are rendered onto\n * requests. A connection's `template` picks one by slug. */\n authenticationTemplate: Schema.Array(McpAuthMethod),\n});\nexport type McpRemoteIntegrationConfig = typeof McpRemoteIntegrationConfig.Type;\n\nexport const McpStdioIntegrationConfig = Schema.Struct({\n transport: Schema.Literal(\"stdio\"),\n /** The command to run */\n command: Schema.String,\n /** Arguments to the command */\n args: Schema.optional(Schema.Array(Schema.String)),\n /** Static, non-credential environment variables injected verbatim into the\n * subprocess. Secret env (API keys / tokens) is NOT stored here — it is\n * declared as a `stdio_env` method in `authenticationTemplate` and its\n * values live on the connection. Optional + legacy: pre-revamp stdio\n * integrations stored their (then-plaintext) env here, so it stays\n * decodable. */\n env: Schema.optional(StringMap),\n /** Working directory */\n cwd: Schema.optional(Schema.String),\n /** Declared auth methods — a single `stdio_env` method naming the secret env\n * vars, or `none`. A connection's `template` picks one by slug, exactly as\n * for remote servers. Optional so pre-revamp stdio configs (which had no\n * methods) still decode; absence is treated as no declared secret env. */\n authenticationTemplate: Schema.optional(Schema.Array(McpAuthMethod)),\n});\nexport type McpStdioIntegrationConfig = typeof McpStdioIntegrationConfig.Type;\n\nexport const McpIntegrationConfig = Schema.Union([\n McpRemoteIntegrationConfig,\n McpStdioIntegrationConfig,\n]);\nexport type McpIntegrationConfig = typeof McpIntegrationConfig.Type;\n\nconst decodeIntegrationConfig = Schema.decodeUnknownOption(McpIntegrationConfig);\n\n/** Parse an opaque integration `config` blob into a typed MCP config, or null\n * if it isn't this plugin's (canonical) shape. Pre-canonical stored shapes\n * are rewritten by the one-off config migration (`migrate-config.ts`), not\n * decoded here — runtime code knows only the canonical model. */\nexport const parseMcpIntegrationConfig = (config: unknown): McpIntegrationConfig | null =>\n Option.getOrNull(decodeIntegrationConfig(config));\n\n// ---------------------------------------------------------------------------\n// Tool annotations — upstream MCP ToolAnnotations we honour (destructiveHint\n// drives requiresApproval).\n// ---------------------------------------------------------------------------\n\nexport const McpToolAnnotations = Schema.Struct({\n title: Schema.optional(Schema.String),\n readOnlyHint: Schema.optional(Schema.Boolean),\n destructiveHint: Schema.optional(Schema.Boolean),\n idempotentHint: Schema.optional(Schema.Boolean),\n openWorldHint: Schema.optional(Schema.Boolean),\n});\nexport type McpToolAnnotations = typeof McpToolAnnotations.Type;\n\n// ---------------------------------------------------------------------------\n// Tool binding — maps a persisted (sanitized) tool name back to its real MCP\n// tool name and upstream annotations, persisted per-connection so invokeTool\n// can dial the server with the correct name.\n// ---------------------------------------------------------------------------\n\nexport const McpToolBinding = Schema.Struct({\n /** Sanitized, address-safe tool name (the `<tool>` address segment). */\n toolId: Schema.String,\n /** The real MCP tool name as advertised by the server. */\n toolName: Schema.String,\n description: Schema.NullOr(Schema.String),\n inputSchema: Schema.optional(Schema.Unknown),\n outputSchema: Schema.optional(Schema.Unknown),\n annotations: Schema.optional(McpToolAnnotations),\n});\nexport type McpToolBinding = typeof McpToolBinding.Type;\n"],"mappings":"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","names":["Schema"]}
@@ -14,7 +14,7 @@ import {
14
14
  mcpAuthMethodFromShorthand,
15
15
  normalizeMcpAuthMethods,
16
16
  parseMcpIntegrationConfig
17
- } from "./chunk-4V3H3DDH.js";
17
+ } from "./chunk-OCDAATE3.js";
18
18
 
19
19
  // src/sdk/manifest.ts
20
20
  import { Option, Schema } from "effect";
@@ -99,6 +99,8 @@ import { CallToolResultSchema } from "@modelcontextprotocol/sdk/types.js";
99
99
  import * as z from "zod/v4";
100
100
  import {
101
101
  authToolFailure,
102
+ AuthTemplateSlug,
103
+ ConnectionName,
102
104
  definePlugin,
103
105
  IntegrationAlreadyExistsError,
104
106
  IntegrationSlug,
@@ -732,6 +734,13 @@ var McpStdioServerInputSchema = Schema4.Struct({
732
734
  description: Schema4.optional(Schema4.String),
733
735
  command: Schema4.String,
734
736
  args: Schema4.optional(Schema4.Array(Schema4.String)),
737
+ /** DECLARE the secret env vars this server needs, by NAME. Their values are
738
+ * supplied as the connection's secret credentials, not here — so the UI
739
+ * defines what env vars exist and the connect step provides the secrets. */
740
+ envVars: Schema4.optional(Schema4.Array(Schema4.String)),
741
+ /** Provide secret env values directly (programmatic / agent one-shot): the
742
+ * add then auto-creates the connection holding them. The UI uses `envVars`
743
+ * instead and leaves the values to the connect step. */
735
744
  env: Schema4.optional(Schema4.Record(Schema4.String, Schema4.String)),
736
745
  cwd: Schema4.optional(Schema4.String),
737
746
  slug: Schema4.optional(Schema4.String)
@@ -803,14 +812,21 @@ var normalizeSlug = (input) => input.slug ?? deriveMcpNamespace({
803
812
  endpoint: input.transport === "stdio" ? void 0 : input.endpoint,
804
813
  command: input.transport === "stdio" ? input.command : void 0
805
814
  });
815
+ var STDIO_ENV_TEMPLATE = "env";
816
+ var stdioEnvVarNames = (input) => {
817
+ const names = new Set(input.envVars ?? []);
818
+ for (const key of Object.keys(input.env ?? {})) names.add(key);
819
+ return [...names];
820
+ };
806
821
  var toIntegrationConfig = (input) => {
807
822
  if (input.transport === "stdio") {
823
+ const vars = stdioEnvVarNames(input);
808
824
  return {
809
825
  transport: "stdio",
810
826
  command: input.command,
811
827
  args: input.args ? [...input.args] : void 0,
812
- env: input.env,
813
- cwd: input.cwd
828
+ cwd: input.cwd,
829
+ authenticationTemplate: vars.length > 0 ? [{ slug: STDIO_ENV_TEMPLATE, kind: "stdio_env", vars }] : [{ slug: "none", kind: "none" }]
814
830
  };
815
831
  }
816
832
  return {
@@ -905,7 +921,7 @@ var makeOAuthProvider = (accessToken) => ({
905
921
  discoveryState: () => void 0
906
922
  });
907
923
  var selectAuthMethod = (config, templateSlug) => {
908
- const methods = config.authenticationTemplate;
924
+ const methods = config.authenticationTemplate ?? [];
909
925
  if (templateSlug !== null) {
910
926
  const match = methods.find((method) => method.slug === templateSlug);
911
927
  if (match) return match;
@@ -922,11 +938,19 @@ var buildConnectorInput = (config, values, templateSlug, allowStdio, httpClientL
922
938
  })
923
939
  );
924
940
  }
941
+ const method = selectAuthMethod(config, templateSlug);
942
+ const env = { ...config.env ?? {} };
943
+ if (method?.kind === "stdio_env") {
944
+ for (const variable of method.vars) {
945
+ const value = values[variable];
946
+ if (value != null) env[variable] = value;
947
+ }
948
+ }
925
949
  return Effect5.succeed({
926
950
  transport: "stdio",
927
951
  command: config.command,
928
952
  args: config.args,
929
- env: config.env,
953
+ env: Object.keys(env).length > 0 ? env : void 0,
930
954
  cwd: config.cwd
931
955
  });
932
956
  }
@@ -952,10 +976,19 @@ var buildConnectorInput = (config, values, templateSlug, allowStdio, httpClientL
952
976
  httpClientLayer
953
977
  });
954
978
  };
979
+ var describeStdioEnvAuthMethod = (method) => ({
980
+ id: method.slug,
981
+ label: "Environment variables",
982
+ kind: "apikey",
983
+ template: method.slug,
984
+ placements: method.vars.map((name) => ({ carrier: "env", name, prefix: "", variable: name }))
985
+ });
955
986
  var describeMcpAuthMethods = (record) => {
956
987
  const config = parseMcpIntegrationConfig(record.config);
957
- if (!config || config.transport === "stdio") return [];
958
- return config.authenticationTemplate.map((method) => {
988
+ if (!config) return [];
989
+ const methods = config.authenticationTemplate ?? [];
990
+ return methods.map((method) => {
991
+ if (method.kind === "stdio_env") return describeStdioEnvAuthMethod(method);
959
992
  if (method.kind === "apikey") return describeApiKeyAuthMethod(method);
960
993
  if (method.kind === "oauth2") {
961
994
  return {
@@ -963,7 +996,12 @@ var describeMcpAuthMethods = (record) => {
963
996
  label: "OAuth",
964
997
  kind: "oauth",
965
998
  template: method.slug,
966
- oauth: { discoveryUrl: config.endpoint, supportsDynamicRegistration: true }
999
+ // Only remote configs carry an endpoint; stdio never reaches here with
1000
+ // oauth2.
1001
+ oauth: {
1002
+ discoveryUrl: config.transport === "remote" ? config.endpoint : void 0,
1003
+ supportsDynamicRegistration: true
1004
+ }
967
1005
  };
968
1006
  }
969
1007
  return describeNoneAuthMethod(method.slug);
@@ -1129,6 +1167,38 @@ var mcpPlugin = definePlugin((options) => {
1129
1167
  attributes: { "mcp.integration.slug": slug }
1130
1168
  })
1131
1169
  );
1170
+ if (input.transport === "stdio") {
1171
+ const hasValues = input.env != null && Object.keys(input.env).length > 0;
1172
+ const declaresSecrets = stdioEnvVarNames(input).length > 0;
1173
+ if (hasValues || !declaresSecrets) {
1174
+ yield* ctx.connections.create({
1175
+ owner: "org",
1176
+ name: ConnectionName.make("default"),
1177
+ integration: slugFrom(slug),
1178
+ template: AuthTemplateSlug.make(hasValues ? STDIO_ENV_TEMPLATE : "none"),
1179
+ values: hasValues ? { ...input.env } : {}
1180
+ }).pipe(
1181
+ // These can't arise right after a successful register with
1182
+ // valid inputs, but the channel must stay within
1183
+ // McpExtensionFailure; surface them as a connection error
1184
+ // rather than swallow a real failure.
1185
+ Effect5.catchTags({
1186
+ IntegrationNotFoundError: (cause) => Effect5.fail(
1187
+ new McpConnectionError({ transport: "stdio", message: cause.message })
1188
+ ),
1189
+ CredentialProviderNotRegisteredError: (cause) => Effect5.fail(
1190
+ new McpConnectionError({ transport: "stdio", message: cause.message })
1191
+ ),
1192
+ InvalidConnectionInputError: (cause) => Effect5.fail(
1193
+ new McpConnectionError({ transport: "stdio", message: cause.message })
1194
+ )
1195
+ }),
1196
+ Effect5.withSpan("mcp.plugin.bootstrap_stdio_connection", {
1197
+ attributes: { "mcp.integration.slug": slug }
1198
+ })
1199
+ );
1200
+ }
1201
+ }
1132
1202
  return { slug };
1133
1203
  }).pipe(
1134
1204
  Effect5.withSpan("mcp.plugin.add_server", {
@@ -1138,6 +1208,50 @@ var mcpPlugin = definePlugin((options) => {
1138
1208
  }
1139
1209
  })
1140
1210
  );
1211
+ const reconcileStdioConnections = () => Effect5.gen(function* () {
1212
+ const integrations = yield* ctx.core.integrations.list();
1213
+ for (const integration of integrations) {
1214
+ if (integration.kind !== MCP_PLUGIN_ID) continue;
1215
+ yield* Effect5.gen(function* () {
1216
+ const record = yield* ctx.core.integrations.get(integration.slug);
1217
+ const config = record ? parseMcpIntegrationConfig(record.config) : null;
1218
+ if (!config || config.transport !== "stdio") return;
1219
+ if (config.authenticationTemplate !== void 0) return;
1220
+ const connections = yield* ctx.connections.list({
1221
+ integration: integration.slug
1222
+ });
1223
+ if (connections.length > 0) return;
1224
+ const inlineEnv = config.env ?? {};
1225
+ const envVars = Object.keys(inlineEnv);
1226
+ const hasEnv = envVars.length > 0;
1227
+ yield* ctx.connections.create({
1228
+ owner: "org",
1229
+ name: ConnectionName.make("default"),
1230
+ integration: integration.slug,
1231
+ template: AuthTemplateSlug.make(hasEnv ? STDIO_ENV_TEMPLATE : "none"),
1232
+ values: hasEnv ? { ...inlineEnv } : {}
1233
+ });
1234
+ const nextConfig = {
1235
+ transport: "stdio",
1236
+ command: config.command,
1237
+ args: config.args,
1238
+ cwd: config.cwd,
1239
+ authenticationTemplate: hasEnv ? [{ slug: STDIO_ENV_TEMPLATE, kind: "stdio_env", vars: envVars }] : [{ slug: "none", kind: "none" }]
1240
+ };
1241
+ yield* ctx.core.integrations.update(integration.slug, { config: nextConfig });
1242
+ }).pipe(
1243
+ Effect5.catch(
1244
+ (cause) => Effect5.logWarning(
1245
+ `mcp: failed healing stdio connection for "${integration.slug}"`,
1246
+ cause
1247
+ )
1248
+ ),
1249
+ Effect5.withSpan("mcp.plugin.reconcile_stdio_connection", {
1250
+ attributes: { "mcp.integration.slug": String(integration.slug) }
1251
+ })
1252
+ );
1253
+ }
1254
+ }).pipe(Effect5.withSpan("mcp.plugin.reconcile_stdio_connections"));
1141
1255
  const removeServer = (slug) => Effect5.gen(function* () {
1142
1256
  const integration = slugFrom(slug);
1143
1257
  const record = yield* ctx.core.integrations.get(integration);
@@ -1231,6 +1345,7 @@ var mcpPlugin = definePlugin((options) => {
1231
1345
  probeEndpoint,
1232
1346
  addServer,
1233
1347
  removeServer,
1348
+ reconcileStdioConnections,
1234
1349
  getServer,
1235
1350
  configureServer,
1236
1351
  configureAuth
@@ -1523,4 +1638,4 @@ export {
1523
1638
  userFacingProbeMessage,
1524
1639
  mcpPlugin
1525
1640
  };
1526
- //# sourceMappingURL=chunk-5GLUVX3H.js.map
1641
+ //# sourceMappingURL=chunk-OHITN5WV.js.map