actions.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. "use server";
  2. import { Client } from "@modelcontextprotocol/sdk/client/index.js";
  3. import {
  4. createClient,
  5. executeRequest,
  6. listPrimitives,
  7. Primitive,
  8. } from "./client";
  9. import { MCPClientLogger } from "./logger";
  10. import conf from "./mcp_config.json";
  11. import { McpRequestMessage } from "./types";
  12. const logger = new MCPClientLogger("MCP Actions");
  13. // Use Map to store all clients
  14. const clientsMap = new Map<
  15. string,
  16. { client: Client; primitives: Primitive[] }
  17. >();
  18. // Whether initialized
  19. let initialized = false;
  20. // Store failed clients
  21. let errorClients: string[] = [];
  22. // Initialize all configured clients
  23. export async function initializeMcpClients() {
  24. // If already initialized, return
  25. if (initialized) {
  26. return;
  27. }
  28. logger.info("Starting to initialize MCP clients...");
  29. // Initialize all clients, key is clientId, value is client config
  30. for (const [clientId, config] of Object.entries(conf.mcpServers)) {
  31. try {
  32. logger.info(`Initializing MCP client: ${clientId}`);
  33. const client = await createClient(config, clientId);
  34. const primitives = await listPrimitives(client);
  35. clientsMap.set(clientId, { client, primitives });
  36. logger.success(
  37. `Client [${clientId}] initialized, ${primitives.length} primitives supported`,
  38. );
  39. } catch (error) {
  40. errorClients.push(clientId);
  41. logger.error(`Failed to initialize client ${clientId}: ${error}`);
  42. }
  43. }
  44. initialized = true;
  45. if (errorClients.length > 0) {
  46. logger.warn(`Failed to initialize clients: ${errorClients.join(", ")}`);
  47. } else {
  48. logger.success("All MCP clients initialized");
  49. }
  50. const availableClients = await getAvailableClients();
  51. logger.info(`Available clients: ${availableClients.join(",")}`);
  52. }
  53. // Execute MCP request
  54. export async function executeMcpAction(
  55. clientId: string,
  56. request: McpRequestMessage,
  57. ) {
  58. try {
  59. // Find the corresponding client
  60. const client = clientsMap.get(clientId)?.client;
  61. if (!client) {
  62. logger.error(`Client ${clientId} not found`);
  63. return;
  64. }
  65. logger.info(`Executing MCP request for ${clientId}`);
  66. // Execute request and return result
  67. return await executeRequest(client, request);
  68. } catch (error) {
  69. logger.error(`MCP execution error: ${error}`);
  70. throw error;
  71. }
  72. }
  73. // Get all available client IDs
  74. export async function getAvailableClients() {
  75. return Array.from(clientsMap.keys()).filter(
  76. (clientId) => !errorClients.includes(clientId),
  77. );
  78. }
  79. // Get all primitives from all clients
  80. export async function getAllPrimitives(): Promise<
  81. {
  82. clientId: string;
  83. primitives: Primitive[];
  84. }[]
  85. > {
  86. return Array.from(clientsMap.entries()).map(([clientId, { primitives }]) => ({
  87. clientId,
  88. primitives,
  89. }));
  90. }