@executor-js/plugin-mcp 1.5.20 → 1.5.22
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/{AddMcpSource-H67EJXJ7.js → AddMcpSource-XMJGVOWN.js} +27 -61
- package/dist/AddMcpSource-XMJGVOWN.js.map +1 -0
- package/dist/{EditMcpSource-AS3ZTP6W.js → EditMcpSource-GPXZQFL5.js} +3 -3
- package/dist/{McpAccountsPanel-4F5WE7FH.js → McpAccountsPanel-CNUWTJ4R.js} +7 -7
- package/dist/McpAccountsPanel-CNUWTJ4R.js.map +1 -0
- package/dist/api/group.d.ts +86 -0
- package/dist/api/index.d.ts +89 -1
- package/dist/{chunk-AMC5G2HJ.js → chunk-N6NNZDXN.js} +20 -2
- package/dist/chunk-N6NNZDXN.js.map +1 -0
- package/dist/{chunk-4V3H3DDH.js → chunk-OCDAATE3.js} +24 -4
- package/dist/chunk-OCDAATE3.js.map +1 -0
- package/dist/{chunk-XSZHVTEM.js → chunk-OHITN5WV.js} +124 -9
- package/dist/chunk-OHITN5WV.js.map +1 -0
- package/dist/client.js +3 -3
- package/dist/core.js +2 -2
- package/dist/index.js +2 -2
- package/dist/react/atoms.d.ts +92 -9
- package/dist/react/client.d.ts +83 -0
- package/dist/sdk/plugin.d.ts +23 -1
- package/dist/sdk/types.d.ts +89 -2
- package/package.json +3 -3
- package/dist/AddMcpSource-H67EJXJ7.js.map +0 -1
- package/dist/McpAccountsPanel-4F5WE7FH.js.map +0 -1
- package/dist/chunk-4V3H3DDH.js.map +0 -1
- package/dist/chunk-AMC5G2HJ.js.map +0 -1
- package/dist/chunk-XSZHVTEM.js.map +0 -1
- /package/dist/{EditMcpSource-AS3ZTP6W.js.map → EditMcpSource-GPXZQFL5.js.map} +0 -0
package/dist/api/index.d.ts
CHANGED
|
@@ -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-
|
|
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-
|
|
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
|
|
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
|
-
/**
|
|
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-
|
|
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-
|
|
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
|
-
|
|
813
|
-
|
|
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:
|
|
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
|
|
958
|
-
|
|
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
|
-
|
|
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-
|
|
1641
|
+
//# sourceMappingURL=chunk-OHITN5WV.js.map
|