mirror of
https://github.com/samanhappy/mcphub.git
synced 2025-12-24 02:39:19 -05:00
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
108 lines
2.8 KiB
TypeScript
108 lines
2.8 KiB
TypeScript
import { Request, Response } from 'express';
|
|
import { ApiResponse } from '../types/index.js';
|
|
import { handleCallToolRequest, getServerByName } from '../services/mcpService.js';
|
|
import { convertParametersToTypes } from '../utils/parameterConversion.js';
|
|
import { getNameSeparator } from '../config/index.js';
|
|
|
|
/**
|
|
* Interface for tool call request
|
|
*/
|
|
export interface ToolCallRequest {
|
|
toolName: string;
|
|
arguments?: Record<string, any>;
|
|
}
|
|
|
|
/**
|
|
* Interface for tool search request
|
|
*/
|
|
export interface ToolSearchRequest {
|
|
query: string;
|
|
limit?: number;
|
|
}
|
|
|
|
/**
|
|
* Interface for tool call result
|
|
*/
|
|
interface ToolCallResult {
|
|
content?: Array<{
|
|
type: string;
|
|
text?: string;
|
|
[key: string]: any;
|
|
}>;
|
|
isError?: boolean;
|
|
[key: string]: any;
|
|
}
|
|
|
|
/**
|
|
* Call a specific tool with given arguments
|
|
*/
|
|
export const callTool = async (req: Request, res: Response): Promise<void> => {
|
|
try {
|
|
const { server } = req.params;
|
|
const { toolName, arguments: toolArgs = {} } = req.body as ToolCallRequest;
|
|
|
|
if (!toolName) {
|
|
res.status(400).json({
|
|
success: false,
|
|
message: 'toolName is required',
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Get the server info to access the tool's input schema
|
|
const serverInfo = getServerByName(server);
|
|
let inputSchema: Record<string, any> = {};
|
|
|
|
if (serverInfo) {
|
|
// Find the tool in the server's tools list
|
|
const fullToolName = `${server}${getNameSeparator()}${toolName}`;
|
|
const tool = serverInfo.tools.find(
|
|
(t: any) => t.name === fullToolName || t.name === toolName,
|
|
);
|
|
if (tool && tool.inputSchema) {
|
|
inputSchema = tool.inputSchema as Record<string, any>;
|
|
}
|
|
}
|
|
|
|
// Convert parameters to proper types based on the tool's input schema
|
|
const convertedArgs = convertParametersToTypes(toolArgs, inputSchema);
|
|
|
|
// Create a mock request structure for handleCallToolRequest
|
|
const mockRequest = {
|
|
params: {
|
|
name: 'call_tool',
|
|
arguments: {
|
|
toolName,
|
|
arguments: convertedArgs,
|
|
},
|
|
},
|
|
};
|
|
|
|
const extra = {
|
|
sessionId: req.headers['x-session-id'] || 'api-session',
|
|
server: server || undefined,
|
|
headers: req.headers, // Include request headers for passthrough
|
|
};
|
|
|
|
const result = (await handleCallToolRequest(mockRequest, extra)) as ToolCallResult;
|
|
|
|
const response: ApiResponse = {
|
|
success: true,
|
|
data: {
|
|
content: result.content || [],
|
|
toolName,
|
|
arguments: convertedArgs,
|
|
},
|
|
};
|
|
|
|
res.json(response);
|
|
} catch (error) {
|
|
console.error('Error calling tool:', error);
|
|
res.status(500).json({
|
|
success: false,
|
|
message: 'Failed to call tool',
|
|
error: error instanceof Error ? error.message : 'Unknown error occurred',
|
|
});
|
|
}
|
|
};
|