-
- {!!mcp && (
+ {!!mcp && showDeleteButton && onDelete && (
@@ -135,22 +125,11 @@ export default function MCPPanel() {
className="max-w-[450px]"
main={
}
selection={{
- selectHandler: () => {
- if (!agent_id) {
- return showToast({
- message: localize('com_agents_no_agent_id_error'),
- status: 'error',
- });
- }
- deleteAgentMCP.mutate({
- mcp_id: mcp.mcp_id,
- agent_id,
- });
- },
+ selectHandler: handleDelete,
selectClasses:
'bg-red-700 dark:bg-red-600 hover:bg-red-800 dark:hover:bg-red-800 transition-color duration-200 text-white',
selectText: localize('com_ui_delete'),
@@ -160,11 +139,14 @@ export default function MCPPanel() {
)}
- {mcp ? localize('com_ui_edit_mcp_server') : localize('com_ui_add_mcp_server')}
+ {title ||
+ (mcp ? localize('com_ui_edit_mcp_server') : localize('com_ui_add_mcp_server'))}
+
+
+ {subtitle || localize('com_agents_mcp_info')}
- {localize('com_agents_mcp_info')}
-
+
diff --git a/client/src/components/SidePanel/Agents/MCPInput.tsx b/client/src/components/SidePanel/MCP/MCPInput.tsx
similarity index 79%
rename from client/src/components/SidePanel/Agents/MCPInput.tsx
rename to client/src/components/SidePanel/MCP/MCPInput.tsx
index 6c2f2ce51e..545b0f4afc 100644
--- a/client/src/components/SidePanel/Agents/MCPInput.tsx
+++ b/client/src/components/SidePanel/MCP/MCPInput.tsx
@@ -5,54 +5,24 @@ import MCPAuth from '~/components/SidePanel/Builder/MCPAuth';
import MCPIcon from '~/components/SidePanel/Agents/MCPIcon';
import { Label, Checkbox } from '~/components/ui';
import useLocalize from '~/hooks/useLocalize';
-import { useToastContext } from '~/Providers';
import { Spinner } from '~/components/svg';
import { MCPForm } from '~/common/types';
-function useUpdateAgentMCP({
- onSuccess,
- onError,
-}: {
- onSuccess: (data: [string, MCP]) => void;
- onError: (error: Error) => void;
-}) {
- return {
- mutate: async ({
- mcp_id,
- metadata,
- agent_id,
- }: {
- mcp_id?: string;
- metadata: MCP['metadata'];
- agent_id: string;
- }) => {
- try {
- // TODO: Implement MCP endpoint
- onSuccess(['success', { mcp_id, metadata, agent_id } as MCP]);
- } catch (error) {
- onError(error as Error);
- }
- },
- isLoading: false,
- };
-}
-
interface MCPInputProps {
mcp?: MCP;
agent_id?: string;
- setMCP: React.Dispatch
>;
+ onSave: (mcp: MCP) => void;
+ isLoading?: boolean;
}
-export default function MCPInput({ mcp, agent_id, setMCP }: MCPInputProps) {
+export default function MCPInput({ mcp, a, onSave, isLoading = false }: MCPInputProps) {
const localize = useLocalize();
- const { showToast } = useToastContext();
const {
handleSubmit,
register,
formState: { errors },
control,
} = useFormContext();
- const [isLoading, setIsLoading] = useState(false);
const [showTools, setShowTools] = useState(false);
const [selectedTools, setSelectedTools] = useState([]);
@@ -64,50 +34,16 @@ export default function MCPInput({ mcp, agent_id, setMCP }: MCPInputProps) {
}
}, [mcp]);
- const updateAgentMCP = useUpdateAgentMCP({
- onSuccess(data) {
- showToast({
- message: localize('com_ui_update_mcp_success'),
- status: 'success',
- });
- setMCP(data[1]);
- setShowTools(true);
- setSelectedTools(data[1].metadata.tools ?? []);
- setIsLoading(false);
- },
- onError(error) {
- showToast({
- message: (error as Error).message || localize('com_ui_update_mcp_error'),
- status: 'error',
- });
- setIsLoading(false);
- },
- });
-
const saveMCP = handleSubmit(async (data: MCPForm) => {
- setIsLoading(true);
- try {
- const response = await updateAgentMCP.mutate({
- agent_id: agent_id ?? '',
- mcp_id: mcp?.mcp_id,
- metadata: {
- ...data,
- tools: selectedTools,
- },
- });
- setMCP(response[1]);
- showToast({
- message: localize('com_ui_update_mcp_success'),
- status: 'success',
- });
- } catch {
- showToast({
- message: localize('com_ui_update_mcp_error'),
- status: 'error',
- });
- } finally {
- setIsLoading(false);
- }
+ const updatedMCP: MCP = {
+ mcp_id: mcp?.mcp_id ?? '',
+ agent_id: a ?? '', // This will be agent_id, conversation_id, etc.
+ metadata: {
+ ...data,
+ tools: selectedTools,
+ },
+ };
+ onSave(updatedMCP);
});
const handleSelectAll = () => {
@@ -140,14 +76,15 @@ export default function MCPInput({ mcp, agent_id, setMCP }: MCPInputProps) {
const reader = new FileReader();
reader.onloadend = () => {
const base64String = reader.result as string;
- setMCP({
+ const updatedMCP: MCP = {
mcp_id: mcp?.mcp_id ?? '',
- agent_id: agent_id ?? '',
+ agent_id: a ?? '',
metadata: {
...mcp?.metadata,
icon: base64String,
},
- });
+ };
+ onSave(updatedMCP);
};
reader.readAsDataURL(file);
}
diff --git a/client/src/components/SidePanel/MCP/MCPPanel.tsx b/client/src/components/SidePanel/MCP/MCPPanel.tsx
index aa2bf72112..5ec168af9e 100644
--- a/client/src/components/SidePanel/MCP/MCPPanel.tsx
+++ b/client/src/components/SidePanel/MCP/MCPPanel.tsx
@@ -9,6 +9,8 @@ import { useGetStartupConfig } from '~/data-provider';
import MCPPanelSkeleton from './MCPPanelSkeleton';
import { useToastContext } from '~/Providers';
import { useLocalize } from '~/hooks';
+import MCPFormPanel from './MCPFormPanel';
+import type { MCP } from '~/common';
interface ServerConfigWithVars {
serverName: string;
@@ -24,6 +26,7 @@ export default function MCPPanel() {
const [selectedServerNameForEditing, setSelectedServerNameForEditing] = useState(
null,
);
+ const [showMCPForm, setShowMCPForm] = useState(false);
const mcpServerDefinitions = useMemo(() => {
if (!startupConfig?.mcpServers) {
@@ -89,14 +92,54 @@ export default function MCPPanel() {
setSelectedServerNameForEditing(null);
};
+ const handleAddMCP = () => {
+ setShowMCPForm(true);
+ };
+
+ const handleBackFromForm = () => {
+ setShowMCPForm(false);
+ };
+
+ const handleSaveMCP = (mcp: MCP) => {
+ // TODO: Implement MCP save logic for conversation context
+ console.log('Saving MCP:', mcp);
+ showToast({
+ message: localize('com_ui_update_mcp_success'),
+ status: 'success',
+ });
+ setShowMCPForm(false);
+ };
+
+ if (showMCPForm) {
+ return (
+
+ );
+ }
+
if (startupConfigLoading) {
return ;
}
if (mcpServerDefinitions.length === 0) {
return (
-
- {localize('com_sidepanel_mcp_no_servers_with_vars')}
+
+
+ {localize('com_sidepanel_mcp_no_servers_with_vars')}
+
+
+
+ {localize('com_ui_add_mcp')}
+
+
);
}
@@ -153,6 +196,12 @@ export default function MCPPanel() {
{server.serverName}
))}
+
+ {localize('com_ui_add_mcp')}
+
);
diff --git a/client/src/locales/en/translation.json b/client/src/locales/en/translation.json
index f1571cc657..6197fb50e5 100644
--- a/client/src/locales/en/translation.json
+++ b/client/src/locales/en/translation.json
@@ -20,6 +20,7 @@
"com_agents_mcp_description_placeholder": "Explain what it does in a few words",
"com_agents_mcp_icon_size": "Minimum size 128 x 128 px",
"com_agents_mcp_info": "Add MCP servers to your agent to enable it to perform tasks and interact with external services",
+ "com_agents_mcp_info_chat": "Add MCP servers to enable chat to perform tasks and interact with external services",
"com_agents_mcp_name_placeholder": "Custom Tool",
"com_agents_mcp_trust_subtext": "Custom connectors are not verified by LibreChat",
"com_agents_mcps_disabled": "You need to create an agent before adding MCPs.",