feat: 添加 MCP Server 全生命周期管理、沙箱托管与第三方导入#233
Draft
githuuuuub wants to merge 42 commits intohigress-group:mainfrom
Draft
feat: 添加 MCP Server 全生命周期管理、沙箱托管与第三方导入#233githuuuuub wants to merge 42 commits intohigress-group:mainfrom
githuuuuub wants to merge 42 commits intohigress-group:mainfrom
Conversation
## 沙箱管理 - SandboxInstance 实体/Service/Controller,支持导入/更新/删除/健康检查 - K8sClientUtils:Fabric8 客户端封装 + Caffeine 缓存 - Admin 前端沙箱管理页面 ## MCP Server 管理 - McpServerMeta(冷数据)+ McpServerEndpoint(热数据)双表模型 - McpServerService:saveMeta/registerMcp/deploySandbox/refreshTools - AgentRuntimeDeployStrategy + SelfHostedDeployStrategy:CRD 部署 - OpenApiMcpController:外部系统注册 MCP - 部署后自动获取工具列表(带重试) ## 协议标准化 - McpProtocolUtils.normalize():统一 stdio/sse/streamableHttp - transportType 只影响热数据,metaProtocolType 控制 CRD PROTOCOL - CRD PROTOCOL:http 映射为 streamableHttp ## Admin 前端 - McpCustomConfigModal:自定义 MCP 配置向导 - ApiProductLinkApi:冷热数据分 Tab,热数据优先 - 支持 query 参数解析 + URL 去重合并 - 产品名自动填充到 MCP 中文名称 ## Portal 前端 - McpDetail:连接配置优先热数据,协议重叠时只显示热数据 - McpSquare / McpCreatePage - 显示名称优先级:product.name > meta.displayName > meta.mcpName - resolvedConfig 增加 type 字段 ## 其他 - ChatService:buildMCPConfigs null 安全 + 优先 endpoint 热数据 - Flyway V14/V15,FlywayConfig outOfOrder + auto-repair - Fabric8 6.1.1 -> 6.13.4 - Helm 模板 hub 空值兼容
…igress-group#181) The "开始对话测试" button was clickable even without an active subscription, allowing users to enter the chat page without proper access. Now the button shows "订阅并开始对话" when unsubscribed and opens the subscription management modal on click, guiding users to subscribe first. 🤖 Generated with [Qoder][https://qoder.com]
…i-arch build support (higress-group#183) * fix(deploy): 修正Nacos启动配置及API响应处理 - 删除Nacos镜像的多余入口脚本配置,使用默认启动方式 - 修改Helm部署Nacos模板,去除多余的启动命令部分 - 优化post_ready脚本中查询消费者ID和产品ID的JSON解析逻辑,改为使用jq稳定提取 - 新增判断产品是否未关联网关的逻辑,避免订阅时因错误导致失败 - 修正artifactDetector中未识别扩展名时返回null的行为 - 在模型详情页面中动态替换cURL示例中的模型名称,避免使用占位符 - 增加模型名称缺失时的提示信息显示 - 更新产品接口中的IProductDetail,补充model字段类型声明 - 扩展artifact类型支持,添加Excel格式文件扩展名判断 * fix(scripts): 更新镜像版本并支持多架构构建 - 修改 push.sh 和 push-podman.sh 中的镜像版本为 latest - 在 push.sh 中启用多架构平台 linux/amd64 和 linux/arm64 - 在 push-podman.sh 中增加清理残留镜像操作,避免冲突 - 保持多架构镜像构建流程的稳定性与兼容性
- 沙箱托管部署后的工具列表获取改为异步执行,不再阻塞部署接口响应 - 管理后台 MCP 来源展示增加 ADMIN(管理员配置) 和 AGENTRUNTIME(AgentRuntime导入) 映射
# Conflicts: # himarket-bootstrap/src/main/java/com/alibaba/himarket/config/SecurityConfig.java # himarket-web/himarket-frontend/src/pages/ModelDetail.tsx # himarket-web/himarket-frontend/src/router.tsx
# Conflicts: # himarket-bootstrap/src/main/resources/application.yml # himarket-web/himarket-frontend/src/router.tsx # pom.xml
feat: add public MCP meta API and cascade delete MCP resources on product removal - Add McpMetaPublicResult DTO with sanitized fields for anonymous access - Add @publicaccess endpoints for batch/single MCP meta queries in McpServerController and ProductController - Add forceDeleteMetaByProduct to cascade delete meta, endpoints and sandbox resources - Fix ProductServiceImpl to properly cascade MCP cleanup on product delete/unlink - Add filter_mcp_server_options preset query in SlsPresetSqlRegistry Frontend: feat: support anonymous browsing for MCP square and detail pages - Add getProductMcpMetaPublic/getProductMcpMetaBatchPublic API calls for unauthenticated users - Toggle between public/authenticated APIs based on login state in McpSquare and McpDetail - Hide "My MCP" tab, "Create MCP" button, and subscribe actions when not logged in - Show login prompt instead of connection config for anonymous users in McpDetail - Replace plain text empty state with EmptyState component
- Add McpProtocolType enum with fromString/normalize/resolveTransportMode - Fix streamableHttp transport falling through to SSE in HiChat - Replace all string-based protocol comparisons with enum across backend - Add frontend MCP protocol constants for admin and developer portals - Hide cold data tabs for remote-imported MCPs when hot data exists - Show origin-based labels on hot data tabs in admin portal - Fix JSON highlighting breaking URLs with ports in developer portal - Show hot/cold config regardless of subscription status - Add sandbox deploy/undeploy event handling
Extract normalizeEndpointUrl() into McpProtocolUtils to centralize the trailing-slash stripping and /sse suffix logic. Replace three separate inline implementations in McpSandboxDeployListener, McpServerServiceImpl.syncPublicEndpoint(), and resolveTransportConfigs() with calls to the shared utility. Fixes a bug where McpSandboxDeployListener did not strip trailing slashes before appending /sse, producing URLs like https://host//sse when the sandbox deploy service returned a URL with a trailing slash.
- Add published-only query methods to McpServerService and impl - Switch OpenApiMcpController to use getPublishedMeta/listPublishedMeta variants - Add findProductIdsByTypeAndStatus to ProductRepository - Add findByProductIdIn/findByProductIdInAndOrigin to McpServerMetaRepository - Disable self-hosted Sandbox tab (coming soon)
…Registry, LobeHub)
- Add McpVendorType enum, McpOrigin.VENDOR_IMPORT
- Add vendor DTOs: RemoteMcpItem, BatchImportParam/Result, RemoteMcpItemParam/Result
- Add McpVendorAdapter interface with enrichForImport() default method
- Add ModelScopeAdapter, McpRegistryAdapter, LobeHubAdapter
- Add VendorAdapterRegistry, McpVendorService/Impl, McpVendorController
- Add ImportMcpModal (two-step vendor selection + card grid), RemoteMcpTable
- Add mcpVendorApi with 300s timeout for batch import
- Add edit button to MCP config page (disabled when deployed)
- Fix MCP Registry pagination: cursor-based with version=latest
- Fix icon JSON format to use {"type":"URL","value":"..."}
- Fix Chinese locale priority for ModelScope and LobeHub adapters
…oy mismatch Deploy uses adminUserId to build CRD resourceName, but endpoint stores userId="*". Undeploy recomputes resourceName with "*", resulting in a different name that fails to match the actual CRD. - Store resourceName in endpoint subscribe_params at creation time - Pass resourceName through undeploy chain via 5-param overload - Add resourceName field to McpSandboxUndeployEvent - Fix deploy rollback and old CRD cleanup to pass correct resourceName - Remove dead code: McpRegistryAdapter containsIgnoreCase/isActiveAndLatest
Replace in-memory ConcurrentHashMap token blacklist with MariaDB-backed persistence to survive application restarts and support multi-instance deployments. Changes: - Add Flyway V14 migration for revoked_token table (SHA-256 hash indexed) - Add RevokedToken JPA entity and RevokedTokenRepository - Add RevokedTokenService with Caffeine L1 cache and scheduled cleanup - Refactor TokenUtil to delegate revocation to RevokedTokenService - Add jqwik property-based tests for bug condition and preservation Closes higress-group#202
…#198) - Add FileUploadValidator with extension whitelist, MIME cross-validation, file size limit (20MB), magic bytes verification, and filename sanitization - Integrate validator into ChatAttachmentServiceImpl.uploadAttachment() - Add 9 jqwik property-based tests for bug condition and preservation - Improve frontend error messages to show backend validation errors
Hide subscribeParams (namespace, resourceName and other K8s deployment parameters) from developer-facing API responses. Admin endpoints with @Adminauth are unaffected. Changes: - Add McpMetaResult.sanitize() to null out subscribeParams - McpServerController: sanitize responses in getMeta, listMetaByProduct, listMetaByProductIds, listPublished, register for non-admin users - ProductController: sanitize responses in listMcpMeta for non-admin users
- Generate sk_ prefixed API Key on deploy when authType=apikey - Create K8s Secret with labels (managed-by, user-id, mcp-name, mcp-server-id, ref-toolserver) - Reference Secret in ToolServer CRD accesses and add ref-secret label - Clean up Secret on undeploy (pass secretName through full undeploy chain) - Write secretName back to subscribeParams after successful deploy - Add SANDBOX branch in resolveAuthHeaders for HiChat/HiCoding auth - Enable API Key option in admin deploy modal (replace disabled bearer) - Display Secret name and masked API Key in hosting config area - Fix JPA flush issue for endpoint delete+insert unique constraint
Resolved 6 conflicts: - Resources.java: merged both AGENT_SPEC/SKILL (main) and SANDBOX/MCP constants (ours) - ProductController.java: kept both ContextHolder import and wildcard import - api.ts (admin): merged main's skillApi enhancements + workerApi with our mcpServerApi/sandboxApi/mcpVendorApi - ApiProducts.tsx: merged MCP import button (ours) with Nacos import + sort (main) - iconUtils.tsx (frontend): merged parseMetaIcon (ours) with getFirstChar + enhanced getIconString (main) - McpDetail.tsx: kept our rewrite, discarded main's minor Spin->DetailSkeleton change DB migrations renumbered: main's V14/V15 kept, ours moved to V16/V17, duplicate V16 removed.
- Fix saveMeta creating duplicate records when mcpName is changed - Allow mcpName to be updated via saveMeta (remove from ignoreProperties) - Add mcpName length check (max 32 chars) before sandbox deploy - Add authType selector to McpCustomConfigModal sandbox config - Add endpoint polling after save-and-deploy in McpCustomConfigModal - Add timeout warning when sandbox deploy polling exceeds max attempts - Remove duplicate Modal.success in ImportMcpModal (keep component modal only)
…nto AgentRuntimeIntegrate-reconstruct - higress-group#223: Docker install script improvements (configurable data dir, upgrade mode) - higress-group#224: Skill/Worker version management improvements and Nacos state handling Resolved 1 conflict in ProductServiceImpl.java: kept both MCP service deps (ours) and Worker/Skill service deps (main).
- Remove hardcoded default Open API Key, disable when OPEN_API_KEY env not set - Add @ModelAttribute auth guard to OpenApiMcpController (prevents unauthenticated endpoints) - Add Apache License 2.0 headers to 3 missing files - Extract McpServerServiceImpl (2001 lines) into 4 focused classes: - McpServerServiceImpl (~960 lines) - core CRUD coordination - McpConfigSyncHelper (~600 lines) - config sync, ProductRef, endpoint URL extraction - McpSandboxOrchestrator (~260 lines) - sandbox deploy/undeploy orchestration - McpTransportResolver (~230 lines) - transport config resolution for HiChat/HiCoding
…gh McpConfigSyncHelper - Restore V15 migration file to original content (avoid Flyway checksum mismatch) - Move endpoint repository access from McpSandboxOrchestrator to McpConfigSyncHelper to eliminate duplicate repository dependency and centralize endpoint operations
1. Remove Thread.sleep blocking in refreshTools - fail fast instead of retrying
with 10s sleep that blocks Tomcat threads
2. Replace HTTPS→HTTP hack with configurable sandbox.ssl-verify property
(defaults to true, set to false to disable SSL verification)
3. Add @PreDestroy shutdown for POLL_SCHEDULER thread pool, convert from
static to instance field for proper lifecycle management
4. K8sClientUtils: auto-evict and recreate client on connectivity failure
(handles expired OIDC tokens without waiting 6h cache expiry)
16. Subscription: respect product autoApprove setting for non-gateway sources
instead of blindly approving all non-gateway subscriptions
17. XSS fix: sanitize HTML entities in highlightJson before dangerouslySetInnerHTML
…anup Security: - Encrypt kubeConfig at rest via JPA EncryptedStringConverter (AES-CBC) - Upgrade Encryptor from AES-ECB to AES-CBC with ECB fallback for legacy data - Encrypt failure now throws instead of silently storing plaintext - Add @Adminauth to listEndpoints (was exposing subscribeParams with API keys) - Centralize SSL trust config in K8sClientUtils.shouldTrustCerts() - Replace navigator.clipboard with copyToClipboard fallback (HTTP compat) Code quality: - Replace magic strings with enum constants (McpEndpointStatus, McpHostingType) - Extract resolveAutoApprove() to eliminate duplicate logic in ConsumerServiceImpl - Extract listPublishedMetaInternal() to deduplicate McpServerServiceImpl - Replace Map<String,String> body with typed DTOs (DeploySandboxParam, UpdateServiceIntroParam) - Fix N+1 queries in McpVendorServiceImpl with batch findByMcpNameIn - Add findByMcpNameIn to McpServerMetaRepository - Add findAllSandboxIds to avoid loading kubeConfig in health checks - Server-side search in McpSquare instead of client-side filtering Bug fixes: - Fix PortalDevelopers duplicate .then() chain - Fix Consumers refresh button (was using unused _refreshIndex state) - Fix SandboxConsoles kubeConfig required validation in edit mode Cleanup: - Remove unused ClusterAttribute, ClusterAttributeConverter - Remove unused /mcp-servers/sandboxes endpoint and frontend getActiveSandboxes - Remove unused Agent page import and /agents route - Remove console.log debug statements from ImportMcpModal
- Merge latest main branch changes (frontend refactoring, UI improvements) - Fix publishProduct: correct product status when already published to portal but status was inconsistent (defensive fix for edge case)
- Vertical layout with centered search bar (matching Square page design) - Sticky search area with IntersectionObserver shadow effect - Debounce auto-search (300ms) instead of enter-only search - CardGridSkeleton loading state instead of Spin - Pagination instead of infinite scroll (PAGE_SIZE=12) - Create button: black circle with hover expand animation - My MCP button: absolute right, navigates to /mcp/my page - Smaller cards (160px height, 4-column grid) - Category/search changes reset to page 1
…nsumer calls Backend: - Batch-load McpServerMeta and McpServerEndpoint for all MCP_SERVER products in fillProducts, eliminating N+1 queries (2 queries instead of 2*N) - Add buildMcpConfigFromPreloaded() that takes pre-loaded data without DB access - Reuse productRefMap in listProductsWithFilter to avoid duplicate query Frontend: - Merge fetchSubscribedProducts and fetchMyMcps into single fetchConsumerData that shares getPrimaryConsumer + getConsumerSubscriptions results - Cache consumerId in ref to avoid redundant API calls on subscribe/unsubscribe
…nt display 🤖 Generated with [Qoder][https://qoder.com]
🤖 Generated with [Qoder][https://qoder.com]
…id SnakeYAML 2.x incompatibility fabric8 6.1.1's Serialization.unmarshal calls SafeConstructor() (no-arg), which was removed in SnakeYAML 2.0. Use Jackson ObjectMapper with YAMLFactory instead, which doesn't depend on SnakeYAML's constructor API.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📝 Description
为 HiMarket 新增完整的 MCP Server 全生命周期管理能力,涵盖以下功能模块:
MCP Server 管理 + 沙箱托管 + 协议标准化(核心功能)
mcp_server_meta(元信息)+mcp_server_endpoint(运行时连接)+sandbox_instance(沙箱实例),Flyway V16/V17 迁移X-API-Key鉴权),仅允许查询已发布产品,非管理员自动脱敏 subscribeParamsAgentRuntime 沙箱部署 API Key 鉴权(对应 spec:
sandbox-auth-apikey)sk_前缀随机密钥(SecureRandom,≥35 字符)subscribeParams,HiChat/HiCoding 调用时自动携带 Authorization header第三方供应商批量导入 MCP(对应 spec:
batch-import-mcp)registerMcp()创建 Product + McpMeta + ProductRef,origin 设为VENDOR_IMPORT其他改进
SecurityConfig新增/mcp/create路由鉴权fillProducts批量加载 MCP meta/endpoint,减少 N+1 查询🔗 Related Issues
✅ Type of Change
🧪 Testing
📋 Checklist
mvn spotless:applyfor backend,npm run lint:fixfor frontend)📊 Test Coverage
📚 Additional Notes
open-api.api-key(环境变量OPEN_API_KEY),用于 Open API 鉴权/mcp/square、/mcp/create、/mcp/my、/mcp/:id)docs/open-api-mcp-servers-v3.mddocs/mcp-cold-hot-table.md、docs/sandbox-instance-table.md