
Research
/Security News
PolinRider Spreads Through Compromised GitHub Accounts and Packagist
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.
Unified multi-provider web search as a CLI, MCP server, and library (OpenAI, Google Custom Search, Gemini)
Web search using the API keys of multiple providers behind a single, unified interface. Bring whichever provider key you already have and search the web — either from your terminal (CLI mode) or from an MCP client such as an editor or agent (MCP server mode). Both modes share the same core search logic.
webseek normalizes two fundamentally different kinds of "web search":
| Provider | Kind | Output |
|---|---|---|
google | SERP-style (Google Custom Search) | a ranked list of links |
openai | LLM-grounded (Responses API web_search) | a synthesized answer + citations |
gemini | LLM-grounded (Grounding with Google Search) | a synthesized answer + citations |
The Gemini provider supports two backends that share the same request/response
shape: the Gemini Developer API (gemini-api, default) and Vertex AI
express mode (vertex-express).
npm install -g webseek # install the CLI globally
npx webseek search "..." -p google # or run without installing
pnpm install
pnpm build # dual-format (ESM + CJS) build via tsdown; exposes the `webseek` bin
During development you can run without building via pnpm dev -- <args> (runs
the TypeScript source through tsx).
webseek search <query...> --provider <openai|google|gemini> [options]
Options for search:
| Flag | Description |
|---|---|
-p, --provider <name> | openai | google | gemini (required) |
-n, --max-results <n> | Desired number of results (SERP providers) |
-m, --model <name> | Model override (openai, gemini) |
--gemini-backend <b> | gemini-api (default) | vertex-express |
--json | Emit normalized JSON instead of text |
--raw | Include the provider's raw response |
Examples:
webseek search "best static site generators 2026" -p google -n 5
webseek search "summarize the latest TypeScript release" -p openai
webseek search "who won euro 2024" -p gemini --gemini-backend vertex-express --json
Start a Model Context Protocol server over
stdio that exposes a single web_search tool:
webseek mcp
Register it with an MCP client, e.g.:
{
"mcpServers": {
"webseek": {
"command": "webseek",
"args": ["mcp"],
"env": { "GEMINI_API_KEY": "..." },
},
},
}
The web_search tool accepts { query, provider, maxResults?, model?, geminiBackend?, includeRaw? }
and returns the normalized result as JSON.
webseek is published as a dual-format package (ESM + CJS), so it can be
imported as a library in addition to running as a CLI/MCP server:
import { runSearch, WebseekError } from "webseek";
const result = await runSearch({ provider: "google", query: "best static site generators 2026" });
console.log(result.results);
CommonJS consumers can require it the same way:
const { runSearch } = require("webseek");
To embed the web_search tool into your own MCP server, use the
createWebSearchTool factory exported from the same entry point.
API keys are read from environment variables only (never from flags), so they don't leak into shell history or process listings.
| Provider | Environment variables |
|---|---|
openai | OPENAI_API_KEY |
google | GOOGLE_API_KEY, GOOGLE_CSE_CX (Programmable Search Engine ID) |
gemini (gemini-api) | GEMINI_API_KEY (falls back to GOOGLE_API_KEY) |
gemini (vertex-express) | VERTEX_API_KEY |
--max-results values paginate and consume more quota.Searches: line;
the source URIs Gemini returns are temporary redirect links.src/
index.ts public library entry (runSearch, types, createWebSearchTool)
cli/ commander program: `search` and `mcp` commands
mcp/ MCP server + the web_search tool
lib/ runSearch — the shared core called by both CLI and MCP
providers/ per-provider implementations (openai, google-cse, gemini)
config/ credential + base-URL resolution from env
output/ text / JSON formatting
utils/ logger, error formatter
e2e/ end-to-end tests (spawn the CLI / drive the MCP server)
pnpm cicheck # format check, lint, typecheck, unit tests, spelling, secrets
pnpm test:e2e # end-to-end tests (CLI subprocess + MCP stdio client)
Publishing to npm is automated. To cut a new version:
draft-release skill — it bumps the version on a release/vX.Y.Z
branch, opens a PR, and creates a draft GitHub release.main.Publishing the release triggers
.github/workflows/publish.yml, which verifies
the tag matches package.json and runs pnpm publish. Authentication uses npm
trusted publishing (OIDC) — no token secret is required, and provenance is
generated automatically. Configure the trusted publisher for the package once on
npmjs.com, pointing it at this repository's publish.yml workflow.
FAQs
Unified multi-provider web search as a CLI, MCP server, and library (OpenAI, Google Custom Search, Gemini)
The npm package webseek receives a total of 24 weekly downloads. As such, webseek popularity was classified as not popular.
We found that webseek demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.

Company News
Allow myself to introduce... myself.