@wolido/pi-anysearch 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,7 +49,7 @@ Get a key at [anysearch.ai](https://anysearch.ai).
49
49
 
50
50
  ```bash
51
51
  npm install
52
- npm test # vitest, 36 tests
52
+ npm test # vitest, 63 tests
53
53
  npm run typecheck # tsc --noEmit
54
54
  ```
55
55
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wolido/pi-anysearch",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "AnySearch AI search API extension for pi",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
package/src/anysearch.ts CHANGED
@@ -50,7 +50,7 @@ export interface AnySearchClient {
50
50
  search(params: SearchParams): Promise<SearchResult>;
51
51
  batchSearch(params: BatchSearchParams): Promise<SearchResult[]>;
52
52
  extract(url: string): Promise<string>;
53
- getDomains(domain: string): Promise<string>;
53
+ getDomains(domain: string | string[]): Promise<string>;
54
54
  }
55
55
 
56
56
  const DEFAULT_BASE_URL = "https://api.anysearch.com";
@@ -168,7 +168,7 @@ export function createAnySearchClient(options: AnySearchClientOptions = {}): Any
168
168
  params: {
169
169
  protocolVersion: "2025-03-26",
170
170
  capabilities: {},
171
- clientInfo: { name: "pi-anysearch", version: "0.1.0" },
171
+ clientInfo: { name: "pi-anysearch", version: "0.2.0" },
172
172
  },
173
173
  }),
174
174
  });
@@ -244,8 +244,9 @@ export function createAnySearchClient(options: AnySearchClientOptions = {}): Any
244
244
  return mcpCall("extract", { url });
245
245
  },
246
246
 
247
- getDomains(domain: string): Promise<string> {
248
- return mcpCall("get_sub_domains", { domain });
247
+ getDomains(domainOrDomains: string | string[]): Promise<string> {
248
+ const args = Array.isArray(domainOrDomains) ? { domains: domainOrDomains } : { domain: domainOrDomains };
249
+ return mcpCall("get_sub_domains", args);
249
250
  },
250
251
  };
251
252
  }
package/src/index.ts CHANGED
@@ -107,12 +107,52 @@ const batchSearchSchema = Type.Object({
107
107
  ...sharedSearchParams,
108
108
  });
109
109
 
110
+ // 17 top-level capability domains accepted by the MCP get_sub_domains tool.
111
+ const DOMAIN_VALUES = [
112
+ "general",
113
+ "resource",
114
+ "social_media",
115
+ "finance",
116
+ "academic",
117
+ "legal",
118
+ "health",
119
+ "business",
120
+ "security",
121
+ "ip",
122
+ "code",
123
+ "energy",
124
+ "environment",
125
+ "agriculture",
126
+ "travel",
127
+ "film",
128
+ "gaming",
129
+ ] as const;
130
+
131
+ const DOMAIN_LIST_TEXT = DOMAIN_VALUES.join(", ");
132
+
133
+ const DOMAIN_DESCRIPTION =
134
+ "Top-level capability domain. Valid values: " + DOMAIN_LIST_TEXT;
135
+
136
+ const DOMAINS_ARRAY_DESCRIPTION =
137
+ "List of top-level capability domains to inspect. Valid values: " +
138
+ DOMAIN_LIST_TEXT +
139
+ ". Pass all 17 values to list the full capability table. AnySearch documentation recommends requesting at most 5 domains per call.";
140
+
110
141
  const extractSchema = Type.Object({
111
142
  url: Type.String({ description: "URL of the page to extract readable content from" }),
112
143
  });
113
144
 
114
145
  const domainsSchema = Type.Object({
115
- domain: Type.String({ description: 'Top-level capability domain to inspect, e.g. "finance", "academic"' }),
146
+ domain: Type.Optional(
147
+ StringEnum(DOMAIN_VALUES, {
148
+ description: DOMAIN_DESCRIPTION,
149
+ }),
150
+ ),
151
+ domains: Type.Optional(
152
+ Type.Array(StringEnum(DOMAIN_VALUES), {
153
+ description: DOMAINS_ARRAY_DESCRIPTION,
154
+ }),
155
+ ),
116
156
  });
117
157
 
118
158
  /** Byte-level truncation of a single field value (e.g. one result's content). */
@@ -212,11 +252,11 @@ export default function anysearchExtension(pi: ExtensionAPI) {
212
252
  name: "anysearch_search",
213
253
  label: "AnySearch Search",
214
254
  description:
215
- "Search the web with AnySearch, a vertical search API with 40 curated capability domains " +
255
+ "Search the web with AnySearch, a vertical search API covering 40 capability domains " +
216
256
  "(finance, academic, legal, security, health, travel, ...). Returns titles, URLs, snippets and " +
217
257
  "extracted page content. When the query clearly belongs to a vertical, pass its capability tag " +
218
258
  "(e.g. finance.quote for stock quotes, academic.search for papers, security.vuln for CVEs, " +
219
- "code.doc for API documentation) for higher-precision results; omit tag for general web search.",
259
+ "code.doc for API documentation): the tag routes the query to that vertical index. Omit tag for general web search.",
220
260
  promptSnippet: "Vertical web search via AnySearch (40 capability tags, cn/intl zones)",
221
261
  promptGuidelines: [
222
262
  "Use anysearch_search for web lookups; set its tag parameter when the request matches a vertical such as finance.quote, academic.search, code.doc or security.vuln.",
@@ -303,7 +343,7 @@ export default function anysearchExtension(pi: ExtensionAPI) {
303
343
  name: "anysearch_domains",
304
344
  label: "AnySearch Domains",
305
345
  description:
306
- "List the curated sub-domains AnySearch covers under a top-level capability domain " +
346
+ "List the capability sub-domains AnySearch covers under a top-level domain " +
307
347
  '(e.g. "finance", "academic", "legal"). Use this to discover which capability tags exist ' +
308
348
  "before choosing a tag for anysearch_search.",
309
349
  promptSnippet: "Discover AnySearch capability sub-domains and tags",
@@ -313,10 +353,14 @@ export default function anysearchExtension(pi: ExtensionAPI) {
313
353
  parameters: domainsSchema,
314
354
  async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
315
355
  const client = await getClient(ctx);
316
- const text = await client.getDomains(params.domain);
356
+ const target = params.domains?.length ? params.domains : params.domain;
357
+ if (!target) {
358
+ throw new Error(`domain or domains is required. Valid values: ${DOMAIN_LIST_TEXT}`);
359
+ }
360
+ const text = await client.getDomains(target);
317
361
  return {
318
362
  content: [{ type: "text", text: truncateForOutput(text) }],
319
- details: { domain: params.domain },
363
+ details: { domain: params.domain, domains: params.domains },
320
364
  };
321
365
  },
322
366
  });