From f72f4ba71b8ce0dd0d98be21f63cdd6bacbeb1f1 Mon Sep 17 00:00:00 2001 From: yoma Date: Sat, 11 Jul 2026 22:16:03 +0800 Subject: [PATCH] Improve MCP token default names --- .../src/components/settings/McpConfigCard.tsx | 30 ++++++++++++++++--- apps/web/src/i18n/resources/en-US.ts | 2 +- apps/web/src/i18n/resources/zh-CN.ts | 2 +- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/apps/web/src/components/settings/McpConfigCard.tsx b/apps/web/src/components/settings/McpConfigCard.tsx index c151ddf8..4d3ccb25 100644 --- a/apps/web/src/components/settings/McpConfigCard.tsx +++ b/apps/web/src/components/settings/McpConfigCard.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState, type FormEvent } from "react"; +import { useEffect, useRef, useState, type FormEvent } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useTranslation } from "react-i18next"; import { ChevronDown, Copy, KeyRound, Plus, ShieldCheck, Trash2 } from "lucide-react"; @@ -24,6 +24,15 @@ interface CreatedTokenNoticeProps { token: string; } +const getNextTokenName = (tokens: ApiToken[]) => { + const highestNumber = tokens.reduce((highest, token) => { + const match = token.name.match(/^MCP Token (\d+)$/i); + return match ? Math.max(highest, Number(match[1])) : highest; + }, 0); + + return `MCP Token ${highestNumber + 1}`; +}; + const CreatedTokenNotice = ({ token }: CreatedTokenNoticeProps) => { const { t } = useTranslation(); const [copiedAction, setCopiedAction] = useState<"token" | "config" | null>(null); @@ -322,7 +331,9 @@ const TokenList = ({ tokens, isLoading, isDeleting, onDelete }: TokenListProps) export const McpConfigCard = () => { const { t } = useTranslation(); const queryClient = useQueryClient(); - const [name, setName] = useState("MCP Agent"); + const [name, setName] = useState("MCP Token 1"); + const [isNameCustomized, setIsNameCustomized] = useState(false); + const nameInitialized = useRef(false); const [selectedScopes, setSelectedScopes] = useState>(() => new Set(ALL_TOKEN_SCOPES)); const [scopeDefaultsSynced, setScopeDefaultsSynced] = useState(false); const [createdToken, setCreatedToken] = useState<{ token: string; apiToken: ApiToken } | null>(null); @@ -345,11 +356,19 @@ export const McpConfigCard = () => { setScopeDefaultsSynced(true); }, [scopeDefaultsSynced, tokensQuery.data?.availableScopes]); + useEffect(() => { + if (!nameInitialized.current && !isNameCustomized && tokensQuery.data?.apiTokens) { + setName(getNextTokenName(tokensQuery.data.apiTokens)); + nameInitialized.current = true; + } + }, [isNameCustomized, tokensQuery.data?.apiTokens]); + const createMutation = useMutation({ mutationFn: api.createApiToken, onSuccess: async (data) => { setCreatedToken(data); - setName(""); + setName(getNextTokenName([...tokens, data.apiToken])); + setIsNameCustomized(true); setSelectedScopes(new Set(availableScopes)); await queryClient.invalidateQueries({ queryKey: ["api-tokens"] }); }, @@ -400,7 +419,10 @@ export const McpConfigCard = () => { setName(event.target.value)} + onChange={(event) => { + setName(event.target.value); + setIsNameCustomized(true); + }} placeholder={t("mcp.namePlaceholder")} />