@executor-js/plugin-mcp 1.5.21 → 2.0.0
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-GOIRH5FQ.js → AddMcpSource-I67EKOO6.js} +28 -68
- package/dist/AddMcpSource-I67EKOO6.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-5GLUVX3H.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-GOIRH5FQ.js.map +0 -1
- package/dist/McpAccountsPanel-4F5WE7FH.js.map +0 -1
- package/dist/chunk-4V3H3DDH.js.map +0 -1
- package/dist/chunk-5GLUVX3H.js.map +0 -1
- package/dist/chunk-AMC5G2HJ.js.map +0 -1
- /package/dist/{EditMcpSource-AS3ZTP6W.js.map → EditMcpSource-GPXZQFL5.js.map} +0 -0
package/dist/react/client.d.ts
CHANGED
|
@@ -55,6 +55,7 @@ export declare const McpClient: import("effect/unstable/reactivity/AtomHttpApi")
|
|
|
55
55
|
readonly description: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
56
56
|
readonly command: import("effect/Schema").String;
|
|
57
57
|
readonly args: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").String>>;
|
|
58
|
+
readonly envVars: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").String>>;
|
|
58
59
|
readonly env: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").String>>;
|
|
59
60
|
readonly cwd: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
60
61
|
readonly slug: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
@@ -95,6 +96,10 @@ export declare const McpClient: import("effect/unstable/reactivity/AtomHttpApi")
|
|
|
95
96
|
}>, import("effect/Schema").Struct<{
|
|
96
97
|
readonly slug: import("effect/Schema").String;
|
|
97
98
|
readonly kind: import("effect/Schema").Literal<"oauth2">;
|
|
99
|
+
}>, import("effect/Schema").Struct<{
|
|
100
|
+
readonly slug: import("effect/Schema").String;
|
|
101
|
+
readonly kind: import("effect/Schema").Literal<"stdio_env">;
|
|
102
|
+
readonly vars: import("effect/Schema").$Array<import("effect/Schema").String>;
|
|
98
103
|
}>]>>;
|
|
99
104
|
}>, import("effect/Schema").Struct<{
|
|
100
105
|
readonly transport: import("effect/Schema").Literal<"stdio">;
|
|
@@ -102,6 +107,28 @@ export declare const McpClient: import("effect/unstable/reactivity/AtomHttpApi")
|
|
|
102
107
|
readonly args: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").String>>;
|
|
103
108
|
readonly env: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").String>>;
|
|
104
109
|
readonly cwd: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
110
|
+
readonly authenticationTemplate: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").Union<readonly [import("effect/Schema").Struct<{
|
|
111
|
+
readonly slug: import("effect/Schema").String;
|
|
112
|
+
readonly kind: import("effect/Schema").Literal<"none">;
|
|
113
|
+
}>, import("effect/Schema").Struct<{
|
|
114
|
+
readonly slug: import("effect/Schema").String;
|
|
115
|
+
readonly kind: import("effect/Schema").Literal<"apikey">;
|
|
116
|
+
readonly label: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
117
|
+
readonly placements: import("effect/Schema").$Array<import("effect/Schema").Struct<{
|
|
118
|
+
readonly carrier: import("effect/Schema").Literals<readonly ["header", "query"]>;
|
|
119
|
+
readonly name: import("effect/Schema").String;
|
|
120
|
+
readonly prefix: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
121
|
+
readonly variable: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
122
|
+
readonly literal: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
123
|
+
}>>;
|
|
124
|
+
}>, import("effect/Schema").Struct<{
|
|
125
|
+
readonly slug: import("effect/Schema").String;
|
|
126
|
+
readonly kind: import("effect/Schema").Literal<"oauth2">;
|
|
127
|
+
}>, import("effect/Schema").Struct<{
|
|
128
|
+
readonly slug: import("effect/Schema").String;
|
|
129
|
+
readonly kind: import("effect/Schema").Literal<"stdio_env">;
|
|
130
|
+
readonly vars: import("effect/Schema").$Array<import("effect/Schema").String>;
|
|
131
|
+
}>]>>>;
|
|
105
132
|
}>]>;
|
|
106
133
|
}>>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("@executor-js/sdk").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<{
|
|
107
134
|
slug: import("effect/Schema").brand<import("effect/Schema").String, "IntegrationSlug">;
|
|
@@ -129,6 +156,10 @@ export declare const McpClient: import("effect/unstable/reactivity/AtomHttpApi")
|
|
|
129
156
|
}>, import("effect/Schema").Struct<{
|
|
130
157
|
readonly slug: import("effect/Schema").String;
|
|
131
158
|
readonly kind: import("effect/Schema").Literal<"oauth2">;
|
|
159
|
+
}>, import("effect/Schema").Struct<{
|
|
160
|
+
readonly slug: import("effect/Schema").String;
|
|
161
|
+
readonly kind: import("effect/Schema").Literal<"stdio_env">;
|
|
162
|
+
readonly vars: import("effect/Schema").$Array<import("effect/Schema").String>;
|
|
132
163
|
}>]>>;
|
|
133
164
|
}>, import("effect/Schema").Struct<{
|
|
134
165
|
readonly transport: import("effect/Schema").Literal<"stdio">;
|
|
@@ -136,6 +167,28 @@ export declare const McpClient: import("effect/unstable/reactivity/AtomHttpApi")
|
|
|
136
167
|
readonly args: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").String>>;
|
|
137
168
|
readonly env: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").String>>;
|
|
138
169
|
readonly cwd: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
170
|
+
readonly authenticationTemplate: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").Union<readonly [import("effect/Schema").Struct<{
|
|
171
|
+
readonly slug: import("effect/Schema").String;
|
|
172
|
+
readonly kind: import("effect/Schema").Literal<"none">;
|
|
173
|
+
}>, import("effect/Schema").Struct<{
|
|
174
|
+
readonly slug: import("effect/Schema").String;
|
|
175
|
+
readonly kind: import("effect/Schema").Literal<"apikey">;
|
|
176
|
+
readonly label: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
177
|
+
readonly placements: import("effect/Schema").$Array<import("effect/Schema").Struct<{
|
|
178
|
+
readonly carrier: import("effect/Schema").Literals<readonly ["header", "query"]>;
|
|
179
|
+
readonly name: import("effect/Schema").String;
|
|
180
|
+
readonly prefix: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
181
|
+
readonly variable: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
182
|
+
readonly literal: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
183
|
+
}>>;
|
|
184
|
+
}>, import("effect/Schema").Struct<{
|
|
185
|
+
readonly slug: import("effect/Schema").String;
|
|
186
|
+
readonly kind: import("effect/Schema").Literal<"oauth2">;
|
|
187
|
+
}>, import("effect/Schema").Struct<{
|
|
188
|
+
readonly slug: import("effect/Schema").String;
|
|
189
|
+
readonly kind: import("effect/Schema").Literal<"stdio_env">;
|
|
190
|
+
readonly vars: import("effect/Schema").$Array<import("effect/Schema").String>;
|
|
191
|
+
}>]>>>;
|
|
139
192
|
}>]>;
|
|
140
193
|
}>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
|
|
141
194
|
readonly config: import("effect/Schema").Union<readonly [import("effect/Schema").Struct<{
|
|
@@ -161,6 +214,10 @@ export declare const McpClient: import("effect/unstable/reactivity/AtomHttpApi")
|
|
|
161
214
|
}>, import("effect/Schema").Struct<{
|
|
162
215
|
readonly slug: import("effect/Schema").String;
|
|
163
216
|
readonly kind: import("effect/Schema").Literal<"oauth2">;
|
|
217
|
+
}>, import("effect/Schema").Struct<{
|
|
218
|
+
readonly slug: import("effect/Schema").String;
|
|
219
|
+
readonly kind: import("effect/Schema").Literal<"stdio_env">;
|
|
220
|
+
readonly vars: import("effect/Schema").$Array<import("effect/Schema").String>;
|
|
164
221
|
}>]>>;
|
|
165
222
|
}>, import("effect/Schema").Struct<{
|
|
166
223
|
readonly transport: import("effect/Schema").Literal<"stdio">;
|
|
@@ -168,6 +225,28 @@ export declare const McpClient: import("effect/unstable/reactivity/AtomHttpApi")
|
|
|
168
225
|
readonly args: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").String>>;
|
|
169
226
|
readonly env: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").String>>;
|
|
170
227
|
readonly cwd: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
228
|
+
readonly authenticationTemplate: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").Union<readonly [import("effect/Schema").Struct<{
|
|
229
|
+
readonly slug: import("effect/Schema").String;
|
|
230
|
+
readonly kind: import("effect/Schema").Literal<"none">;
|
|
231
|
+
}>, import("effect/Schema").Struct<{
|
|
232
|
+
readonly slug: import("effect/Schema").String;
|
|
233
|
+
readonly kind: import("effect/Schema").Literal<"apikey">;
|
|
234
|
+
readonly label: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
235
|
+
readonly placements: import("effect/Schema").$Array<import("effect/Schema").Struct<{
|
|
236
|
+
readonly carrier: import("effect/Schema").Literals<readonly ["header", "query"]>;
|
|
237
|
+
readonly name: import("effect/Schema").String;
|
|
238
|
+
readonly prefix: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
239
|
+
readonly variable: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
240
|
+
readonly literal: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
241
|
+
}>>;
|
|
242
|
+
}>, import("effect/Schema").Struct<{
|
|
243
|
+
readonly slug: import("effect/Schema").String;
|
|
244
|
+
readonly kind: import("effect/Schema").Literal<"oauth2">;
|
|
245
|
+
}>, import("effect/Schema").Struct<{
|
|
246
|
+
readonly slug: import("effect/Schema").String;
|
|
247
|
+
readonly kind: import("effect/Schema").Literal<"stdio_env">;
|
|
248
|
+
readonly vars: import("effect/Schema").$Array<import("effect/Schema").String>;
|
|
249
|
+
}>]>>>;
|
|
171
250
|
}>]>;
|
|
172
251
|
}>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("@executor-js/sdk").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<{
|
|
173
252
|
slug: import("effect/Schema").brand<import("effect/Schema").String, "IntegrationSlug">;
|
|
@@ -210,5 +289,9 @@ export declare const McpClient: import("effect/unstable/reactivity/AtomHttpApi")
|
|
|
210
289
|
}>, import("effect/Schema").Struct<{
|
|
211
290
|
readonly slug: import("effect/Schema").String;
|
|
212
291
|
readonly kind: import("effect/Schema").Literal<"oauth2">;
|
|
292
|
+
}>, import("effect/Schema").Struct<{
|
|
293
|
+
readonly slug: import("effect/Schema").String;
|
|
294
|
+
readonly kind: import("effect/Schema").Literal<"stdio_env">;
|
|
295
|
+
readonly vars: import("effect/Schema").$Array<import("effect/Schema").String>;
|
|
213
296
|
}>]>>;
|
|
214
297
|
}>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("@executor-js/sdk").InternalError | typeof import("../sdk").McpConnectionError | typeof import("../sdk").McpToolDiscoveryError>, never, never>, false>>;
|
package/dist/sdk/plugin.d.ts
CHANGED
|
@@ -52,6 +52,13 @@ declare const McpStdioServerInputSchema: Schema.Struct<{
|
|
|
52
52
|
readonly description: Schema.optional<Schema.String>;
|
|
53
53
|
readonly command: Schema.String;
|
|
54
54
|
readonly args: Schema.optional<Schema.$Array<Schema.String>>;
|
|
55
|
+
/** DECLARE the secret env vars this server needs, by NAME. Their values are
|
|
56
|
+
* supplied as the connection's secret credentials, not here — so the UI
|
|
57
|
+
* defines what env vars exist and the connect step provides the secrets. */
|
|
58
|
+
readonly envVars: Schema.optional<Schema.$Array<Schema.String>>;
|
|
59
|
+
/** Provide secret env values directly (programmatic / agent one-shot): the
|
|
60
|
+
* add then auto-creates the connection holding them. The UI uses `envVars`
|
|
61
|
+
* instead and leaves the values to the connect step. */
|
|
55
62
|
readonly env: Schema.optional<Schema.$Record<Schema.String, Schema.String>>;
|
|
56
63
|
readonly cwd: Schema.optional<Schema.String>;
|
|
57
64
|
readonly slug: Schema.optional<Schema.String>;
|
|
@@ -103,6 +110,13 @@ declare const McpAddServerInputSchema: Schema.Union<readonly [Schema.Struct<{
|
|
|
103
110
|
readonly description: Schema.optional<Schema.String>;
|
|
104
111
|
readonly command: Schema.String;
|
|
105
112
|
readonly args: Schema.optional<Schema.$Array<Schema.String>>;
|
|
113
|
+
/** DECLARE the secret env vars this server needs, by NAME. Their values are
|
|
114
|
+
* supplied as the connection's secret credentials, not here — so the UI
|
|
115
|
+
* defines what env vars exist and the connect step provides the secrets. */
|
|
116
|
+
readonly envVars: Schema.optional<Schema.$Array<Schema.String>>;
|
|
117
|
+
/** Provide secret env values directly (programmatic / agent one-shot): the
|
|
118
|
+
* add then auto-creates the connection holding them. The UI uses `envVars`
|
|
119
|
+
* instead and leaves the values to the connect step. */
|
|
106
120
|
readonly env: Schema.optional<Schema.$Record<Schema.String, Schema.String>>;
|
|
107
121
|
readonly cwd: Schema.optional<Schema.String>;
|
|
108
122
|
readonly slug: Schema.optional<Schema.String>;
|
|
@@ -211,8 +225,9 @@ export declare const mcpPlugin: import("@executor-js/sdk").ConfiguredPlugin<"mcp
|
|
|
211
225
|
}, McpConnectionError, never>;
|
|
212
226
|
addServer: (input: McpServerInput) => Effect.Effect<{
|
|
213
227
|
slug: string;
|
|
214
|
-
}, StorageFailure | IntegrationAlreadyExistsError, never>;
|
|
228
|
+
}, StorageFailure | IntegrationAlreadyExistsError | McpConnectionError, never>;
|
|
215
229
|
removeServer: (slug: string) => Effect.Effect<void, StorageFailure, never>;
|
|
230
|
+
reconcileStdioConnections: () => Effect.Effect<void, StorageFailure, never>;
|
|
216
231
|
getServer: (slug: string) => Effect.Effect<IntegrationRecord | null, StorageFailure, never>;
|
|
217
232
|
configureServer: (slug: string, config: McpIntegrationConfigType) => Effect.Effect<void, StorageFailure, never>;
|
|
218
233
|
configureAuth: (slug: string, input: McpConfigureAuthInput) => Effect.Effect<readonly ({
|
|
@@ -232,6 +247,10 @@ export declare const mcpPlugin: import("@executor-js/sdk").ConfiguredPlugin<"mcp
|
|
|
232
247
|
} | {
|
|
233
248
|
readonly slug: string;
|
|
234
249
|
readonly kind: "oauth2";
|
|
250
|
+
} | {
|
|
251
|
+
readonly slug: string;
|
|
252
|
+
readonly kind: "stdio_env";
|
|
253
|
+
readonly vars: readonly string[];
|
|
235
254
|
})[], StorageFailure, never>;
|
|
236
255
|
}, {}, McpPluginOptions, undefined, Layer.Layer<unknown, never, never>, import("effect/unstable/httpapi/HttpApiGroup").Any>;
|
|
237
256
|
export type McpExtensionFailure = McpConnectionError | McpToolDiscoveryError | StorageFailure;
|
|
@@ -241,6 +260,9 @@ export interface McpPluginExtension {
|
|
|
241
260
|
readonly slug: string;
|
|
242
261
|
}, McpExtensionFailure | IntegrationAlreadyExistsError>;
|
|
243
262
|
readonly removeServer: (slug: string) => Effect.Effect<void, McpExtensionFailure>;
|
|
263
|
+
/** Ensure every stdio integration has its default connection (migrating any
|
|
264
|
+
* legacy inline env into the secret store). Idempotent; safe to run at boot. */
|
|
265
|
+
readonly reconcileStdioConnections: () => Effect.Effect<void, McpExtensionFailure>;
|
|
244
266
|
readonly getServer: (slug: string) => Effect.Effect<(Integration & {
|
|
245
267
|
readonly config: IntegrationConfig;
|
|
246
268
|
}) | null, McpExtensionFailure>;
|
package/dist/sdk/types.d.ts
CHANGED
|
@@ -10,6 +10,19 @@ export declare const McpOAuthMethod: Schema.Struct<{
|
|
|
10
10
|
readonly kind: Schema.Literal<"oauth2">;
|
|
11
11
|
}>;
|
|
12
12
|
export type McpOAuthMethod = typeof McpOAuthMethod.Type;
|
|
13
|
+
/** Stdio env credential: the named environment variables a stdio server needs
|
|
14
|
+
* (often API keys / tokens). A connection supplies one secret value per `var`,
|
|
15
|
+
* keyed by the var name; at launch the connector injects them into the
|
|
16
|
+
* subprocess env. The VALUES live in the secret store as the connection's
|
|
17
|
+
* inputs, never in this config blob — that is the "properly store auth" half
|
|
18
|
+
* of the stdio model, mirroring how remote apikey methods keep their secrets
|
|
19
|
+
* on the connection rather than the integration. */
|
|
20
|
+
export declare const McpStdioEnvMethod: Schema.Struct<{
|
|
21
|
+
readonly slug: Schema.String;
|
|
22
|
+
readonly kind: Schema.Literal<"stdio_env">;
|
|
23
|
+
readonly vars: Schema.$Array<Schema.String>;
|
|
24
|
+
}>;
|
|
25
|
+
export type McpStdioEnvMethod = typeof McpStdioEnvMethod.Type;
|
|
13
26
|
export declare const McpAuthMethod: Schema.Union<readonly [Schema.Struct<{
|
|
14
27
|
readonly slug: Schema.String;
|
|
15
28
|
readonly kind: Schema.Literal<"none">;
|
|
@@ -27,6 +40,10 @@ export declare const McpAuthMethod: Schema.Union<readonly [Schema.Struct<{
|
|
|
27
40
|
}>, Schema.Struct<{
|
|
28
41
|
readonly slug: Schema.String;
|
|
29
42
|
readonly kind: Schema.Literal<"oauth2">;
|
|
43
|
+
}>, Schema.Struct<{
|
|
44
|
+
readonly slug: Schema.String;
|
|
45
|
+
readonly kind: Schema.Literal<"stdio_env">;
|
|
46
|
+
readonly vars: Schema.$Array<Schema.String>;
|
|
30
47
|
}>]>;
|
|
31
48
|
export type McpAuthMethod = typeof McpAuthMethod.Type;
|
|
32
49
|
/** Single-method `auth` shorthand on `addServer` — agent convenience for the
|
|
@@ -111,6 +128,10 @@ export declare const McpRemoteIntegrationConfig: Schema.Struct<{
|
|
|
111
128
|
}>, Schema.Struct<{
|
|
112
129
|
readonly slug: Schema.String;
|
|
113
130
|
readonly kind: Schema.Literal<"oauth2">;
|
|
131
|
+
}>, Schema.Struct<{
|
|
132
|
+
readonly slug: Schema.String;
|
|
133
|
+
readonly kind: Schema.Literal<"stdio_env">;
|
|
134
|
+
readonly vars: Schema.$Array<Schema.String>;
|
|
114
135
|
}>]>>;
|
|
115
136
|
}>;
|
|
116
137
|
export type McpRemoteIntegrationConfig = typeof McpRemoteIntegrationConfig.Type;
|
|
@@ -120,10 +141,41 @@ export declare const McpStdioIntegrationConfig: Schema.Struct<{
|
|
|
120
141
|
readonly command: Schema.String;
|
|
121
142
|
/** Arguments to the command */
|
|
122
143
|
readonly args: Schema.optional<Schema.$Array<Schema.String>>;
|
|
123
|
-
/**
|
|
144
|
+
/** Static, non-credential environment variables injected verbatim into the
|
|
145
|
+
* subprocess. Secret env (API keys / tokens) is NOT stored here — it is
|
|
146
|
+
* declared as a `stdio_env` method in `authenticationTemplate` and its
|
|
147
|
+
* values live on the connection. Optional + legacy: pre-revamp stdio
|
|
148
|
+
* integrations stored their (then-plaintext) env here, so it stays
|
|
149
|
+
* decodable. */
|
|
124
150
|
readonly env: Schema.optional<Schema.$Record<Schema.String, Schema.String>>;
|
|
125
151
|
/** Working directory */
|
|
126
152
|
readonly cwd: Schema.optional<Schema.String>;
|
|
153
|
+
/** Declared auth methods — a single `stdio_env` method naming the secret env
|
|
154
|
+
* vars, or `none`. A connection's `template` picks one by slug, exactly as
|
|
155
|
+
* for remote servers. Optional so pre-revamp stdio configs (which had no
|
|
156
|
+
* methods) still decode; absence is treated as no declared secret env. */
|
|
157
|
+
readonly authenticationTemplate: Schema.optional<Schema.$Array<Schema.Union<readonly [Schema.Struct<{
|
|
158
|
+
readonly slug: Schema.String;
|
|
159
|
+
readonly kind: Schema.Literal<"none">;
|
|
160
|
+
}>, Schema.Struct<{
|
|
161
|
+
readonly slug: Schema.String;
|
|
162
|
+
readonly kind: Schema.Literal<"apikey">;
|
|
163
|
+
readonly label: Schema.optional<Schema.String>;
|
|
164
|
+
readonly placements: Schema.$Array<Schema.Struct<{
|
|
165
|
+
readonly carrier: Schema.Literals<readonly ["header", "query"]>;
|
|
166
|
+
readonly name: Schema.String;
|
|
167
|
+
readonly prefix: Schema.optional<Schema.String>;
|
|
168
|
+
readonly variable: Schema.optional<Schema.String>;
|
|
169
|
+
readonly literal: Schema.optional<Schema.String>;
|
|
170
|
+
}>>;
|
|
171
|
+
}>, Schema.Struct<{
|
|
172
|
+
readonly slug: Schema.String;
|
|
173
|
+
readonly kind: Schema.Literal<"oauth2">;
|
|
174
|
+
}>, Schema.Struct<{
|
|
175
|
+
readonly slug: Schema.String;
|
|
176
|
+
readonly kind: Schema.Literal<"stdio_env">;
|
|
177
|
+
readonly vars: Schema.$Array<Schema.String>;
|
|
178
|
+
}>]>>>;
|
|
127
179
|
}>;
|
|
128
180
|
export type McpStdioIntegrationConfig = typeof McpStdioIntegrationConfig.Type;
|
|
129
181
|
export declare const McpIntegrationConfig: Schema.Union<readonly [Schema.Struct<{
|
|
@@ -155,6 +207,10 @@ export declare const McpIntegrationConfig: Schema.Union<readonly [Schema.Struct<
|
|
|
155
207
|
}>, Schema.Struct<{
|
|
156
208
|
readonly slug: Schema.String;
|
|
157
209
|
readonly kind: Schema.Literal<"oauth2">;
|
|
210
|
+
}>, Schema.Struct<{
|
|
211
|
+
readonly slug: Schema.String;
|
|
212
|
+
readonly kind: Schema.Literal<"stdio_env">;
|
|
213
|
+
readonly vars: Schema.$Array<Schema.String>;
|
|
158
214
|
}>]>>;
|
|
159
215
|
}>, Schema.Struct<{
|
|
160
216
|
readonly transport: Schema.Literal<"stdio">;
|
|
@@ -162,10 +218,41 @@ export declare const McpIntegrationConfig: Schema.Union<readonly [Schema.Struct<
|
|
|
162
218
|
readonly command: Schema.String;
|
|
163
219
|
/** Arguments to the command */
|
|
164
220
|
readonly args: Schema.optional<Schema.$Array<Schema.String>>;
|
|
165
|
-
/**
|
|
221
|
+
/** Static, non-credential environment variables injected verbatim into the
|
|
222
|
+
* subprocess. Secret env (API keys / tokens) is NOT stored here — it is
|
|
223
|
+
* declared as a `stdio_env` method in `authenticationTemplate` and its
|
|
224
|
+
* values live on the connection. Optional + legacy: pre-revamp stdio
|
|
225
|
+
* integrations stored their (then-plaintext) env here, so it stays
|
|
226
|
+
* decodable. */
|
|
166
227
|
readonly env: Schema.optional<Schema.$Record<Schema.String, Schema.String>>;
|
|
167
228
|
/** Working directory */
|
|
168
229
|
readonly cwd: Schema.optional<Schema.String>;
|
|
230
|
+
/** Declared auth methods — a single `stdio_env` method naming the secret env
|
|
231
|
+
* vars, or `none`. A connection's `template` picks one by slug, exactly as
|
|
232
|
+
* for remote servers. Optional so pre-revamp stdio configs (which had no
|
|
233
|
+
* methods) still decode; absence is treated as no declared secret env. */
|
|
234
|
+
readonly authenticationTemplate: Schema.optional<Schema.$Array<Schema.Union<readonly [Schema.Struct<{
|
|
235
|
+
readonly slug: Schema.String;
|
|
236
|
+
readonly kind: Schema.Literal<"none">;
|
|
237
|
+
}>, Schema.Struct<{
|
|
238
|
+
readonly slug: Schema.String;
|
|
239
|
+
readonly kind: Schema.Literal<"apikey">;
|
|
240
|
+
readonly label: Schema.optional<Schema.String>;
|
|
241
|
+
readonly placements: Schema.$Array<Schema.Struct<{
|
|
242
|
+
readonly carrier: Schema.Literals<readonly ["header", "query"]>;
|
|
243
|
+
readonly name: Schema.String;
|
|
244
|
+
readonly prefix: Schema.optional<Schema.String>;
|
|
245
|
+
readonly variable: Schema.optional<Schema.String>;
|
|
246
|
+
readonly literal: Schema.optional<Schema.String>;
|
|
247
|
+
}>>;
|
|
248
|
+
}>, Schema.Struct<{
|
|
249
|
+
readonly slug: Schema.String;
|
|
250
|
+
readonly kind: Schema.Literal<"oauth2">;
|
|
251
|
+
}>, Schema.Struct<{
|
|
252
|
+
readonly slug: Schema.String;
|
|
253
|
+
readonly kind: Schema.Literal<"stdio_env">;
|
|
254
|
+
readonly vars: Schema.$Array<Schema.String>;
|
|
255
|
+
}>]>>>;
|
|
169
256
|
}>]>;
|
|
170
257
|
export type McpIntegrationConfig = typeof McpIntegrationConfig.Type;
|
|
171
258
|
/** Parse an opaque integration `config` blob into a typed MCP config, or null
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@executor-js/plugin-mcp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"homepage": "https://github.com/RhysSullivan/executor/tree/main/packages/plugins/mcp",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/RhysSullivan/executor/issues"
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@cfworker/json-schema": "^4.1.1",
|
|
56
56
|
"@effect/platform-node": "4.0.0-beta.59",
|
|
57
|
-
"@executor-js/config": "
|
|
58
|
-
"@executor-js/sdk": "
|
|
57
|
+
"@executor-js/config": "2.0.0",
|
|
58
|
+
"@executor-js/sdk": "2.0.0",
|
|
59
59
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
60
60
|
"zod": "4.3.6"
|
|
61
61
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react/AddMcpSource.tsx","../src/react/McpRemoteSourceFields.tsx"],"sourcesContent":["import { useReducer, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useAtomSet } from \"@effect/atom-react\";\nimport * as Exit from \"effect/Exit\";\nimport * as Match from \"effect/Match\";\n\nimport { Button } from \"@executor-js/react/components/button\";\nimport {\n AuthMethodListEditor,\n useAuthMethodList,\n type AuthMethodRow,\n type AuthMethodSeed,\n} from \"@executor-js/react/components/auth-method-list-editor\";\nimport {\n CardStack,\n CardStackContent,\n CardStackEntryField,\n} from \"@executor-js/react/components/card-stack\";\nimport { FloatActions } from \"@executor-js/react/components/float-actions\";\nimport { Input } from \"@executor-js/react/components/input\";\nimport { Spinner } from \"@executor-js/react/components/spinner\";\nimport { Textarea } from \"@executor-js/react/components/textarea\";\nimport {\n integrationDisplayNameFromUrl,\n slugifyNamespace,\n IntegrationIdentityFields,\n useIntegrationIdentity,\n} from \"@executor-js/react/plugins/integration-identity\";\nimport {\n addIntegrationErrorMessage,\n errorMessageFromExit,\n FormErrorAlert,\n SlugCollisionAlert,\n useSlugAlreadyExists,\n} from \"@executor-js/react/lib/integration-add\";\n\nimport { integrationWriteKeys } from \"@executor-js/react/api/reactivity-keys\";\nimport type { McpAuthMethodInput } from \"../sdk/types\";\nimport { probeMcpEndpoint, addMcpServer } from \"./atoms\";\nimport { McpRemoteSourceFields } from \"./McpRemoteSourceFields\";\nimport { mcpAuthMethodInputFromEditorValue, mcpWireAuthInput } from \"./auth-method-config\";\nimport { mcpPresets, type McpPreset } from \"../sdk/presets\";\n\n// The remote add flow REGISTERS the server's declared auth methods through the\n// shared `AuthMethodListEditor` — accounts (the API key value / OAuth sign-in)\n// are added later from the integration's detail hub (P6: add without auth,\n// connect later). The probe SEEDS the list (detected OAuth → an OAuth row; a\n// 401 without OAuth → a bearer-header row; open server → a no-auth row) and\n// the user can add alternate methods (e.g. an API key alongside OAuth, or a\n// declared method on a server that advertises none).\n\nconst STDIO_ENV_ESCAPE_REPLACEMENTS: Readonly<Record<string, string>> = {\n \"\\\\\": \"\\\\\",\n n: \"\\n\",\n r: \"\\r\",\n t: \"\\t\",\n '\"': '\"',\n};\n\n// ---------------------------------------------------------------------------\n// Preset lookup\n// ---------------------------------------------------------------------------\n\nfunction findPreset(id: string | undefined): McpPreset | undefined {\n if (!id) return undefined;\n return mcpPresets.find((p) => p.id === id);\n}\n\n// ---------------------------------------------------------------------------\n// State machine (remote flow)\n// ---------------------------------------------------------------------------\n\ntype ProbeResult = {\n connected: boolean;\n requiresAuthentication: boolean;\n requiresOAuth: boolean;\n supportsDynamicRegistration: boolean;\n name: string;\n slug: string;\n toolCount: number | null;\n serverName: string | null;\n instructions: string | null;\n};\n\ntype State =\n | { step: \"url\"; url: string }\n | { step: \"probing\"; url: string; probe: ProbeResult | null }\n | { step: \"probed\"; url: string; probe: ProbeResult }\n | { step: \"adding\"; url: string; probe: ProbeResult }\n | {\n step: \"error\";\n url: string;\n probe: ProbeResult | null;\n error: string;\n };\n\ntype Action =\n | { type: \"set-url\"; url: string }\n | { type: \"probe-start\" }\n | { type: \"probe-ok\"; probe: ProbeResult }\n | { type: \"probe-fail\"; error: string }\n | { type: \"add-start\" }\n | { type: \"add-fail\"; error: string }\n | { type: \"retry\" };\n\nconst init: State = { step: \"url\", url: \"\" };\n\nfunction reducer(state: State, action: Action): State {\n return Match.value(action).pipe(\n Match.discriminator(\"type\")(\"set-url\", (a): State => ({ step: \"url\", url: a.url })),\n Match.discriminator(\"type\")(\n \"probe-start\",\n (): State => ({\n step: \"probing\",\n url: state.url,\n probe: \"probe\" in state ? state.probe : null,\n }),\n ),\n Match.discriminator(\"type\")(\n \"probe-ok\",\n (a): State => ({ step: \"probed\", url: state.url, probe: a.probe }),\n ),\n Match.discriminator(\"type\")(\n \"probe-fail\",\n (a): State => ({\n step: \"error\",\n url: state.url,\n probe: null,\n error: a.error,\n }),\n ),\n Match.discriminator(\"type\")(\"add-start\", (): State => {\n const probe = \"probe\" in state ? state.probe : null;\n if (!probe) return state;\n return { step: \"adding\", url: state.url, probe };\n }),\n Match.discriminator(\"type\")(\"add-fail\", (a): State => {\n if (state.step !== \"adding\") return state;\n return {\n step: \"error\",\n url: state.url,\n probe: state.probe,\n error: a.error,\n };\n }),\n Match.discriminator(\"type\")(\"retry\", (): State => {\n if (state.step !== \"error\") return state;\n return state.probe\n ? { step: \"probed\", url: state.url, probe: state.probe }\n : { step: \"url\", url: state.url };\n }),\n Match.exhaustive,\n );\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport default function AddMcpSource(props: {\n onComplete: (slug?: string) => void;\n onCancel: () => void;\n initialUrl?: string;\n initialPreset?: string;\n /** Whether the stdio transport is enabled on the server. */\n allowStdio?: boolean;\n}) {\n const allowStdio = props.allowStdio ?? false;\n const rawPreset = findPreset(props.initialPreset);\n // Drop stdio presets when stdio is disabled — the caller should have\n // already filtered these out, but defence-in-depth.\n const preset = rawPreset?.transport === \"stdio\" && !allowStdio ? undefined : rawPreset;\n const isStdioPreset = preset?.transport === \"stdio\";\n\n const [transport, setTransport] = useState<\"remote\" | \"stdio\">(\n isStdioPreset && allowStdio ? \"stdio\" : \"remote\",\n );\n\n // --- Stdio state ---\n const [stdioCommand, setStdioCommand] = useState(isStdioPreset ? preset.command : \"\");\n const [stdioArgs, setStdioArgs] = useState(\n isStdioPreset && preset.args ? preset.args.join(\" \") : \"\",\n );\n const [stdioEnv, setStdioEnv] = useState(\"\");\n const stdioIdentity = useIntegrationIdentity({\n fallbackName: isStdioPreset ? preset.name : stdioCommand,\n });\n const [stdioAdding, setStdioAdding] = useState(false);\n const [stdioError, setStdioError] = useState<string | null>(null);\n\n // --- Remote state ---\n const remoteUrl =\n !isStdioPreset && preset?.transport === undefined && preset?.url\n ? preset.url\n : (props.initialUrl ?? \"\");\n\n const [state, dispatch] = useReducer(\n reducer,\n remoteUrl ? { step: \"url\" as const, url: remoteUrl } : init,\n );\n\n const doProbe = useAtomSet(probeMcpEndpoint, { mode: \"promiseExit\" });\n const doAddServer = useAtomSet(addMcpServer, { mode: \"promiseExit\" });\n\n const probe = \"probe\" in state ? state.probe : null;\n\n // The probe seeds the method list: detected OAuth → an OAuth row; a 401\n // without OAuth metadata → a bearer-header row; an open server → a no-auth\n // row. The user can edit any row or add alternate methods alongside.\n const authMethodSeeds: readonly AuthMethodSeed[] = useMemo(() => {\n if (!probe) return [];\n if (probe.requiresOAuth) {\n return [\n {\n value: { kind: \"oauth\", authorizationUrl: \"\", tokenUrl: \"\", scopes: [] },\n label: \"Detected\",\n },\n ];\n }\n if (probe.requiresAuthentication) {\n return [\n {\n value: {\n kind: \"apikey\",\n placements: [{ carrier: \"header\", name: \"Authorization\", prefix: \"Bearer \" }],\n },\n label: \"Detected\",\n },\n ];\n }\n return [{ value: { kind: \"none\" }, label: \"Detected\" }];\n }, [probe]);\n const authMethodList = useAuthMethodList(authMethodSeeds);\n\n const remoteIdentity = useIntegrationIdentity({\n fallbackName:\n integrationDisplayNameFromUrl(state.url, \"MCP\") ?? probe?.serverName ?? probe?.name ?? \"\",\n });\n // Agent-visible description: prefilled from the server's `instructions`\n // until the user types (null = untouched, keep deriving from the probe).\n const [descriptionDraft, setDescriptionDraft] = useState<string | null>(null);\n const resolvedDescription = descriptionDraft ?? probe?.instructions ?? \"\";\n const isProbing = state.step === \"probing\";\n const isAdding = state.step === \"adding\";\n\n // Pre-empt the API's `IntegrationAlreadyExistsError`: adding an integration\n // whose slug already exists clobbers the existing one's connections/policies,\n // so the API blocks it. Surface that here from the tenant-scoped catalog list.\n // A blank derived namespace lets the server assign the slug, so only flag a\n // collision when the user-derived slug is non-empty.\n const remoteSlug = slugifyNamespace(remoteIdentity.namespace);\n const stdioSlug = slugifyNamespace(stdioIdentity.namespace);\n const remoteSlugExists = useSlugAlreadyExists(remoteSlug);\n const stdioSlugExists = useSlugAlreadyExists(stdioSlug);\n\n const canAdd = Boolean(probe) && !isAdding && !remoteSlugExists;\n // Probe failures are shown inline on the URL field; other failures\n // (add server) render in the bottom error block.\n const probeError = state.step === \"error\" && state.probe === null ? state.error : null;\n const otherError = state.step === \"error\" && state.probe !== null ? state.error : null;\n\n // ---- Remote actions ----\n\n const handleProbe = useCallback(async () => {\n dispatch({ type: \"probe-start\" });\n const exit = await doProbe({\n payload: { endpoint: state.url.trim() },\n });\n if (Exit.isFailure(exit)) {\n dispatch({\n type: \"probe-fail\",\n error: errorMessageFromExit(exit, \"Failed to connect\"),\n });\n return;\n }\n dispatch({ type: \"probe-ok\", probe: exit.value });\n }, [state.url, doProbe]);\n\n // Keep the latest handleProbe in a ref so the debounced effect can call it\n // without depending on its identity (which changes every render).\n const handleProbeRef = useRef(handleProbe);\n handleProbeRef.current = handleProbe;\n\n // Auto-probe whenever the URL changes (debounced) while we're on the\n // remote transport and not already probing/probed.\n useEffect(() => {\n if (transport !== \"remote\") return;\n if (state.step !== \"url\") return;\n const trimmed = state.url.trim();\n if (!trimmed) return;\n const handle = setTimeout(() => {\n handleProbeRef.current();\n }, 400);\n return () => clearTimeout(handle);\n }, [transport, state.step, state.url]);\n\n // Register the integration with the declared auth methods, returning the\n // assigned slug (or null on failure — an error is dispatched in that case).\n const registerIntegration = useCallback(\n async (authenticationTemplate: readonly McpAuthMethodInput[]): Promise<string | null> => {\n const displayName = remoteIdentity.name.trim() || probe?.serverName || probe?.name || \"MCP\";\n const slug = slugifyNamespace(remoteIdentity.namespace) || undefined;\n const exit = await doAddServer({\n payload: {\n transport: \"remote\" as const,\n name: displayName,\n ...(resolvedDescription.trim().length > 0\n ? { description: resolvedDescription.trim() }\n : {}),\n endpoint: state.url.trim(),\n ...(slug ? { slug } : {}),\n authenticationTemplate,\n },\n reactivityKeys: integrationWriteKeys,\n });\n if (Exit.isFailure(exit)) {\n dispatch({\n type: \"add-fail\",\n error: addIntegrationErrorMessage(exit, slug ?? displayName, \"Failed to add server\"),\n });\n return null;\n }\n return exit.value.slug;\n },\n [doAddServer, probe, remoteIdentity, resolvedDescription, state.url],\n );\n\n const handleAddRemote = useCallback(async () => {\n if (!probe) return;\n dispatch({ type: \"add-start\" });\n // Every row registers as a declared method (a lone no-auth row registers\n // the open-server method). Slugs are assigned server-side by kind.\n const methods = authMethodList.rows.map((row: AuthMethodRow) =>\n mcpWireAuthInput(mcpAuthMethodInputFromEditorValue(row.value)),\n );\n const slug = await registerIntegration(\n methods.length > 0 ? methods : [{ kind: \"none\" as const }],\n );\n if (slug === null) return;\n props.onComplete(slug);\n }, [probe, authMethodList.rows, registerIntegration, props]);\n\n // ---- Stdio actions ----\n\n const parseStdioArgs = (raw: string): string[] => {\n if (!raw.trim()) return [];\n const args: string[] = [];\n const regex = /[^\\s\"]+|\"([^\"]*)\"/g;\n let match;\n while ((match = regex.exec(raw)) !== null) {\n args.push(match[1] ?? match[0]);\n }\n return args;\n };\n\n const parseStdioEnvValue = (raw: string): string => {\n const value = raw.trim();\n if (value.length < 2) return value;\n\n const quote = value[0];\n if ((quote !== '\"' && quote !== \"'\") || value[value.length - 1] !== quote) {\n return value;\n }\n\n const inner = value.slice(1, -1);\n if (quote === \"'\") return inner;\n\n return inner.replace(\n /\\\\([\\\\nrt\"])/g,\n (_, escaped: string) => STDIO_ENV_ESCAPE_REPLACEMENTS[escaped] ?? escaped,\n );\n };\n\n const parseStdioEnv = (raw: string): Record<string, string> | undefined => {\n if (!raw.trim()) return undefined;\n const env: Record<string, string> = {};\n for (const line of raw.split(\"\\n\")) {\n const eq = line.indexOf(\"=\");\n if (eq > 0) {\n env[line.slice(0, eq).trim()] = parseStdioEnvValue(line.slice(eq + 1));\n }\n }\n return Object.keys(env).length > 0 ? env : undefined;\n };\n\n const handleAddStdio = useCallback(async () => {\n const cmd = stdioCommand.trim();\n if (!cmd) return;\n setStdioAdding(true);\n setStdioError(null);\n const displayName = stdioIdentity.name.trim() || cmd;\n const slug = slugifyNamespace(stdioIdentity.namespace) || undefined;\n const exit = await doAddServer({\n payload: {\n transport: \"stdio\" as const,\n name: displayName,\n ...(slug ? { slug } : {}),\n command: cmd,\n args: parseStdioArgs(stdioArgs),\n env: parseStdioEnv(stdioEnv),\n },\n reactivityKeys: integrationWriteKeys,\n });\n if (Exit.isFailure(exit)) {\n setStdioError(addIntegrationErrorMessage(exit, slug ?? displayName, \"Failed to add server\"));\n setStdioAdding(false);\n return;\n }\n props.onComplete(exit.value.slug);\n }, [stdioCommand, stdioArgs, stdioEnv, stdioIdentity, doAddServer, props]);\n\n // ---- Render ----\n\n return (\n <div className=\"flex flex-1 flex-col gap-6\">\n <div>\n <h1 className=\"text-xl font-semibold text-foreground\">Add MCP Source</h1>\n <p className=\"mt-1 text-[13px] text-muted-foreground\">\n Connect to an MCP server to discover and use its tools.\n </p>\n </div>\n\n {/* Transport toggle — only shown when stdio is enabled server-side */}\n {allowStdio && (\n <div className=\"flex gap-1 rounded-lg border border-border bg-muted/30 p-1\">\n <Button\n variant=\"ghost\"\n type=\"button\"\n onClick={() => setTransport(\"remote\")}\n className={`flex-1 rounded-md px-3 py-1.5 text-sm font-medium transition-colors ${\n transport === \"remote\"\n ? \"bg-background text-foreground shadow-sm\"\n : \"text-muted-foreground hover:text-foreground\"\n }`}\n >\n Remote\n </Button>\n <Button\n variant=\"ghost\"\n type=\"button\"\n onClick={() => setTransport(\"stdio\")}\n className={`flex-1 rounded-md px-3 py-1.5 text-sm font-medium transition-colors ${\n transport === \"stdio\"\n ? \"bg-background text-foreground shadow-sm\"\n : \"text-muted-foreground hover:text-foreground\"\n }`}\n >\n Stdio\n </Button>\n </div>\n )}\n\n {transport === \"remote\" ? (\n <>\n <McpRemoteSourceFields\n url={state.url}\n onUrlChange={(url) => dispatch({ type: \"set-url\", url })}\n identity={remoteIdentity}\n description={resolvedDescription}\n onDescriptionChange={setDescriptionDraft}\n preview={probe}\n probing={isProbing}\n error={probeError}\n onRetry={handleProbe}\n />\n\n {/* Authentication — declares the auth methods to register through the\n shared list editor. The credentials themselves (API key value /\n OAuth sign-in) are added from the integration's detail hub after\n adding. */}\n {probe && (\n <AuthMethodListEditor\n list={authMethodList}\n title=\"How does this server authenticate?\"\n oauthMetadata=\"discovered\"\n emptyHint=\"No methods declared. Add a method, or add the server without auth and connect from the integration page later.\"\n footerHint=\"Every method here is registered with the server. Connect an account from the integration page after adding.\"\n />\n )}\n\n {/* Error (add server). Probe errors show inline on the field. */}\n {otherError && (\n <div className=\"space-y-2\">\n <FormErrorAlert message={otherError} />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => dispatch({ type: \"retry\" })}\n className=\"text-xs\"\n >\n Try again\n </Button>\n </div>\n )}\n\n {remoteSlugExists && !isAdding && <SlugCollisionAlert slug={remoteSlug} />}\n\n <FloatActions>\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={() => props.onCancel()}\n disabled={isAdding}\n >\n Cancel\n </Button>\n {(probe || isProbing) && (\n <Button type=\"button\" onClick={handleAddRemote} disabled={!canAdd}>\n {isAdding ? (\n <>\n <Spinner className=\"size-3.5\" /> Adding…\n </>\n ) : (\n \"Add source\"\n )}\n </Button>\n )}\n </FloatActions>\n </>\n ) : (\n <>\n {/* Stdio form */}\n <CardStack>\n <CardStackContent className=\"border-t-0\">\n <CardStackEntryField\n label=\"Command\"\n description=\"- The executable to run (e.g. npx, uvx, node).\"\n >\n <Input\n value={stdioCommand}\n onChange={(e) => setStdioCommand((e.target as HTMLInputElement).value)}\n placeholder=\"npx\"\n className=\"font-mono text-sm\"\n />\n </CardStackEntryField>\n\n <CardStackEntryField\n label=\"Arguments\"\n description=\"- Space-separated arguments passed to the command.\"\n >\n <Input\n value={stdioArgs}\n onChange={(e) => setStdioArgs((e.target as HTMLInputElement).value)}\n placeholder=\"-y chrome-devtools-mcp@latest\"\n className=\"font-mono text-sm\"\n />\n </CardStackEntryField>\n\n <CardStackEntryField\n label=\"Environment variables\"\n description=\"- One per line, KEY=value format.\"\n >\n <Textarea\n value={stdioEnv}\n onChange={(e) => setStdioEnv((e.target as HTMLTextAreaElement).value)}\n placeholder={\"KEY=value\\nANOTHER=value\"}\n rows={3}\n maxRows={10}\n className=\"font-mono text-sm\"\n />\n </CardStackEntryField>\n </CardStackContent>\n </CardStack>\n\n <IntegrationIdentityFields identity={stdioIdentity} namePlaceholder=\"My MCP Server\" />\n\n {/* Stdio error */}\n {stdioError && <FormErrorAlert message={stdioError} />}\n\n {stdioSlugExists && !stdioAdding && <SlugCollisionAlert slug={stdioSlug} />}\n\n <FloatActions>\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={() => props.onCancel()}\n disabled={stdioAdding}\n >\n Cancel\n </Button>\n <Button\n type=\"button\"\n onClick={handleAddStdio}\n disabled={!stdioCommand.trim() || stdioAdding || stdioSlugExists}\n >\n {stdioAdding ? (\n <>\n <Spinner className=\"size-3.5\" /> Adding…\n </>\n ) : (\n \"Add source\"\n )}\n </Button>\n </FloatActions>\n </>\n )}\n </div>\n );\n}\n","import { Badge } from \"@executor-js/react/components/badge\";\nimport {\n CardStack,\n CardStackContent,\n CardStackEntry,\n CardStackEntryActions,\n CardStackEntryContent,\n CardStackEntryDescription,\n CardStackEntryField,\n CardStackEntryMedia,\n CardStackEntryTitle,\n} from \"@executor-js/react/components/card-stack\";\nimport { FieldError } from \"@executor-js/react/components/field\";\nimport { Input } from \"@executor-js/react/components/input\";\nimport { Textarea } from \"@executor-js/react/components/textarea\";\nimport { Skeleton } from \"@executor-js/react/components/skeleton\";\nimport { IntegrationFavicon } from \"@executor-js/react/components/integration-favicon\";\nimport { IOSSpinner } from \"@executor-js/react/components/spinner\";\nimport { Button } from \"@executor-js/react/components/button\";\nimport {\n IntegrationIdentityFieldRows,\n type IntegrationIdentity,\n} from \"@executor-js/react/plugins/integration-identity\";\n\nexport type McpRemoteSourcePreview = {\n readonly name: string;\n readonly serverName: string | null;\n readonly connected: boolean;\n readonly requiresAuthentication: boolean;\n readonly requiresOAuth: boolean;\n readonly toolCount: number | null;\n};\n\nexport function McpRemoteSourceFields(props: {\n readonly url: string;\n readonly onUrlChange: (url: string) => void;\n readonly identity: IntegrationIdentity;\n /** The integration's agent-visible description (prefilled from the server's\n * `instructions` when the probe connected). */\n readonly description?: string;\n readonly onDescriptionChange?: (value: string) => void;\n readonly preview: McpRemoteSourcePreview | null;\n readonly probing?: boolean;\n readonly error?: string | null;\n readonly onRetry?: () => void;\n readonly namespaceReadOnly?: boolean;\n readonly urlDisabled?: boolean;\n}) {\n const previewDescription = props.preview\n ? props.preview.connected\n ? props.preview.toolCount === null\n ? null\n : `${props.preview.toolCount} tool${props.preview.toolCount !== 1 ? \"s\" : \"\"} available`\n : props.preview.requiresOAuth\n ? \"OAuth required to discover tools\"\n : props.preview.requiresAuthentication\n ? \"Authentication required to discover tools\"\n : \"Ready to add\"\n : null;\n\n if (props.preview) {\n return (\n <CardStack>\n <CardStackContent className=\"border-t-0\">\n <CardStackEntry>\n <CardStackEntryMedia>\n <IntegrationFavicon url={props.url} size={32} />\n </CardStackEntryMedia>\n <CardStackEntryContent>\n <CardStackEntryTitle>\n {props.preview.serverName ?? props.preview.name}\n </CardStackEntryTitle>\n {previewDescription ? (\n <CardStackEntryDescription>{previewDescription}</CardStackEntryDescription>\n ) : null}\n </CardStackEntryContent>\n <CardStackEntryActions>\n {props.preview.connected ? (\n <Badge\n variant=\"outline\"\n className=\"border-border bg-muted text-[10px] text-foreground\"\n >\n Connected\n </Badge>\n ) : props.preview.requiresOAuth ? (\n <Badge\n variant=\"outline\"\n className=\"border-border bg-muted text-[10px] text-muted-foreground\"\n >\n OAuth required\n </Badge>\n ) : (\n <Badge\n variant=\"outline\"\n className=\"border-border bg-muted text-[10px] text-muted-foreground\"\n >\n Auth required\n </Badge>\n )}\n </CardStackEntryActions>\n </CardStackEntry>\n <IntegrationIdentityFieldRows\n identity={props.identity}\n namePlaceholder=\"e.g. Linear\"\n namespaceReadOnly={props.namespaceReadOnly}\n />\n {props.onDescriptionChange && (\n <CardStackEntryField label=\"Description\">\n <Textarea\n value={props.description ?? \"\"}\n onChange={(e) =>\n props.onDescriptionChange?.((e.target as HTMLTextAreaElement).value)\n }\n placeholder=\"What this server offers and when to reach for it\"\n rows={2}\n maxRows={6}\n className=\"text-sm\"\n />\n <p className=\"text-[11px] text-muted-foreground\">\n Agent-visible. Prefilled from the server's instructions when it sends any.\n </p>\n </CardStackEntryField>\n )}\n <CardStackEntryField label=\"Server URL\">\n <Input\n value={props.url}\n onChange={(e) => props.onUrlChange((e.target as HTMLInputElement).value)}\n placeholder=\"https://mcp.example.com\"\n className=\"w-full font-mono text-sm\"\n disabled={props.urlDisabled}\n />\n </CardStackEntryField>\n </CardStackContent>\n </CardStack>\n );\n }\n\n if (props.probing) {\n return (\n <CardStack>\n <CardStackContent className=\"border-t-0\">\n <CardStackEntry>\n <CardStackEntryMedia>\n <Skeleton className=\"size-4 rounded\" />\n </CardStackEntryMedia>\n <CardStackEntryContent>\n <Skeleton className=\"h-4 w-40\" />\n <Skeleton className=\"mt-1 h-3 w-32\" />\n </CardStackEntryContent>\n <CardStackEntryActions>\n <Skeleton className=\"h-4 w-20 rounded-full\" />\n </CardStackEntryActions>\n </CardStackEntry>\n </CardStackContent>\n </CardStack>\n );\n }\n\n return (\n <CardStack>\n <CardStackContent className=\"border-t-0\">\n <CardStackEntryField label=\"Server URL\">\n <div className=\"relative\">\n <Input\n value={props.url}\n onChange={(e) => props.onUrlChange((e.target as HTMLInputElement).value)}\n placeholder=\"https://mcp.example.com\"\n className=\"w-full pr-9 font-mono text-sm\"\n aria-invalid={props.error ? true : undefined}\n disabled={props.urlDisabled}\n />\n {props.probing && (\n <div className=\"pointer-events-none absolute right-2 top-1/2 -translate-y-1/2\">\n <IOSSpinner className=\"size-4\" />\n </div>\n )}\n </div>\n {props.error && (\n <div className=\"mt-2 space-y-2\">\n <FieldError>{props.error}</FieldError>\n {props.onRetry && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={props.onRetry}\n className=\"h-7 px-2 text-xs\"\n >\n Try again\n </Button>\n )}\n </div>\n )}\n </CardStackEntryField>\n </CardStackContent>\n </CardStack>\n );\n}\n"],"mappings":"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","names":["Button","CardStack","CardStackContent","CardStackEntryField","Input","Textarea","jsx","jsxs","value","Button","CardStack","CardStackContent","CardStackEntryField","Input","Textarea"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react/McpAccountsPanel.tsx"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport { useAtomSet, useAtomValue } from \"@effect/atom-react\";\nimport * as AsyncResult from \"effect/unstable/reactivity/AsyncResult\";\nimport * as Exit from \"effect/Exit\";\n\nimport { IntegrationSlug } from \"@executor-js/sdk/shared\";\nimport type { IntegrationAccountHandoff } from \"@executor-js/sdk/client\";\nimport { AccountsSection } from \"@executor-js/react/components/accounts-section\";\nimport type { AuthMethod, Placement } from \"@executor-js/react/lib/auth-placements\";\nimport {\n useCustomMethodActions,\n type AuthMethodsCodec,\n type ConfigureAuthMethods,\n} from \"@executor-js/react/lib/custom-auth-methods\";\nimport { integrationWriteKeys } from \"@executor-js/react/api/reactivity-keys\";\n\nimport { configureMcpAuth, mcpServerAtom } from \"./atoms\";\nimport {\n authMethodsFromConfig,\n mcpAuthMethodInputsFromPlacements,\n mcpWireAuthInput,\n} from \"./auth-method-config\";\nimport type { McpAuthMethod } from \"../sdk/types\";\n\n// ---------------------------------------------------------------------------\n// MCP Accounts hub — fills the generic detail page's `accounts` slot.\n//\n// Reads the integration's declared `authenticationTemplate` (via `getServer`),\n// converts it to generic `AuthMethod[]`, and composes the generic\n// `AccountsSection` — whose Add-account offers those methods plus a \"+ Custom\n// method\" row. The custom-method create/remove is the shared skeleton\n// (`useCustomMethodActions`) parameterized by the MCP codec and the\n// merge-append `configureAuth` endpoint, so adding an API key method never\n// displaces a declared OAuth method. Stdio servers have no remote credential\n// to configure — no methods, no custom-method affordance.\n// ---------------------------------------------------------------------------\n\nexport default function McpAccountsPanel(props: {\n readonly sourceId: string;\n readonly integrationName: string;\n readonly accountHandoff?: IntegrationAccountHandoff | null;\n}) {\n const { sourceId, integrationName, accountHandoff } = props;\n const slug = IntegrationSlug.make(sourceId);\n const serverResult = useAtomValue(mcpServerAtom(slug));\n const doConfigureAuth = useAtomSet(configureMcpAuth, { mode: \"promiseExit\" });\n\n const server = AsyncResult.isSuccess(serverResult) ? serverResult.value : null;\n const config = server?.config ?? null;\n const remote = config !== null && config.transport === \"remote\" ? config : null;\n\n const existingTemplate = useMemo<readonly McpAuthMethod[]>(\n () => remote?.authenticationTemplate ?? [],\n [remote],\n );\n\n const methods = useMemo<readonly AuthMethod[]>(\n () => (remote ? authMethodsFromConfig(existingTemplate, remote.endpoint) : []),\n [existingTemplate, remote],\n );\n\n const configure = useCallback<ConfigureAuthMethods<McpAuthMethod>>(\n async (input) => {\n const exit = await doConfigureAuth({\n params: { slug },\n payload: {\n authenticationTemplate: input.authenticationTemplate.map(mcpWireAuthInput),\n ...(input.mode ? { mode: input.mode } : {}),\n },\n reactivityKeys: integrationWriteKeys,\n });\n return Exit.map(exit, (result) => result.authenticationTemplate);\n },\n [doConfigureAuth, slug],\n );\n\n const codec = useMemo<AuthMethodsCodec<McpAuthMethod>>(\n () => ({\n toAuthMethods: (templates: readonly McpAuthMethod[]) =>\n authMethodsFromConfig(templates, remote?.endpoint ?? \"\"),\n // MCP custom methods are header credentials; the inputs omit slugs and\n // the backend merge backfills `custom_<id>`.\n templatesFromPlacements: (placements: readonly Placement[]) =>\n mcpAuthMethodInputsFromPlacements(placements) as readonly McpAuthMethod[],\n slugOf: (template: McpAuthMethod) => template.slug,\n }),\n [remote?.endpoint],\n );\n\n const { createCustomMethod, removeCustomMethod } = useCustomMethodActions({\n existing: existingTemplate,\n codec,\n configure,\n });\n\n const canConfigureAuth = remote !== null;\n\n return (\n <div className=\"mx-auto max-w-3xl space-y-8 px-6 py-8\">\n <AccountsSection\n integration={slug}\n integrationName={integrationName}\n methods={methods}\n accountHandoff={accountHandoff}\n createCustomMethod={canConfigureAuth ? createCustomMethod : undefined}\n removeCustomMethod={canConfigureAuth ? removeCustomMethod : undefined}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;AAAA,SAAS,aAAa,eAAe;AACrC,SAAS,YAAY,oBAAoB;AACzC,YAAY,iBAAiB;AAC7B,YAAY,UAAU;AAEtB,SAAS,uBAAuB;AAEhC,SAAS,uBAAuB;AAEhC;AAAA,EACE;AAAA,OAGK;AACP,SAAS,4BAA4B;AAqF/B;AA9DS,SAAR,iBAAkC,OAItC;AACD,QAAM,EAAE,UAAU,iBAAiB,eAAe,IAAI;AACtD,QAAM,OAAO,gBAAgB,KAAK,QAAQ;AAC1C,QAAM,eAAe,aAAa,cAAc,IAAI,CAAC;AACrD,QAAM,kBAAkB,WAAW,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAE5E,QAAM,SAAqB,sBAAU,YAAY,IAAI,aAAa,QAAQ;AAC1E,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,SAAS,WAAW,QAAQ,OAAO,cAAc,WAAW,SAAS;AAE3E,QAAM,mBAAmB;AAAA,IACvB,MAAM,QAAQ,0BAA0B,CAAC;AAAA,IACzC,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,UAAU;AAAA,IACd,MAAO,SAAS,sBAAsB,kBAAkB,OAAO,QAAQ,IAAI,CAAC;AAAA,IAC5E,CAAC,kBAAkB,MAAM;AAAA,EAC3B;AAEA,QAAM,YAAY;AAAA,IAChB,OAAO,UAAU;AACf,YAAM,OAAO,MAAM,gBAAgB;AAAA,QACjC,QAAQ,EAAE,KAAK;AAAA,QACf,SAAS;AAAA,UACP,wBAAwB,MAAM,uBAAuB,IAAI,gBAAgB;AAAA,UACzE,GAAI,MAAM,OAAO,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,QAC3C;AAAA,QACA,gBAAgB;AAAA,MAClB,CAAC;AACD,aAAY,SAAI,MAAM,CAAC,WAAW,OAAO,sBAAsB;AAAA,IACjE;AAAA,IACA,CAAC,iBAAiB,IAAI;AAAA,EACxB;AAEA,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL,eAAe,CAAC,cACd,sBAAsB,WAAW,QAAQ,YAAY,EAAE;AAAA;AAAA;AAAA,MAGzD,yBAAyB,CAAC,eACxB,kCAAkC,UAAU;AAAA,MAC9C,QAAQ,CAAC,aAA4B,SAAS;AAAA,IAChD;AAAA,IACA,CAAC,QAAQ,QAAQ;AAAA,EACnB;AAEA,QAAM,EAAE,oBAAoB,mBAAmB,IAAI,uBAAuB;AAAA,IACxE,UAAU;AAAA,IACV;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,mBAAmB,WAAW;AAEpC,SACE,oBAAC,SAAI,WAAU,yCACb;AAAA,IAAC;AAAA;AAAA,MACC,aAAa;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA,oBAAoB,mBAAmB,qBAAqB;AAAA,MAC5D,oBAAoB,mBAAmB,qBAAqB;AAAA;AAAA,EAC9D,GACF;AAEJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
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\nexport const McpAuthMethod = Schema.Union([NoneAuthMethod, ApiKeyAuthMethod, McpOAuthMethod]);\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 /** Environment variables */\n env: Schema.optional(StringMap),\n /** Working directory */\n cwd: Schema.optional(Schema.String),\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":";AAGA,SAAS,MAAM,cAAc;AAEtB,IAAM,qBAAN,cAAiC,OAAO,iBAAqC;AAAA,EAClF;AAAA,EACA;AAAA,IACE,WAAW,OAAO;AAAA,IAClB,SAAS,OAAO;AAAA,EAClB;AAAA,EACA,EAAE,eAAe,IAAI;AACvB,EAAE;AAAC;AAEI,IAAM,wBAAN,cAAoC,OAAO,iBAAwC;AAAA,EACxF;AAAA,EACA;AAAA,IACE,OAAO,OAAO,SAAS,CAAC,WAAW,YAAY,CAAC;AAAA,IAChD,SAAS,OAAO;AAAA,EAClB;AAAA,EACA,EAAE,eAAe,IAAI;AACvB,EAAE;AAAC;AAKI,IAAM,qBAAN,cAAiC,KAAK,YAAY,oBAAoB,EAI1E;AAAC;AAEG,IAAM,kCAAN,cAA8C,KAAK;AAAA,EACxD;AACF,EAEG;AAAC;AAEG,IAAM,gBAAN,cAA4B,OAAO,iBAAgC;AAAA,EACxE;AAAA,EACA;AAAA,IACE,SAAS,OAAO;AAAA,EAClB;AAAA,EACA,EAAE,eAAe,IAAI;AACvB,EAAE;AAAC;;;AC5CH,SAAS,QAAQ,QAAQ,UAAAA,eAAc;AACvC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAkBA,IAAM,qBAAqBA,QAAO,SAAS,CAAC,mBAAmB,OAAO,MAAM,CAAC;AAI7E,IAAM,eAAeA,QAAO,SAAS,CAAC,mBAAmB,OAAO,SAAS,MAAM,CAAC;AAoBhF,IAAM,iBAAiBA,QAAO,OAAO;AAAA,EAC1C,MAAMA,QAAO;AAAA,EACb,MAAMA,QAAO,QAAQ,QAAQ;AAC/B,CAAC;AAGM,IAAM,gBAAgBA,QAAO,MAAM,CAAC,gBAAgB,kBAAkB,cAAc,CAAC;AAMrF,IAAM,mBAAmBA,QAAO,MAAM;AAAA,EAC3CA,QAAO,OAAO,EAAE,MAAMA,QAAO,QAAQ,MAAM,EAAE,CAAC;AAAA,EAC9CA,QAAO,OAAO;AAAA,IACZ,MAAMA,QAAO,QAAQ,QAAQ;AAAA,IAC7B,YAAYA,QAAO;AAAA,IACnB,QAAQA,QAAO,SAASA,QAAO,MAAM;AAAA,EACvC,CAAC;AAAA,EACDA,QAAO,OAAO,EAAE,MAAMA,QAAO,QAAQ,QAAQ,EAAE,CAAC;AAClD,CAAC;AAMM,IAAM,6BAA6B,CAAC,SAA0C;AACnF,MAAI,KAAK,SAAS,UAAU;AAC1B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YAAY;AAAA,QACV;AAAA,UACE,SAAS;AAAA,UACT,MAAM,KAAK;AAAA,UACX,GAAI,KAAK,WAAW,SAAY,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,QAC7D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,MAAM,KAAK,MAAM,MAAM,KAAK,KAAK;AAC5C;AAIO,IAAM,qBAAqBA,QAAO,MAAM;AAAA,EAC7CA,QAAO,OAAO,EAAE,MAAMA,QAAO,SAASA,QAAO,MAAM,GAAG,MAAMA,QAAO,QAAQ,MAAM,EAAE,CAAC;AAAA,EACpFA,QAAO,OAAO,EAAE,MAAMA,QAAO,SAASA,QAAO,MAAM,GAAG,MAAMA,QAAO,QAAQ,QAAQ,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMtF;AACF,CAAC;AAaD,IAAM,qBAAqB,CAAC,WAAgD;AAC1E,MAAI,OAAO,SAAS,SAAU,QAAO,OAAO;AAC5C,MAAI,OAAO,WAAW,WAAW,GAAG;AAClC,WAAO,OAAO,WAAW,CAAC,EAAG,YAAY,WAAW,WAAW;AAAA,EACjE;AACA,SAAO;AACT;AAMO,IAAM,4BAA4B,CACvC,YAEA,QAAQ;AAAA,EACN,CAAC,WACC,qBAAqB,MAAM,IACtB,6BAA6B,MAAM,IACnC;AACT;AAKK,IAAM,0BAA0B,CACrC,YAEA;AAAA,EACE,0BAA0B,OAAO;AAAA,EACjC;AACF;AAOF,IAAM,YAAYA,QAAO,OAAOA,QAAO,QAAQA,QAAO,MAAM;AAErD,IAAM,6BAA6BA,QAAO,OAAO;AAAA,EACtD,WAAWA,QAAO,QAAQ,QAAQ;AAAA;AAAA,EAElC,UAAUA,QAAO;AAAA;AAAA,EAEjB,iBAAiB,mBAAmB;AAAA,IAClCA,QAAO;AAAA,IACPA,QAAO,uBAAuB,OAAO,QAAQ,MAAe,CAAC;AAAA,EAC/D;AAAA;AAAA,EAEA,aAAaA,QAAO,SAAS,SAAS;AAAA;AAAA,EAEtC,SAASA,QAAO,SAAS,SAAS;AAAA;AAAA;AAAA,EAGlC,wBAAwBA,QAAO,MAAM,aAAa;AACpD,CAAC;AAGM,IAAM,4BAA4BA,QAAO,OAAO;AAAA,EACrD,WAAWA,QAAO,QAAQ,OAAO;AAAA;AAAA,EAEjC,SAASA,QAAO;AAAA;AAAA,EAEhB,MAAMA,QAAO,SAASA,QAAO,MAAMA,QAAO,MAAM,CAAC;AAAA;AAAA,EAEjD,KAAKA,QAAO,SAAS,SAAS;AAAA;AAAA,EAE9B,KAAKA,QAAO,SAASA,QAAO,MAAM;AACpC,CAAC;AAGM,IAAM,uBAAuBA,QAAO,MAAM;AAAA,EAC/C;AAAA,EACA;AACF,CAAC;AAGD,IAAM,0BAA0BA,QAAO,oBAAoB,oBAAoB;AAMxE,IAAM,4BAA4B,CAAC,WACxC,OAAO,UAAU,wBAAwB,MAAM,CAAC;AAO3C,IAAM,qBAAqBA,QAAO,OAAO;AAAA,EAC9C,OAAOA,QAAO,SAASA,QAAO,MAAM;AAAA,EACpC,cAAcA,QAAO,SAASA,QAAO,OAAO;AAAA,EAC5C,iBAAiBA,QAAO,SAASA,QAAO,OAAO;AAAA,EAC/C,gBAAgBA,QAAO,SAASA,QAAO,OAAO;AAAA,EAC9C,eAAeA,QAAO,SAASA,QAAO,OAAO;AAC/C,CAAC;AASM,IAAM,iBAAiBA,QAAO,OAAO;AAAA;AAAA,EAE1C,QAAQA,QAAO;AAAA;AAAA,EAEf,UAAUA,QAAO;AAAA,EACjB,aAAaA,QAAO,OAAOA,QAAO,MAAM;AAAA,EACxC,aAAaA,QAAO,SAASA,QAAO,OAAO;AAAA,EAC3C,cAAcA,QAAO,SAASA,QAAO,OAAO;AAAA,EAC5C,aAAaA,QAAO,SAAS,kBAAkB;AACjD,CAAC;","names":["Schema"]}
|