mcp-omnisearch
Version:
MCP server for integrating Omnisearch with LLMs
70 lines (69 loc) • 3.1 kB
JavaScript
// Firecrawl Map Provider Implementation
import { ErrorType, ProviderError, } from '../../common/types.js';
import { is_api_key_valid } from '../../common/utils.js';
import { config, FIRECRAWL_API_KEY } from '../../config/env.js';
export class FirecrawlMapProviderImpl {
constructor() {
this.name = 'firecrawl';
this.description = 'Map a website with Firecrawl, discovering all URLs within a domain. Best for site mapping, content discovery, and understanding website structure.';
this.api_url = 'https://api.firecrawl.dev/v1/map';
if (!is_api_key_valid(FIRECRAWL_API_KEY, 'firecrawl')) {
throw new Error('Invalid Firecrawl API key');
}
}
async map_url(url, options) {
try {
const max_depth = options?.max_depth || 2;
// Set timeout
const timeout = config.firecrawl.map.timeout;
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
// Prepare request body
const request_body = {
url,
maxDepth: max_depth,
};
// Call Firecrawl API
const response = await fetch(this.api_url, {
method: 'POST',
headers: {
'Authorization': `Bearer ${FIRECRAWL_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(request_body),
signal: controller.signal,
});
clearTimeout(timeoutId);
// Handle response
if (!response.ok) {
if (response.status === 429) {
throw new ProviderError(ErrorType.RATE_LIMIT, 'Firecrawl rate limit exceeded', this.name);
}
throw new ProviderError(ErrorType.API_ERROR, `Firecrawl API error: ${response.status} ${response.statusText}`, this.name);
}
const data = await response.json();
if (!data.success) {
throw new ProviderError(ErrorType.API_ERROR, `Firecrawl API error: ${data.error || 'Unknown error'}`, this.name);
}
// Process response
return {
urls: data.data.urls || [],
metadata: {
root_url: url,
urls_found: (data.data.urls || []).length,
max_depth,
timestamp: new Date().toISOString(),
},
source_provider: this.name,
};
}
catch (error) {
if (error instanceof Error) {
if (error.name === 'AbortError') {
throw new ProviderError(ErrorType.API_ERROR, `Firecrawl map request timed out after ${config.firecrawl.map.timeout}ms`, this.name);
}
}
throw new ProviderError(ErrorType.PROVIDER_ERROR, `Error mapping URL: ${error instanceof Error ? error.message : String(error)}`, this.name, error);
}
}
}