mirror of
https://github.com/coleam00/Archon.git
synced 2025-12-24 02:39:17 -05:00
cleanup: remove unused mcpClientService and update deprecation comments
- Remove mcpClientService.ts (445 lines) - no longer used after removing MCP client components - Update deprecation comments in mcpServerService to remove references to deleted service - This completes the MCP service cleanup
This commit is contained in:
@@ -1,445 +0,0 @@
|
||||
import { z } from 'zod';
|
||||
import { getApiUrl } from '../config/api';
|
||||
|
||||
// ========================================
|
||||
// TYPES & INTERFACES
|
||||
// ========================================
|
||||
|
||||
export interface MCPClientConfig {
|
||||
name: string;
|
||||
transport_type: 'http'; // Only Streamable HTTP is supported for MCP clients
|
||||
connection_config: {
|
||||
url: string; // The Streamable HTTP endpoint URL (e.g., http://localhost:8051/mcp)
|
||||
};
|
||||
auto_connect?: boolean;
|
||||
health_check_interval?: number;
|
||||
is_default?: boolean;
|
||||
}
|
||||
|
||||
export interface MCPClient {
|
||||
id: string;
|
||||
name: string;
|
||||
transport_type: 'http'; // Only Streamable HTTP is supported
|
||||
connection_config: {
|
||||
url: string;
|
||||
};
|
||||
status: 'connected' | 'disconnected' | 'connecting' | 'error';
|
||||
auto_connect: boolean;
|
||||
health_check_interval: number;
|
||||
last_seen: string | null;
|
||||
last_error: string | null;
|
||||
is_default: boolean;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface MCPClientTool {
|
||||
id: string;
|
||||
client_id: string;
|
||||
tool_name: string;
|
||||
tool_description: string | null;
|
||||
tool_schema: Record<string, any>;
|
||||
discovered_at: string;
|
||||
}
|
||||
|
||||
export interface ToolCallRequest {
|
||||
client_id: string;
|
||||
tool_name: string;
|
||||
arguments: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface ClientStatus {
|
||||
client_id: string;
|
||||
status: string;
|
||||
last_seen: string | null;
|
||||
last_error: string | null;
|
||||
is_active: boolean;
|
||||
}
|
||||
|
||||
export interface ToolsResponse {
|
||||
client_id: string;
|
||||
tools: MCPClientTool[];
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface AllToolsResponse {
|
||||
archon_tools: MCPTool[];
|
||||
client_tools: { client: MCPClient; tools: MCPClientTool[] }[];
|
||||
total_count: number;
|
||||
}
|
||||
|
||||
// Zod schemas for MCP protocol
|
||||
const MCPParameterSchema = z.object({
|
||||
name: z.string(),
|
||||
description: z.string().optional(),
|
||||
required: z.boolean().optional(),
|
||||
type: z.string().optional(),
|
||||
});
|
||||
|
||||
const MCPToolSchema = z.object({
|
||||
name: z.string(),
|
||||
description: z.string().optional(),
|
||||
inputSchema: z.object({
|
||||
type: z.literal('object'),
|
||||
properties: z.record(z.any()).optional(),
|
||||
required: z.array(z.string()).optional(),
|
||||
}).optional(),
|
||||
});
|
||||
|
||||
export type MCPTool = z.infer<typeof MCPToolSchema>;
|
||||
export type MCPParameter = z.infer<typeof MCPParameterSchema>;
|
||||
|
||||
import { getApiUrl } from '../config/api';
|
||||
|
||||
/**
|
||||
* MCP Client Service - Universal MCP client that connects to any MCP servers
|
||||
* This service communicates with the standalone Python MCP client service
|
||||
*/
|
||||
class MCPClientService {
|
||||
private baseUrl = getApiUrl();
|
||||
|
||||
// ========================================
|
||||
// CLIENT MANAGEMENT
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* Get all configured MCP clients
|
||||
*/
|
||||
async getClients(): Promise<MCPClient[]> {
|
||||
const response = await fetch(`${this.baseUrl}/api/mcp/clients/`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to get MCP clients');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MCP client
|
||||
*/
|
||||
async createClient(config: MCPClientConfig): Promise<MCPClient> {
|
||||
const response = await fetch(`${this.baseUrl}/api/mcp/clients/`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(config)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
throw new Error(error.detail || 'Failed to create MCP client');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific MCP client
|
||||
*/
|
||||
async getClient(clientId: string): Promise<MCPClient> {
|
||||
const response = await fetch(`${this.baseUrl}/api/mcp/clients/${clientId}`);
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
throw new Error(error.detail || 'Failed to get MCP client');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an MCP client
|
||||
*/
|
||||
async updateClient(clientId: string, updates: Partial<MCPClientConfig>): Promise<MCPClient> {
|
||||
const response = await fetch(`${this.baseUrl}/api/mcp/clients/${clientId}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(updates)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
throw new Error(error.detail || 'Failed to update MCP client');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an MCP client
|
||||
*/
|
||||
async deleteClient(clientId: string): Promise<{ success: boolean; message: string }> {
|
||||
const response = await fetch(`${this.baseUrl}/api/mcp/clients/${clientId}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
throw new Error(error.detail || 'Failed to delete MCP client');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// CONNECTION MANAGEMENT
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* Connect to an MCP client
|
||||
*/
|
||||
async connectClient(clientId: string): Promise<{ success: boolean; message: string }> {
|
||||
const response = await fetch(`${this.baseUrl}/api/mcp/clients/${clientId}/connect`, {
|
||||
method: 'POST'
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
throw new Error(error.detail || 'Failed to connect to MCP client');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from an MCP client
|
||||
*/
|
||||
async disconnectClient(clientId: string): Promise<{ success: boolean; message: string }> {
|
||||
const response = await fetch(`${this.baseUrl}/api/mcp/clients/${clientId}/disconnect`, {
|
||||
method: 'POST'
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
throw new Error(error.detail || 'Failed to disconnect from MCP client');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get client status and health
|
||||
*/
|
||||
async getClientStatus(clientId: string): Promise<ClientStatus> {
|
||||
const response = await fetch(`${this.baseUrl}/api/mcp/clients/${clientId}/status`);
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
throw new Error(error.detail || 'Failed to get client status');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a client configuration before saving
|
||||
*/
|
||||
async testClientConfig(config: MCPClientConfig): Promise<{ success: boolean; message: string }> {
|
||||
const response = await fetch(`${this.baseUrl}/api/mcp/clients/test-config`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(config)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
throw new Error(error.detail || 'Failed to test client configuration');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// TOOL DISCOVERY & EXECUTION
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* Get tools from a specific client
|
||||
*/
|
||||
async getClientTools(clientId: string): Promise<ToolsResponse> {
|
||||
const response = await fetch(`${this.baseUrl}/api/mcp/clients/${clientId}/tools`);
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
throw new Error(error.detail || 'Failed to get client tools');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a tool on a specific client
|
||||
*/
|
||||
async callClientTool(request: ToolCallRequest): Promise<any> {
|
||||
const response = await fetch(`${this.baseUrl}/api/mcp/clients/tools/call`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(request)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
throw new Error(error.detail || 'Failed to call client tool');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tools from all connected clients (including Archon via MCP client)
|
||||
*/
|
||||
async getAllAvailableTools(): Promise<AllToolsResponse> {
|
||||
const response = await fetch(`${this.baseUrl}/api/mcp/clients/tools/all`);
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
throw new Error(error.detail || 'Failed to get all available tools');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Discover tools from a specific client (force refresh)
|
||||
*/
|
||||
async discoverClientTools(clientId: string): Promise<ToolsResponse> {
|
||||
const response = await fetch(`${this.baseUrl}/api/mcp/clients/${clientId}/tools/discover`, {
|
||||
method: 'POST'
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
throw new Error(error.detail || 'Failed to discover client tools');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// CONVENIENCE METHODS
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* Connect to multiple clients at once
|
||||
*/
|
||||
async connectMultipleClients(clientIds: string[]): Promise<Array<{ clientId: string; success: boolean; message: string }>> {
|
||||
const results = await Promise.allSettled(
|
||||
clientIds.map(async (clientId) => {
|
||||
try {
|
||||
const result = await this.connectClient(clientId);
|
||||
return { clientId, ...result };
|
||||
} catch (error) {
|
||||
return {
|
||||
clientId,
|
||||
success: false,
|
||||
message: error instanceof Error ? error.message : 'Unknown error'
|
||||
};
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
return results.map((result, index) =>
|
||||
result.status === 'fulfilled'
|
||||
? result.value
|
||||
: { clientId: clientIds[index], success: false, message: result.reason?.message || 'Failed to connect' }
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get status for all clients
|
||||
*/
|
||||
async getAllClientStatuses(): Promise<Array<{ client: MCPClient; status: ClientStatus }>> {
|
||||
const clients = await this.getClients();
|
||||
|
||||
const statuses = await Promise.allSettled(
|
||||
clients.map(async (client) => {
|
||||
try {
|
||||
const status = await this.getClientStatus(client.id);
|
||||
return { client, status };
|
||||
} catch (error) {
|
||||
return {
|
||||
client,
|
||||
status: {
|
||||
client_id: client.id,
|
||||
status: 'error',
|
||||
last_seen: null,
|
||||
last_error: error instanceof Error ? error.message : 'Unknown error',
|
||||
is_active: false
|
||||
}
|
||||
};
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
return statuses.map((result) =>
|
||||
result.status === 'fulfilled' ? result.value : result.reason
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-connect to all clients marked with auto_connect
|
||||
*/
|
||||
async autoConnectClients(): Promise<Array<{ clientId: string; success: boolean; message: string }>> {
|
||||
const clients = await this.getClients();
|
||||
const autoConnectClients = clients.filter(client => client.auto_connect);
|
||||
|
||||
if (autoConnectClients.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return this.connectMultipleClients(autoConnectClients.map(c => c.id));
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// ARCHON INTEGRATION HELPERS
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* Create Archon MCP client using Streamable HTTP transport
|
||||
*/
|
||||
async createArchonClient(): Promise<MCPClient> {
|
||||
// Require ARCHON_MCP_PORT to be set
|
||||
const mcpPort = import.meta.env.ARCHON_MCP_PORT;
|
||||
if (!mcpPort) {
|
||||
throw new Error(
|
||||
'ARCHON_MCP_PORT environment variable is required. ' +
|
||||
'Please set it in your environment variables. ' +
|
||||
'Default value: 8051'
|
||||
);
|
||||
}
|
||||
|
||||
// Get the host from the API URL
|
||||
const apiUrl = getApiUrl();
|
||||
const url = new URL(apiUrl || `http://${window.location.hostname}:${mcpPort}`);
|
||||
const mcpUrl = `${url.protocol}//${url.hostname}:${mcpPort}/mcp`;
|
||||
|
||||
const archonConfig: MCPClientConfig = {
|
||||
name: 'Archon',
|
||||
transport_type: 'http',
|
||||
connection_config: {
|
||||
url: mcpUrl
|
||||
},
|
||||
auto_connect: true,
|
||||
health_check_interval: 30,
|
||||
is_default: true
|
||||
};
|
||||
|
||||
return this.createClient(archonConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default Archon client (or create if doesn't exist)
|
||||
*/
|
||||
async getOrCreateArchonClient(): Promise<MCPClient> {
|
||||
const clients = await this.getClients();
|
||||
const archonClient = clients.find(client => client.is_default || client.name === 'Archon');
|
||||
|
||||
if (archonClient) {
|
||||
return archonClient;
|
||||
}
|
||||
|
||||
return this.createArchonClient();
|
||||
}
|
||||
}
|
||||
|
||||
export const mcpClientService = new MCPClientService();
|
||||
@@ -192,7 +192,7 @@ class MCPServerService {
|
||||
|
||||
/**
|
||||
* Get available tools from the running Archon MCP server
|
||||
* @deprecated Use mcpClientService for tool discovery instead
|
||||
* @deprecated This method is deprecated
|
||||
*/
|
||||
async getAvailableTools(): Promise<MCPTool[]> {
|
||||
try {
|
||||
@@ -209,7 +209,7 @@ class MCPServerService {
|
||||
|
||||
/**
|
||||
* Call a specific tool on the Archon MCP server
|
||||
* @deprecated Use mcpClientService for tool calls instead
|
||||
* @deprecated This method is deprecated
|
||||
*/
|
||||
async callTool(name: string, arguments_: Record<string, any>): Promise<any> {
|
||||
try {
|
||||
@@ -229,9 +229,9 @@ export const mcpServerService = new MCPServerService();
|
||||
|
||||
/**
|
||||
* Legacy function - use mcpServerService.getAvailableTools() instead
|
||||
* @deprecated Use mcpServerService.getAvailableTools() or mcpClientService instead
|
||||
* @deprecated Use mcpServerService.getAvailableTools() instead
|
||||
*/
|
||||
export const getMCPTools = async () => {
|
||||
console.warn('getMCPTools is deprecated. Use mcpServerService.getAvailableTools() or mcpClientService instead.');
|
||||
console.warn('getMCPTools is deprecated. Use mcpServerService.getAvailableTools() instead.');
|
||||
return mcpServerService.getAvailableTools();
|
||||
};
|
||||
Reference in New Issue
Block a user