feat(mcp): add 1Panel MCP and enhance MCP credential management (#14189)

* feat(mcp): add 1Panel MCP and enhance MCP credential management

* feat(i18n): implement MCP document localization and remove legacy code
This commit is contained in:
蘭
2026-10-26 13:59:49 +08:00
committed by GitHub
parent 93ca724985
commit d7355f3ccc
108 changed files with 12064 additions and 142 deletions
+122
View File
@@ -0,0 +1,122 @@
export namespace PanelMCP {
export type CredentialStatus = 'Enable' | 'Disable' | 'Revoked' | 'Expired';
export interface EditableCredential {
name: string;
description: string;
expiresAt: string | null;
tools: string[];
toolPolicies: Record<string, string>;
toolReadOnly: Record<string, boolean>;
nodeIds: string[];
}
export interface Credential extends EditableCredential {
id: string;
keyHint: string;
status: CredentialStatus;
revision: number;
createdAt: string;
ownerName: string;
staleTools: string[];
}
export interface Reference {
id: string;
revision: number;
}
export interface Created {
item: Credential;
token: string;
alreadyCreated?: boolean;
}
export type Client = 'generic' | 'codex' | 'claude';
export interface Revealed {
id: string;
token: string;
}
export interface Exported {
filename: string;
content: string;
}
export interface ToolOperation {
id: string;
method: string;
path: string;
bodySchema: Record<string, unknown>;
responseFields: string[];
}
export interface Tool {
toolId: string;
schemaVersion: number;
name: string;
description: string;
categoryId: string;
categoryName: string;
categoryOrder: number;
readOnly: boolean;
risk: string;
inputSchema: Record<string, unknown>;
operations: ToolOperation[];
policyHash: string;
}
export interface Catalog {
contractVersion: number;
tools: Tool[];
scope: 'nodes';
toolNodeIds: Record<string, string[]>;
}
export interface Node {
id: string;
name: string;
status: string;
isLocal: boolean;
}
export type RuntimeType = 'docker';
export interface Settings {
runtimeType: RuntimeType;
dockerImage: string;
enabled: boolean;
listenPort: number;
externalUrl: string;
revision: number;
accessPolicy: 'inherit' | 'restricted' | 'all';
allowedIPs: string[];
}
export interface ServiceStatus {
runtimeType: RuntimeType;
dockerImage: string;
containerName: string;
imageId: string;
enabled: boolean;
installed: boolean;
status: 'not_installed' | 'unsupported' | 'stopped' | 'running' | 'unhealthy' | 'incompatible';
ready: boolean;
reason: string;
adapterVersion: string;
contractVersion: number;
protocol: 'streamable-http';
endpoint: string;
internalEndpoint: string;
canManageService: boolean;
}
export interface Installation {
dockerImage: string;
listenPort: number;
externalUrl: string;
revision: number;
}
export type Operation = 'start' | 'stop' | 'restart';
export interface Invocation {
id: string;
requestId: string;
credentialId: string;
credentialName: string;
ownerName: string;
toolId: string;
nodeId: string;
revision: number;
status: 'running' | 'success' | 'denied' | 'failed';
code: string;
startedAt: string;
finishedAt: string | null;
durationMs: number;
}
}
+39
View File
@@ -0,0 +1,39 @@
import http from '@/api';
import type { ReqPage, ResPage } from '@/api/interface';
import type { PanelMCP } from '@/api/interface/panel-mcp';
const prefix = '/core/mcp';
const local = { headers: { CurrentNode: 'local' } };
export const getPanelMCPStatus = () => http.get<PanelMCP.ServiceStatus>(`${prefix}/status`, {}, local);
export const getPanelMCPSettings = () => http.get<PanelMCP.Settings>(`${prefix}/settings`, {}, local);
export const savePanelMCPSettings = (params: PanelMCP.Settings) =>
http.postWithConfig(`${prefix}/settings`, params, { ...local, timeout: 60000 });
export const operatePanelMCPService = (operation: PanelMCP.Operation) =>
http.postWithConfig(`${prefix}/service/operate`, { operation }, { ...local, timeout: 60000 });
export const installPanelMCPService = (params: PanelMCP.Installation) =>
http.postWithConfig<PanelMCP.ServiceStatus>(`${prefix}/service/install`, params, { ...local, timeout: 420000 });
export const getPanelMCPLogs = () => http.get<{ content: string }>(`${prefix}/service/logs`, {}, local);
export const getPanelMCPCatalog = () => http.get<PanelMCP.Catalog>(`${prefix}/catalog`, {}, local);
export const getPanelMCPNodes = () => http.get<PanelMCP.Node[]>(`${prefix}/nodes`, {}, local);
export const searchPanelMCPCredentials = (params: ReqPage & { excludeRevoked?: boolean }) =>
http.postWithConfig<ResPage<PanelMCP.Credential>>(`${prefix}/credentials/search`, params, local);
export const createPanelMCPCredential = (params: PanelMCP.EditableCredential & { requestID: string }) =>
http.postWithConfig<PanelMCP.Created>(`${prefix}/credentials/create`, params, local);
export const updatePanelMCPCredential = (params: PanelMCP.EditableCredential & PanelMCP.Reference) =>
http.postWithConfig(`${prefix}/credentials/update`, params, local);
export const setPanelMCPCredentialStatus = (params: PanelMCP.Reference & { status: 'Enable' | 'Disable' }) =>
http.postWithConfig(`${prefix}/credentials/status`, params, local);
export const revokePanelMCPCredential = (params: PanelMCP.Reference) =>
http.postWithConfig(`${prefix}/credentials/revoke`, params, local);
export const revealPanelMCPCredential = (params: PanelMCP.Reference, signal?: AbortSignal) =>
http.postWithConfig<PanelMCP.Revealed>(`${prefix}/credentials/reveal`, params, { ...local, signal });
export const rotatePanelMCPCredential = (params: PanelMCP.Reference, signal?: AbortSignal) =>
http.postWithConfig<PanelMCP.Created>(`${prefix}/credentials/rotate`, params, { ...local, signal });
export const exportPanelMCPCredential = (
params: PanelMCP.Reference & { client: PanelMCP.Client },
signal?: AbortSignal,
) => http.postWithConfig<PanelMCP.Exported>(`${prefix}/credentials/export`, params, { ...local, signal });
export const searchPanelMCPInvocations = (
params: ReqPage & { credentialId?: string; toolId?: string; status?: string },
) => http.postWithConfig<ResPage<PanelMCP.Invocation>>(`${prefix}/invocations/search`, params, local);