-
Notifications
You must be signed in to change notification settings - Fork 614
feat: Add mcprouter's MCP marketplace api support #727
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughAdds MCP Router marketplace integration: a new McpRouterManager, presenter APIs for listing/installing marketplace servers and API-key management, built-in market UI and route, MCP server config shape changes (source/sourceId, descriptions, auto-approve/disable), and UI enhancements for masked custom headers and smarter edit-mode initialization. Changes
Sequence Diagram(s)sequenceDiagram
participant U as User
participant V as McpBuiltinMarket (Vue)
participant P as McpPresenter
participant R as McpRouterManager
participant A as MCPRouter API
U->>V: Open Built-in Market
V->>P: listMcpRouterServers(page, limit)
P->>R: listServers(page, limit)
R->>A: POST /market/list {page, limit}
A-->>R: { code:0, data:{ servers[] } }
R-->>P: servers[]
P-->>V: servers[]
V-->>U: Render items
sequenceDiagram
participant U as User
participant V as McpBuiltinMarket (Vue)
participant P as McpPresenter
participant R as McpRouterManager
participant C as ConfigPresenter
participant A as MCPRouter API
U->>V: Click Install (server_key)
V->>P: setMcpRouterApiKey(key)
P->>C: save mcprouterApiKey
V->>P: installMcpRouterServer(server_key)
P->>R: installServer(server_key)
R->>A: POST /market/get {server: server_key} + Authorization
A-->>R: { code:0, data:{ detail } }
R->>C: addMcpServer({ source:'mcprouter', sourceId:server_key, ... })
C-->>R: true
R-->>P: true
P-->>V: success
V-->>U: Mark as installed + toast
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
♻️ Duplicate comments (1)
src/renderer/src/i18n/en-US/common.json (1)
75-76: LGTM: Shared “Saved” key addedKey is correctly placed in common.json and matches usage expectations.
Note: See the FA-IR comment for a repository-wide verification script ensuring this key exists across all locales.
🧹 Nitpick comments (23)
src/renderer/src/i18n/zh-HK/common.json (1)
75-77: Unify terminology: use Traditional HK form consistent with "save""save" is translated as "儲存", but "saved" is "已保存". For zh-HK, prefer "已儲存" to stay consistent and avoid Simplified usage.
- "saved": "已保存" + "saved": "已儲存"src/renderer/src/i18n/ko-KR/common.json (1)
75-77: Adjust "saved" to avoid collision with "save"Currently both "save" and "saved" are "저장". Suggest "저장됨" for the past/complete state, which is standard in Korean UIs.
- "saved": "저장" + "saved": "저장됨"src/renderer/src/i18n/ru-RU/common.json (1)
75-77: Fix Russian aspect: use neutral passive form"Сохранил" reads as “He saved”. For status labels, use "Сохранено".
- "saved": "Сохранил" + "saved": "Сохранено"src/renderer/src/i18n/zh-TW/common.json (1)
75-76: Nit: Prefer TW phrasing “已儲存” for consistency with “儲存”For zh-TW, “儲存” is used for the “save” label; aligning the past tense to “已儲存” improves locale consistency.
Apply:
- "saved": "已保存" + "saved": "已儲存"src/renderer/src/i18n/fr-FR/settings.json (1)
632-633: French phrasing + consistency: prefer “clé API” and adjust style
- “Apikey” is not idiomatic French. Use “clé API” and neutral phrasing.
- Optional: “fonctionnalité” reads more natural than “fonction” in UX copy.
Proposed update:
- "e2bApiKeyRequired": "Apikey doit être entré pour activer la fonction E2B", + "e2bApiKeyRequired": "La clé API est requise pour activer la fonctionnalité E2B",src/renderer/src/i18n/fr-FR/common.json (1)
75-76: Use the correct French past participle for “Saved”“Sauvé” is unnatural in this UX context. Prefer “Enregistré” (consistent with “Enregistrer”).
- "saved": "Sauvé" + "saved": "Enregistré"src/renderer/src/i18n/fr-FR/routes.json (1)
13-15: Minor casing/style consistency for FrenchFrench UI labels generally avoid capitalizing common nouns mid-sentence. Consider lowercasing “Prompts” for consistency with other entries.
- "settings-prompt": "Gestion des Prompts", + "settings-prompt": "Gestion des prompts",“Marché MCP” looks good.
src/renderer/src/i18n/ru-RU/routes.json (1)
14-15: Localize the new route label into RussianCurrently the value is in English. Consider translating for consistency with other RU labels.
Suggested change:
- "settings-mcp-market": "MCP Market" + "settings-mcp-market": "Рынок MCP"If you prefer a different style (e.g., "Маркет MCP"), I can update across locales for consistency notes.
src/renderer/src/i18n/fa-IR/settings.json (1)
640-642: Polish Persian punctuation and term consistency (comma spacing + API Key phrasing).
- Remove the space before the Persian comma in clickToEdit.
- Prefer consistent terminology for API keys. Suggest "API Key" phrasing over "Apikey" and a more natural sentence.
Apply this diff:
- "e2bApiKeyRequired": "برای فعال کردن عملکرد E2B باید Apikey وارد شود", - "clickToEdit": "برای مشاهده مطالب کامل ، روی ویرایش کلیک کنید" + "e2bApiKeyRequired": "برای فعالسازی E2B، وارد کردن API Key الزامی است", + "clickToEdit": "برای مشاهده مطالب کامل، روی ویرایش کلیک کنید"src/renderer/src/i18n/ja-JP/common.json (1)
75-77: Clarify “saved” usage context for Japanese translationThe
"saved"key is present in everycommon.jsonundersrc/renderer/src/i18n, so updating the Japanese file won’t introduce missing keys elsewhere. Please confirm whether this label is shown as:
- a persistent status/state (e.g. “Status: Saved”)
→ use “保存済み”- a one-time toast/message after an action
→ use “保存しました”Once confirmed, apply one of:
--- a/src/renderer/src/i18n/ja-JP/common.json +++ b/src/renderer/src/i18n/ja-JP/common.json @@ -74,3 +74,4 @@ "clear": "クリア", - "saved": "保存" + "saved": "保存済み" }--- a/src/renderer/src/i18n/ja-JP/common.json +++ b/src/renderer/src/i18n/ja-JP/common.json @@ -74,3 +74,4 @@ "clear": "クリア", - "saved": "保存" + "saved": "保存しました" }src/renderer/src/i18n/ru-RU/settings.json (1)
632-634: Unify “API key” terminology and improve sentence style.Use “ключ API” (or “API‑ключ”) consistently across RU locale, and prefer a more natural construction.
Apply this diff:
- "e2bApiKeyRequired": "Apikey должен быть введен, чтобы включить функцию E2B", + "e2bApiKeyRequired": "Для включения функции E2B необходимо ввести ключ API",src/renderer/src/i18n/ko-KR/mcp.json (1)
249-268: Standardize MCPRouter brand and improve Korean phrasing (more natural, consistent formal tone).Current strings mix “McProuter” and contain machine-translated/awkward phrasing. Suggested edits below keep the existing formal imperative tone “-하십시오” used elsewhere in this file and unify branding to “MCPRouter”.
- "apiKeyPlaceholder": "McProuter API 키를 입력하십시오", - "apiKeyRequiredDesc": "설치하기 전에 먼저 McProuter API 키를 작성하십시오.", + "apiKeyPlaceholder": "MCPRouter API 키를 입력하십시오", + "apiKeyRequiredDesc": "설치 전에 먼저 MCPRouter API 키를 입력하십시오.", "apiKeyRequiredTitle": "API 키가 필요합니다", - "browseBuiltin": "내장 MCP 시장을 찾아보십시오", + "browseBuiltin": "내장 MCP 시장 둘러보기", "builtinTitle": "MCP 시장", - "empty": "아직 서비스가 없습니다", - "install": "설치하다", - "installFailed": "설치가 실패했습니다", - "installSuccess": "성공적으로 설치", - "installed": "설치", - "keyGuide": "열쇠를 얻으십시오", - "keyHelpEnd": "API 키를 신청 한 후 위의 입력 상자를 채우십시오.", - "keyHelpText": "먼저 도착하십시오", - "loadMore": "더로드하십시오", - "noMore": "더 이상", - "poweredBy": "McProuter에 의해 구동", - "pullDownToLoad": "더 많은로드하기 위해 계속 드롭 다운하십시오" + "empty": "표시할 서비스가 없습니다", + "install": "설치", + "installFailed": "설치 실패", + "installSuccess": "설치 성공", + "installed": "설치됨", + "keyGuide": "키 발급", + "keyHelpEnd": "API 키를 신청한 후 위의 입력란에 입력하십시오.", + "keyHelpText": "먼저 다음으로 이동하십시오", + "loadMore": "더 불러오기", + "noMore": "더 이상 없음", + "poweredBy": "MCPRouter 제공", + "pullDownToLoad": "더 불러오려면 아래로 당기십시오"src/renderer/src/i18n/zh-CN/mcp.json (1)
253-253: Localize the “Powered by” label to Chinese.Keep brand as “MCPRouter” but localize the phrase for consistency with the rest of zh-CN UI text.
- "poweredBy": "Powered by MCPRouter", + "poweredBy": "由 MCPRouter 提供支持",src/renderer/src/i18n/ru-RU/mcp.json (1)
249-268: Fix Russian grammar and unify “MCPRouter” brand.Several phrases are unnatural, and the brand is inconsistently cased. Suggested improvements below.
- "apiKeyPlaceholder": "Введите ключ McProuter API", - "apiKeyRequiredDesc": "Пожалуйста, заполните клавишу McProuter API сначала перед установкой", - "apiKeyRequiredTitle": "Требует ключа API", - "browseBuiltin": "Просмотрите встроенный рынок MCP", - "builtinTitle": "MCP Market", - "empty": "Пока нет услуг", + "apiKeyPlaceholder": "Введите ключ API MCPRouter", + "apiKeyRequiredDesc": "Пожалуйста, укажите ключ API MCPRouter перед установкой.", + "apiKeyRequiredTitle": "Требуется ключ API", + "browseBuiltin": "Просмотреть встроенный рынок MCP", + "builtinTitle": "Рынок MCP", + "empty": "Сервисы отсутствуют", "install": "Установить", - "installFailed": "Установка не удалась", - "installSuccess": "Установка успешно", - "installed": "Установлен", - "keyGuide": "Получите ключ", - "keyHelpEnd": "После подачи заявки на ключ API заполните поле ввода выше", - "keyHelpText": "Пожалуйста, приезжайте первым", - "loadMore": "Загружать больше", - "noMore": "Больше не надо", - "poweredBy": "Оборудован от McProuter", - "pullDownToLoad": "Продолжайте падать, чтобы загружать больше" + "installFailed": "Не удалось установить", + "installSuccess": "Установка выполнена успешно", + "installed": "Установлено", + "keyGuide": "Где получить ключ", + "keyHelpEnd": "После получения ключа API укажите его в поле выше.", + "keyHelpText": "Сначала перейдите на", + "loadMore": "Загрузить ещё", + "noMore": "Больше нет", + "poweredBy": "Работает на базе MCPRouter", + "pullDownToLoad": "Потяните вниз, чтобы загрузить ещё"src/renderer/src/i18n/fa-IR/mcp.json (1)
250-268: Improve Persian phrasing and unify “MCPRouter” brand.A few strings read unnatural or use inconsistent capitalization. Suggested edits below use idiomatic Persian and correct punctuation.
- "apiKeyPlaceholder": "کلید API MCPROUTER را وارد کنید", - "apiKeyRequiredDesc": "لطفاً قبل از نصب ، ابتدا کلید API McProuter را پر کنید", - "apiKeyRequiredTitle": "به کلید API نیاز دارد", + "apiKeyPlaceholder": "کلید API MCPRouter را وارد کنید", + "apiKeyRequiredDesc": "لطفاً پیش از نصب، ابتدا کلید API MCPRouter را وارد کنید.", + "apiKeyRequiredTitle": "نیاز به کلید API", "browseBuiltin": "مرور بازار داخلی MCP", "builtinTitle": "بازار MCP", - "empty": "هنوز هیچ خدمتی وجود ندارد", - "install": "نصب کردن", - "installFailed": "نصب انجام نشد", - "installSuccess": "نصب با موفقیت", + "empty": "هیچ خدمتی موجود نیست", + "install": "نصب", + "installFailed": "نصب ناموفق بود", + "installSuccess": "نصب با موفقیت انجام شد", "installed": "نصب شده", - "keyGuide": "کلید را دریافت کنید", - "keyHelpEnd": "پس از درخواست کلید API ، کادر ورودی را در بالا پر کنید", - "keyHelpText": "لطفا ابتدا وارد شوید", - "loadMore": "بار بیشتر", - "noMore": "نه بیشتر", - "poweredBy": "نیرو توسط McProuter", - "pullDownToLoad": "برای بارگیری بیشتر به پایین بیاید" + "keyGuide": "دریافت کلید", + "keyHelpEnd": "پس از دریافت کلید API، آن را در کادر بالا وارد کنید.", + "keyHelpText": "ابتدا به", + "loadMore": "بارگذاری بیشتر", + "noMore": "مورد بیشتری نیست", + "poweredBy": "قدرتگرفته از MCPRouter", + "pullDownToLoad": "برای بارگذاری بیشتر پایین بکشید"src/shared/presenter.d.ts (1)
991-993: Consider adding JSDoc comments for the new source tracking fields.The
sourceandsourceIdfields enable tracking of server origins, which is crucial for the marketplace integration. However, their purpose and expected values should be documented for better maintainability.Add documentation to clarify the purpose and expected values:
- source?: string // 来源标识: "mcprouter" | "modelscope" | undefined(for manual) - sourceId?: string // 来源ID: mcprouter的uuid 或 modelscope的mcpServer.id + /** Source identifier indicating where the server configuration originated from */ + source?: 'mcprouter' | 'modelscope' // undefined for manually added servers + /** Unique identifier from the source system (e.g., UUID for mcprouter, server.id for modelscope) */ + sourceId?: stringsrc/renderer/src/components/mcp-config/mcpServerForm.vue (1)
556-574: Consider extracting the masking logic to a utility function.The
maskSensitiveValuefunction could be useful in other parts of the application where sensitive data needs to be displayed. Consider moving it to a shared utility module for reusability.Create a shared utility function:
// src/renderer/src/utils/sensitive.ts export function maskSensitiveValue(value: string): string { return value.replace(/=(.+)/g, (_, val) => { const trimmedVal = val.trim() if (trimmedVal.length <= 4) { return '=' + '*'.repeat(trimmedVal.length) } else if (trimmedVal.length <= 12) { return '=' + trimmedVal.substring(0, 1) + '*'.repeat(6) } else { const start = trimmedVal.substring(0, 2) const end = trimmedVal.substring(trimmedVal.length - 2) return '=' + start + '*'.repeat(8) + end } }) }Then import and use it in the component:
+import { maskSensitiveValue } from '@/utils/sensitive' -const maskSensitiveValue = (value: string): string => { - // ... existing implementation -}src/main/presenter/mcpPresenter/mcprouterManager.ts (1)
40-41: Consider using environment variables for API endpointsThe API endpoints are hardcoded. Consider moving them to a configuration file or environment variables for better maintainability and to support different environments (development, staging, production).
-const LIST_ENDPOINT = 'https://api.mcprouter.to/v1/list-servers' -const GET_ENDPOINT = 'https://api.mcprouter.to/v1/get-server' +const LIST_ENDPOINT = process.env.MCPROUTER_LIST_ENDPOINT || 'https://api.mcprouter.to/v1/list-servers' +const GET_ENDPOINT = process.env.MCPROUTER_GET_ENDPOINT || 'https://api.mcprouter.to/v1/get-server'src/renderer/src/components/settings/McpBuiltinMarket.vue (3)
140-147: Add error handling for loadApiKeyThe loadApiKey function silently catches all errors. Consider at least logging errors for debugging purposes.
const loadApiKey = async () => { try { const key = await mcpP.getMcpRouterApiKey?.() apiKeyInput.value = key || '' - } catch {} + } catch (error) { + console.error('Failed to load MCP Router API key:', error) + } }
169-183: Performance: Consider batch checking installation statusThe current implementation checks installation status one by one. For better performance, consider implementing a batch check method.
const checkInstalledServers = async () => { const installed = new Set<string>() - for (const item of items.value) { - try { - // 使用 server_key 作为 sourceId 检查安装状态,因为这是我们在安装时保存的标识符 - const isInstalled = await mcpP.isServerInstalled?.('mcprouter', item.server_key) - if (isInstalled) { - installed.add(item.server_key) - } - } catch (e) { - console.error('Failed to check installation status:', e) - } - } + // Consider implementing a batch check method in the presenter + const serverKeys = items.value.map(item => item.server_key) + try { + // This would require implementing a new batch check method + const installationStatuses = await mcpP.batchCheckServerInstallation?.('mcprouter', serverKeys) + if (installationStatuses) { + installationStatuses.forEach((status, index) => { + if (status) { + installed.add(serverKeys[index]) + } + }) + } + } catch (e) { + console.error('Failed to batch check installation status:', e) + // Fallback to individual checks + for (const item of items.value) { + try { + const isInstalled = await mcpP.isServerInstalled?.('mcprouter', item.server_key) + if (isInstalled) { + installed.add(item.server_key) + } + } catch (e) { + console.error('Failed to check installation status:', e) + } + } + } installedServers.value = installed }
286-296: Potential race condition with setTimeoutUsing setTimeout to check content height after mounting could lead to race conditions. Consider using nextTick or MutationObserver for more reliable detection.
onMounted(async () => { await loadApiKey() await fetchPage() // 初始加载后检查是否需要启用强制拉取模式 - setTimeout(() => { + await nextTick() const el = scrollContainer.value if (el && !hasMore.value) { const contentTooShort = el.scrollHeight <= el.clientHeight if (contentTooShort && items.value.length > 0) { canPullMore.value = true showPullToLoad.value = true } } - }, 100) })src/main/presenter/mcpPresenter/index.ts (2)
217-220: Consider adding error details for better debuggingThe error message could be more descriptive to help with debugging.
async installMcpRouterServer(serverKey: string): Promise<boolean> { - if (!this.mcprouter) throw new Error('McpRouterManager not available') + if (!this.mcprouter) throw new Error('McpRouterManager not available - initialization may have failed') return this.mcprouter.installServer(serverKey) }
240-263: Consider optimizing batch updatesThe updateMcpRouterServersAuth method could be optimized by batching all updates into a single configuration save operation instead of multiple individual updates.
async updateMcpRouterServersAuth(apiKey: string): Promise<void> { const servers = await this.configPresenter.getMcpServers() - const updates: Array<{ name: string; config: Partial<MCPServerConfig> }> = [] + const updatedServers = { ...servers } + let updateCount = 0 for (const [serverName, config] of Object.entries(servers)) { if (config.source === 'mcprouter' && config.customHeaders) { const updatedHeaders = { ...config.customHeaders, Authorization: `Bearer ${apiKey}` } - updates.push({ - name: serverName, - config: { customHeaders: updatedHeaders } - }) + updatedServers[serverName] = { + ...config, + customHeaders: updatedHeaders + } + updateCount++ } } - // 批量更新所有服务器的 Authorization - for (const update of updates) { - await this.configPresenter.updateMcpServer(update.name, update.config) - } + // Single batch update + if (updateCount > 0) { + await this.configPresenter.setMcpServers(updatedServers) + } - console.log(`Updated Authorization for ${updates.length} mcprouter servers`) + console.log(`Updated Authorization for ${updateCount} mcprouter servers`) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (44)
src/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts(1 hunks)src/main/presenter/mcpPresenter/index.ts(3 hunks)src/main/presenter/mcpPresenter/mcprouterManager.ts(1 hunks)src/renderer/src/components/mcp-config/mcpServerForm.vue(3 hunks)src/renderer/src/components/settings/McpBuiltinMarket.vue(1 hunks)src/renderer/src/components/settings/McpSettings.vue(3 hunks)src/renderer/src/i18n/en-US/common.json(1 hunks)src/renderer/src/i18n/en-US/mcp.json(1 hunks)src/renderer/src/i18n/en-US/routes.json(1 hunks)src/renderer/src/i18n/en-US/settings.json(1 hunks)src/renderer/src/i18n/fa-IR/common.json(1 hunks)src/renderer/src/i18n/fa-IR/mcp.json(1 hunks)src/renderer/src/i18n/fa-IR/routes.json(1 hunks)src/renderer/src/i18n/fa-IR/settings.json(1 hunks)src/renderer/src/i18n/fr-FR/common.json(1 hunks)src/renderer/src/i18n/fr-FR/mcp.json(1 hunks)src/renderer/src/i18n/fr-FR/routes.json(1 hunks)src/renderer/src/i18n/fr-FR/settings.json(1 hunks)src/renderer/src/i18n/ja-JP/common.json(1 hunks)src/renderer/src/i18n/ja-JP/mcp.json(1 hunks)src/renderer/src/i18n/ja-JP/routes.json(1 hunks)src/renderer/src/i18n/ja-JP/settings.json(1 hunks)src/renderer/src/i18n/ko-KR/common.json(1 hunks)src/renderer/src/i18n/ko-KR/mcp.json(1 hunks)src/renderer/src/i18n/ko-KR/routes.json(1 hunks)src/renderer/src/i18n/ko-KR/settings.json(1 hunks)src/renderer/src/i18n/ru-RU/common.json(1 hunks)src/renderer/src/i18n/ru-RU/mcp.json(1 hunks)src/renderer/src/i18n/ru-RU/routes.json(1 hunks)src/renderer/src/i18n/ru-RU/settings.json(1 hunks)src/renderer/src/i18n/zh-CN/common.json(1 hunks)src/renderer/src/i18n/zh-CN/mcp.json(1 hunks)src/renderer/src/i18n/zh-CN/routes.json(1 hunks)src/renderer/src/i18n/zh-CN/settings.json(1 hunks)src/renderer/src/i18n/zh-HK/common.json(1 hunks)src/renderer/src/i18n/zh-HK/mcp.json(1 hunks)src/renderer/src/i18n/zh-HK/routes.json(1 hunks)src/renderer/src/i18n/zh-HK/settings.json(1 hunks)src/renderer/src/i18n/zh-TW/common.json(1 hunks)src/renderer/src/i18n/zh-TW/mcp.json(1 hunks)src/renderer/src/i18n/zh-TW/routes.json(1 hunks)src/renderer/src/i18n/zh-TW/settings.json(1 hunks)src/renderer/src/router/index.ts(1 hunks)src/shared/presenter.d.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (21)
src/renderer/src/**/*
📄 CodeRabbit Inference Engine (.cursor/rules/i18n.mdc)
src/renderer/src/**/*: All user-facing strings must use i18n keys (avoid hardcoded user-visible text in code)
Use the 'vue-i18n' framework for all internationalization in the renderer
Ensure all user-visible text in the renderer uses the translation system
Files:
src/renderer/src/i18n/fr-FR/settings.jsonsrc/renderer/src/i18n/ko-KR/routes.jsonsrc/renderer/src/i18n/en-US/common.jsonsrc/renderer/src/i18n/en-US/routes.jsonsrc/renderer/src/router/index.tssrc/renderer/src/i18n/ja-JP/common.jsonsrc/renderer/src/i18n/zh-HK/routes.jsonsrc/renderer/src/i18n/zh-TW/routes.jsonsrc/renderer/src/i18n/fr-FR/routes.jsonsrc/renderer/src/i18n/zh-TW/common.jsonsrc/renderer/src/i18n/fa-IR/common.jsonsrc/renderer/src/i18n/zh-CN/common.jsonsrc/renderer/src/i18n/en-US/settings.jsonsrc/renderer/src/i18n/fa-IR/routes.jsonsrc/renderer/src/components/settings/McpSettings.vuesrc/renderer/src/i18n/zh-CN/settings.jsonsrc/renderer/src/i18n/ko-KR/common.jsonsrc/renderer/src/i18n/ru-RU/settings.jsonsrc/renderer/src/i18n/ko-KR/settings.jsonsrc/renderer/src/i18n/zh-TW/mcp.jsonsrc/renderer/src/i18n/fa-IR/settings.jsonsrc/renderer/src/i18n/ko-KR/mcp.jsonsrc/renderer/src/i18n/fr-FR/common.jsonsrc/renderer/src/i18n/fr-FR/mcp.jsonsrc/renderer/src/i18n/zh-TW/settings.jsonsrc/renderer/src/i18n/ja-JP/settings.jsonsrc/renderer/src/i18n/ru-RU/mcp.jsonsrc/renderer/src/components/settings/McpBuiltinMarket.vuesrc/renderer/src/i18n/zh-HK/settings.jsonsrc/renderer/src/i18n/zh-HK/common.jsonsrc/renderer/src/i18n/ja-JP/routes.jsonsrc/renderer/src/i18n/ru-RU/common.jsonsrc/renderer/src/i18n/ru-RU/routes.jsonsrc/renderer/src/i18n/zh-CN/mcp.jsonsrc/renderer/src/i18n/zh-CN/routes.jsonsrc/renderer/src/i18n/en-US/mcp.jsonsrc/renderer/src/i18n/zh-HK/mcp.jsonsrc/renderer/src/i18n/fa-IR/mcp.jsonsrc/renderer/src/i18n/ja-JP/mcp.jsonsrc/renderer/src/components/mcp-config/mcpServerForm.vue
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Use English for logs and comments
Files:
src/renderer/src/router/index.tssrc/renderer/src/components/settings/McpSettings.vuesrc/main/presenter/mcpPresenter/mcprouterManager.tssrc/renderer/src/components/settings/McpBuiltinMarket.vuesrc/shared/presenter.d.tssrc/renderer/src/components/mcp-config/mcpServerForm.vuesrc/main/presenter/mcpPresenter/index.tssrc/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Strict type checking enabled for TypeScript
**/*.{ts,tsx}: 始终使用 try-catch 处理可能的错误
提供有意义的错误信息
记录详细的错误日志
优雅降级处理
日志应包含时间戳、日志级别、错误代码、错误描述、堆栈跟踪(如适用)、相关上下文信息
日志级别应包括 ERROR、WARN、INFO、DEBUG
不要吞掉错误
提供用户友好的错误信息
实现错误重试机制
避免记录敏感信息
使用结构化日志
设置适当的日志级别
Files:
src/renderer/src/router/index.tssrc/main/presenter/mcpPresenter/mcprouterManager.tssrc/shared/presenter.d.tssrc/main/presenter/mcpPresenter/index.tssrc/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts
src/renderer/src/**/*.{ts,tsx,vue}
📄 CodeRabbit Inference Engine (CLAUDE.md)
src/renderer/src/**/*.{ts,tsx,vue}: Use Pinia for frontend state management
Renderer to Main: Use usePresenter.ts composable for direct presenter method calls
Files:
src/renderer/src/router/index.tssrc/renderer/src/components/settings/McpSettings.vuesrc/renderer/src/components/settings/McpBuiltinMarket.vuesrc/renderer/src/components/mcp-config/mcpServerForm.vue
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development-setup.mdc)
**/*.{js,jsx,ts,tsx}: 使用 OxLint 进行代码检查
Log和注释使用英文书写
Files:
src/renderer/src/router/index.tssrc/main/presenter/mcpPresenter/mcprouterManager.tssrc/shared/presenter.d.tssrc/main/presenter/mcpPresenter/index.tssrc/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts
src/{main,renderer}/**/*.ts
📄 CodeRabbit Inference Engine (.cursor/rules/electron-best-practices.mdc)
src/{main,renderer}/**/*.ts: Use context isolation for improved security
Implement proper inter-process communication (IPC) patterns
Optimize application startup time with lazy loading
Implement proper error handling and logging for debugging
Files:
src/renderer/src/router/index.tssrc/main/presenter/mcpPresenter/mcprouterManager.tssrc/main/presenter/mcpPresenter/index.tssrc/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts
src/renderer/**/*.{vue,ts,js,tsx,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/project-structure.mdc)
渲染进程代码放在
src/renderer
Files:
src/renderer/src/router/index.tssrc/renderer/src/components/settings/McpSettings.vuesrc/renderer/src/components/settings/McpBuiltinMarket.vuesrc/renderer/src/components/mcp-config/mcpServerForm.vue
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/vue-best-practices.mdc)
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}: Use the Composition API for better code organization and reusability
Implement proper state management with Pinia
Utilize Vue Router for navigation and route management
Leverage Vue's built-in reactivity system for efficient data handling
Files:
src/renderer/src/router/index.tssrc/renderer/src/components/settings/McpSettings.vuesrc/renderer/src/components/settings/McpBuiltinMarket.vuesrc/renderer/src/components/mcp-config/mcpServerForm.vue
src/renderer/src/router/**/*.{vue,ts,tsx,js,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/vue-router-best-practices.mdc)
src/renderer/src/router/**/*.{vue,ts,tsx,js,jsx}: Use named routes for easier navigation and maintenance
Implement route-level code splitting for better performance
Use route meta fields for attaching additional data to routes
Implement proper navigation guards for authentication and authorization
Use dynamic routing for handling variable route segments
Files:
src/renderer/src/router/index.ts
src/renderer/**/*.{ts,tsx,vue}
📄 CodeRabbit Inference Engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,tsx,vue}: Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError).
Use TypeScript for all code; prefer types over interfaces.
Avoid enums; use const objects instead.
Use arrow functions for methods and computed properties.
Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements.
Files:
src/renderer/src/router/index.tssrc/renderer/src/components/settings/McpSettings.vuesrc/renderer/src/components/settings/McpBuiltinMarket.vuesrc/renderer/src/components/mcp-config/mcpServerForm.vue
src/renderer/**/*.{vue,ts}
📄 CodeRabbit Inference Engine (.cursor/rules/vue-shadcn.mdc)
Implement lazy loading for routes and components.
Files:
src/renderer/src/router/index.tssrc/renderer/src/components/settings/McpSettings.vuesrc/renderer/src/components/settings/McpBuiltinMarket.vuesrc/renderer/src/components/mcp-config/mcpServerForm.vue
src/renderer/**/*.{ts,vue}
📄 CodeRabbit Inference Engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,vue}: Use useFetch and useAsyncData for data fetching.
Implement SEO best practices using Nuxt's useHead and useSeoMeta.
Files:
src/renderer/src/router/index.tssrc/renderer/src/components/settings/McpSettings.vuesrc/renderer/src/components/settings/McpBuiltinMarket.vuesrc/renderer/src/components/mcp-config/mcpServerForm.vue
src/renderer/src/**/*.vue
📄 CodeRabbit Inference Engine (CLAUDE.md)
src/renderer/src/**/*.vue: Use Composition API for all Vue 3 components
Use Tailwind CSS with scoped styles for styling
Organize components by feature in src/renderer/src/
Follow existing component patterns in src/renderer/src/ when creating new UI components
Use Composition API with proper TypeScript typing for new UI components
Implement responsive design with Tailwind CSS for new UI components
Add proper error handling and loading states for new UI componentsUse scoped styles to prevent CSS conflicts between components
Files:
src/renderer/src/components/settings/McpSettings.vuesrc/renderer/src/components/settings/McpBuiltinMarket.vuesrc/renderer/src/components/mcp-config/mcpServerForm.vue
src/main/**/*.ts
📄 CodeRabbit Inference Engine (CLAUDE.md)
Main to Renderer: Use EventBus to broadcast events via mainWindow.webContents.send()
Use Electron's built-in APIs for file system and native dialogs
Files:
src/main/presenter/mcpPresenter/mcprouterManager.tssrc/main/presenter/mcpPresenter/index.tssrc/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts
src/main/presenter/**/*.ts
📄 CodeRabbit Inference Engine (CLAUDE.md)
One presenter per functional domain
Files:
src/main/presenter/mcpPresenter/mcprouterManager.tssrc/main/presenter/mcpPresenter/index.tssrc/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts
src/main/**/*.{ts,js,tsx,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/project-structure.mdc)
主进程代码放在
src/main
Files:
src/main/presenter/mcpPresenter/mcprouterManager.tssrc/main/presenter/mcpPresenter/index.tssrc/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts
src/shared/**/*.ts
📄 CodeRabbit Inference Engine (CLAUDE.md)
Shared types in src/shared/
Files:
src/shared/presenter.d.ts
src/shared/*.d.ts
📄 CodeRabbit Inference Engine (.cursor/rules/electron-best-practices.mdc)
The shared/*.d.ts files are used to define the types of objects exposed by the main process to the renderer process
Files:
src/shared/presenter.d.ts
src/shared/**/*.{ts,tsx,d.ts}
📄 CodeRabbit Inference Engine (.cursor/rules/project-structure.mdc)
共享类型定义放在
shared目录
Files:
src/shared/presenter.d.ts
src/main/presenter/mcpPresenter/index.ts
📄 CodeRabbit Inference Engine (CLAUDE.md)
Register new MCP tool in mcpPresenter/index.ts
Files:
src/main/presenter/mcpPresenter/index.ts
src/main/presenter/llmProviderPresenter/providers/*.ts
📄 CodeRabbit Inference Engine (CLAUDE.md)
src/main/presenter/llmProviderPresenter/providers/*.ts: Create provider file in src/main/presenter/llmProviderPresenter/providers/ when adding a new LLM provider
Implement coreStream method following standardized event interface in LLM provider files
src/main/presenter/llmProviderPresenter/providers/*.ts: Each file insrc/main/presenter/llmProviderPresenter/providers/*.tsshould handle interaction with a specific LLM API, including request/response formatting, tool definition conversion, native/non-native tool call management, and standardizing output streams to a common event format.
Provider implementations must use acoreStreammethod that yields standardized stream events to decouple the main loop from provider-specific details.
ThecoreStreammethod in each Provider must perform a single streaming API request per conversation round and must not contain multi-round tool call loop logic.
Provider files should implement helper methods such asformatMessages,convertToProviderTools,parseFunctionCalls, andprepareFunctionCallPromptas needed for provider-specific logic.
All provider implementations must parse provider-specific data chunks and yield standardized events for text, reasoning, tool calls, usage, errors, stop reasons, and image data.
When a provider does not support native function calling, it must prepare messages using prompt wrapping (e.g.,prepareFunctionCallPrompt) before making the API call.
When a provider supports native function calling, MCP tools must be converted to the provider's format (e.g., usingconvertToProviderTools) and included in the API request.
Provider implementations should aggregate and yield usage events as part of the standardized stream.
Provider implementations should yield image data events in the standardized format when applicable.
Provider implementations should yield reasoning events in the standardized format when applicable.
Provider implementations should yield tool call events (`tool_call_star...
Files:
src/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts
🧠 Learnings (11)
📚 Learning: 2025-07-21T01:46:30.354Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/i18n.mdc:0-0
Timestamp: 2025-07-21T01:46:30.354Z
Learning: Applies to src/renderer/src/i18n/common.json : Shared translation keys must be placed in 'src/renderer/src/i18n/common.json'
Applied to files:
src/renderer/src/i18n/fr-FR/settings.jsonsrc/renderer/src/i18n/en-US/common.jsonsrc/renderer/src/i18n/ja-JP/common.jsonsrc/renderer/src/i18n/zh-HK/routes.jsonsrc/renderer/src/i18n/zh-TW/routes.jsonsrc/renderer/src/i18n/fr-FR/routes.jsonsrc/renderer/src/i18n/zh-TW/common.jsonsrc/renderer/src/i18n/zh-CN/common.jsonsrc/renderer/src/i18n/ko-KR/common.jsonsrc/renderer/src/i18n/ru-RU/settings.jsonsrc/renderer/src/i18n/fr-FR/common.jsonsrc/renderer/src/i18n/zh-HK/settings.jsonsrc/renderer/src/i18n/zh-HK/common.jsonsrc/renderer/src/i18n/ru-RU/common.jsonsrc/renderer/src/i18n/ru-RU/routes.json
📚 Learning: 2025-07-21T01:46:30.354Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/i18n.mdc:0-0
Timestamp: 2025-07-21T01:46:30.354Z
Learning: Applies to src/renderer/src/i18n/*.json : When adding new translations, add shared keys to 'common.json' and language-specific keys to the respective language file; keep all language files' keys consistent
Applied to files:
src/renderer/src/i18n/fr-FR/settings.jsonsrc/renderer/src/i18n/en-US/common.jsonsrc/renderer/src/i18n/ja-JP/common.jsonsrc/renderer/src/i18n/zh-TW/common.jsonsrc/renderer/src/i18n/zh-CN/common.jsonsrc/renderer/src/i18n/zh-HK/common.jsonsrc/renderer/src/i18n/ru-RU/common.json
📚 Learning: 2025-07-21T01:47:28.817Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/vue-best-practices.mdc:0-0
Timestamp: 2025-07-21T01:47:28.817Z
Learning: Applies to src/renderer/src/**/*.{vue,ts,tsx,js,jsx} : Utilize Vue Router for navigation and route management
Applied to files:
src/renderer/src/router/index.tssrc/renderer/src/components/settings/McpSettings.vue
📚 Learning: 2025-07-21T01:45:33.790Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T01:45:33.790Z
Learning: Applies to src/main/presenter/mcpPresenter/inMemoryServers/*.ts : Implement new MCP tool in src/main/presenter/mcpPresenter/inMemoryServers/ when adding a new MCP tool
Applied to files:
src/main/presenter/mcpPresenter/mcprouterManager.tssrc/shared/presenter.d.tssrc/main/presenter/mcpPresenter/index.tssrc/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts
📚 Learning: 2025-07-21T01:45:33.790Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T01:45:33.790Z
Learning: Applies to src/main/presenter/mcpPresenter/index.ts : Register new MCP tool in mcpPresenter/index.ts
Applied to files:
src/main/presenter/mcpPresenter/mcprouterManager.tssrc/shared/presenter.d.tssrc/main/presenter/mcpPresenter/index.ts
📚 Learning: 2025-07-21T01:46:52.880Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-07-21T01:46:52.880Z
Learning: Applies to src/main/presenter/llmProviderPresenter/index.ts : `src/main/presenter/llmProviderPresenter/index.ts` should manage the overall Agent loop, conversation history, tool execution via `McpPresenter`, and frontend communication via `eventBus`.
Applied to files:
src/main/presenter/mcpPresenter/mcprouterManager.tssrc/shared/presenter.d.tssrc/main/presenter/mcpPresenter/index.tssrc/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts
📚 Learning: 2025-07-21T01:45:33.790Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T01:45:33.790Z
Learning: Applies to src/main/presenter/configPresenter/**/*.ts : Centralize configuration in configPresenter/
Applied to files:
src/main/presenter/mcpPresenter/index.ts
📚 Learning: 2025-07-21T01:46:52.880Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-07-21T01:46:52.880Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : When a provider supports native function calling, MCP tools must be converted to the provider's format (e.g., using `convertToProviderTools`) and included in the API request.
Applied to files:
src/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts
📚 Learning: 2025-07-21T01:45:33.790Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T01:45:33.790Z
Learning: Applies to src/main/presenter/configPresenter/providers.ts : Add provider configuration in configPresenter/providers.ts when adding a new LLM provider
Applied to files:
src/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts
📚 Learning: 2025-07-21T01:46:52.880Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-07-21T01:46:52.880Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : Provider files should implement helper methods such as `formatMessages`, `convertToProviderTools`, `parseFunctionCalls`, and `prepareFunctionCallPrompt` as needed for provider-specific logic.
Applied to files:
src/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts
📚 Learning: 2025-07-21T01:46:52.880Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/llm-agent-loop.mdc:0-0
Timestamp: 2025-07-21T01:46:52.880Z
Learning: Applies to src/main/presenter/llmProviderPresenter/providers/*.ts : Each file in `src/main/presenter/llmProviderPresenter/providers/*.ts` should handle interaction with a specific LLM API, including request/response formatting, tool definition conversion, native/non-native tool call management, and standardizing output streams to a common event format.
Applied to files:
src/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts
🧬 Code Graph Analysis (2)
src/main/presenter/mcpPresenter/mcprouterManager.ts (1)
src/shared/presenter.d.ts (2)
IConfigPresenter(343-465)MCPServerConfig(979-993)
src/main/presenter/mcpPresenter/index.ts (3)
src/main/presenter/mcpPresenter/mcprouterManager.ts (1)
McpRouterManager(43-124)src/shared/presenter.d.ts (2)
IConfigPresenter(343-465)MCPServerConfig(979-993)src/main/presenter/index.ts (1)
presenter(184-184)
🔇 Additional comments (36)
src/renderer/src/i18n/ko-KR/routes.json (1)
13-15: LGTM: new route key added and JSON remains valid"settings-mcp-market" is correctly added and matches the router meta usage. No issues.
src/renderer/src/i18n/zh-CN/common.json (1)
75-77: i18n: Verified “saved” key across all locales
Allcommon.jsonfiles for en-US, fa-IR, fr-FR, ja-JP, ko-KR, ru-RU, zh-CN, zh-HK, and zh-TW include the new"saved"key, meeting our shared-key placement guidelines. LGTM.src/renderer/src/i18n/zh-HK/routes.json (1)
13-14: LGTM: ‘settings-mcp-market’ present in all route localesVerified that every
routes.jsonundersrc/renderer/src/i18nincludes the newsettings-mcp-marketkey. JSON syntax is intact and placement is appropriate for routertitleKeyresolution. No further changes required.src/renderer/src/i18n/zh-TW/routes.json (1)
13-14: LGTM: TW route label added consistently for MCP Market
settings-mcp-marketis correctly added and localized. Placement in routes.json is correct.src/renderer/src/i18n/fa-IR/common.json (1)
75-76: LGTM: Consistent addition of “saved” key across all locales
Verified that everycommon.jsonundersrc/renderer/src/i18ndefines the shared"saved"key, fully aligning with our i18n conventions.src/renderer/src/i18n/fa-IR/routes.json (1)
13-15: LGTM for new route labelThe addition of “بازار MCP” aligns with the new route and matches the pattern across locales.
src/renderer/src/i18n/zh-TW/settings.json (1)
632-633: LGTM for zh-TW additions
- “啟用E2B功能必須要輸入 ApiKey” and “點擊編輯以查看完整內容” read correctly and match the intended UX.
- The casing “ApiKey” matches nearby strings in this locale file.
No changes needed.
src/renderer/src/i18n/en-US/settings.json (2)
627-627: LGTM: added clickToEdit key aligns with masked headers UXThe key placement under mcp.serverForm is appropriate and the English copy is clear.
575-642: Locale key presence and JSON validity confirmed
All i18nsettings.jsonfiles are valid JSON and include themcp.serverForm.clickToEditentry. No further action is needed.src/renderer/src/i18n/ja-JP/settings.json (1)
619-620: LGTM: natural JP translation for clickToEdit「クリックして編集し、完全な内容を表示」はわかりやすく、文脈に合っています。
src/renderer/src/i18n/ko-KR/settings.json (1)
632-634: LGTM: KR translation added and JSON punctuation adjusted correctlyThe added clickToEdit string is clear and formal; preceding comma fix maintains valid JSON.
src/renderer/src/i18n/zh-CN/settings.json (1)
626-627: LGTM: CN translation added under correct scope“点击编辑以查看完整内容” reads well and matches the intended UX hint.
src/renderer/src/i18n/zh-HK/settings.json (1)
632-634: LGTM: Natural HK Traditional phrasing for clickToEdit.“點擊編輯以查看完整內容” reads well and aligns with other locales.
src/renderer/src/i18n/zh-CN/routes.json (1)
13-14: LGTM — new route key is correct and consistent.The added
routes.settings-mcp-marketentry looks good and matches the router’stitleKey. No hardcoded UI strings in code paths depend on this.src/renderer/src/i18n/zh-CN/mcp.json (1)
249-268: All.marketkeys are consistent across localesI’ve compared
src/renderer/src/i18n/en-US/mcp.jsonagainst every othermcp.jsonand found no missing or extra keys in any locale. All.marketsections are fully synchronized.src/renderer/src/i18n/zh-HK/mcp.json (1)
250-268: LGTM! Comprehensive MCP market translations added.The new market translations are well-structured and cover all necessary UI elements for the MCP marketplace integration. The translations maintain consistency with other language variants and follow the established i18n pattern.
src/shared/presenter.d.ts (1)
1144-1167: Well-structured MCP Router marketplace API methods.The new optional methods for MCP Router integration are properly typed and follow the existing interface patterns. The pagination support in
listMcpRouterServersand the comprehensive server metadata structure are well-designed.src/renderer/src/components/mcp-config/mcpServerForm.vue (5)
59-61: Good implementation of sensitive data masking for custom headers.The addition of state management for masking sensitive header values enhances security by preventing accidental exposure of API keys and tokens in the UI.
1145-1182: Excellent UX implementation for sensitive header editing.The masked overlay approach with focus/blur handlers provides a secure and intuitive way to edit sensitive headers. The visual feedback with the "click to edit" hint and proper border styling maintains consistency with the rest of the form.
696-717: Robust header parsing implementation.The
parseKeyValueHeadersfunction correctly handles edge cases like empty lines and ensures proper key-value separation. The use ofindexOfinstead ofsplitprevents issues with values containing multiple=characters.
615-637: Smart auto-detection of imageServer model configuration.The watcher effectively parses and applies the model configuration from args for imageServer type, with appropriate error handling via console.warn when no matching model is found.
639-683: Comprehensive edit mode initialization.The watcher properly handles initial configuration loading in edit mode, including special handling for powerpack E2B settings and custom headers formatting. The guard against overwriting when
defaultJsonConfigis provided prevents conflicts.src/renderer/src/router/index.ts (1)
74-82: Well-integrated MCP Market route.The new route follows the established pattern for settings sub-routes, with proper component lazy-loading, i18n integration, and consistent icon usage. The placement within the settings hierarchy is logical.
src/renderer/src/i18n/en-US/routes.json (1)
13-14: Route translation properly added.The new "MCP Market" translation entry is correctly placed and follows the naming convention.
src/renderer/src/i18n/ja-JP/routes.json (1)
13-14: LGTM! Proper JSON formatting and consistent localization.The addition of the MCP Market route translation is well-formatted with the correct trailing comma and consistent with other Japanese translations in the file.
src/renderer/src/components/settings/McpSettings.vue (3)
219-223: LGTM! Proper Vue Router integration following coding guidelines.The import and usage of
useRouterfollows Vue.js best practices and the coding guidelines for utilizing Vue Router for navigation management.
172-180: LGTM! Well-structured button with proper i18n integration.The new "Browse Builtin" button follows the existing UI pattern with proper icon usage, localized text, and consistent styling. The implementation correctly uses the translation key
mcp.market.browseBuiltin.
454-457: LGTM! Clean navigation implementation with proper routing.The
openBuiltinMarketfunction correctly uses Vue Router'spushmethod for programmatic navigation to the MCP market route, following the coding guidelines for route management.src/renderer/src/i18n/fr-FR/mcp.json (1)
250-268: LGTM! Comprehensive French translations for MCP Market feature.The market object contains well-structured French translations covering all aspects of the MCP Market UI:
- API key management and validation messages
- Installation states and feedback
- Navigation and loading states
- Proper French terminology and grammar
The translations are consistent with the existing French localization patterns in the file.
src/renderer/src/i18n/ja-JP/mcp.json (1)
250-268: LGTM! Complete Japanese translations for MCP Market functionality.The market translations are comprehensive and properly formatted:
- Clear Japanese terminology for technical concepts like "API key" and "installation"
- Appropriate honorific language ("APIキーを申請し")
- Consistent formatting with existing Japanese translations
- Covers all UI states from browsing to installation feedback
src/renderer/src/i18n/en-US/mcp.json (1)
250-268: LGTM! Complete English translations for MCP Market integration.The market object provides comprehensive English translations covering all MCP Market functionality:
- Clear and professional language for API key management
- Appropriate user feedback messages for installation states
- Consistent terminology with "MCPRouter" branding
- Well-structured loading and pagination messages
The translations follow the existing English localization patterns and maintain consistency with technical terminology used throughout the application.
src/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts (1)
307-308: Improved displayName fallback chainThe updated fallback logic now considers
mcpServer.namebefore falling back toid, providing a more meaningful display name.src/renderer/src/components/settings/McpBuiltinMarket.vue (1)
15-21: Verified: No API key logging or exposure detected
All searches forconsole.log|error|warn|debugand error-handler patterns referencingapiKeyacross.tsand.vuefiles returned no hits. The<Input type="password">correctly masks the value, and there’s no evidence the key is ever logged or surfaced in error messages. No further action required.src/main/presenter/mcpPresenter/index.ts (3)
96-101: Good defensive error handling for McpRouterManager initializationThe try-catch block gracefully handles initialization failures and logs a warning instead of crashing the application. This ensures the MCP presenter can still function even if McpRouter integration fails.
193-215: LGTM! Well-structured McpRouter API methodsThe listMcpRouterServers method properly validates the manager availability, delegates to the manager, and provides a safe default return value.
230-238: Efficient server installation check implementationGood implementation using source and sourceId fields to check if a server is already installed. This aligns well with the new source-based server management architecture.
| // 更新现有 mcprouter 服务器的 Authorization header | ||
| if (newKey) { | ||
| await mcpP.updateMcpRouterServersAuth?.(newKey) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Security concern: API key update in Authorization headers
Updating Authorization headers for existing servers when the API key changes is good, but ensure that the old API key is properly invalidated and that this doesn't create a security vulnerability if multiple API keys exist.
🏁 Script executed:
#!/bin/bash
# Check how API keys are stored and managed
echo "Checking API key storage patterns..."
rg "mcprouterApiKey" --type ts -A 3 -B 3 | head -30
# Check for any API key validation or rotation logic
echo -e "\nChecking for API key validation..."
rg "validateApiKey|rotateApiKey|invalidateApiKey" --type tsLength of output: 2375
#!/bin/bash
echo "Locating updateMcpRouterServersAuth usage and definition..."
rg "updateMcpRouterServersAuth" -n -A5 -B5 --type tsEnsure old API key is invalidated when rotating keys
I didn’t find any invalidateApiKey or rotation logic in the mcpPresenter after updating the key. Without revoking the previous key, any servers still holding it could continue to authenticate. Please add explicit invalidation of the old key when you call updateMcpRouterServersAuth(newKey):
• In src/renderer/src/components/settings/McpBuiltinMarket.vue (lines 154–157), you already invoke
await mcpP.updateMcpRouterServersAuth?.(newKey)
– ensure this method also handles revoking the previous key.
• In src/main/presenter/mcpPresenter/index.ts under setMcpRouterApiKey, call your key-rotation or invalidation endpoint.
• In src/main/presenter/mcpPresenter/mcprouterManager.ts, extend updateMcpRouterServersAuth (or add a new helper) to send a revoke/invalidate request for the old API key before applying the new one.
This will close the gap where stale keys remain valid.
🤖 Prompt for AI Agents
In src/renderer/src/components/settings/McpBuiltinMarket.vue around lines
154–157, you call await mcpP.updateMcpRouterServersAuth?.(newKey) but there is
no invalidation of the previous API key; update the flow so the old key is
revoked when rotating keys: ensure mcpP.updateMcpRouterServersAuth triggers a
revoke of the old key before applying the new one, modify
src/main/presenter/mcpPresenter/index.ts in setMcpRouterApiKey to call the
key-rotation/invalidate endpoint (pass oldKey and newKey or token id), and
extend src/main/presenter/mcpPresenter/mcprouterManager.ts
updateMcpRouterServersAuth (or add a helper) to first send an HTTP request to
the mcprouter revoke/invalidate API for the old key, verify successful
revocation, then propagate the new key to servers; handle errors and rollback if
revoke fails.
* fix: add AlertDialogDescription to resolve accessibility warning (#706) * fix: resolve focus flicker when creating new windows with Ctrl+Shift+N (#707) * feat: enhance window management by implementing main window ID handling (#709) * docs: update zhipu developer doc website link (#715) Co-authored-by: gongchao <chao.gong@aminer.cn> * refactor: better translate (#716) * chore: en-us i18n * chore(i18n): polish ja-JP translations across UI; keep chat.input.placeholder unchanged * chore(i18n): polish fr-FR translations; keep chat.input.placeholder unchanged * chore(i18n): refine fr-FR MCP & Settings copy; idiomatic, concise, brand-consistent * chore(i18n): polish ru-RU translations across UI; keep chat.input.placeholder unchanged * chore(i18n): polish fa-IR translations across UI; keep chat.input.placeholder unchanged * chore: fix format * chore: fix i18n * chore: lock rolldown-vite version * feat: add GPT-5 series model support (#717) * ci(vite): Bundle the main file into a single file to speed up loading. (#718) * fix(math): parser by upgrade vue-renderer-markdown (#722) * chore: bump deps (#721) * chore: bump deps * fix: rolldown-vite 7.1.0 and duckdb bundle issue * chore: back to vite * chore: update electron * chore: update versions * fix(math): parser by upgrade vue-renderer-markdown (#722) * chore: bump deps --------- Co-authored-by: Simon He <57086651+Simon-He95@users.noreply.github.com> * fix: add scrollable support to PopoverContent to prevent overflow (#720) * feat: implement floating chat window system with performance optimization (#724) * feat: add mcp sync and modelscope provider #615 (#723) * wip: add modelscope provider * feat: add mcp sync to modelscope * fix: add scrollable support to PopoverContent to prevent overflow (#720) * feat: implement floating chat window system with performance optimization (#724) * chore: i18n and format * feat: better style * fix: mcp tool display --------- Co-authored-by: yyhhyyyyyy <yyhhyyyyyy8@gmail.com> * fix: move_files newPath parse issue (#725) * fix: move_files newPath 参数计算规则 * fix: move_files 移动前需要判断dest是目录还是文件 * feat: add Claude Opus 4.1 to anthropic default model list (#726) * feat: Add mcprouter's MCP marketplace api support (#727) * wip: add mcp market * feat: mcp market install * wip: mcp install status sync * feat: mcp server config mask * chore: remove working doc * chore: add translate * feat: add ESC key to close floating chat window (#728) * feat: add floating button position persistence with boundary validation (#729) * feat: add floating button position persistence with boundary validation * feat: refactor floating button to use electron-window-state * chore: bump to 0.3.0 * feat: add reasoning_effort parameter support for gpt-oss models (#731) * feat: add reasoning_effort parameter support for gpt-oss models - add reasoning effort UI support across all components * fix: preserve user reasoning effort settings and improve display logic * fix: artifacts code not streaming (#732) * fix: artifact react load failed * chore: remove log * fix: artifacts code not stream * fix: format --------- Co-authored-by: yyhhyyyyyy <yyhhyyyyyy8@gmail.com> Co-authored-by: hllshiro <40970081+hllshiro@users.noreply.github.com> Co-authored-by: tomsun28 <tomsun28@outlook.com> Co-authored-by: gongchao <chao.gong@aminer.cn> Co-authored-by: Simon He <57086651+Simon-He95@users.noreply.github.com> Co-authored-by: wanna <wanna.w@binarywalk.com>
* fix: add AlertDialogDescription to resolve accessibility warning (#706) * fix: resolve focus flicker when creating new windows with Ctrl+Shift+N (#707) * feat: enhance window management by implementing main window ID handling (#709) * docs: update zhipu developer doc website link (#715) Co-authored-by: gongchao <chao.gong@aminer.cn> * refactor: better translate (#716) * chore: en-us i18n * chore(i18n): polish ja-JP translations across UI; keep chat.input.placeholder unchanged * chore(i18n): polish fr-FR translations; keep chat.input.placeholder unchanged * chore(i18n): refine fr-FR MCP & Settings copy; idiomatic, concise, brand-consistent * chore(i18n): polish ru-RU translations across UI; keep chat.input.placeholder unchanged * chore(i18n): polish fa-IR translations across UI; keep chat.input.placeholder unchanged * chore: fix format * chore: fix i18n * chore: lock rolldown-vite version * feat: add GPT-5 series model support (#717) * ci(vite): Bundle the main file into a single file to speed up loading. (#718) * fix(math): parser by upgrade vue-renderer-markdown (#722) * chore: bump deps (#721) * chore: bump deps * fix: rolldown-vite 7.1.0 and duckdb bundle issue * chore: back to vite * chore: update electron * chore: update versions * fix(math): parser by upgrade vue-renderer-markdown (#722) * chore: bump deps --------- Co-authored-by: Simon He <57086651+Simon-He95@users.noreply.github.com> * fix: add scrollable support to PopoverContent to prevent overflow (#720) * feat: implement floating chat window system with performance optimization (#724) * feat: add mcp sync and modelscope provider #615 (#723) * wip: add modelscope provider * feat: add mcp sync to modelscope * fix: add scrollable support to PopoverContent to prevent overflow (#720) * feat: implement floating chat window system with performance optimization (#724) * chore: i18n and format * feat: better style * fix: mcp tool display --------- Co-authored-by: yyhhyyyyyy <yyhhyyyyyy8@gmail.com> * fix: move_files newPath parse issue (#725) * fix: move_files newPath 参数计算规则 * fix: move_files 移动前需要判断dest是目录还是文件 * feat: add Claude Opus 4.1 to anthropic default model list (#726) * feat: Add mcprouter's MCP marketplace api support (#727) * wip: add mcp market * feat: mcp market install * wip: mcp install status sync * feat: mcp server config mask * chore: remove working doc * chore: add translate * feat: add ESC key to close floating chat window (#728) * feat: add floating button position persistence with boundary validation (#729) * feat: add floating button position persistence with boundary validation * feat: refactor floating button to use electron-window-state * chore: bump to 0.3.0 * feat: add reasoning_effort parameter support for gpt-oss models (#731) * feat: add reasoning_effort parameter support for gpt-oss models - add reasoning effort UI support across all components * fix: preserve user reasoning effort settings and improve display logic * fix: artifacts code not streaming (#732) * fix: artifact react load failed * chore: remove log * fix: artifacts code not stream * fix: format * feat: disable automatic model enabling for better UX (#734) * feat: sync provider sorting from settings to model selection (#736) * feat: sync provider sorting from settings to model selection * feat: refactor ModelSelect to use computed providers for better reactivity --------- Co-authored-by: yyhhyyyyyy <yyhhyyyyyy8@gmail.com> Co-authored-by: hllshiro <40970081+hllshiro@users.noreply.github.com> Co-authored-by: tomsun28 <tomsun28@outlook.com> Co-authored-by: gongchao <chao.gong@aminer.cn> Co-authored-by: Simon He <57086651+Simon-He95@users.noreply.github.com> Co-authored-by: wanna <wanna.w@binarywalk.com>
feat #681
接入了https://mcprouter.co/ 提供的 MCP 市场



可以直接在应用中一键安装 MCP
Summary by CodeRabbit
New Features
Bug Fixes / Behavior
Chores