@executor-js/plugin-mcp 1.4.29 → 1.4.30
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-TLAL463B.js → AddMcpSource-3HUBFR3K.js} +68 -141
- package/dist/AddMcpSource-3HUBFR3K.js.map +1 -0
- package/dist/{EditMcpSource-FAWEECNU.js → EditMcpSource-UVGSSC2R.js} +106 -83
- package/dist/EditMcpSource-UVGSSC2R.js.map +1 -0
- package/dist/McpSourceSummary-UWVCAJOU.js +171 -0
- package/dist/McpSourceSummary-UWVCAJOU.js.map +1 -0
- package/dist/api/group.d.ts +92 -180
- package/dist/api/index.d.ts +97 -382
- package/dist/{chunk-4ORPFRLI.js → chunk-2A4H3UVR.js} +21 -80
- package/dist/chunk-2A4H3UVR.js.map +1 -0
- package/dist/{chunk-M6REVU6O.js → chunk-3TGDWTNE.js} +14 -40
- package/dist/chunk-3TGDWTNE.js.map +1 -0
- package/dist/{chunk-2DOCEPYN.js → chunk-H5PLTEMB.js} +632 -713
- package/dist/chunk-H5PLTEMB.js.map +1 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/{chunk-SKSXXFOA.js → chunk-TW44CBXJ.js} +12 -1
- package/dist/chunk-TW44CBXJ.js.map +1 -0
- package/dist/client.js +5 -4
- package/dist/client.js.map +1 -1
- package/dist/core.js +4 -6
- package/dist/index.js +4 -2
- package/dist/promise.d.ts +1 -1
- package/dist/react/atoms.d.ts +198 -236
- package/dist/react/client.d.ts +91 -179
- package/dist/sdk/binding-store.d.ts +3 -163
- package/dist/sdk/index.d.ts +2 -2
- package/dist/sdk/plugin.d.ts +172 -225
- package/dist/sdk/presets.d.ts +1 -0
- package/dist/sdk/testing-fixtures.test.d.ts +1 -0
- package/dist/sdk/types.d.ts +58 -83
- package/dist/{stdio-connector-AA5S6UUJ.js → stdio-connector-MDW6PW36.js} +3 -1
- package/dist/{stdio-connector-AA5S6UUJ.js.map → stdio-connector-MDW6PW36.js.map} +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/server.d.ts +70 -4
- package/dist/testing.js +14085 -30
- package/dist/testing.js.map +1 -1
- package/package.json +3 -4
- package/dist/AddMcpSource-TLAL463B.js.map +0 -1
- package/dist/EditMcpSource-FAWEECNU.js.map +0 -1
- package/dist/McpSourceSummary-257JNETP.js +0 -85
- package/dist/McpSourceSummary-257JNETP.js.map +0 -1
- package/dist/chunk-2DOCEPYN.js.map +0 -1
- package/dist/chunk-4ORPFRLI.js.map +0 -1
- package/dist/chunk-M6REVU6O.js.map +0 -1
- package/dist/chunk-SKSXXFOA.js.map +0 -1
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
mcpPresets
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TW44CBXJ.js";
|
|
4
4
|
import {
|
|
5
5
|
McpRemoteSourceFields
|
|
6
6
|
} from "./chunk-ZIRGIRGP.js";
|
|
7
7
|
import {
|
|
8
8
|
addMcpSourceOptimistic,
|
|
9
9
|
probeMcpEndpoint
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
} from "./chunk-M6REVU6O.js";
|
|
10
|
+
} from "./chunk-2A4H3UVR.js";
|
|
11
|
+
import "./chunk-3TGDWTNE.js";
|
|
12
|
+
import "./chunk-PZ5AY32C.js";
|
|
14
13
|
|
|
15
14
|
// src/react/AddMcpSource.tsx
|
|
16
15
|
import { useReducer, useCallback, useEffect, useRef, useState } from "react";
|
|
@@ -24,22 +23,21 @@ import { Button } from "@executor-js/react/components/button";
|
|
|
24
23
|
import {
|
|
25
24
|
CardStack,
|
|
26
25
|
CardStackContent,
|
|
27
|
-
CardStackEntry,
|
|
28
26
|
CardStackEntryField
|
|
29
27
|
} from "@executor-js/react/components/card-stack";
|
|
30
28
|
import { FieldLabel } from "@executor-js/react/components/field";
|
|
31
29
|
import { FilterTabs } from "@executor-js/react/components/filter-tabs";
|
|
32
30
|
import { FloatActions } from "@executor-js/react/components/float-actions";
|
|
33
31
|
import { Input } from "@executor-js/react/components/input";
|
|
34
|
-
import { Label } from "@executor-js/react/components/label";
|
|
35
32
|
import { Spinner } from "@executor-js/react/components/spinner";
|
|
36
33
|
import { Textarea } from "@executor-js/react/components/textarea";
|
|
37
34
|
import {
|
|
38
35
|
emptyHttpCredentials,
|
|
39
36
|
httpCredentialsValid,
|
|
40
37
|
HttpCredentialsEditor,
|
|
41
|
-
|
|
42
|
-
serializeHttpCredentials
|
|
38
|
+
serializeConfigureHttpCredentials,
|
|
39
|
+
serializeHttpCredentials,
|
|
40
|
+
serializeTemplateHttpCredentials
|
|
43
41
|
} from "@executor-js/react/plugins/http-credentials";
|
|
44
42
|
import {
|
|
45
43
|
sourceDisplayNameFromUrl,
|
|
@@ -58,10 +56,24 @@ import {
|
|
|
58
56
|
CredentialUsageRow,
|
|
59
57
|
useCredentialTargetScope
|
|
60
58
|
} from "@executor-js/react/plugins/credential-target-scope";
|
|
59
|
+
import {
|
|
60
|
+
defaultHeaderAuthPresets
|
|
61
|
+
} from "@executor-js/react/plugins/secret-header-auth";
|
|
61
62
|
import { sourceWriteKeys } from "@executor-js/react/api/reactivity-keys";
|
|
62
63
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
64
|
+
var mcpHeaderPresets = [
|
|
65
|
+
{ key: "text", label: "Plaintext header", name: "", valueKind: "text" },
|
|
66
|
+
...defaultHeaderAuthPresets
|
|
67
|
+
];
|
|
63
68
|
var ErrorMessage = Schema.Struct({ message: Schema.String });
|
|
64
69
|
var decodeErrorMessage = Schema.decodeUnknownOption(ErrorMessage);
|
|
70
|
+
var STDIO_ENV_ESCAPE_REPLACEMENTS = {
|
|
71
|
+
"\\": "\\",
|
|
72
|
+
n: "\n",
|
|
73
|
+
r: "\r",
|
|
74
|
+
t: " ",
|
|
75
|
+
'"': '"'
|
|
76
|
+
};
|
|
65
77
|
var errorMessageFromExit = (exit, fallback) => Option.match(Option.flatMap(Exit.findErrorOption(exit), decodeErrorMessage), {
|
|
66
78
|
onNone: () => fallback,
|
|
67
79
|
onSome: ({ message }) => message
|
|
@@ -212,7 +224,6 @@ function AddMcpSource(props) {
|
|
|
212
224
|
startErrorMessage: "Failed to start OAuth"
|
|
213
225
|
});
|
|
214
226
|
const [remoteAuthMode, setRemoteAuthMode] = useState("none");
|
|
215
|
-
const [remoteHeaders, setRemoteHeaders] = useState([]);
|
|
216
227
|
const [remoteCredentials, setRemoteCredentials] = useState(() => emptyHttpCredentials());
|
|
217
228
|
const probe = "probe" in state ? state.probe : null;
|
|
218
229
|
const tokens = "tokens" in state ? state.tokens : null;
|
|
@@ -223,12 +234,9 @@ function AddMcpSource(props) {
|
|
|
223
234
|
const isAdding = state.step === "adding";
|
|
224
235
|
const isOAuthBusy = state.step === "oauth-starting" || state.step === "oauth-waiting" || oauth.busy;
|
|
225
236
|
const canUseNone = probe?.requiresOAuth !== true || probe.supportsDynamicRegistration === false;
|
|
226
|
-
const remoteHeadersComplete = remoteHeaders.every(
|
|
227
|
-
(header) => header.name.trim() && header.value.trim()
|
|
228
|
-
);
|
|
229
237
|
const remoteCredentialsComplete = httpCredentialsValid(remoteCredentials);
|
|
230
238
|
const authReady = remoteAuthMode === "none" ? canUseNone : tokens !== null;
|
|
231
|
-
const canAdd = Boolean(probe) && authReady &&
|
|
239
|
+
const canAdd = Boolean(probe) && authReady && remoteCredentialsComplete && !isAdding && !isOAuthBusy;
|
|
232
240
|
const probeError = state.step === "error" && state.probe === null ? state.error : null;
|
|
233
241
|
const otherError = state.step === "error" && state.probe !== null ? state.error : null;
|
|
234
242
|
const handleProbe = useCallback(async () => {
|
|
@@ -307,38 +315,47 @@ function AddMcpSource(props) {
|
|
|
307
315
|
const handleAddRemote = useCallback(async () => {
|
|
308
316
|
if (!probe) return;
|
|
309
317
|
dispatch({ type: "add-start" });
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
connectionId: tokens.connectionId
|
|
313
|
-
} : {
|
|
314
|
-
kind: "oauth2",
|
|
315
|
-
connectionSlot: MCP_OAUTH_CONNECTION_SLOT
|
|
316
|
-
} : { kind: "none" };
|
|
317
|
-
const headers = Object.fromEntries(
|
|
318
|
-
remoteHeaders.map((header) => [header.name.trim(), header.value.trim()]).filter(([name, value2]) => name && value2)
|
|
319
|
-
);
|
|
320
|
-
const credentials = serializeScopedHttpCredentials(
|
|
318
|
+
const templateCredentials = serializeTemplateHttpCredentials(remoteCredentials);
|
|
319
|
+
const configureCredentials = serializeConfigureHttpCredentials(
|
|
321
320
|
remoteCredentials,
|
|
322
321
|
requestCredentialTargetScope
|
|
323
322
|
);
|
|
324
|
-
const remoteRequestHeaders =
|
|
325
|
-
|
|
326
|
-
...credentials.headers
|
|
327
|
-
};
|
|
323
|
+
const remoteRequestHeaders = templateCredentials.headers;
|
|
324
|
+
const hasInitialCredentials = Object.keys(configureCredentials.headers).length > 0 || Object.keys(configureCredentials.queryParams).length > 0 || remoteAuthMode === "oauth2" && tokens;
|
|
328
325
|
const displayName = remoteIdentity.name.trim() || probe.serverName || probe.name;
|
|
329
326
|
const slugNamespace = slugifyNamespace(remoteIdentity.namespace);
|
|
330
327
|
const exit = await doAdd({
|
|
331
328
|
params: { scopeId },
|
|
332
329
|
payload: {
|
|
333
|
-
targetScope: scopeId,
|
|
334
330
|
transport: "remote",
|
|
335
331
|
name: displayName,
|
|
336
332
|
namespace: slugNamespace || void 0,
|
|
337
333
|
endpoint: state.url.trim(),
|
|
338
|
-
auth,
|
|
339
|
-
credentialTargetScope: remoteAuthMode === "oauth2" && tokens ? oauthCredentialTargetScope : requestCredentialTargetScope,
|
|
340
334
|
...Object.keys(remoteRequestHeaders).length > 0 ? { headers: remoteRequestHeaders } : {},
|
|
341
|
-
...Object.keys(
|
|
335
|
+
...Object.keys(templateCredentials.queryParams).length > 0 ? {
|
|
336
|
+
queryParams: templateCredentials.queryParams
|
|
337
|
+
} : {},
|
|
338
|
+
...hasInitialCredentials ? {
|
|
339
|
+
credentials: {
|
|
340
|
+
scope: requestCredentialTargetScope,
|
|
341
|
+
...Object.keys(configureCredentials.headers).length > 0 ? {
|
|
342
|
+
headers: configureCredentials.headers
|
|
343
|
+
} : {},
|
|
344
|
+
...Object.keys(configureCredentials.queryParams).length > 0 ? {
|
|
345
|
+
queryParams: configureCredentials.queryParams
|
|
346
|
+
} : {},
|
|
347
|
+
...remoteAuthMode === "oauth2" && tokens ? {
|
|
348
|
+
auth: {
|
|
349
|
+
oauth2: {
|
|
350
|
+
connection: {
|
|
351
|
+
kind: "connection",
|
|
352
|
+
connectionId: tokens.connectionId
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
} : {}
|
|
357
|
+
}
|
|
358
|
+
} : {}
|
|
342
359
|
},
|
|
343
360
|
reactivityKeys: sourceWriteKeys
|
|
344
361
|
});
|
|
@@ -353,7 +370,6 @@ function AddMcpSource(props) {
|
|
|
353
370
|
}, [
|
|
354
371
|
probe,
|
|
355
372
|
remoteAuthMode,
|
|
356
|
-
remoteHeaders,
|
|
357
373
|
remoteCredentials,
|
|
358
374
|
remoteIdentity,
|
|
359
375
|
tokens,
|
|
@@ -361,8 +377,7 @@ function AddMcpSource(props) {
|
|
|
361
377
|
doAdd,
|
|
362
378
|
props,
|
|
363
379
|
scopeId,
|
|
364
|
-
requestCredentialTargetScope
|
|
365
|
-
oauthCredentialTargetScope
|
|
380
|
+
requestCredentialTargetScope
|
|
366
381
|
]);
|
|
367
382
|
const parseStdioArgs = (raw) => {
|
|
368
383
|
if (!raw.trim()) return [];
|
|
@@ -374,13 +389,27 @@ function AddMcpSource(props) {
|
|
|
374
389
|
}
|
|
375
390
|
return args;
|
|
376
391
|
};
|
|
392
|
+
const parseStdioEnvValue = (raw) => {
|
|
393
|
+
const value2 = raw.trim();
|
|
394
|
+
if (value2.length < 2) return value2;
|
|
395
|
+
const quote = value2[0];
|
|
396
|
+
if (quote !== '"' && quote !== "'" || value2[value2.length - 1] !== quote) {
|
|
397
|
+
return value2;
|
|
398
|
+
}
|
|
399
|
+
const inner = value2.slice(1, -1);
|
|
400
|
+
if (quote === "'") return inner;
|
|
401
|
+
return inner.replace(
|
|
402
|
+
/\\([\\nrt"])/g,
|
|
403
|
+
(_, escaped) => STDIO_ENV_ESCAPE_REPLACEMENTS[escaped] ?? escaped
|
|
404
|
+
);
|
|
405
|
+
};
|
|
377
406
|
const parseStdioEnv = (raw) => {
|
|
378
407
|
if (!raw.trim()) return void 0;
|
|
379
408
|
const env = {};
|
|
380
409
|
for (const line of raw.split("\n")) {
|
|
381
410
|
const eq = line.indexOf("=");
|
|
382
411
|
if (eq > 0) {
|
|
383
|
-
env[line.slice(0, eq).trim()] = line.slice(eq + 1)
|
|
412
|
+
env[line.slice(0, eq).trim()] = parseStdioEnvValue(line.slice(eq + 1));
|
|
384
413
|
}
|
|
385
414
|
}
|
|
386
415
|
return Object.keys(env).length > 0 ? env : void 0;
|
|
@@ -395,7 +424,6 @@ function AddMcpSource(props) {
|
|
|
395
424
|
const exit = await doAdd({
|
|
396
425
|
params: { scopeId },
|
|
397
426
|
payload: {
|
|
398
|
-
targetScope: scopeId,
|
|
399
427
|
transport: "stdio",
|
|
400
428
|
name: displayName,
|
|
401
429
|
namespace: slugNamespace || void 0,
|
|
@@ -462,6 +490,7 @@ function AddMcpSource(props) {
|
|
|
462
490
|
targetScope: requestCredentialTargetScope,
|
|
463
491
|
credentialScopeOptions,
|
|
464
492
|
bindingScopeOptions: credentialScopeOptions,
|
|
493
|
+
headerPresets: mcpHeaderPresets,
|
|
465
494
|
labels: {
|
|
466
495
|
headers: "Request headers",
|
|
467
496
|
queryParams: "Query parameters"
|
|
@@ -548,84 +577,6 @@ function AddMcpSource(props) {
|
|
|
548
577
|
}
|
|
549
578
|
)
|
|
550
579
|
] }),
|
|
551
|
-
probe && /* @__PURE__ */ jsxs("section", { className: "space-y-2.5", children: [
|
|
552
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
553
|
-
/* @__PURE__ */ jsx(Label, { children: "Additional headers" }),
|
|
554
|
-
/* @__PURE__ */ jsx("p", { className: "mt-1 text-[12px] text-muted-foreground", children: "Plaintext headers sent with every request. Use request headers above for secret-backed values." })
|
|
555
|
-
] }),
|
|
556
|
-
/* @__PURE__ */ jsx(CardStack, { children: /* @__PURE__ */ jsx(CardStackContent, { children: remoteHeaders.length === 0 ? /* @__PURE__ */ jsx(
|
|
557
|
-
AddPlainHeaderRow,
|
|
558
|
-
{
|
|
559
|
-
leading: /* @__PURE__ */ jsx("span", { children: "No headers" }),
|
|
560
|
-
onClick: () => setRemoteHeaders((headers) => [...headers, { name: "", value: "" }])
|
|
561
|
-
}
|
|
562
|
-
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
563
|
-
remoteHeaders.map((header, index) => /* @__PURE__ */ jsxs(CardStackEntry, { className: "flex-col items-stretch gap-2", children: [
|
|
564
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
565
|
-
/* @__PURE__ */ jsx(Label, { className: "text-[10px] uppercase tracking-wider text-muted-foreground", children: "Header" }),
|
|
566
|
-
/* @__PURE__ */ jsx(
|
|
567
|
-
Button,
|
|
568
|
-
{
|
|
569
|
-
type: "button",
|
|
570
|
-
variant: "ghost",
|
|
571
|
-
size: "xs",
|
|
572
|
-
className: "text-muted-foreground hover:text-destructive",
|
|
573
|
-
onClick: () => setRemoteHeaders(
|
|
574
|
-
(headers) => headers.filter((_, headerIndex) => headerIndex !== index)
|
|
575
|
-
),
|
|
576
|
-
children: "Remove"
|
|
577
|
-
}
|
|
578
|
-
)
|
|
579
|
-
] }),
|
|
580
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
581
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
582
|
-
/* @__PURE__ */ jsx(Label, { className: "text-[10px] uppercase tracking-wider text-muted-foreground", children: "Name" }),
|
|
583
|
-
/* @__PURE__ */ jsx(
|
|
584
|
-
Input,
|
|
585
|
-
{
|
|
586
|
-
value: header.name,
|
|
587
|
-
onChange: (event) => setRemoteHeaders(
|
|
588
|
-
(headers) => headers.map(
|
|
589
|
-
(current, headerIndex) => headerIndex === index ? {
|
|
590
|
-
...current,
|
|
591
|
-
name: event.target.value
|
|
592
|
-
} : current
|
|
593
|
-
)
|
|
594
|
-
),
|
|
595
|
-
placeholder: "X-Organization-Id",
|
|
596
|
-
className: "h-8 text-xs font-mono"
|
|
597
|
-
}
|
|
598
|
-
)
|
|
599
|
-
] }),
|
|
600
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
601
|
-
/* @__PURE__ */ jsx(Label, { className: "text-[10px] uppercase tracking-wider text-muted-foreground", children: "Value" }),
|
|
602
|
-
/* @__PURE__ */ jsx(
|
|
603
|
-
Input,
|
|
604
|
-
{
|
|
605
|
-
value: header.value,
|
|
606
|
-
onChange: (event) => setRemoteHeaders(
|
|
607
|
-
(headers) => headers.map(
|
|
608
|
-
(current, headerIndex) => headerIndex === index ? {
|
|
609
|
-
...current,
|
|
610
|
-
value: event.target.value
|
|
611
|
-
} : current
|
|
612
|
-
)
|
|
613
|
-
),
|
|
614
|
-
placeholder: "workspace-id",
|
|
615
|
-
className: "h-8 text-xs font-mono"
|
|
616
|
-
}
|
|
617
|
-
)
|
|
618
|
-
] })
|
|
619
|
-
] })
|
|
620
|
-
] }, index)),
|
|
621
|
-
/* @__PURE__ */ jsx(
|
|
622
|
-
AddPlainHeaderRow,
|
|
623
|
-
{
|
|
624
|
-
onClick: () => setRemoteHeaders((headers) => [...headers, { name: "", value: "" }])
|
|
625
|
-
}
|
|
626
|
-
)
|
|
627
|
-
] }) }) })
|
|
628
|
-
] }),
|
|
629
580
|
otherError && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
630
581
|
/* @__PURE__ */ jsx("div", { className: "rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2", children: /* @__PURE__ */ jsx("p", { className: "text-[12px] text-destructive", children: otherError }) }),
|
|
631
582
|
/* @__PURE__ */ jsx(
|
|
@@ -732,31 +683,7 @@ function AddMcpSource(props) {
|
|
|
732
683
|
] })
|
|
733
684
|
] });
|
|
734
685
|
}
|
|
735
|
-
function AddPlainHeaderRow({
|
|
736
|
-
onClick,
|
|
737
|
-
leading
|
|
738
|
-
}) {
|
|
739
|
-
return (
|
|
740
|
-
// oxlint-disable-next-line react/forbid-elements
|
|
741
|
-
/* @__PURE__ */ jsxs(
|
|
742
|
-
"button",
|
|
743
|
-
{
|
|
744
|
-
type: "button",
|
|
745
|
-
onClick: (event) => {
|
|
746
|
-
event.stopPropagation();
|
|
747
|
-
onClick();
|
|
748
|
-
},
|
|
749
|
-
"aria-label": "Add header",
|
|
750
|
-
className: "flex w-full items-center justify-between gap-4 px-4 py-3 text-sm text-muted-foreground outline-none transition-[background-color] duration-150 ease-[cubic-bezier(0.23,1,0.32,1)] hover:bg-accent/40 focus-visible:bg-accent/40",
|
|
751
|
-
children: [
|
|
752
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 text-left", children: leading }),
|
|
753
|
-
/* @__PURE__ */ jsx("svg", { "aria-hidden": true, viewBox: "0 0 16 16", fill: "none", className: "size-4 shrink-0", children: /* @__PURE__ */ jsx("path", { d: "M8 3.5v9M3.5 8h9", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) })
|
|
754
|
-
]
|
|
755
|
-
}
|
|
756
|
-
)
|
|
757
|
-
);
|
|
758
|
-
}
|
|
759
686
|
export {
|
|
760
687
|
AddMcpSource as default
|
|
761
688
|
};
|
|
762
|
-
//# sourceMappingURL=AddMcpSource-
|
|
689
|
+
//# sourceMappingURL=AddMcpSource-3HUBFR3K.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/AddMcpSource.tsx"],"sourcesContent":["import { useReducer, useCallback, useEffect, useRef, useState } from \"react\";\nimport { useAtomSet } from \"@effect/atom-react\";\nimport * as Exit from \"effect/Exit\";\nimport * as Match from \"effect/Match\";\nimport * as Option from \"effect/Option\";\nimport * as Schema from \"effect/Schema\";\n\nimport { useScope } from \"@executor-js/react/api/scope-context\";\nimport { Button } from \"@executor-js/react/components/button\";\nimport {\n CardStack,\n CardStackContent,\n CardStackEntryField,\n} from \"@executor-js/react/components/card-stack\";\nimport { FieldLabel } from \"@executor-js/react/components/field\";\nimport { FilterTabs } from \"@executor-js/react/components/filter-tabs\";\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 emptyHttpCredentials,\n httpCredentialsValid,\n HttpCredentialsEditor,\n serializeConfigureHttpCredentials,\n serializeHttpCredentials,\n serializeTemplateHttpCredentials,\n} from \"@executor-js/react/plugins/http-credentials\";\nimport {\n sourceDisplayNameFromUrl,\n slugifyNamespace,\n SourceIdentityFields,\n useSourceIdentity,\n} from \"@executor-js/react/plugins/source-identity\";\nimport { useSecretPickerSecrets } from \"@executor-js/react/plugins/use-secret-picker-secrets\";\nimport {\n oauthCallbackUrl,\n oauthConnectionId,\n useOAuthPopupFlow,\n type OAuthCompletionPayload,\n} from \"@executor-js/react/plugins/oauth-sign-in\";\nimport {\n CredentialControlField,\n CredentialUsageRow,\n useCredentialTargetScope,\n} from \"@executor-js/react/plugins/credential-target-scope\";\nimport {\n defaultHeaderAuthPresets,\n type HeaderAuthPreset,\n} from \"@executor-js/react/plugins/secret-header-auth\";\n\ntype RemoteAuthMode = \"none\" | \"oauth2\";\nimport { sourceWriteKeys } from \"@executor-js/react/api/reactivity-keys\";\nimport { probeMcpEndpoint, addMcpSourceOptimistic } from \"./atoms\";\nimport { McpRemoteSourceFields } from \"./McpRemoteSourceFields\";\nimport { mcpPresets, type McpPreset } from \"../sdk/presets\";\nimport type { McpConfiguredValueInput, McpCredentialInput } from \"../sdk/types\";\n\nconst mcpHeaderPresets: readonly HeaderAuthPreset[] = [\n { key: \"text\", label: \"Plaintext header\", name: \"\", valueKind: \"text\" },\n ...defaultHeaderAuthPresets,\n];\n\nconst ErrorMessage = Schema.Struct({ message: Schema.String });\nconst decodeErrorMessage = Schema.decodeUnknownOption(ErrorMessage);\nconst STDIO_ENV_ESCAPE_REPLACEMENTS: Readonly<Record<string, string>> = {\n \"\\\\\": \"\\\\\",\n n: \"\\n\",\n r: \"\\r\",\n t: \"\\t\",\n '\"': '\"',\n};\n\nconst errorMessageFromExit = (exit: Exit.Exit<unknown, unknown>, fallback: string): string =>\n Option.match(Option.flatMap(Exit.findErrorOption(exit), decodeErrorMessage), {\n onNone: () => fallback,\n onSome: ({ message }) => message,\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 OAuthTokens = OAuthCompletionPayload;\n\ntype ProbeResult = {\n connected: boolean;\n requiresOAuth: boolean;\n supportsDynamicRegistration: boolean;\n name: string;\n namespace: string;\n toolCount: number | null;\n serverName: 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: \"oauth-starting\"; url: string; probe: ProbeResult }\n | {\n step: \"oauth-waiting\";\n url: string;\n probe: ProbeResult;\n sessionId: string;\n }\n | { step: \"oauth-done\"; url: string; probe: ProbeResult; tokens: OAuthTokens }\n | {\n step: \"adding\";\n url: string;\n probe: ProbeResult;\n tokens: OAuthTokens | null;\n }\n | {\n step: \"error\";\n url: string;\n probe: ProbeResult | null;\n tokens: OAuthTokens | 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: \"oauth-start\" }\n | { type: \"oauth-waiting\"; sessionId: string }\n | { type: \"oauth-ok\"; tokens: OAuthTokens }\n | { type: \"oauth-fail\"; error: string }\n | { type: \"oauth-cancelled\" }\n | { type: \"oauth-reset\" }\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 tokens: null,\n error: a.error,\n }),\n ),\n Match.discriminator(\"type\")(\"oauth-start\", (): State => {\n if (state.step !== \"probed\" && state.step !== \"error\") return state;\n return {\n step: \"oauth-starting\",\n url: state.url,\n probe: state.step === \"probed\" ? state.probe : state.probe!,\n };\n }),\n Match.discriminator(\"type\")(\"oauth-waiting\", (a): State => {\n if (state.step !== \"oauth-starting\") return state;\n return {\n step: \"oauth-waiting\",\n url: state.url,\n probe: state.probe,\n sessionId: a.sessionId,\n };\n }),\n Match.discriminator(\"type\")(\"oauth-ok\", (a): State => {\n if (state.step !== \"oauth-waiting\") return state;\n return {\n step: \"oauth-done\",\n url: state.url,\n probe: state.probe,\n tokens: a.tokens,\n };\n }),\n Match.discriminator(\"type\")(\"oauth-fail\", (a): State => {\n if (state.step !== \"oauth-starting\" && state.step !== \"oauth-waiting\") return state;\n return {\n step: \"error\",\n url: state.url,\n probe: state.probe,\n tokens: null,\n error: a.error,\n };\n }),\n Match.discriminator(\"type\")(\"oauth-cancelled\", (): State => {\n if (state.step !== \"oauth-waiting\") return state;\n return { step: \"probed\", url: state.url, probe: state.probe };\n }),\n Match.discriminator(\"type\")(\"oauth-reset\", (): State => {\n if (\"probe\" in state && state.probe) {\n return { step: \"probed\", url: state.url, probe: state.probe };\n }\n return state;\n }),\n Match.discriminator(\"type\")(\"add-start\", (): State => {\n const tokens =\n state.step === \"oauth-done\" ? state.tokens : state.step === \"probed\" ? null : null;\n const probe = \"probe\" in state ? state.probe : null;\n if (!probe) return state;\n return { step: \"adding\", url: state.url, probe, tokens };\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 tokens: state.tokens,\n error: a.error,\n };\n }),\n Match.discriminator(\"type\")(\"retry\", (): State => {\n if (state.step !== \"error\") return state;\n return state.probe\n ? state.tokens\n ? {\n step: \"oauth-done\",\n url: state.url,\n probe: state.probe,\n tokens: state.tokens,\n }\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: () => 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 = useSourceIdentity({\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 scopeId = useScope();\n const { credentialTargetScope: requestCredentialTargetScope } = useCredentialTargetScope();\n const {\n credentialTargetScope: oauthCredentialTargetScope,\n setCredentialTargetScope: setOAuthCredentialTargetScope,\n credentialScopeOptions,\n } = useCredentialTargetScope();\n const doProbe = useAtomSet(probeMcpEndpoint, { mode: \"promiseExit\" });\n const doAdd = useAtomSet(addMcpSourceOptimistic(scopeId), {\n mode: \"promiseExit\",\n });\n const secretList = useSecretPickerSecrets();\n const oauth = useOAuthPopupFlow<OAuthCompletionPayload>({\n popupName: \"mcp-oauth\",\n popupBlockedMessage: \"OAuth popup was blocked\",\n detectPopupClosed: false,\n startErrorMessage: \"Failed to start OAuth\",\n });\n\n const [remoteAuthMode, setRemoteAuthMode] = useState<RemoteAuthMode>(\"none\");\n const [remoteCredentials, setRemoteCredentials] = useState(() => emptyHttpCredentials());\n\n const probe = \"probe\" in state ? state.probe : null;\n const tokens = \"tokens\" in state ? state.tokens : null;\n\n const remoteIdentity = useSourceIdentity({\n fallbackName:\n sourceDisplayNameFromUrl(state.url, \"MCP\") ?? probe?.serverName ?? probe?.name ?? \"\",\n });\n const isProbing = state.step === \"probing\";\n const isAdding = state.step === \"adding\";\n const isOAuthBusy =\n state.step === \"oauth-starting\" || state.step === \"oauth-waiting\" || oauth.busy;\n const canUseNone = probe?.requiresOAuth !== true || probe.supportsDynamicRegistration === false;\n const remoteCredentialsComplete = httpCredentialsValid(remoteCredentials);\n const authReady = remoteAuthMode === \"none\" ? canUseNone : tokens !== null;\n const canAdd =\n Boolean(probe) && authReady && remoteCredentialsComplete && !isAdding && !isOAuthBusy;\n // Probe failures are shown inline on the URL field; other failures\n // (OAuth start, add source) 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 { headers, queryParams } = serializeHttpCredentials(remoteCredentials);\n const exit = await doProbe({\n params: { scopeId },\n payload: {\n endpoint: state.url.trim(),\n ...(Object.keys(headers).length > 0 ? { headers } : {}),\n ...(Object.keys(queryParams).length > 0 ? { queryParams } : {}),\n },\n });\n if (Exit.isFailure(exit)) {\n dispatch({\n type: \"probe-fail\",\n error: errorMessageFromExit(exit, \"Failed to connect\"),\n });\n return;\n }\n setRemoteAuthMode(exit.value.requiresOAuth ? \"oauth2\" : \"none\");\n dispatch({ type: \"probe-ok\", probe: exit.value });\n }, [state.url, scopeId, doProbe, remoteCredentials]);\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 const handleRemoteCredentialsChange = useCallback((next: typeof remoteCredentials) => {\n setRemoteCredentials(next);\n }, []);\n\n const handleOAuth = useCallback(async () => {\n dispatch({ type: \"oauth-start\" });\n const namespaceSlug =\n slugifyNamespace(remoteIdentity.namespace) ||\n slugifyNamespace(probe?.namespace ?? \"\") ||\n \"mcp\";\n const { headers, queryParams } = serializeHttpCredentials(remoteCredentials);\n await oauth.start({\n payload: {\n endpoint: state.url.trim(),\n ...(Object.keys(headers).length > 0 ? { headers } : {}),\n ...(Object.keys(queryParams).length > 0 ? { queryParams } : {}),\n redirectUrl: oauthCallbackUrl(),\n connectionId: oauthConnectionId({\n pluginId: \"mcp\",\n namespace: namespaceSlug,\n }),\n tokenScope: oauthCredentialTargetScope,\n strategy: { kind: \"dynamic-dcr\" },\n pluginId: \"mcp\",\n identityLabel: `${remoteIdentity.name.trim() || probe?.serverName || probe?.name || \"MCP\"} OAuth`,\n },\n onSuccess: (result) => {\n dispatch({\n type: \"oauth-ok\",\n tokens: {\n connectionId: result.connectionId,\n expiresAt: result.expiresAt,\n scope: result.scope,\n },\n });\n },\n onAuthorizationStarted: (result) =>\n dispatch({ type: \"oauth-waiting\", sessionId: result.sessionId }),\n onError: (error) => dispatch({ type: \"oauth-fail\", error }),\n });\n }, [state.url, remoteIdentity, probe, remoteCredentials, oauth, oauthCredentialTargetScope]);\n\n const handleCancelOAuth = useCallback(() => {\n oauth.cancel();\n dispatch({ type: \"oauth-cancelled\" });\n }, [oauth]);\n\n const handleAddRemote = useCallback(async () => {\n if (!probe) return;\n dispatch({ type: \"add-start\" });\n const templateCredentials = serializeTemplateHttpCredentials(remoteCredentials);\n const configureCredentials = serializeConfigureHttpCredentials(\n remoteCredentials,\n requestCredentialTargetScope,\n );\n const remoteRequestHeaders = templateCredentials.headers as Record<\n string,\n McpConfiguredValueInput\n >;\n const hasInitialCredentials =\n Object.keys(configureCredentials.headers).length > 0 ||\n Object.keys(configureCredentials.queryParams).length > 0 ||\n (remoteAuthMode === \"oauth2\" && tokens);\n const displayName = remoteIdentity.name.trim() || probe.serverName || probe.name;\n const slugNamespace = slugifyNamespace(remoteIdentity.namespace);\n const exit = await doAdd({\n params: { scopeId },\n payload: {\n transport: \"remote\" as const,\n name: displayName,\n namespace: slugNamespace || undefined,\n endpoint: state.url.trim(),\n ...(Object.keys(remoteRequestHeaders).length > 0 ? { headers: remoteRequestHeaders } : {}),\n ...(Object.keys(templateCredentials.queryParams).length > 0\n ? {\n queryParams: templateCredentials.queryParams as Record<\n string,\n McpConfiguredValueInput\n >,\n }\n : {}),\n ...(hasInitialCredentials\n ? {\n credentials: {\n scope: requestCredentialTargetScope,\n ...(Object.keys(configureCredentials.headers).length > 0\n ? {\n headers: configureCredentials.headers as Record<string, McpCredentialInput>,\n }\n : {}),\n ...(Object.keys(configureCredentials.queryParams).length > 0\n ? {\n queryParams: configureCredentials.queryParams as Record<\n string,\n McpCredentialInput\n >,\n }\n : {}),\n ...(remoteAuthMode === \"oauth2\" && tokens\n ? {\n auth: {\n oauth2: {\n connection: {\n kind: \"connection\" as const,\n connectionId: tokens.connectionId,\n },\n },\n },\n }\n : {}),\n },\n }\n : {}),\n },\n reactivityKeys: sourceWriteKeys,\n });\n if (Exit.isFailure(exit)) {\n dispatch({\n type: \"add-fail\",\n error: errorMessageFromExit(exit, \"Failed to add source\"),\n });\n return;\n }\n props.onComplete();\n }, [\n probe,\n remoteAuthMode,\n remoteCredentials,\n remoteIdentity,\n tokens,\n state.url,\n doAdd,\n props,\n scopeId,\n requestCredentialTargetScope,\n ]);\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 slugNamespace = slugifyNamespace(stdioIdentity.namespace);\n const exit = await doAdd({\n params: { scopeId },\n payload: {\n transport: \"stdio\" as const,\n name: displayName,\n namespace: slugNamespace || undefined,\n command: cmd,\n args: parseStdioArgs(stdioArgs),\n env: parseStdioEnv(stdioEnv),\n },\n reactivityKeys: sourceWriteKeys,\n });\n if (Exit.isFailure(exit)) {\n setStdioError(errorMessageFromExit(exit, \"Failed to add source\"));\n setStdioAdding(false);\n return;\n }\n props.onComplete();\n }, [stdioCommand, stdioArgs, stdioEnv, stdioIdentity, doAdd, scopeId, 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 preview={probe}\n probing={isProbing}\n error={probeError}\n onRetry={handleProbe}\n />\n\n <HttpCredentialsEditor\n credentials={remoteCredentials}\n onChange={handleRemoteCredentialsChange}\n existingSecrets={secretList}\n sourceName={remoteIdentity.name}\n targetScope={requestCredentialTargetScope}\n credentialScopeOptions={credentialScopeOptions}\n bindingScopeOptions={credentialScopeOptions}\n headerPresets={mcpHeaderPresets}\n labels={{\n headers: \"Request headers\",\n queryParams: \"Query parameters\",\n }}\n />\n\n {/* Authentication */}\n {probe && (\n <section className=\"space-y-2.5\">\n <div className=\"flex items-center justify-between gap-3\">\n <FieldLabel>Authentication</FieldLabel>\n <FilterTabs<RemoteAuthMode>\n tabs={\n probe.requiresOAuth && probe.supportsDynamicRegistration\n ? [{ value: \"oauth2\", label: \"OAuth\" }]\n : [\n { value: \"none\", label: \"None\" },\n { value: \"oauth2\", label: \"OAuth\" },\n ]\n }\n value={remoteAuthMode}\n onChange={setRemoteAuthMode}\n />\n </div>\n\n {remoteAuthMode === \"oauth2\" && (\n <CredentialUsageRow\n value={oauthCredentialTargetScope}\n options={credentialScopeOptions}\n onChange={(targetScope) => {\n setOAuthCredentialTargetScope(targetScope);\n dispatch({ type: \"oauth-reset\" });\n }}\n label=\"Connection saved to\"\n help=\"Choose who can use the OAuth connection.\"\n >\n <CredentialControlField\n label=\"Connect via OAuth\"\n help=\"Start the provider OAuth flow.\"\n >\n {!tokens &&\n state.step === \"probed\" &&\n (probe.supportsDynamicRegistration ? (\n <Button\n type=\"button\"\n onClick={handleOAuth}\n variant=\"outline\"\n className=\"w-full\"\n >\n Sign in\n </Button>\n ) : (\n <div className=\"rounded-md border border-border bg-muted/30 px-3 py-2 text-xs text-muted-foreground\">\n This server requires OAuth, but its authorization server does not support\n dynamic client registration. Use request headers with a bearer token, or\n save the source and connect a supported OAuth connection later.\n </div>\n ))}\n\n {!tokens && state.step === \"oauth-starting\" && (\n <div className=\"flex min-h-9 items-center gap-2 rounded-md border border-border bg-muted/30 px-3 py-2\">\n <Spinner className=\"size-3.5\" />\n <span className=\"text-xs text-muted-foreground\">\n Starting authorization...\n </span>\n </div>\n )}\n\n {!tokens && state.step === \"oauth-waiting\" && (\n <div className=\"flex min-h-9 items-center gap-2 rounded-md border border-blue-500/30 bg-blue-500/5 px-3 py-2\">\n <Spinner className=\"size-3.5 text-blue-500\" />\n <span className=\"text-xs text-blue-600 dark:text-blue-400\">\n Waiting for authorization...\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleCancelOAuth}\n className=\"ml-auto h-7 px-2 text-xs\"\n >\n Cancel\n </Button>\n </div>\n )}\n\n {tokens && (\n <div className=\"flex min-h-9 items-center gap-2 rounded-md border border-emerald-500/30 bg-emerald-500/5 px-3 py-2\">\n <svg viewBox=\"0 0 16 16\" fill=\"none\" className=\"size-3.5 text-emerald-500\">\n <path\n d=\"M3 8.5l3 3 7-7\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n <span className=\"text-xs font-medium text-emerald-600 dark:text-emerald-400\">\n Authenticated\n </span>\n </div>\n )}\n </CredentialControlField>\n </CredentialUsageRow>\n )}\n </section>\n )}\n\n {/* Error (OAuth / add source). Probe errors show inline on the field. */}\n {otherError && (\n <div className=\"space-y-2\">\n <div className=\"rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2\">\n <p className=\"text-[12px] text-destructive\">{otherError}</p>\n </div>\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 <FloatActions>\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={() => {\n oauth.cancel();\n props.onCancel();\n }}\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 <SourceIdentityFields identity={stdioIdentity} namePlaceholder=\"My MCP Server\" />\n\n {/* Stdio error */}\n {stdioError && (\n <div className=\"rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2\">\n <p className=\"text-[12px] text-destructive\">{stdioError}</p>\n </div>\n )}\n\n <FloatActions>\n <Button type=\"button\" variant=\"ghost\" onClick={props.onCancel} disabled={stdioAdding}>\n Cancel\n </Button>\n <Button\n type=\"button\"\n onClick={handleAddStdio}\n disabled={!stdioCommand.trim() || stdioAdding}\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"],"mappings":"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","names":["match","value"]}
|