diff --git a/client/mcp_service.go b/client/mcp_service.go index abc18600..f5680c04 100644 --- a/client/mcp_service.go +++ b/client/mcp_service.go @@ -78,10 +78,11 @@ type MCPResource struct { // MCPTestResult represents the result of testing an MCP service connection type MCPTestResult struct { - Success bool `json:"success"` - Message string `json:"message,omitempty"` - Tools []*MCPTool `json:"tools,omitempty"` - Resources []*MCPResource `json:"resources,omitempty"` + Success bool `json:"success"` + Message string `json:"message,omitempty"` + Description string `json:"description,omitempty"` + Tools []*MCPTool `json:"tools,omitempty"` + Resources []*MCPResource `json:"resources,omitempty"` } // CreateMCPService creates a new MCP service diff --git a/docs/api/mcp-service.md b/docs/api/mcp-service.md index 46b539bf..6102ab88 100644 --- a/docs/api/mcp-service.md +++ b/docs/api/mcp-service.md @@ -306,6 +306,7 @@ curl --location --request POST 'http://localhost:8080/api/v1/mcp-services/mcp-00 "data": { "success": true, "message": "连接成功", + "description": "提供全球天气信息查询", "tools": [ { "name": "get_weather", diff --git a/frontend/src/api/mcp-service.ts b/frontend/src/api/mcp-service.ts index 4404690f..033d25f9 100644 --- a/frontend/src/api/mcp-service.ts +++ b/frontend/src/api/mcp-service.ts @@ -19,6 +19,10 @@ export interface MCPService { // optional-property typing remains so create-mode payloads can still // carry them in the initial POST body. api_key?: string + // Header name carrying api_key when auth_type is "api_key". Non-secret; + // empty defaults to "X-API-Key". Lets services expecting the key in a + // different header (e.g. raw token in "Authorization") work. + api_key_header?: string token?: string custom_headers?: Record // OAuth-only, non-secret configuration. @@ -69,6 +73,10 @@ export interface MCPResource { export interface MCPTestResult { success: boolean message?: string + description?: string + // Set when the server requires OAuth (RFC 9728) but the service was not + // configured for it — the UI guides the user to switch to OAuth 2.0. + oauth_required?: boolean tools?: MCPTool[] resources?: MCPResource[] } @@ -212,4 +220,3 @@ export async function resolveToolApproval( ): Promise { await post(`/api/v1/agent/tool-approvals/${encodeURIComponent(pendingId)}`, body) } - diff --git a/frontend/src/i18n/locales/en-US.ts b/frontend/src/i18n/locales/en-US.ts index 726e2ec0..b53517cf 100755 --- a/frontend/src/i18n/locales/en-US.ts +++ b/frontend/src/i18n/locales/en-US.ts @@ -4465,6 +4465,14 @@ export default { addEnvVar: 'Add Environment Variable', enableService: 'Enable Service', authConfig: 'Authentication', + authType: 'Auth Method', + authTypeNone: 'None / Custom Header', + authTypeApiKey: 'API Key / Token', + authTypeOAuth: 'OAuth 2.0 (authorize on first connect)', + oauthAuthorizeHint: 'Clicking "Authorize" saves the current config first, then starts authorization (each user authorizes individually).', + apiKeyHeader: 'Header Name', + apiKeyHeaderDesc: 'Defaults to X-API-Key. For Bearer, set Authorization and put "Bearer " in the value below; for raw-token services use Authorization with the raw token.', + credentialValue: 'Secret / Token', apiKey: 'API Key', bearerToken: 'Bearer Token', optional: 'Optional', @@ -4484,7 +4492,8 @@ export default { created: 'MCP service created', updated: 'MCP service updated', createFailed: 'Failed to create MCP service', - updateFailed: 'Failed to update MCP service' + updateFailed: 'Failed to update MCP service', + oauthRequired: 'This server requires OAuth. Switched to OAuth 2.0 — save, then click "Authorize".' }, customHeaders: { label: 'Custom Headers (optional)', diff --git a/frontend/src/i18n/locales/ko-KR.ts b/frontend/src/i18n/locales/ko-KR.ts index ca21ce75..b2d2fc4d 100755 --- a/frontend/src/i18n/locales/ko-KR.ts +++ b/frontend/src/i18n/locales/ko-KR.ts @@ -4461,6 +4461,14 @@ export default { addEnvVar: "환경 변수 추가", enableService: "서비스 활성화", authConfig: "인증 설정", + authType: "인증 방식", + authTypeNone: "없음 / 사용자 정의 헤더", + authTypeApiKey: "API Key / Token", + authTypeOAuth: "OAuth 2.0(최초 연결 시 인증)", + oauthAuthorizeHint: "「인증하기」를 클릭하면 현재 설정을 먼저 자동 저장한 후 인증을 시작합니다(사용자별 개별 인증).", + apiKeyHeader: "요청 헤더 이름", + apiKeyHeaderDesc: "비워 두면 기본값은 X-API-Key입니다. Bearer 방식은 Authorization을 입력하고 아래 비밀 값에 \"Bearer \"을 작성하세요. 원시 토큰이 필요하면 Authorization에 토큰을 그대로 입력합니다.", + credentialValue: "비밀 값 / 토큰", apiKey: "API Key", bearerToken: "Bearer Token", optional: "선택", @@ -4481,6 +4489,7 @@ export default { updated: "MCP 서비스가 업데이트되었습니다", createFailed: "MCP 서비스 생성 실패", updateFailed: "MCP 서비스 업데이트 실패", + oauthRequired: "이 서비스는 OAuth 인증이 필요하여 OAuth 2.0으로 자동 전환했습니다. 저장 후 「인증하기」를 클릭하세요.", }, customHeaders: { label: "사용자 지정 헤더(선택 사항)", diff --git a/frontend/src/i18n/locales/ru-RU.ts b/frontend/src/i18n/locales/ru-RU.ts index 221e13df..fbf71a23 100755 --- a/frontend/src/i18n/locales/ru-RU.ts +++ b/frontend/src/i18n/locales/ru-RU.ts @@ -4113,6 +4113,14 @@ export default { addEnvVar: 'Добавить переменную', enableService: 'Включить сервис', authConfig: 'Аутентификация', + authType: 'Способ аутентификации', + authTypeNone: 'Нет / Свой заголовок', + authTypeApiKey: 'API Key / Token', + authTypeOAuth: 'OAuth 2.0 (авторизация при первом подключении)', + oauthAuthorizeHint: 'Нажатие «Авторизоваться» сначала сохранит текущую конфигурацию, затем запустит авторизацию (каждый пользователь авторизуется отдельно).', + apiKeyHeader: 'Имя заголовка', + apiKeyHeaderDesc: 'По умолчанию X-API-Key. Для Bearer укажите Authorization и впишите "Bearer " в значение ниже; для «сырого» токена используйте Authorization и сам токен.', + credentialValue: 'Секрет / Токен', apiKey: 'API Key', bearerToken: 'Bearer Token', optional: 'Необязательно', @@ -4132,7 +4140,8 @@ export default { created: 'Сервис MCP создан', updated: 'Сервис MCP обновлён', createFailed: 'Не удалось создать сервис MCP', - updateFailed: 'Не удалось обновить сервис MCP' + updateFailed: 'Не удалось обновить сервис MCP', + oauthRequired: 'Сервис требует OAuth. Переключено на OAuth 2.0 — сохраните и нажмите «Авторизоваться».' }, customHeaders: { label: 'Пользовательские заголовки (необязательно)', diff --git a/frontend/src/i18n/locales/zh-CN.ts b/frontend/src/i18n/locales/zh-CN.ts index 70eb059b..2cba47a1 100755 --- a/frontend/src/i18n/locales/zh-CN.ts +++ b/frontend/src/i18n/locales/zh-CN.ts @@ -4468,9 +4468,11 @@ export default { authConfig: "认证配置", authType: "认证方式", authTypeNone: "无 / 自定义 Header", - authTypeApiKey: "API Key", - authTypeBearer: "Bearer Token", + authTypeApiKey: "API Key / Token", authTypeOAuth: "OAuth 2.0(首次连接授权)", + apiKeyHeader: "请求头名称", + apiKeyHeaderDesc: "留空默认 X-API-Key。Bearer 方式请填 Authorization,并在下方密钥值中写 “Bearer ”;需要裸 token 时填 Authorization 并直接填入 token。", + credentialValue: "密钥值 / Token", oauthScopes: "Scopes(可选,空格分隔)", oauthAuthorization: "授权状态", oauthAuthorized: "已授权", @@ -4479,6 +4481,7 @@ export default { oauthReauthorize: "重新授权", oauthRevoke: "撤销授权", oauthSaveFirstHint: "保存服务后,可在编辑页发起首次授权(每个用户独立授权)。", + oauthAuthorizeHint: "点击「去授权」会先自动保存当前配置,再发起授权(每个用户独立授权)。", apiKey: "API Key", bearerToken: "Bearer Token", optional: "可选", @@ -4499,6 +4502,7 @@ export default { updated: "MCP 服务已更新", createFailed: "创建 MCP 服务失败", updateFailed: "更新 MCP 服务失败", + oauthRequired: "该服务需要 OAuth 授权,已自动切换为 OAuth 2.0,请保存后点击「去授权」。", authorized: "授权成功", authorizeFailed: "发起授权失败", revoked: "已撤销授权", diff --git a/frontend/src/views/settings/components/McpServiceDialog.vue b/frontend/src/views/settings/components/McpServiceDialog.vue index e280da21..b0d98c82 100644 --- a/frontend/src/views/settings/components/McpServiceDialog.vue +++ b/frontend/src/views/settings/components/McpServiceDialog.vue @@ -196,7 +196,19 @@
- + +
+ +
@@ -205,7 +217,7 @@ -
+
@@ -217,13 +229,13 @@ {{ oauthAuthorized ? t('mcpServiceDialog.oauthReauthorize', '重新授权') : t('mcpServiceDialog.oauthAuthorize', '去授权') }}
+

+ {{ t('mcpServiceDialog.oauthAuthorizeHint', '点击「去授权」会先自动保存当前配置,再发起授权(每个用户独立授权)。') }} +

-

- {{ t('mcpServiceDialog.oauthSaveFirstHint', '保存服务后,可在编辑页发起首次授权(每个用户独立授权)。') }} -

-