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

@pi-vault/pi-tools

v0.5.1

Published

Pi extension for web search, content extraction, documentation lookup, and deep research tools

Readme

@pi-vault/pi-tools

npm version Quality Node >= 24.15.0 License: MIT

Web search, content extraction, documentation lookup, and deep research tools for Pi.

What's new in 0.5.1

TinyFish provider added. TINYFISH_API_KEY enables keyless search and fetch through the new TinyFish provider — see the provider table for setup.

Internal architecture deepened. Search filter enforcement, provider catalog, operation policy, runtime lifecycle, and content extraction now share clearer seams. No public API changes.

Install

pi install npm:@pi-vault/pi-tools

Reload Pi after installation:

/reload

The extension can use keyless providers such as Jina. DuckDuckGo also works without an API key after you install the ddgs CLI:

uv tool install ddgs
# or: pip install ddgs

Run /tools in Pi to open the dashboard and configure more providers. The dashboard detects available environment variables and can write the global config for you.

/tools

Use it

Ask Pi in plain language. The extension registers up to seven tools, depending on which providers you configure:

| Tool | Use it for | | ----------------- | ------------------------------------------------------------------- | | web_search | Current information, releases, and live web results | | web_fetch | Web pages, PDFs, GitHub URLs, YouTube videos, and local video files | | web_read | Full text from a large response using its contentId | | code_search | Programming examples and technical documentation through Exa | | web_docs_search | Finding a Context7 library ID | | web_docs_fetch | Focused, version-aware Context7 documentation | | web_research | Multi-source Exa research and saved findings reports |

Search the web

Search the web for the latest Vitest mocking documentation.
Search npm release notes after 2026-01-01, using only npmjs.com.
Search for current SQLite performance guidance and combine multiple providers.

web_search supports provider selection, domain filters, publication dates, compact results, and optional multi-provider fusion. If a provider fails, Pi Tools tries the next eligible provider unless the request was cancelled.

Fetch pages and files

Fetch https://example.com/spec and summarize the requirements.
Fetch these URLs and compare them: https://a.dev/docs, https://b.dev/docs
Fetch https://example.com/page in raw mode.

web_fetch accepts one URL or up to 20 URLs. It extracts readable HTML, PDFs, GitHub repositories and files, and some Next.js RSC pages. It can fall back to Jina, Gemini, or a configured fetch provider when direct extraction is not enough.

Large responses include a contentId. Ask Pi to pass that ID to web_read for the full text. Stored content lasts for the current session.

Work with YouTube, video, and PDFs

Fetch https://www.youtube.com/watch?v=VIDEO_ID and summarize the transcript.
Extract 4 frames from https://www.youtube.com/watch?v=VIDEO_ID between 02:00 and 03:00.
Analyze /absolute/path/to/demo.mp4 and list the main steps shown.
Fetch https://example.com/scanned-report.pdf and summarize it.

YouTube transcript extraction can use Gemini or Perplexity. Frame extraction uses yt-dlp and ffmpeg. Local video analysis uses Gemini. Scanned PDF OCR uses pdftoppm and either the active model's image support or Gemini as a fallback.

Look up code and library documentation

Find TypeScript examples for AbortSignal timeout handling.
Find the React library in Context7 for hooks documentation.
Fetch Context7 docs for /facebook/react about useState hooks.

Use web_docs_search before web_docs_fetch. Include a focused question, and pin a version in the library ID when reproducibility matters, such as /vercel/[email protected].

Run deep research

Research the trade-offs between PostgreSQL logical replication and CDC. Save a findings report to docs/replication.md.

web_research supports lite, standard, and full modes. It requires EXA_API_KEY. Pass outputPath to save a report and rawOutputPath to keep the source metadata.

Manage providers

Run /tools to open the interactive dashboard. The dashboard has three tabs:

  • Providers — toggle a provider on or off, set a credential, change the default provider, and run a test in place.
  • Status — per-provider budget state, session outcomes (success/failure), and average latency.
  • Activity — recent provider events streamed live.

Switch between global and project scope inside the dashboard. Project scope requires the project to be trusted or to already have a .pi/tools.json.

Provider configuration refreshes automatically every 30 seconds. The dashboard's reload action triggers an immediate refresh.

Available providers

| Provider | Capabilities | Setup | | ----------------- | ----------------------------- | ---------------------------------- | | Brave | Search | BRAVE_API_KEY | | Brave LLM | Search | BRAVE_API_KEY | | Context7 | Docs | CONTEXT7_API_KEY | | DuckDuckGo | Search | ddgs CLI | | Exa | Search, fetch, code, research | EXA_API_KEY | | fastCRW | Search | FASTCRW_API_KEY | | Firecrawl | Search, fetch | API key optional | | Jina | Search, fetch | API key optional | | LangSearch | Search | LANGSEARCH_API_KEY | | Linkup | Search | LINKUP_API_KEY | | Marginalia | Search | No API key | | Ollama | Search, fetch | Local Ollama server | | OpenAI Codex | Search | Pi /login OAuth | | OpenAI web search | Search | OPENAI_API_KEY | | Parallel | Search, fetch | PARALLEL_API_KEY | | Perplexity | Search, YouTube fallback | PERPLEXITY_API_KEY | | SearXNG | Search | SearXNG instance, API key optional | | Serper | Search | SERPER_API_KEY | | Sofya | Search, fetch | SOFYA_API_KEY | | Tavily | Search, fetch | TAVILY_API_KEY | | TinyFish | Search, fetch | TINYFISH_API_KEY | | WebSearchAPI | Search | WEBSEARCHAPI_API_KEY | | You.com | Search | YOUCOM_API_KEY |

Pi Tools ranks providers by tier and availability, and optionally by recent session performance. Automatic selection skips exhausted hard budgets. Provider-specific date and domain filters depend on the upstream API; declared post-filters are applied locally where possible, and a request is rejected when no eligible provider can enforce its filters.

openai-codex uses the active Pi OAuth session. Run /login and select openai-codex before using it; the provider no longer accepts OPENAI_API_KEY as a fallback. To search with OPENAI_API_KEY instead, configure openai-web-search.

Configure files and credentials

The global config is $PI_CODING_AGENT_DIR/extensions/tools.json; when the variable is unset, Pi supplies its agent directory. A project .pi/tools.json overrides it. Pi Tools deep-merges project settings, global settings, and built-in defaults in that order.

Minimal config

A starter configuration with one keyed search provider and a few keyless defaults:

{
  "defaultProvider": "auto",
  "providers": {
    "exa": {
      "enabled": true,
      "apiKey": "EXA_API_KEY"
    },
    "duckduckgo": { "enabled": true },
    "firecrawl": { "enabled": true },
    "jina": { "enabled": true },
    "marginalia": { "enabled": true },
    "openai-codex": { "enabled": true }
  }
}

A provider apiKey can be:

  • an environment-variable name, such as "EXA_API_KEY"
  • a literal key
  • a shell command prefixed with !, such as "!op read op://pi/exa/api-key"

Shell-command credentials are cached until the next config refresh. Sensitive fields in project config are ignored until Pi marks the project as trusted.

Full configuration reference

The complete shape of the merged configuration. Every field shown here is honored by the extension; omit any section to use the built-in default.

{
  "defaultProvider": "auto",
  "selectionStrategy": "auto",
  "providers": {
    "brave": {
      "enabled": false,
      "apiKey": "BRAVE_API_KEY"
    },
    "brave-llm": {
      "enabled": false,
      "apiKey": "BRAVE_API_KEY",
      "tokenBudget": 4096
    },
    "context7": {
      "enabled": false,
      "apiKey": "CONTEXT7_API_KEY"
    },
    "duckduckgo": {
      "enabled": true,
      "ddgsBackend": "api",
      "ddgsRegion": "us-en"
    },
    "exa": {
      "enabled": false,
      "apiKey": "EXA_API_KEY"
    },
    "fastcrw": {
      "enabled": false,
      "apiKey": "FASTCRW_API_KEY",
      "baseUrl": "https://api.fastcrw.com"
    },
    "firecrawl": {
      "enabled": true
    },
    "jina": {
      "enabled": true
    },
    "langsearch": {
      "enabled": false,
      "apiKey": "LANGSEARCH_API_KEY"
    },
    "linkup": {
      "enabled": false,
      "apiKey": "LINKUP_API_KEY",
      "depth": "standard"
    },
    "marginalia": {
      "enabled": true
    },
    "ollama": {
      "enabled": false,
      "baseUrl": "http://localhost:11434"
    },
    "openai-codex": {
      "enabled": true
    },
    "openai-web-search": {
      "enabled": false,
      "apiKey": "OPENAI_API_KEY",
      "model": "gpt-4.1-mini"
    },
    "parallel": {
      "enabled": false,
      "apiKey": "PARALLEL_API_KEY"
    },
    "perplexity": {
      "enabled": false,
      "apiKey": "PERPLEXITY_API_KEY",
      "model": "sonar"
    },
    "searxng": {
      "enabled": false,
      "instanceUrl": "http://localhost:8080"
    },
    "serper": {
      "enabled": false,
      "apiKey": "SERPER_API_KEY"
    },
    "sofya": {
      "enabled": false,
      "apiKey": "SOFYA_API_KEY",
      "searchDepth": "basic",
      "topic": "general"
    },
    "tavily": {
      "enabled": false,
      "apiKey": "TAVILY_API_KEY"
    },
    "tinyfish": {
      "enabled": true,
      "apiKey": "TINYFISH_API_KEY"
    },
    "websearchapi": {
      "enabled": false,
      "apiKey": "WEBSEARCHAPI_API_KEY"
    },
    "youcom": {
      "enabled": false,
      "apiKey": "YOUCOM_API_KEY"
    }
  },
  "github": {
    "enabled": true,
    "maxRepoSizeMB": 350,
    "cloneTimeoutSeconds": 30
  },
  "combine": {
    "enabled": false,
    "mode": "targeted",
    "targetBackends": 3,
    "k": 60
  },
  "gemini": {
    "apiKey": "GEMINI_API_KEY",
    "baseUrl": "https://generativelanguage.googleapis.com",
    "cloudflareApiKey": "CLOUDFLARE_API_KEY",
    "allowBrowserCookies": false,
    "chromeProfile": "Default"
  },
  "youtube": {
    "enabled": true,
    "preferredModel": "gemini-3-flash-preview"
  },
  "video": {
    "enabled": true,
    "preferredModel": "gemini-3-flash-preview",
    "maxSizeMB": 50
  },
  "pdf": {
    "ocrEnabled": true,
    "ocrMaxPages": 5,
    "ocrDpi": 150
  },
  "deepResearch": {
    "enabled": true,
    "modeDefaults": {
      "lite": {
        "type": "deep-lite",
        "numResults": 15,
        "textMaxCharacters": 10000,
        "timeoutSeconds": 300,
        "highlightsMaxCharacters": 600,
        "highlightNumSentences": 3,
        "highlightsPerUrl": 1
      },
      "standard": {
        "type": "deep-reasoning",
        "numResults": 50,
        "textMaxCharacters": 16000,
        "timeoutSeconds": 600,
        "highlightsMaxCharacters": 900,
        "highlightNumSentences": 4,
        "highlightsPerUrl": 2
      },
      "full": {
        "type": "deep-reasoning",
        "numResults": 100,
        "textMaxCharacters": 24000,
        "timeoutSeconds": 1800,
        "highlightsMaxCharacters": 1200,
        "highlightNumSentences": 5,
        "highlightsPerUrl": 3
      }
    },
    "outputSchema": null,
    "guidance": {}
  },
  "guidance": {
    "web_search": {},
    "web_fetch": {},
    "web_read": {},
    "code_search": {},
    "web_docs_search": {},
    "web_docs_fetch": {}
  },
  "ssrf": {
    "allowRanges": []
  }
}

Provider budgets

Every built-in provider has a default budget. Omit it to keep that default, or replace the complete object for one provider:

{
  "providers": {
    "exa": {
      "budget": {
        "mode": "hard",
        "limit": 10,
        "period": "month",
        "unit": "usd",
        "pool": "exa"
      }
    },
    "jina": { "budget": { "mode": "managed" } },
    "duckduckgo": { "budget": { "mode": "unlimited" } }
  }
}

Hard budgets accept day, month, or lifetime periods and request, credit, or usd units. Day and month boundaries use UTC calendar time. A pool shares one counter across providers; every provider in that pool must use the same limit, period, and unit. Invalid or conflicting overrides are ignored as a group.

managed delegates limits to the provider or plan. unlimited means Pi Tools does not meter the provider. Local reservations are saved before requests to $PI_CODING_AGENT_DIR/cache/pi-tools/usage.json. Version 2 keeps compatible current-month legacy request counts for non-shared monthly budgets; monthlyQuota settings are not migrated.

Enforcement is atomic within one Pi process. Separate concurrent Pi processes can briefly exceed the same local ceiling; interprocess locking is intentionally deferred until that becomes an observed need.

Useful advanced settings:

  • selectionStrategy: auto or best-performing
  • combine: optional reciprocal-rank fusion across eligible providers
  • github: GitHub repository size and clone timeout limits
  • gemini: API key, custom base URL, Cloudflare AI Gateway key, and browser-cookie access
  • youtube and video: enablement, preferred Gemini model, and local video size limit
  • pdf: OCR enablement, page limit, and rasterization DPI
  • deepResearch: mode defaults, structured output schema, and report guidance
  • guidance: prompt overrides for individual tools
  • ssrf.allowRanges: explicit CIDR exceptions for trusted private networks

To use Gemini browser cookies, set PI_ALLOW_BROWSER_COOKIES=1 or enable gemini.allowBrowserCookies in the global config. Project config cannot enable sensitive cookie or network access unless the project is trusted.

Optional command-line tools

| Tool | Enables | | ----------------------- | ------------------------------------------------------- | | ddgs | Keyless DuckDuckGo search | | gh | Richer GitHub repository access when Pi chooses the CLI | | yt-dlp | YouTube stream lookup and frame extraction | | ffmpeg | YouTube and local video frame extraction | | pdftoppm from Poppler | Scanned PDF rasterization for OCR |

Development

pnpm install
pnpm check
pnpm release:check

Changelog

See CHANGELOG.md for release notes.

License

MIT. See LICENSE.