Files
patchy631--ai-engineering-hub/open-agent-builder/lib/mcp/resolver.ts
T
2026-07-13 12:37:47 +08:00

114 lines
3.0 KiB
TypeScript

/**
* MCP Resolver
* Fetches MCP configurations from Convex at runtime
* This ensures executors always use the latest configuration
*/
import { ConvexHttpClient } from "convex/browser";
import { api } from "@/convex/_generated/api";
import { Id } from "@/convex/_generated/dataModel";
// Create a Convex client for server-side usage
const getConvexClient = () => {
const url = process.env.NEXT_PUBLIC_CONVEX_URL;
if (!url) {
console.error('NEXT_PUBLIC_CONVEX_URL not configured');
return null;
}
return new ConvexHttpClient(url);
};
/**
* Resolve multiple MCP server IDs to their full configurations
*/
export async function resolveMCPServers(serverIds: string[]): Promise<any[]> {
if (!serverIds || serverIds.length === 0) {
return [];
}
// Handle legacy format (full config objects instead of IDs)
if (typeof serverIds[0] === 'object') {
console.log('✅ Using legacy mcpTools format (already resolved)');
return serverIds; // Already resolved
}
const convex = getConvexClient();
if (!convex) {
console.warn('Convex not configured, returning empty MCP servers');
return [];
}
try {
// Fetch server configurations from Convex
const servers = await convex.query(api.mcpServers.getMCPServersByIds, {
ids: serverIds as Id<"mcpServers">[],
});
// Transform to the format expected by executors
return servers.filter(Boolean).map(server => ({
name: server.name,
url: server.url,
description: server.description,
authType: server.authType,
accessToken: server.accessToken,
availableTools: server.tools || [],
headers: server.headers,
}));
} catch (error) {
console.error('Error resolving MCP servers:', error);
return [];
}
}
/**
* Resolve a single MCP server ID to its configuration
*/
export async function resolveMCPServer(serverId: string): Promise<any | null> {
if (!serverId) {
return null;
}
const convex = getConvexClient();
if (!convex) {
console.warn('Convex not configured, cannot resolve MCP server');
return null;
}
try {
const server = await convex.query(api.mcpServers.getMCPServer, {
id: serverId as Id<"mcpServers">,
});
if (!server) {
return null;
}
return {
name: server.name,
url: server.url,
description: server.description,
authType: server.authType,
accessToken: server.accessToken,
availableTools: server.tools || [],
headers: server.headers,
};
} catch (error) {
console.error('Error resolving MCP server:', error);
return null;
}
}
/**
* Helper to check if a node is using the old mcpTools format
* and migrate it to the new mcpServerIds format
*/
export function migrateMCPData(data: any): any {
// If using old format with full configs, return as-is for backward compatibility
if (data.mcpTools && Array.isArray(data.mcpTools)) {
console.warn('Node using legacy mcpTools format. Consider migrating to mcpServerIds.');
return data;
}
// New format uses mcpServerIds
return data;
}