feat(mcp): add standalone server registry

Implement C.1 stdio MCP server CRUD, encrypted environment secrets, command digest approval, connection tests, lifecycle recovery, and dynamic tool registration. Add the standalone frontend configuration center, contracts, regression tests, and development documentation.
This commit is contained in:
2026-09-03 14:49:49 +08:00
parent 0c392eebe4
commit d4ffbdcadd
15 changed files with 1086 additions and 12 deletions
+1
View File
@@ -8,6 +8,7 @@ export * as chatService from './chatService'
export * as agentService from './agentService'
export * as skillService from './skillService'
export * as pluginService from './pluginService'
export * as mcpServerService from './mcpServerService'
export * as providerService from './providerService'
export * as taskService from './taskService'
export * as indexService from './indexService'
+17
View File
@@ -0,0 +1,17 @@
import apiClient from './apiClient'
import type { McpServer, McpServerInput, OperationResponse } from '@/contracts'
const base = '/api/mcp/servers'
export async function listMcpServers(): Promise<McpServer[]> {
return (await apiClient.get<{ items: McpServer[] }>(base)).items
}
export const createMcpServer = (input: McpServerInput) => apiClient.post<McpServer>(base, input)
export const updateMcpServer = (id: string, input: McpServerInput) => apiClient.put<McpServer>(`${base}/${id}`, input)
export const deleteMcpServer = (id: string) => apiClient.delete<OperationResponse>(`${base}/${id}`)
export const trustMcpServer = (server: McpServer) => apiClient.post<McpServer>(`${base}/${server.server_id}/trust`, { command_digest: server.command_digest })
export const testMcpServer = (id: string) => apiClient.post<McpServer>(`${base}/${id}/test`)
export const enableMcpServer = (id: string) => apiClient.post<McpServer>(`${base}/${id}/enable`)
export const disableMcpServer = (id: string) => apiClient.post<McpServer>(`${base}/${id}/disable`)
export const putMcpServerSecret = (id: string, key: string, secret: string) => apiClient.put(`${base}/${id}/secrets/${encodeURIComponent(key)}`, { secret })
export const deleteMcpServerSecret = (id: string, key: string) => apiClient.delete(`${base}/${id}/secrets/${encodeURIComponent(key)}`)