compiler/packages/react-mcp-server/src/utils/algolia.ts TYPESCRIPT 120 lines View on github.com → Search inside
1/**2 * Copyright (c) Meta Platforms, Inc. and affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 */78import type {DocSearchHit, InternalDocSearchHit} from '../types/algolia';9import {liteClient, type Hit, type SearchResponse} from 'algoliasearch/lite';1011// https://github.com/reactjs/react.dev/blob/55986965fbf69c2584040039c9586a01bd54eba7/src/siteConfig.js#L15-L1912const ALGOLIA_CONFIG = {13  appId: '1FCF9AYYAT',14  apiKey: '1b7ad4e1c89e645e351e59d40544eda1',15  indexName: 'beta-react',16};1718export const ALGOLIA_CLIENT = liteClient(19  ALGOLIA_CONFIG.appId,20  ALGOLIA_CONFIG.apiKey,21);2223export function printHierarchy(24  hit: DocSearchHit | InternalDocSearchHit,25): string {26  let val = `${hit.hierarchy.lvl0} > ${hit.hierarchy.lvl1}`;27  if (hit.hierarchy.lvl2 != null) {28    val = val.concat(` > ${hit.hierarchy.lvl2}`);29  }30  if (hit.hierarchy.lvl3 != null) {31    val = val.concat(` > ${hit.hierarchy.lvl3}`);32  }33  if (hit.hierarchy.lvl4 != null) {34    val = val.concat(` > ${hit.hierarchy.lvl4}`);35  }36  if (hit.hierarchy.lvl5 != null) {37    val = val.concat(` > ${hit.hierarchy.lvl5}`);38  }39  if (hit.hierarchy.lvl6 != null) {40    val = val.concat(` > ${hit.hierarchy.lvl6}`);41  }42  return val;43}4445export async function queryAlgolia(46  message: string | Array<string>,47): Promise<Array<string>> {48  const {results} = await ALGOLIA_CLIENT.search<DocSearchHit>({49    requests: [50      {51        query: Array.isArray(message) ? message.join('\n') : message,52        indexName: ALGOLIA_CONFIG.indexName,53        attributesToRetrieve: [54          'hierarchy.lvl0',55          'hierarchy.lvl1',56          'hierarchy.lvl2',57          'hierarchy.lvl3',58          'hierarchy.lvl4',59          'hierarchy.lvl5',60          'hierarchy.lvl6',61          'content',62          'url',63        ],64        attributesToSnippet: [65          `hierarchy.lvl1:10`,66          `hierarchy.lvl2:10`,67          `hierarchy.lvl3:10`,68          `hierarchy.lvl4:10`,69          `hierarchy.lvl5:10`,70          `hierarchy.lvl6:10`,71          `content:10`,72        ],73        snippetEllipsisText: '…',74        hitsPerPage: 30,75        attributesToHighlight: [76          'hierarchy.lvl0',77          'hierarchy.lvl1',78          'hierarchy.lvl2',79          'hierarchy.lvl3',80          'hierarchy.lvl4',81          'hierarchy.lvl5',82          'hierarchy.lvl6',83          'content',84        ],85      },86    ],87  });88  const firstResult = results[0] as SearchResponse<DocSearchHit>;89  const {hits} = firstResult;90  const deduped = new Map();91  for (const hit of hits) {92    // drop hashes to dedupe properly93    const u = new URL(hit.url);94    if (deduped.has(u.pathname)) {95      continue;96    }97    deduped.set(u.pathname, hit);98  }99  const pages: Array<string | null> = await Promise.all(100    Array.from(deduped.values()).map(hit => {101      return fetch(hit.url, {102        headers: {103          'User-Agent':104            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36',105        },106      }).then(res => {107        if (res.ok === true) {108          return res.text();109        } else {110          console.error(111            `Could not fetch docs: ${res.status} ${res.statusText}`,112          );113          return null;114        }115      });116    }),117  );118  return pages.filter(page => page !== null);119}

Security findings 1

Generic API Key
security

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.