@assistant-ui/react-mcp 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/buildHeaders.d.ts +9 -0
- package/dist/auth/buildHeaders.d.ts.map +1 -0
- package/dist/auth/buildHeaders.js +15 -0
- package/dist/auth/buildHeaders.js.map +1 -0
- package/dist/auth/createOAuthProvider.d.ts +22 -0
- package/dist/auth/createOAuthProvider.d.ts.map +1 -0
- package/dist/auth/createOAuthProvider.js +148 -0
- package/dist/auth/createOAuthProvider.js.map +1 -0
- package/dist/auth/types.d.ts +9 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +2 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/connector.d.ts +3 -0
- package/dist/connector.d.ts.map +1 -0
- package/dist/connector.js +6 -0
- package/dist/connector.js.map +1 -0
- package/dist/context/McpConnectorByIndexProvider.d.ts +5 -0
- package/dist/context/McpConnectorByIndexProvider.d.ts.map +1 -0
- package/dist/context/McpConnectorByIndexProvider.js +13 -0
- package/dist/context/McpConnectorByIndexProvider.js.map +1 -0
- package/dist/context/McpCustomServerByIndexProvider.d.ts +5 -0
- package/dist/context/McpCustomServerByIndexProvider.d.ts.map +1 -0
- package/dist/context/McpCustomServerByIndexProvider.js +13 -0
- package/dist/context/McpCustomServerByIndexProvider.js.map +1 -0
- package/dist/context/McpServerByIdProvider.d.ts +5 -0
- package/dist/context/McpServerByIdProvider.d.ts.map +1 -0
- package/dist/context/McpServerByIdProvider.js +13 -0
- package/dist/context/McpServerByIdProvider.js.map +1 -0
- package/dist/hooks/useMcpOAuthCallback.d.ts +17 -0
- package/dist/hooks/useMcpOAuthCallback.d.ts.map +1 -0
- package/dist/hooks/useMcpOAuthCallback.js +59 -0
- package/dist/hooks/useMcpOAuthCallback.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-scope.d.ts +109 -0
- package/dist/mcp-scope.d.ts.map +1 -0
- package/dist/mcp-scope.js +2 -0
- package/dist/mcp-scope.js.map +1 -0
- package/dist/primitives/addForm/McpAddFormAuthFields.d.ts +15 -0
- package/dist/primitives/addForm/McpAddFormAuthFields.d.ts.map +1 -0
- package/dist/primitives/addForm/McpAddFormAuthFields.js +18 -0
- package/dist/primitives/addForm/McpAddFormAuthFields.js.map +1 -0
- package/dist/primitives/addForm/McpAddFormAuthSelect.d.ts +8 -0
- package/dist/primitives/addForm/McpAddFormAuthSelect.d.ts.map +1 -0
- package/dist/primitives/addForm/McpAddFormAuthSelect.js +24 -0
- package/dist/primitives/addForm/McpAddFormAuthSelect.js.map +1 -0
- package/dist/primitives/addForm/McpAddFormCancel.d.ts +10 -0
- package/dist/primitives/addForm/McpAddFormCancel.d.ts.map +1 -0
- package/dist/primitives/addForm/McpAddFormCancel.js +15 -0
- package/dist/primitives/addForm/McpAddFormCancel.js.map +1 -0
- package/dist/primitives/addForm/McpAddFormError.d.ts +10 -0
- package/dist/primitives/addForm/McpAddFormError.d.ts.map +1 -0
- package/dist/primitives/addForm/McpAddFormError.js +12 -0
- package/dist/primitives/addForm/McpAddFormError.js.map +1 -0
- package/dist/primitives/addForm/McpAddFormNameField.d.ts +8 -0
- package/dist/primitives/addForm/McpAddFormNameField.d.ts.map +1 -0
- package/dist/primitives/addForm/McpAddFormNameField.js +10 -0
- package/dist/primitives/addForm/McpAddFormNameField.js.map +1 -0
- package/dist/primitives/addForm/McpAddFormRoot.d.ts +16 -0
- package/dist/primitives/addForm/McpAddFormRoot.d.ts.map +1 -0
- package/dist/primitives/addForm/McpAddFormRoot.js +102 -0
- package/dist/primitives/addForm/McpAddFormRoot.js.map +1 -0
- package/dist/primitives/addForm/McpAddFormSubmit.d.ts +10 -0
- package/dist/primitives/addForm/McpAddFormSubmit.d.ts.map +1 -0
- package/dist/primitives/addForm/McpAddFormSubmit.js +10 -0
- package/dist/primitives/addForm/McpAddFormSubmit.js.map +1 -0
- package/dist/primitives/addForm/McpAddFormUrlField.d.ts +8 -0
- package/dist/primitives/addForm/McpAddFormUrlField.d.ts.map +1 -0
- package/dist/primitives/addForm/McpAddFormUrlField.js +10 -0
- package/dist/primitives/addForm/McpAddFormUrlField.js.map +1 -0
- package/dist/primitives/addForm/context.d.ts +21 -0
- package/dist/primitives/addForm/context.d.ts.map +1 -0
- package/dist/primitives/addForm/context.js +10 -0
- package/dist/primitives/addForm/context.js.map +1 -0
- package/dist/primitives/addForm.d.ts +9 -0
- package/dist/primitives/addForm.d.ts.map +1 -0
- package/dist/primitives/addForm.js +9 -0
- package/dist/primitives/addForm.js.map +1 -0
- package/dist/primitives/manager/McpManagerAddCustomTrigger.d.ts +10 -0
- package/dist/primitives/manager/McpManagerAddCustomTrigger.d.ts.map +1 -0
- package/dist/primitives/manager/McpManagerAddCustomTrigger.js +9 -0
- package/dist/primitives/manager/McpManagerAddCustomTrigger.js.map +1 -0
- package/dist/primitives/manager/McpManagerConnectors.d.ts +31 -0
- package/dist/primitives/manager/McpManagerConnectors.d.ts.map +1 -0
- package/dist/primitives/manager/McpManagerConnectors.js +41 -0
- package/dist/primitives/manager/McpManagerConnectors.js.map +1 -0
- package/dist/primitives/manager/McpManagerCustomServers.d.ts +31 -0
- package/dist/primitives/manager/McpManagerCustomServers.d.ts.map +1 -0
- package/dist/primitives/manager/McpManagerCustomServers.js +37 -0
- package/dist/primitives/manager/McpManagerCustomServers.js.map +1 -0
- package/dist/primitives/manager/McpManagerRoot.d.ts +10 -0
- package/dist/primitives/manager/McpManagerRoot.d.ts.map +1 -0
- package/dist/primitives/manager/McpManagerRoot.js +10 -0
- package/dist/primitives/manager/McpManagerRoot.js.map +1 -0
- package/dist/primitives/manager.d.ts +5 -0
- package/dist/primitives/manager.d.ts.map +1 -0
- package/dist/primitives/manager.js +5 -0
- package/dist/primitives/manager.js.map +1 -0
- package/dist/primitives/server/McpServerConnectButton.d.ts +10 -0
- package/dist/primitives/server/McpServerConnectButton.d.ts.map +1 -0
- package/dist/primitives/server/McpServerConnectButton.js +20 -0
- package/dist/primitives/server/McpServerConnectButton.js.map +1 -0
- package/dist/primitives/server/McpServerDisconnectButton.d.ts +10 -0
- package/dist/primitives/server/McpServerDisconnectButton.d.ts.map +1 -0
- package/dist/primitives/server/McpServerDisconnectButton.js +20 -0
- package/dist/primitives/server/McpServerDisconnectButton.js.map +1 -0
- package/dist/primitives/server/McpServerError.d.ts +10 -0
- package/dist/primitives/server/McpServerError.d.ts.map +1 -0
- package/dist/primitives/server/McpServerError.js +12 -0
- package/dist/primitives/server/McpServerError.js.map +1 -0
- package/dist/primitives/server/McpServerIcon.d.ts +18 -0
- package/dist/primitives/server/McpServerIcon.d.ts.map +1 -0
- package/dist/primitives/server/McpServerIcon.js +14 -0
- package/dist/primitives/server/McpServerIcon.js.map +1 -0
- package/dist/primitives/server/McpServerName.d.ts +10 -0
- package/dist/primitives/server/McpServerName.d.ts.map +1 -0
- package/dist/primitives/server/McpServerName.js +10 -0
- package/dist/primitives/server/McpServerName.js.map +1 -0
- package/dist/primitives/server/McpServerOAuthLink.d.ts +16 -0
- package/dist/primitives/server/McpServerOAuthLink.d.ts.map +1 -0
- package/dist/primitives/server/McpServerOAuthLink.js +13 -0
- package/dist/primitives/server/McpServerOAuthLink.js.map +1 -0
- package/dist/primitives/server/McpServerRemoveButton.d.ts +10 -0
- package/dist/primitives/server/McpServerRemoveButton.d.ts.map +1 -0
- package/dist/primitives/server/McpServerRemoveButton.js +18 -0
- package/dist/primitives/server/McpServerRemoveButton.js.map +1 -0
- package/dist/primitives/server/McpServerRoot.d.ts +10 -0
- package/dist/primitives/server/McpServerRoot.d.ts.map +1 -0
- package/dist/primitives/server/McpServerRoot.js +13 -0
- package/dist/primitives/server/McpServerRoot.js.map +1 -0
- package/dist/primitives/server/McpServerStatus.d.ts +10 -0
- package/dist/primitives/server/McpServerStatus.d.ts.map +1 -0
- package/dist/primitives/server/McpServerStatus.js +10 -0
- package/dist/primitives/server/McpServerStatus.js.map +1 -0
- package/dist/primitives/server/McpServerToolName.d.ts +10 -0
- package/dist/primitives/server/McpServerToolName.d.ts.map +1 -0
- package/dist/primitives/server/McpServerToolName.js +10 -0
- package/dist/primitives/server/McpServerToolName.js.map +1 -0
- package/dist/primitives/server/McpServerTools.d.ts +10 -0
- package/dist/primitives/server/McpServerTools.d.ts.map +1 -0
- package/dist/primitives/server/McpServerTools.js +19 -0
- package/dist/primitives/server/McpServerTools.js.map +1 -0
- package/dist/primitives/server.d.ts +12 -0
- package/dist/primitives/server.d.ts.map +1 -0
- package/dist/primitives/server.js +12 -0
- package/dist/primitives/server.js.map +1 -0
- package/dist/resources/McpManagerResource.d.ts +13 -0
- package/dist/resources/McpManagerResource.d.ts.map +1 -0
- package/dist/resources/McpManagerResource.js +191 -0
- package/dist/resources/McpManagerResource.js.map +1 -0
- package/dist/resources/McpServerResource.d.ts +17 -0
- package/dist/resources/McpServerResource.d.ts.map +1 -0
- package/dist/resources/McpServerResource.js +239 -0
- package/dist/resources/McpServerResource.js.map +1 -0
- package/dist/resources/storage/McpCustomStorage.d.ts +3 -0
- package/dist/resources/storage/McpCustomStorage.d.ts.map +1 -0
- package/dist/resources/storage/McpCustomStorage.js +3 -0
- package/dist/resources/storage/McpCustomStorage.js.map +1 -0
- package/dist/resources/storage/McpLocalStorage.d.ts +9 -0
- package/dist/resources/storage/McpLocalStorage.d.ts.map +1 -0
- package/dist/resources/storage/McpLocalStorage.js +67 -0
- package/dist/resources/storage/McpLocalStorage.js.map +1 -0
- package/dist/resources/storage/McpMemoryStorage.d.ts +3 -0
- package/dist/resources/storage/McpMemoryStorage.d.ts.map +1 -0
- package/dist/resources/storage/McpMemoryStorage.js +19 -0
- package/dist/resources/storage/McpMemoryStorage.js.map +1 -0
- package/dist/resources/storage/types.d.ts +12 -0
- package/dist/resources/storage/types.d.ts.map +1 -0
- package/dist/resources/storage/types.js +2 -0
- package/dist/resources/storage/types.js.map +1 -0
- package/dist/utils/serverId.d.ts +2 -0
- package/dist/utils/serverId.d.ts.map +1 -0
- package/dist/utils/serverId.js +16 -0
- package/dist/utils/serverId.js.map +1 -0
- package/package.json +67 -0
- package/src/auth/buildHeaders.ts +19 -0
- package/src/auth/createOAuthProvider.ts +172 -0
- package/src/auth/types.ts +12 -0
- package/src/connector.ts +7 -0
- package/src/context/McpConnectorByIndexProvider.tsx +16 -0
- package/src/context/McpCustomServerByIndexProvider.tsx +16 -0
- package/src/context/McpServerByIdProvider.tsx +17 -0
- package/src/hooks/useMcpOAuthCallback.tsx +79 -0
- package/src/index.ts +68 -0
- package/src/mcp-scope.ts +110 -0
- package/src/primitives/addForm/McpAddFormAuthFields.tsx +51 -0
- package/src/primitives/addForm/McpAddFormAuthSelect.tsx +55 -0
- package/src/primitives/addForm/McpAddFormCancel.tsx +33 -0
- package/src/primitives/addForm/McpAddFormError.tsx +27 -0
- package/src/primitives/addForm/McpAddFormNameField.tsx +34 -0
- package/src/primitives/addForm/McpAddFormRoot.tsx +141 -0
- package/src/primitives/addForm/McpAddFormSubmit.tsx +30 -0
- package/src/primitives/addForm/McpAddFormUrlField.tsx +35 -0
- package/src/primitives/addForm/context.tsx +37 -0
- package/src/primitives/addForm.ts +8 -0
- package/src/primitives/manager/McpManagerAddCustomTrigger.tsx +21 -0
- package/src/primitives/manager/McpManagerConnectors.tsx +76 -0
- package/src/primitives/manager/McpManagerCustomServers.tsx +72 -0
- package/src/primitives/manager/McpManagerRoot.tsx +28 -0
- package/src/primitives/manager.ts +4 -0
- package/src/primitives/server/McpServerConnectButton.tsx +39 -0
- package/src/primitives/server/McpServerDisconnectButton.tsx +38 -0
- package/src/primitives/server/McpServerError.tsx +27 -0
- package/src/primitives/server/McpServerIcon.tsx +35 -0
- package/src/primitives/server/McpServerName.tsx +26 -0
- package/src/primitives/server/McpServerOAuthLink.tsx +38 -0
- package/src/primitives/server/McpServerRemoveButton.tsx +35 -0
- package/src/primitives/server/McpServerRoot.tsx +35 -0
- package/src/primitives/server/McpServerStatus.tsx +26 -0
- package/src/primitives/server/McpServerToolName.tsx +26 -0
- package/src/primitives/server/McpServerTools.tsx +39 -0
- package/src/primitives/server.ts +14 -0
- package/src/resources/McpManagerResource.ts +253 -0
- package/src/resources/McpServerResource.ts +292 -0
- package/src/resources/storage/McpCustomStorage.ts +6 -0
- package/src/resources/storage/McpLocalStorage.ts +77 -0
- package/src/resources/storage/McpMemoryStorage.ts +22 -0
- package/src/resources/storage/types.ts +16 -0
- package/src/utils/serverId.ts +19 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ComponentPropsWithoutRef,
|
|
3
|
+
type ComponentRef,
|
|
4
|
+
forwardRef,
|
|
5
|
+
} from "react";
|
|
6
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
7
|
+
import { useAddForm, type AddFormAuthType } from "./context";
|
|
8
|
+
|
|
9
|
+
const AUTH_TYPES: ReadonlySet<AddFormAuthType> = new Set([
|
|
10
|
+
"none",
|
|
11
|
+
"bearer",
|
|
12
|
+
"oauth",
|
|
13
|
+
]);
|
|
14
|
+
|
|
15
|
+
function asAuthType(value: string): AddFormAuthType | null {
|
|
16
|
+
return (AUTH_TYPES as ReadonlySet<string>).has(value)
|
|
17
|
+
? (value as AddFormAuthType)
|
|
18
|
+
: null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export namespace McpAddFormPrimitiveAuthSelect {
|
|
22
|
+
export type Element = ComponentRef<typeof Primitive.select>;
|
|
23
|
+
export type Props = Omit<
|
|
24
|
+
ComponentPropsWithoutRef<typeof Primitive.select>,
|
|
25
|
+
"value" | "onChange"
|
|
26
|
+
>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const McpAddFormPrimitiveAuthSelect = forwardRef<
|
|
30
|
+
McpAddFormPrimitiveAuthSelect.Element,
|
|
31
|
+
McpAddFormPrimitiveAuthSelect.Props
|
|
32
|
+
>((props, ref) => {
|
|
33
|
+
const { state, setField } = useAddForm();
|
|
34
|
+
return (
|
|
35
|
+
<Primitive.select
|
|
36
|
+
{...props}
|
|
37
|
+
ref={ref}
|
|
38
|
+
value={state.authType}
|
|
39
|
+
onChange={(e) => {
|
|
40
|
+
const next = asAuthType(e.target.value);
|
|
41
|
+
if (next) setField("authType", next);
|
|
42
|
+
}}
|
|
43
|
+
>
|
|
44
|
+
{props.children ?? (
|
|
45
|
+
<>
|
|
46
|
+
<option value="oauth">OAuth</option>
|
|
47
|
+
<option value="bearer">Bearer token</option>
|
|
48
|
+
<option value="none">None</option>
|
|
49
|
+
</>
|
|
50
|
+
)}
|
|
51
|
+
</Primitive.select>
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
McpAddFormPrimitiveAuthSelect.displayName = "McpAddFormPrimitive.AuthSelect";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ComponentPropsWithoutRef,
|
|
3
|
+
type ComponentRef,
|
|
4
|
+
forwardRef,
|
|
5
|
+
} from "react";
|
|
6
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
7
|
+
import { useAddForm } from "./context";
|
|
8
|
+
|
|
9
|
+
export namespace McpAddFormPrimitiveCancel {
|
|
10
|
+
export type Element = ComponentRef<typeof Primitive.button>;
|
|
11
|
+
export type Props = ComponentPropsWithoutRef<typeof Primitive.button>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const McpAddFormPrimitiveCancel = forwardRef<
|
|
15
|
+
McpAddFormPrimitiveCancel.Element,
|
|
16
|
+
McpAddFormPrimitiveCancel.Props
|
|
17
|
+
>((props, ref) => {
|
|
18
|
+
const { cancel } = useAddForm();
|
|
19
|
+
return (
|
|
20
|
+
<Primitive.button
|
|
21
|
+
{...props}
|
|
22
|
+
type="button"
|
|
23
|
+
ref={ref}
|
|
24
|
+
onClick={(e) => {
|
|
25
|
+
props.onClick?.(e);
|
|
26
|
+
if (e.defaultPrevented) return;
|
|
27
|
+
cancel();
|
|
28
|
+
}}
|
|
29
|
+
/>
|
|
30
|
+
);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
McpAddFormPrimitiveCancel.displayName = "McpAddFormPrimitive.Cancel";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ComponentPropsWithoutRef,
|
|
3
|
+
type ComponentRef,
|
|
4
|
+
forwardRef,
|
|
5
|
+
} from "react";
|
|
6
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
7
|
+
import { useAddForm } from "./context";
|
|
8
|
+
|
|
9
|
+
export namespace McpAddFormPrimitiveError {
|
|
10
|
+
export type Element = ComponentRef<typeof Primitive.div>;
|
|
11
|
+
export type Props = ComponentPropsWithoutRef<typeof Primitive.div>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const McpAddFormPrimitiveError = forwardRef<
|
|
15
|
+
McpAddFormPrimitiveError.Element,
|
|
16
|
+
McpAddFormPrimitiveError.Props
|
|
17
|
+
>((props, ref) => {
|
|
18
|
+
const { state } = useAddForm();
|
|
19
|
+
if (!state.error) return null;
|
|
20
|
+
return (
|
|
21
|
+
<Primitive.div {...props} ref={ref}>
|
|
22
|
+
{props.children ?? state.error}
|
|
23
|
+
</Primitive.div>
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
McpAddFormPrimitiveError.displayName = "McpAddFormPrimitive.Error";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ComponentPropsWithoutRef,
|
|
3
|
+
type ComponentRef,
|
|
4
|
+
forwardRef,
|
|
5
|
+
} from "react";
|
|
6
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
7
|
+
import { useAddForm } from "./context";
|
|
8
|
+
|
|
9
|
+
export namespace McpAddFormPrimitiveNameField {
|
|
10
|
+
export type Element = ComponentRef<typeof Primitive.input>;
|
|
11
|
+
export type Props = Omit<
|
|
12
|
+
ComponentPropsWithoutRef<typeof Primitive.input>,
|
|
13
|
+
"value" | "onChange" | "type"
|
|
14
|
+
>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const McpAddFormPrimitiveNameField = forwardRef<
|
|
18
|
+
McpAddFormPrimitiveNameField.Element,
|
|
19
|
+
McpAddFormPrimitiveNameField.Props
|
|
20
|
+
>((props, ref) => {
|
|
21
|
+
const { state, setField } = useAddForm();
|
|
22
|
+
return (
|
|
23
|
+
<Primitive.input
|
|
24
|
+
type="text"
|
|
25
|
+
placeholder="Name"
|
|
26
|
+
{...props}
|
|
27
|
+
ref={ref}
|
|
28
|
+
value={state.name}
|
|
29
|
+
onChange={(e) => setField("name", e.target.value)}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
McpAddFormPrimitiveNameField.displayName = "McpAddFormPrimitive.NameField";
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ComponentPropsWithoutRef,
|
|
3
|
+
type ComponentRef,
|
|
4
|
+
type FormEventHandler,
|
|
5
|
+
forwardRef,
|
|
6
|
+
useCallback,
|
|
7
|
+
useMemo,
|
|
8
|
+
useState,
|
|
9
|
+
} from "react";
|
|
10
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
11
|
+
import { useAui } from "@assistant-ui/store";
|
|
12
|
+
import { AddFormContext, type AddFormState } from "./context";
|
|
13
|
+
import type { MCPAuthConfig } from "../../mcp-scope";
|
|
14
|
+
|
|
15
|
+
const INITIAL: AddFormState = {
|
|
16
|
+
name: "",
|
|
17
|
+
url: "",
|
|
18
|
+
authType: "oauth",
|
|
19
|
+
bearerToken: "",
|
|
20
|
+
scopes: "",
|
|
21
|
+
submitting: false,
|
|
22
|
+
error: null,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function validateUrl(raw: string): { url: string } | { error: string } {
|
|
26
|
+
const trimmed = raw.trim();
|
|
27
|
+
if (!trimmed) return { error: "URL is required" };
|
|
28
|
+
let parsed: URL;
|
|
29
|
+
try {
|
|
30
|
+
parsed = new URL(trimmed);
|
|
31
|
+
} catch {
|
|
32
|
+
return { error: "Invalid URL" };
|
|
33
|
+
}
|
|
34
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
35
|
+
return { error: "URL must be http(s)" };
|
|
36
|
+
}
|
|
37
|
+
return { url: trimmed };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export namespace McpAddFormPrimitiveRoot {
|
|
41
|
+
export type Element = ComponentRef<typeof Primitive.form>;
|
|
42
|
+
export type Props = Omit<
|
|
43
|
+
ComponentPropsWithoutRef<typeof Primitive.form>,
|
|
44
|
+
"onSubmit"
|
|
45
|
+
> & {
|
|
46
|
+
onSubmitted?: (id: string) => void;
|
|
47
|
+
onCancel?: () => void;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const McpAddFormPrimitiveRoot = forwardRef<
|
|
52
|
+
McpAddFormPrimitiveRoot.Element,
|
|
53
|
+
McpAddFormPrimitiveRoot.Props
|
|
54
|
+
>(({ onSubmitted, onCancel, ...props }, ref) => {
|
|
55
|
+
const aui = useAui();
|
|
56
|
+
const [state, setState] = useState<AddFormState>(INITIAL);
|
|
57
|
+
|
|
58
|
+
const setField = useCallback(
|
|
59
|
+
<K extends keyof AddFormState>(key: K, value: AddFormState[K]) => {
|
|
60
|
+
setState((prev) => ({ ...prev, [key]: value }));
|
|
61
|
+
},
|
|
62
|
+
[],
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const reset = useCallback(() => setState(INITIAL), []);
|
|
66
|
+
|
|
67
|
+
const buildAuth = useCallback((): MCPAuthConfig => {
|
|
68
|
+
switch (state.authType) {
|
|
69
|
+
case "none":
|
|
70
|
+
return { type: "none" };
|
|
71
|
+
case "bearer":
|
|
72
|
+
return { type: "bearer", token: state.bearerToken || undefined };
|
|
73
|
+
case "oauth": {
|
|
74
|
+
const scopeList = state.scopes
|
|
75
|
+
.split(/[\s,]+/)
|
|
76
|
+
.map((s) => s.trim())
|
|
77
|
+
.filter(Boolean);
|
|
78
|
+
return {
|
|
79
|
+
type: "oauth",
|
|
80
|
+
scopes: scopeList.length > 0 ? scopeList : undefined,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}, [state.authType, state.bearerToken, state.scopes]);
|
|
85
|
+
|
|
86
|
+
const submit = useCallback(async () => {
|
|
87
|
+
if (state.submitting) return;
|
|
88
|
+
if (!state.name.trim()) {
|
|
89
|
+
setState((p) => ({ ...p, error: "Name is required" }));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (state.authType === "bearer" && !state.bearerToken.trim()) {
|
|
93
|
+
setState((p) => ({ ...p, error: "Bearer token is required" }));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const urlResult = validateUrl(state.url);
|
|
97
|
+
if ("error" in urlResult) {
|
|
98
|
+
setState((p) => ({ ...p, error: urlResult.error }));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
setState((p) => ({ ...p, submitting: true, error: null }));
|
|
102
|
+
try {
|
|
103
|
+
const id = await aui.mcp().addCustomServer({
|
|
104
|
+
name: state.name.trim(),
|
|
105
|
+
url: urlResult.url,
|
|
106
|
+
auth: buildAuth(),
|
|
107
|
+
});
|
|
108
|
+
setState(INITIAL);
|
|
109
|
+
onSubmitted?.(id);
|
|
110
|
+
} catch (err) {
|
|
111
|
+
setState((p) => ({
|
|
112
|
+
...p,
|
|
113
|
+
submitting: false,
|
|
114
|
+
error: err instanceof Error ? err.message : String(err),
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
117
|
+
}, [aui, buildAuth, onSubmitted, state]);
|
|
118
|
+
|
|
119
|
+
const cancel = useCallback(() => {
|
|
120
|
+
setState(INITIAL);
|
|
121
|
+
onCancel?.();
|
|
122
|
+
}, [onCancel]);
|
|
123
|
+
|
|
124
|
+
const value = useMemo(
|
|
125
|
+
() => ({ state, setField, reset, submit, cancel }),
|
|
126
|
+
[state, setField, reset, submit, cancel],
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
const onFormSubmit: FormEventHandler<HTMLFormElement> = (e) => {
|
|
130
|
+
e.preventDefault();
|
|
131
|
+
void submit();
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
return (
|
|
135
|
+
<AddFormContext.Provider value={value}>
|
|
136
|
+
<Primitive.form {...props} ref={ref} onSubmit={onFormSubmit} />
|
|
137
|
+
</AddFormContext.Provider>
|
|
138
|
+
);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
McpAddFormPrimitiveRoot.displayName = "McpAddFormPrimitive.Root";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ComponentPropsWithoutRef,
|
|
3
|
+
type ComponentRef,
|
|
4
|
+
forwardRef,
|
|
5
|
+
} from "react";
|
|
6
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
7
|
+
import { useAddForm } from "./context";
|
|
8
|
+
|
|
9
|
+
export namespace McpAddFormPrimitiveSubmit {
|
|
10
|
+
export type Element = ComponentRef<typeof Primitive.button>;
|
|
11
|
+
export type Props = ComponentPropsWithoutRef<typeof Primitive.button>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const McpAddFormPrimitiveSubmit = forwardRef<
|
|
15
|
+
McpAddFormPrimitiveSubmit.Element,
|
|
16
|
+
McpAddFormPrimitiveSubmit.Props
|
|
17
|
+
>((props, ref) => {
|
|
18
|
+
const { state } = useAddForm();
|
|
19
|
+
return (
|
|
20
|
+
<Primitive.button
|
|
21
|
+
type="submit"
|
|
22
|
+
{...props}
|
|
23
|
+
ref={ref}
|
|
24
|
+
disabled={props.disabled || state.submitting}
|
|
25
|
+
data-submitting={state.submitting || undefined}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
McpAddFormPrimitiveSubmit.displayName = "McpAddFormPrimitive.Submit";
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ComponentPropsWithoutRef,
|
|
3
|
+
type ComponentRef,
|
|
4
|
+
forwardRef,
|
|
5
|
+
} from "react";
|
|
6
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
7
|
+
import { useAddForm } from "./context";
|
|
8
|
+
|
|
9
|
+
export namespace McpAddFormPrimitiveUrlField {
|
|
10
|
+
export type Element = ComponentRef<typeof Primitive.input>;
|
|
11
|
+
export type Props = Omit<
|
|
12
|
+
ComponentPropsWithoutRef<typeof Primitive.input>,
|
|
13
|
+
"value" | "onChange" | "type"
|
|
14
|
+
>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const McpAddFormPrimitiveUrlField = forwardRef<
|
|
18
|
+
McpAddFormPrimitiveUrlField.Element,
|
|
19
|
+
McpAddFormPrimitiveUrlField.Props
|
|
20
|
+
>((props, ref) => {
|
|
21
|
+
const { state, setField } = useAddForm();
|
|
22
|
+
return (
|
|
23
|
+
<Primitive.input
|
|
24
|
+
type="url"
|
|
25
|
+
inputMode="url"
|
|
26
|
+
placeholder="https://example.com/mcp"
|
|
27
|
+
{...props}
|
|
28
|
+
ref={ref}
|
|
29
|
+
value={state.url}
|
|
30
|
+
onChange={(e) => setField("url", e.target.value)}
|
|
31
|
+
/>
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
McpAddFormPrimitiveUrlField.displayName = "McpAddFormPrimitive.UrlField";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
import type { MCPAuthConfig } from "../../mcp-scope";
|
|
3
|
+
|
|
4
|
+
export type AddFormAuthType = MCPAuthConfig["type"];
|
|
5
|
+
|
|
6
|
+
export type AddFormState = {
|
|
7
|
+
name: string;
|
|
8
|
+
url: string;
|
|
9
|
+
authType: AddFormAuthType;
|
|
10
|
+
bearerToken: string;
|
|
11
|
+
scopes: string;
|
|
12
|
+
submitting: boolean;
|
|
13
|
+
error: string | null;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type AddFormContextValue = {
|
|
17
|
+
state: AddFormState;
|
|
18
|
+
setField: <K extends keyof AddFormState>(
|
|
19
|
+
key: K,
|
|
20
|
+
value: AddFormState[K],
|
|
21
|
+
) => void;
|
|
22
|
+
reset: () => void;
|
|
23
|
+
submit: () => Promise<void>;
|
|
24
|
+
cancel: () => void;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const AddFormContext = createContext<AddFormContextValue | null>(null);
|
|
28
|
+
|
|
29
|
+
export const useAddForm = (): AddFormContextValue => {
|
|
30
|
+
const ctx = useContext(AddFormContext);
|
|
31
|
+
if (!ctx) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
"McpAddFormPrimitive.* must be used inside McpAddFormPrimitive.Root",
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return ctx;
|
|
37
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { McpAddFormPrimitiveRoot as Root } from "./addForm/McpAddFormRoot";
|
|
2
|
+
export { McpAddFormPrimitiveNameField as NameField } from "./addForm/McpAddFormNameField";
|
|
3
|
+
export { McpAddFormPrimitiveUrlField as UrlField } from "./addForm/McpAddFormUrlField";
|
|
4
|
+
export { McpAddFormPrimitiveAuthSelect as AuthSelect } from "./addForm/McpAddFormAuthSelect";
|
|
5
|
+
export { McpAddFormPrimitiveAuthFields as AuthFields } from "./addForm/McpAddFormAuthFields";
|
|
6
|
+
export { McpAddFormPrimitiveSubmit as Submit } from "./addForm/McpAddFormSubmit";
|
|
7
|
+
export { McpAddFormPrimitiveCancel as Cancel } from "./addForm/McpAddFormCancel";
|
|
8
|
+
export { McpAddFormPrimitiveError as Error } from "./addForm/McpAddFormError";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ComponentPropsWithoutRef,
|
|
3
|
+
type ComponentRef,
|
|
4
|
+
forwardRef,
|
|
5
|
+
} from "react";
|
|
6
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
7
|
+
|
|
8
|
+
export namespace McpManagerPrimitiveAddCustomTrigger {
|
|
9
|
+
export type Element = ComponentRef<typeof Primitive.button>;
|
|
10
|
+
export type Props = ComponentPropsWithoutRef<typeof Primitive.button>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const McpManagerPrimitiveAddCustomTrigger = forwardRef<
|
|
14
|
+
McpManagerPrimitiveAddCustomTrigger.Element,
|
|
15
|
+
McpManagerPrimitiveAddCustomTrigger.Props
|
|
16
|
+
>((props, ref) => {
|
|
17
|
+
return <Primitive.button {...props} type="button" ref={ref} />;
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
McpManagerPrimitiveAddCustomTrigger.displayName =
|
|
21
|
+
"McpManagerPrimitive.AddCustomTrigger";
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { type FC, type ReactNode, memo, useMemo } from "react";
|
|
2
|
+
import { RenderChildrenWithAccessor, useAuiState } from "@assistant-ui/store";
|
|
3
|
+
import { McpConnectorByIndexProvider } from "../../context/McpConnectorByIndexProvider";
|
|
4
|
+
import type { MCPServerState } from "../../mcp-scope";
|
|
5
|
+
|
|
6
|
+
// ASCII Unit Separator — never appears in MCP connector ids (uuids, urls,
|
|
7
|
+
// app-provided strings).
|
|
8
|
+
const SEP = "\x1f";
|
|
9
|
+
|
|
10
|
+
export namespace McpManagerPrimitiveConnectors {
|
|
11
|
+
export type Props = {
|
|
12
|
+
/**
|
|
13
|
+
* Render function called once per connector. Receives a lazy `server`
|
|
14
|
+
* accessor — reading it inside the render function subscribes to that
|
|
15
|
+
* connector's state.
|
|
16
|
+
*/
|
|
17
|
+
children: (value: { server: MCPServerState }) => ReactNode;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const McpManagerPrimitiveConnectorsInner: FC<{
|
|
22
|
+
children: (value: { server: MCPServerState }) => ReactNode;
|
|
23
|
+
}> = ({ children }) => {
|
|
24
|
+
// Subscribe to the connector id list, joined to a primitive so identity
|
|
25
|
+
// is stable when the list hasn't changed. Re-renders on add/remove/reorder
|
|
26
|
+
// but not on per-item state changes.
|
|
27
|
+
const idsJoined = useAuiState((s) =>
|
|
28
|
+
s.mcp.connectors.map((c) => c.id).join(SEP),
|
|
29
|
+
);
|
|
30
|
+
const ids = useMemo(
|
|
31
|
+
() => (idsJoined ? idsJoined.split(SEP) : []),
|
|
32
|
+
[idsJoined],
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
return useMemo(() => {
|
|
36
|
+
if (ids.length === 0) return null;
|
|
37
|
+
return ids.map((id, index) => (
|
|
38
|
+
<McpConnectorByIndexProvider key={id} index={index}>
|
|
39
|
+
<RenderChildrenWithAccessor
|
|
40
|
+
getItemState={(aui) => aui.mcp().connector({ index }).getState()}
|
|
41
|
+
>
|
|
42
|
+
{(getItem) =>
|
|
43
|
+
children({
|
|
44
|
+
get server() {
|
|
45
|
+
return getItem();
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
</RenderChildrenWithAccessor>
|
|
50
|
+
</McpConnectorByIndexProvider>
|
|
51
|
+
));
|
|
52
|
+
}, [ids, children]);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Renders all connectors declared on `McpManagerResource`.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```tsx
|
|
60
|
+
* <McpManagerPrimitive.Connectors>
|
|
61
|
+
* {({ server }) => (
|
|
62
|
+
* <McpServerPrimitive.Root>
|
|
63
|
+
* <McpServerPrimitive.Name />
|
|
64
|
+
* {server.connectionState === "error" && <p>{server.lastError?.message}</p>}
|
|
65
|
+
* </McpServerPrimitive.Root>
|
|
66
|
+
* )}
|
|
67
|
+
* </McpManagerPrimitive.Connectors>
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export const McpManagerPrimitiveConnectors: FC<McpManagerPrimitiveConnectors.Props> =
|
|
71
|
+
memo(
|
|
72
|
+
McpManagerPrimitiveConnectorsInner,
|
|
73
|
+
(prev, next) => prev.children === next.children,
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
McpManagerPrimitiveConnectors.displayName = "McpManagerPrimitive.Connectors";
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { type FC, type ReactNode, memo, useMemo } from "react";
|
|
2
|
+
import { RenderChildrenWithAccessor, useAuiState } from "@assistant-ui/store";
|
|
3
|
+
import { McpCustomServerByIndexProvider } from "../../context/McpCustomServerByIndexProvider";
|
|
4
|
+
import type { MCPServerState } from "../../mcp-scope";
|
|
5
|
+
|
|
6
|
+
const SEP = "\x1f";
|
|
7
|
+
|
|
8
|
+
export namespace McpManagerPrimitiveCustomServers {
|
|
9
|
+
export type Props = {
|
|
10
|
+
/**
|
|
11
|
+
* Render function called once per custom server. Receives a lazy
|
|
12
|
+
* `server` accessor — reading it inside the render function subscribes
|
|
13
|
+
* to that server's state.
|
|
14
|
+
*/
|
|
15
|
+
children: (value: { server: MCPServerState }) => ReactNode;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const McpManagerPrimitiveCustomServersInner: FC<{
|
|
20
|
+
children: (value: { server: MCPServerState }) => ReactNode;
|
|
21
|
+
}> = ({ children }) => {
|
|
22
|
+
const idsJoined = useAuiState((s) =>
|
|
23
|
+
s.mcp.customServers.map((c) => c.id).join(SEP),
|
|
24
|
+
);
|
|
25
|
+
const ids = useMemo(
|
|
26
|
+
() => (idsJoined ? idsJoined.split(SEP) : []),
|
|
27
|
+
[idsJoined],
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
return useMemo(() => {
|
|
31
|
+
if (ids.length === 0) return null;
|
|
32
|
+
return ids.map((id, index) => (
|
|
33
|
+
<McpCustomServerByIndexProvider key={id} index={index}>
|
|
34
|
+
<RenderChildrenWithAccessor
|
|
35
|
+
getItemState={(aui) => aui.mcp().customServer({ index }).getState()}
|
|
36
|
+
>
|
|
37
|
+
{(getItem) =>
|
|
38
|
+
children({
|
|
39
|
+
get server() {
|
|
40
|
+
return getItem();
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
</RenderChildrenWithAccessor>
|
|
45
|
+
</McpCustomServerByIndexProvider>
|
|
46
|
+
));
|
|
47
|
+
}, [ids, children]);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Renders all user-added custom servers persisted in storage.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```tsx
|
|
55
|
+
* <McpManagerPrimitive.CustomServers>
|
|
56
|
+
* {() => (
|
|
57
|
+
* <McpServerPrimitive.Root>
|
|
58
|
+
* <McpServerPrimitive.Name />
|
|
59
|
+
* <McpServerPrimitive.RemoveButton>Remove</McpServerPrimitive.RemoveButton>
|
|
60
|
+
* </McpServerPrimitive.Root>
|
|
61
|
+
* )}
|
|
62
|
+
* </McpManagerPrimitive.CustomServers>
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export const McpManagerPrimitiveCustomServers: FC<McpManagerPrimitiveCustomServers.Props> =
|
|
66
|
+
memo(
|
|
67
|
+
McpManagerPrimitiveCustomServersInner,
|
|
68
|
+
(prev, next) => prev.children === next.children,
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
McpManagerPrimitiveCustomServers.displayName =
|
|
72
|
+
"McpManagerPrimitive.CustomServers";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ComponentPropsWithoutRef,
|
|
3
|
+
type ComponentRef,
|
|
4
|
+
forwardRef,
|
|
5
|
+
} from "react";
|
|
6
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
7
|
+
import { useAuiState } from "@assistant-ui/store";
|
|
8
|
+
|
|
9
|
+
export namespace McpManagerPrimitiveRoot {
|
|
10
|
+
export type Element = ComponentRef<typeof Primitive.div>;
|
|
11
|
+
export type Props = ComponentPropsWithoutRef<typeof Primitive.div>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const McpManagerPrimitiveRoot = forwardRef<
|
|
15
|
+
McpManagerPrimitiveRoot.Element,
|
|
16
|
+
McpManagerPrimitiveRoot.Props
|
|
17
|
+
>((props, ref) => {
|
|
18
|
+
const isHydrated = useAuiState((s) => s.mcp.isHydrated);
|
|
19
|
+
return (
|
|
20
|
+
<Primitive.div
|
|
21
|
+
{...props}
|
|
22
|
+
ref={ref}
|
|
23
|
+
data-mcp-hydrated={isHydrated || undefined}
|
|
24
|
+
/>
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
McpManagerPrimitiveRoot.displayName = "McpManagerPrimitive.Root";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { McpManagerPrimitiveRoot as Root } from "./manager/McpManagerRoot";
|
|
2
|
+
export { McpManagerPrimitiveConnectors as Connectors } from "./manager/McpManagerConnectors";
|
|
3
|
+
export { McpManagerPrimitiveCustomServers as CustomServers } from "./manager/McpManagerCustomServers";
|
|
4
|
+
export { McpManagerPrimitiveAddCustomTrigger as AddCustomTrigger } from "./manager/McpManagerAddCustomTrigger";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ComponentPropsWithoutRef,
|
|
3
|
+
type ComponentRef,
|
|
4
|
+
forwardRef,
|
|
5
|
+
} from "react";
|
|
6
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
7
|
+
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
8
|
+
|
|
9
|
+
export namespace McpServerPrimitiveConnectButton {
|
|
10
|
+
export type Element = ComponentRef<typeof Primitive.button>;
|
|
11
|
+
export type Props = ComponentPropsWithoutRef<typeof Primitive.button>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const CONNECTABLE = new Set(["disconnected", "error", "authRequired"]);
|
|
15
|
+
|
|
16
|
+
export const McpServerPrimitiveConnectButton = forwardRef<
|
|
17
|
+
McpServerPrimitiveConnectButton.Element,
|
|
18
|
+
McpServerPrimitiveConnectButton.Props
|
|
19
|
+
>((props, ref) => {
|
|
20
|
+
const state = useAuiState((s) => s.mcpServer.connectionState);
|
|
21
|
+
const aui = useAui();
|
|
22
|
+
if (!CONNECTABLE.has(state)) return null;
|
|
23
|
+
return (
|
|
24
|
+
<Primitive.button
|
|
25
|
+
{...props}
|
|
26
|
+
type="button"
|
|
27
|
+
ref={ref}
|
|
28
|
+
data-state-hint={state === "authRequired" ? "auth-required" : undefined}
|
|
29
|
+
onClick={(e) => {
|
|
30
|
+
props.onClick?.(e);
|
|
31
|
+
if (e.defaultPrevented) return;
|
|
32
|
+
void aui.mcpServer().connect();
|
|
33
|
+
}}
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
McpServerPrimitiveConnectButton.displayName =
|
|
39
|
+
"McpServerPrimitive.ConnectButton";
|