mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-07-17 18:06:06 +00:00
feat(mcp): support mcp resources (#2215)
* feat(mcp): support mcp resources * feat(web): split MCP resources into tab * docs: add MCP resources PR review * feat(mcp): productionize resource support * feat(mcp): scope local agent tools and resources * fix(web): gate space embedding models behind login * fix(web): prevent clipped space model CTA * test: update preproc resource tool expectations * fix(web): expose skill authoring tools in selector --------- Co-authored-by: yang.xiang <yang.xiang@advancegroup.com> Co-authored-by: Hyu <chenhyu@proton.me> Co-authored-by: Junyan Qin <rockchinq@gmail.com>
This commit is contained in:
@@ -563,6 +563,11 @@ export interface MCPServerRuntimeInfo {
|
||||
* server runs inside Box. Absent when Box is unavailable. */
|
||||
box_session_id?: string;
|
||||
box_enabled?: boolean;
|
||||
resource_count: number;
|
||||
resources: MCPResource[];
|
||||
resource_template_count?: number;
|
||||
resource_templates?: MCPResourceTemplate[];
|
||||
resource_capabilities?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export type MCPServer =
|
||||
@@ -617,11 +622,67 @@ export interface MCPTool {
|
||||
parameters?: object;
|
||||
}
|
||||
|
||||
export interface MCPResource {
|
||||
uri: string;
|
||||
name: string;
|
||||
title?: string;
|
||||
description: string;
|
||||
mime_type: string;
|
||||
size?: number;
|
||||
icons?: object[];
|
||||
annotations?: Record<string, unknown>;
|
||||
_meta?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface MCPResourceTemplate {
|
||||
uri_template: string;
|
||||
name: string;
|
||||
title?: string;
|
||||
description: string;
|
||||
mime_type: string;
|
||||
icons?: object[];
|
||||
annotations?: Record<string, unknown>;
|
||||
_meta?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface MCPResourceContent {
|
||||
uri: string;
|
||||
mime_type: string;
|
||||
type: 'text' | 'blob';
|
||||
text?: string;
|
||||
blob?: string | null;
|
||||
bytes?: number;
|
||||
truncated?: boolean;
|
||||
binary_omitted?: boolean;
|
||||
_meta?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface ApiRespMCPResources {
|
||||
resources: MCPResource[];
|
||||
resource_templates?: MCPResourceTemplate[];
|
||||
resource_capabilities?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface ApiRespMCPResourceContents {
|
||||
contents: MCPResourceContent[];
|
||||
server_name?: string;
|
||||
server_uuid?: string;
|
||||
uri?: string;
|
||||
source?: string;
|
||||
bytes?: number;
|
||||
truncated?: boolean;
|
||||
cache_hit?: boolean;
|
||||
warnings?: string[];
|
||||
}
|
||||
|
||||
export interface PluginTool {
|
||||
name: string;
|
||||
description: string;
|
||||
human_desc: string;
|
||||
parameters: object;
|
||||
source?: 'builtin' | 'plugin' | 'mcp' | 'skill';
|
||||
source_name?: string;
|
||||
source_id?: string;
|
||||
}
|
||||
|
||||
export interface ApiRespTools {
|
||||
|
||||
@@ -67,6 +67,8 @@ export enum DynamicFormItemType {
|
||||
PLUGIN_SELECTOR = 'plugin-selector',
|
||||
BOT_SELECTOR = 'bot-selector',
|
||||
TOOLS_SELECTOR = 'tools-selector',
|
||||
RICH_TOOLS_SELECTOR = 'rich-tools-selector',
|
||||
RESOURCES_SELECTOR = 'resources-selector',
|
||||
WEBHOOK_URL = 'webhook-url',
|
||||
EMBED_CODE = 'embed-code',
|
||||
QR_CODE_LOGIN = 'qr-code-login',
|
||||
|
||||
@@ -40,6 +40,8 @@ import {
|
||||
BoxSessionInfo,
|
||||
ApiRespMCPServers,
|
||||
ApiRespMCPServer,
|
||||
ApiRespMCPResources,
|
||||
ApiRespMCPResourceContents,
|
||||
MCPServer,
|
||||
ApiRespModelProviders,
|
||||
ApiRespModelProvider,
|
||||
@@ -269,10 +271,20 @@ export class BackendClient extends BaseHttpClient {
|
||||
enable_all_plugins: boolean;
|
||||
enable_all_mcp_servers: boolean;
|
||||
enable_all_skills: boolean;
|
||||
mcp_resource_agent_read_enabled: boolean;
|
||||
bound_plugins: Array<{ author: string; name: string }>;
|
||||
available_plugins: Plugin[];
|
||||
bound_mcp_servers: string[];
|
||||
available_mcp_servers: MCPServer[];
|
||||
bound_mcp_resources: Array<{
|
||||
server_uuid?: string;
|
||||
server_name?: string;
|
||||
uri: string;
|
||||
mode?: string;
|
||||
enabled?: boolean;
|
||||
max_bytes?: number;
|
||||
max_tokens?: number;
|
||||
}>;
|
||||
bound_skills: string[];
|
||||
available_skills: Skill[];
|
||||
}> {
|
||||
@@ -287,15 +299,32 @@ export class BackendClient extends BaseHttpClient {
|
||||
enable_all_mcp_servers: boolean = true,
|
||||
bound_skills: string[] = [],
|
||||
enable_all_skills: boolean = true,
|
||||
bound_mcp_resources?: Array<{
|
||||
server_uuid?: string;
|
||||
server_name?: string;
|
||||
uri: string;
|
||||
mode?: string;
|
||||
enabled?: boolean;
|
||||
max_bytes?: number;
|
||||
max_tokens?: number;
|
||||
}>,
|
||||
mcp_resource_agent_read_enabled?: boolean,
|
||||
): Promise<object> {
|
||||
return this.put(`/api/v1/pipelines/${uuid}/extensions`, {
|
||||
const payload: Record<string, unknown> = {
|
||||
bound_plugins,
|
||||
bound_mcp_servers,
|
||||
enable_all_plugins,
|
||||
enable_all_mcp_servers,
|
||||
bound_skills,
|
||||
enable_all_skills,
|
||||
});
|
||||
};
|
||||
if (bound_mcp_resources !== undefined) {
|
||||
payload.bound_mcp_resources = bound_mcp_resources;
|
||||
}
|
||||
if (mcp_resource_agent_read_enabled !== undefined) {
|
||||
payload.mcp_resource_agent_read_enabled = mcp_resource_agent_read_enabled;
|
||||
}
|
||||
return this.put(`/api/v1/pipelines/${uuid}/extensions`, payload);
|
||||
}
|
||||
|
||||
// ============ WebSocket Chat API ============
|
||||
@@ -865,8 +894,11 @@ export class BackendClient extends BaseHttpClient {
|
||||
|
||||
// ========== Tools ==========
|
||||
|
||||
public getTools(): Promise<ApiRespTools> {
|
||||
return this.get('/api/v1/tools');
|
||||
public getTools(pipelineId?: string): Promise<ApiRespTools> {
|
||||
return this.get(
|
||||
'/api/v1/tools',
|
||||
pipelineId ? { pipeline_uuid: pipelineId } : undefined,
|
||||
);
|
||||
}
|
||||
|
||||
public getToolDetail(toolName: string): Promise<ApiRespToolDetail> {
|
||||
@@ -926,6 +958,28 @@ export class BackendClient extends BaseHttpClient {
|
||||
return this.post('/api/v1/mcp/servers', { source });
|
||||
}
|
||||
|
||||
public getMCPServerResources(
|
||||
serverName: string,
|
||||
): Promise<ApiRespMCPResources> {
|
||||
return this.get(
|
||||
`/api/v1/mcp/servers/${encodeURIComponent(serverName)}/resources`,
|
||||
);
|
||||
}
|
||||
|
||||
public readMCPServerResource(
|
||||
serverName: string,
|
||||
uri: string,
|
||||
maxBytes?: number,
|
||||
): Promise<ApiRespMCPResourceContents> {
|
||||
return this.post(
|
||||
`/api/v1/mcp/servers/${encodeURIComponent(serverName)}/resources/read`,
|
||||
{
|
||||
uri,
|
||||
max_bytes: maxBytes,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// ============ System API ============
|
||||
public getSystemInfo(): Promise<ApiRespSystemInfo> {
|
||||
return this.get('/api/v1/system/info');
|
||||
|
||||
Reference in New Issue
Block a user