@executor-js/plugin-mcp 0.0.1-beta.6 → 0.0.1

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.
@@ -1,5 +1,5 @@
1
1
  // src/sdk/binding-store.ts
2
- import { Effect, Schema as Schema2 } from "effect";
2
+ import { Effect as Effect2, Schema as Schema5 } from "effect";
3
3
  import { makeInMemoryScopedKv, scopeKv } from "@executor-js/sdk";
4
4
 
5
5
  // src/sdk/types.ts
@@ -58,191 +58,58 @@ var McpToolBinding = class extends Schema.Class("McpToolBinding")({
58
58
  }) {
59
59
  };
60
60
 
61
- // src/sdk/binding-store.ts
62
- var StoredBindingEntry = Schema2.Struct({
63
- namespace: Schema2.String,
64
- binding: McpToolBinding,
65
- sourceData: Schema2.Unknown
66
- });
67
- var encodeBindingEntry = Schema2.encodeSync(Schema2.parseJson(StoredBindingEntry));
68
- var decodeBindingEntry = Schema2.decodeUnknownSync(Schema2.parseJson(StoredBindingEntry));
69
- var makeStore = (bindings, sources) => ({
70
- // ---- Bindings ----
71
- get: (toolId) => Effect.gen(function* () {
72
- const raw = yield* bindings.get(toolId);
73
- if (!raw) return null;
74
- const entry = decodeBindingEntry(raw);
75
- return {
76
- binding: entry.binding,
77
- sourceData: entry.sourceData
78
- };
79
- }),
80
- put: (toolId, namespace, binding, sourceData) => bindings.set([{ key: toolId, value: encodeBindingEntry({ namespace, binding, sourceData }) }]),
81
- remove: (toolId) => bindings.delete([toolId]).pipe(Effect.asVoid),
82
- listByNamespace: (namespace) => Effect.gen(function* () {
83
- const entries = yield* bindings.list();
84
- const ids = [];
85
- for (const e of entries) {
86
- const entry = decodeBindingEntry(e.value);
87
- if (entry.namespace === namespace) ids.push(e.key);
88
- }
89
- return ids;
90
- }),
91
- removeByNamespace: (namespace) => Effect.gen(function* () {
92
- const entries = yield* bindings.list();
93
- const ids = [];
94
- for (const e of entries) {
95
- const entry = decodeBindingEntry(e.value);
96
- if (entry.namespace === namespace) ids.push(e.key);
97
- }
98
- if (ids.length > 0) yield* bindings.delete(ids);
99
- return ids;
100
- }),
101
- // ---- Sources (meta + config combined) ----
102
- putSource: (source) => sources.set([{ key: source.namespace, value: JSON.stringify(source) }]),
103
- removeSource: (namespace) => sources.delete([namespace]).pipe(Effect.asVoid),
104
- listSources: () => Effect.gen(function* () {
105
- const entries = yield* sources.list();
106
- return entries.map((e) => JSON.parse(e.value));
107
- }),
108
- getSource: (namespace) => Effect.gen(function* () {
109
- const raw = yield* sources.get(namespace);
110
- if (!raw) return null;
111
- return JSON.parse(raw);
112
- }),
113
- getSourceConfig: (namespace) => Effect.gen(function* () {
114
- const raw = yield* sources.get(namespace);
115
- if (!raw) return null;
116
- const source = JSON.parse(raw);
117
- return source.config;
118
- })
119
- });
120
- var makeKvBindingStore = (kv, namespace) => makeStore(scopeKv(kv, `${namespace}.bindings`), scopeKv(kv, `${namespace}.sources`));
121
- var makeInMemoryBindingStore = () => makeStore(makeInMemoryScopedKv(), makeInMemoryScopedKv());
122
-
123
- // src/sdk/plugin.ts
124
- import { Effect as Effect6, Exit, ScopedCache, Duration, Scope } from "effect";
61
+ // src/sdk/oauth.ts
125
62
  import {
126
- Source,
127
- SourceDetectionResult,
128
- definePlugin,
129
- ToolId,
130
- SecretId
131
- } from "@executor-js/sdk";
132
-
133
- // src/sdk/connection.ts
134
- import { Client } from "@modelcontextprotocol/sdk/client/index.js";
135
- import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
136
- import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
137
- import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
138
- import { Effect as Effect2 } from "effect";
63
+ auth
64
+ } from "@modelcontextprotocol/sdk/client/auth.js";
65
+ import { Effect, Schema as Schema3 } from "effect";
139
66
 
140
67
  // src/sdk/errors.ts
141
- import { Schema as Schema3 } from "effect";
142
- var McpConnectionError = class extends Schema3.TaggedError()(
68
+ import { Schema as Schema2 } from "effect";
69
+ var McpConnectionError = class extends Schema2.TaggedError()(
143
70
  "McpConnectionError",
144
71
  {
145
- transport: Schema3.String,
146
- message: Schema3.String
72
+ transport: Schema2.String,
73
+ message: Schema2.String
147
74
  }
148
75
  ) {
149
76
  };
150
- var McpToolDiscoveryError = class extends Schema3.TaggedError()(
77
+ var McpToolDiscoveryError = class extends Schema2.TaggedError()(
151
78
  "McpToolDiscoveryError",
152
79
  {
153
- stage: Schema3.Literal("connect", "list_tools"),
154
- message: Schema3.String
80
+ stage: Schema2.Literal("connect", "list_tools"),
81
+ message: Schema2.String
155
82
  }
156
83
  ) {
157
84
  };
158
- var McpInvocationError = class extends Schema3.TaggedError()(
85
+ var McpInvocationError = class extends Schema2.TaggedError()(
159
86
  "McpInvocationError",
160
87
  {
161
- toolName: Schema3.String,
162
- message: Schema3.String
88
+ toolName: Schema2.String,
89
+ message: Schema2.String
163
90
  }
164
91
  ) {
165
92
  };
166
- var McpOAuthError = class extends Schema3.TaggedError()("McpOAuthError", {
167
- message: Schema3.String
93
+ var McpOAuthError = class extends Schema2.TaggedError()("McpOAuthError", {
94
+ message: Schema2.String
168
95
  }) {
169
96
  };
170
97
 
171
- // src/sdk/connection.ts
172
- var buildEndpointUrl = (endpoint, queryParams) => {
173
- const url = new URL(endpoint);
174
- for (const [key, value] of Object.entries(queryParams)) {
175
- url.searchParams.set(key, value);
176
- }
177
- return url;
178
- };
179
- var createClient = () => new Client(
180
- { name: "executor-mcp", version: "0.1.0" },
181
- { capabilities: { elicitation: { form: {}, url: {} } } }
182
- );
183
- var connectionFromClient = (client) => ({
184
- client,
185
- close: () => client.close()
98
+ // src/sdk/oauth.ts
99
+ var JsonObject = Schema3.Record({ key: Schema3.String, value: Schema3.Unknown });
100
+ var McpOAuthDiscoveryState = Schema3.Struct({
101
+ resourceMetadataUrl: Schema3.NullOr(Schema3.String),
102
+ authorizationServerUrl: Schema3.NullOr(Schema3.String),
103
+ resourceMetadata: Schema3.NullOr(JsonObject),
104
+ authorizationServerMetadata: Schema3.NullOr(JsonObject),
105
+ clientInformation: Schema3.NullOr(JsonObject)
186
106
  });
187
- var connectClient = (input) => Effect2.gen(function* () {
188
- const client = createClient();
189
- const transportInstance = input.createTransport();
190
- yield* Effect2.tryPromise({
191
- try: () => client.connect(transportInstance),
192
- catch: (cause) => new McpConnectionError({
193
- transport: input.transport,
194
- message: `Failed connecting via ${input.transport}: ${cause instanceof Error ? cause.message : String(cause)}`
195
- })
196
- });
197
- return connectionFromClient(client);
107
+ var McpOAuthSession = Schema3.Struct({
108
+ ...McpOAuthDiscoveryState.fields,
109
+ endpoint: Schema3.String,
110
+ redirectUrl: Schema3.String,
111
+ codeVerifier: Schema3.String
198
112
  });
199
- var createMcpConnector = (input) => {
200
- if (input.transport === "stdio") {
201
- const command = input.command.trim();
202
- if (!command) {
203
- return new McpConnectionError({
204
- transport: "stdio",
205
- message: "MCP stdio transport requires a command"
206
- });
207
- }
208
- return connectClient({
209
- transport: "stdio",
210
- createTransport: () => new StdioClientTransport({
211
- command,
212
- args: input.args ? [...input.args] : void 0,
213
- env: input.env ? { ...process.env, ...input.env } : void 0,
214
- cwd: input.cwd?.trim().length ? input.cwd.trim() : void 0
215
- })
216
- });
217
- }
218
- const headers = input.headers ?? {};
219
- const remoteTransport = input.remoteTransport ?? "auto";
220
- const requestInit = Object.keys(headers).length > 0 ? { headers } : void 0;
221
- const endpoint = buildEndpointUrl(input.endpoint, input.queryParams ?? {});
222
- const connectStreamableHttp = connectClient({
223
- transport: "streamable-http",
224
- createTransport: () => new StreamableHTTPClientTransport(endpoint, {
225
- requestInit,
226
- authProvider: input.authProvider
227
- })
228
- });
229
- const connectSse = connectClient({
230
- transport: "sse",
231
- createTransport: () => new SSEClientTransport(endpoint, {
232
- requestInit,
233
- authProvider: input.authProvider
234
- })
235
- });
236
- if (remoteTransport === "streamable-http") return connectStreamableHttp;
237
- if (remoteTransport === "sse") return connectSse;
238
- return connectStreamableHttp.pipe(Effect2.catchAll(() => connectSse));
239
- };
240
-
241
- // src/sdk/oauth.ts
242
- import {
243
- auth
244
- } from "@modelcontextprotocol/sdk/client/auth.js";
245
- import { Effect as Effect3 } from "effect";
246
113
  var toJsonObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
247
114
  var CLIENT_METADATA = {
248
115
  grant_types: ["authorization_code", "refresh_token"],
@@ -257,13 +124,13 @@ var extractDiscoveryState = (discoveryState, clientInformation) => ({
257
124
  authorizationServerMetadata: toJsonObject(discoveryState?.authorizationServerMetadata),
258
125
  clientInformation: toJsonObject(clientInformation)
259
126
  });
260
- var callAuth = (provider, opts) => Effect3.tryPromise({
127
+ var callAuth = (provider, opts) => Effect.tryPromise({
261
128
  try: () => auth(provider, opts),
262
129
  catch: (cause) => new McpOAuthError({
263
130
  message: cause instanceof Error ? cause.message : String(cause)
264
131
  })
265
132
  });
266
- var startMcpOAuthAuthorization = (input) => Effect3.gen(function* () {
133
+ var startMcpOAuthAuthorization = (input) => Effect.gen(function* () {
267
134
  let authorizationUrl;
268
135
  let codeVerifier;
269
136
  let discoveryState;
@@ -309,7 +176,7 @@ var startMcpOAuthAuthorization = (input) => Effect3.gen(function* () {
309
176
  ...extractDiscoveryState(discoveryState, clientInformation)
310
177
  };
311
178
  });
312
- var exchangeMcpOAuthCode = (input) => Effect3.gen(function* () {
179
+ var exchangeMcpOAuthCode = (input) => Effect.gen(function* () {
313
180
  const { session } = input;
314
181
  let tokens;
315
182
  let discoveryState = {
@@ -359,27 +226,215 @@ var exchangeMcpOAuthCode = (input) => Effect3.gen(function* () {
359
226
  };
360
227
  });
361
228
 
229
+ // src/sdk/stored-source.ts
230
+ import { Schema as Schema4 } from "effect";
231
+ var McpStoredSourceSchema = class extends Schema4.Class("McpStoredSource")({
232
+ namespace: Schema4.String,
233
+ name: Schema4.String,
234
+ config: McpStoredSourceData
235
+ }) {
236
+ };
237
+
238
+ // src/sdk/binding-store.ts
239
+ var MCP_OAUTH_SESSION_TTL_MS = 15 * 60 * 1e3;
240
+ var StoredOAuthSession = Schema5.Struct({
241
+ session: McpOAuthSession,
242
+ expiresAt: Schema5.Number
243
+ });
244
+ var encodeOAuthSession = Schema5.encodeSync(Schema5.parseJson(StoredOAuthSession));
245
+ var decodeOAuthSession = Schema5.decodeUnknownSync(Schema5.parseJson(StoredOAuthSession));
246
+ var encodeSource = Schema5.encodeSync(Schema5.parseJson(McpStoredSourceSchema));
247
+ var decodeSource = Schema5.decodeUnknownSync(Schema5.parseJson(McpStoredSourceSchema));
248
+ var StoredBindingEntry = Schema5.Struct({
249
+ namespace: Schema5.String,
250
+ binding: McpToolBinding
251
+ });
252
+ var encodeBindingEntry = Schema5.encodeSync(Schema5.parseJson(StoredBindingEntry));
253
+ var decodeBindingEntry = Schema5.decodeUnknownSync(Schema5.parseJson(StoredBindingEntry));
254
+ var makeStore = (bindings, sources, oauthSessions) => ({
255
+ // ---- Bindings ----
256
+ get: (toolId) => Effect2.gen(function* () {
257
+ const raw = yield* bindings.get(toolId);
258
+ if (!raw) return null;
259
+ const entry = decodeBindingEntry(raw);
260
+ return {
261
+ binding: entry.binding,
262
+ namespace: entry.namespace
263
+ };
264
+ }),
265
+ put: (toolId, namespace, binding) => bindings.set([{ key: toolId, value: encodeBindingEntry({ namespace, binding }) }]),
266
+ remove: (toolId) => bindings.delete([toolId]).pipe(Effect2.asVoid),
267
+ listByNamespace: (namespace) => Effect2.gen(function* () {
268
+ const entries = yield* bindings.list();
269
+ const ids = [];
270
+ for (const e of entries) {
271
+ const entry = decodeBindingEntry(e.value);
272
+ if (entry.namespace === namespace) ids.push(e.key);
273
+ }
274
+ return ids;
275
+ }),
276
+ removeByNamespace: (namespace) => Effect2.gen(function* () {
277
+ const entries = yield* bindings.list();
278
+ const ids = [];
279
+ for (const e of entries) {
280
+ const entry = decodeBindingEntry(e.value);
281
+ if (entry.namespace === namespace) ids.push(e.key);
282
+ }
283
+ if (ids.length > 0) yield* bindings.delete(ids);
284
+ return ids;
285
+ }),
286
+ // ---- Sources (meta + config combined) ----
287
+ putSource: (source) => sources.set([{ key: source.namespace, value: encodeSource(source) }]),
288
+ removeSource: (namespace) => sources.delete([namespace]).pipe(Effect2.asVoid),
289
+ listSources: () => Effect2.gen(function* () {
290
+ const entries = yield* sources.list();
291
+ return entries.map((e) => decodeSource(e.value));
292
+ }),
293
+ getSource: (namespace) => Effect2.gen(function* () {
294
+ const raw = yield* sources.get(namespace);
295
+ if (!raw) return null;
296
+ return decodeSource(raw);
297
+ }),
298
+ getSourceConfig: (namespace) => Effect2.gen(function* () {
299
+ const raw = yield* sources.get(namespace);
300
+ if (!raw) return null;
301
+ return decodeSource(raw).config;
302
+ }),
303
+ // ---- Pending OAuth sessions (short-lived, between startOAuth and completeOAuth) ----
304
+ putOAuthSession: (sessionId, session) => oauthSessions.set([
305
+ {
306
+ key: sessionId,
307
+ value: encodeOAuthSession({
308
+ session,
309
+ expiresAt: Date.now() + MCP_OAUTH_SESSION_TTL_MS
310
+ })
311
+ }
312
+ ]),
313
+ getOAuthSession: (sessionId) => Effect2.gen(function* () {
314
+ const raw = yield* oauthSessions.get(sessionId);
315
+ if (!raw) return null;
316
+ const entry = decodeOAuthSession(raw);
317
+ if (entry.expiresAt < Date.now()) {
318
+ yield* oauthSessions.delete([sessionId]);
319
+ return null;
320
+ }
321
+ return entry.session;
322
+ }),
323
+ deleteOAuthSession: (sessionId) => oauthSessions.delete([sessionId]).pipe(Effect2.asVoid)
324
+ });
325
+ var makeKvBindingStore = (kv, namespace) => makeStore(
326
+ scopeKv(kv, `${namespace}.bindings`),
327
+ scopeKv(kv, `${namespace}.sources`),
328
+ scopeKv(kv, `${namespace}.oauth-sessions`)
329
+ );
330
+ var makeInMemoryBindingStore = () => makeStore(makeInMemoryScopedKv(), makeInMemoryScopedKv(), makeInMemoryScopedKv());
331
+
332
+ // src/sdk/plugin.ts
333
+ import { Effect as Effect6, Exit, ScopedCache, Duration, Scope } from "effect";
334
+ import {
335
+ Source,
336
+ SourceDetectionResult,
337
+ definePlugin,
338
+ ToolId,
339
+ SecretId
340
+ } from "@executor-js/sdk";
341
+
342
+ // src/sdk/connection.ts
343
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
344
+ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
345
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
346
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
347
+ import { Effect as Effect3 } from "effect";
348
+ var buildEndpointUrl = (endpoint, queryParams) => {
349
+ const url = new URL(endpoint);
350
+ for (const [key, value] of Object.entries(queryParams)) {
351
+ url.searchParams.set(key, value);
352
+ }
353
+ return url;
354
+ };
355
+ var createClient = () => new Client(
356
+ { name: "executor-mcp", version: "0.1.0" },
357
+ { capabilities: { elicitation: { form: {}, url: {} } } }
358
+ );
359
+ var connectionFromClient = (client) => ({
360
+ client,
361
+ close: () => client.close()
362
+ });
363
+ var connectClient = (input) => Effect3.gen(function* () {
364
+ const client = createClient();
365
+ const transportInstance = input.createTransport();
366
+ yield* Effect3.tryPromise({
367
+ try: () => client.connect(transportInstance),
368
+ catch: (cause) => new McpConnectionError({
369
+ transport: input.transport,
370
+ message: `Failed connecting via ${input.transport}: ${cause instanceof Error ? cause.message : String(cause)}`
371
+ })
372
+ });
373
+ return connectionFromClient(client);
374
+ });
375
+ var createMcpConnector = (input) => {
376
+ if (input.transport === "stdio") {
377
+ const command = input.command.trim();
378
+ if (!command) {
379
+ return new McpConnectionError({
380
+ transport: "stdio",
381
+ message: "MCP stdio transport requires a command"
382
+ });
383
+ }
384
+ return connectClient({
385
+ transport: "stdio",
386
+ createTransport: () => new StdioClientTransport({
387
+ command,
388
+ args: input.args ? [...input.args] : void 0,
389
+ env: input.env ? { ...process.env, ...input.env } : void 0,
390
+ cwd: input.cwd?.trim().length ? input.cwd.trim() : void 0
391
+ })
392
+ });
393
+ }
394
+ const headers = input.headers ?? {};
395
+ const remoteTransport = input.remoteTransport ?? "auto";
396
+ const requestInit = Object.keys(headers).length > 0 ? { headers } : void 0;
397
+ const endpoint = buildEndpointUrl(input.endpoint, input.queryParams ?? {});
398
+ const connectStreamableHttp = connectClient({
399
+ transport: "streamable-http",
400
+ createTransport: () => new StreamableHTTPClientTransport(endpoint, {
401
+ requestInit,
402
+ authProvider: input.authProvider
403
+ })
404
+ });
405
+ const connectSse = connectClient({
406
+ transport: "sse",
407
+ createTransport: () => new SSEClientTransport(endpoint, {
408
+ requestInit,
409
+ authProvider: input.authProvider
410
+ })
411
+ });
412
+ if (remoteTransport === "streamable-http") return connectStreamableHttp;
413
+ if (remoteTransport === "sse") return connectSse;
414
+ return connectStreamableHttp.pipe(Effect3.catchAll(() => connectSse));
415
+ };
416
+
362
417
  // src/sdk/discover.ts
363
418
  import { Effect as Effect4 } from "effect";
364
419
 
365
420
  // src/sdk/manifest.ts
366
- import { Schema as Schema4 } from "effect";
367
- var ListedTool = Schema4.Struct({
368
- name: Schema4.String,
369
- description: Schema4.optional(Schema4.NullOr(Schema4.String)),
370
- inputSchema: Schema4.optional(Schema4.Unknown),
371
- parameters: Schema4.optional(Schema4.Unknown),
372
- outputSchema: Schema4.optional(Schema4.Unknown)
421
+ import { Schema as Schema6 } from "effect";
422
+ var ListedTool = Schema6.Struct({
423
+ name: Schema6.String,
424
+ description: Schema6.optional(Schema6.NullOr(Schema6.String)),
425
+ inputSchema: Schema6.optional(Schema6.Unknown),
426
+ parameters: Schema6.optional(Schema6.Unknown),
427
+ outputSchema: Schema6.optional(Schema6.Unknown)
373
428
  });
374
- var ListToolsResult = Schema4.Struct({
375
- tools: Schema4.Array(ListedTool)
429
+ var ListToolsResult = Schema6.Struct({
430
+ tools: Schema6.Array(ListedTool)
376
431
  });
377
- var ServerInfo = Schema4.Struct({
378
- name: Schema4.optional(Schema4.String),
379
- version: Schema4.optional(Schema4.String)
432
+ var ServerInfo = Schema6.Struct({
433
+ name: Schema6.optional(Schema6.String),
434
+ version: Schema6.optional(Schema6.String)
380
435
  });
381
- var decodeListToolsResult = Schema4.decodeUnknownOption(ListToolsResult);
382
- var decodeServerInfo = Schema4.decodeUnknownOption(ServerInfo);
436
+ var decodeListToolsResult = Schema6.decodeUnknownOption(ListToolsResult);
437
+ var decodeServerInfo = Schema6.decodeUnknownOption(ServerInfo);
383
438
  var sanitize = (value) => {
384
439
  const s = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
385
440
  return s || "tool";
@@ -457,7 +512,7 @@ var discoverTools = (connector) => Effect4.gen(function* () {
457
512
  });
458
513
 
459
514
  // src/sdk/invoke.ts
460
- import { Effect as Effect5, Schema as Schema5 } from "effect";
515
+ import { Effect as Effect5, Schema as Schema7 } from "effect";
461
516
  import { ElicitRequestSchema } from "@modelcontextprotocol/sdk/types.js";
462
517
  import {
463
518
  ToolInvocationResult,
@@ -503,21 +558,21 @@ var makeOAuthProvider = (accessToken, tokenType, refreshToken) => ({
503
558
  },
504
559
  discoveryState: () => void 0
505
560
  });
506
- var McpElicitParams = Schema5.Union(
507
- Schema5.Struct({
508
- mode: Schema5.Literal("url"),
509
- message: Schema5.String,
510
- url: Schema5.String,
511
- elicitationId: Schema5.optional(Schema5.String),
512
- id: Schema5.optional(Schema5.String)
561
+ var McpElicitParams = Schema7.Union(
562
+ Schema7.Struct({
563
+ mode: Schema7.Literal("url"),
564
+ message: Schema7.String,
565
+ url: Schema7.String,
566
+ elicitationId: Schema7.optional(Schema7.String),
567
+ id: Schema7.optional(Schema7.String)
513
568
  }),
514
- Schema5.Struct({
515
- mode: Schema5.optional(Schema5.Literal("form")),
516
- message: Schema5.String,
517
- requestedSchema: Schema5.Record({ key: Schema5.String, value: Schema5.Unknown })
569
+ Schema7.Struct({
570
+ mode: Schema7.optional(Schema7.Literal("form")),
571
+ message: Schema7.String,
572
+ requestedSchema: Schema7.Record({ key: Schema7.String, value: Schema7.Unknown })
518
573
  })
519
574
  );
520
- var decodeElicitParams = Schema5.decodeUnknownSync(McpElicitParams);
575
+ var decodeElicitParams = Schema7.decodeUnknownSync(McpElicitParams);
521
576
  var toElicitationRequest = (params) => params.mode === "url" ? new UrlElicitation({
522
577
  message: params.message,
523
578
  url: params.url,
@@ -618,7 +673,15 @@ var makeMcpInvoker = (opts) => {
618
673
  cause: void 0
619
674
  });
620
675
  }
621
- const { binding, sourceData } = entry;
676
+ const sourceData = yield* opts.bindingStore.getSourceConfig(entry.namespace);
677
+ if (!sourceData) {
678
+ return yield* new ToolInvocationError({
679
+ toolId,
680
+ message: `No MCP source config found for namespace "${entry.namespace}"`,
681
+ cause: void 0
682
+ });
683
+ }
684
+ const { binding } = entry;
622
685
  const cacheKey = connectionCacheKey(sourceData);
623
686
  const connector = resolveConnectorInput(sourceData, opts.secrets, opts.scopeId).pipe(
624
687
  Effect5.flatMap((ci) => createMcpConnector(ci)),
@@ -782,7 +845,6 @@ var mcpDiscoveryError = (message) => new McpToolDiscoveryError({ stage: "list_to
782
845
  var mcpPlugin = (options) => {
783
846
  const bindingStore = options?.bindingStore ?? makeInMemoryBindingStore();
784
847
  const addedSources = /* @__PURE__ */ new Map();
785
- const oauthSessions = /* @__PURE__ */ new Map();
786
848
  return definePlugin({
787
849
  key: "mcp",
788
850
  init: (ctx) => Effect6.gen(function* () {
@@ -825,6 +887,7 @@ var mcpPlugin = (options) => {
825
887
  id: s.namespace,
826
888
  name: s.name,
827
889
  kind: "mcp",
890
+ url: s.config.transport === "remote" ? s.config.endpoint : void 0,
828
891
  canEdit: isRemote
829
892
  })
830
893
  );
@@ -951,8 +1014,7 @@ var mcpPlugin = (options) => {
951
1014
  (e) => bindingStore.put(
952
1015
  ToolId.make(joinToolPath(sourceId, e.toolId)),
953
1016
  sourceId,
954
- toBinding(e),
955
- sd
1017
+ toBinding(e)
956
1018
  ),
957
1019
  { discard: true }
958
1020
  );
@@ -1020,8 +1082,7 @@ var mcpPlugin = (options) => {
1020
1082
  (e) => bindingStore.put(
1021
1083
  ToolId.make(joinToolPath(namespace, e.toolId)),
1022
1084
  namespace,
1023
- toBinding(e),
1024
- sd
1085
+ toBinding(e)
1025
1086
  ),
1026
1087
  { discard: true }
1027
1088
  );
@@ -1038,6 +1099,7 @@ var mcpPlugin = (options) => {
1038
1099
  id: namespace,
1039
1100
  name: sourceName,
1040
1101
  kind: "mcp",
1102
+ url: sd.transport === "remote" ? sd.endpoint : void 0,
1041
1103
  canEdit: config.transport === "remote"
1042
1104
  })
1043
1105
  );
@@ -1064,8 +1126,7 @@ var mcpPlugin = (options) => {
1064
1126
  (e) => bindingStore.put(
1065
1127
  ToolId.make(joinToolPath(namespace, e.toolId)),
1066
1128
  namespace,
1067
- toBinding(e),
1068
- sd
1129
+ toBinding(e)
1069
1130
  ),
1070
1131
  { discard: true }
1071
1132
  );
@@ -1087,7 +1148,7 @@ var mcpPlugin = (options) => {
1087
1148
  redirectUrl: input.redirectUrl,
1088
1149
  state: sessionId
1089
1150
  }).pipe(Effect6.mapError((e) => mcpOAuthError(`OAuth start failed: ${e.message}`)));
1090
- oauthSessions.set(sessionId, {
1151
+ yield* bindingStore.putOAuthSession(sessionId, {
1091
1152
  endpoint: fullEndpoint,
1092
1153
  redirectUrl: input.redirectUrl,
1093
1154
  codeVerifier: started.codeVerifier,
@@ -1105,7 +1166,7 @@ var mcpPlugin = (options) => {
1105
1166
  const completeOAuth = (input) => Effect6.gen(function* () {
1106
1167
  if (input.error) return yield* mcpOAuthError(`OAuth error: ${input.error}`);
1107
1168
  if (!input.code) return yield* mcpOAuthError("Missing OAuth authorization code");
1108
- const session = oauthSessions.get(input.state);
1169
+ const session = yield* bindingStore.getOAuthSession(input.state);
1109
1170
  if (!session) return yield* mcpOAuthError(`OAuth session not found: ${input.state}`);
1110
1171
  const exchanged = yield* exchangeMcpOAuthCode({
1111
1172
  session,
@@ -1135,7 +1196,7 @@ var mcpPlugin = (options) => {
1135
1196
  );
1136
1197
  refreshTokenSecretId = ref.id;
1137
1198
  }
1138
- oauthSessions.delete(input.state);
1199
+ yield* bindingStore.deleteOAuthSession(input.state);
1139
1200
  const expiresAt = typeof exchanged.tokens.expires_in === "number" ? Date.now() + exchanged.tokens.expires_in * 1e3 : null;
1140
1201
  return {
1141
1202
  accessTokenSecretId: accessTokenRef.id,
@@ -1146,9 +1207,9 @@ var mcpPlugin = (options) => {
1146
1207
  };
1147
1208
  });
1148
1209
  const updateSource = (namespace, input) => Effect6.gen(function* () {
1149
- const existingConfig = yield* bindingStore.getSourceConfig(namespace);
1150
- if (!existingConfig || existingConfig.transport !== "remote") return;
1151
- const remote = existingConfig;
1210
+ const existing = yield* bindingStore.getSource(namespace);
1211
+ if (!existing || existing.config.transport !== "remote") return;
1212
+ const remote = existing.config;
1152
1213
  const updatedConfig = {
1153
1214
  ...remote,
1154
1215
  ...input.endpoint !== void 0 ? { endpoint: input.endpoint } : {},
@@ -1156,20 +1217,11 @@ var mcpPlugin = (options) => {
1156
1217
  ...input.auth !== void 0 ? { auth: input.auth } : {},
1157
1218
  ...input.queryParams !== void 0 ? { queryParams: input.queryParams } : {}
1158
1219
  };
1159
- const sources = yield* bindingStore.listSources();
1160
- const existingMeta = sources.find((s) => s.namespace === namespace);
1161
1220
  yield* bindingStore.putSource({
1162
1221
  namespace,
1163
- name: existingMeta?.name ?? namespace,
1222
+ name: input.name?.trim() || existing.name,
1164
1223
  config: updatedConfig
1165
1224
  });
1166
- const toolIds = yield* bindingStore.listByNamespace(namespace);
1167
- for (const toolId of toolIds) {
1168
- const entry = yield* bindingStore.get(toolId);
1169
- if (entry) {
1170
- yield* bindingStore.put(toolId, namespace, entry.binding, updatedConfig);
1171
- }
1172
- }
1173
1225
  });
1174
1226
  const getSource = (namespace) => bindingStore.getSource(namespace);
1175
1227
  return {
@@ -1200,4 +1252,4 @@ export {
1200
1252
  makeKvBindingStore,
1201
1253
  mcpPlugin
1202
1254
  };
1203
- //# sourceMappingURL=chunk-NJ4CITCV.js.map
1255
+ //# sourceMappingURL=chunk-X3JTTDWJ.js.map