Skip to main content
Glama
Noveum
by Noveum

Get_Unblurred_Image_URL

Retrieve the URL of an unblurred image by providing the unique request ID. This tool simplifies accessing clear visuals from the API-Market MCP Server.

Instructions

This endpoint retrieves the URL of the Unblurred image for a given request ID.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
request_idYesUnique identifier for the request.

Implementation Reference

  • Generic execution handler for all dynamically generated tools. It constructs the HTTP request from the tool ID (method-path), uses input arguments as query params for GET or body for others, calls the API via axios, and returns the JSON response.
    this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { id, name, arguments: params } = request.params; console.error("Received request:", request.params); console.error("Using parameters from arguments:", params); // Find tool by ID or name let tool: Tool | undefined; let toolId: string | undefined; if (id) { toolId = id.trim(); tool = this.tools.get(toolId); } else if (name) { // Search for tool by name for (const [tid, t] of this.tools.entries()) { if (t.name === name) { tool = t; toolId = tid; break; } } } if (!tool || !toolId) { console.error( `Available tools: ${Array.from(this.tools.entries()) .map(([id, t]) => `${id} (${t.name})`) .join(", ")}`, ); throw new Error(`Tool not found: ${id || name}`); } console.error(`Executing tool: ${toolId} (${tool.name})`); try { // Extract method and path from tool ID const [method, ...pathParts] = toolId.split("-"); let path = "/" + pathParts.join("/") .replace(/-/g, "/") .replaceAll('!', "-"); // Ensure base URL ends with slash for proper joining const baseUrl = this.config.apiBaseUrl.endsWith("/") ? this.config.apiBaseUrl : `${this.config.apiBaseUrl}/`; // Remove leading slash from path to avoid double slashes const cleanPath = path.startsWith("/") ? path.slice(1) : path; let url; try { // Validate that the path results in a valid URL // Construct the full URL url = new URL(cleanPath, baseUrl).toString(); } catch (error) { throw new Error(`Invalid path generated from tool ID ${toolId}: ${error.message}`); } // Prepare request configuration this.config.headers = this.config.headers || {}; const contentType = this.headers.get(toolId); if (contentType) { this.config.headers['Content-Type'] = contentType; } const config: any = { method: method.toLowerCase(), url: url, headers: this.config.headers, }; // Handle different parameter types based on HTTP method if (method.toLowerCase() === "get") { // For GET requests, ensure parameters are properly structured if (params && typeof params === "object") { // Handle array parameters properly const queryParams: Record<string, string> = {}; for (const [key, value] of Object.entries(params)) { if (Array.isArray(value)) { // Join array values with commas for query params queryParams[key] = value.join(","); } else if (value !== undefined && value !== null) { // Convert other values to strings queryParams[key] = String(value); } } config.params = queryParams; } } else { // For POST, PUT, PATCH - send as body config.data = params; } console.error("Final request config:", config); try { const response = await axios(config); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { if (axios.isAxiosError(error)) { console.error("Request failed:", { status: error.response?.status, statusText: error.response?.statusText, data: error.response?.data, headers: error.response?.headers, }); throw new Error( `API request failed: ${error.message} - ${JSON.stringify(error.response?.data)}`, ); } throw error; } } catch (error) { if (axios.isAxiosError(error)) { throw new Error(`API request failed: ${error.message}`); } throw error; } });
  • Parses OpenAPI specs from files listed in config.openApiSpec (default: modified_files.txt), iterates over paths and operations, generates toolId from method-cleanPath, tool name from operationId/summary/path with spaces replaced by _, generates inputSchema from parameters and requestBody, and registers the Tool in the internal tools Map.
    private async parseOpenAPISpec(): Promise<void> { const paths = await this.listOfFilePaths() for (const cur_path of paths) { if (!cur_path || cur_path.trim() === '') { console.error('Skipping empty path'); continue; } try { const spec = await this.loadOpenAPISpec(path.resolve(__dirname, cur_path)); // Convert each OpenAPI path to an MCP tool for (const [path, pathItem] of Object.entries(spec.paths)) { if (!pathItem) continue; for (const [method, operation] of Object.entries(pathItem)) { if (method === "parameters" || !operation) continue; const op = operation as OpenAPIV3.OperationObject; // Create a clean tool ID by removing the leading slash and replacing special chars const cleanPath = path.replace(/^\//, ""); const toolId = `${method.toUpperCase()}-${cleanPath}`.replace( /[^a-zA-Z0-9-_]/g, "-", ); const tool: Tool = { name: (op.operationId || op.summary || `${method.toUpperCase()} ${path}`).replace(/\s+/g, "_"), description: op.description || `Make a ${method.toUpperCase()} request to ${path}`, inputSchema: { type: "object", properties: {}, // Add any additional properties from OpenAPI spec }, }; // Add parameters from operation if (op.parameters) { for (const param of op.parameters) { if ("name" in param && "in" in param) { const paramSchema = param.schema as OpenAPIV3.SchemaObject; tool.inputSchema.properties[param.name] = { type: paramSchema.type || "string", description: param.description || `${param.name} parameter`, }; if (param.required) { tool.inputSchema.required = tool.inputSchema.required || []; tool.inputSchema.required.push(param.name); } } } } // Add request body if present (for POST, PUT, etc.) if (op.requestBody) { const requestBody = op.requestBody as OpenAPIV3.RequestBodyObject; const content = requestBody.content; // Usually we'd look for application/json content type if (content?.['application/json']) { this.headers.set(toolId, 'application/json'); const jsonSchema = content['application/json'].schema as OpenAPIV3.SchemaObject; // If it's a reference, we'd need to resolve it // For simplicity, assuming it's an inline schema if (jsonSchema.properties) { // Add all properties from the request body schema for (const [propName, propSchema] of Object.entries(jsonSchema.properties)) { tool.inputSchema.properties[propName] = propSchema; } // Add required properties if defined if (jsonSchema.required) { tool.inputSchema.required = tool.inputSchema.required || []; tool.inputSchema.required.push(...jsonSchema.required); } } } else if (content?.['application/x-www-form-urlencoded']) { this.headers.set(toolId, 'application/x-www-form-urlencoded'); const urlencodedSchema = content['application/x-www-form-urlencoded'].schema as OpenAPIV3.SchemaObject; if (urlencodedSchema.properties) { for (const [propName, propSchema] of Object.entries(urlencodedSchema.properties)) { tool.inputSchema.properties[propName] = propSchema; } if (urlencodedSchema.required) { tool.inputSchema.required = tool.inputSchema.required || []; tool.inputSchema.required.push(...urlencodedSchema.required); } } } } this.tools.set(toolId, tool); } } } catch (error) { console.error(`Error parsing OpenAPI spec from ${cur_path}:`, error); } } }
  • Registers the ListToolsRequestSchema handler that returns all registered tools.
    this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: Array.from(this.tools.values()), }; });
  • The start method which calls parseOpenAPISpec() to register tools before connecting the server.
    async start(): Promise<void> { await this.parseOpenAPISpec(); const transport = new StdioServerTransport(); await this.server.connect(transport); console.error("OpenAPI MCP Server running on stdio"); }
  • Code block where inputSchema for each tool is constructed from OpenAPI operation parameters and requestBody content.
    inputSchema: { type: "object", properties: {}, // Add any additional properties from OpenAPI spec }, }; // Add parameters from operation if (op.parameters) { for (const param of op.parameters) { if ("name" in param && "in" in param) { const paramSchema = param.schema as OpenAPIV3.SchemaObject; tool.inputSchema.properties[param.name] = { type: paramSchema.type || "string", description: param.description || `${param.name} parameter`, }; if (param.required) { tool.inputSchema.required = tool.inputSchema.required || []; tool.inputSchema.required.push(param.name); } } } } // Add request body if present (for POST, PUT, etc.) if (op.requestBody) { const requestBody = op.requestBody as OpenAPIV3.RequestBodyObject; const content = requestBody.content; // Usually we'd look for application/json content type if (content?.['application/json']) { this.headers.set(toolId, 'application/json'); const jsonSchema = content['application/json'].schema as OpenAPIV3.SchemaObject; // If it's a reference, we'd need to resolve it // For simplicity, assuming it's an inline schema if (jsonSchema.properties) { // Add all properties from the request body schema for (const [propName, propSchema] of Object.entries(jsonSchema.properties)) { tool.inputSchema.properties[propName] = propSchema; } // Add required properties if defined if (jsonSchema.required) { tool.inputSchema.required = tool.inputSchema.required || []; tool.inputSchema.required.push(...jsonSchema.required); } } } else if (content?.['application/x-www-form-urlencoded']) { this.headers.set(toolId, 'application/x-www-form-urlencoded'); const urlencodedSchema = content['application/x-www-form-urlencoded'].schema as OpenAPIV3.SchemaObject; if (urlencodedSchema.properties) { for (const [propName, propSchema] of Object.entries(urlencodedSchema.properties)) { tool.inputSchema.properties[propName] = propSchema; } if (urlencodedSchema.required) { tool.inputSchema.required = tool.inputSchema.required || []; tool.inputSchema.required.push(...urlencodedSchema.required); } } } }

Latest Blog Posts

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/Noveum/api-market-mcp-server'

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