@executor-js/plugin-mcp 0.1.0 → 0.2.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.
Files changed (45) hide show
  1. package/dist/AddMcpSource-VM3HY26S.js +762 -0
  2. package/dist/AddMcpSource-VM3HY26S.js.map +1 -0
  3. package/dist/EditMcpSource-WELWGRJG.js +259 -0
  4. package/dist/EditMcpSource-WELWGRJG.js.map +1 -0
  5. package/dist/McpSourceSummary-7TDQXLT5.js +85 -0
  6. package/dist/McpSourceSummary-7TDQXLT5.js.map +1 -0
  7. package/dist/api/group.d.ts +109 -17
  8. package/dist/api/index.d.ts +391 -0
  9. package/dist/chunk-2ETJ6LQH.js +239 -0
  10. package/dist/chunk-2ETJ6LQH.js.map +1 -0
  11. package/dist/chunk-OOOH3IO4.js +2194 -0
  12. package/dist/chunk-OOOH3IO4.js.map +1 -0
  13. package/dist/chunk-SKSXXFOA.js +104 -0
  14. package/dist/chunk-SKSXXFOA.js.map +1 -0
  15. package/dist/chunk-Z4CRPOLI.js +186 -0
  16. package/dist/chunk-Z4CRPOLI.js.map +1 -0
  17. package/dist/chunk-ZIRGIRGP.js +115 -0
  18. package/dist/chunk-ZIRGIRGP.js.map +1 -0
  19. package/dist/client.js +51 -0
  20. package/dist/client.js.map +1 -0
  21. package/dist/core.js +26 -2
  22. package/dist/index.js +2 -1
  23. package/dist/react/McpRemoteSourceFields.d.ts +18 -0
  24. package/dist/react/McpSourceSummary.d.ts +5 -0
  25. package/dist/react/atoms.d.ts +206 -6
  26. package/dist/react/client.d.ts +113 -16
  27. package/dist/react/index.d.ts +1 -1
  28. package/dist/react/plugin-client.d.ts +9 -2
  29. package/dist/sdk/binding-store.d.ts +106 -1
  30. package/dist/sdk/index.d.ts +1 -1
  31. package/dist/sdk/invoke.d.ts +2 -0
  32. package/dist/sdk/plugin.d.ts +142 -114
  33. package/dist/sdk/probe-shape-real-servers.live.test.d.ts +1 -0
  34. package/dist/sdk/probe-shape.d.ts +17 -3
  35. package/dist/sdk/stored-source.d.ts +9 -6
  36. package/dist/sdk/types.d.ts +138 -13
  37. package/dist/{stdio-connector-KNHLETKM.js → stdio-connector-AA5S6UUJ.js} +1 -1
  38. package/dist/{stdio-connector-KNHLETKM.js.map → stdio-connector-AA5S6UUJ.js.map} +1 -1
  39. package/dist/testing/index.d.ts +1 -0
  40. package/dist/{sdk/test-utils.d.ts → testing/server.d.ts} +0 -6
  41. package/dist/testing.js +51 -0
  42. package/dist/testing.js.map +1 -0
  43. package/package.json +17 -4
  44. package/dist/chunk-C2GNZGFJ.js +0 -1622
  45. package/dist/chunk-C2GNZGFJ.js.map +0 -1
@@ -21,12 +21,117 @@ export declare const mcpSchema: {
21
21
  readonly type: "json";
22
22
  readonly required: true;
23
23
  };
24
+ readonly auth_kind: {
25
+ readonly type: ["none", "header", "oauth2"];
26
+ readonly required: true;
27
+ readonly defaultValue: "none";
28
+ };
29
+ readonly auth_header_name: {
30
+ readonly type: "string";
31
+ readonly required: false;
32
+ };
33
+ readonly auth_header_slot: {
34
+ readonly type: "string";
35
+ readonly required: false;
36
+ };
37
+ readonly auth_header_prefix: {
38
+ readonly type: "string";
39
+ readonly required: false;
40
+ };
41
+ readonly auth_connection_slot: {
42
+ readonly type: "string";
43
+ readonly required: false;
44
+ };
45
+ readonly auth_client_id_slot: {
46
+ readonly type: "string";
47
+ readonly required: false;
48
+ };
49
+ readonly auth_client_secret_slot: {
50
+ readonly type: "string";
51
+ readonly required: false;
52
+ };
24
53
  readonly created_at: {
25
54
  readonly type: "date";
26
55
  readonly required: true;
27
56
  };
28
57
  };
29
58
  };
59
+ readonly mcp_source_header: {
60
+ readonly fields: {
61
+ readonly id: {
62
+ readonly type: "string";
63
+ readonly required: true;
64
+ };
65
+ readonly scope_id: {
66
+ readonly type: "string";
67
+ readonly required: true;
68
+ readonly index: true;
69
+ };
70
+ readonly source_id: {
71
+ readonly type: "string";
72
+ readonly required: true;
73
+ readonly index: true;
74
+ };
75
+ readonly name: {
76
+ readonly type: "string";
77
+ readonly required: true;
78
+ };
79
+ readonly kind: {
80
+ readonly type: ["text", "binding"];
81
+ readonly required: true;
82
+ };
83
+ readonly text_value: {
84
+ readonly type: "string";
85
+ readonly required: false;
86
+ };
87
+ readonly slot_key: {
88
+ readonly type: "string";
89
+ readonly required: false;
90
+ };
91
+ readonly prefix: {
92
+ readonly type: "string";
93
+ readonly required: false;
94
+ };
95
+ };
96
+ };
97
+ readonly mcp_source_query_param: {
98
+ readonly fields: {
99
+ readonly id: {
100
+ readonly type: "string";
101
+ readonly required: true;
102
+ };
103
+ readonly scope_id: {
104
+ readonly type: "string";
105
+ readonly required: true;
106
+ readonly index: true;
107
+ };
108
+ readonly source_id: {
109
+ readonly type: "string";
110
+ readonly required: true;
111
+ readonly index: true;
112
+ };
113
+ readonly name: {
114
+ readonly type: "string";
115
+ readonly required: true;
116
+ };
117
+ readonly kind: {
118
+ readonly type: ["text", "binding"];
119
+ readonly required: true;
120
+ };
121
+ readonly text_value: {
122
+ readonly type: "string";
123
+ readonly required: false;
124
+ };
125
+ readonly slot_key: {
126
+ readonly type: "string";
127
+ readonly required: false;
128
+ };
129
+ readonly prefix: {
130
+ readonly type: "string";
131
+ readonly required: false;
132
+ };
133
+ };
134
+ };
30
135
  readonly mcp_binding: {
31
136
  readonly fields: {
32
137
  readonly id: {
@@ -83,4 +188,4 @@ export interface McpBindingStore {
83
188
  readonly putSource: (source: McpStoredSource) => Effect.Effect<void, StorageFailure>;
84
189
  readonly removeSource: (namespace: string, scope: string) => Effect.Effect<void, StorageFailure>;
85
190
  }
86
- export declare const makeMcpStore: ({ adapter: db, }: StorageDeps<McpSchema>) => McpBindingStore;
191
+ export declare const makeMcpStore: ({ adapter: db }: StorageDeps<McpSchema>) => McpBindingStore;
@@ -1,3 +1,3 @@
1
1
  export { mcpPlugin, type McpPluginExtension, type McpPluginOptions, type McpSourceConfig, type McpRemoteSourceConfig, type McpStdioSourceConfig, type McpProbeResult, type McpUpdateSourceInput, } from "./plugin";
2
2
  export { makeMcpStore, mcpSchema, type McpBindingStore, type McpSchema, type McpStoredSource, } from "./binding-store";
3
- export { McpConnectionAuth } from "./types";
3
+ export { ConfiguredMcpCredentialValue, MCP_HEADER_AUTH_SLOT, MCP_OAUTH_CLIENT_ID_SLOT, MCP_OAUTH_CLIENT_SECRET_SLOT, MCP_OAUTH_CONNECTION_SLOT, McpConnectionAuth, McpConnectionAuthInput, McpCredentialInput, McpSourceBindingInput, McpSourceBindingRef, mcpHeaderSlot, mcpQueryParamSlot, type McpSourceBindingValue, } from "./types";
@@ -8,6 +8,8 @@ export interface InvokeMcpToolInput {
8
8
  readonly toolName: string;
9
9
  readonly args: unknown;
10
10
  readonly sourceData: McpStoredSourceData;
11
+ readonly sourceId: string;
12
+ readonly sourceScope: string;
11
13
  /** Innermost executor scope id at invoke time. Mixed into the
12
14
  * connection cache key so per-user OAuth/secret resolution doesn't
13
15
  * collapse multiple users onto one shared connection. */
@@ -1,9 +1,10 @@
1
- import { Effect } from "effect";
2
- import { McpExtensionService } from "../api/handlers";
1
+ import { Effect, Layer } from "effect";
2
+ import type { HttpClient } from "effect/unstable/http";
3
3
  import { type StorageFailure } from "@executor-js/sdk/core";
4
4
  import { type McpBindingStore, type McpStoredSource } from "./binding-store";
5
5
  import { McpConnectionError, McpToolDiscoveryError } from "./errors";
6
- import { type McpConnectionAuth, type SecretBackedValue } from "./types";
6
+ import { type McpShapeProbeResult } from "./probe-shape";
7
+ import { McpSourceBindingInput, McpSourceBindingRef, type McpConnectionAuthInput, type McpCredentialInput, type SecretBackedValue } from "./types";
7
8
  import { type ConfigFileSink } from "@executor-js/config";
8
9
  /**
9
10
  * Executor scope id that owns a newly-added MCP source row. Must be one
@@ -19,10 +20,15 @@ export interface McpRemoteSourceConfig extends McpSourceScopeField {
19
20
  readonly name: string;
20
21
  readonly endpoint: string;
21
22
  readonly remoteTransport?: "streamable-http" | "sse" | "auto";
22
- readonly queryParams?: Record<string, SecretBackedValue>;
23
- readonly headers?: Record<string, SecretBackedValue>;
23
+ readonly queryParams?: Record<string, McpCredentialInput>;
24
+ readonly headers?: Record<string, McpCredentialInput>;
24
25
  readonly namespace?: string;
25
- readonly auth?: McpConnectionAuth;
26
+ readonly auth?: McpConnectionAuthInput;
27
+ /**
28
+ * Scope that owns any direct credentials supplied on this call. Required
29
+ * whenever headers/queryParams/auth carry direct secret or connection ids.
30
+ */
31
+ readonly credentialTargetScope?: string;
26
32
  }
27
33
  export interface McpStdioSourceConfig extends McpSourceScopeField {
28
34
  readonly transport: "stdio";
@@ -37,6 +43,7 @@ export type McpSourceConfig = McpRemoteSourceConfig | McpStdioSourceConfig;
37
43
  export interface McpProbeResult {
38
44
  readonly connected: boolean;
39
45
  readonly requiresOAuth: boolean;
46
+ readonly supportsDynamicRegistration: boolean;
40
47
  readonly name: string;
41
48
  readonly namespace: string;
42
49
  readonly toolCount: number | null;
@@ -45,15 +52,25 @@ export interface McpProbeResult {
45
52
  export interface McpUpdateSourceInput {
46
53
  readonly name?: string;
47
54
  readonly endpoint?: string;
48
- readonly headers?: Record<string, SecretBackedValue>;
49
- readonly queryParams?: Record<string, SecretBackedValue>;
50
- readonly auth?: McpConnectionAuth;
55
+ readonly headers?: Record<string, McpCredentialInput>;
56
+ readonly queryParams?: Record<string, McpCredentialInput>;
57
+ readonly credentialTargetScope?: string;
58
+ readonly auth?: McpConnectionAuthInput;
51
59
  }
52
60
  export interface McpProbeEndpointInput {
53
61
  readonly endpoint: string;
54
62
  readonly headers?: Record<string, SecretBackedValue>;
55
63
  readonly queryParams?: Record<string, SecretBackedValue>;
56
64
  }
65
+ /** Translate a non-MCP probe outcome into a message a user can act on.
66
+ * The technical `reason` (`401 without Bearer WWW-Authenticate — not an
67
+ * MCP auth challenge`, etc.) stays in telemetry via the probe span; the
68
+ * user gets a sentence pointing at their next step. Exported for tests. */
69
+ export declare const userFacingProbeMessage: (shape: Extract<McpShapeProbeResult, {
70
+ kind: "not-mcp";
71
+ } | {
72
+ kind: "unreachable";
73
+ }>) => string;
57
74
  export interface McpPluginOptions {
58
75
  /**
59
76
  * Allow configuring stdio-transport MCP sources. Off by default.
@@ -62,6 +79,7 @@ export interface McpPluginOptions {
62
79
  * `process.env`. Only enable for trusted single-user contexts.
63
80
  */
64
81
  readonly dangerouslyAllowStdioMCP?: boolean;
82
+ readonly httpClientLayer?: Layer.Layer<HttpClient.HttpClient>;
65
83
  /** If provided, source add/remove is mirrored to executor.jsonc
66
84
  * (best-effort — file errors are logged, not raised). */
67
85
  readonly configFile?: ConfigFileSink;
@@ -70,6 +88,7 @@ export declare const mcpPlugin: import("@executor-js/sdk/core").ConfiguredPlugin
70
88
  probeEndpoint: (input: string | McpProbeEndpointInput) => Effect.Effect<{
71
89
  connected: true;
72
90
  requiresOAuth: false;
91
+ supportsDynamicRegistration: false;
73
92
  name: string;
74
93
  namespace: string;
75
94
  toolCount: number;
@@ -77,6 +96,7 @@ export declare const mcpPlugin: import("@executor-js/sdk/core").ConfiguredPlugin
77
96
  } | {
78
97
  connected: false;
79
98
  requiresOAuth: true;
99
+ supportsDynamicRegistration: boolean;
80
100
  name: string;
81
101
  namespace: string;
82
102
  toolCount: null;
@@ -91,7 +111,10 @@ export declare const mcpPlugin: import("@executor-js/sdk/core").ConfiguredPlugin
91
111
  toolCount: number;
92
112
  }, StorageFailure | McpConnectionError | McpToolDiscoveryError, never>;
93
113
  getSource: (namespace: string, scope: string) => Effect.Effect<McpStoredSource | null, StorageFailure, never>;
94
- updateSource: (namespace: string, scope: string, input: McpUpdateSourceInput) => Effect.Effect<void, StorageFailure, never>;
114
+ updateSource: (namespace: string, scope: string, input: McpUpdateSourceInput) => Effect.Effect<void, StorageFailure | McpConnectionError, never>;
115
+ listSourceBindings: (sourceId: string, sourceScope: string) => Effect.Effect<readonly McpSourceBindingRef[], StorageFailure, never>;
116
+ setSourceBinding: (input: McpSourceBindingInput) => Effect.Effect<McpSourceBindingRef, StorageFailure, never>;
117
+ removeSourceBinding: (sourceId: string, sourceScope: string, slot: string, scope: string) => Effect.Effect<void, StorageFailure, never>;
95
118
  }, McpBindingStore, McpPluginOptions, {
96
119
  readonly mcp_source: {
97
120
  readonly fields: {
@@ -112,12 +135,117 @@ export declare const mcpPlugin: import("@executor-js/sdk/core").ConfiguredPlugin
112
135
  readonly type: "json";
113
136
  readonly required: true;
114
137
  };
138
+ readonly auth_kind: {
139
+ readonly type: ["none", "header", "oauth2"];
140
+ readonly required: true;
141
+ readonly defaultValue: "none";
142
+ };
143
+ readonly auth_header_name: {
144
+ readonly type: "string";
145
+ readonly required: false;
146
+ };
147
+ readonly auth_header_slot: {
148
+ readonly type: "string";
149
+ readonly required: false;
150
+ };
151
+ readonly auth_header_prefix: {
152
+ readonly type: "string";
153
+ readonly required: false;
154
+ };
155
+ readonly auth_connection_slot: {
156
+ readonly type: "string";
157
+ readonly required: false;
158
+ };
159
+ readonly auth_client_id_slot: {
160
+ readonly type: "string";
161
+ readonly required: false;
162
+ };
163
+ readonly auth_client_secret_slot: {
164
+ readonly type: "string";
165
+ readonly required: false;
166
+ };
115
167
  readonly created_at: {
116
168
  readonly type: "date";
117
169
  readonly required: true;
118
170
  };
119
171
  };
120
172
  };
173
+ readonly mcp_source_header: {
174
+ readonly fields: {
175
+ readonly id: {
176
+ readonly type: "string";
177
+ readonly required: true;
178
+ };
179
+ readonly scope_id: {
180
+ readonly type: "string";
181
+ readonly required: true;
182
+ readonly index: true;
183
+ };
184
+ readonly source_id: {
185
+ readonly type: "string";
186
+ readonly required: true;
187
+ readonly index: true;
188
+ };
189
+ readonly name: {
190
+ readonly type: "string";
191
+ readonly required: true;
192
+ };
193
+ readonly kind: {
194
+ readonly type: ["text", "binding"];
195
+ readonly required: true;
196
+ };
197
+ readonly text_value: {
198
+ readonly type: "string";
199
+ readonly required: false;
200
+ };
201
+ readonly slot_key: {
202
+ readonly type: "string";
203
+ readonly required: false;
204
+ };
205
+ readonly prefix: {
206
+ readonly type: "string";
207
+ readonly required: false;
208
+ };
209
+ };
210
+ };
211
+ readonly mcp_source_query_param: {
212
+ readonly fields: {
213
+ readonly id: {
214
+ readonly type: "string";
215
+ readonly required: true;
216
+ };
217
+ readonly scope_id: {
218
+ readonly type: "string";
219
+ readonly required: true;
220
+ readonly index: true;
221
+ };
222
+ readonly source_id: {
223
+ readonly type: "string";
224
+ readonly required: true;
225
+ readonly index: true;
226
+ };
227
+ readonly name: {
228
+ readonly type: "string";
229
+ readonly required: true;
230
+ };
231
+ readonly kind: {
232
+ readonly type: ["text", "binding"];
233
+ readonly required: true;
234
+ };
235
+ readonly text_value: {
236
+ readonly type: "string";
237
+ readonly required: false;
238
+ };
239
+ readonly slot_key: {
240
+ readonly type: "string";
241
+ readonly required: false;
242
+ };
243
+ readonly prefix: {
244
+ readonly type: "string";
245
+ readonly required: false;
246
+ };
247
+ };
248
+ };
121
249
  readonly mcp_binding: {
122
250
  readonly fields: {
123
251
  readonly id: {
@@ -144,110 +272,7 @@ export declare const mcpPlugin: import("@executor-js/sdk/core").ConfiguredPlugin
144
272
  };
145
273
  };
146
274
  };
147
- }, typeof McpExtensionService, import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").ApiGroup<"executor", "mcp">, never, import("effect/unstable/http/HttpRouter").Request<"Requires", McpExtensionService>>, import("effect/unstable/httpapi/HttpApiGroup").HttpApiGroup<"mcp", import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"probeEndpoint", "POST", "/scopes/:scopeId/mcp/probe", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<import("effect/Schema").Struct<{
148
- scopeId: import("effect/Schema").brand<import("effect/Schema").String, "ScopeId">;
149
- }>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
150
- readonly endpoint: import("effect/Schema").String;
151
- readonly headers: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Union<readonly [import("effect/Schema").String, import("effect/Schema").Struct<{
152
- readonly secretId: import("effect/Schema").String;
153
- readonly prefix: import("effect/Schema").optional<import("effect/Schema").String>;
154
- }>]>>>;
155
- readonly queryParams: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Union<readonly [import("effect/Schema").String, import("effect/Schema").Struct<{
156
- readonly secretId: import("effect/Schema").String;
157
- readonly prefix: import("effect/Schema").optional<import("effect/Schema").String>;
158
- }>]>>>;
159
- }>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
160
- readonly connected: import("effect/Schema").Boolean;
161
- readonly requiresOAuth: import("effect/Schema").Boolean;
162
- readonly name: import("effect/Schema").String;
163
- readonly namespace: import("effect/Schema").String;
164
- readonly toolCount: import("effect/Schema").NullOr<import("effect/Schema").Number>;
165
- readonly serverName: import("effect/Schema").NullOr<import("effect/Schema").String>;
166
- }>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("@executor-js/api").InternalError | typeof McpConnectionError | typeof McpToolDiscoveryError>, never, never> | import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"addSource", "POST", "/scopes/:scopeId/mcp/sources", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<import("effect/Schema").Struct<{
167
- scopeId: import("effect/Schema").brand<import("effect/Schema").String, "ScopeId">;
168
- }>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Union<readonly [import("effect/Schema").Struct<{
169
- readonly transport: import("effect/Schema").Literal<"remote">;
170
- readonly name: import("effect/Schema").String;
171
- readonly endpoint: import("effect/Schema").String;
172
- readonly remoteTransport: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["streamable-http", "sse", "auto"]>>;
173
- readonly namespace: import("effect/Schema").optional<import("effect/Schema").String>;
174
- readonly queryParams: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Union<readonly [import("effect/Schema").String, import("effect/Schema").Struct<{
175
- readonly secretId: import("effect/Schema").String;
176
- readonly prefix: import("effect/Schema").optional<import("effect/Schema").String>;
177
- }>]>>>;
178
- readonly headers: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Union<readonly [import("effect/Schema").String, import("effect/Schema").Struct<{
179
- readonly secretId: import("effect/Schema").String;
180
- readonly prefix: import("effect/Schema").optional<import("effect/Schema").String>;
181
- }>]>>>;
182
- readonly auth: import("effect/Schema").optional<import("effect/Schema").Union<readonly [import("effect/Schema").Struct<{
183
- readonly kind: import("effect/Schema").Literal<"none">;
184
- }>, import("effect/Schema").Struct<{
185
- readonly kind: import("effect/Schema").Literal<"header">;
186
- readonly headerName: import("effect/Schema").String;
187
- readonly secretId: import("effect/Schema").String;
188
- readonly prefix: import("effect/Schema").optional<import("effect/Schema").String>;
189
- }>, import("effect/Schema").Struct<{
190
- readonly kind: import("effect/Schema").Literal<"oauth2">;
191
- readonly connectionId: import("effect/Schema").String;
192
- readonly clientIdSecretId: import("effect/Schema").optional<import("effect/Schema").String>;
193
- readonly clientSecretSecretId: import("effect/Schema").optional<import("effect/Schema").NullOr<import("effect/Schema").String>>;
194
- }>]>>;
195
- }>, import("effect/Schema").Struct<{
196
- readonly transport: import("effect/Schema").Literal<"stdio">;
197
- readonly name: import("effect/Schema").String;
198
- readonly command: import("effect/Schema").String;
199
- readonly args: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").String>>;
200
- readonly env: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").String>>;
201
- readonly cwd: import("effect/Schema").optional<import("effect/Schema").String>;
202
- readonly namespace: import("effect/Schema").optional<import("effect/Schema").String>;
203
- }>]>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
204
- readonly toolCount: import("effect/Schema").Number;
205
- readonly namespace: import("effect/Schema").String;
206
- }>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("@executor-js/api").InternalError | typeof McpConnectionError | typeof McpToolDiscoveryError>, never, never> | import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"removeSource", "POST", "/scopes/:scopeId/mcp/sources/remove", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<import("effect/Schema").Struct<{
207
- scopeId: import("effect/Schema").brand<import("effect/Schema").String, "ScopeId">;
208
- }>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
209
- readonly namespace: import("effect/Schema").String;
210
- }>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
211
- readonly removed: import("effect/Schema").Boolean;
212
- }>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("@executor-js/api").InternalError | typeof McpConnectionError | typeof McpToolDiscoveryError>, never, never> | import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"refreshSource", "POST", "/scopes/:scopeId/mcp/sources/refresh", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<import("effect/Schema").Struct<{
213
- scopeId: import("effect/Schema").brand<import("effect/Schema").String, "ScopeId">;
214
- }>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
215
- readonly namespace: import("effect/Schema").String;
216
- }>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
217
- readonly toolCount: import("effect/Schema").Number;
218
- }>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("@executor-js/api").InternalError | typeof McpConnectionError | typeof McpToolDiscoveryError>, never, never> | import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"getSource", "GET", "/scopes/:scopeId/mcp/sources/:namespace", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<import("effect/Schema").Struct<{
219
- scopeId: import("effect/Schema").brand<import("effect/Schema").String, "ScopeId">;
220
- namespace: import("effect/Schema").String;
221
- }>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").NullOr<typeof import("./stored-source").McpStoredSourceSchema>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("@executor-js/api").InternalError | typeof McpConnectionError | typeof McpToolDiscoveryError>, never, never> | import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"updateSource", "PATCH", "/scopes/:scopeId/mcp/sources/:namespace", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<import("effect/Schema").Struct<{
222
- scopeId: import("effect/Schema").brand<import("effect/Schema").String, "ScopeId">;
223
- namespace: import("effect/Schema").String;
224
- }>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
225
- readonly name: import("effect/Schema").optional<import("effect/Schema").String>;
226
- readonly endpoint: import("effect/Schema").optional<import("effect/Schema").String>;
227
- readonly headers: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Union<readonly [import("effect/Schema").String, import("effect/Schema").Struct<{
228
- readonly secretId: import("effect/Schema").String;
229
- readonly prefix: import("effect/Schema").optional<import("effect/Schema").String>;
230
- }>]>>>;
231
- readonly queryParams: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Union<readonly [import("effect/Schema").String, import("effect/Schema").Struct<{
232
- readonly secretId: import("effect/Schema").String;
233
- readonly prefix: import("effect/Schema").optional<import("effect/Schema").String>;
234
- }>]>>>;
235
- readonly auth: import("effect/Schema").optional<import("effect/Schema").Union<readonly [import("effect/Schema").Struct<{
236
- readonly kind: import("effect/Schema").Literal<"none">;
237
- }>, import("effect/Schema").Struct<{
238
- readonly kind: import("effect/Schema").Literal<"header">;
239
- readonly headerName: import("effect/Schema").String;
240
- readonly secretId: import("effect/Schema").String;
241
- readonly prefix: import("effect/Schema").optional<import("effect/Schema").String>;
242
- }>, import("effect/Schema").Struct<{
243
- readonly kind: import("effect/Schema").Literal<"oauth2">;
244
- readonly connectionId: import("effect/Schema").String;
245
- readonly clientIdSecretId: import("effect/Schema").optional<import("effect/Schema").String>;
246
- readonly clientSecretSecretId: import("effect/Schema").optional<import("effect/Schema").NullOr<import("effect/Schema").String>>;
247
- }>]>>;
248
- }>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
249
- readonly updated: import("effect/Schema").Boolean;
250
- }>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("@executor-js/api").InternalError | typeof McpConnectionError | typeof McpToolDiscoveryError>, never, never>, false>>;
275
+ }, undefined, Layer.Layer<unknown, never, never>, import("effect/unstable/httpapi/HttpApiGroup").Any>;
251
276
  /**
252
277
  * Errors any MCP extension method may surface. The first four are
253
278
  * plugin-domain tagged errors that flow directly to clients (4xx, each
@@ -271,5 +296,8 @@ export interface McpPluginExtension {
271
296
  }, McpExtensionFailure>;
272
297
  readonly getSource: (namespace: string, scope: string) => Effect.Effect<McpStoredSource | null, McpExtensionFailure>;
273
298
  readonly updateSource: (namespace: string, scope: string, input: McpUpdateSourceInput) => Effect.Effect<void, McpExtensionFailure>;
299
+ readonly listSourceBindings: (sourceId: string, sourceScope: string) => Effect.Effect<readonly McpSourceBindingRef[], StorageFailure>;
300
+ readonly setSourceBinding: (input: McpSourceBindingInput) => Effect.Effect<McpSourceBindingRef, StorageFailure>;
301
+ readonly removeSourceBinding: (sourceId: string, sourceScope: string, slot: string, scope: string) => Effect.Effect<void, StorageFailure>;
274
302
  }
275
303
  export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,18 @@
1
- import { Effect } from "effect";
1
+ import { Effect, Layer } from "effect";
2
+ import { HttpClient } from "effect/unstable/http";
3
+ /** Why the probe rejected an endpoint as not-MCP.
4
+ *
5
+ * - `auth-required` — server returned 401. We don't know for sure it's
6
+ * an MCP server (no spec-compliant Bearer challenge or the body
7
+ * isn't JSON-RPC), but the right next step for the user is the same
8
+ * either way: provide credentials and retry. This is what
9
+ * misclassifies real MCP servers like cubic.dev (no
10
+ * resource_metadata) or ref.tools (no WWW-Authenticate at all)
11
+ * without the URL-token fallback at the detect layer.
12
+ * - `wrong-shape` — endpoint responded but with a body or status that
13
+ * doesn't match any MCP shape (200 HTML, 400 GraphQL, 404 from a
14
+ * static host, etc.). User action: this URL probably isn't MCP. */
15
+ export type McpProbeRejectCategory = "auth-required" | "wrong-shape";
2
16
  export type McpShapeProbeResult =
3
17
  /** Server answered initialize successfully — either a 2xx with a
4
18
  * JSON-RPC payload, or a 401 + WWW-Authenticate: Bearer (RFC 6750
@@ -11,6 +25,7 @@ export type McpShapeProbeResult =
11
25
  | {
12
26
  readonly kind: "not-mcp";
13
27
  readonly reason: string;
28
+ readonly category: McpProbeRejectCategory;
14
29
  }
15
30
  /** Transport-level failure (DNS, TLS, timeout, abort, ...). */
16
31
  | {
@@ -18,10 +33,9 @@ export type McpShapeProbeResult =
18
33
  readonly reason: string;
19
34
  };
20
35
  export interface ProbeOptions {
21
- /** Injected for tests. Defaults to the global `fetch`. */
22
- readonly fetch?: typeof fetch;
23
36
  /** Abort the request after this many ms. Default 8000. */
24
37
  readonly timeoutMs?: number;
38
+ readonly httpClientLayer?: Layer.Layer<HttpClient.HttpClient>;
25
39
  readonly headers?: Record<string, string>;
26
40
  readonly queryParams?: Record<string, string>;
27
41
  }
@@ -1,17 +1,20 @@
1
1
  import { Schema } from "effect";
2
2
  declare const McpStoredSourceSchema_base: Schema.Class<McpStoredSourceSchema, Schema.Struct<{
3
3
  readonly namespace: Schema.String;
4
+ readonly scope: Schema.brand<Schema.String, "ScopeId">;
4
5
  readonly name: Schema.String;
5
6
  readonly config: Schema.Union<readonly [Schema.Struct<{
6
7
  readonly transport: Schema.Literal<"remote">;
7
8
  readonly endpoint: Schema.String;
8
9
  readonly remoteTransport: Schema.withConstructorDefault<Schema.optionalKey<Schema.Literals<readonly ["streamable-http", "sse", "auto"]>>>;
9
10
  readonly queryParams: Schema.optional<Schema.$Record<Schema.String, Schema.Union<readonly [Schema.String, Schema.Struct<{
10
- readonly secretId: Schema.String;
11
+ readonly kind: Schema.Literal<"binding">;
12
+ readonly slot: Schema.String;
11
13
  readonly prefix: Schema.optional<Schema.String>;
12
14
  }>]>>>;
13
15
  readonly headers: Schema.optional<Schema.$Record<Schema.String, Schema.Union<readonly [Schema.String, Schema.Struct<{
14
- readonly secretId: Schema.String;
16
+ readonly kind: Schema.Literal<"binding">;
17
+ readonly slot: Schema.String;
15
18
  readonly prefix: Schema.optional<Schema.String>;
16
19
  }>]>>>;
17
20
  readonly auth: Schema.Union<readonly [Schema.Struct<{
@@ -19,13 +22,13 @@ declare const McpStoredSourceSchema_base: Schema.Class<McpStoredSourceSchema, Sc
19
22
  }>, Schema.Struct<{
20
23
  readonly kind: Schema.Literal<"header">;
21
24
  readonly headerName: Schema.String;
22
- readonly secretId: Schema.String;
25
+ readonly secretSlot: Schema.String;
23
26
  readonly prefix: Schema.optional<Schema.String>;
24
27
  }>, Schema.Struct<{
25
28
  readonly kind: Schema.Literal<"oauth2">;
26
- readonly connectionId: Schema.String;
27
- readonly clientIdSecretId: Schema.optional<Schema.String>;
28
- readonly clientSecretSecretId: Schema.optional<Schema.NullOr<Schema.String>>;
29
+ readonly connectionSlot: Schema.String;
30
+ readonly clientIdSlot: Schema.optional<Schema.String>;
31
+ readonly clientSecretSlot: Schema.optional<Schema.String>;
29
32
  }>]>;
30
33
  }>, Schema.Struct<{
31
34
  readonly transport: Schema.Literal<"stdio">;