Most search servers hand back results and forget them. Storing scraped content as embeddings means the second and third question on a topic are answered from what you already paid to fetch, and the ordering — newest first, then by similarity — is tuned for research where recency matters. The cost is setup: this wants a Postgres with pgvector, a search key, a scraping key and an embedding backend before the first query runs.
An MCP server that pairs a web search with a similarity search over what it already fetched. Searching scrapes the results; a second tool then extracts the relevant passages from those previous searches by embedding similarity, so a topic can be revisited without hitting the search API again.
- Web search that takes a list of queries at once, with an optional page number defaulting to 1, and scrapes what it finds
- Extraction from previous searches: pass the queries to merge and get back the relevant chunks from what was already stored
- Storage in PostgreSQL with pgvector, using a 1024-dimension embedding column and a similarity function that filters by threshold and orders by date then similarity
- A choice of embedding backend, including a local Ollama server, so embeddings need not go to a hosted provider
Several keys, because the pipeline spans several services: `SEARCHAPI_API_KEY` for search, `FIRECRAWL_API_KEY` for scraping, and an embedding route — `EMBEDDING_URL`, `OLLAMA_URL` and `EMBEDDING_MODEL` for a local server, or `AZURE_OPENAI_ENDPOINT` with `AZURE_OPENAI_API_KEY`, with `VOYAGE_API_KEY` also read from the environment. A PostgreSQL database with the pgvector extension installed, and a `web_search` table plus the matching function created from the SQL in the README. Python with uv: clone, `uv venv`, then `uv pip install -e .`, launched through uv against `main.py`. The project is `parquet_mcp_server` (0.1.0 in pyproject); Smithery can install it for Claude Desktop automatically.
