@amaster.ai/pi-web-access
Pi extension for web search, URL content extraction, and image search (Cloudflare, Tavily, Kimi, DeepSeek, Mimo, Z.AI, DashScope, Unsplash, and more)
Package details
Install @amaster.ai/pi-web-access from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@amaster.ai/pi-web-access- Package
@amaster.ai/pi-web-access- Version
0.1.29- Published
- Oct 20, 2026
- Downloads
- 4,496/mo · 768/wk
- Author
- qianchuan
- License
- Apache-2.0
- Types
- extension
- Size
- 2 MB
- Dependencies
- 2 dependencies · 3 peers
Pi manifest JSON
{
"image": "https://raw.githubusercontent.com/TGYD-helige/pi/master/packages/pi-web-access/preview.png",
"extensions": [
"./dist/index.js"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-web-access

Pi extension for web search and URL content extraction.
Tools
web_search
Search the web for information. Also available via /web-search <query>. Registered when a keyed search provider is available, or when the keyless parallel provider is explicitly selected.
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | yes | The search query |
maxResults |
number | no | Max results to return (default 5) |
topic |
"general" | "news" |
no | Topic category |
timeRange |
"day" | "week" | "month" | "year" |
no | Recency filter |
includeDomains |
string[] | no | Only include results from these domains |
excludeDomains |
string[] | no | Exclude results from these domains |
web_fetch
Fetch a URL and return its content. Also available via /web-fetch <url> [extraction instructions]; instructions default to “Summarize this page.” when omitted. When fetch.summary is configured, the summary model processes the content using prompt; otherwise the fetched content is returned directly and prompt is retained for compatibility but ignored. Only registered when fetch.provider or fetch.summary is configured.
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | yes | Public HTTP(S) URL; private, loopback, link-local, metadata, credentialed, and unsafe redirect destinations are rejected |
prompt |
string | yes | Instructions for the configured summary model; retained for compatibility but ignored when fetch.summary is not configured |
x_search
Search X (Twitter) for posts and social media content. Only registered when xai provider has an API key.
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | yes | The search query on X |
allowedHandles |
string[] | no | Only include posts from these handles (max 20) |
excludedHandles |
string[] | no | Exclude posts from these handles (max 20) |
fromDate |
string | no | Start date (YYYY-MM-DD) |
toDate |
string | no | End date (YYYY-MM-DD) |
image_search
Search the web for images. Only registered when an image search provider (dashscope or unsplash) has an API key. Also invocable directly via the /image-search <query> command.
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | yes | Description of the images to search for |
Structured tool results
On Pi runtimes with structured tool support, codemode receives objects from these tools instead of parsing their Markdown. web_search, x_search, and image_search return { provider, query, answer?, results, truncated }, where each source has title, url, content, and an optional score. web_fetch returns { url, title, content, truncated }; content is the summary when a summary model is configured. Readable tool results remain available.
Results are bounded and truncated indicates shortened text or omitted sources; retained source URLs are never shortened. Failed calls return { error } with isError: true, so scripts must check for error before reading result fields. Cancellation still aborts the call. Older Pi runtimes keep their text-result behavior.
Providers
| Provider | Search | Fetch | X Search | Image Search | Default Base URL | Env Var | Default Model |
|---|---|---|---|---|---|---|---|
cloudflare |
✓ | ✗ | ✗ | ✗ | https://api.cloudflare.com/client/v4 |
CLOUDFLARE_API_TOKEN |
- |
parallel |
✓ | ✗ | ✗ | ✗ | https://search.parallel.ai/mcp |
no key | - |
tavily |
✓ | ✓ | ✗ | ✗ | https://api.tavily.com |
TAVILY_API_KEY |
- |
brave |
✓ | ✗ | ✗ | ✗ | https://api.search.brave.com |
BRAVE_API_KEY |
- |
firecrawl |
✓ | ✓ | ✗ | ✗ | https://api.firecrawl.dev |
FIRECRAWL_API_KEY |
- |
kimi |
✓ | ✗ | ✗ | ✗ | https://api.moonshot.cn/v1 |
MOONSHOT_API_KEY |
kimi-k3 |
mimo |
✓ | ✗ | ✗ | ✗ | https://api.xiaomimimo.com/v1 |
MIMO_API_KEY |
mimo-v2.5-pro |
zai |
✓ | ✓ | ✗ | ✗ | https://api.z.ai |
ZAI_API_KEY |
- |
gemini |
✓ | ✗ | ✗ | ✗ | https://generativelanguage.googleapis.com/v1beta |
GEMINI_API_KEY |
gemini-2.5-flash |
perplexity |
✓ | ✓ | ✗ | ✗ | https://api.perplexity.ai |
PERPLEXITY_API_KEY |
openai/gpt-5.5 |
deepseek |
✓ | ✓ | ✗ | ✗ | https://api.deepseek.com |
DEEPSEEK_API_KEY |
- |
openrouter |
✓ | ✓ | ✗ | ✗ | https://openrouter.ai/api/v1 |
OPENROUTER_API_KEY |
openai/gpt-4.1-mini |
xai |
✓ | ✗ | ✓ | ✗ | https://api.x.ai/v1 |
XAI_API_KEY |
grok-4.3 |
openai |
✓ | ✗ | ✗ | ✗ | https://api.openai.com/v1 |
OPENAI_API_KEY |
gpt-5.5 |
anthropic |
✓ | ✓ | ✗ | ✗ | https://api.anthropic.com/v1 |
ANTHROPIC_API_KEY |
claude-sonnet-4-6 |
dashscope |
✓ | ✓ | ✗ | ✓ | https://dashscope.aliyuncs.com/compatible-mode/v1 |
DASHSCOPE_API_KEY |
qwen3.8-flash |
unsplash |
✗ | ✗ | ✗ | ✓ | https://api.unsplash.com |
UNSPLASH_ACCESS_KEY |
- |
you |
✓ | ✓ | ✗ | ✗ | https://ydc-index.io |
YDC_API_KEY |
- |
DeepSeek Search and Fetch
DeepSeek uses the Search and Fetch APIs: POST /v1/tools/search returns ranked sources with long summaries, and POST /v1/tools/fetch returns Markdown. Set search.provider and/or fetch.provider to "deepseek" and supply DEEPSEEK_API_KEY or providers.deepseek.apiKey. Existing DeepSeek settings continue to work; model is ignored and search no longer returns a synthesized answer. Both root and /v1 base URLs are supported.
Search requests use count (default 5, API limit 50) and need_content: false; fetch a result URL for its full body. Domain filters become site: / -site: syntax, and timeRange becomes an after:YYYY-MM-DD filter (1/7/30/365 days, UTC). The complete query, including filters, must contain 1–128 Unicode characters. topic is ignored; use query terms to search for news. Raw DeepSeek search syntax can also be included directly in the query.
Cloudflare Web Search
Set search.provider to "cloudflare". The Cloudflare Web Search REST API requires an account ID, an API token with Workers AI: Read and AI Gateway: Read permissions, and an AI Gateway with credits or a stored provider key. The default gateway is default; the default search provider is ceramic.
{
"pi-web-access": {
"search": { "provider": "cloudflare" },
"providers": {
"cloudflare": {
"apiKey": "${CLOUDFLARE_API_TOKEN}",
"accountId": "${CLOUDFLARE_ACCOUNT_ID}",
"gatewayId": "default",
"searchProvider": "ceramic"
}
}
}
}
apiKey and accountId fall back to CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID. Cloudflare is also eligible for automatic selection when both are available, after the existing search providers. Configure interpolated values in user or agent settings; trusted project settings do not expand environment variables.
Cloudflare-only provider settings:
| Field | Description |
|---|---|
accountId |
Cloudflare account ID (required; environment fallback supported). |
gatewayId |
AI Gateway ID (default default). |
searchProvider |
ceramic, exa, or linkup (default ceramic). |
byokAlias |
Optional alias of a provider key stored in AI Gateway. If it is missing on the gateway, the API fails rather than falling back to credits. |
Requests use POST {baseUrl}/accounts/{accountId}/ai/websearch/. Queries must contain 1–1024 characters. maxResults defaults to 5 and is capped at 10; topic, timeRange, includeDomains, and excludeDomains are ignored because this API does not support them. Results contain titles, URLs, and description snippets, without a synthesized answer; large snippets are truncated. Cloudflare supports search only.
Custom Kimi base URLs must support both /chat/completions and /formulas/*.
You.com search returns web and news results in one call; topic: "news" prefers news results and applies a one-week freshness window. The Contents API (/v1/contents) returns clean Markdown for web_fetch. Get a key at you.com/platform/api-keys.
Custom DashScope base URLs must point to an OpenAI-compatible Responses API root — ${baseUrl}/responses is called for all capabilities. For the international site or a dedicated workspace endpoint, use e.g. https://dashscope-intl.aliyuncs.com/compatible-mode/v1. DashScope fetch uses the web_extractor tool and image search uses web_search_image; both are agent-style tools and can take minutes per call (default timeout 5 min, tune via timeoutMs). DashScope search supports only basic web search — includeDomains/excludeDomains filters are ignored.
Fetch fallback (when fetch.provider is not set): Jina Reader (r.jina.ai, free, JS-rendered) → local HTTP GET + turndown.
Configuration
Settings key: pi-web-access
Project .pi/settings.json values are loaded only after project trust is accepted and are not environment-interpolated. User and agent settings retain environment interpolation.
{
"pi-web-access": {
"search": {
"provider": "kimi"
},
"fetch": {
"provider": "zai",
"summary": {
"provider": "amaster",
"model": "deepseek-v4-flash"
}
},
"providers": {
"kimi": {
"apiKey": "AMASTER_API_KEY",
"baseUrl": "https://credits.amaster.ai/v1"
},
"zai": {
"apiKey": "${ZAI_API_KEY}"
},
"xai": {
"apiKey": "${XAI_API_KEY}"
}
}
}
}
search
| Field | Description |
|---|---|
provider |
Which provider to use for web search. Not set = auto-select first provider with key. Explicitly selecting parallel enables keyless search; otherwise no key means the tool is not registered. |
fetch
| Field | Description |
|---|---|
provider |
Which provider to use for URL fetching. Not set = Jina Reader → local fallback. |
summary |
Model config for summarizing fetched content. |
summary.provider |
Model provider name (resolved via pi model registry). |
summary.model |
Model id. |
If neither fetch.provider nor fetch.summary is configured, web_fetch is not registered.
imageSearch
| Field | Description |
|---|---|
provider |
Which provider to use for image search (dashscope or unsplash). Not set = auto-select first provider with key. No key at all = tool not registered. |
providers
Per-provider configuration. Each provider supports:
| Field | Description |
|---|---|
apiKey |
API key. User and agent settings support $ENV_VAR and ${ENV_VAR}; only the braced form supports :-fallback. Project settings keep placeholders literal. |
baseUrl |
Override the default API endpoint. |
model |
Override the default model. |
headers |
Extra headers merged into every request. |
Environment variables serve as fallbacks when apiKey is not set in config.
Parallel is opt-in and supports search only: it never enables image search or web_fetch, and it does not perform URL fetching or extraction. When selected, search objectives and queries leave the machine for https://search.parallel.ai/mcp; this can include agent-generated repository context and user-supplied URLs contained in those objectives or queries. Existing automatic provider selection, provider order, and keyed provider behavior are unchanged.
Architecture
Each provider implements the WebProvider interface via BaseProvider:
// providers/base.ts
export interface WebProvider {
readonly id: BuiltInProviderId;
search(params: SearchParams, provider: ResolvedProvider): Promise<SearchResponse>;
fetch(url: string, provider: ResolvedProvider): Promise<FetchResponse>;
imageSearch(params: ImageSearchParams, provider: ResolvedProvider): Promise<SearchResponse>;
}
export abstract class BaseProvider implements WebProvider {
abstract readonly id: BuiltInProviderId;
// Default implementations throw "not supported"
async search(...) { throw new Error(`${this.id} does not support web_search.`); }
async fetch(...) { throw new Error(`${this.id} does not support web_fetch.`); }
async imageSearch(...) { throw new Error(`${this.id} does not support image_search.`); }
}
Providers only override methods they support. Provider-specific capabilities (like XaiProvider.xsearch) are exposed as additional methods on the class.
Tool Registration Rules
web_searchand/web-search <query>— registered when a search provider has an API key, or when keylessparallelis explicitly selected.web_fetchand/web-fetch <url> [extraction instructions]— registered whenfetch.providerorfetch.summaryis configured.x_search— registered when xai provider has an API key.image_search— registered when an image search provider (dashscope, unsplash) has an API key;/image-searchcommand is registered alongside it. AnimageSearch.providerthat doesn't support image search (e.g."openai") is treated as unconfigured.- If none are configured, the extension loads silently with no tools registered.
Install
pi install npm:@amaster.ai/pi-web-access
Development
pnpm build # tsc -b
pnpm typecheck # tsc -b --pretty false
pnpm test # vitest run src