@pi-vault/pi-tools

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

Packages

Package details

extension

Install @pi-vault/pi-tools from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@pi-vault/pi-tools
Package
@pi-vault/pi-tools
Version
0.5.0
Published
Jul 22, 2026
Downloads
680/mo · 208/wk
Author
lanhhoang
License
MIT
Types
extension
Size
390 KB
Dependencies
5 dependencies · 3 peers
Pi manifest JSON
{
  "extensions": [
    "./src/index.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

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.0

Dashboard replaces typed /tools subcommands. Run /tools to open the interactive dashboard with three tabs: Providers (toggle, key, default, run tests), Status (budgets, session outcomes, latency), and Activity (recent provider events). Typed subcommands such as /tools status, /tools enable, /tools key, /tools test, /tools default, and /tools monitor on|off are no longer supported.

Provider budgets are enforceable. Hard, managed, unlimited, and shared-pool policies replace the old monthlyQuota settings. Budget status is reported per provider in the Status tab.

openai-codex requires Pi OAuth. The OPENAI_API_KEY fallback is gone. Run /login and select openai-codex before using it. To search with OPENAI_API_KEY instead, configure openai-web-search.

Usage persistence moved. Provider usage now lives at $PI_CODING_AGENT_DIR/cache/pi-tools/usage.json using a version 2 UTC-period ledger.

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/next.js@v15.1.8.

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
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; unsupported filters are applied locally where possible.

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"
    },
    "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.