npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@counterposition/pi-web-search

v0.10.0

Published

Multi-provider web search and markdown page fetch for Pi

Readme

Pi Web Search

A Pi extension that gives the agent two tools for working with the open web:

  1. web_search for querying multiple search providers with automatic fallback.
  2. web_fetch for reading pages as clean markdown.

The extension manages four search backends (Brave, Tavily, Exa, Parallel) behind a single interface. It works with no API keys: Parallel's free search tier is used when no other provider is configured. It selects the best available provider for each request based on the capabilities the request needs, falls back on transient failures, and tells the agent when a result has been degraded. Page fetching is backed by Jina Reader.

Install

pi install npm:@counterposition/pi-web-search

Needs Pi 1.2.0 or newer.

Tools

web_search

Returns titles, URLs, snippets, and dates. Parameters:

| Parameter | Description | | ------------- | -------------------------------------------------------------------------------------------------------------- | | query | Search query. | | depth | basic (default) returns snippets. thorough uses content-capable search and may include one inline excerpt. | | freshness | Optional recency filter: day, week, month, or year. | | domains | Optional allowlist of bare hostnames to restrict results (max 10). | | max_results | 1--20, default 5. |

web_fetch

Fetches a URL through Jina Reader and returns the page content as markdown. Long pages are paginated: use offset and max_chars to page through content in 8,000-character windows by default (up to 20,000 per call). Fetched pages are cached in an LRU cache (20 entries, 5-minute TTL) so repeated reads of the same URL within a session are free.

In codemode scripts, both tools return objects instead of text: search results with their provider and filters, or a page chunk with nextOffset and hasMore.

Providers

Each search provider has different capabilities. The extension routes requests to the provider best suited for the job:

| Provider | Capabilities | Best for | | ------------ | ------------------------------------------------------------------------ | --------------------------------------------- | | Brave | search, freshness | Fast basic queries; time-sensitive searches | | Tavily | search, content, semantic, freshness, domain filter, dates | Thorough searches; domain-scoped research | | Exa | search, content, semantic, freshness, domain filter, dates | Thorough searches; domain-scoped research | | Parallel | search, content, semantic, dates; freshness and domain filter with a key | Zero-config default; one key for every search | | Jina | page fetch | Reading full pages as markdown |

How provider resolution works: When a search comes in, the extension ranks available providers by how well they match the request. A thorough search needs the content capability, so Tavily and Exa are preferred. A basic search with a freshness filter prefers Brave. Parallel is always ranked last, so it only serves a request when no other configured provider can. If the top-ranked provider fails transiently (network error, rate limit), the next provider in the ranking is tried. If no provider can serve the requested depth, a thorough search degrades to basic and the agent is told.

You can override the automatic ranking by setting a preferred provider per depth level (see Settings below).

Configuration

API keys

No key is required to get started. Keys can be set as environment variables or in the global Pi settings file (~/.pi/agent/settings.json under webSearch.apiKeys). Project-level API keys are intentionally ignored.

| Variable | Provider | Required | | ------------------ | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | BRAVE_API_KEY | Brave Search | For basic/fresh searches | | TAVILY_API_KEY | Tavily | For thorough searches | | EXA_API_KEY | Exa | For thorough searches | | PARALLEL_API_KEY | Parallel | Optional (free tier works without a key; a key adds native freshness and domain filters and higher rate limits) | | JINA_API_KEY | Jina Reader | Optional (works without a key at lower rate limits) |

Without any keys, searches go to Parallel's free tier, which is rate-limited and only approximates freshness and domain filters. For heavier use, set PARALLEL_API_KEY alone (it serves basic and thorough searches), or BRAVE_API_KEY plus either TAVILY_API_KEY or EXA_API_KEY.

Settings

Optional overrides in settings.json (global or project-level) under webSearch:

{
  "webSearch": {
    "preferredBasicProvider": "brave",
    "preferredThoroughProvider": "tavily"
  }
}

When set, the preferred provider is tried first for that depth level before falling back to the default ranking.

Security

The extension takes two precautions around untrusted web content:

  • SSRF protection. web_fetch validates URLs before fetching. Private and reserved IP ranges (RFC 1918, link-local, loopback), cloud metadata endpoints, and .local/.internal hostnames are all blocked. Only http and https schemes are allowed; embedded credentials are rejected.
  • Keyless search goes to Parallel. With no search keys configured, queries are sent to Parallel's free endpoint under Parallel's terms.
  • Prompt injection mitigation. The extension appends a system prompt instructing the agent to treat web content as untrusted data, not as instructions to follow.