Skip to main content
Glama

Web-curl MCP Server

rest-client.tsβ€’4.75 kB
// Define the interface for the fetch_api tool arguments export interface FetchApiArgs { url: string; method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS'; headers?: Record<string, string>; body?: any; // Can be string, Buffer, stream, or URLSearchParams timeout?: number; // Timeout in milliseconds limit: number; // Maximum number of characters to return in the response body (required) } // Validate the arguments for fetch_api tool export const isValidFetchApiArgs = (args: any): args is FetchApiArgs => { if (typeof args !== 'object' || args === null) return false; if (typeof args.url !== 'string') return false; if (!['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'].includes(args.method)) return false; if (args.headers !== undefined && (typeof args.headers !== 'object' || args.headers === null || Array.isArray(args.headers))) return false; // body can be of various types, so a simple check might not be sufficient, // but for now, we'll assume it's provided correctly if it exists. if (args.timeout !== undefined && typeof args.timeout !== 'number') return false; if (args.limit === undefined || typeof args.limit !== 'number') return false; // limit is required and must be a number return true; }; export interface FetchApiResponse { status: number; statusText: string; headers: Record<string, string>; body: any; ok: boolean; url: string; bodyLength?: number; // length of the un-truncated body (characters) truncated?: boolean; // whether the body was truncated to satisfy limit } // Function to make the API request export const fetchApi = async (args: FetchApiArgs): Promise<FetchApiResponse> => { const { url, method, headers, body, timeout = 60000, limit } = args; const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), timeout); try { const options: RequestInit = { method, headers, signal: controller.signal, // The `timeout` option is specific to `node-fetch` and not part of the standard `RequestInit`. // The timeout logic is now handled manually using AbortController. }; if (body !== undefined) { if (typeof body === 'object' && headers && headers['Content-Type'] === 'application/json') { options.body = JSON.stringify(body); } else { options.body = body; // Works for string, Buffer, FormData, URLSearchParams } } const response: Response = await fetch(url, options); clearTimeout(timeoutId); let responseBody: any; const contentType = response.headers.get('content-type'); if (contentType && contentType.includes('application/json')) { responseBody = await response.json(); } else if (contentType && (contentType.includes('text/') || contentType.includes('application/xml') || contentType.includes('application/xhtml+xml'))) { responseBody = await response.text(); } else { // For binary data or unknown content types, try to get as buffer then base64 encode try { const buffer = await response.arrayBuffer(); responseBody = Buffer.from(buffer).toString('base64'); } catch (e) { responseBody = 'Could not parse body (binary or unknown content type)'; } } const responseHeaders: Record<string, string> = {}; response.headers.forEach((value, name) => { responseHeaders[name] = value; }); // Enforce output limit: convert body to string for length measurement/truncation. let fullBodyString: string; try { if (typeof responseBody === 'string') { fullBodyString = responseBody; } else { fullBodyString = JSON.stringify(responseBody); } } catch (e) { fullBodyString = String(responseBody); } const bodyLength = fullBodyString.length; let truncated = false; let finalBody: any = responseBody; if (typeof limit === 'number' && bodyLength > limit) { // When truncation is necessary, return a string truncated to 'limit' characters. finalBody = fullBodyString.substring(0, limit); truncated = true; } else { // If not truncated and original was JSON-parsed, keep original parsed object, // otherwise keep the string. finalBody = responseBody; } return { status: response.status, statusText: response.statusText, headers: responseHeaders, body: finalBody, ok: response.ok, url: response.url, bodyLength, truncated, }; } catch (error: any) { clearTimeout(timeoutId); if (error.name === 'AbortError') { throw new Error(`Request timed out after ${timeout / 1000} seconds`); } throw error; } };

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rayss868/MCP-Web-Curl'

If you have feedback or need assistance with the MCP directory API, please join our Discord server