@executor-js/plugin-mcp 1.5.11 → 1.5.12
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-ZDNQ7F6I.js → AddMcpSource-HCJNPYGW.js} +25 -5
- package/dist/AddMcpSource-HCJNPYGW.js.map +1 -0
- package/dist/{EditMcpSource-75NJRWZR.js → EditMcpSource-BV5ZEWEY.js} +41 -60
- package/dist/EditMcpSource-BV5ZEWEY.js.map +1 -0
- package/dist/{McpAccountsPanel-QBCSCJE7.js → McpAccountsPanel-Y3D6HSPC.js} +2 -2
- package/dist/api/group.d.ts +5 -0
- package/dist/api/index.d.ts +6 -0
- package/dist/{chunk-3AOD4VAW.js → chunk-AL7N323J.js} +7 -2
- package/dist/chunk-AL7N323J.js.map +1 -0
- package/dist/{chunk-6BJ6MZF7.js → chunk-QAG34CWT.js} +20 -8
- package/dist/chunk-QAG34CWT.js.map +1 -0
- package/dist/client.js +6 -6
- package/dist/client.js.map +1 -1
- package/dist/core.js +1 -1
- package/dist/index.js +1 -1
- package/dist/react/EditMcpSource.d.ts +2 -4
- package/dist/react/McpRemoteSourceFields.d.ts +4 -0
- package/dist/react/atoms.d.ts +3 -0
- package/dist/react/client.d.ts +3 -0
- package/dist/sdk/manifest.d.ts +3 -0
- package/dist/sdk/plugin.d.ts +12 -0
- package/package.json +3 -3
- package/dist/AddMcpSource-ZDNQ7F6I.js.map +0 -1
- package/dist/EditMcpSource-75NJRWZR.js.map +0 -1
- package/dist/chunk-3AOD4VAW.js.map +0 -1
- package/dist/chunk-6BJ6MZF7.js.map +0 -1
- /package/dist/{McpAccountsPanel-QBCSCJE7.js.map → McpAccountsPanel-Y3D6HSPC.js.map} +0 -0
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
mcpAuthMethodInputFromEditorValue,
|
|
7
7
|
mcpWireAuthInput,
|
|
8
8
|
probeMcpEndpoint
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-AL7N323J.js";
|
|
10
10
|
import "./chunk-3H5Y7JCQ.js";
|
|
11
11
|
|
|
12
12
|
// src/react/AddMcpSource.tsx
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
import { FloatActions } from "@executor-js/react/components/float-actions";
|
|
28
28
|
import { Input as Input2 } from "@executor-js/react/components/input";
|
|
29
29
|
import { Spinner } from "@executor-js/react/components/spinner";
|
|
30
|
-
import { Textarea } from "@executor-js/react/components/textarea";
|
|
30
|
+
import { Textarea as Textarea2 } from "@executor-js/react/components/textarea";
|
|
31
31
|
import {
|
|
32
32
|
integrationDisplayNameFromUrl,
|
|
33
33
|
slugifyNamespace,
|
|
@@ -58,6 +58,7 @@ import {
|
|
|
58
58
|
} from "@executor-js/react/components/card-stack";
|
|
59
59
|
import { FieldError } from "@executor-js/react/components/field";
|
|
60
60
|
import { Input } from "@executor-js/react/components/input";
|
|
61
|
+
import { Textarea } from "@executor-js/react/components/textarea";
|
|
61
62
|
import { Skeleton } from "@executor-js/react/components/skeleton";
|
|
62
63
|
import { IntegrationFavicon } from "@executor-js/react/components/integration-favicon";
|
|
63
64
|
import { IOSSpinner } from "@executor-js/react/components/spinner";
|
|
@@ -107,6 +108,20 @@ function McpRemoteSourceFields(props) {
|
|
|
107
108
|
namespaceReadOnly: props.namespaceReadOnly
|
|
108
109
|
}
|
|
109
110
|
),
|
|
111
|
+
props.onDescriptionChange && /* @__PURE__ */ jsxs(CardStackEntryField, { label: "Description", children: [
|
|
112
|
+
/* @__PURE__ */ jsx(
|
|
113
|
+
Textarea,
|
|
114
|
+
{
|
|
115
|
+
value: props.description ?? "",
|
|
116
|
+
onChange: (e) => props.onDescriptionChange?.(e.target.value),
|
|
117
|
+
placeholder: "What this server offers and when to reach for it",
|
|
118
|
+
rows: 2,
|
|
119
|
+
maxRows: 6,
|
|
120
|
+
className: "text-sm"
|
|
121
|
+
}
|
|
122
|
+
),
|
|
123
|
+
/* @__PURE__ */ jsx("p", { className: "text-[11px] text-muted-foreground", children: "Agent-visible. Prefilled from the server's instructions when it sends any." })
|
|
124
|
+
] }),
|
|
110
125
|
/* @__PURE__ */ jsx(CardStackEntryField, { label: "Server URL", children: /* @__PURE__ */ jsx(
|
|
111
126
|
Input,
|
|
112
127
|
{
|
|
@@ -273,6 +288,8 @@ function AddMcpSource(props) {
|
|
|
273
288
|
const remoteIdentity = useIntegrationIdentity({
|
|
274
289
|
fallbackName: integrationDisplayNameFromUrl(state.url, "MCP") ?? probe?.serverName ?? probe?.name ?? ""
|
|
275
290
|
});
|
|
291
|
+
const [descriptionDraft, setDescriptionDraft] = useState(null);
|
|
292
|
+
const resolvedDescription = descriptionDraft ?? probe?.instructions ?? "";
|
|
276
293
|
const isProbing = state.step === "probing";
|
|
277
294
|
const isAdding = state.step === "adding";
|
|
278
295
|
const remoteSlug = slugifyNamespace(remoteIdentity.namespace);
|
|
@@ -316,6 +333,7 @@ function AddMcpSource(props) {
|
|
|
316
333
|
payload: {
|
|
317
334
|
transport: "remote",
|
|
318
335
|
name: displayName,
|
|
336
|
+
...resolvedDescription.trim().length > 0 ? { description: resolvedDescription.trim() } : {},
|
|
319
337
|
endpoint: state.url.trim(),
|
|
320
338
|
...slug ? { slug } : {},
|
|
321
339
|
authenticationTemplate
|
|
@@ -331,7 +349,7 @@ function AddMcpSource(props) {
|
|
|
331
349
|
}
|
|
332
350
|
return exit.value.slug;
|
|
333
351
|
},
|
|
334
|
-
[doAddServer, probe, remoteIdentity, state.url]
|
|
352
|
+
[doAddServer, probe, remoteIdentity, resolvedDescription, state.url]
|
|
335
353
|
);
|
|
336
354
|
const handleAddRemote = useCallback(async () => {
|
|
337
355
|
if (!probe) return;
|
|
@@ -439,6 +457,8 @@ function AddMcpSource(props) {
|
|
|
439
457
|
url: state.url,
|
|
440
458
|
onUrlChange: (url) => dispatch({ type: "set-url", url }),
|
|
441
459
|
identity: remoteIdentity,
|
|
460
|
+
description: resolvedDescription,
|
|
461
|
+
onDescriptionChange: setDescriptionDraft,
|
|
442
462
|
preview: probe,
|
|
443
463
|
probing: isProbing,
|
|
444
464
|
error: probeError,
|
|
@@ -526,7 +546,7 @@ function AddMcpSource(props) {
|
|
|
526
546
|
label: "Environment variables",
|
|
527
547
|
description: "- One per line, KEY=value format.",
|
|
528
548
|
children: /* @__PURE__ */ jsx2(
|
|
529
|
-
|
|
549
|
+
Textarea2,
|
|
530
550
|
{
|
|
531
551
|
value: stdioEnv,
|
|
532
552
|
onChange: (e) => setStdioEnv(e.target.value),
|
|
@@ -572,4 +592,4 @@ function AddMcpSource(props) {
|
|
|
572
592
|
export {
|
|
573
593
|
AddMcpSource as default
|
|
574
594
|
};
|
|
575
|
-
//# sourceMappingURL=AddMcpSource-
|
|
595
|
+
//# sourceMappingURL=AddMcpSource-HCJNPYGW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/AddMcpSource.tsx","../src/react/McpRemoteSourceFields.tsx"],"sourcesContent":["import { useReducer, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useAtomSet } from \"@effect/atom-react\";\nimport * as Exit from \"effect/Exit\";\nimport * as Match from \"effect/Match\";\n\nimport { Button } from \"@executor-js/react/components/button\";\nimport {\n AuthMethodListEditor,\n useAuthMethodList,\n type AuthMethodRow,\n type AuthMethodSeed,\n} from \"@executor-js/react/components/auth-method-list-editor\";\nimport {\n CardStack,\n CardStackContent,\n CardStackEntryField,\n} from \"@executor-js/react/components/card-stack\";\nimport { FloatActions } from \"@executor-js/react/components/float-actions\";\nimport { Input } from \"@executor-js/react/components/input\";\nimport { Spinner } from \"@executor-js/react/components/spinner\";\nimport { Textarea } from \"@executor-js/react/components/textarea\";\nimport {\n integrationDisplayNameFromUrl,\n slugifyNamespace,\n IntegrationIdentityFields,\n useIntegrationIdentity,\n} from \"@executor-js/react/plugins/integration-identity\";\nimport {\n addIntegrationErrorMessage,\n errorMessageFromExit,\n FormErrorAlert,\n SlugCollisionAlert,\n useSlugAlreadyExists,\n} from \"@executor-js/react/lib/integration-add\";\n\nimport { integrationWriteKeys } from \"@executor-js/react/api/reactivity-keys\";\nimport type { McpAuthMethodInput } from \"../sdk/types\";\nimport { probeMcpEndpoint, addMcpServer } from \"./atoms\";\nimport { McpRemoteSourceFields } from \"./McpRemoteSourceFields\";\nimport { mcpAuthMethodInputFromEditorValue, mcpWireAuthInput } from \"./auth-method-config\";\nimport { mcpPresets, type McpPreset } from \"../sdk/presets\";\n\n// The remote add flow REGISTERS the server's declared auth methods through the\n// shared `AuthMethodListEditor` — accounts (the API key value / OAuth sign-in)\n// are added later from the integration's detail hub (P6: add without auth,\n// connect later). The probe SEEDS the list (detected OAuth → an OAuth row; a\n// 401 without OAuth → a bearer-header row; open server → a no-auth row) and\n// the user can add alternate methods (e.g. an API key alongside OAuth, or a\n// declared method on a server that advertises none).\n\nconst STDIO_ENV_ESCAPE_REPLACEMENTS: Readonly<Record<string, string>> = {\n \"\\\\\": \"\\\\\",\n n: \"\\n\",\n r: \"\\r\",\n t: \"\\t\",\n '\"': '\"',\n};\n\n// ---------------------------------------------------------------------------\n// Preset lookup\n// ---------------------------------------------------------------------------\n\nfunction findPreset(id: string | undefined): McpPreset | undefined {\n if (!id) return undefined;\n return mcpPresets.find((p) => p.id === id);\n}\n\n// ---------------------------------------------------------------------------\n// State machine (remote flow)\n// ---------------------------------------------------------------------------\n\ntype ProbeResult = {\n connected: boolean;\n requiresAuthentication: boolean;\n requiresOAuth: boolean;\n supportsDynamicRegistration: boolean;\n name: string;\n slug: string;\n toolCount: number | null;\n serverName: string | null;\n instructions: string | null;\n};\n\ntype State =\n | { step: \"url\"; url: string }\n | { step: \"probing\"; url: string; probe: ProbeResult | null }\n | { step: \"probed\"; url: string; probe: ProbeResult }\n | { step: \"adding\"; url: string; probe: ProbeResult }\n | {\n step: \"error\";\n url: string;\n probe: ProbeResult | null;\n error: string;\n };\n\ntype Action =\n | { type: \"set-url\"; url: string }\n | { type: \"probe-start\" }\n | { type: \"probe-ok\"; probe: ProbeResult }\n | { type: \"probe-fail\"; error: string }\n | { type: \"add-start\" }\n | { type: \"add-fail\"; error: string }\n | { type: \"retry\" };\n\nconst init: State = { step: \"url\", url: \"\" };\n\nfunction reducer(state: State, action: Action): State {\n return Match.value(action).pipe(\n Match.discriminator(\"type\")(\"set-url\", (a): State => ({ step: \"url\", url: a.url })),\n Match.discriminator(\"type\")(\n \"probe-start\",\n (): State => ({\n step: \"probing\",\n url: state.url,\n probe: \"probe\" in state ? state.probe : null,\n }),\n ),\n Match.discriminator(\"type\")(\n \"probe-ok\",\n (a): State => ({ step: \"probed\", url: state.url, probe: a.probe }),\n ),\n Match.discriminator(\"type\")(\n \"probe-fail\",\n (a): State => ({\n step: \"error\",\n url: state.url,\n probe: null,\n error: a.error,\n }),\n ),\n Match.discriminator(\"type\")(\"add-start\", (): State => {\n const probe = \"probe\" in state ? state.probe : null;\n if (!probe) return state;\n return { step: \"adding\", url: state.url, probe };\n }),\n Match.discriminator(\"type\")(\"add-fail\", (a): State => {\n if (state.step !== \"adding\") return state;\n return {\n step: \"error\",\n url: state.url,\n probe: state.probe,\n error: a.error,\n };\n }),\n Match.discriminator(\"type\")(\"retry\", (): State => {\n if (state.step !== \"error\") return state;\n return state.probe\n ? { step: \"probed\", url: state.url, probe: state.probe }\n : { step: \"url\", url: state.url };\n }),\n Match.exhaustive,\n );\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport default function AddMcpSource(props: {\n onComplete: (slug?: string) => void;\n onCancel: () => void;\n initialUrl?: string;\n initialPreset?: string;\n /** Whether the stdio transport is enabled on the server. */\n allowStdio?: boolean;\n}) {\n const allowStdio = props.allowStdio ?? false;\n const rawPreset = findPreset(props.initialPreset);\n // Drop stdio presets when stdio is disabled — the caller should have\n // already filtered these out, but defence-in-depth.\n const preset = rawPreset?.transport === \"stdio\" && !allowStdio ? undefined : rawPreset;\n const isStdioPreset = preset?.transport === \"stdio\";\n\n const [transport, setTransport] = useState<\"remote\" | \"stdio\">(\n isStdioPreset && allowStdio ? \"stdio\" : \"remote\",\n );\n\n // --- Stdio state ---\n const [stdioCommand, setStdioCommand] = useState(isStdioPreset ? preset.command : \"\");\n const [stdioArgs, setStdioArgs] = useState(\n isStdioPreset && preset.args ? preset.args.join(\" \") : \"\",\n );\n const [stdioEnv, setStdioEnv] = useState(\"\");\n const stdioIdentity = useIntegrationIdentity({\n fallbackName: isStdioPreset ? preset.name : stdioCommand,\n });\n const [stdioAdding, setStdioAdding] = useState(false);\n const [stdioError, setStdioError] = useState<string | null>(null);\n\n // --- Remote state ---\n const remoteUrl =\n !isStdioPreset && preset?.transport === undefined && preset?.url\n ? preset.url\n : (props.initialUrl ?? \"\");\n\n const [state, dispatch] = useReducer(\n reducer,\n remoteUrl ? { step: \"url\" as const, url: remoteUrl } : init,\n );\n\n const doProbe = useAtomSet(probeMcpEndpoint, { mode: \"promiseExit\" });\n const doAddServer = useAtomSet(addMcpServer, { mode: \"promiseExit\" });\n\n const probe = \"probe\" in state ? state.probe : null;\n\n // The probe seeds the method list: detected OAuth → an OAuth row; a 401\n // without OAuth metadata → a bearer-header row; an open server → a no-auth\n // row. The user can edit any row or add alternate methods alongside.\n const authMethodSeeds: readonly AuthMethodSeed[] = useMemo(() => {\n if (!probe) return [];\n if (probe.requiresOAuth) {\n return [\n {\n value: { kind: \"oauth\", authorizationUrl: \"\", tokenUrl: \"\", scopes: [] },\n label: \"Detected\",\n },\n ];\n }\n if (probe.requiresAuthentication) {\n return [\n {\n value: {\n kind: \"apikey\",\n placements: [{ carrier: \"header\", name: \"Authorization\", prefix: \"Bearer \" }],\n },\n label: \"Detected\",\n },\n ];\n }\n return [{ value: { kind: \"none\" }, label: \"Detected\" }];\n }, [probe]);\n const authMethodList = useAuthMethodList(authMethodSeeds);\n\n const remoteIdentity = useIntegrationIdentity({\n fallbackName:\n integrationDisplayNameFromUrl(state.url, \"MCP\") ?? probe?.serverName ?? probe?.name ?? \"\",\n });\n // Agent-visible description: prefilled from the server's `instructions`\n // until the user types (null = untouched, keep deriving from the probe).\n const [descriptionDraft, setDescriptionDraft] = useState<string | null>(null);\n const resolvedDescription = descriptionDraft ?? probe?.instructions ?? \"\";\n const isProbing = state.step === \"probing\";\n const isAdding = state.step === \"adding\";\n\n // Pre-empt the API's `IntegrationAlreadyExistsError`: adding an integration\n // whose slug already exists clobbers the existing one's connections/policies,\n // so the API blocks it. Surface that here from the tenant-scoped catalog list.\n // A blank derived namespace lets the server assign the slug, so only flag a\n // collision when the user-derived slug is non-empty.\n const remoteSlug = slugifyNamespace(remoteIdentity.namespace);\n const stdioSlug = slugifyNamespace(stdioIdentity.namespace);\n const remoteSlugExists = useSlugAlreadyExists(remoteSlug);\n const stdioSlugExists = useSlugAlreadyExists(stdioSlug);\n\n const canAdd = Boolean(probe) && !isAdding && !remoteSlugExists;\n // Probe failures are shown inline on the URL field; other failures\n // (add server) render in the bottom error block.\n const probeError = state.step === \"error\" && state.probe === null ? state.error : null;\n const otherError = state.step === \"error\" && state.probe !== null ? state.error : null;\n\n // ---- Remote actions ----\n\n const handleProbe = useCallback(async () => {\n dispatch({ type: \"probe-start\" });\n const exit = await doProbe({\n payload: { endpoint: state.url.trim() },\n });\n if (Exit.isFailure(exit)) {\n dispatch({\n type: \"probe-fail\",\n error: errorMessageFromExit(exit, \"Failed to connect\"),\n });\n return;\n }\n dispatch({ type: \"probe-ok\", probe: exit.value });\n }, [state.url, doProbe]);\n\n // Keep the latest handleProbe in a ref so the debounced effect can call it\n // without depending on its identity (which changes every render).\n const handleProbeRef = useRef(handleProbe);\n handleProbeRef.current = handleProbe;\n\n // Auto-probe whenever the URL changes (debounced) while we're on the\n // remote transport and not already probing/probed.\n useEffect(() => {\n if (transport !== \"remote\") return;\n if (state.step !== \"url\") return;\n const trimmed = state.url.trim();\n if (!trimmed) return;\n const handle = setTimeout(() => {\n handleProbeRef.current();\n }, 400);\n return () => clearTimeout(handle);\n }, [transport, state.step, state.url]);\n\n // Register the integration with the declared auth methods, returning the\n // assigned slug (or null on failure — an error is dispatched in that case).\n const registerIntegration = useCallback(\n async (authenticationTemplate: readonly McpAuthMethodInput[]): Promise<string | null> => {\n const displayName = remoteIdentity.name.trim() || probe?.serverName || probe?.name || \"MCP\";\n const slug = slugifyNamespace(remoteIdentity.namespace) || undefined;\n const exit = await doAddServer({\n payload: {\n transport: \"remote\" as const,\n name: displayName,\n ...(resolvedDescription.trim().length > 0\n ? { description: resolvedDescription.trim() }\n : {}),\n endpoint: state.url.trim(),\n ...(slug ? { slug } : {}),\n authenticationTemplate,\n },\n reactivityKeys: integrationWriteKeys,\n });\n if (Exit.isFailure(exit)) {\n dispatch({\n type: \"add-fail\",\n error: addIntegrationErrorMessage(exit, slug ?? displayName, \"Failed to add server\"),\n });\n return null;\n }\n return exit.value.slug;\n },\n [doAddServer, probe, remoteIdentity, resolvedDescription, state.url],\n );\n\n const handleAddRemote = useCallback(async () => {\n if (!probe) return;\n dispatch({ type: \"add-start\" });\n // Every row registers as a declared method (a lone no-auth row registers\n // the open-server method). Slugs are assigned server-side by kind.\n const methods = authMethodList.rows.map((row: AuthMethodRow) =>\n mcpWireAuthInput(mcpAuthMethodInputFromEditorValue(row.value)),\n );\n const slug = await registerIntegration(\n methods.length > 0 ? methods : [{ kind: \"none\" as const }],\n );\n if (slug === null) return;\n props.onComplete(slug);\n }, [probe, authMethodList.rows, registerIntegration, props]);\n\n // ---- Stdio actions ----\n\n const parseStdioArgs = (raw: string): string[] => {\n if (!raw.trim()) return [];\n const args: string[] = [];\n const regex = /[^\\s\"]+|\"([^\"]*)\"/g;\n let match;\n while ((match = regex.exec(raw)) !== null) {\n args.push(match[1] ?? match[0]);\n }\n return args;\n };\n\n const parseStdioEnvValue = (raw: string): string => {\n const value = raw.trim();\n if (value.length < 2) return value;\n\n const quote = value[0];\n if ((quote !== '\"' && quote !== \"'\") || value[value.length - 1] !== quote) {\n return value;\n }\n\n const inner = value.slice(1, -1);\n if (quote === \"'\") return inner;\n\n return inner.replace(\n /\\\\([\\\\nrt\"])/g,\n (_, escaped: string) => STDIO_ENV_ESCAPE_REPLACEMENTS[escaped] ?? escaped,\n );\n };\n\n const parseStdioEnv = (raw: string): Record<string, string> | undefined => {\n if (!raw.trim()) return undefined;\n const env: Record<string, string> = {};\n for (const line of raw.split(\"\\n\")) {\n const eq = line.indexOf(\"=\");\n if (eq > 0) {\n env[line.slice(0, eq).trim()] = parseStdioEnvValue(line.slice(eq + 1));\n }\n }\n return Object.keys(env).length > 0 ? env : undefined;\n };\n\n const handleAddStdio = useCallback(async () => {\n const cmd = stdioCommand.trim();\n if (!cmd) return;\n setStdioAdding(true);\n setStdioError(null);\n const displayName = stdioIdentity.name.trim() || cmd;\n const slug = slugifyNamespace(stdioIdentity.namespace) || undefined;\n const exit = await doAddServer({\n payload: {\n transport: \"stdio\" as const,\n name: displayName,\n ...(slug ? { slug } : {}),\n command: cmd,\n args: parseStdioArgs(stdioArgs),\n env: parseStdioEnv(stdioEnv),\n },\n reactivityKeys: integrationWriteKeys,\n });\n if (Exit.isFailure(exit)) {\n setStdioError(addIntegrationErrorMessage(exit, slug ?? displayName, \"Failed to add server\"));\n setStdioAdding(false);\n return;\n }\n props.onComplete(exit.value.slug);\n }, [stdioCommand, stdioArgs, stdioEnv, stdioIdentity, doAddServer, props]);\n\n // ---- Render ----\n\n return (\n <div className=\"flex flex-1 flex-col gap-6\">\n <div>\n <h1 className=\"text-xl font-semibold text-foreground\">Add MCP Source</h1>\n <p className=\"mt-1 text-[13px] text-muted-foreground\">\n Connect to an MCP server to discover and use its tools.\n </p>\n </div>\n\n {/* Transport toggle — only shown when stdio is enabled server-side */}\n {allowStdio && (\n <div className=\"flex gap-1 rounded-lg border border-border bg-muted/30 p-1\">\n <Button\n variant=\"ghost\"\n type=\"button\"\n onClick={() => setTransport(\"remote\")}\n className={`flex-1 rounded-md px-3 py-1.5 text-sm font-medium transition-colors ${\n transport === \"remote\"\n ? \"bg-background text-foreground shadow-sm\"\n : \"text-muted-foreground hover:text-foreground\"\n }`}\n >\n Remote\n </Button>\n <Button\n variant=\"ghost\"\n type=\"button\"\n onClick={() => setTransport(\"stdio\")}\n className={`flex-1 rounded-md px-3 py-1.5 text-sm font-medium transition-colors ${\n transport === \"stdio\"\n ? \"bg-background text-foreground shadow-sm\"\n : \"text-muted-foreground hover:text-foreground\"\n }`}\n >\n Stdio\n </Button>\n </div>\n )}\n\n {transport === \"remote\" ? (\n <>\n <McpRemoteSourceFields\n url={state.url}\n onUrlChange={(url) => dispatch({ type: \"set-url\", url })}\n identity={remoteIdentity}\n description={resolvedDescription}\n onDescriptionChange={setDescriptionDraft}\n preview={probe}\n probing={isProbing}\n error={probeError}\n onRetry={handleProbe}\n />\n\n {/* Authentication — declares the auth methods to register through the\n shared list editor. The credentials themselves (API key value /\n OAuth sign-in) are added from the integration's detail hub after\n adding. */}\n {probe && (\n <AuthMethodListEditor\n list={authMethodList}\n title=\"How does this server authenticate?\"\n oauthMetadata=\"discovered\"\n emptyHint=\"No methods declared. Add a method, or add the server without auth and connect from the integration page later.\"\n footerHint=\"Every method here is registered with the server. Connect an account from the integration page after adding.\"\n />\n )}\n\n {/* Error (add server). Probe errors show inline on the field. */}\n {otherError && (\n <div className=\"space-y-2\">\n <FormErrorAlert message={otherError} />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => dispatch({ type: \"retry\" })}\n className=\"text-xs\"\n >\n Try again\n </Button>\n </div>\n )}\n\n {remoteSlugExists && !isAdding && <SlugCollisionAlert slug={remoteSlug} />}\n\n <FloatActions>\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={() => props.onCancel()}\n disabled={isAdding}\n >\n Cancel\n </Button>\n {(probe || isProbing) && (\n <Button type=\"button\" onClick={handleAddRemote} disabled={!canAdd}>\n {isAdding ? (\n <>\n <Spinner className=\"size-3.5\" /> Adding…\n </>\n ) : (\n \"Add source\"\n )}\n </Button>\n )}\n </FloatActions>\n </>\n ) : (\n <>\n {/* Stdio form */}\n <CardStack>\n <CardStackContent className=\"border-t-0\">\n <CardStackEntryField\n label=\"Command\"\n description=\"- The executable to run (e.g. npx, uvx, node).\"\n >\n <Input\n value={stdioCommand}\n onChange={(e) => setStdioCommand((e.target as HTMLInputElement).value)}\n placeholder=\"npx\"\n className=\"font-mono text-sm\"\n />\n </CardStackEntryField>\n\n <CardStackEntryField\n label=\"Arguments\"\n description=\"- Space-separated arguments passed to the command.\"\n >\n <Input\n value={stdioArgs}\n onChange={(e) => setStdioArgs((e.target as HTMLInputElement).value)}\n placeholder=\"-y chrome-devtools-mcp@latest\"\n className=\"font-mono text-sm\"\n />\n </CardStackEntryField>\n\n <CardStackEntryField\n label=\"Environment variables\"\n description=\"- One per line, KEY=value format.\"\n >\n <Textarea\n value={stdioEnv}\n onChange={(e) => setStdioEnv((e.target as HTMLTextAreaElement).value)}\n placeholder={\"KEY=value\\nANOTHER=value\"}\n rows={3}\n maxRows={10}\n className=\"font-mono text-sm\"\n />\n </CardStackEntryField>\n </CardStackContent>\n </CardStack>\n\n <IntegrationIdentityFields identity={stdioIdentity} namePlaceholder=\"My MCP Server\" />\n\n {/* Stdio error */}\n {stdioError && <FormErrorAlert message={stdioError} />}\n\n {stdioSlugExists && !stdioAdding && <SlugCollisionAlert slug={stdioSlug} />}\n\n <FloatActions>\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={() => props.onCancel()}\n disabled={stdioAdding}\n >\n Cancel\n </Button>\n <Button\n type=\"button\"\n onClick={handleAddStdio}\n disabled={!stdioCommand.trim() || stdioAdding || stdioSlugExists}\n >\n {stdioAdding ? (\n <>\n <Spinner className=\"size-3.5\" /> Adding…\n </>\n ) : (\n \"Add source\"\n )}\n </Button>\n </FloatActions>\n </>\n )}\n </div>\n );\n}\n","import { Badge } from \"@executor-js/react/components/badge\";\nimport {\n CardStack,\n CardStackContent,\n CardStackEntry,\n CardStackEntryActions,\n CardStackEntryContent,\n CardStackEntryDescription,\n CardStackEntryField,\n CardStackEntryMedia,\n CardStackEntryTitle,\n} from \"@executor-js/react/components/card-stack\";\nimport { FieldError } from \"@executor-js/react/components/field\";\nimport { Input } from \"@executor-js/react/components/input\";\nimport { Textarea } from \"@executor-js/react/components/textarea\";\nimport { Skeleton } from \"@executor-js/react/components/skeleton\";\nimport { IntegrationFavicon } from \"@executor-js/react/components/integration-favicon\";\nimport { IOSSpinner } from \"@executor-js/react/components/spinner\";\nimport { Button } from \"@executor-js/react/components/button\";\nimport {\n IntegrationIdentityFieldRows,\n type IntegrationIdentity,\n} from \"@executor-js/react/plugins/integration-identity\";\n\nexport type McpRemoteSourcePreview = {\n readonly name: string;\n readonly serverName: string | null;\n readonly connected: boolean;\n readonly requiresAuthentication: boolean;\n readonly requiresOAuth: boolean;\n readonly toolCount: number | null;\n};\n\nexport function McpRemoteSourceFields(props: {\n readonly url: string;\n readonly onUrlChange: (url: string) => void;\n readonly identity: IntegrationIdentity;\n /** The integration's agent-visible description (prefilled from the server's\n * `instructions` when the probe connected). */\n readonly description?: string;\n readonly onDescriptionChange?: (value: string) => void;\n readonly preview: McpRemoteSourcePreview | null;\n readonly probing?: boolean;\n readonly error?: string | null;\n readonly onRetry?: () => void;\n readonly namespaceReadOnly?: boolean;\n readonly urlDisabled?: boolean;\n}) {\n const previewDescription = props.preview\n ? props.preview.connected\n ? props.preview.toolCount === null\n ? null\n : `${props.preview.toolCount} tool${props.preview.toolCount !== 1 ? \"s\" : \"\"} available`\n : props.preview.requiresOAuth\n ? \"OAuth required to discover tools\"\n : props.preview.requiresAuthentication\n ? \"Authentication required to discover tools\"\n : \"Ready to add\"\n : null;\n\n if (props.preview) {\n return (\n <CardStack>\n <CardStackContent className=\"border-t-0\">\n <CardStackEntry>\n <CardStackEntryMedia>\n <IntegrationFavicon url={props.url} size={32} />\n </CardStackEntryMedia>\n <CardStackEntryContent>\n <CardStackEntryTitle>\n {props.preview.serverName ?? props.preview.name}\n </CardStackEntryTitle>\n {previewDescription ? (\n <CardStackEntryDescription>{previewDescription}</CardStackEntryDescription>\n ) : null}\n </CardStackEntryContent>\n <CardStackEntryActions>\n {props.preview.connected ? (\n <Badge\n variant=\"outline\"\n className=\"border-emerald-500/20 bg-emerald-500/10 text-[10px] text-emerald-600 dark:text-emerald-400\"\n >\n Connected\n </Badge>\n ) : props.preview.requiresOAuth ? (\n <Badge\n variant=\"outline\"\n className=\"border-amber-500/20 bg-amber-500/10 text-[10px] text-amber-600 dark:text-amber-400\"\n >\n OAuth required\n </Badge>\n ) : (\n <Badge\n variant=\"outline\"\n className=\"border-amber-500/20 bg-amber-500/10 text-[10px] text-amber-600 dark:text-amber-400\"\n >\n Auth required\n </Badge>\n )}\n </CardStackEntryActions>\n </CardStackEntry>\n <IntegrationIdentityFieldRows\n identity={props.identity}\n namePlaceholder=\"e.g. Linear\"\n namespaceReadOnly={props.namespaceReadOnly}\n />\n {props.onDescriptionChange && (\n <CardStackEntryField label=\"Description\">\n <Textarea\n value={props.description ?? \"\"}\n onChange={(e) =>\n props.onDescriptionChange?.((e.target as HTMLTextAreaElement).value)\n }\n placeholder=\"What this server offers and when to reach for it\"\n rows={2}\n maxRows={6}\n className=\"text-sm\"\n />\n <p className=\"text-[11px] text-muted-foreground\">\n Agent-visible. Prefilled from the server's instructions when it sends any.\n </p>\n </CardStackEntryField>\n )}\n <CardStackEntryField label=\"Server URL\">\n <Input\n value={props.url}\n onChange={(e) => props.onUrlChange((e.target as HTMLInputElement).value)}\n placeholder=\"https://mcp.example.com\"\n className=\"w-full font-mono text-sm\"\n disabled={props.urlDisabled}\n />\n </CardStackEntryField>\n </CardStackContent>\n </CardStack>\n );\n }\n\n if (props.probing) {\n return (\n <CardStack>\n <CardStackContent className=\"border-t-0\">\n <CardStackEntry>\n <CardStackEntryMedia>\n <Skeleton className=\"size-4 rounded\" />\n </CardStackEntryMedia>\n <CardStackEntryContent>\n <Skeleton className=\"h-4 w-40\" />\n <Skeleton className=\"mt-1 h-3 w-32\" />\n </CardStackEntryContent>\n <CardStackEntryActions>\n <Skeleton className=\"h-4 w-20 rounded-full\" />\n </CardStackEntryActions>\n </CardStackEntry>\n </CardStackContent>\n </CardStack>\n );\n }\n\n return (\n <CardStack>\n <CardStackContent className=\"border-t-0\">\n <CardStackEntryField label=\"Server URL\">\n <div className=\"relative\">\n <Input\n value={props.url}\n onChange={(e) => props.onUrlChange((e.target as HTMLInputElement).value)}\n placeholder=\"https://mcp.example.com\"\n className=\"w-full pr-9 font-mono text-sm\"\n aria-invalid={props.error ? true : undefined}\n disabled={props.urlDisabled}\n />\n {props.probing && (\n <div className=\"pointer-events-none absolute right-2 top-1/2 -translate-y-1/2\">\n <IOSSpinner className=\"size-4\" />\n </div>\n )}\n </div>\n {props.error && (\n <div className=\"mt-2 space-y-2\">\n <FieldError>{props.error}</FieldError>\n {props.onRetry && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={props.onRetry}\n className=\"h-7 px-2 text-xs\"\n >\n Try again\n </Button>\n )}\n </div>\n )}\n </CardStackEntryField>\n </CardStackContent>\n </CardStack>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAAA,SAAS,YAAY,aAAa,WAAW,SAAS,QAAQ,gBAAgB;AAC9E,SAAS,kBAAkB;AAC3B,YAAY,UAAU;AACtB,YAAY,WAAW;AAEvB,SAAS,UAAAA,eAAc;AACvB;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE,aAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,uBAAAC;AAAA,OACK;AACP,SAAS,oBAAoB;AAC7B,SAAS,SAAAC,cAAa;AACtB,SAAS,eAAe;AACxB,SAAS,YAAAC,iBAAgB;AACzB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,4BAA4B;;;ACnCrC,SAAS,aAAa;AACtB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAC3B,SAAS,aAAa;AACtB,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,0BAA0B;AACnC,SAAS,kBAAkB;AAC3B,SAAS,cAAc;AACvB;AAAA,EACE;AAAA,OAEK;AA4CO,cAEF,YAFE;AAjCP,SAAS,sBAAsB,OAcnC;AACD,QAAM,qBAAqB,MAAM,UAC7B,MAAM,QAAQ,YACZ,MAAM,QAAQ,cAAc,OAC1B,OACA,GAAG,MAAM,QAAQ,SAAS,QAAQ,MAAM,QAAQ,cAAc,IAAI,MAAM,EAAE,eAC5E,MAAM,QAAQ,gBACZ,qCACA,MAAM,QAAQ,yBACZ,8CACA,iBACN;AAEJ,MAAI,MAAM,SAAS;AACjB,WACE,oBAAC,aACC,+BAAC,oBAAiB,WAAU,cAC1B;AAAA,2BAAC,kBACC;AAAA,4BAAC,uBACC,8BAAC,sBAAmB,KAAK,MAAM,KAAK,MAAM,IAAI,GAChD;AAAA,QACA,qBAAC,yBACC;AAAA,8BAAC,uBACE,gBAAM,QAAQ,cAAc,MAAM,QAAQ,MAC7C;AAAA,UACC,qBACC,oBAAC,6BAA2B,8BAAmB,IAC7C;AAAA,WACN;AAAA,QACA,oBAAC,yBACE,gBAAM,QAAQ,YACb;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,WAAU;AAAA,YACX;AAAA;AAAA,QAED,IACE,MAAM,QAAQ,gBAChB;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,WAAU;AAAA,YACX;AAAA;AAAA,QAED,IAEA;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,WAAU;AAAA,YACX;AAAA;AAAA,QAED,GAEJ;AAAA,SACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,UAAU,MAAM;AAAA,UAChB,iBAAgB;AAAA,UAChB,mBAAmB,MAAM;AAAA;AAAA,MAC3B;AAAA,MACC,MAAM,uBACL,qBAAC,uBAAoB,OAAM,eACzB;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,MAAM,eAAe;AAAA,YAC5B,UAAU,CAAC,MACT,MAAM,sBAAuB,EAAE,OAA+B,KAAK;AAAA,YAErE,aAAY;AAAA,YACZ,MAAM;AAAA,YACN,SAAS;AAAA,YACT,WAAU;AAAA;AAAA,QACZ;AAAA,QACA,oBAAC,OAAE,WAAU,qCAAoC,wFAEjD;AAAA,SACF;AAAA,MAEF,oBAAC,uBAAoB,OAAM,cACzB;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,MAAM;AAAA,UACb,UAAU,CAAC,MAAM,MAAM,YAAa,EAAE,OAA4B,KAAK;AAAA,UACvE,aAAY;AAAA,UACZ,WAAU;AAAA,UACV,UAAU,MAAM;AAAA;AAAA,MAClB,GACF;AAAA,OACF,GACF;AAAA,EAEJ;AAEA,MAAI,MAAM,SAAS;AACjB,WACE,oBAAC,aACC,8BAAC,oBAAiB,WAAU,cAC1B,+BAAC,kBACC;AAAA,0BAAC,uBACC,8BAAC,YAAS,WAAU,kBAAiB,GACvC;AAAA,MACA,qBAAC,yBACC;AAAA,4BAAC,YAAS,WAAU,YAAW;AAAA,QAC/B,oBAAC,YAAS,WAAU,iBAAgB;AAAA,SACtC;AAAA,MACA,oBAAC,yBACC,8BAAC,YAAS,WAAU,yBAAwB,GAC9C;AAAA,OACF,GACF,GACF;AAAA,EAEJ;AAEA,SACE,oBAAC,aACC,8BAAC,oBAAiB,WAAU,cAC1B,+BAAC,uBAAoB,OAAM,cACzB;AAAA,yBAAC,SAAI,WAAU,YACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,MAAM;AAAA,UACb,UAAU,CAAC,MAAM,MAAM,YAAa,EAAE,OAA4B,KAAK;AAAA,UACvE,aAAY;AAAA,UACZ,WAAU;AAAA,UACV,gBAAc,MAAM,QAAQ,OAAO;AAAA,UACnC,UAAU,MAAM;AAAA;AAAA,MAClB;AAAA,MACC,MAAM,WACL,oBAAC,SAAI,WAAU,iEACb,8BAAC,cAAW,WAAU,UAAS,GACjC;AAAA,OAEJ;AAAA,IACC,MAAM,SACL,qBAAC,SAAI,WAAU,kBACb;AAAA,0BAAC,cAAY,gBAAM,OAAM;AAAA,MACxB,MAAM,WACL;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,SAAS,MAAM;AAAA,UACf,WAAU;AAAA,UACX;AAAA;AAAA,MAED;AAAA,OAEJ;AAAA,KAEJ,GACF,GACF;AAEJ;;;ADyNM,SA+FY,UA9FV,OAAAC,MADF,QAAAC,aAAA;AA5WN,IAAM,gCAAkE;AAAA,EACtE,MAAM;AAAA,EACN,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,KAAK;AACP;AAMA,SAAS,WAAW,IAA+C;AACjE,MAAI,CAAC,GAAI,QAAO;AAChB,SAAO,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAC3C;AAuCA,IAAM,OAAc,EAAE,MAAM,OAAO,KAAK,GAAG;AAE3C,SAAS,QAAQ,OAAc,QAAuB;AACpD,SAAa,YAAM,MAAM,EAAE;AAAA,IACnB,oBAAc,MAAM,EAAE,WAAW,CAAC,OAAc,EAAE,MAAM,OAAO,KAAK,EAAE,IAAI,EAAE;AAAA,IAC5E,oBAAc,MAAM;AAAA,MACxB;AAAA,MACA,OAAc;AAAA,QACZ,MAAM;AAAA,QACN,KAAK,MAAM;AAAA,QACX,OAAO,WAAW,QAAQ,MAAM,QAAQ;AAAA,MAC1C;AAAA,IACF;AAAA,IACM,oBAAc,MAAM;AAAA,MACxB;AAAA,MACA,CAAC,OAAc,EAAE,MAAM,UAAU,KAAK,MAAM,KAAK,OAAO,EAAE,MAAM;AAAA,IAClE;AAAA,IACM,oBAAc,MAAM;AAAA,MACxB;AAAA,MACA,CAAC,OAAc;AAAA,QACb,MAAM;AAAA,QACN,KAAK,MAAM;AAAA,QACX,OAAO;AAAA,QACP,OAAO,EAAE;AAAA,MACX;AAAA,IACF;AAAA,IACM,oBAAc,MAAM,EAAE,aAAa,MAAa;AACpD,YAAM,QAAQ,WAAW,QAAQ,MAAM,QAAQ;AAC/C,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO,EAAE,MAAM,UAAU,KAAK,MAAM,KAAK,MAAM;AAAA,IACjD,CAAC;AAAA,IACK,oBAAc,MAAM,EAAE,YAAY,CAAC,MAAa;AACpD,UAAI,MAAM,SAAS,SAAU,QAAO;AACpC,aAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,MAAM;AAAA,QACX,OAAO,MAAM;AAAA,QACb,OAAO,EAAE;AAAA,MACX;AAAA,IACF,CAAC;AAAA,IACK,oBAAc,MAAM,EAAE,SAAS,MAAa;AAChD,UAAI,MAAM,SAAS,QAAS,QAAO;AACnC,aAAO,MAAM,QACT,EAAE,MAAM,UAAU,KAAK,MAAM,KAAK,OAAO,MAAM,MAAM,IACrD,EAAE,MAAM,OAAO,KAAK,MAAM,IAAI;AAAA,IACpC,CAAC;AAAA,IACK;AAAA,EACR;AACF;AAMe,SAAR,aAA8B,OAOlC;AACD,QAAM,aAAa,MAAM,cAAc;AACvC,QAAM,YAAY,WAAW,MAAM,aAAa;AAGhD,QAAM,SAAS,WAAW,cAAc,WAAW,CAAC,aAAa,SAAY;AAC7E,QAAM,gBAAgB,QAAQ,cAAc;AAE5C,QAAM,CAAC,WAAW,YAAY,IAAI;AAAA,IAChC,iBAAiB,aAAa,UAAU;AAAA,EAC1C;AAGA,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,gBAAgB,OAAO,UAAU,EAAE;AACpF,QAAM,CAAC,WAAW,YAAY,IAAI;AAAA,IAChC,iBAAiB,OAAO,OAAO,OAAO,KAAK,KAAK,GAAG,IAAI;AAAA,EACzD;AACA,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,EAAE;AAC3C,QAAM,gBAAgB,uBAAuB;AAAA,IAC3C,cAAc,gBAAgB,OAAO,OAAO;AAAA,EAC9C,CAAC;AACD,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,KAAK;AACpD,QAAM,CAAC,YAAY,aAAa,IAAI,SAAwB,IAAI;AAGhE,QAAM,YACJ,CAAC,iBAAiB,QAAQ,cAAc,UAAa,QAAQ,MACzD,OAAO,MACN,MAAM,cAAc;AAE3B,QAAM,CAAC,OAAO,QAAQ,IAAI;AAAA,IACxB;AAAA,IACA,YAAY,EAAE,MAAM,OAAgB,KAAK,UAAU,IAAI;AAAA,EACzD;AAEA,QAAM,UAAU,WAAW,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACpE,QAAM,cAAc,WAAW,cAAc,EAAE,MAAM,cAAc,CAAC;AAEpE,QAAM,QAAQ,WAAW,QAAQ,MAAM,QAAQ;AAK/C,QAAM,kBAA6C,QAAQ,MAAM;AAC/D,QAAI,CAAC,MAAO,QAAO,CAAC;AACpB,QAAI,MAAM,eAAe;AACvB,aAAO;AAAA,QACL;AAAA,UACE,OAAO,EAAE,MAAM,SAAS,kBAAkB,IAAI,UAAU,IAAI,QAAQ,CAAC,EAAE;AAAA,UACvE,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,QAAI,MAAM,wBAAwB;AAChC,aAAO;AAAA,QACL;AAAA,UACE,OAAO;AAAA,YACL,MAAM;AAAA,YACN,YAAY,CAAC,EAAE,SAAS,UAAU,MAAM,iBAAiB,QAAQ,UAAU,CAAC;AAAA,UAC9E;AAAA,UACA,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,WAAO,CAAC,EAAE,OAAO,EAAE,MAAM,OAAO,GAAG,OAAO,WAAW,CAAC;AAAA,EACxD,GAAG,CAAC,KAAK,CAAC;AACV,QAAM,iBAAiB,kBAAkB,eAAe;AAExD,QAAM,iBAAiB,uBAAuB;AAAA,IAC5C,cACE,8BAA8B,MAAM,KAAK,KAAK,KAAK,OAAO,cAAc,OAAO,QAAQ;AAAA,EAC3F,CAAC;AAGD,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAwB,IAAI;AAC5E,QAAM,sBAAsB,oBAAoB,OAAO,gBAAgB;AACvE,QAAM,YAAY,MAAM,SAAS;AACjC,QAAM,WAAW,MAAM,SAAS;AAOhC,QAAM,aAAa,iBAAiB,eAAe,SAAS;AAC5D,QAAM,YAAY,iBAAiB,cAAc,SAAS;AAC1D,QAAM,mBAAmB,qBAAqB,UAAU;AACxD,QAAM,kBAAkB,qBAAqB,SAAS;AAEtD,QAAM,SAAS,QAAQ,KAAK,KAAK,CAAC,YAAY,CAAC;AAG/C,QAAM,aAAa,MAAM,SAAS,WAAW,MAAM,UAAU,OAAO,MAAM,QAAQ;AAClF,QAAM,aAAa,MAAM,SAAS,WAAW,MAAM,UAAU,OAAO,MAAM,QAAQ;AAIlF,QAAM,cAAc,YAAY,YAAY;AAC1C,aAAS,EAAE,MAAM,cAAc,CAAC;AAChC,UAAM,OAAO,MAAM,QAAQ;AAAA,MACzB,SAAS,EAAE,UAAU,MAAM,IAAI,KAAK,EAAE;AAAA,IACxC,CAAC;AACD,QAAS,eAAU,IAAI,GAAG;AACxB,eAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO,qBAAqB,MAAM,mBAAmB;AAAA,MACvD,CAAC;AACD;AAAA,IACF;AACA,aAAS,EAAE,MAAM,YAAY,OAAO,KAAK,MAAM,CAAC;AAAA,EAClD,GAAG,CAAC,MAAM,KAAK,OAAO,CAAC;AAIvB,QAAM,iBAAiB,OAAO,WAAW;AACzC,iBAAe,UAAU;AAIzB,YAAU,MAAM;AACd,QAAI,cAAc,SAAU;AAC5B,QAAI,MAAM,SAAS,MAAO;AAC1B,UAAM,UAAU,MAAM,IAAI,KAAK;AAC/B,QAAI,CAAC,QAAS;AACd,UAAM,SAAS,WAAW,MAAM;AAC9B,qBAAe,QAAQ;AAAA,IACzB,GAAG,GAAG;AACN,WAAO,MAAM,aAAa,MAAM;AAAA,EAClC,GAAG,CAAC,WAAW,MAAM,MAAM,MAAM,GAAG,CAAC;AAIrC,QAAM,sBAAsB;AAAA,IAC1B,OAAO,2BAAkF;AACvF,YAAM,cAAc,eAAe,KAAK,KAAK,KAAK,OAAO,cAAc,OAAO,QAAQ;AACtF,YAAM,OAAO,iBAAiB,eAAe,SAAS,KAAK;AAC3D,YAAM,OAAO,MAAM,YAAY;AAAA,QAC7B,SAAS;AAAA,UACP,WAAW;AAAA,UACX,MAAM;AAAA,UACN,GAAI,oBAAoB,KAAK,EAAE,SAAS,IACpC,EAAE,aAAa,oBAAoB,KAAK,EAAE,IAC1C,CAAC;AAAA,UACL,UAAU,MAAM,IAAI,KAAK;AAAA,UACzB,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,UACvB;AAAA,QACF;AAAA,QACA,gBAAgB;AAAA,MAClB,CAAC;AACD,UAAS,eAAU,IAAI,GAAG;AACxB,iBAAS;AAAA,UACP,MAAM;AAAA,UACN,OAAO,2BAA2B,MAAM,QAAQ,aAAa,sBAAsB;AAAA,QACrF,CAAC;AACD,eAAO;AAAA,MACT;AACA,aAAO,KAAK,MAAM;AAAA,IACpB;AAAA,IACA,CAAC,aAAa,OAAO,gBAAgB,qBAAqB,MAAM,GAAG;AAAA,EACrE;AAEA,QAAM,kBAAkB,YAAY,YAAY;AAC9C,QAAI,CAAC,MAAO;AACZ,aAAS,EAAE,MAAM,YAAY,CAAC;AAG9B,UAAM,UAAU,eAAe,KAAK;AAAA,MAAI,CAAC,QACvC,iBAAiB,kCAAkC,IAAI,KAAK,CAAC;AAAA,IAC/D;AACA,UAAM,OAAO,MAAM;AAAA,MACjB,QAAQ,SAAS,IAAI,UAAU,CAAC,EAAE,MAAM,OAAgB,CAAC;AAAA,IAC3D;AACA,QAAI,SAAS,KAAM;AACnB,UAAM,WAAW,IAAI;AAAA,EACvB,GAAG,CAAC,OAAO,eAAe,MAAM,qBAAqB,KAAK,CAAC;AAI3D,QAAM,iBAAiB,CAAC,QAA0B;AAChD,QAAI,CAAC,IAAI,KAAK,EAAG,QAAO,CAAC;AACzB,UAAM,OAAiB,CAAC;AACxB,UAAM,QAAQ;AACd,QAAI;AACJ,YAAQ,QAAQ,MAAM,KAAK,GAAG,OAAO,MAAM;AACzC,WAAK,KAAK,MAAM,CAAC,KAAK,MAAM,CAAC,CAAC;AAAA,IAChC;AACA,WAAO;AAAA,EACT;AAEA,QAAM,qBAAqB,CAAC,QAAwB;AAClD,UAAMC,SAAQ,IAAI,KAAK;AACvB,QAAIA,OAAM,SAAS,EAAG,QAAOA;AAE7B,UAAM,QAAQA,OAAM,CAAC;AACrB,QAAK,UAAU,OAAO,UAAU,OAAQA,OAAMA,OAAM,SAAS,CAAC,MAAM,OAAO;AACzE,aAAOA;AAAA,IACT;AAEA,UAAM,QAAQA,OAAM,MAAM,GAAG,EAAE;AAC/B,QAAI,UAAU,IAAK,QAAO;AAE1B,WAAO,MAAM;AAAA,MACX;AAAA,MACA,CAAC,GAAG,YAAoB,8BAA8B,OAAO,KAAK;AAAA,IACpE;AAAA,EACF;AAEA,QAAM,gBAAgB,CAAC,QAAoD;AACzE,QAAI,CAAC,IAAI,KAAK,EAAG,QAAO;AACxB,UAAM,MAA8B,CAAC;AACrC,eAAW,QAAQ,IAAI,MAAM,IAAI,GAAG;AAClC,YAAM,KAAK,KAAK,QAAQ,GAAG;AAC3B,UAAI,KAAK,GAAG;AACV,YAAI,KAAK,MAAM,GAAG,EAAE,EAAE,KAAK,CAAC,IAAI,mBAAmB,KAAK,MAAM,KAAK,CAAC,CAAC;AAAA,MACvE;AAAA,IACF;AACA,WAAO,OAAO,KAAK,GAAG,EAAE,SAAS,IAAI,MAAM;AAAA,EAC7C;AAEA,QAAM,iBAAiB,YAAY,YAAY;AAC7C,UAAM,MAAM,aAAa,KAAK;AAC9B,QAAI,CAAC,IAAK;AACV,mBAAe,IAAI;AACnB,kBAAc,IAAI;AAClB,UAAM,cAAc,cAAc,KAAK,KAAK,KAAK;AACjD,UAAM,OAAO,iBAAiB,cAAc,SAAS,KAAK;AAC1D,UAAM,OAAO,MAAM,YAAY;AAAA,MAC7B,SAAS;AAAA,QACP,WAAW;AAAA,QACX,MAAM;AAAA,QACN,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,QACvB,SAAS;AAAA,QACT,MAAM,eAAe,SAAS;AAAA,QAC9B,KAAK,cAAc,QAAQ;AAAA,MAC7B;AAAA,MACA,gBAAgB;AAAA,IAClB,CAAC;AACD,QAAS,eAAU,IAAI,GAAG;AACxB,oBAAc,2BAA2B,MAAM,QAAQ,aAAa,sBAAsB,CAAC;AAC3F,qBAAe,KAAK;AACpB;AAAA,IACF;AACA,UAAM,WAAW,KAAK,MAAM,IAAI;AAAA,EAClC,GAAG,CAAC,cAAc,WAAW,UAAU,eAAe,aAAa,KAAK,CAAC;AAIzE,SACE,gBAAAD,MAAC,SAAI,WAAU,8BACb;AAAA,oBAAAA,MAAC,SACC;AAAA,sBAAAD,KAAC,QAAG,WAAU,yCAAwC,4BAAc;AAAA,MACpE,gBAAAA,KAAC,OAAE,WAAU,0CAAyC,qEAEtD;AAAA,OACF;AAAA,IAGC,cACC,gBAAAC,MAAC,SAAI,WAAU,8DACb;AAAA,sBAAAD;AAAA,QAACG;AAAA,QAAA;AAAA,UACC,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,SAAS,MAAM,aAAa,QAAQ;AAAA,UACpC,WAAW,uEACT,cAAc,WACV,4CACA,6CACN;AAAA,UACD;AAAA;AAAA,MAED;AAAA,MACA,gBAAAH;AAAA,QAACG;AAAA,QAAA;AAAA,UACC,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,SAAS,MAAM,aAAa,OAAO;AAAA,UACnC,WAAW,uEACT,cAAc,UACV,4CACA,6CACN;AAAA,UACD;AAAA;AAAA,MAED;AAAA,OACF;AAAA,IAGD,cAAc,WACb,gBAAAF,MAAA,YACE;AAAA,sBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,KAAK,MAAM;AAAA,UACX,aAAa,CAAC,QAAQ,SAAS,EAAE,MAAM,WAAW,IAAI,CAAC;AAAA,UACvD,UAAU;AAAA,UACV,aAAa;AAAA,UACb,qBAAqB;AAAA,UACrB,SAAS;AAAA,UACT,SAAS;AAAA,UACT,OAAO;AAAA,UACP,SAAS;AAAA;AAAA,MACX;AAAA,MAMC,SACC,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAM;AAAA,UACN,OAAM;AAAA,UACN,eAAc;AAAA,UACd,WAAU;AAAA,UACV,YAAW;AAAA;AAAA,MACb;AAAA,MAID,cACC,gBAAAC,MAAC,SAAI,WAAU,aACb;AAAA,wBAAAD,KAAC,kBAAe,SAAS,YAAY;AAAA,QACrC,gBAAAA;AAAA,UAACG;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,MAAM,SAAS,EAAE,MAAM,QAAQ,CAAC;AAAA,YACzC,WAAU;AAAA,YACX;AAAA;AAAA,QAED;AAAA,SACF;AAAA,MAGD,oBAAoB,CAAC,YAAY,gBAAAH,KAAC,sBAAmB,MAAM,YAAY;AAAA,MAExE,gBAAAC,MAAC,gBACC;AAAA,wBAAAD;AAAA,UAACG;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,SAAS,MAAM,MAAM,SAAS;AAAA,YAC9B,UAAU;AAAA,YACX;AAAA;AAAA,QAED;AAAA,SACE,SAAS,cACT,gBAAAH,KAACG,SAAA,EAAO,MAAK,UAAS,SAAS,iBAAiB,UAAU,CAAC,QACxD,qBACC,gBAAAF,MAAA,YACE;AAAA,0BAAAD,KAAC,WAAQ,WAAU,YAAW;AAAA,UAAE;AAAA,WAClC,IAEA,cAEJ;AAAA,SAEJ;AAAA,OACF,IAEA,gBAAAC,MAAA,YAEE;AAAA,sBAAAD,KAACI,YAAA,EACC,0BAAAH,MAACI,mBAAA,EAAiB,WAAU,cAC1B;AAAA,wBAAAL;AAAA,UAACM;AAAA,UAAA;AAAA,YACC,OAAM;AAAA,YACN,aAAY;AAAA,YAEZ,0BAAAN;AAAA,cAACO;AAAA,cAAA;AAAA,gBACC,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM,gBAAiB,EAAE,OAA4B,KAAK;AAAA,gBACrE,aAAY;AAAA,gBACZ,WAAU;AAAA;AAAA,YACZ;AAAA;AAAA,QACF;AAAA,QAEA,gBAAAP;AAAA,UAACM;AAAA,UAAA;AAAA,YACC,OAAM;AAAA,YACN,aAAY;AAAA,YAEZ,0BAAAN;AAAA,cAACO;AAAA,cAAA;AAAA,gBACC,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM,aAAc,EAAE,OAA4B,KAAK;AAAA,gBAClE,aAAY;AAAA,gBACZ,WAAU;AAAA;AAAA,YACZ;AAAA;AAAA,QACF;AAAA,QAEA,gBAAAP;AAAA,UAACM;AAAA,UAAA;AAAA,YACC,OAAM;AAAA,YACN,aAAY;AAAA,YAEZ,0BAAAN;AAAA,cAACQ;AAAA,cAAA;AAAA,gBACC,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM,YAAa,EAAE,OAA+B,KAAK;AAAA,gBACpE,aAAa;AAAA,gBACb,MAAM;AAAA,gBACN,SAAS;AAAA,gBACT,WAAU;AAAA;AAAA,YACZ;AAAA;AAAA,QACF;AAAA,SACF,GACF;AAAA,MAEA,gBAAAR,KAAC,6BAA0B,UAAU,eAAe,iBAAgB,iBAAgB;AAAA,MAGnF,cAAc,gBAAAA,KAAC,kBAAe,SAAS,YAAY;AAAA,MAEnD,mBAAmB,CAAC,eAAe,gBAAAA,KAAC,sBAAmB,MAAM,WAAW;AAAA,MAEzE,gBAAAC,MAAC,gBACC;AAAA,wBAAAD;AAAA,UAACG;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,SAAS,MAAM,MAAM,SAAS;AAAA,YAC9B,UAAU;AAAA,YACX;AAAA;AAAA,QAED;AAAA,QACA,gBAAAH;AAAA,UAACG;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS;AAAA,YACT,UAAU,CAAC,aAAa,KAAK,KAAK,eAAe;AAAA,YAEhD,wBACC,gBAAAF,MAAA,YACE;AAAA,8BAAAD,KAAC,WAAQ,WAAU,YAAW;AAAA,cAAE;AAAA,eAClC,IAEA;AAAA;AAAA,QAEJ;AAAA,SACF;AAAA,OACF;AAAA,KAEJ;AAEJ;","names":["Button","CardStack","CardStackContent","CardStackEntryField","Input","Textarea","jsx","jsxs","value","Button","CardStack","CardStackContent","CardStackEntryField","Input","Textarea"]}
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
mcpAuthMethodInputFromEditorValue,
|
|
5
5
|
mcpServerAtom,
|
|
6
6
|
mcpWireAuthInput
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-AL7N323J.js";
|
|
8
8
|
import "./chunk-3H5Y7JCQ.js";
|
|
9
9
|
|
|
10
10
|
// src/react/EditMcpSource.tsx
|
|
11
|
-
import { useCallback, useMemo, useState } from "react";
|
|
11
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
12
12
|
import { useAtomValue, useAtomSet } from "@effect/atom-react";
|
|
13
13
|
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
|
|
14
14
|
import * as Exit from "effect/Exit";
|
|
@@ -19,15 +19,6 @@ import {
|
|
|
19
19
|
AuthMethodListEditor,
|
|
20
20
|
useAuthMethodList
|
|
21
21
|
} from "@executor-js/react/components/auth-method-list-editor";
|
|
22
|
-
import { Button } from "@executor-js/react/components/button";
|
|
23
|
-
import {
|
|
24
|
-
CardStack,
|
|
25
|
-
CardStackContent,
|
|
26
|
-
CardStackEntry,
|
|
27
|
-
CardStackEntryContent,
|
|
28
|
-
CardStackEntryDescription,
|
|
29
|
-
CardStackEntryTitle
|
|
30
|
-
} from "@executor-js/react/components/card-stack";
|
|
31
22
|
import { Badge } from "@executor-js/react/components/badge";
|
|
32
23
|
import { FormErrorAlert } from "@executor-js/react/lib/integration-add";
|
|
33
24
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -59,7 +50,6 @@ function RemoteEdit(props) {
|
|
|
59
50
|
[server.config.authenticationTemplate]
|
|
60
51
|
);
|
|
61
52
|
const list = useAuthMethodList(seeds);
|
|
62
|
-
const [saving, setSaving] = useState(false);
|
|
63
53
|
const [error, setError] = useState(null);
|
|
64
54
|
const editedMethods = useMemo(
|
|
65
55
|
() => list.rows.map((row) => {
|
|
@@ -82,8 +72,7 @@ function RemoteEdit(props) {
|
|
|
82
72
|
return false;
|
|
83
73
|
});
|
|
84
74
|
}, [editedMethods, server.config.authenticationTemplate]);
|
|
85
|
-
const
|
|
86
|
-
setSaving(true);
|
|
75
|
+
const applyStaged = useCallback(async () => {
|
|
87
76
|
setError(null);
|
|
88
77
|
const exit = await doConfigureAuth({
|
|
89
78
|
params: { slug: server.slug },
|
|
@@ -95,84 +84,76 @@ function RemoteEdit(props) {
|
|
|
95
84
|
});
|
|
96
85
|
if (Exit.isFailure(exit)) {
|
|
97
86
|
setError("Failed to update authentication methods");
|
|
98
|
-
|
|
99
|
-
return;
|
|
87
|
+
return { ok: false };
|
|
100
88
|
}
|
|
101
|
-
|
|
89
|
+
return { ok: true, summary: "Authentication methods updated." };
|
|
102
90
|
}, [doConfigureAuth, editedMethods, server.slug]);
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
91
|
+
const onPendingChangeRef = useRef(props.onPendingChange);
|
|
92
|
+
onPendingChangeRef.current = props.onPendingChange;
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
onPendingChangeRef.current?.(methodsChanged ? applyStaged : null);
|
|
95
|
+
return () => onPendingChangeRef.current?.(null);
|
|
96
|
+
}, [methodsChanged, applyStaged]);
|
|
97
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-4 border-t border-border/60 pt-5", children: [
|
|
98
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
99
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: "Authentication methods" }),
|
|
100
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
101
|
+
"Changes apply when you save. The endpoint (",
|
|
102
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono", children: server.config.endpoint }),
|
|
103
|
+
") is part of the server's identity \u2014 remove and re-add to change it."
|
|
104
|
+
] })
|
|
107
105
|
] }),
|
|
108
|
-
/* @__PURE__ */ jsx(CardStack, { children: /* @__PURE__ */ jsx(CardStackContent, { className: "border-t-0", children: /* @__PURE__ */ jsxs(CardStackEntry, { children: [
|
|
109
|
-
/* @__PURE__ */ jsxs(CardStackEntryContent, { children: [
|
|
110
|
-
/* @__PURE__ */ jsx(CardStackEntryTitle, { children: server.description || String(server.slug) }),
|
|
111
|
-
/* @__PURE__ */ jsx(CardStackEntryDescription, { className: "font-mono text-xs", children: server.config.endpoint })
|
|
112
|
-
] }),
|
|
113
|
-
/* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: "remote" })
|
|
114
|
-
] }) }) }),
|
|
115
106
|
/* @__PURE__ */ jsx(
|
|
116
107
|
AuthMethodListEditor,
|
|
117
108
|
{
|
|
118
109
|
list,
|
|
119
|
-
title: "How does this server authenticate?",
|
|
120
110
|
oauthMetadata: "discovered",
|
|
121
111
|
emptyHint: "No methods declared. Add one, or save to mark this server as open (no authentication).",
|
|
122
112
|
footerHint: "Connections pick one of these methods. Removing a method detaches connections created against it."
|
|
123
113
|
}
|
|
124
114
|
),
|
|
125
|
-
|
|
126
|
-
error && /* @__PURE__ */ jsx(FormErrorAlert, { message: error }),
|
|
127
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-end border-t border-border pt-4", children: /* @__PURE__ */ jsx(Button, { onClick: props.onSave, children: "Done" }) })
|
|
115
|
+
error && /* @__PURE__ */ jsx(FormErrorAlert, { message: error })
|
|
128
116
|
] });
|
|
129
117
|
}
|
|
130
118
|
function StdioReadOnly(props) {
|
|
131
119
|
const { command, args } = props.server.config;
|
|
132
|
-
return /* @__PURE__ */ jsxs("div", { className: "space-y-
|
|
133
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
134
|
-
/* @__PURE__ */ jsx("
|
|
135
|
-
/* @__PURE__ */ jsx("p", { className: "
|
|
120
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-3 border-t border-border/60 pt-5", children: [
|
|
121
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
122
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: "Server command" }),
|
|
123
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Stdio MCP sources cannot be edited. Remove and recreate the source with the updated command." })
|
|
136
124
|
] }),
|
|
137
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 rounded-
|
|
138
|
-
/* @__PURE__ */ jsxs("
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
" ",
|
|
143
|
-
(args ?? []).join(" ")
|
|
144
|
-
] })
|
|
125
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 rounded-md border border-border/60 bg-muted/40 px-3 py-2", children: [
|
|
126
|
+
/* @__PURE__ */ jsxs("p", { className: "min-w-0 flex-1 truncate font-mono text-xs text-foreground", children: [
|
|
127
|
+
command,
|
|
128
|
+
" ",
|
|
129
|
+
(args ?? []).join(" ")
|
|
145
130
|
] }),
|
|
146
131
|
/* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: "stdio" })
|
|
147
|
-
] })
|
|
148
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-end border-t border-border pt-4", children: /* @__PURE__ */ jsx(Button, { onClick: props.onSave, children: "Done" }) })
|
|
132
|
+
] })
|
|
149
133
|
] });
|
|
150
134
|
}
|
|
151
|
-
function EditMcpSource({
|
|
152
|
-
sourceId,
|
|
153
|
-
onSave
|
|
154
|
-
}) {
|
|
135
|
+
function EditMcpSource({ sourceId, onPendingChange }) {
|
|
155
136
|
const slug = IntegrationSlug.make(sourceId);
|
|
156
137
|
const serverResult = useAtomValue(mcpServerAtom(slug));
|
|
157
138
|
const server = AsyncResult.isSuccess(serverResult) ? serverResult.value : null;
|
|
158
|
-
if (!AsyncResult.isSuccess(serverResult) || server === null)
|
|
159
|
-
return /* @__PURE__ */ jsx("div", { className: "space-y-6", children: /* @__PURE__ */ jsxs("div", { children: [
|
|
160
|
-
/* @__PURE__ */ jsx("h1", { className: "text-xl font-semibold text-foreground", children: "Edit MCP Source" }),
|
|
161
|
-
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: "Loading configuration\u2026" })
|
|
162
|
-
] }) });
|
|
163
|
-
}
|
|
139
|
+
if (!AsyncResult.isSuccess(serverResult) || server === null) return null;
|
|
164
140
|
if (server.config.transport === "stdio") {
|
|
165
141
|
return /* @__PURE__ */ jsx(
|
|
166
142
|
StdioReadOnly,
|
|
167
143
|
{
|
|
168
|
-
server
|
|
169
|
-
onSave
|
|
144
|
+
server
|
|
170
145
|
}
|
|
171
146
|
);
|
|
172
147
|
}
|
|
173
|
-
return /* @__PURE__ */ jsx(
|
|
148
|
+
return /* @__PURE__ */ jsx(
|
|
149
|
+
RemoteEdit,
|
|
150
|
+
{
|
|
151
|
+
server,
|
|
152
|
+
...onPendingChange ? { onPendingChange } : {}
|
|
153
|
+
}
|
|
154
|
+
);
|
|
174
155
|
}
|
|
175
156
|
export {
|
|
176
157
|
EditMcpSource as default
|
|
177
158
|
};
|
|
178
|
-
//# sourceMappingURL=EditMcpSource-
|
|
159
|
+
//# sourceMappingURL=EditMcpSource-BV5ZEWEY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/EditMcpSource.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useAtomValue, useAtomSet } from \"@effect/atom-react\";\nimport * as AsyncResult from \"effect/unstable/reactivity/AsyncResult\";\nimport * as Exit from \"effect/Exit\";\n\nimport { IntegrationSlug } from \"@executor-js/sdk/shared\";\nimport type { EditSheetApplyResult, EditSheetSectionProps } from \"@executor-js/sdk/client\";\nimport { apiKeyMethodLabel, type AuthPlacement } from \"@executor-js/sdk/http-auth\";\nimport { integrationWriteKeys } from \"@executor-js/react/api/reactivity-keys\";\nimport {\n AuthMethodListEditor,\n useAuthMethodList,\n type AuthMethodRow,\n type AuthMethodSeed,\n} from \"@executor-js/react/components/auth-method-list-editor\";\nimport { Badge } from \"@executor-js/react/components/badge\";\nimport { FormErrorAlert } from \"@executor-js/react/lib/integration-add\";\n\nimport { configureMcpAuth, mcpServerAtom } from \"./atoms\";\nimport type {\n McpAuthMethod,\n McpCanonicalAuthMethodInput,\n McpIntegrationConfig,\n} from \"../sdk/types\";\nimport {\n editorValueFromMcpAuthMethod,\n mcpAuthMethodInputFromEditorValue,\n mcpWireAuthInput,\n} from \"./auth-method-config\";\n\ntype McpServer = {\n readonly slug: IntegrationSlug;\n readonly description: string;\n readonly kind: string;\n readonly canRemove: boolean;\n readonly canRefresh: boolean;\n readonly config: McpIntegrationConfig;\n};\n\ntype McpRemoteConfig = Extract<McpIntegrationConfig, { transport: \"remote\" }>;\n\nconst methodSeedLabel = (method: McpAuthMethod): string => {\n if (method.kind === \"oauth2\") return \"OAuth\";\n if (method.kind === \"apikey\") return apiKeyMethodLabel(method);\n return \"No authentication\";\n};\n\nconst samePlacements = (\n a: readonly AuthPlacement[] | undefined,\n b: readonly AuthPlacement[] | undefined,\n): boolean => {\n const left = a ?? [];\n const right = b ?? [];\n if (left.length !== right.length) return false;\n return left.every((placement: AuthPlacement, index: number) => {\n const other = right[index];\n return (\n other !== undefined &&\n placement.carrier === other.carrier &&\n placement.name === other.name &&\n (placement.prefix ?? \"\") === (other.prefix ?? \"\") &&\n (placement.variable ?? \"\") === (other.variable ?? \"\") &&\n (placement.literal ?? null) === (other.literal ?? null)\n );\n });\n};\n\n// ---------------------------------------------------------------------------\n// Remote edit — v2: the integration's endpoint is part of its identity\n// (opaque-to-core config); the editable surface is the declared auth-method\n// LIST, through the same shared editor as the add flow. Accounts (credentials)\n// are managed from the integration page's accounts hub. Rendered inside the\n// integration Edit sheet (plugin `editSheet` slot).\n// ---------------------------------------------------------------------------\n\nfunction RemoteEdit(props: {\n server: McpServer & { config: McpRemoteConfig };\n onPendingChange?: EditSheetSectionProps[\"onPendingChange\"];\n}) {\n const { server } = props;\n const doConfigureAuth = useAtomSet(configureMcpAuth, { mode: \"promiseExit\" });\n\n const seeds = useMemo<readonly AuthMethodSeed[]>(\n () =>\n server.config.authenticationTemplate.map(\n (method: McpAuthMethod): AuthMethodSeed => ({\n value: editorValueFromMcpAuthMethod(method),\n slug: method.slug,\n label: methodSeedLabel(method),\n }),\n ),\n [server.config.authenticationTemplate],\n );\n const list = useAuthMethodList(seeds);\n\n const [error, setError] = useState<string | null>(null);\n\n // The edited methods, slugs preserved for seeded rows so existing\n // connections (bound by template slug) stay attached. New rows omit the\n // slug — the backend assigns kind-based ones.\n const editedMethods = useMemo<readonly McpCanonicalAuthMethodInput[]>(\n () =>\n list.rows.map((row: AuthMethodRow): McpCanonicalAuthMethodInput => {\n const input = mcpAuthMethodInputFromEditorValue(row.value);\n return row.seedSlug !== undefined ? { ...input, slug: row.seedSlug } : input;\n }),\n [list.rows],\n );\n\n const methodsChanged = useMemo(() => {\n const stored = server.config.authenticationTemplate;\n if (editedMethods.length !== stored.length) return true;\n return editedMethods.some((method: McpCanonicalAuthMethodInput, index: number) => {\n const current = stored[index];\n if (!current) return true;\n if ((method.slug ?? \"\") !== current.slug) return true;\n if (method.kind !== current.kind) return true;\n if (method.kind === \"apikey\" && current.kind === \"apikey\") {\n return !samePlacements(method.placements, current.placements);\n }\n return false;\n });\n }, [editedMethods, server.config.authenticationTemplate]);\n\n // Staged apply, run by the sheet's Save when the method list changed.\n const applyStaged = useCallback(async (): Promise<EditSheetApplyResult> => {\n setError(null);\n const exit = await doConfigureAuth({\n params: { slug: server.slug },\n payload: {\n authenticationTemplate:\n editedMethods.length > 0\n ? editedMethods.map(mcpWireAuthInput)\n : [{ kind: \"none\" as const }],\n mode: \"replace\",\n },\n reactivityKeys: integrationWriteKeys,\n });\n if (Exit.isFailure(exit)) {\n setError(\"Failed to update authentication methods\");\n return { ok: false };\n }\n return { ok: true, summary: \"Authentication methods updated.\" };\n }, [doConfigureAuth, editedMethods, server.slug]);\n\n const onPendingChangeRef = useRef(props.onPendingChange);\n onPendingChangeRef.current = props.onPendingChange;\n useEffect(() => {\n onPendingChangeRef.current?.(methodsChanged ? applyStaged : null);\n return () => onPendingChangeRef.current?.(null);\n }, [methodsChanged, applyStaged]);\n\n return (\n <div className=\"space-y-4 border-t border-border/60 pt-5\">\n <div className=\"space-y-1\">\n <p className=\"text-sm font-medium text-foreground\">Authentication methods</p>\n <p className=\"text-xs text-muted-foreground\">\n Changes apply when you save. The endpoint (\n <span className=\"font-mono\">{server.config.endpoint}</span>) is part of the server's\n identity — remove and re-add to change it.\n </p>\n </div>\n\n <AuthMethodListEditor\n list={list}\n oauthMetadata=\"discovered\"\n emptyHint=\"No methods declared. Add one, or save to mark this server as open (no authentication).\"\n footerHint=\"Connections pick one of these methods. Removing a method detaches connections created against it.\"\n />\n\n {error && <FormErrorAlert message={error} />}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Stdio read-only view\n// ---------------------------------------------------------------------------\n\nfunction StdioReadOnly(props: {\n server: McpServer & { config: Extract<McpIntegrationConfig, { transport: \"stdio\" }> };\n}) {\n const { command, args } = props.server.config;\n return (\n <div className=\"space-y-3 border-t border-border/60 pt-5\">\n <div className=\"space-y-1\">\n <p className=\"text-sm font-medium text-foreground\">Server command</p>\n <p className=\"text-xs text-muted-foreground\">\n Stdio MCP sources cannot be edited. Remove and recreate the source with the updated\n command.\n </p>\n </div>\n <div className=\"flex items-center gap-3 rounded-md border border-border/60 bg-muted/40 px-3 py-2\">\n <p className=\"min-w-0 flex-1 truncate font-mono text-xs text-foreground\">\n {command} {(args ?? []).join(\" \")}\n </p>\n <Badge variant=\"secondary\" className=\"text-xs\">\n stdio\n </Badge>\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Main component — the mcp plugin's section of the integration Edit sheet.\n// `sourceId` is the integration slug (v2).\n// ---------------------------------------------------------------------------\n\nexport default function EditMcpSource({ sourceId, onPendingChange }: EditSheetSectionProps) {\n const slug = IntegrationSlug.make(sourceId);\n const serverResult = useAtomValue(mcpServerAtom(slug));\n const server = AsyncResult.isSuccess(serverResult) ? serverResult.value : null;\n\n if (!AsyncResult.isSuccess(serverResult) || server === null) return null;\n\n if (server.config.transport === \"stdio\") {\n return (\n <StdioReadOnly\n server={\n server as McpServer & { config: Extract<McpIntegrationConfig, { transport: \"stdio\" }> }\n }\n />\n );\n }\n\n return (\n <RemoteEdit\n server={server as McpServer & { config: McpRemoteConfig }}\n {...(onPendingChange ? { onPendingChange } : {})}\n />\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
mcpAuthMethodInputsFromPlacements,
|
|
5
5
|
mcpServerAtom,
|
|
6
6
|
mcpWireAuthInput
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-AL7N323J.js";
|
|
8
8
|
import "./chunk-3H5Y7JCQ.js";
|
|
9
9
|
|
|
10
10
|
// src/react/McpAccountsPanel.tsx
|
|
@@ -80,4 +80,4 @@ function McpAccountsPanel(props) {
|
|
|
80
80
|
export {
|
|
81
81
|
McpAccountsPanel as default
|
|
82
82
|
};
|
|
83
|
-
//# sourceMappingURL=McpAccountsPanel-
|
|
83
|
+
//# sourceMappingURL=McpAccountsPanel-Y3D6HSPC.js.map
|
package/dist/api/group.d.ts
CHANGED
|
@@ -15,9 +15,13 @@ export declare const McpGroup: HttpApiGroup.HttpApiGroup<"mcp", HttpApiEndpoint.
|
|
|
15
15
|
readonly slug: Schema.String;
|
|
16
16
|
readonly toolCount: Schema.NullOr<Schema.Number>;
|
|
17
17
|
readonly serverName: Schema.NullOr<Schema.String>;
|
|
18
|
+
/** Server `instructions` from initialize — prefills the description field. */
|
|
19
|
+
readonly instructions: Schema.NullOr<Schema.String>;
|
|
18
20
|
}>>, HttpApiEndpoint.Json<typeof InternalError | typeof McpConnectionError | typeof McpToolDiscoveryError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"addServer", "POST", "/mcp/servers", HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Union<readonly [Schema.Struct<{
|
|
19
21
|
readonly transport: Schema.optional<Schema.Literal<"remote">>;
|
|
20
22
|
readonly name: Schema.String;
|
|
23
|
+
/** Agent-visible catalog description. Defaults to the display name. */
|
|
24
|
+
readonly description: Schema.optional<Schema.String>;
|
|
21
25
|
readonly endpoint: Schema.String;
|
|
22
26
|
readonly remoteTransport: Schema.optional<Schema.Literals<readonly ["streamable-http", "sse", "auto"]>>;
|
|
23
27
|
readonly slug: Schema.optional<Schema.String>;
|
|
@@ -57,6 +61,7 @@ export declare const McpGroup: HttpApiGroup.HttpApiGroup<"mcp", HttpApiEndpoint.
|
|
|
57
61
|
}>, Schema.Struct<{
|
|
58
62
|
readonly transport: Schema.Literal<"stdio">;
|
|
59
63
|
readonly name: Schema.String;
|
|
64
|
+
readonly description: Schema.optional<Schema.String>;
|
|
60
65
|
readonly command: Schema.String;
|
|
61
66
|
readonly args: Schema.optional<Schema.$Array<Schema.String>>;
|
|
62
67
|
readonly env: Schema.optional<Schema.$Record<Schema.String, Schema.String>>;
|
package/dist/api/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export declare const mcpHttpPlugin: import("@executor-js/sdk/core").ConfiguredPl
|
|
|
12
12
|
slug: string;
|
|
13
13
|
toolCount: number;
|
|
14
14
|
serverName: string | null;
|
|
15
|
+
instructions: string | null;
|
|
15
16
|
} | {
|
|
16
17
|
connected: false;
|
|
17
18
|
requiresAuthentication: true;
|
|
@@ -21,6 +22,7 @@ export declare const mcpHttpPlugin: import("@executor-js/sdk/core").ConfiguredPl
|
|
|
21
22
|
slug: string;
|
|
22
23
|
toolCount: null;
|
|
23
24
|
serverName: null;
|
|
25
|
+
instructions: null;
|
|
24
26
|
} | {
|
|
25
27
|
connected: false;
|
|
26
28
|
requiresAuthentication: true;
|
|
@@ -30,6 +32,7 @@ export declare const mcpHttpPlugin: import("@executor-js/sdk/core").ConfiguredPl
|
|
|
30
32
|
slug: string;
|
|
31
33
|
toolCount: null;
|
|
32
34
|
serverName: null;
|
|
35
|
+
instructions: null;
|
|
33
36
|
}, import("../sdk").McpConnectionError, never>;
|
|
34
37
|
addServer: (input: import("../promise").McpServerInput) => import("effect/Effect").Effect<{
|
|
35
38
|
slug: string;
|
|
@@ -68,9 +71,11 @@ export declare const mcpHttpPlugin: import("@executor-js/sdk/core").ConfiguredPl
|
|
|
68
71
|
readonly slug: import("effect/Schema").String;
|
|
69
72
|
readonly toolCount: import("effect/Schema").NullOr<import("effect/Schema").Number>;
|
|
70
73
|
readonly serverName: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
74
|
+
readonly instructions: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
71
75
|
}>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("@executor-js/api").InternalError | typeof import("../sdk").McpConnectionError | typeof import("../sdk").McpToolDiscoveryError>, never, never> | import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"addServer", "POST", "/mcp/servers", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Union<readonly [import("effect/Schema").Struct<{
|
|
72
76
|
readonly transport: import("effect/Schema").optional<import("effect/Schema").Literal<"remote">>;
|
|
73
77
|
readonly name: import("effect/Schema").String;
|
|
78
|
+
readonly description: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
74
79
|
readonly endpoint: import("effect/Schema").String;
|
|
75
80
|
readonly remoteTransport: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["streamable-http", "sse", "auto"]>>;
|
|
76
81
|
readonly slug: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
@@ -107,6 +112,7 @@ export declare const mcpHttpPlugin: import("@executor-js/sdk/core").ConfiguredPl
|
|
|
107
112
|
}>, import("effect/Schema").Struct<{
|
|
108
113
|
readonly transport: import("effect/Schema").Literal<"stdio">;
|
|
109
114
|
readonly name: import("effect/Schema").String;
|
|
115
|
+
readonly description: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
110
116
|
readonly command: import("effect/Schema").String;
|
|
111
117
|
readonly args: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").String>>;
|
|
112
118
|
readonly env: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").String>>;
|
|
@@ -30,6 +30,8 @@ var StringMap = Schema.Record(Schema.String, Schema.String);
|
|
|
30
30
|
var AddRemoteServerPayload = Schema.Struct({
|
|
31
31
|
transport: Schema.optional(Schema.Literal("remote")),
|
|
32
32
|
name: Schema.String,
|
|
33
|
+
/** Agent-visible catalog description. Defaults to the display name. */
|
|
34
|
+
description: Schema.optional(Schema.String),
|
|
33
35
|
endpoint: Schema.String,
|
|
34
36
|
remoteTransport: Schema.optional(Schema.Literals(["streamable-http", "sse", "auto"])),
|
|
35
37
|
slug: Schema.optional(Schema.String),
|
|
@@ -44,6 +46,7 @@ var AddRemoteServerPayload = Schema.Struct({
|
|
|
44
46
|
var AddStdioServerPayload = Schema.Struct({
|
|
45
47
|
transport: Schema.Literal("stdio"),
|
|
46
48
|
name: Schema.String,
|
|
49
|
+
description: Schema.optional(Schema.String),
|
|
47
50
|
command: Schema.String,
|
|
48
51
|
args: Schema.optional(Schema.Array(Schema.String)),
|
|
49
52
|
env: Schema.optional(StringMap),
|
|
@@ -64,7 +67,9 @@ var ProbeEndpointResponse = Schema.Struct({
|
|
|
64
67
|
name: Schema.String,
|
|
65
68
|
slug: Schema.String,
|
|
66
69
|
toolCount: Schema.NullOr(Schema.Number),
|
|
67
|
-
serverName: Schema.NullOr(Schema.String)
|
|
70
|
+
serverName: Schema.NullOr(Schema.String),
|
|
71
|
+
/** Server `instructions` from initialize — prefills the description field. */
|
|
72
|
+
instructions: Schema.NullOr(Schema.String)
|
|
68
73
|
});
|
|
69
74
|
var AddServerResponse = Schema.Struct({
|
|
70
75
|
slug: Schema.String
|
|
@@ -212,4 +217,4 @@ export {
|
|
|
212
217
|
authMethodsFromConfig,
|
|
213
218
|
mcpAuthMethodInputsFromPlacements
|
|
214
219
|
};
|
|
215
|
-
//# sourceMappingURL=chunk-
|
|
220
|
+
//# sourceMappingURL=chunk-AL7N323J.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/atoms.ts","../src/react/client.ts","../src/api/group.ts","../src/react/auth-method-config.ts"],"sourcesContent":["import type { IntegrationSlug } from \"@executor-js/sdk/shared\";\nimport { ReactivityKey } from \"@executor-js/react/api/reactivity-keys\";\nimport { McpClient } from \"./client\";\n\n// ---------------------------------------------------------------------------\n// Query atoms (v2)\n//\n// An MCP server is an integration. `getServer` reads the integration row's\n// opaque config (transport, endpoint, auth template). Credentials are separate\n// owner-scoped connections, created through the core connections / oauth surface\n// — there is no per-server credential binding to read here anymore.\n// ---------------------------------------------------------------------------\n\nexport const mcpServerAtom = (slug: IntegrationSlug) =>\n McpClient.query(\"mcp\", \"getServer\", {\n params: { slug },\n timeToLive: \"15 seconds\",\n reactivityKeys: [ReactivityKey.integrations, ReactivityKey.tools],\n });\n\n// ---------------------------------------------------------------------------\n// Mutation atoms\n// ---------------------------------------------------------------------------\n\nexport const probeMcpEndpoint = McpClient.mutation(\"mcp\", \"probeEndpoint\");\nexport const addMcpServer = McpClient.mutation(\"mcp\", \"addServer\");\nexport const removeMcpServer = McpClient.mutation(\"mcp\", \"removeServer\");\nexport const configureMcpServer = McpClient.mutation(\"mcp\", \"configureServer\");\n// Merge-append auth methods onto an integration's `authenticationTemplate`.\nexport const configureMcpAuth = McpClient.mutation(\"mcp\", \"configureAuth\");\n","import { createPluginAtomClient } from \"@executor-js/sdk/client\";\nimport {\n getExecutorApiBaseUrl,\n getExecutorServerAuthorizationHeader,\n} from \"@executor-js/react/api/server-connection\";\nimport { McpGroup } from \"../api/group\";\n\nexport const McpClient = createPluginAtomClient(McpGroup, {\n baseUrl: getExecutorApiBaseUrl,\n authorizationHeader: getExecutorServerAuthorizationHeader,\n});\n","import { HttpApiEndpoint, HttpApiGroup } from \"effect/unstable/httpapi\";\nimport { Schema } from \"effect\";\nimport {\n IntegrationSlug,\n InternalError,\n IntegrationAlreadyExistsError,\n} from \"@executor-js/sdk/shared\";\n\nimport { McpConnectionError, McpToolDiscoveryError } from \"../sdk/errors\";\nimport {\n McpAuthMethod,\n McpAuthMethodInput,\n McpAuthShorthand,\n McpIntegrationConfig,\n} from \"../sdk/types\";\n\n// ---------------------------------------------------------------------------\n// Params\n// ---------------------------------------------------------------------------\n\nconst SlugParams = { slug: IntegrationSlug };\n\nconst StringMap = Schema.Record(Schema.String, Schema.String);\n\n// ---------------------------------------------------------------------------\n// Add server — discriminated union on transport. An MCP server is registered\n// as an integration; connections (credentials) are created separately through\n// the core connections / oauth surface.\n// ---------------------------------------------------------------------------\n\nconst AddRemoteServerPayload = Schema.Struct({\n transport: Schema.optional(Schema.Literal(\"remote\")),\n name: Schema.String,\n /** Agent-visible catalog description. Defaults to the display name. */\n description: Schema.optional(Schema.String),\n endpoint: Schema.String,\n remoteTransport: Schema.optional(Schema.Literals([\"streamable-http\", \"sse\", \"auto\"])),\n slug: Schema.optional(Schema.String),\n queryParams: Schema.optional(StringMap),\n headers: Schema.optional(StringMap),\n /** Declared auth methods a connection can be applied through. */\n authenticationTemplate: Schema.optional(Schema.Array(McpAuthMethodInput)),\n /** Single-method shorthand (legacy callers); ignored when\n * `authenticationTemplate` is present. */\n auth: Schema.optional(McpAuthShorthand),\n});\n\nconst AddStdioServerPayload = Schema.Struct({\n transport: Schema.Literal(\"stdio\"),\n name: Schema.String,\n description: Schema.optional(Schema.String),\n command: Schema.String,\n args: Schema.optional(Schema.Array(Schema.String)),\n env: Schema.optional(StringMap),\n cwd: Schema.optional(Schema.String),\n slug: Schema.optional(Schema.String),\n});\n\nconst AddServerPayload = Schema.Union([AddRemoteServerPayload, AddStdioServerPayload]);\n\nconst ProbeEndpointPayload = Schema.Struct({\n endpoint: Schema.String,\n headers: Schema.optional(StringMap),\n queryParams: Schema.optional(StringMap),\n});\n\nconst ProbeEndpointResponse = Schema.Struct({\n connected: Schema.Boolean,\n requiresAuthentication: Schema.Boolean,\n requiresOAuth: Schema.Boolean,\n supportsDynamicRegistration: Schema.Boolean,\n name: Schema.String,\n slug: Schema.String,\n toolCount: Schema.NullOr(Schema.Number),\n serverName: Schema.NullOr(Schema.String),\n /** Server `instructions` from initialize — prefills the description field. */\n instructions: Schema.NullOr(Schema.String),\n});\n\n// ---------------------------------------------------------------------------\n// Responses\n// ---------------------------------------------------------------------------\n\nconst AddServerResponse = Schema.Struct({\n slug: Schema.String,\n});\n\nconst RemoveServerResponse = Schema.Struct({\n removed: Schema.Boolean,\n});\n\nconst ConfigureServerPayload = Schema.Struct({\n config: McpIntegrationConfig,\n});\n\nconst ConfigureServerResponse = Schema.Struct({\n config: McpIntegrationConfig,\n});\n\n// The configureAuth payload/response — custom auth methods to merge-append\n// onto the integration's `authenticationTemplate` (or `replace` the set).\n// Mirrors the GraphQL/OpenAPI configure endpoints.\nconst ConfigureAuthPayload = Schema.Struct({\n authenticationTemplate: Schema.Array(McpAuthMethodInput),\n mode: Schema.optional(Schema.Literals([\"merge\", \"replace\"])),\n});\n\nconst ConfigureAuthResponse = Schema.Struct({\n authenticationTemplate: Schema.Array(McpAuthMethod),\n});\n\nconst GetServerResponse = Schema.NullOr(\n Schema.Struct({\n slug: IntegrationSlug,\n description: Schema.String,\n kind: Schema.String,\n canRemove: Schema.Boolean,\n canRefresh: Schema.Boolean,\n config: McpIntegrationConfig,\n }),\n);\n\n// ---------------------------------------------------------------------------\n// Group\n//\n// Integrations are tenant-level (no scope segment); plugin domain errors carry\n// their own `HttpApiSchema` status (4xx). `InternalError` is the shared opaque\n// 500 translated at the HTTP edge.\n// ---------------------------------------------------------------------------\n\nexport const McpGroup = HttpApiGroup.make(\"mcp\")\n .add(\n HttpApiEndpoint.post(\"probeEndpoint\", \"/mcp/probe\", {\n payload: ProbeEndpointPayload,\n success: ProbeEndpointResponse,\n error: [InternalError, McpConnectionError, McpToolDiscoveryError],\n }),\n )\n .add(\n HttpApiEndpoint.post(\"addServer\", \"/mcp/servers\", {\n payload: AddServerPayload,\n success: AddServerResponse,\n error: [\n InternalError,\n McpConnectionError,\n McpToolDiscoveryError,\n IntegrationAlreadyExistsError,\n ],\n }),\n )\n .add(\n HttpApiEndpoint.delete(\"removeServer\", \"/mcp/servers/:slug\", {\n params: SlugParams,\n success: RemoveServerResponse,\n error: [InternalError, McpConnectionError, McpToolDiscoveryError],\n }),\n )\n .add(\n HttpApiEndpoint.get(\"getServer\", \"/mcp/servers/:slug\", {\n params: SlugParams,\n success: GetServerResponse,\n error: [InternalError, McpConnectionError, McpToolDiscoveryError],\n }),\n )\n .add(\n HttpApiEndpoint.post(\"configureServer\", \"/mcp/servers/:slug/config\", {\n params: SlugParams,\n payload: ConfigureServerPayload,\n success: ConfigureServerResponse,\n error: [InternalError, McpConnectionError, McpToolDiscoveryError],\n }),\n )\n .add(\n HttpApiEndpoint.post(\"configureAuth\", \"/mcp/servers/:slug/auth\", {\n params: SlugParams,\n payload: ConfigureAuthPayload,\n success: ConfigureAuthResponse,\n error: [InternalError, McpConnectionError, McpToolDiscoveryError],\n }),\n );\n","// ---------------------------------------------------------------------------\n// MCP ↔ generic auth-method converters — a thin oauth adapter over the shared\n// codec (`@executor-js/react/lib/shared-auth-method-codec`). The apikey/none\n// paths (multi-placement, multi-variable) live in the shared codec; MCP only\n// contributes its oauth flavor: endpoint-less methods whose metadata is\n// discovered at connect time (`discoveryUrl` = the MCP endpoint).\n// ---------------------------------------------------------------------------\n\nimport { AuthTemplateSlug } from \"@executor-js/sdk/shared\";\nimport type { AuthTemplateEditorValue } from \"@executor-js/react/components/auth-template-editor\";\nimport type { AuthMethod, Placement } from \"@executor-js/react/lib/auth-placements\";\nimport {\n authMethodFromSharedTemplate,\n editorValueFromSharedMethod,\n sharedMethodInputFromEditorValue,\n wirePlacementsFromEditor,\n} from \"@executor-js/react/lib/shared-auth-method-codec\";\n\nimport { wireAuthInputFromShared } from \"@executor-js/react/lib/shared-auth-method-codec\";\nimport type { McpAuthMethod, McpAuthMethodInput, McpCanonicalAuthMethodInput } from \"../sdk/types\";\n\n/** Serialize a canonical method into the wire input union (apikey → the\n * request-shaped dialect; none/oauth2 pass through). */\nexport const mcpWireAuthInput = (\n method: McpAuthMethod | McpCanonicalAuthMethodInput,\n): McpAuthMethodInput => wireAuthInputFromShared(method) as McpAuthMethodInput;\n\nconst oauthAuthMethod = (slug: string, endpoint: string): AuthMethod => ({\n id: slug,\n label: \"OAuth\",\n kind: \"oauth\",\n source: slug.startsWith(\"custom_\") ? \"custom\" : \"spec\",\n template: AuthTemplateSlug.make(slug),\n placements: [],\n oauth: { discoveryUrl: endpoint, supportsDynamicRegistration: true },\n});\n\n/** Convert a generic editor value into one MCP auth-method input (no slug —\n * the backend assigns carrier-derived slugs). An apikey value keeps every\n * named placement (headers and query params mix freely); one with no usable\n * placement falls back to `none`. */\nexport function mcpAuthMethodInputFromEditorValue(\n value: AuthTemplateEditorValue,\n): McpCanonicalAuthMethodInput {\n if (value.kind === \"oauth\") return { kind: \"oauth2\" };\n return (sharedMethodInputFromEditorValue(value) ?? {\n kind: \"none\",\n }) as McpCanonicalAuthMethodInput;\n}\n\n/** Convert one stored MCP method into the generic editor value. */\nexport function editorValueFromMcpAuthMethod(method: McpAuthMethod): AuthTemplateEditorValue {\n if (method.kind === \"oauth2\") {\n return { kind: \"oauth\", authorizationUrl: \"\", tokenUrl: \"\", scopes: [] };\n }\n return editorValueFromSharedMethod(method);\n}\n\n/** Project the stored methods into the generic `AuthMethod[]` the hub renders.\n * Mirrors the server's `describeMcpAuthMethods`; `custom_` slugs mark\n * user-created methods (removable from the hub). `endpoint` feeds the oauth\n * method's probe-at-connect `discoveryUrl`. */\nexport function authMethodsFromConfig(\n methods: readonly McpAuthMethod[],\n endpoint: string,\n): AuthMethod[] {\n return methods.map((method: McpAuthMethod): AuthMethod => {\n if (method.kind === \"oauth2\") return oauthAuthMethod(method.slug, endpoint);\n return authMethodFromSharedTemplate(method);\n });\n}\n\n/** Build the MCP method input for a custom method from generic placements —\n * ONE method carrying every named placement (header + query mix in a single\n * method; each placement renders from its own input variable, or shares one).\n * Empty when no placement is usable. */\nexport function mcpAuthMethodInputsFromPlacements(\n placements: readonly Placement[],\n): McpCanonicalAuthMethodInput[] {\n const wire = wirePlacementsFromEditor(placements);\n if (wire.length === 0) return [];\n return [{ kind: \"apikey\", placements: wire }];\n}\n"],"mappings":"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","names":[]}
|