// src/hooks/useMCP.js
// React hook for MCP functionality
import { useState, useEffect, useCallback } from 'react';
import mcpService from '../services/mcpService';
export const useMCP = () => {
const [isConnected, setIsConnected] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const [availableModels, setAvailableModels] = useState({});
const [capabilities, setCapabilities] = useState(null);
const [availableTools, setAvailableTools] = useState([]);
// Check connection on mount
useEffect(() => {
checkConnection();
}, []);
const checkConnection = useCallback(async () => {
try {
console.log('Checking MCP connection...');
const health = await mcpService.checkHealth();
setIsConnected(true);
setError(null);
console.log('MCP connected successfully:', health);
// Load capabilities (includes models and tools)
try {
const caps = await mcpService.getCapabilities();
setCapabilities(caps);
setAvailableModels(caps.available_models || {});
setAvailableTools(caps.tools || []);
console.log('MCP capabilities loaded:', caps);
} catch (capError) {
console.warn('Could not load capabilities:', capError);
// Fallback to models only
try {
const models = await mcpService.getModels();
setAvailableModels(models.models || {});
} catch (modelError) {
console.warn('Could not load models:', modelError);
}
}
} catch (err) {
setIsConnected(false);
setError('Cannot connect to MCP server. Make sure it\'s running on localhost:8000');
console.error('MCP connection failed:', err);
}
}, []);
const chat = useCallback(async (message, model = 'mistral:latest', options = {}) => {
if (!message.trim()) {
throw new Error('Message cannot be empty');
}
setIsLoading(true);
setError(null);
try {
console.log(`Sending chat message: "${message}" to model: ${model}`);
const response = await mcpService.chat(message, model, options);
console.log('Chat response received:', response);
return response;
} catch (err) {
const errorMessage = err.message || 'Chat failed';
setError(errorMessage);
console.error('Chat error:', err);
throw new Error(errorMessage);
} finally {
setIsLoading(false);
}
}, []);
const chatStream = useCallback(async (message, model = 'mistral:latest', options = {}, onChunk = null) => {
if (!message.trim()) {
throw new Error('Message cannot be empty');
}
setIsLoading(true);
setError(null);
try {
console.log(`Sending streaming chat message: "${message}" to model: ${model}`);
const response = await mcpService.chatStream(message, model, options, onChunk);
console.log('Streaming chat response completed:', response);
return response;
} catch (err) {
const errorMessage = err.message || 'Streaming chat failed';
setError(errorMessage);
console.error('Streaming chat error:', err);
throw new Error(errorMessage);
} finally {
setIsLoading(false);
}
}, []);
const conversationChat = useCallback(async (message, conversationId, model = 'mistral:latest', options = {}) => {
if (!message.trim()) {
throw new Error('Message cannot be empty');
}
setIsLoading(true);
setError(null);
try {
console.log(`Sending conversation chat: "${message}" for conversation: ${conversationId}`);
const response = await mcpService.conversationChat(message, conversationId, model, options);
console.log('Conversation chat response received:', response);
return response;
} catch (err) {
const errorMessage = err.message || 'Conversation chat failed';
setError(errorMessage);
console.error('Conversation chat error:', err);
throw new Error(errorMessage);
} finally {
setIsLoading(false);
}
}, []);
const storeMemory = useCallback(async (conversationId, content, metadata = {}) => {
try {
console.log(`Storing memory for conversation: ${conversationId}`);
const response = await mcpService.storeMemory(conversationId, content, metadata);
console.log('Memory stored:', response);
return response;
} catch (err) {
const errorMessage = err.message || 'Memory storage failed';
setError(errorMessage);
console.error('Memory storage error:', err);
throw new Error(errorMessage);
}
}, []);
const getMemory = useCallback(async (conversationId, limit = 20) => {
try {
console.log(`Getting memory for conversation: ${conversationId}`);
const response = await mcpService.getMemory(conversationId, limit);
console.log('Memory retrieved:', response);
return response;
} catch (err) {
const errorMessage = err.message || 'Memory retrieval failed';
setError(errorMessage);
console.error('Memory retrieval error:', err);
throw new Error(errorMessage);
}
}, []);
const testConnection = useCallback(async () => {
try {
setIsLoading(true);
const echoResponse = await mcpService.echo('Connection test');
console.log('Connection test successful:', echoResponse);
return echoResponse;
} catch (err) {
console.error('Connection test failed:', err);
throw err;
} finally {
setIsLoading(false);
}
}, []);
// Get capabilities function
const getCapabilities = useCallback(async () => {
try {
const caps = await mcpService.getCapabilities();
setCapabilities(caps);
setAvailableModels(caps.available_models || {});
setAvailableTools(caps.tools || []);
return caps;
} catch (err) {
console.error('Failed to get capabilities:', err);
throw err;
}
}, []);
return {
// Connection state
isConnected,
isLoading,
error,
// Capabilities and tools
capabilities,
availableModels,
availableTools,
// Actions
checkConnection,
getCapabilities,
chat,
chatStream,
conversationChat,
storeMemory,
getMemory,
testConnection,
// Direct service access
mcpService,
};
};