@mcp-b/react-components 0.6.3 → 0.6.5

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.
@@ -5,7 +5,7 @@ import { Context, ContextContent, ContextContentBody, ContextContentHeader, Cont
5
5
  import { Conversation, ConversationContent, ConversationEmptyState, ConversationScrollButton } from "./Conversation.js";
6
6
  import { Message, MessageAction, MessageActions, MessageAttachment, MessageContent, MessageResponse } from "./Message.js";
7
7
  import { MenuGroup, MenuGroupLabel } from "./Menu.js";
8
- import { PromptInput, PromptInputActionAddAttachments, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuTrigger, PromptInputApproval, PromptInputAttachments, PromptInputBody, PromptInputButton, PromptInputFooter, PromptInputPermissionSelector, PromptInputSubmit, PromptInputTextarea, PromptInputTools, getApprovalRequestId, getPendingToolApprovals, usePromptInputAttachments } from "./PromptInput.js";
8
+ import { PromptInput, PromptInputActionAddAttachments, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuTrigger, PromptInputApproval, PromptInputAttachments, PromptInputBody, PromptInputButton, PromptInputFooter, PromptInputPermissionSelector, PromptInputSubmit, PromptInputTextarea, PromptInputTools, getApprovalRequestId, getApprovalStateKey, getPendingToolApprovals, usePromptInputAttachments } from "./PromptInput.js";
9
9
  import { Reasoning, ReasoningContent, ReasoningTrigger } from "./Reasoning.js";
10
10
  import * as React from "react";
11
11
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -107,7 +107,7 @@ function AgentChat({ className, messages, status = "ready", onSubmit, onStop, pl
107
107
  const [skippedApprovalIds, setSkippedApprovalIds] = React.useState([]);
108
108
  const pendingApprovals = getPendingToolApprovals(messages, { pausedExecutions: Boolean(executionApprovals) }).filter(({ part }) => {
109
109
  if (part.state === "approval-requested" && !onApprovalResponse) return false;
110
- const id = getApprovalRequestId(part);
110
+ const id = getApprovalStateKey(part);
111
111
  return Boolean(id) && !skippedApprovalIds.includes(id);
112
112
  });
113
113
  const approvalsWired = Boolean(onApprovalResponse || executionApprovals);
@@ -117,8 +117,9 @@ function AgentChat({ className, messages, status = "ready", onSubmit, onStop, pl
117
117
  if (permissionMode !== "bypass") return;
118
118
  for (const { part } of pendingApprovals) {
119
119
  const id = getApprovalRequestId(part);
120
- if (!id || autoApprovedIds.current.has(id)) continue;
121
- autoApprovedIds.current.add(id);
120
+ const key = getApprovalStateKey(part);
121
+ if (!id || !key || autoApprovedIds.current.has(key)) continue;
122
+ autoApprovedIds.current.add(key);
122
123
  if (part.state === "approval-requested") onApprovalResponse?.({
123
124
  id,
124
125
  approved: true
@@ -195,7 +196,7 @@ function AgentChat({ className, messages, status = "ready", onSubmit, onStop, pl
195
196
  onRespond: onApprovalResponse,
196
197
  executionApprovals,
197
198
  onSkip: () => {
198
- const id = getApprovalRequestId(pendingApproval.part);
199
+ const id = getApprovalStateKey(pendingApproval.part);
199
200
  if (id) setSkippedApprovalIds((previous) => [...previous, id]);
200
201
  }
201
202
  }) : /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -3,7 +3,7 @@ import { y as LinkIcon } from "../icons-BCNawx-T.js";
3
3
  import { Popover } from "./Popover.js";
4
4
  import { Button } from "./Button.js";
5
5
  import { a as CodeBlockCopyButton, i as CodeBlockContent, n as CodeBlockActions, p as CodeBlockTitle, r as CodeBlockContainer, s as CodeBlockHeader, t as CodeBlock } from "../CodeBlock-BK0sOAbV.js";
6
- import { DCR_MCP_SERVER_CARDS, MANUAL_MCP_SERVER_CARDS } from "../utils/mcp-server-catalog.js";
6
+ import { DCR_MCP_SERVER_CARDS, MANUAL_MCP_SERVER_CARDS, getMcpServerIconSrc } from "../utils/mcp-server-catalog.js";
7
7
  import * as React from "react";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
9
  //#region src/components/AgentConnection.tsx
@@ -192,26 +192,29 @@ function McpServerList({ heading, servers }) {
192
192
  function McpServerSetup({ setup }) {
193
193
  return /* @__PURE__ */ jsxs("div", {
194
194
  className: "agent-connect__mcp-setup",
195
- children: [/* @__PURE__ */ jsx("p", { children: setup.description }), setup.links.length > 0 ? /* @__PURE__ */ jsx("ul", {
196
- className: "agent-connect__mcp-setup-links",
197
- role: "list",
198
- children: setup.links.map((link) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", {
199
- href: link.url,
200
- target: "_blank",
201
- rel: "noreferrer",
202
- children: link.label
203
- }) }, `${link.label}:${link.url}`))
204
- }) : null]
195
+ children: [
196
+ /* @__PURE__ */ jsx("p", { children: setup.description }),
197
+ /* @__PURE__ */ jsxs("p", {
198
+ className: "agent-connect__mcp-setup-auth",
199
+ children: [/* @__PURE__ */ jsx("span", { children: setup.auth.label }), setup.auth.fields.length > 0 ? /* @__PURE__ */ jsx("span", { children: setup.auth.fields.map((field) => field.label).join(", ") }) : null]
200
+ }),
201
+ setup.links.length > 0 ? /* @__PURE__ */ jsx("ul", {
202
+ className: "agent-connect__mcp-setup-links",
203
+ role: "list",
204
+ children: setup.links.map((link) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", {
205
+ href: link.url,
206
+ target: "_blank",
207
+ rel: "noreferrer",
208
+ children: link.label
209
+ }) }, `${link.label}:${link.url}`))
210
+ }) : null
211
+ ]
205
212
  });
206
213
  }
207
214
  function renderMcpServerIcon(server) {
208
- const icon = server.icon;
209
- if (typeof icon === "string") return /* @__PURE__ */ jsx(McpServerIconImage, {
210
- src: icon,
211
- name: server.name
212
- });
213
- if (icon) return /* @__PURE__ */ jsx(McpServerIconImage, {
214
- src: icon.src,
215
+ const src = getMcpServerIconSrc(server);
216
+ if (src) return /* @__PURE__ */ jsx(McpServerIconImage, {
217
+ src,
215
218
  name: server.name
216
219
  });
217
220
  return server.name.slice(0, 1);
@@ -1,6 +1,7 @@
1
1
  import { A as SpinnerIcon, D as PlusIcon, N as WarningIcon, a as CheckIcon } from "../icons-BCNawx-T.js";
2
2
  import { Button } from "./Button.js";
3
3
  import { MenuContent, MenuGroup, MenuGroupLabel, MenuItem, MenuRoot, MenuShortcut, MenuTrigger } from "./Menu.js";
4
+ import { getMcpServerIconSrc } from "../utils/mcp-server-catalog.js";
4
5
  import * as React from "react";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
7
  //#region src/components/McpServerPicker.tsx
@@ -65,7 +66,7 @@ function McpServerPickerRow({ server, onConnect }) {
65
66
  children: [
66
67
  /* @__PURE__ */ jsx("span", {
67
68
  className: "mcp-server-picker__icon",
68
- children: renderIcon(server.icon, server.name)
69
+ children: renderIcon(server)
69
70
  }),
70
71
  /* @__PURE__ */ jsxs("span", {
71
72
  className: "mcp-server-picker__copy",
@@ -106,18 +107,15 @@ function getStatusLabel(status) {
106
107
  if (status === "connecting") return "Connecting";
107
108
  return "";
108
109
  }
109
- function renderIcon(icon, name) {
110
- if (typeof icon === "string") return /* @__PURE__ */ jsx(IconImage, {
111
- src: icon,
112
- name
113
- });
114
- if (icon) return /* @__PURE__ */ jsx(IconImage, {
115
- src: icon.src,
116
- name
110
+ function renderIcon(server) {
111
+ const src = getMcpServerIconSrc(server);
112
+ if (src) return /* @__PURE__ */ jsx(IconImage, {
113
+ src,
114
+ name: server.name
117
115
  });
118
116
  return /* @__PURE__ */ jsx("span", {
119
117
  className: "mcp-server-picker__fallback-icon",
120
- children: name.slice(0, 1)
118
+ children: server.name.slice(0, 1)
121
119
  });
122
120
  }
123
121
  function IconImage({ src, name }) {
@@ -356,6 +356,8 @@ interface ExecutionApprovals {
356
356
  }
357
357
  /** The id a response must carry: the approval id, or the paused run's executionId. */
358
358
  declare function getApprovalRequestId(part: ApprovalToolPart): string | undefined;
359
+ /** Component-local identity: paused executions can ask for multiple approvals. */
360
+ declare function getApprovalStateKey(part: ApprovalToolPart): string | undefined;
359
361
  interface PendingToolApproval<MessageT extends UIMessage = UIMessage> {
360
362
  message: MessageT;
361
363
  messageIndex: number;
@@ -529,4 +531,4 @@ declare const PromptInputCommandItem: typeof ComboboxItem;
529
531
  type PromptInputCommandSeparatorProps = React.ComponentPropsWithoutRef<typeof ComboboxSeparator>;
530
532
  declare const PromptInputCommandSeparator: React.ForwardRefExoticComponent<Omit<import("@base-ui/react").SeparatorProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
531
533
  //#endregion
532
- export { ApprovalToolPart, AttachmentsContext, ExecutionApprovals, PendingToolApproval, PermissionMode, PromptInput, PromptInputActionAddAttachments, PromptInputActionAddAttachmentsProps, PromptInputActionAddScreenshot, PromptInputActionAddScreenshotProps, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuContentProps, PromptInputActionMenuItem, PromptInputActionMenuItemProps, PromptInputActionMenuProps, PromptInputActionMenuTrigger, PromptInputActionMenuTriggerProps, PromptInputApproval, PromptInputApprovalProps, PromptInputAttachment, PromptInputAttachmentProps, PromptInputAttachments, PromptInputAttachmentsProps, PromptInputBody, PromptInputBodyProps, PromptInputButton, PromptInputButtonProps, PromptInputButtonTooltip, PromptInputCommand, PromptInputCommandEmpty, PromptInputCommandEmptyProps, PromptInputCommandGroup, PromptInputCommandGroupProps, PromptInputCommandInput, PromptInputCommandInputProps, PromptInputCommandItem, PromptInputCommandItemProps, PromptInputCommandList, PromptInputCommandListProps, PromptInputCommandProps, PromptInputCommandSeparator, PromptInputCommandSeparatorProps, PromptInputControllerProps, PromptInputFilePart, PromptInputFooter, PromptInputFooterProps, PromptInputHeader, PromptInputHeaderProps, PromptInputHoverCard, PromptInputHoverCardContent, PromptInputHoverCardContentProps, PromptInputHoverCardProps, PromptInputHoverCardTrigger, PromptInputHoverCardTriggerProps, PromptInputMessage, PromptInputPermissionSelector, PromptInputPermissionSelectorProps, PromptInputProps, PromptInputProvider, PromptInputProviderProps, PromptInputReferencedSource, PromptInputSelect, PromptInputSelectContent, PromptInputSelectContentProps, PromptInputSelectItem, PromptInputSelectItemProps, PromptInputSelectProps, PromptInputSelectTrigger, PromptInputSelectTriggerProps, PromptInputSelectValue, PromptInputSelectValueProps, PromptInputStatus, PromptInputSubmit, PromptInputSubmitProps, PromptInputTab, PromptInputTabBody, PromptInputTabBodyProps, PromptInputTabItem, PromptInputTabItemProps, PromptInputTabLabel, PromptInputTabLabelProps, PromptInputTabProps, PromptInputTabsList, PromptInputTabsListProps, PromptInputTextarea, PromptInputTextareaProps, PromptInputTools, PromptInputToolsProps, PromptInputTooltipConfig, ReferencedSourcesContext, TextInputContext, TooltipSide, getApprovalRequestId, getPendingToolApprovals, usePromptInputAttachments, usePromptInputController, usePromptInputReferencedSources, useProviderAttachments };
534
+ export { ApprovalToolPart, AttachmentsContext, ExecutionApprovals, PendingToolApproval, PermissionMode, PromptInput, PromptInputActionAddAttachments, PromptInputActionAddAttachmentsProps, PromptInputActionAddScreenshot, PromptInputActionAddScreenshotProps, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuContentProps, PromptInputActionMenuItem, PromptInputActionMenuItemProps, PromptInputActionMenuProps, PromptInputActionMenuTrigger, PromptInputActionMenuTriggerProps, PromptInputApproval, PromptInputApprovalProps, PromptInputAttachment, PromptInputAttachmentProps, PromptInputAttachments, PromptInputAttachmentsProps, PromptInputBody, PromptInputBodyProps, PromptInputButton, PromptInputButtonProps, PromptInputButtonTooltip, PromptInputCommand, PromptInputCommandEmpty, PromptInputCommandEmptyProps, PromptInputCommandGroup, PromptInputCommandGroupProps, PromptInputCommandInput, PromptInputCommandInputProps, PromptInputCommandItem, PromptInputCommandItemProps, PromptInputCommandList, PromptInputCommandListProps, PromptInputCommandProps, PromptInputCommandSeparator, PromptInputCommandSeparatorProps, PromptInputControllerProps, PromptInputFilePart, PromptInputFooter, PromptInputFooterProps, PromptInputHeader, PromptInputHeaderProps, PromptInputHoverCard, PromptInputHoverCardContent, PromptInputHoverCardContentProps, PromptInputHoverCardProps, PromptInputHoverCardTrigger, PromptInputHoverCardTriggerProps, PromptInputMessage, PromptInputPermissionSelector, PromptInputPermissionSelectorProps, PromptInputProps, PromptInputProvider, PromptInputProviderProps, PromptInputReferencedSource, PromptInputSelect, PromptInputSelectContent, PromptInputSelectContentProps, PromptInputSelectItem, PromptInputSelectItemProps, PromptInputSelectProps, PromptInputSelectTrigger, PromptInputSelectTriggerProps, PromptInputSelectValue, PromptInputSelectValueProps, PromptInputStatus, PromptInputSubmit, PromptInputSubmitProps, PromptInputTab, PromptInputTabBody, PromptInputTabBodyProps, PromptInputTabItem, PromptInputTabItemProps, PromptInputTabLabel, PromptInputTabLabelProps, PromptInputTabProps, PromptInputTabsList, PromptInputTabsListProps, PromptInputTextarea, PromptInputTextareaProps, PromptInputTools, PromptInputToolsProps, PromptInputTooltipConfig, ReferencedSourcesContext, TextInputContext, TooltipSide, getApprovalRequestId, getApprovalStateKey, getPendingToolApprovals, usePromptInputAttachments, usePromptInputController, usePromptInputReferencedSources, useProviderAttachments };
@@ -667,6 +667,14 @@ function getApprovalRequestId(part) {
667
667
  if (part.state === "approval-requested") return part.approval.id;
668
668
  return getPausedExecution(part)?.executionId;
669
669
  }
670
+ /** Component-local identity: paused executions can ask for multiple approvals. */
671
+ function getApprovalStateKey(part) {
672
+ if (part.state === "approval-requested") return part.approval.id;
673
+ const paused = getPausedExecution(part);
674
+ if (!paused) return void 0;
675
+ const seq = paused.pending[0]?.seq;
676
+ return seq === void 0 ? paused.executionId : `${paused.executionId}:${seq}`;
677
+ }
670
678
  /** Derives pending tool approvals straight from the messages — no app-owned shapes. */
671
679
  function getPendingToolApprovals(messages, { pausedExecutions = false } = {}) {
672
680
  const pending = [];
@@ -701,7 +709,7 @@ function PromptInputApproval({ part, onRespond, executionApprovals, onSkip, ques
701
709
  const reasonRef = React.useRef(null);
702
710
  const approval = part.state === "approval-requested" ? part.approval : void 0;
703
711
  const paused = getPausedExecution(part);
704
- const approvalId = approval?.id ?? paused?.executionId;
712
+ const approvalId = getApprovalStateKey(part);
705
713
  React.useEffect(() => {
706
714
  setSelected("approve");
707
715
  setReason("");
@@ -709,19 +717,23 @@ function PromptInputApproval({ part, onRespond, executionApprovals, onSkip, ques
709
717
  }, [approvalId]);
710
718
  if (approval ? !onRespond : !(paused && executionApprovals)) return null;
711
719
  const toolName = getToolName(part);
712
- const respond = (approved) => {
720
+ const respond = async (approved) => {
713
721
  if (busy) return;
714
722
  setBusy(true);
715
723
  const trimmed = reason.trim();
716
724
  const denyReason = !approved && trimmed ? trimmed : void 0;
717
- if (approval) onRespond?.({
718
- id: approval.id,
719
- approved,
720
- reason: denyReason
721
- });
722
- else if (paused) approved ? executionApprovals?.approve(paused.executionId) : executionApprovals?.reject(paused.executionId, denyReason);
725
+ try {
726
+ if (approval) await onRespond?.({
727
+ id: approval.id,
728
+ approved,
729
+ reason: denyReason
730
+ });
731
+ else if (paused) await (approved ? executionApprovals?.approve(paused.executionId) : executionApprovals?.reject(paused.executionId, denyReason));
732
+ } finally {
733
+ setBusy(false);
734
+ }
723
735
  };
724
- const submit = () => respond(selected === "approve");
736
+ const submit = () => void respond(selected === "approve");
725
737
  const input = "input" in part ? part.input : void 0;
726
738
  const inputEntries = input && typeof input === "object" && !Array.isArray(input) ? Object.entries(input) : void 0;
727
739
  return /* @__PURE__ */ jsxs("div", {
@@ -790,7 +802,7 @@ function PromptInputApproval({ part, onRespond, executionApprovals, onSkip, ques
790
802
  className: "prompt-input__approval-option",
791
803
  "data-selected": selected === "approve" || void 0,
792
804
  disabled: busy,
793
- onClick: () => respond(true),
805
+ onClick: () => void respond(true),
794
806
  onFocus: () => setSelected("approve"),
795
807
  children: [
796
808
  /* @__PURE__ */ jsx("span", {
@@ -1047,4 +1059,4 @@ function createId() {
1047
1059
  return globalThis.crypto?.randomUUID?.() ?? `prompt-input-${Date.now()}-${Math.random()}`;
1048
1060
  }
1049
1061
  //#endregion
1050
- export { PromptInput, PromptInputActionAddAttachments, PromptInputActionAddScreenshot, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuItem, PromptInputActionMenuTrigger, PromptInputApproval, PromptInputAttachment, PromptInputAttachments, PromptInputBody, PromptInputButton, PromptInputCommand, PromptInputCommandEmpty, PromptInputCommandGroup, PromptInputCommandInput, PromptInputCommandItem, PromptInputCommandList, PromptInputCommandSeparator, PromptInputFooter, PromptInputHeader, PromptInputHoverCard, PromptInputHoverCardContent, PromptInputHoverCardTrigger, PromptInputPermissionSelector, PromptInputProvider, PromptInputSelect, PromptInputSelectContent, PromptInputSelectItem, PromptInputSelectTrigger, PromptInputSelectValue, PromptInputSubmit, PromptInputTab, PromptInputTabBody, PromptInputTabItem, PromptInputTabLabel, PromptInputTabsList, PromptInputTextarea, PromptInputTools, getApprovalRequestId, getPendingToolApprovals, usePromptInputAttachments, usePromptInputController, usePromptInputReferencedSources, useProviderAttachments };
1062
+ export { PromptInput, PromptInputActionAddAttachments, PromptInputActionAddScreenshot, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuItem, PromptInputActionMenuTrigger, PromptInputApproval, PromptInputAttachment, PromptInputAttachments, PromptInputBody, PromptInputButton, PromptInputCommand, PromptInputCommandEmpty, PromptInputCommandGroup, PromptInputCommandInput, PromptInputCommandItem, PromptInputCommandList, PromptInputCommandSeparator, PromptInputFooter, PromptInputHeader, PromptInputHoverCard, PromptInputHoverCardContent, PromptInputHoverCardTrigger, PromptInputPermissionSelector, PromptInputProvider, PromptInputSelect, PromptInputSelectContent, PromptInputSelectItem, PromptInputSelectTrigger, PromptInputSelectValue, PromptInputSubmit, PromptInputTab, PromptInputTabBody, PromptInputTabItem, PromptInputTabLabel, PromptInputTabsList, PromptInputTextarea, PromptInputTools, getApprovalRequestId, getApprovalStateKey, getPendingToolApprovals, usePromptInputAttachments, usePromptInputController, usePromptInputReferencedSources, useProviderAttachments };
@@ -251,6 +251,17 @@
251
251
  overflow-wrap: anywhere;
252
252
  }
253
253
 
254
+ .agent-connect__mcp-setup-auth {
255
+ display: flex;
256
+ flex-wrap: wrap;
257
+ gap: 0.25rem;
258
+ }
259
+
260
+ .agent-connect__mcp-setup-auth span:first-child {
261
+ color: var(--sigvelo-color-text);
262
+ font-weight: var(--sigvelo-font-weight-semibold);
263
+ }
264
+
254
265
  .agent-connect__mcp-setup-links {
255
266
  display: flex;
256
267
  flex-wrap: wrap;
@@ -7,7 +7,21 @@ interface McpServerSetupLink {
7
7
  label: string;
8
8
  url: string;
9
9
  }
10
+ type McpServerSetupAuthFieldName = "bearerToken" | "clientId" | "clientSecret" | "redirectUrl" | "scope";
11
+ interface McpServerSetupAuthField {
12
+ name: McpServerSetupAuthFieldName;
13
+ label: string;
14
+ inputType?: "password" | "text" | "url";
15
+ placeholder?: string;
16
+ required?: boolean;
17
+ }
18
+ interface McpServerSetupAuth {
19
+ type: "bearer" | "manual_oauth_client" | "none";
20
+ label: string;
21
+ fields: readonly McpServerSetupAuthField[];
22
+ }
10
23
  interface McpServerManualSetup {
24
+ auth: McpServerSetupAuth;
11
25
  description: string;
12
26
  links: readonly McpServerSetupLink[];
13
27
  }
@@ -22,6 +36,70 @@ interface McpServerCard {
22
36
  statusLabel?: string;
23
37
  manualSetup?: McpServerManualSetup;
24
38
  }
39
+ declare const MCP_SERVER_SETUP_AUTH: {
40
+ readonly bearer: {
41
+ readonly type: "bearer";
42
+ readonly label: "Bearer / API key";
43
+ readonly fields: readonly [{
44
+ readonly name: "bearerToken";
45
+ readonly label: "API key / Bearer token";
46
+ readonly inputType: "password";
47
+ readonly placeholder: "Paste token";
48
+ readonly required: true;
49
+ }];
50
+ };
51
+ readonly manualOAuthClient: {
52
+ readonly type: "manual_oauth_client";
53
+ readonly label: "OAuth client ID";
54
+ readonly fields: readonly [{
55
+ readonly name: "clientId";
56
+ readonly label: "OAuth client ID";
57
+ readonly placeholder: "Client ID";
58
+ readonly required: true;
59
+ }, {
60
+ readonly name: "redirectUrl";
61
+ readonly label: "Redirect URL";
62
+ readonly inputType: "url";
63
+ readonly placeholder: "Registered OAuth callback URL";
64
+ }, {
65
+ readonly name: "scope";
66
+ readonly label: "Scope";
67
+ readonly placeholder: "Space-separated scopes";
68
+ }];
69
+ };
70
+ readonly manualOAuthClientSecret: {
71
+ readonly type: "manual_oauth_client";
72
+ readonly label: "OAuth client ID + secret";
73
+ readonly fields: readonly [{
74
+ readonly name: "clientId";
75
+ readonly label: "OAuth client ID";
76
+ readonly placeholder: "Client ID";
77
+ readonly required: true;
78
+ }, {
79
+ readonly name: "clientSecret";
80
+ readonly label: "OAuth client secret";
81
+ readonly inputType: "password";
82
+ readonly placeholder: "Client secret";
83
+ readonly required: true;
84
+ }, {
85
+ readonly name: "redirectUrl";
86
+ readonly label: "Redirect URL";
87
+ readonly inputType: "url";
88
+ readonly placeholder: "Registered OAuth callback URL";
89
+ }, {
90
+ readonly name: "scope";
91
+ readonly label: "Scope";
92
+ readonly placeholder: "Space-separated scopes";
93
+ }];
94
+ };
95
+ readonly none: {
96
+ readonly type: "none";
97
+ readonly label: "No auth";
98
+ readonly fields: readonly [];
99
+ };
100
+ };
101
+ declare function getMcpServerIconSrc(server: Pick<McpServerCard, "icon" | "url">): string | undefined;
102
+ declare function inferMcpServerFaviconUrl(url: string): string | undefined;
25
103
  /** Remote MCP servers whose OAuth metadata exposes a registration_endpoint. */
26
104
  declare const DCR_MCP_SERVER_CARDS: readonly [{
27
105
  readonly id: "airtable";
@@ -257,6 +335,31 @@ declare const MANUAL_MCP_SERVER_CARDS: readonly [{
257
335
  readonly category: "Manual";
258
336
  readonly icon: "https://cdn.simpleicons.org/asana/F06A6A";
259
337
  readonly manualSetup: {
338
+ readonly auth: {
339
+ readonly type: "manual_oauth_client";
340
+ readonly label: "OAuth client ID + secret";
341
+ readonly fields: readonly [{
342
+ readonly name: "clientId";
343
+ readonly label: "OAuth client ID";
344
+ readonly placeholder: "Client ID";
345
+ readonly required: true;
346
+ }, {
347
+ readonly name: "clientSecret";
348
+ readonly label: "OAuth client secret";
349
+ readonly inputType: "password";
350
+ readonly placeholder: "Client secret";
351
+ readonly required: true;
352
+ }, {
353
+ readonly name: "redirectUrl";
354
+ readonly label: "Redirect URL";
355
+ readonly inputType: "url";
356
+ readonly placeholder: "Registered OAuth callback URL";
357
+ }, {
358
+ readonly name: "scope";
359
+ readonly label: "Scope";
360
+ readonly placeholder: "Space-separated scopes";
361
+ }];
362
+ };
260
363
  readonly description: "Create an Asana MCP app, configure its redirect URL and workspace distribution, then connect with the app client ID and secret.";
261
364
  readonly links: readonly [{
262
365
  readonly label: "Developer console";
@@ -277,6 +380,25 @@ declare const MANUAL_MCP_SERVER_CARDS: readonly [{
277
380
  readonly category: "Manual";
278
381
  readonly icon: "https://cdn.simpleicons.org/gmail/EA4335";
279
382
  readonly manualSetup: {
383
+ readonly auth: {
384
+ readonly type: "manual_oauth_client";
385
+ readonly label: "OAuth client ID";
386
+ readonly fields: readonly [{
387
+ readonly name: "clientId";
388
+ readonly label: "OAuth client ID";
389
+ readonly placeholder: "Client ID";
390
+ readonly required: true;
391
+ }, {
392
+ readonly name: "redirectUrl";
393
+ readonly label: "Redirect URL";
394
+ readonly inputType: "url";
395
+ readonly placeholder: "Registered OAuth callback URL";
396
+ }, {
397
+ readonly name: "scope";
398
+ readonly label: "Scope";
399
+ readonly placeholder: "Space-separated scopes";
400
+ }];
401
+ };
280
402
  readonly description: "Enable Gmail and Gmail MCP APIs, configure OAuth consent, add Gmail read/compose scopes, and create a web OAuth client.";
281
403
  readonly links: readonly [{
282
404
  readonly label: "Setup guide";
@@ -300,6 +422,25 @@ declare const MANUAL_MCP_SERVER_CARDS: readonly [{
300
422
  readonly category: "Manual";
301
423
  readonly icon: "https://cdn.simpleicons.org/googlecalendar/4285F4";
302
424
  readonly manualSetup: {
425
+ readonly auth: {
426
+ readonly type: "manual_oauth_client";
427
+ readonly label: "OAuth client ID";
428
+ readonly fields: readonly [{
429
+ readonly name: "clientId";
430
+ readonly label: "OAuth client ID";
431
+ readonly placeholder: "Client ID";
432
+ readonly required: true;
433
+ }, {
434
+ readonly name: "redirectUrl";
435
+ readonly label: "Redirect URL";
436
+ readonly inputType: "url";
437
+ readonly placeholder: "Registered OAuth callback URL";
438
+ }, {
439
+ readonly name: "scope";
440
+ readonly label: "Scope";
441
+ readonly placeholder: "Space-separated scopes";
442
+ }];
443
+ };
303
444
  readonly description: "Enable Calendar and Calendar MCP APIs, configure OAuth consent, add calendar read/freebusy scopes, and create a web OAuth client.";
304
445
  readonly links: readonly [{
305
446
  readonly label: "Setup guide";
@@ -323,6 +464,25 @@ declare const MANUAL_MCP_SERVER_CARDS: readonly [{
323
464
  readonly category: "Manual";
324
465
  readonly icon: "https://cdn.simpleicons.org/googlechat/00AC47";
325
466
  readonly manualSetup: {
467
+ readonly auth: {
468
+ readonly type: "manual_oauth_client";
469
+ readonly label: "OAuth client ID";
470
+ readonly fields: readonly [{
471
+ readonly name: "clientId";
472
+ readonly label: "OAuth client ID";
473
+ readonly placeholder: "Client ID";
474
+ readonly required: true;
475
+ }, {
476
+ readonly name: "redirectUrl";
477
+ readonly label: "Redirect URL";
478
+ readonly inputType: "url";
479
+ readonly placeholder: "Registered OAuth callback URL";
480
+ }, {
481
+ readonly name: "scope";
482
+ readonly label: "Scope";
483
+ readonly placeholder: "Space-separated scopes";
484
+ }];
485
+ };
326
486
  readonly description: "Enable Chat and Chat MCP APIs, configure a Chat app, add Chat read/send scopes, and create a web OAuth client.";
327
487
  readonly links: readonly [{
328
488
  readonly label: "Setup guide";
@@ -346,6 +506,25 @@ declare const MANUAL_MCP_SERVER_CARDS: readonly [{
346
506
  readonly category: "Manual";
347
507
  readonly icon: "https://cdn.simpleicons.org/googledrive/4285F4";
348
508
  readonly manualSetup: {
509
+ readonly auth: {
510
+ readonly type: "manual_oauth_client";
511
+ readonly label: "OAuth client ID";
512
+ readonly fields: readonly [{
513
+ readonly name: "clientId";
514
+ readonly label: "OAuth client ID";
515
+ readonly placeholder: "Client ID";
516
+ readonly required: true;
517
+ }, {
518
+ readonly name: "redirectUrl";
519
+ readonly label: "Redirect URL";
520
+ readonly inputType: "url";
521
+ readonly placeholder: "Registered OAuth callback URL";
522
+ }, {
523
+ readonly name: "scope";
524
+ readonly label: "Scope";
525
+ readonly placeholder: "Space-separated scopes";
526
+ }];
527
+ };
349
528
  readonly description: "Enable Drive and Drive MCP APIs, configure OAuth consent, add Drive read/file scopes, and create a web OAuth client.";
350
529
  readonly links: readonly [{
351
530
  readonly label: "Setup guide";
@@ -369,6 +548,25 @@ declare const MANUAL_MCP_SERVER_CARDS: readonly [{
369
548
  readonly category: "Manual";
370
549
  readonly icon: "https://cdn.simpleicons.org/google/4285F4";
371
550
  readonly manualSetup: {
551
+ readonly auth: {
552
+ readonly type: "manual_oauth_client";
553
+ readonly label: "OAuth client ID";
554
+ readonly fields: readonly [{
555
+ readonly name: "clientId";
556
+ readonly label: "OAuth client ID";
557
+ readonly placeholder: "Client ID";
558
+ readonly required: true;
559
+ }, {
560
+ readonly name: "redirectUrl";
561
+ readonly label: "Redirect URL";
562
+ readonly inputType: "url";
563
+ readonly placeholder: "Registered OAuth callback URL";
564
+ }, {
565
+ readonly name: "scope";
566
+ readonly label: "Scope";
567
+ readonly placeholder: "Space-separated scopes";
568
+ }];
569
+ };
372
570
  readonly description: "Enable People API, configure OAuth consent, add contacts/profile/directory scopes, and create a web OAuth client.";
373
571
  readonly links: readonly [{
374
572
  readonly label: "Setup guide";
@@ -392,6 +590,25 @@ declare const MANUAL_MCP_SERVER_CARDS: readonly [{
392
590
  readonly category: "Manual";
393
591
  readonly icon: "https://cdn.simpleicons.org/google/4285F4";
394
592
  readonly manualSetup: {
593
+ readonly auth: {
594
+ readonly type: "manual_oauth_client";
595
+ readonly label: "OAuth client ID";
596
+ readonly fields: readonly [{
597
+ readonly name: "clientId";
598
+ readonly label: "OAuth client ID";
599
+ readonly placeholder: "Client ID";
600
+ readonly required: true;
601
+ }, {
602
+ readonly name: "redirectUrl";
603
+ readonly label: "Redirect URL";
604
+ readonly inputType: "url";
605
+ readonly placeholder: "Registered OAuth callback URL";
606
+ }, {
607
+ readonly name: "scope";
608
+ readonly label: "Scope";
609
+ readonly placeholder: "Space-separated scopes";
610
+ }];
611
+ };
395
612
  readonly description: "Enable the Workspace MCP service plus Gmail, Drive, Calendar, and Chat APIs, then configure OAuth consent and readonly search scopes.";
396
613
  readonly links: readonly [{
397
614
  readonly label: "Setup guide";
@@ -407,6 +624,62 @@ declare const MANUAL_MCP_SERVER_CARDS: readonly [{
407
624
  readonly url: "https://console.cloud.google.com/apis/credentials";
408
625
  }];
409
626
  };
627
+ }, {
628
+ readonly id: "posthog";
629
+ readonly name: "PostHog";
630
+ readonly url: "https://mcp.posthog.com/mcp";
631
+ readonly description: "Analyze product analytics and feature flags";
632
+ readonly category: "Manual";
633
+ readonly icon: "https://cdn.simpleicons.org/posthog/000000";
634
+ readonly manualSetup: {
635
+ readonly auth: {
636
+ readonly type: "bearer";
637
+ readonly label: "Bearer / API key";
638
+ readonly fields: readonly [{
639
+ readonly name: "bearerToken";
640
+ readonly label: "API key / Bearer token";
641
+ readonly inputType: "password";
642
+ readonly placeholder: "Paste token";
643
+ readonly required: true;
644
+ }];
645
+ };
646
+ readonly description: "Create a PostHog personal API key with the MCP Server preset, then connect with that key as a bearer token.";
647
+ readonly links: readonly [{
648
+ readonly label: "MCP docs";
649
+ readonly url: "https://posthog.com/docs/model-context-protocol";
650
+ }, {
651
+ readonly label: "API keys";
652
+ readonly url: "https://app.posthog.com/settings/user-api-keys";
653
+ }];
654
+ };
655
+ }, {
656
+ readonly id: "firecrawl";
657
+ readonly name: "Firecrawl";
658
+ readonly url: "https://mcp.firecrawl.dev/v2/mcp";
659
+ readonly description: "Search, crawl, scrape, and extract web data";
660
+ readonly category: "Manual";
661
+ readonly icon: "https://www.firecrawl.dev/favicon.ico";
662
+ readonly manualSetup: {
663
+ readonly auth: {
664
+ readonly type: "bearer";
665
+ readonly label: "Bearer / API key";
666
+ readonly fields: readonly [{
667
+ readonly name: "bearerToken";
668
+ readonly label: "API key / Bearer token";
669
+ readonly inputType: "password";
670
+ readonly placeholder: "Paste token";
671
+ readonly required: true;
672
+ }];
673
+ };
674
+ readonly description: "Create a Firecrawl API key, then connect the hosted MCP endpoint with Authorization: Bearer.";
675
+ readonly links: readonly [{
676
+ readonly label: "MCP server";
677
+ readonly url: "https://github.com/firecrawl/firecrawl-mcp-server";
678
+ }, {
679
+ readonly label: "API auth";
680
+ readonly url: "https://docs.firecrawl.dev/api-reference/introduction";
681
+ }];
682
+ };
410
683
  }, {
411
684
  readonly id: "hubspot";
412
685
  readonly name: "HubSpot";
@@ -415,6 +688,31 @@ declare const MANUAL_MCP_SERVER_CARDS: readonly [{
415
688
  readonly category: "Manual";
416
689
  readonly icon: "https://cdn.simpleicons.org/hubspot/FF7A59";
417
690
  readonly manualSetup: {
691
+ readonly auth: {
692
+ readonly type: "manual_oauth_client";
693
+ readonly label: "OAuth client ID + secret";
694
+ readonly fields: readonly [{
695
+ readonly name: "clientId";
696
+ readonly label: "OAuth client ID";
697
+ readonly placeholder: "Client ID";
698
+ readonly required: true;
699
+ }, {
700
+ readonly name: "clientSecret";
701
+ readonly label: "OAuth client secret";
702
+ readonly inputType: "password";
703
+ readonly placeholder: "Client secret";
704
+ readonly required: true;
705
+ }, {
706
+ readonly name: "redirectUrl";
707
+ readonly label: "Redirect URL";
708
+ readonly inputType: "url";
709
+ readonly placeholder: "Registered OAuth callback URL";
710
+ }, {
711
+ readonly name: "scope";
712
+ readonly label: "Scope";
713
+ readonly placeholder: "Space-separated scopes";
714
+ }];
715
+ };
418
716
  readonly description: "Create a HubSpot MCP Auth App, configure the redirect URL, and connect with OAuth credentials from a PKCE-capable client.";
419
717
  readonly links: readonly [{
420
718
  readonly label: "Setup guide";
@@ -432,6 +730,25 @@ declare const MANUAL_MCP_SERVER_CARDS: readonly [{
432
730
  readonly category: "Manual";
433
731
  readonly icon: "https://www.microsoft.com/favicon.ico";
434
732
  readonly manualSetup: {
733
+ readonly auth: {
734
+ readonly type: "manual_oauth_client";
735
+ readonly label: "OAuth client ID";
736
+ readonly fields: readonly [{
737
+ readonly name: "clientId";
738
+ readonly label: "OAuth client ID";
739
+ readonly placeholder: "Client ID";
740
+ readonly required: true;
741
+ }, {
742
+ readonly name: "redirectUrl";
743
+ readonly label: "Redirect URL";
744
+ readonly inputType: "url";
745
+ readonly placeholder: "Registered OAuth callback URL";
746
+ }, {
747
+ readonly name: "scope";
748
+ readonly label: "Scope";
749
+ readonly placeholder: "Space-separated scopes";
750
+ }];
751
+ };
435
752
  readonly description: "Provision the preview tenant resource, register the client, grant delegated MCP permissions, and connect with Microsoft Entra OAuth.";
436
753
  readonly links: readonly [{
437
754
  readonly label: "Overview";
@@ -449,6 +766,11 @@ declare const MANUAL_MCP_SERVER_CARDS: readonly [{
449
766
  readonly category: "Manual";
450
767
  readonly icon: "https://www.microsoft.com/favicon.ico";
451
768
  readonly manualSetup: {
769
+ readonly auth: {
770
+ readonly type: "none";
771
+ readonly label: "No auth";
772
+ readonly fields: readonly [];
773
+ };
452
774
  readonly description: "No OAuth is required; add the Streamable HTTP endpoint directly to the MCP client.";
453
775
  readonly links: readonly [{
454
776
  readonly label: "Setup guide";
@@ -463,6 +785,25 @@ declare const MANUAL_MCP_SERVER_CARDS: readonly [{
463
785
  readonly category: "Manual";
464
786
  readonly icon: "https://www.salesforce.com/favicon.ico";
465
787
  readonly manualSetup: {
788
+ readonly auth: {
789
+ readonly type: "manual_oauth_client";
790
+ readonly label: "OAuth client ID";
791
+ readonly fields: readonly [{
792
+ readonly name: "clientId";
793
+ readonly label: "OAuth client ID";
794
+ readonly placeholder: "Client ID";
795
+ readonly required: true;
796
+ }, {
797
+ readonly name: "redirectUrl";
798
+ readonly label: "Redirect URL";
799
+ readonly inputType: "url";
800
+ readonly placeholder: "Registered OAuth callback URL";
801
+ }, {
802
+ readonly name: "scope";
803
+ readonly label: "Scope";
804
+ readonly placeholder: "Space-separated scopes";
805
+ }];
806
+ };
466
807
  readonly description: "Create a Salesforce External Client App with mcp_api and refresh_token scopes, require PKCE, activate the hosted server, and connect with the consumer key.";
467
808
  readonly links: readonly [{
468
809
  readonly label: "Client connection";
@@ -483,6 +824,31 @@ declare const MANUAL_MCP_SERVER_CARDS: readonly [{
483
824
  readonly category: "Manual";
484
825
  readonly icon: "https://slack.com/favicon.ico";
485
826
  readonly manualSetup: {
827
+ readonly auth: {
828
+ readonly type: "manual_oauth_client";
829
+ readonly label: "OAuth client ID + secret";
830
+ readonly fields: readonly [{
831
+ readonly name: "clientId";
832
+ readonly label: "OAuth client ID";
833
+ readonly placeholder: "Client ID";
834
+ readonly required: true;
835
+ }, {
836
+ readonly name: "clientSecret";
837
+ readonly label: "OAuth client secret";
838
+ readonly inputType: "password";
839
+ readonly placeholder: "Client secret";
840
+ readonly required: true;
841
+ }, {
842
+ readonly name: "redirectUrl";
843
+ readonly label: "Redirect URL";
844
+ readonly inputType: "url";
845
+ readonly placeholder: "Registered OAuth callback URL";
846
+ }, {
847
+ readonly name: "scope";
848
+ readonly label: "Scope";
849
+ readonly placeholder: "Space-separated scopes";
850
+ }];
851
+ };
486
852
  readonly description: "Create or reuse a Slack app, enable MCP access, add user scopes and redirect URLs, then connect with the app client ID and secret.";
487
853
  readonly links: readonly [{
488
854
  readonly label: "Slack apps";
@@ -503,6 +869,31 @@ declare const MANUAL_MCP_SERVER_CARDS: readonly [{
503
869
  readonly category: "Manual";
504
870
  readonly icon: "https://cdn.simpleicons.org/zoom/0B5CFF";
505
871
  readonly manualSetup: {
872
+ readonly auth: {
873
+ readonly type: "manual_oauth_client";
874
+ readonly label: "OAuth client ID + secret";
875
+ readonly fields: readonly [{
876
+ readonly name: "clientId";
877
+ readonly label: "OAuth client ID";
878
+ readonly placeholder: "Client ID";
879
+ readonly required: true;
880
+ }, {
881
+ readonly name: "clientSecret";
882
+ readonly label: "OAuth client secret";
883
+ readonly inputType: "password";
884
+ readonly placeholder: "Client secret";
885
+ readonly required: true;
886
+ }, {
887
+ readonly name: "redirectUrl";
888
+ readonly label: "Redirect URL";
889
+ readonly inputType: "url";
890
+ readonly placeholder: "Registered OAuth callback URL";
891
+ }, {
892
+ readonly name: "scope";
893
+ readonly label: "Scope";
894
+ readonly placeholder: "Space-separated scopes";
895
+ }];
896
+ };
506
897
  readonly description: "Create a Zoom Marketplace General app, add the MCP product scopes, configure the client redirect URL, and connect with OAuth credentials.";
507
898
  readonly links: readonly [{
508
899
  readonly label: "Setup guide";
@@ -517,4 +908,4 @@ declare const MANUAL_MCP_SERVER_CARDS: readonly [{
517
908
  };
518
909
  }];
519
910
  //#endregion
520
- export { DCR_MCP_SERVER_CARDS, MANUAL_MCP_SERVER_CARDS, McpServerCard, McpServerCardIcon, McpServerManualSetup, McpServerPickerStatus, McpServerSetupLink };
911
+ export { DCR_MCP_SERVER_CARDS, MANUAL_MCP_SERVER_CARDS, MCP_SERVER_SETUP_AUTH, McpServerCard, McpServerCardIcon, McpServerManualSetup, McpServerPickerStatus, McpServerSetupAuth, McpServerSetupAuthField, McpServerSetupAuthFieldName, McpServerSetupLink, getMcpServerIconSrc, inferMcpServerFaviconUrl };
@@ -1,6 +1,91 @@
1
1
  //#region src/utils/mcp-server-catalog.ts
2
2
  const DCR_CATEGORY = "Auto";
3
3
  const MANUAL_CATEGORY = "Manual";
4
+ const MCP_SERVER_SETUP_AUTH = {
5
+ bearer: {
6
+ type: "bearer",
7
+ label: "Bearer / API key",
8
+ fields: [{
9
+ name: "bearerToken",
10
+ label: "API key / Bearer token",
11
+ inputType: "password",
12
+ placeholder: "Paste token",
13
+ required: true
14
+ }]
15
+ },
16
+ manualOAuthClient: {
17
+ type: "manual_oauth_client",
18
+ label: "OAuth client ID",
19
+ fields: [
20
+ {
21
+ name: "clientId",
22
+ label: "OAuth client ID",
23
+ placeholder: "Client ID",
24
+ required: true
25
+ },
26
+ {
27
+ name: "redirectUrl",
28
+ label: "Redirect URL",
29
+ inputType: "url",
30
+ placeholder: "Registered OAuth callback URL"
31
+ },
32
+ {
33
+ name: "scope",
34
+ label: "Scope",
35
+ placeholder: "Space-separated scopes"
36
+ }
37
+ ]
38
+ },
39
+ manualOAuthClientSecret: {
40
+ type: "manual_oauth_client",
41
+ label: "OAuth client ID + secret",
42
+ fields: [
43
+ {
44
+ name: "clientId",
45
+ label: "OAuth client ID",
46
+ placeholder: "Client ID",
47
+ required: true
48
+ },
49
+ {
50
+ name: "clientSecret",
51
+ label: "OAuth client secret",
52
+ inputType: "password",
53
+ placeholder: "Client secret",
54
+ required: true
55
+ },
56
+ {
57
+ name: "redirectUrl",
58
+ label: "Redirect URL",
59
+ inputType: "url",
60
+ placeholder: "Registered OAuth callback URL"
61
+ },
62
+ {
63
+ name: "scope",
64
+ label: "Scope",
65
+ placeholder: "Space-separated scopes"
66
+ }
67
+ ]
68
+ },
69
+ none: {
70
+ type: "none",
71
+ label: "No auth",
72
+ fields: []
73
+ }
74
+ };
75
+ function getMcpServerIconSrc(server) {
76
+ if (typeof server.icon === "string") return server.icon;
77
+ if (server.icon?.src) return server.icon.src;
78
+ return inferMcpServerFaviconUrl(server.url);
79
+ }
80
+ function inferMcpServerFaviconUrl(url) {
81
+ try {
82
+ const parsed = new URL(url);
83
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return void 0;
84
+ return new URL("/favicon.ico", parsed).href;
85
+ } catch {
86
+ return;
87
+ }
88
+ }
4
89
  /** Remote MCP servers whose OAuth metadata exposes a registration_endpoint. */
5
90
  const DCR_MCP_SERVER_CARDS = [
6
91
  {
@@ -270,6 +355,7 @@ const MANUAL_MCP_SERVER_CARDS = [
270
355
  category: MANUAL_CATEGORY,
271
356
  icon: "https://cdn.simpleicons.org/asana/F06A6A",
272
357
  manualSetup: {
358
+ auth: MCP_SERVER_SETUP_AUTH.manualOAuthClientSecret,
273
359
  description: "Create an Asana MCP app, configure its redirect URL and workspace distribution, then connect with the app client ID and secret.",
274
360
  links: [
275
361
  {
@@ -295,6 +381,7 @@ const MANUAL_MCP_SERVER_CARDS = [
295
381
  category: MANUAL_CATEGORY,
296
382
  icon: "https://cdn.simpleicons.org/gmail/EA4335",
297
383
  manualSetup: {
384
+ auth: MCP_SERVER_SETUP_AUTH.manualOAuthClient,
298
385
  description: "Enable Gmail and Gmail MCP APIs, configure OAuth consent, add Gmail read/compose scopes, and create a web OAuth client.",
299
386
  links: [
300
387
  {
@@ -324,6 +411,7 @@ const MANUAL_MCP_SERVER_CARDS = [
324
411
  category: MANUAL_CATEGORY,
325
412
  icon: "https://cdn.simpleicons.org/googlecalendar/4285F4",
326
413
  manualSetup: {
414
+ auth: MCP_SERVER_SETUP_AUTH.manualOAuthClient,
327
415
  description: "Enable Calendar and Calendar MCP APIs, configure OAuth consent, add calendar read/freebusy scopes, and create a web OAuth client.",
328
416
  links: [
329
417
  {
@@ -353,6 +441,7 @@ const MANUAL_MCP_SERVER_CARDS = [
353
441
  category: MANUAL_CATEGORY,
354
442
  icon: "https://cdn.simpleicons.org/googlechat/00AC47",
355
443
  manualSetup: {
444
+ auth: MCP_SERVER_SETUP_AUTH.manualOAuthClient,
356
445
  description: "Enable Chat and Chat MCP APIs, configure a Chat app, add Chat read/send scopes, and create a web OAuth client.",
357
446
  links: [
358
447
  {
@@ -382,6 +471,7 @@ const MANUAL_MCP_SERVER_CARDS = [
382
471
  category: MANUAL_CATEGORY,
383
472
  icon: "https://cdn.simpleicons.org/googledrive/4285F4",
384
473
  manualSetup: {
474
+ auth: MCP_SERVER_SETUP_AUTH.manualOAuthClient,
385
475
  description: "Enable Drive and Drive MCP APIs, configure OAuth consent, add Drive read/file scopes, and create a web OAuth client.",
386
476
  links: [
387
477
  {
@@ -411,6 +501,7 @@ const MANUAL_MCP_SERVER_CARDS = [
411
501
  category: MANUAL_CATEGORY,
412
502
  icon: "https://cdn.simpleicons.org/google/4285F4",
413
503
  manualSetup: {
504
+ auth: MCP_SERVER_SETUP_AUTH.manualOAuthClient,
414
505
  description: "Enable People API, configure OAuth consent, add contacts/profile/directory scopes, and create a web OAuth client.",
415
506
  links: [
416
507
  {
@@ -440,6 +531,7 @@ const MANUAL_MCP_SERVER_CARDS = [
440
531
  category: MANUAL_CATEGORY,
441
532
  icon: "https://cdn.simpleicons.org/google/4285F4",
442
533
  manualSetup: {
534
+ auth: MCP_SERVER_SETUP_AUTH.manualOAuthClient,
443
535
  description: "Enable the Workspace MCP service plus Gmail, Drive, Calendar, and Chat APIs, then configure OAuth consent and readonly search scopes.",
444
536
  links: [
445
537
  {
@@ -461,6 +553,44 @@ const MANUAL_MCP_SERVER_CARDS = [
461
553
  ]
462
554
  }
463
555
  },
556
+ {
557
+ id: "posthog",
558
+ name: "PostHog",
559
+ url: "https://mcp.posthog.com/mcp",
560
+ description: "Analyze product analytics and feature flags",
561
+ category: MANUAL_CATEGORY,
562
+ icon: "https://cdn.simpleicons.org/posthog/000000",
563
+ manualSetup: {
564
+ auth: MCP_SERVER_SETUP_AUTH.bearer,
565
+ description: "Create a PostHog personal API key with the MCP Server preset, then connect with that key as a bearer token.",
566
+ links: [{
567
+ label: "MCP docs",
568
+ url: "https://posthog.com/docs/model-context-protocol"
569
+ }, {
570
+ label: "API keys",
571
+ url: "https://app.posthog.com/settings/user-api-keys"
572
+ }]
573
+ }
574
+ },
575
+ {
576
+ id: "firecrawl",
577
+ name: "Firecrawl",
578
+ url: "https://mcp.firecrawl.dev/v2/mcp",
579
+ description: "Search, crawl, scrape, and extract web data",
580
+ category: MANUAL_CATEGORY,
581
+ icon: "https://www.firecrawl.dev/favicon.ico",
582
+ manualSetup: {
583
+ auth: MCP_SERVER_SETUP_AUTH.bearer,
584
+ description: "Create a Firecrawl API key, then connect the hosted MCP endpoint with Authorization: Bearer.",
585
+ links: [{
586
+ label: "MCP server",
587
+ url: "https://github.com/firecrawl/firecrawl-mcp-server"
588
+ }, {
589
+ label: "API auth",
590
+ url: "https://docs.firecrawl.dev/api-reference/introduction"
591
+ }]
592
+ }
593
+ },
464
594
  {
465
595
  id: "hubspot",
466
596
  name: "HubSpot",
@@ -469,6 +599,7 @@ const MANUAL_MCP_SERVER_CARDS = [
469
599
  category: MANUAL_CATEGORY,
470
600
  icon: "https://cdn.simpleicons.org/hubspot/FF7A59",
471
601
  manualSetup: {
602
+ auth: MCP_SERVER_SETUP_AUTH.manualOAuthClientSecret,
472
603
  description: "Create a HubSpot MCP Auth App, configure the redirect URL, and connect with OAuth credentials from a PKCE-capable client.",
473
604
  links: [{
474
605
  label: "Setup guide",
@@ -487,6 +618,7 @@ const MANUAL_MCP_SERVER_CARDS = [
487
618
  category: MANUAL_CATEGORY,
488
619
  icon: "https://www.microsoft.com/favicon.ico",
489
620
  manualSetup: {
621
+ auth: MCP_SERVER_SETUP_AUTH.manualOAuthClient,
490
622
  description: "Provision the preview tenant resource, register the client, grant delegated MCP permissions, and connect with Microsoft Entra OAuth.",
491
623
  links: [{
492
624
  label: "Overview",
@@ -505,6 +637,7 @@ const MANUAL_MCP_SERVER_CARDS = [
505
637
  category: MANUAL_CATEGORY,
506
638
  icon: "https://www.microsoft.com/favicon.ico",
507
639
  manualSetup: {
640
+ auth: MCP_SERVER_SETUP_AUTH.none,
508
641
  description: "No OAuth is required; add the Streamable HTTP endpoint directly to the MCP client.",
509
642
  links: [{
510
643
  label: "Setup guide",
@@ -520,6 +653,7 @@ const MANUAL_MCP_SERVER_CARDS = [
520
653
  category: MANUAL_CATEGORY,
521
654
  icon: "https://www.salesforce.com/favicon.ico",
522
655
  manualSetup: {
656
+ auth: MCP_SERVER_SETUP_AUTH.manualOAuthClient,
523
657
  description: "Create a Salesforce External Client App with mcp_api and refresh_token scopes, require PKCE, activate the hosted server, and connect with the consumer key.",
524
658
  links: [
525
659
  {
@@ -545,6 +679,7 @@ const MANUAL_MCP_SERVER_CARDS = [
545
679
  category: MANUAL_CATEGORY,
546
680
  icon: "https://slack.com/favicon.ico",
547
681
  manualSetup: {
682
+ auth: MCP_SERVER_SETUP_AUTH.manualOAuthClientSecret,
548
683
  description: "Create or reuse a Slack app, enable MCP access, add user scopes and redirect URLs, then connect with the app client ID and secret.",
549
684
  links: [
550
685
  {
@@ -570,6 +705,7 @@ const MANUAL_MCP_SERVER_CARDS = [
570
705
  category: MANUAL_CATEGORY,
571
706
  icon: "https://cdn.simpleicons.org/zoom/0B5CFF",
572
707
  manualSetup: {
708
+ auth: MCP_SERVER_SETUP_AUTH.manualOAuthClientSecret,
573
709
  description: "Create a Zoom Marketplace General app, add the MCP product scopes, configure the client redirect URL, and connect with OAuth credentials.",
574
710
  links: [
575
711
  {
@@ -589,4 +725,4 @@ const MANUAL_MCP_SERVER_CARDS = [
589
725
  }
590
726
  ];
591
727
  //#endregion
592
- export { DCR_MCP_SERVER_CARDS, MANUAL_MCP_SERVER_CARDS };
728
+ export { DCR_MCP_SERVER_CARDS, MANUAL_MCP_SERVER_CARDS, MCP_SERVER_SETUP_AUTH, getMcpServerIconSrc, inferMcpServerFaviconUrl };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-b/react-components",
3
- "version": "0.6.3",
3
+ "version": "0.6.5",
4
4
  "description": "MCP-B React components built on Base UI and shared design tokens, including Cloudflare Think chat primitives.",
5
5
  "homepage": "https://design-system.sigvelo.com",
6
6
  "bugs": {
@@ -49,7 +49,7 @@
49
49
  "anser": "^2.3.5",
50
50
  "shiki": "^3.23.0",
51
51
  "streamdown": "^2.5.0",
52
- "@mcp-b/design-tokens": "0.6.3"
52
+ "@mcp-b/design-tokens": "0.6.5"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@ai-sdk/react": "^3.0.194",