Spaces:
Runtime error
Runtime error
File size: 4,278 Bytes
24caae0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
import { useState, useEffect, useCallback } from 'react';
// Custom hook for managing MCP servers and tools
function useMcp(mcpServers) {
const [serverTools, setServerTools] = useState({});
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
// Discover tools from all MCP servers
const discoverTools = useCallback(async () => {
console.log('Discovering MCP tools, servers:', mcpServers);
if (!mcpServers || mcpServers.length === 0) {
console.log('No MCP servers configured');
setServerTools({});
return;
}
setIsLoading(true);
setError(null);
const toolsMap = {};
try {
// Discover tools from each server in parallel
const discoveryPromises = mcpServers.map(async (server) => {
try {
const response = await fetch('/api/mcp/discover', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ server })
});
if (!response.ok) {
const errorText = await response.text();
console.error(`Error discovering tools for server ${server.name}:`, errorText);
return {
serverId: server.id,
tools: [],
error: `Failed to discover tools: ${response.status}`
};
}
return await response.json();
} catch (error) {
console.error(`Error discovering tools for server ${server.name}:`, error);
return {
serverId: server.id,
tools: [],
error: error.message
};
}
});
const results = await Promise.all(discoveryPromises);
// Organize tools by server
results.forEach(result => {
if (result && result.serverId) {
toolsMap[result.serverId] = {
tools: result.tools || [],
error: result.error || null
};
}
});
setServerTools(toolsMap);
} catch (error) {
console.error('Error discovering MCP tools:', error);
setError(error.message);
} finally {
setIsLoading(false);
}
}, [mcpServers]);
// Execute a tool on an MCP server
const executeTool = useCallback(async (serverId, toolName, parameters) => {
if (!mcpServers || !serverId || !toolName) {
throw new Error('Invalid tool execution parameters');
}
const server = mcpServers.find(s => s.id === serverId);
if (!server) {
throw new Error(`MCP server with ID ${serverId} not found`);
}
try {
const response = await fetch('/api/mcp/execute', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
server,
tool: toolName,
parameters
})
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Tool execution failed: ${response.status} - ${errorText}`);
}
return await response.json();
} catch (error) {
console.error(`Error executing tool ${toolName} on server ${server.name}:`, error);
throw error;
}
}, [mcpServers]);
// Discover tools when servers change
useEffect(() => {
console.log('MCP servers changed, discovering tools');
discoverTools();
}, [discoverTools]);
// Get all available tools across all servers
const getAllTools = useCallback(() => {
console.log('Getting all MCP tools, serverTools:', serverTools);
const allTools = [];
Object.entries(serverTools).forEach(([serverId, serverData]) => {
if (serverData.tools && serverData.tools.length > 0) {
const server = mcpServers.find(s => s.id === serverId);
if (server) {
serverData.tools.forEach(tool => {
allTools.push({
...tool,
serverId,
serverName: server.name
});
});
}
}
});
console.log('All MCP tools:', allTools);
return allTools;
}, [serverTools, mcpServers]);
return {
serverTools,
isLoading,
error,
discoverTools,
executeTool,
getAllTools
};
}
export default useMcp;
|