api_call
Execute API calls by specifying HTTP methods, paths, parameters, and headers to interact with REST APIs defined in Swagger specifications.
Instructions
调用示例API API的通用工具。支持所有HTTP方法和路径。
Tool call template
Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {
"method": "<method>",
"path": "<path>"
},
"name": "api_call"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| method | Yes | HTTP方法 | |
| path | Yes | API路径,例如: /users/{id} 或 /posts | |
| pathParams | No | 路径参数,例如: {"id": "123"} | |
| queryParams | No | 查询参数,例如: {"limit": 10, "offset": 0} | |
| headers | No | 请求头,例如: {"Authorization": "Bearer token"} | |
| body | No | 请求体数据(用于POST/PUT等方法) |
Implementation Reference
- src/index.js:504-617 (handler)The primary handler function for the 'api_call' tool. It destructures the input arguments, builds the request using buildUnifiedApiRequest, performs an HTTP fetch request with timeout and retry logic, handles JSON/text responses, and returns the response details.
async function executeUnifiedApiCall(args) { const { method, path, pathParams = {}, queryParams = {}, headers = {}, body, } = args; if (!method || !path) { throw new McpError(ErrorCode.InvalidParams, "method和path参数是必需的"); } let lastError; for (let attempt = 1; attempt <= config.http.maxRetries; attempt++) { try { const { url, headers: requestHeaders, body: requestBody, } = buildUnifiedApiRequest( method, path, pathParams, queryParams, headers, body ); if (config.logging.enableConsole) { console.error(`🚀 发起API调用: ${method.toUpperCase()} ${url}`); } const controller = new AbortController(); const timeoutId = setTimeout( () => controller.abort(), config.http.timeout ); try { const response = await fetch(url, { method: method.toUpperCase(), headers: requestHeaders, body: requestBody, signal: controller.signal, }); clearTimeout(timeoutId); const contentType = response.headers.get("content-type"); let responseData; if (contentType && contentType.includes("application/json")) { responseData = await response.json(); } else { responseData = await response.text(); } if (config.logging.enableConsole) { console.error( `✅ API调用成功: ${response.status} ${response.statusText}` ); } return { content: [ { type: "text", text: `状态码: ${response.status} ${ response.statusText }\n内容类型: ${ contentType || "unknown" }\n响应数据: ${JSON.stringify(responseData, null, 2)}`, }, ], }; } catch (fetchError) { clearTimeout(timeoutId); if (fetchError.name === "AbortError") { throw new Error(`请求超时 (${config.http.timeout}ms)`); } throw fetchError; } } catch (error) { lastError = error; if (config.logging.enableConsole) { console.error( `🔄 API调用失败 (尝试 ${attempt}/${config.http.maxRetries}):`, error.message ); } if (attempt === config.http.maxRetries || error instanceof McpError) { break; } await delay(config.http.retryDelay * attempt); } } if (lastError instanceof McpError) { throw lastError; } throw new McpError( ErrorCode.InternalError, `API调用失败: ${lastError.message}` ); } - src/index.js:269-307 (schema)The schema definition for the 'api_call' tool, including name, description, and detailed inputSchema specifying properties for HTTP method, path, pathParams, queryParams, headers, body, with required fields.
{ name: "api_call", description: `调用${swaggerDoc.info.title} API的通用工具。支持所有HTTP方法和路径。`, inputSchema: { type: "object", properties: { method: { type: "string", enum: ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"], description: "HTTP方法", }, path: { type: "string", description: "API路径,例如: /users/{id} 或 /posts", }, pathParams: { type: "object", description: '路径参数,例如: {"id": "123"}', additionalProperties: true, }, queryParams: { type: "object", description: '查询参数,例如: {"limit": 10, "offset": 0}', additionalProperties: true, }, headers: { type: "object", description: '请求头,例如: {"Authorization": "Bearer token"}', additionalProperties: true, }, body: { type: "object", description: "请求体数据(用于POST/PUT等方法)", additionalProperties: true, }, }, required: ["method", "path"], }, }, - src/index.js:832-852 (registration)The MCP CallTool request handler registration. It uses a switch statement on the tool name to dispatch 'api_call' calls to the executeUnifiedApiCall handler function.
server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { switch (name) { case "api_call": return await executeUnifiedApiCall(args); case "api_list_endpoints": return await listEndpoints(args); case "api_get_endpoint_info": return await getEndpointDetails(args); default: throw new McpError(ErrorCode.InvalidRequest, `未知工具: ${name}`); } } catch (error) { if (error instanceof McpError) { throw error; } throw new McpError(ErrorCode.InternalError, error.message); } }); - src/index.js:824-829 (registration)The MCP ListTools request handler registration, which dynamically generates and returns the list of available tools, including 'api_call', by calling createUnifiedApiTools().
server.setRequestHandler(ListToolsRequestSchema, async () => { const tools = createUnifiedApiTools(); return { tools: tools, }; }); - src/index.js:351-395 (helper)Helper function used by the api_call handler to construct the complete request object (URL with path/query params, headers, body) from the input arguments.
function buildUnifiedApiRequest( method, path, pathParams = {}, queryParams = {}, headers = {}, body = null ) { const baseUrl = global.baseUrl; // 处理路径参数 let url = baseUrl + path; for (const [key, value] of Object.entries(pathParams)) { url = url.replace(`{${key}}`, encodeURIComponent(value)); } // 处理查询参数 const query = new URLSearchParams(); for (const [key, value] of Object.entries(queryParams)) { if (value !== undefined && value !== null) { query.append(key, value); } } if (query.toString()) { url += "?" + query.toString(); } // 处理请求头 const requestHeaders = { "User-Agent": config.http.userAgent, ...headers, }; // 处理请求体 let requestBody = null; if (body && (method === "POST" || method === "PUT" || method === "PATCH")) { requestBody = typeof body === "string" ? body : JSON.stringify(body); if (!requestHeaders["Content-Type"]) { requestHeaders["Content-Type"] = "application/json"; } } return { url, headers: requestHeaders, body: requestBody }; }