mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-04 02:31:27 +00:00
feat(ui): i18n for MCP server creation and user env vars modal
This commit is contained in:
parent
8708a1e614
commit
6b7e0f6bee
4 changed files with 338 additions and 110 deletions
|
|
@ -4,6 +4,7 @@ import { useMutation, useQuery } from "@tanstack/react-query";
|
|||
import { MCPServer, MCPUserEnvVarsStatus } from "./types";
|
||||
import { getMCPUserEnvVars, storeMCPUserEnvVars } from "../networking";
|
||||
import NotificationsManager from "../molecules/notifications_manager";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const { Text, Title } = Typography;
|
||||
|
||||
|
|
@ -24,6 +25,7 @@ interface UserEnvVarsModalProps {
|
|||
*/
|
||||
const UserEnvVarsModal: React.FC<UserEnvVarsModalProps> = ({ server, open, accessToken, onClose, onSaved }) => {
|
||||
const [form] = Form.useForm();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const {
|
||||
data: status,
|
||||
|
|
@ -38,12 +40,16 @@ const UserEnvVarsModal: React.FC<UserEnvVarsModalProps> = ({ server, open, acces
|
|||
const saveMutation = useMutation({
|
||||
mutationFn: (values: Record<string, string>) => storeMCPUserEnvVars(accessToken!, server!.server_id, values),
|
||||
onSuccess: (saved) => {
|
||||
NotificationsManager.success("Credentials saved");
|
||||
NotificationsManager.success(t("mcpTools.userEnvVarsModal.savedSuccess"));
|
||||
onSaved?.(saved);
|
||||
onClose();
|
||||
},
|
||||
onError: (err) => {
|
||||
NotificationsManager.fromBackend(`Failed to save env vars: ${err instanceof Error ? err.message : String(err)}`);
|
||||
NotificationsManager.fromBackend(
|
||||
t("mcpTools.userEnvVarsModal.saveFailed", {
|
||||
error: err instanceof Error ? err.message : String(err),
|
||||
}),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -74,9 +80,9 @@ const UserEnvVarsModal: React.FC<UserEnvVarsModalProps> = ({ server, open, acces
|
|||
<div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Title level={5} style={{ margin: 0 }}>
|
||||
Set your credentials
|
||||
{t("mcpTools.userEnvVarsModal.title")}
|
||||
</Title>
|
||||
<Tag color="blue">Per-user</Tag>
|
||||
<Tag color="blue">{t("mcpTools.userEnvVarsModal.perUserTag")}</Tag>
|
||||
</div>
|
||||
<Text type="secondary" className="text-xs">
|
||||
{displayName}
|
||||
|
|
@ -90,16 +96,12 @@ const UserEnvVarsModal: React.FC<UserEnvVarsModalProps> = ({ server, open, acces
|
|||
<Spin />
|
||||
</div>
|
||||
) : isError ? (
|
||||
<Alert type="error" showIcon message="Failed to load env vars" />
|
||||
<Alert type="error" showIcon message={t("mcpTools.userEnvVarsModal.loadError")} />
|
||||
) : required.length === 0 ? (
|
||||
<Alert type="info" showIcon message="No per-user fields configured for this server." />
|
||||
<Alert type="info" showIcon message={t("mcpTools.userEnvVarsModal.noFieldsConfigured")} />
|
||||
) : (
|
||||
<>
|
||||
<Text className="text-sm text-gray-600 block">
|
||||
These values are private to you. Your admin configured this MCP server to require these per-user
|
||||
credentials. Saved values are never shown back; leave an already-set field blank to keep it, or enter a
|
||||
value to set or change it.
|
||||
</Text>
|
||||
<Text className="text-sm text-gray-600 block">{t("mcpTools.userEnvVarsModal.privacyNote")}</Text>
|
||||
<Form form={form} layout="vertical" onFinish={handleSave} disabled={isSaving}>
|
||||
{required.map((spec) => (
|
||||
<Form.Item
|
||||
|
|
@ -108,15 +110,21 @@ const UserEnvVarsModal: React.FC<UserEnvVarsModalProps> = ({ server, open, acces
|
|||
label={
|
||||
<span className="flex items-center gap-2">
|
||||
<span className="font-mono text-sm font-semibold">{spec.name}</span>
|
||||
{spec.is_set && <Tag color="green">Set</Tag>}
|
||||
{spec.is_set && <Tag color="green">{t("mcpTools.userEnvVarsModal.setTag")}</Tag>}
|
||||
</span>
|
||||
}
|
||||
extra={spec.description || undefined}
|
||||
rules={spec.is_set ? undefined : [{ required: true, message: `${spec.name} is required` }]}
|
||||
rules={
|
||||
spec.is_set
|
||||
? undefined
|
||||
: [{ required: true, message: t("mcpTools.userEnvVarsModal.fieldRequired", { name: spec.name }) }]
|
||||
}
|
||||
>
|
||||
<Input.Password
|
||||
placeholder={
|
||||
spec.is_set ? "Enter a new value to overwrite" : spec.description || `Enter your ${spec.name}`
|
||||
spec.is_set
|
||||
? t("mcpTools.userEnvVarsModal.overwritePlaceholder")
|
||||
: spec.description || t("mcpTools.userEnvVarsModal.enterFieldPlaceholder", { name: spec.name })
|
||||
}
|
||||
visibilityToggle
|
||||
/>
|
||||
|
|
@ -124,10 +132,10 @@ const UserEnvVarsModal: React.FC<UserEnvVarsModalProps> = ({ server, open, acces
|
|||
))}
|
||||
<div className="flex items-center justify-end gap-2 pt-2 border-t border-gray-100">
|
||||
<Button onClick={onClose} disabled={isSaving}>
|
||||
Cancel
|
||||
{t("common.cancel")}
|
||||
</Button>
|
||||
<Button type="primary" htmlType="submit" loading={isSaving}>
|
||||
Save Credentials
|
||||
{t("mcpTools.userEnvVarsModal.saveButton")}
|
||||
</Button>
|
||||
</div>
|
||||
</Form>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import { Modal, Tooltip, Form, Select, Input, Switch, Collapse } from "antd";
|
|||
import { InfoCircleOutlined } from "@ant-design/icons";
|
||||
import { Button, TextInput } from "@tremor/react";
|
||||
import { createMCPServer, registerMCPServer, storeMCPOAuthUserCredential } from "../networking";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Trans } from "react-i18next";
|
||||
import { setToken } from "@/utils/mcpTokenStore";
|
||||
import {
|
||||
AUTH_TYPE,
|
||||
|
|
@ -70,6 +72,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
onBackToDiscovery,
|
||||
}) => {
|
||||
const [form] = Form.useForm();
|
||||
const { t } = useTranslation();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [costConfig, setCostConfig] = useState<MCPServerCostInfo>({});
|
||||
const [formValues, setFormValues] = useState<Record<string, any>>({});
|
||||
|
|
@ -183,9 +186,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
|
||||
form.setFieldsValue({ credentials });
|
||||
|
||||
NotificationsManager.success(
|
||||
"OAuth authorization successful! Please click 'Create MCP Server' to save the configuration.",
|
||||
);
|
||||
NotificationsManager.success(t("mcpTools.createMcpServer.oauthAuthSuccess"));
|
||||
}
|
||||
},
|
||||
onBeforeRedirect: persistCreateUiState,
|
||||
|
|
@ -372,7 +373,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
|
||||
console.log("Parsed stdio config:", stdioFields);
|
||||
} catch (error) {
|
||||
NotificationsManager.fromBackend("Invalid JSON in stdio configuration");
|
||||
NotificationsManager.fromBackend(t("mcpTools.createMcpServer.invalidJsonStdio"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -388,7 +389,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
try {
|
||||
tokenValidation = JSON.parse(rawTokenValidationJson);
|
||||
} catch {
|
||||
NotificationsManager.fromBackend("Invalid JSON in Token Validation Rules");
|
||||
NotificationsManager.fromBackend(t("mcpTools.createMcpServer.invalidJsonTokenValidation"));
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
|
@ -468,7 +469,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
}
|
||||
|
||||
NotificationsManager.success(
|
||||
isAdmin ? "MCP Server created successfully" : "MCP Server submitted for admin review",
|
||||
isAdmin ? t("mcpTools.createMcpServer.createSuccess") : t("mcpTools.createMcpServer.submitSuccess"),
|
||||
);
|
||||
form.resetFields();
|
||||
setCostConfig({});
|
||||
|
|
@ -483,7 +484,9 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
} catch (error) {
|
||||
const reason = error instanceof Error ? error.message : String(error);
|
||||
NotificationsManager.fromBackend(
|
||||
isAdmin ? `Error creating MCP Server: ${reason}` : `Error submitting MCP Server: ${reason}`,
|
||||
isAdmin
|
||||
? t("mcpTools.createMcpServer.createFailed", { reason })
|
||||
: t("mcpTools.createMcpServer.submitFailed", { reason }),
|
||||
);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
|
|
@ -537,7 +540,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 bg-blue-500 rounded-full"></div>
|
||||
<span className="font-medium">{searchValue}</span>
|
||||
<span className="text-gray-400 text-xs ml-1">create new group</span>
|
||||
<span className="text-gray-400 text-xs ml-1">{t("mcpTools.createMcpServer.createNewGroup")}</span>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
|
|
@ -587,7 +590,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
)}
|
||||
<img
|
||||
src={mcpLogoImg}
|
||||
alt="MCP Logo"
|
||||
alt={t("mcpTools.createMcpServer.mcpLogoAlt")}
|
||||
className="w-8 h-8 object-contain"
|
||||
style={{
|
||||
height: "20px",
|
||||
|
|
@ -596,7 +599,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
}}
|
||||
/>
|
||||
<h2 className="text-xl font-semibold text-gray-900">
|
||||
{isAdmin ? "Add New MCP Server" : "Submit MCP Server for Review"}
|
||||
{isAdmin ? t("mcpTools.createMcpServer.modalTitleAdmin") : t("mcpTools.createMcpServer.modalTitleUser")}
|
||||
</h2>
|
||||
</div>
|
||||
}
|
||||
|
|
@ -621,28 +624,27 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
>
|
||||
{!isAdmin && (
|
||||
<div className="rounded-md bg-blue-50 border border-blue-200 px-4 py-3 text-sm text-blue-800">
|
||||
Your submission will be sent for admin review before it becomes active. Note: the request must be made
|
||||
with a team-scoped API key.
|
||||
{t("mcpTools.createMcpServer.nonAdminBanner")}
|
||||
</div>
|
||||
)}
|
||||
<div className="grid grid-cols-1 gap-6">
|
||||
<Form.Item
|
||||
label={
|
||||
<span className="text-sm font-medium text-gray-700 flex items-center">
|
||||
MCP Server Name
|
||||
<Tooltip title="Best practice: Use a descriptive name that indicates the server's purpose (e.g., 'GitHub_MCP', 'Email_Service'). Cannot contain spaces or hyphens; use underscores instead. Names must comply with SEP-986 and will be rejected if invalid (https://modelcontextprotocol.io/specification/2025-11-25/server/tools#tool-names).">
|
||||
{t("mcpTools.createMcpServer.serverNameLabel")}
|
||||
<Tooltip title={t("mcpTools.createMcpServer.serverNameTooltip")}>
|
||||
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
|
||||
</Tooltip>
|
||||
</span>
|
||||
}
|
||||
name="server_name"
|
||||
rules={[
|
||||
{ required: false, message: "Please enter a server name" },
|
||||
{ required: false, message: t("mcpTools.createMcpServer.serverNameRequired") },
|
||||
{ validator: (_, value) => validateMCPServerName(value) },
|
||||
]}
|
||||
>
|
||||
<TextInput
|
||||
placeholder="e.g., GitHub_MCP, Zapier_MCP, etc."
|
||||
placeholder={t("mcpTools.createMcpServer.serverNamePlaceholder")}
|
||||
className="rounded-lg border-gray-300 focus:border-blue-500 focus:ring-blue-500"
|
||||
/>
|
||||
</Form.Item>
|
||||
|
|
@ -650,8 +652,8 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
<Form.Item
|
||||
label={
|
||||
<span className="text-sm font-medium text-gray-700 flex items-center">
|
||||
Alias
|
||||
<Tooltip title="A short, unique identifier for this server. Defaults to the server name if not provided. Cannot contain spaces or hyphens; use underscores instead.">
|
||||
{t("mcpTools.createMcpServer.aliasLabel")}
|
||||
<Tooltip title={t("mcpTools.createMcpServer.aliasTooltip")}>
|
||||
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
|
||||
</Tooltip>
|
||||
</span>
|
||||
|
|
@ -660,24 +662,24 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
rules={[{ required: false }, { validator: (_, value) => validateMCPServerName(value) }]}
|
||||
>
|
||||
<TextInput
|
||||
placeholder="e.g., GitHub_MCP, Zapier_MCP, etc."
|
||||
placeholder={t("mcpTools.createMcpServer.serverNamePlaceholder")}
|
||||
className="rounded-lg border-gray-300 focus:border-blue-500 focus:ring-blue-500"
|
||||
onChange={() => setAliasManuallyEdited(true)}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={<span className="text-sm font-medium text-gray-700">Description</span>}
|
||||
label={<span className="text-sm font-medium text-gray-700">{t("common.description")}</span>}
|
||||
name="description"
|
||||
rules={[
|
||||
{
|
||||
required: false,
|
||||
message: "Please enter a server description",
|
||||
message: t("mcpTools.createMcpServer.descriptionRequired"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<TextInput
|
||||
placeholder="Brief description of what this server does"
|
||||
placeholder={t("mcpTools.createMcpServer.descriptionPlaceholder")}
|
||||
className="rounded-lg border-gray-300 focus:border-blue-500 focus:ring-blue-500"
|
||||
/>
|
||||
</Form.Item>
|
||||
|
|
@ -685,7 +687,11 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
<MCPLogoSelector value={logoUrl} onChange={setLogoUrl} />
|
||||
|
||||
<Form.Item
|
||||
label={<span className="text-sm font-medium text-gray-700">GitHub / Source URL</span>}
|
||||
label={
|
||||
<span className="text-sm font-medium text-gray-700">
|
||||
{t("mcpTools.createMcpServer.sourceUrlLabel")}
|
||||
</span>
|
||||
}
|
||||
name="source_url"
|
||||
>
|
||||
<TextInput
|
||||
|
|
@ -695,31 +701,41 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={<span className="text-sm font-medium text-gray-700">Transport Type</span>}
|
||||
label={
|
||||
<span className="text-sm font-medium text-gray-700">
|
||||
{t("mcpTools.createMcpServer.transportLabel")}
|
||||
</span>
|
||||
}
|
||||
name="transport"
|
||||
rules={[{ required: true, message: "Please select a transport type" }]}
|
||||
rules={[{ required: true, message: t("mcpTools.createMcpServer.transportRequired") }]}
|
||||
>
|
||||
<Select
|
||||
placeholder="Select transport"
|
||||
placeholder={t("mcpTools.createMcpServer.transportPlaceholder")}
|
||||
className="rounded-lg"
|
||||
size="large"
|
||||
onChange={handleTransportChange}
|
||||
value={transportType}
|
||||
>
|
||||
<Select.Option value="http">Streamable HTTP (Recommended)</Select.Option>
|
||||
<Select.Option value="sse">Server-Sent Events (SSE)</Select.Option>
|
||||
<Select.Option value="stdio">Standard Input/Output (stdio)</Select.Option>
|
||||
<Select.Option value={TRANSPORT.OPENAPI}>OpenAPI Spec</Select.Option>
|
||||
<Select.Option value="http">{t("mcpTools.createMcpServer.transportHttp")}</Select.Option>
|
||||
<Select.Option value="sse">{t("mcpTools.createMcpServer.transportSse")}</Select.Option>
|
||||
<Select.Option value="stdio">{t("mcpTools.createMcpServer.transportStdio")}</Select.Option>
|
||||
<Select.Option value={TRANSPORT.OPENAPI}>
|
||||
{t("mcpTools.createMcpServer.transportOpenapi")}
|
||||
</Select.Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
{/* URL field - only show for HTTP and SSE */}
|
||||
{(transportType === "http" || transportType === "sse") && (
|
||||
<Form.Item
|
||||
label={<span className="text-sm font-medium text-gray-700">MCP Server URL</span>}
|
||||
label={
|
||||
<span className="text-sm font-medium text-gray-700">
|
||||
{t("mcpTools.createMcpServer.serverUrlLabel")}
|
||||
</span>
|
||||
}
|
||||
name="url"
|
||||
rules={[
|
||||
{ required: true, message: "Please enter a server URL" },
|
||||
{ required: true, message: t("mcpTools.createMcpServer.serverUrlRequired") },
|
||||
{ validator: (_, value) => validateMCPServerUrl(value) },
|
||||
]}
|
||||
>
|
||||
|
|
@ -748,8 +764,8 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
<Form.Item
|
||||
label={
|
||||
<span className="text-sm font-medium text-gray-700 flex items-center gap-2">
|
||||
BYOK (Bring Your Own Key)
|
||||
<Tooltip title="When enabled, each user provides their own API key for this service. Keys are stored per-user and never shared.">
|
||||
{t("mcpTools.createMcpServer.byokLabel")}
|
||||
<Tooltip title={t("mcpTools.createMcpServer.byokTooltip")}>
|
||||
<InfoCircleOutlined className="text-blue-400 hover:text-blue-600 cursor-help" />
|
||||
</Tooltip>
|
||||
</span>
|
||||
|
|
@ -772,7 +788,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
<div className="mb-4 p-3 bg-blue-50 rounded-lg text-sm text-blue-700 flex items-start gap-2">
|
||||
<InfoCircleOutlined className="mt-0.5 flex-shrink-0" />
|
||||
<span>
|
||||
User keys will be sent as:{" "}
|
||||
{t("mcpTools.createMcpServer.byokKeysSentAs")}{" "}
|
||||
<code className="font-mono bg-blue-100 px-1 rounded">
|
||||
{getFieldValue("auth_type") === "bearer_token" && "Authorization: Bearer {key}"}
|
||||
{getFieldValue("auth_type") === "token" && "Authorization: token {key}"}
|
||||
|
|
@ -780,7 +796,6 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
{getFieldValue("auth_type") === "basic" && "Authorization: Basic {key}"}
|
||||
{getFieldValue("auth_type") === "authorization" && "Authorization: {key}"}
|
||||
</code>
|
||||
{!getFieldValue("auth_type") && "Set Authentication Type below to specify the format."}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -788,16 +803,18 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
<div className="mb-4 p-3 bg-yellow-50 rounded-lg text-sm text-yellow-700 flex items-start gap-2">
|
||||
<InfoCircleOutlined className="mt-0.5 flex-shrink-0" />
|
||||
<span>
|
||||
Set the <strong>Authentication Type</strong> below to specify how user keys are sent
|
||||
(e.g., Bearer Token, API Key header).
|
||||
<Trans
|
||||
i18nKey="mcpTools.createMcpServer.byokSetAuthType"
|
||||
components={{ strong: <strong /> }}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<Form.Item
|
||||
label={
|
||||
<span className="text-sm font-medium text-gray-700">
|
||||
Access Description
|
||||
<Tooltip title="List of permissions shown to users in the connection modal (e.g. 'Create and manage Jira issues')">
|
||||
{t("mcpTools.createMcpServer.byokAccessDescLabel")}
|
||||
<Tooltip title={t("mcpTools.createMcpServer.byokAccessDescTooltip")}>
|
||||
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
|
||||
</Tooltip>
|
||||
</span>
|
||||
|
|
@ -806,7 +823,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
>
|
||||
<Select
|
||||
mode="tags"
|
||||
placeholder="Add access description items (press Enter after each)"
|
||||
placeholder={t("mcpTools.createMcpServer.byokAccessDescPlaceholder")}
|
||||
className="w-full"
|
||||
tokenSeparators={[","]}
|
||||
/>
|
||||
|
|
@ -815,8 +832,8 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
<Form.Item
|
||||
label={
|
||||
<span className="text-sm font-medium text-gray-700">
|
||||
API Key Help URL
|
||||
<Tooltip title="Optional link shown to users to help them find their API key">
|
||||
{t("mcpTools.createMcpServer.byokApiKeyHelpUrlLabel")}
|
||||
<Tooltip title={t("mcpTools.createMcpServer.byokApiKeyHelpUrlTooltip")}>
|
||||
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
|
||||
</Tooltip>
|
||||
</span>
|
||||
|
|
@ -840,18 +857,33 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
items={[
|
||||
{
|
||||
key: "auth",
|
||||
label: <span className="text-sm font-semibold text-gray-700">Authentication</span>,
|
||||
label: (
|
||||
<span className="text-sm font-semibold text-gray-700">
|
||||
{t("mcpTools.createMcpServer.authLabel")}
|
||||
</span>
|
||||
),
|
||||
children: (
|
||||
<>
|
||||
<Form.Item name="auth_type" rules={[{ required: true, message: "Please select an auth type" }]}>
|
||||
<Select placeholder="Select auth type" className="rounded-lg" size="large">
|
||||
<Select.Option value="none">None</Select.Option>
|
||||
<Select.Option value="api_key">API Key</Select.Option>
|
||||
<Select.Option value="bearer_token">Bearer Token</Select.Option>
|
||||
<Select.Option value="token">Token</Select.Option>
|
||||
<Select.Option value="basic">Basic Auth</Select.Option>
|
||||
<Select.Option value="oauth2">OAuth</Select.Option>
|
||||
<Select.Option value="aws_sigv4">AWS SigV4 (Bedrock AgentCore MCPs)</Select.Option>
|
||||
<Form.Item
|
||||
name="auth_type"
|
||||
rules={[{ required: true, message: t("mcpTools.createMcpServer.authTypeRequired") }]}
|
||||
>
|
||||
<Select
|
||||
placeholder={t("mcpTools.createMcpServer.authTypePlaceholder")}
|
||||
className="rounded-lg"
|
||||
size="large"
|
||||
>
|
||||
<Select.Option value="none">{t("mcpTools.createMcpServer.authNone")}</Select.Option>
|
||||
<Select.Option value="api_key">{t("mcpTools.createMcpServer.authApiKey")}</Select.Option>
|
||||
<Select.Option value="bearer_token">
|
||||
{t("mcpTools.createMcpServer.authBearerToken")}
|
||||
</Select.Option>
|
||||
<Select.Option value="token">{t("mcpTools.createMcpServer.authToken")}</Select.Option>
|
||||
<Select.Option value="basic">{t("mcpTools.createMcpServer.authBasic")}</Select.Option>
|
||||
<Select.Option value="oauth2">{t("mcpTools.createMcpServer.authOauth")}</Select.Option>
|
||||
<Select.Option value="aws_sigv4">
|
||||
{t("mcpTools.createMcpServer.authAwsSigv4")}
|
||||
</Select.Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
|
|
@ -859,8 +891,8 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
<Form.Item
|
||||
label={
|
||||
<span className="text-sm font-medium text-gray-700 flex items-center">
|
||||
Authentication Value
|
||||
<Tooltip title="Token, password, or header value to send with each request for the selected auth type.">
|
||||
{t("mcpTools.createMcpServer.authValueLabel")}
|
||||
<Tooltip title={t("mcpTools.createMcpServer.authValueTooltip")}>
|
||||
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
|
||||
</Tooltip>
|
||||
</span>
|
||||
|
|
@ -870,14 +902,14 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
{
|
||||
validator: (_, value) =>
|
||||
value && typeof value === "string" && value.trim() === ""
|
||||
? Promise.reject(new Error("Authentication value cannot be empty whitespace"))
|
||||
? Promise.reject(new Error(t("mcpTools.createMcpServer.authValueEmpty")))
|
||||
: Promise.resolve(),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<TextInput
|
||||
type="password"
|
||||
placeholder="Enter token or secret"
|
||||
placeholder={t("mcpTools.createMcpServer.authValuePlaceholder")}
|
||||
className="rounded-lg border-gray-300 focus:border-blue-500 focus:ring-blue-500"
|
||||
/>
|
||||
</Form.Item>
|
||||
|
|
@ -906,27 +938,31 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
{transportType !== "stdio" && transportType !== "" && isAwsSigV4AuthType && (
|
||||
<>
|
||||
<p className="text-sm text-gray-500 mb-2">
|
||||
For MCP servers hosted on AWS Bedrock AgentCore.{" "}
|
||||
<a
|
||||
href="https://docs.litellm.ai/docs/mcp_aws_sigv4"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-500 hover:text-blue-700"
|
||||
>
|
||||
View docs →
|
||||
</a>
|
||||
<Trans
|
||||
i18nKey="mcpTools.createMcpServer.awsSigv4Desc"
|
||||
components={{
|
||||
a: (
|
||||
<a
|
||||
href="https://docs.litellm.ai/docs/mcp_aws_sigv4"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-500 hover:text-blue-700"
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
<Form.Item
|
||||
label={
|
||||
<span className="text-sm font-medium text-gray-700 flex items-center">
|
||||
AWS Region
|
||||
<Tooltip title="AWS region for SigV4 signing (e.g., us-east-1)">
|
||||
{t("mcpTools.createMcpServer.awsRegionLabel")}
|
||||
<Tooltip title={t("mcpTools.createMcpServer.awsRegionTooltip")}>
|
||||
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
|
||||
</Tooltip>
|
||||
</span>
|
||||
}
|
||||
name={["credentials", "aws_region_name"]}
|
||||
rules={[{ required: true, message: "AWS region is required for SigV4 auth" }]}
|
||||
rules={[{ required: true, message: t("mcpTools.createMcpServer.awsRegionRequired") }]}
|
||||
>
|
||||
<Input
|
||||
placeholder="us-east-1"
|
||||
|
|
@ -936,8 +972,8 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
<Form.Item
|
||||
label={
|
||||
<span className="text-sm font-medium text-gray-700 flex items-center">
|
||||
AWS Service Name
|
||||
<Tooltip title="AWS service name for SigV4 signing. Defaults to 'bedrock-agentcore'.">
|
||||
{t("mcpTools.createMcpServer.awsServiceNameLabel")}
|
||||
<Tooltip title={t("mcpTools.createMcpServer.awsServiceNameTooltip")}>
|
||||
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
|
||||
</Tooltip>
|
||||
</span>
|
||||
|
|
@ -952,8 +988,8 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
<Form.Item
|
||||
label={
|
||||
<span className="text-sm font-medium text-gray-700 flex items-center">
|
||||
AWS Access Key ID
|
||||
<Tooltip title="Optional. If not provided, falls back to the boto3 credential chain (IAM role, env vars, etc.).">
|
||||
{t("mcpTools.createMcpServer.awsAccessKeyIdLabel")}
|
||||
<Tooltip title={t("mcpTools.createMcpServer.awsAccessKeyIdTooltip")}>
|
||||
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
|
||||
</Tooltip>
|
||||
</span>
|
||||
|
|
@ -965,9 +1001,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
validator(_, value) {
|
||||
const secretKey = getFieldValue(["credentials", "aws_secret_access_key"]);
|
||||
if (secretKey && !value) {
|
||||
return Promise.reject(
|
||||
new Error("Access Key ID is required when Secret Access Key is provided"),
|
||||
);
|
||||
return Promise.reject(new Error(t("mcpTools.createMcpServer.awsAccessKeyIdRequired")));
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
|
@ -975,15 +1009,15 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
]}
|
||||
>
|
||||
<Input.Password
|
||||
placeholder="AKIA... (optional — uses IAM role if blank)"
|
||||
placeholder={t("mcpTools.createMcpServer.awsAccessKeyIdPlaceholder")}
|
||||
className="rounded-lg border-gray-300 focus:border-blue-500 focus:ring-blue-500"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={
|
||||
<span className="text-sm font-medium text-gray-700 flex items-center">
|
||||
AWS Secret Access Key
|
||||
<Tooltip title="Optional. Required if AWS Access Key ID is provided.">
|
||||
{t("mcpTools.createMcpServer.awsSecretKeyLabel")}
|
||||
<Tooltip title={t("mcpTools.createMcpServer.awsSecretKeyTooltip")}>
|
||||
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
|
||||
</Tooltip>
|
||||
</span>
|
||||
|
|
@ -995,9 +1029,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
validator(_, value) {
|
||||
const accessKeyId = getFieldValue(["credentials", "aws_access_key_id"]);
|
||||
if (accessKeyId && !value) {
|
||||
return Promise.reject(
|
||||
new Error("Secret Access Key is required when Access Key ID is provided"),
|
||||
);
|
||||
return Promise.reject(new Error(t("mcpTools.createMcpServer.awsSecretKeyRequired")));
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
|
@ -1005,15 +1037,15 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
]}
|
||||
>
|
||||
<Input.Password
|
||||
placeholder="Enter secret key (optional — uses IAM role if blank)"
|
||||
placeholder={t("mcpTools.createMcpServer.awsSecretKeyPlaceholder")}
|
||||
className="rounded-lg border-gray-300 focus:border-blue-500 focus:ring-blue-500"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={
|
||||
<span className="text-sm font-medium text-gray-700 flex items-center">
|
||||
AWS Session Token
|
||||
<Tooltip title="Optional. Only needed for temporary STS credentials.">
|
||||
{t("mcpTools.createMcpServer.awsSessionTokenLabel")}
|
||||
<Tooltip title={t("mcpTools.createMcpServer.awsSessionTokenTooltip")}>
|
||||
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
|
||||
</Tooltip>
|
||||
</span>
|
||||
|
|
@ -1021,15 +1053,15 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
name={["credentials", "aws_session_token"]}
|
||||
>
|
||||
<Input.Password
|
||||
placeholder="Enter session token (optional)"
|
||||
placeholder={t("mcpTools.createMcpServer.awsSessionTokenPlaceholder")}
|
||||
className="rounded-lg border-gray-300 focus:border-blue-500 focus:ring-blue-500"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={
|
||||
<span className="text-sm font-medium text-gray-700 flex items-center">
|
||||
AWS Role ARN
|
||||
<Tooltip title="Optional. IAM role ARN to assume via STS before signing. If set, LiteLLM calls sts:AssumeRole to get temporary credentials. Uses ambient credentials (IAM role, env vars) as the source identity unless explicit keys are also provided.">
|
||||
{t("mcpTools.createMcpServer.awsRoleArnLabel")}
|
||||
<Tooltip title={t("mcpTools.createMcpServer.awsRoleArnTooltip")}>
|
||||
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
|
||||
</Tooltip>
|
||||
</span>
|
||||
|
|
@ -1037,15 +1069,15 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
name={["credentials", "aws_role_name"]}
|
||||
>
|
||||
<Input
|
||||
placeholder="arn:aws:iam::123456789012:role/MyRole (optional)"
|
||||
placeholder={t("mcpTools.createMcpServer.awsRoleArnPlaceholder")}
|
||||
className="rounded-lg border-gray-300 focus:border-blue-500 focus:ring-blue-500"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={
|
||||
<span className="text-sm font-medium text-gray-700 flex items-center">
|
||||
AWS Session Name
|
||||
<Tooltip title="Optional. Session name for the AssumeRole call — appears in CloudTrail logs. Auto-generated if omitted.">
|
||||
{t("mcpTools.createMcpServer.awsSessionNameLabel")}
|
||||
<Tooltip title={t("mcpTools.createMcpServer.awsSessionNameTooltip")}>
|
||||
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
|
||||
</Tooltip>
|
||||
</span>
|
||||
|
|
@ -1053,7 +1085,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
name={["credentials", "aws_session_name"]}
|
||||
>
|
||||
<Input
|
||||
placeholder="litellm-prod (optional, auto-generated if blank)"
|
||||
placeholder={t("mcpTools.createMcpServer.awsSessionNamePlaceholder")}
|
||||
className="rounded-lg border-gray-300 focus:border-blue-500 focus:ring-blue-500"
|
||||
/>
|
||||
</Form.Item>
|
||||
|
|
@ -1127,10 +1159,10 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
|
||||
<div className="flex items-center justify-end space-x-3 pt-6 border-t border-gray-100">
|
||||
<Button variant="secondary" onClick={handleCancel}>
|
||||
Cancel
|
||||
{t("common.cancel")}
|
||||
</Button>
|
||||
<Button variant="primary" loading={isLoading}>
|
||||
{isLoading ? "Creating..." : "Add MCP Server"}
|
||||
{isLoading ? t("mcpTools.createMcpServer.creating") : t("mcpTools.createMcpServer.addButton")}
|
||||
</Button>
|
||||
</div>
|
||||
</Form>
|
||||
|
|
|
|||
|
|
@ -3326,6 +3326,100 @@
|
|||
"required": "Please enter stdio configuration",
|
||||
"invalidJson": "Please enter valid JSON"
|
||||
},
|
||||
"userEnvVarsModal": {
|
||||
"title": "Set your credentials",
|
||||
"perUserTag": "Per-user",
|
||||
"loadError": "Failed to load env vars",
|
||||
"noFieldsConfigured": "No per-user fields configured for this server.",
|
||||
"privacyNote": "These values are private to you. Your admin configured this MCP server to require these per-user credentials. Saved values are never shown back; leave an already-set field blank to keep it, or enter a value to set or change it.",
|
||||
"setTag": "Set",
|
||||
"fieldRequired": "{{name}} is required",
|
||||
"overwritePlaceholder": "Enter a new value to overwrite",
|
||||
"enterFieldPlaceholder": "Enter your {{name}}",
|
||||
"savedSuccess": "Credentials saved",
|
||||
"saveFailed": "Failed to save env vars: {{error}}",
|
||||
"saveButton": "Save Credentials"
|
||||
},
|
||||
"createMcpServer": {
|
||||
"oauthAuthSuccess": "OAuth authorization successful! Please click 'Create MCP Server' to save the configuration.",
|
||||
"invalidJsonStdio": "Invalid JSON in stdio configuration",
|
||||
"invalidJsonTokenValidation": "Invalid JSON in Token Validation Rules",
|
||||
"createSuccess": "MCP Server created successfully",
|
||||
"submitSuccess": "MCP Server submitted for admin review",
|
||||
"createFailed": "Error creating MCP Server: {{reason}}",
|
||||
"submitFailed": "Error submitting MCP Server: {{reason}}",
|
||||
"createNewGroup": "create new group",
|
||||
"mcpLogoAlt": "MCP Logo",
|
||||
"modalTitleAdmin": "Add New MCP Server",
|
||||
"modalTitleUser": "Submit MCP Server for Review",
|
||||
"nonAdminBanner": "Your submission will be sent for admin review before it becomes active. Note: the request must be made with a team-scoped API key.",
|
||||
"serverNameLabel": "MCP Server Name",
|
||||
"serverNameTooltip": "Best practice: Use a descriptive name that indicates the server's purpose (e.g., 'GitHub_MCP', 'Email_Service'). Cannot contain spaces or hyphens; use underscores instead. Names must comply with SEP-986 and will be rejected if invalid (https://modelcontextprotocol.io/specification/2025-11-25/server/tools#tool-names).",
|
||||
"serverNameRequired": "Please enter a server name",
|
||||
"serverNamePlaceholder": "e.g., GitHub_MCP, Zapier_MCP, etc.",
|
||||
"aliasLabel": "Alias",
|
||||
"aliasTooltip": "A short, unique identifier for this server. Defaults to the server name if not provided. Cannot contain spaces or hyphens; use underscores instead.",
|
||||
"descriptionRequired": "Please enter a server description",
|
||||
"descriptionPlaceholder": "Brief description of what this server does",
|
||||
"sourceUrlLabel": "GitHub / Source URL",
|
||||
"transportLabel": "Transport Type",
|
||||
"transportRequired": "Please select a transport type",
|
||||
"transportPlaceholder": "Select transport",
|
||||
"transportHttp": "Streamable HTTP (Recommended)",
|
||||
"transportSse": "Server-Sent Events (SSE)",
|
||||
"transportStdio": "Standard Input/Output (stdio)",
|
||||
"transportOpenapi": "OpenAPI Spec",
|
||||
"serverUrlLabel": "MCP Server URL",
|
||||
"serverUrlRequired": "Please enter a server URL",
|
||||
"byokLabel": "BYOK (Bring Your Own Key)",
|
||||
"byokTooltip": "When enabled, each user provides their own API key for this service. Keys are stored per-user and never shared.",
|
||||
"byokKeysSentAs": "User keys will be sent as:",
|
||||
"byokSetAuthType": "Set the <strong>Authentication Type</strong> below to specify how user keys are sent (e.g., Bearer Token, API Key header).",
|
||||
"byokAccessDescLabel": "Access Description",
|
||||
"byokAccessDescTooltip": "List of permissions shown to users in the connection modal (e.g. 'Create and manage Jira issues')",
|
||||
"byokAccessDescPlaceholder": "Add access description items (press Enter after each)",
|
||||
"byokApiKeyHelpUrlLabel": "API Key Help URL",
|
||||
"byokApiKeyHelpUrlTooltip": "Optional link shown to users to help them find their API key",
|
||||
"authLabel": "Authentication",
|
||||
"authTypeRequired": "Please select an auth type",
|
||||
"authTypePlaceholder": "Select auth type",
|
||||
"authNone": "None",
|
||||
"authApiKey": "API Key",
|
||||
"authBearerToken": "Bearer Token",
|
||||
"authToken": "Token",
|
||||
"authBasic": "Basic Auth",
|
||||
"authOauth": "OAuth",
|
||||
"authAwsSigv4": "AWS SigV4 (Bedrock AgentCore MCPs)",
|
||||
"authValueLabel": "Authentication Value",
|
||||
"authValueTooltip": "Token, password, or header value to send with each request for the selected auth type.",
|
||||
"authValueEmpty": "Authentication value cannot be empty whitespace",
|
||||
"authValuePlaceholder": "Enter token or secret",
|
||||
"awsSigv4Desc": "For MCP servers hosted on AWS Bedrock AgentCore. <a>View docs</a>",
|
||||
"awsRegionLabel": "AWS Region",
|
||||
"awsRegionTooltip": "AWS region for SigV4 signing (e.g., us-east-1)",
|
||||
"awsRegionRequired": "AWS region is required for SigV4 auth",
|
||||
"awsServiceNameLabel": "AWS Service Name",
|
||||
"awsServiceNameTooltip": "AWS service name for SigV4 signing. Defaults to 'bedrock-agentcore'.",
|
||||
"awsAccessKeyIdLabel": "AWS Access Key ID",
|
||||
"awsAccessKeyIdTooltip": "Optional. If not provided, falls back to the boto3 credential chain (IAM role, env vars, etc.).",
|
||||
"awsAccessKeyIdRequired": "Access Key ID is required when Secret Access Key is provided",
|
||||
"awsAccessKeyIdPlaceholder": "AKIA... (optional — uses IAM role if blank)",
|
||||
"awsSecretKeyLabel": "AWS Secret Access Key",
|
||||
"awsSecretKeyTooltip": "Optional. Required if AWS Access Key ID is provided.",
|
||||
"awsSecretKeyRequired": "Secret Access Key is required when Access Key ID is provided",
|
||||
"awsSecretKeyPlaceholder": "Enter secret key (optional — uses IAM role if blank)",
|
||||
"awsSessionTokenLabel": "AWS Session Token",
|
||||
"awsSessionTokenTooltip": "Optional. Only needed for temporary STS credentials.",
|
||||
"awsSessionTokenPlaceholder": "Enter session token (optional)",
|
||||
"awsRoleArnLabel": "AWS Role ARN",
|
||||
"awsRoleArnTooltip": "Optional. IAM role ARN to assume via STS before signing. If set, LiteLLM calls sts:AssumeRole to get temporary credentials. Uses ambient credentials (IAM role, env vars) as the source identity unless explicit keys are also provided.",
|
||||
"awsRoleArnPlaceholder": "arn:aws:iam::123456789012:role/MyRole (optional)",
|
||||
"awsSessionNameLabel": "AWS Session Name",
|
||||
"awsSessionNameTooltip": "Optional. Session name for the AssumeRole call — appears in CloudTrail logs. Auto-generated if omitted.",
|
||||
"awsSessionNamePlaceholder": "litellm-prod (optional, auto-generated if blank)",
|
||||
"creating": "Creating...",
|
||||
"addButton": "Add MCP Server"
|
||||
},
|
||||
"toolTestPanel": {
|
||||
"testToolTitle": "Test Tool:",
|
||||
"clickToCopyToolName": "Click to copy tool name",
|
||||
|
|
|
|||
|
|
@ -3326,6 +3326,100 @@
|
|||
"required": "请输入 stdio 配置",
|
||||
"invalidJson": "请输入有效的 JSON"
|
||||
},
|
||||
"userEnvVarsModal": {
|
||||
"title": "设置您的凭据",
|
||||
"perUserTag": "按用户",
|
||||
"loadError": "加载环境变量失败",
|
||||
"noFieldsConfigured": "此服务器未配置按用户字段。",
|
||||
"privacyNote": "这些值仅对您私有。您的管理员配置了此 MCP 服务器需要这些按用户凭据。已保存的值不会再次显示;已设置的字段留空表示保留原值,输入新值则覆盖。",
|
||||
"setTag": "已设置",
|
||||
"fieldRequired": "{{name}} 为必填项",
|
||||
"overwritePlaceholder": "输入新值以覆盖",
|
||||
"enterFieldPlaceholder": "输入您的 {{name}}",
|
||||
"savedSuccess": "凭据已保存",
|
||||
"saveFailed": "保存环境变量失败:{{error}}",
|
||||
"saveButton": "保存凭据"
|
||||
},
|
||||
"createMcpServer": {
|
||||
"oauthAuthSuccess": "OAuth 授权成功!请点击「创建 MCP 服务器」保存配置。",
|
||||
"invalidJsonStdio": "stdio 配置中的 JSON 无效",
|
||||
"invalidJsonTokenValidation": "Token 验证规则中的 JSON 无效",
|
||||
"createSuccess": "MCP 服务器创建成功",
|
||||
"submitSuccess": "MCP 服务器已提交,待管理员审核",
|
||||
"createFailed": "创建 MCP 服务器时出错:{{reason}}",
|
||||
"submitFailed": "提交 MCP 服务器时出错:{{reason}}",
|
||||
"createNewGroup": "创建新组",
|
||||
"mcpLogoAlt": "MCP Logo",
|
||||
"modalTitleAdmin": "添加新 MCP 服务器",
|
||||
"modalTitleUser": "提交 MCP 服务器审核",
|
||||
"nonAdminBanner": "您的提交将发送给管理员审核后才能生效。注意:请求必须使用团队范围的 API 密钥。",
|
||||
"serverNameLabel": "MCP 服务器名称",
|
||||
"serverNameTooltip": "最佳实践:使用描述性名称说明服务器用途(如 'GitHub_MCP'、'Email_Service')。不能包含空格或连字符,请使用下划线。名称须符合 SEP-986,无效名称将被拒绝。",
|
||||
"serverNameRequired": "请输入服务器名称",
|
||||
"serverNamePlaceholder": "例如:GitHub_MCP、Zapier_MCP 等",
|
||||
"aliasLabel": "别名",
|
||||
"aliasTooltip": "此服务器的简短唯一标识符。未提供时默认使用服务器名称。不能包含空格或连字符,请使用下划线。",
|
||||
"descriptionRequired": "请输入服务器描述",
|
||||
"descriptionPlaceholder": "简要描述此服务器的功能",
|
||||
"sourceUrlLabel": "GitHub / 源码 URL",
|
||||
"transportLabel": "传输类型",
|
||||
"transportRequired": "请选择传输类型",
|
||||
"transportPlaceholder": "选择传输类型",
|
||||
"transportHttp": "Streamable HTTP(推荐)",
|
||||
"transportSse": "Server-Sent Events (SSE)",
|
||||
"transportStdio": "Standard Input/Output (stdio)",
|
||||
"transportOpenapi": "OpenAPI Spec",
|
||||
"serverUrlLabel": "MCP 服务器 URL",
|
||||
"serverUrlRequired": "请输入服务器 URL",
|
||||
"byokLabel": "BYOK(自带密钥)",
|
||||
"byokTooltip": "启用后,每位用户为此服务提供自己的 API 密钥。密钥按用户存储,不共享。",
|
||||
"byokKeysSentAs": "用户密钥发送格式:",
|
||||
"byokSetAuthType": "请在下方设置<strong>认证类型</strong>,以指定用户密钥的发送方式(如 Bearer Token、API Key 请求头)。",
|
||||
"byokAccessDescLabel": "访问描述",
|
||||
"byokAccessDescTooltip": "在连接弹窗中向用户显示的权限列表(例如:'创建和管理 Jira 问题')",
|
||||
"byokAccessDescPlaceholder": "添加访问描述项(每项后按回车)",
|
||||
"byokApiKeyHelpUrlLabel": "API 密钥帮助 URL",
|
||||
"byokApiKeyHelpUrlTooltip": "向用户显示的可选链接,帮助其找到 API 密钥",
|
||||
"authLabel": "认证",
|
||||
"authTypeRequired": "请选择认证类型",
|
||||
"authTypePlaceholder": "选择认证类型",
|
||||
"authNone": "无",
|
||||
"authApiKey": "API Key",
|
||||
"authBearerToken": "Bearer Token",
|
||||
"authToken": "Token",
|
||||
"authBasic": "Basic Auth",
|
||||
"authOauth": "OAuth",
|
||||
"authAwsSigv4": "AWS SigV4(Bedrock AgentCore MCPs)",
|
||||
"authValueLabel": "认证值",
|
||||
"authValueTooltip": "针对所选认证类型,随每次请求发送的 Token、密码或请求头值。",
|
||||
"authValueEmpty": "认证值不能为纯空格",
|
||||
"authValuePlaceholder": "输入 Token 或密钥",
|
||||
"awsSigv4Desc": "适用于托管在 AWS Bedrock AgentCore 上的 MCP 服务器。<a>查看文档</a>",
|
||||
"awsRegionLabel": "AWS 区域",
|
||||
"awsRegionTooltip": "SigV4 签名使用的 AWS 区域(如 us-east-1)",
|
||||
"awsRegionRequired": "SigV4 认证需要提供 AWS 区域",
|
||||
"awsServiceNameLabel": "AWS 服务名称",
|
||||
"awsServiceNameTooltip": "SigV4 签名使用的 AWS 服务名称,默认为 'bedrock-agentcore'。",
|
||||
"awsAccessKeyIdLabel": "AWS Access Key ID",
|
||||
"awsAccessKeyIdTooltip": "可选。若不提供,则回退到 boto3 凭据链(IAM 角色、环境变量等)。",
|
||||
"awsAccessKeyIdRequired": "提供 Secret Access Key 时必须同时提供 Access Key ID",
|
||||
"awsAccessKeyIdPlaceholder": "AKIA...(可选,留空使用 IAM 角色)",
|
||||
"awsSecretKeyLabel": "AWS Secret Access Key",
|
||||
"awsSecretKeyTooltip": "可选。提供 AWS Access Key ID 时必须填写。",
|
||||
"awsSecretKeyRequired": "提供 Access Key ID 时必须同时提供 Secret Access Key",
|
||||
"awsSecretKeyPlaceholder": "输入密钥(可选,留空使用 IAM 角色)",
|
||||
"awsSessionTokenLabel": "AWS Session Token",
|
||||
"awsSessionTokenTooltip": "可选。仅在使用临时 STS 凭据时需要。",
|
||||
"awsSessionTokenPlaceholder": "输入 Session Token(可选)",
|
||||
"awsRoleArnLabel": "AWS Role ARN",
|
||||
"awsRoleArnTooltip": "可选。签名前通过 STS 代入的 IAM 角色 ARN。若设置,LiteLLM 将调用 sts:AssumeRole 获取临时凭据。除非同时提供了显式密钥,否则使用环境凭据(IAM 角色、环境变量)作为源身份。",
|
||||
"awsRoleArnPlaceholder": "arn:aws:iam::123456789012:role/MyRole(可选)",
|
||||
"awsSessionNameLabel": "AWS Session Name",
|
||||
"awsSessionNameTooltip": "可选。AssumeRole 调用的会话名称,出现在 CloudTrail 日志中。若不填写则自动生成。",
|
||||
"awsSessionNamePlaceholder": "litellm-prod(可选,留空自动生成)",
|
||||
"creating": "创建中...",
|
||||
"addButton": "添加 MCP 服务器"
|
||||
},
|
||||
"toolTestPanel": {
|
||||
"testToolTitle": "测试工具:",
|
||||
"clickToCopyToolName": "点击复制工具名称",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue