mcp-omnisearch
Version:
MCP server for integrating Omnisearch with LLMs
89 lines (88 loc) • 4.44 kB
JavaScript
import { http_json } from '../../../common/http.js';
import { ErrorType, ProviderError, } from '../../../common/types.js';
import { handle_provider_error, retry_with_backoff, sanitize_query, validate_api_key, } from '../../../common/utils.js';
import { config } from '../../../config/env.js';
export class KagiEnrichmentProvider {
constructor() {
this.name = 'kagi_enrichment';
this.description = 'Provides supplementary content from specialized indexes (Teclis for web, TinyGem for news). Ideal for discovering non-mainstream results and enriching content with specialized knowledge.';
}
async enhance_content(content) {
const api_key = validate_api_key(config.enhancement.kagi_enrichment.api_key, this.name);
const enrich_request = async () => {
try {
// Try both web and news endpoints
const [webData, newsData] = await Promise.all([
http_json(this.name, `https://kagi.com/api/v0/enrich/web?${new URLSearchParams({
q: sanitize_query('artificial intelligence software development'),
limit: '5',
})}`, {
method: 'GET',
headers: {
Authorization: `Bot ${api_key}`,
Accept: 'application/json',
},
signal: AbortSignal.timeout(config.enhancement.kagi_enrichment.timeout),
}),
http_json(this.name, `https://kagi.com/api/v0/enrich/news?${new URLSearchParams({
q: sanitize_query('artificial intelligence code generation testing'),
limit: '5',
})}`, {
method: 'GET',
headers: {
Authorization: `Bot ${api_key}`,
Accept: 'application/json',
},
signal: AbortSignal.timeout(config.enhancement.kagi_enrichment.timeout),
}),
]);
if (!webData?.data || !newsData?.data) {
throw new ProviderError(ErrorType.API_ERROR, 'Unexpected response: missing data from enrichment endpoints', this.name);
}
// Combine and filter results
const allData = [...webData.data, ...newsData.data].filter((result) =>
// Filter for results about software/development/AI
result.snippet?.toLowerCase().includes('software') ||
result.snippet?.toLowerCase().includes('develop') ||
result.snippet?.toLowerCase().includes('programming') ||
result.snippet?.toLowerCase().includes('code') ||
result.snippet
?.toLowerCase()
.includes('artificial intelligence') ||
result.snippet?.toLowerCase().includes('ai'));
// Clean and combine snippets
const enhanced_content = allData
.map((result) => result.snippet)
.filter(Boolean)
.map((snippet) =>
// Fix HTML entities
snippet
.replace(/'/g, "'")
.replace(/"/g, '"')
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>'))
.join('\n\n');
return {
original_content: content,
enhanced_content,
enhancements: [
{
type: 'content_enrichment',
description: 'Added supplementary information from Teclis (web) and TinyGem (news) specialized indexes',
},
],
sources: allData.map((result) => ({
title: result.title,
url: result.url,
})),
source_provider: this.name,
};
}
catch (error) {
handle_provider_error(error, this.name, 'enrich content');
}
};
return retry_with_backoff(enrich_request);
}
}