@youdotcom-oss/mcp 1.5.1 → 1.6.0

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.
Files changed (49) hide show
  1. package/bin/stdio.js +394 -415
  2. package/package.json +12 -23
  3. package/src/contents/contents.schemas.ts +3 -48
  4. package/src/contents/contents.utils.ts +33 -133
  5. package/src/contents/register-contents-tool.ts +24 -24
  6. package/src/contents/tests/contents.utils.spec.ts +58 -134
  7. package/src/express/express.schema.ts +23 -0
  8. package/src/express/express.utils.ts +10 -121
  9. package/src/express/register-express-tool.ts +19 -19
  10. package/src/express/tests/express.utils.spec.ts +80 -159
  11. package/src/get-mcp-server.ts +3 -3
  12. package/src/http.ts +38 -38
  13. package/src/search/register-search-tool.ts +23 -23
  14. package/src/search/search.schema.ts +38 -0
  15. package/src/search/search.utils.ts +18 -96
  16. package/src/search/tests/search.utils.spec.ts +61 -194
  17. package/src/shared/format-search-results-text.ts +16 -16
  18. package/src/shared/get-logger.ts +4 -4
  19. package/src/shared/tests/shared.utils.spec.ts +56 -56
  20. package/src/shared/use-client-version.ts +8 -8
  21. package/src/stdio.ts +16 -16
  22. package/src/tests/http.spec.ts +105 -105
  23. package/src/tests/tool.spec.ts +212 -212
  24. package/dist/contents/contents.schemas.d.ts +0 -55
  25. package/dist/contents/contents.utils.d.ts +0 -28
  26. package/dist/contents/register-contents-tool.d.ts +0 -10
  27. package/dist/express/express.schemas.d.ts +0 -56
  28. package/dist/express/express.utils.d.ts +0 -45
  29. package/dist/express/register-express-tool.d.ts +0 -6
  30. package/dist/get-mcp-server.d.ts +0 -2
  31. package/dist/http.d.ts +0 -3
  32. package/dist/main.d.ts +0 -9
  33. package/dist/search/register-search-tool.d.ts +0 -6
  34. package/dist/search/search.schemas.d.ts +0 -133
  35. package/dist/search/search.utils.d.ts +0 -98
  36. package/dist/shared/api-constants.d.ts +0 -9
  37. package/dist/shared/check-response-for-errors.d.ts +0 -6
  38. package/dist/shared/format-search-results-text.d.ts +0 -19
  39. package/dist/shared/generate-error-report-link.d.ts +0 -9
  40. package/dist/shared/get-logger.d.ts +0 -7
  41. package/dist/shared/use-client-version.d.ts +0 -6
  42. package/dist/stdio.d.ts +0 -2
  43. package/src/express/express.schemas.ts +0 -99
  44. package/src/main.ts +0 -9
  45. package/src/search/search.schemas.ts +0 -147
  46. package/src/shared/api-constants.ts +0 -10
  47. package/src/shared/check-response-for-errors.ts +0 -13
  48. package/src/shared/generate-error-report-link.ts +0 -37
  49. package/src/tests/exports.spec.ts +0 -24
package/bin/stdio.js CHANGED
@@ -6276,7 +6276,7 @@ var require_formats = __commonJS((exports) => {
6276
6276
  }
6277
6277
  var TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i;
6278
6278
  function getTime(strictTimeZone) {
6279
- return function time(str) {
6279
+ return function time3(str) {
6280
6280
  const matches = TIME.exec(str);
6281
6281
  if (!matches)
6282
6282
  return false;
@@ -6489,7 +6489,7 @@ var require_dist = __commonJS((exports, module) => {
6489
6489
  exports.default = formatsPlugin;
6490
6490
  });
6491
6491
 
6492
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+ef0d3631caac8971/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
6492
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+115df24086ffac64/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
6493
6493
  import process3 from "node:process";
6494
6494
 
6495
6495
  // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/core.js
@@ -8342,10 +8342,6 @@ var $ZodNull = /* @__PURE__ */ $constructor("$ZodNull", (inst, def) => {
8342
8342
  return payload;
8343
8343
  };
8344
8344
  });
8345
- var $ZodAny = /* @__PURE__ */ $constructor("$ZodAny", (inst, def) => {
8346
- $ZodType.init(inst, def);
8347
- inst._zod.parse = (payload) => payload;
8348
- });
8349
8345
  var $ZodUnknown = /* @__PURE__ */ $constructor("$ZodUnknown", (inst, def) => {
8350
8346
  $ZodType.init(inst, def);
8351
8347
  inst._zod.parse = (payload) => payload;
@@ -9695,11 +9691,6 @@ function _null2(Class2, params) {
9695
9691
  ...normalizeParams(params)
9696
9692
  });
9697
9693
  }
9698
- function _any(Class2) {
9699
- return new Class2({
9700
- type: "any"
9701
- });
9702
- }
9703
9694
  function _unknown(Class2) {
9704
9695
  return new Class2({
9705
9696
  type: "unknown"
@@ -11148,14 +11139,6 @@ var ZodNull = /* @__PURE__ */ $constructor("ZodNull", (inst, def) => {
11148
11139
  function _null3(params) {
11149
11140
  return _null2(ZodNull, params);
11150
11141
  }
11151
- var ZodAny = /* @__PURE__ */ $constructor("ZodAny", (inst, def) => {
11152
- $ZodAny.init(inst, def);
11153
- ZodType.init(inst, def);
11154
- inst._zod.processJSONSchema = (ctx, json, params) => anyProcessor(inst, ctx, json, params);
11155
- });
11156
- function any() {
11157
- return _any(ZodAny);
11158
- }
11159
11142
  var ZodUnknown = /* @__PURE__ */ $constructor("ZodUnknown", (inst, def) => {
11160
11143
  $ZodUnknown.init(inst, def);
11161
11144
  ZodType.init(inst, def);
@@ -11524,7 +11507,7 @@ function preprocess(fn, schema) {
11524
11507
  // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
11525
11508
  config(en_default());
11526
11509
 
11527
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+ef0d3631caac8971/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
11510
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+115df24086ffac64/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
11528
11511
  var LATEST_PROTOCOL_VERSION = "2025-11-25";
11529
11512
  var SUPPORTED_PROTOCOL_VERSIONS = [LATEST_PROTOCOL_VERSION, "2025-06-18", "2025-03-26", "2024-11-05", "2024-10-07"];
11530
11513
  var RELATED_TASK_META_KEY = "io.modelcontextprotocol/related-task";
@@ -12366,7 +12349,7 @@ class UrlElicitationRequiredError extends McpError {
12366
12349
  }
12367
12350
  }
12368
12351
 
12369
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+ef0d3631caac8971/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
12352
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+115df24086ffac64/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
12370
12353
  class ReadBuffer {
12371
12354
  append(chunk) {
12372
12355
  this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk;
@@ -12396,7 +12379,7 @@ function serializeMessage(message) {
12396
12379
  `;
12397
12380
  }
12398
12381
 
12399
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+ef0d3631caac8971/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
12382
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+115df24086ffac64/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
12400
12383
  class StdioServerTransport {
12401
12384
  constructor(_stdin = process3.stdin, _stdout = process3.stdout) {
12402
12385
  this._stdin = _stdin;
@@ -12453,121 +12436,8 @@ class StdioServerTransport {
12453
12436
  });
12454
12437
  }
12455
12438
  }
12456
- // package.json
12457
- var package_default = {
12458
- name: "@youdotcom-oss/mcp",
12459
- version: "1.5.1",
12460
- description: "You.com API Model Context Protocol Server",
12461
- license: "MIT",
12462
- engines: {
12463
- node: ">=18",
12464
- bun: ">= 1.2.21"
12465
- },
12466
- repository: {
12467
- type: "git",
12468
- url: "git+https://github.com/youdotcom-oss/dx-toolkit.git",
12469
- directory: "packages/mcp"
12470
- },
12471
- bugs: {
12472
- url: "https://github.com/youdotcom-oss/dx-toolkit/issues"
12473
- },
12474
- homepage: "https://github.com/youdotcom-oss/dx-toolkit/tree/main/packages/mcp#readme",
12475
- author: "You.com (https://you.com)",
12476
- keywords: [
12477
- "mcp",
12478
- "web search",
12479
- "model context protocol"
12480
- ],
12481
- bin: "bin/stdio.js",
12482
- type: "module",
12483
- main: "./src/main.ts",
12484
- exports: {
12485
- ".": {
12486
- types: "./dist/main.d.ts",
12487
- default: "./src/main.ts"
12488
- },
12489
- "./http": "./src/http.ts",
12490
- "./stdio": "./src/stdio.ts"
12491
- },
12492
- files: [
12493
- "bin/stdio.js",
12494
- "./dist/**",
12495
- "./src/**",
12496
- "!./src/**/tests/*",
12497
- "!./src/**/*.spec.@(tsx|ts)"
12498
- ],
12499
- publishConfig: {
12500
- access: "public"
12501
- },
12502
- scripts: {
12503
- build: "bun run build:stdio && bun run build:types",
12504
- "build:stdio": "bun build ./src/stdio.ts --outfile ./bin/stdio.js --target=node",
12505
- "build:types": "tsc --project tsconfig.json --declaration --emitDeclarationOnly --noEmit false",
12506
- check: "bun run check:biome && bun run check:types && bun run check:package",
12507
- "check:biome": "biome check",
12508
- "check:package": "format-package --check",
12509
- "check:types": "tsc --noEmit",
12510
- "check:write": "bun run format && bun run lint:fix && bun run format:package",
12511
- dev: "bun src/stdio.ts",
12512
- format: "biome format --write",
12513
- "format:check": "biome format",
12514
- "format:package": "format-package --write",
12515
- inspect: "bash -c 'source .env 2>/dev/null || true; bunx @modelcontextprotocol/inspector -e YDC_API_KEY=$YDC_API_KEY bun dev'",
12516
- lint: "biome lint",
12517
- "lint:fix": "biome lint --write",
12518
- start: "bun run bin/http",
12519
- test: "bun test",
12520
- "test:coverage": "bun test --coverage",
12521
- "test:coverage:watch": "bun test --coverage --watch",
12522
- "test:watch": "bun test --watch"
12523
- },
12524
- mcpName: "io.github.youdotcom-oss/mcp",
12525
- types: "./dist/main.d.ts",
12526
- dependencies: {
12527
- zod: "^4.3.5",
12528
- "@hono/mcp": "^0.2.3",
12529
- "@modelcontextprotocol/sdk": "^1.25.2",
12530
- hono: "^4.11.4"
12531
- },
12532
- devDependencies: {
12533
- "@modelcontextprotocol/inspector": "0.18.0"
12534
- }
12535
- };
12536
-
12537
- // src/shared/generate-error-report-link.ts
12538
- var generateErrorReportLink = ({
12539
- errorMessage,
12540
- tool,
12541
- clientInfo
12542
- }) => {
12543
- const subject = `MCP Server Issue v${package_default.version}`;
12544
- const body = `Server Version: v${package_default.version}
12545
- Client: ${clientInfo}
12546
- Tool: ${tool}
12547
-
12548
- Error Message:
12549
- ${errorMessage}
12550
12439
 
12551
- Steps to Reproduce:
12552
- 1.
12553
- 2.
12554
- 3.
12555
-
12556
- Additional Context:
12557
- `;
12558
- const params = new URLSearchParams({
12559
- subject,
12560
- body
12561
- });
12562
- return `mailto:support@you.com?${params.toString()}`;
12563
- };
12564
-
12565
- // src/shared/get-logger.ts
12566
- var getLogger = (mcp) => async (params) => {
12567
- await mcp.server.sendLoggingMessage(params);
12568
- };
12569
-
12570
- // src/contents/contents.schemas.ts
12440
+ // ../api/src/contents/contents.schemas.ts
12571
12441
  var ContentsQuerySchema = object({
12572
12442
  urls: array(string2().url()).min(1).describe('Array of webpage URLs to extract content from (e.g., ["https://example.com"])'),
12573
12443
  formats: array(_enum(["markdown", "html", "metadata"])).optional().describe('Output formats: array of "markdown" (text), "html" (layout), or "metadata" (structured data)'),
@@ -12586,28 +12456,12 @@ var ContentsItemSchema = object({
12586
12456
  }).optional().describe("Structured metadata when available")
12587
12457
  });
12588
12458
  var ContentsApiResponseSchema = array(ContentsItemSchema);
12589
- var ContentsStructuredContentSchema = object({
12590
- count: number2().describe("URLs processed"),
12591
- formats: array(string2()).describe("Content formats requested"),
12592
- items: array(object({
12593
- url: string2().describe("URL"),
12594
- title: string2().optional().describe("Title"),
12595
- markdown: string2().optional().describe("Markdown content"),
12596
- html: string2().optional().describe("HTML content"),
12597
- metadata: object({
12598
- jsonld: array(record(string2(), unknown())).optional(),
12599
- opengraph: record(string2(), string2()).optional(),
12600
- twitter: record(string2(), string2()).optional()
12601
- }).optional().describe("Structured metadata")
12602
- })).describe("Extracted items")
12603
- });
12604
-
12605
- // src/shared/api-constants.ts
12459
+ // ../api/src/shared/api.constants.ts
12606
12460
  var SEARCH_API_URL = "https://ydc-index.io/v1/search";
12607
12461
  var EXPRESS_API_URL = "https://api.you.com/v1/agents/runs";
12608
12462
  var CONTENTS_API_URL = "https://ydc-index.io/v1/contents";
12609
12463
 
12610
- // src/shared/check-response-for-errors.ts
12464
+ // ../api/src/shared/check-response-for-errors.ts
12611
12465
  var checkResponseForErrors = (responseData) => {
12612
12466
  if (typeof responseData === "object" && responseData !== null && "error" in responseData) {
12613
12467
  const errorMessage = typeof responseData.error === "string" ? responseData.error : JSON.stringify(responseData.error);
@@ -12616,7 +12470,7 @@ var checkResponseForErrors = (responseData) => {
12616
12470
  return responseData;
12617
12471
  };
12618
12472
 
12619
- // src/contents/contents.utils.ts
12473
+ // ../api/src/contents/contents.utils.ts
12620
12474
  var fetchContents = async ({
12621
12475
  contentsQuery: { urls, formats, format, crawl_timeout },
12622
12476
  YDC_API_KEY = process.env.YDC_API_KEY,
@@ -12671,6 +12525,303 @@ var fetchContents = async ({
12671
12525
  const parsedResults = ContentsApiResponseSchema.parse(results);
12672
12526
  return parsedResults;
12673
12527
  };
12528
+ // ../api/src/express/express.schemas.ts
12529
+ var ExpressAgentInputSchema = object({
12530
+ input: string2().min(1, "Input is required").describe("Query or prompt"),
12531
+ tools: array(object({
12532
+ type: _enum(["web_search"]).describe("Tool type")
12533
+ })).optional().describe("Tools (web search only)")
12534
+ });
12535
+ var ApiSearchResultItemSchema = object({
12536
+ source_type: string2().nullable().optional(),
12537
+ citation_uri: string2().optional(),
12538
+ url: string2(),
12539
+ title: string2(),
12540
+ snippet: string2(),
12541
+ thumbnail_url: string2().nullable().optional(),
12542
+ provider: string2().nullable().optional()
12543
+ });
12544
+ var ExpressAgentApiOutputItemSchema = union([
12545
+ object({
12546
+ type: literal("web_search.results"),
12547
+ content: array(ApiSearchResultItemSchema)
12548
+ }),
12549
+ object({
12550
+ type: literal("message.answer"),
12551
+ text: string2()
12552
+ })
12553
+ ]);
12554
+ var ExpressAgentApiResponseSchema = object({
12555
+ output: array(ExpressAgentApiOutputItemSchema),
12556
+ agent: string2().optional().describe("Agent identifier"),
12557
+ mode: string2().optional().describe("Agent mode"),
12558
+ input: array(object({
12559
+ role: _enum(["user"]).describe("User role"),
12560
+ content: string2().describe("User question")
12561
+ })).optional().describe("Input messages")
12562
+ }).passthrough();
12563
+ var McpSearchResultItemSchema = object({
12564
+ url: string2().describe("URL"),
12565
+ title: string2().describe("Title"),
12566
+ snippet: string2().describe("Snippet")
12567
+ });
12568
+ var ExpressAgentMcpResponseSchema = object({
12569
+ answer: string2().describe("AI answer"),
12570
+ results: object({
12571
+ web: array(McpSearchResultItemSchema).describe("Web results")
12572
+ }).optional().describe("Search results"),
12573
+ agent: string2().optional().describe("Agent ID")
12574
+ });
12575
+ // ../api/src/express/express.utils.ts
12576
+ var agentThrowOnFailedStatus = async (response) => {
12577
+ const errorCode = response.status;
12578
+ const errorData = await response.json();
12579
+ if (errorCode === 400) {
12580
+ throw new Error(`Bad Request:
12581
+ ${JSON.stringify(errorData)}`);
12582
+ } else if (errorCode === 401) {
12583
+ throw new Error(`Unauthorized: The Agent APIs require a valid You.com API key with agent access. Ensure your YDC_API_KEY has permissions for agent endpoints.`);
12584
+ } else if (errorCode === 403) {
12585
+ throw new Error(`Forbidden: You are not allowed to use the requested tool for this agent or tenant`);
12586
+ } else if (errorCode === 429) {
12587
+ throw new Error("Rate limited by You.com API. Please try again later.");
12588
+ }
12589
+ throw new Error(`Failed to call agent. Error code: ${errorCode}`);
12590
+ };
12591
+ var callExpressAgent = async ({
12592
+ YDC_API_KEY = process.env.YDC_API_KEY,
12593
+ agentInput: { input, tools },
12594
+ getUserAgent
12595
+ }) => {
12596
+ const requestBody = {
12597
+ agent: "express",
12598
+ input,
12599
+ stream: false
12600
+ };
12601
+ if (tools) {
12602
+ requestBody.tools = tools;
12603
+ }
12604
+ const options = {
12605
+ method: "POST",
12606
+ headers: new Headers({
12607
+ Authorization: `Bearer ${YDC_API_KEY || ""}`,
12608
+ "Content-Type": "application/json",
12609
+ Accept: "application/json",
12610
+ "User-Agent": getUserAgent()
12611
+ }),
12612
+ body: JSON.stringify(requestBody)
12613
+ };
12614
+ const response = await fetch(EXPRESS_API_URL, options);
12615
+ if (!response.ok) {
12616
+ await agentThrowOnFailedStatus(response);
12617
+ }
12618
+ const jsonResponse = await response.json();
12619
+ checkResponseForErrors(jsonResponse);
12620
+ const apiResponse = ExpressAgentApiResponseSchema.parse(jsonResponse);
12621
+ const answerItem = apiResponse.output.find((item) => item.type === "message.answer");
12622
+ if (!answerItem) {
12623
+ throw new Error("Express API response missing required message.answer item");
12624
+ }
12625
+ const searchItem = apiResponse.output.find((item) => item.type === "web_search.results");
12626
+ const mcpResponse = {
12627
+ answer: answerItem.text,
12628
+ agent: apiResponse.agent
12629
+ };
12630
+ if (searchItem && "content" in searchItem && Array.isArray(searchItem.content)) {
12631
+ mcpResponse.results = {
12632
+ web: searchItem.content.map((item) => ({
12633
+ url: item.url || item.citation_uri || "",
12634
+ title: item.title || "",
12635
+ snippet: item.snippet || ""
12636
+ }))
12637
+ };
12638
+ }
12639
+ return mcpResponse;
12640
+ };
12641
+ // ../api/src/search/search.schemas.ts
12642
+ var SearchQuerySchema = object({
12643
+ query: string2().min(1, "Query is required").describe("Search query (supports +, -, site:, filetype:, lang:)"),
12644
+ count: number2().int().min(1).max(100).optional().describe("Max results per section"),
12645
+ freshness: string2().optional().describe("day/week/month/year or YYYY-MM-DDtoYYYY-MM-DD"),
12646
+ offset: number2().int().min(0).max(9).optional().describe("Pagination offset"),
12647
+ country: _enum([
12648
+ "AR",
12649
+ "AU",
12650
+ "AT",
12651
+ "BE",
12652
+ "BR",
12653
+ "CA",
12654
+ "CL",
12655
+ "DK",
12656
+ "FI",
12657
+ "FR",
12658
+ "DE",
12659
+ "HK",
12660
+ "IN",
12661
+ "ID",
12662
+ "IT",
12663
+ "JP",
12664
+ "KR",
12665
+ "MY",
12666
+ "MX",
12667
+ "NL",
12668
+ "NZ",
12669
+ "NO",
12670
+ "CN",
12671
+ "PL",
12672
+ "PT",
12673
+ "PH",
12674
+ "RU",
12675
+ "SA",
12676
+ "ZA",
12677
+ "ES",
12678
+ "SE",
12679
+ "CH",
12680
+ "TW",
12681
+ "TR",
12682
+ "GB",
12683
+ "US"
12684
+ ]).optional().describe("Country code"),
12685
+ safesearch: _enum(["off", "moderate", "strict"]).optional().describe("Filter level"),
12686
+ site: string2().optional().describe("Specific domain"),
12687
+ fileType: string2().optional().describe("File type"),
12688
+ language: string2().optional().describe("ISO 639-1 language code"),
12689
+ excludeTerms: string2().optional().describe("Terms to exclude (pipe-separated)"),
12690
+ exactTerms: string2().optional().describe("Exact terms (pipe-separated)"),
12691
+ livecrawl: _enum(["web", "news", "all"]).optional().describe("Live-crawl sections for full content"),
12692
+ livecrawl_formats: _enum(["html", "markdown"]).optional().describe("Format for crawled content")
12693
+ });
12694
+ var WebResultSchema = object({
12695
+ url: string2().describe("URL"),
12696
+ title: string2().describe("Title"),
12697
+ description: string2().describe("Description"),
12698
+ snippets: array(string2()).describe("Content snippets"),
12699
+ page_age: string2().optional().describe("Publication timestamp"),
12700
+ authors: array(string2()).optional().describe("Authors"),
12701
+ thumbnail_url: string2().optional().describe("Thumbnail image URL"),
12702
+ favicon_url: string2().optional().describe("Favicon URL"),
12703
+ contents: object({
12704
+ html: string2().optional().describe("Full HTML content"),
12705
+ markdown: string2().optional().describe("Full Markdown content")
12706
+ }).optional().describe("Live-crawled page content")
12707
+ });
12708
+ var NewsResultSchema = object({
12709
+ title: string2().describe("Title"),
12710
+ description: string2().describe("Description"),
12711
+ page_age: string2().describe("Publication timestamp"),
12712
+ url: string2().describe("URL"),
12713
+ thumbnail_url: string2().optional().describe("Thumbnail image URL"),
12714
+ contents: object({
12715
+ html: string2().optional().describe("Full HTML content"),
12716
+ markdown: string2().optional().describe("Full Markdown content")
12717
+ }).optional().describe("Live-crawled page content")
12718
+ });
12719
+ var MetadataSchema = object({
12720
+ search_uuid: string2().optional().describe("Unique search request ID"),
12721
+ query: string2().describe("Query"),
12722
+ latency: number2().describe("Latency in seconds")
12723
+ });
12724
+ var SearchResponseSchema = object({
12725
+ results: object({
12726
+ web: array(WebResultSchema).optional(),
12727
+ news: array(NewsResultSchema).optional()
12728
+ }),
12729
+ metadata: MetadataSchema.partial()
12730
+ });
12731
+ // ../api/src/search/search.utils.ts
12732
+ var fetchSearchResults = async ({
12733
+ YDC_API_KEY = process.env.YDC_API_KEY,
12734
+ searchQuery: { query, site, fileType, language, exactTerms, excludeTerms, ...rest },
12735
+ getUserAgent
12736
+ }) => {
12737
+ const url = new URL(SEARCH_API_URL);
12738
+ const searchParams = new URLSearchParams;
12739
+ const searchQuery = [query];
12740
+ site && searchQuery.push(`site:${site}`);
12741
+ fileType && searchQuery.push(`filetype:${fileType}`);
12742
+ language && searchQuery.push(`lang:${language}`);
12743
+ if (exactTerms && excludeTerms) {
12744
+ throw new Error("Cannot specify both exactTerms and excludeTerms - please use only one");
12745
+ }
12746
+ exactTerms && searchQuery.push(exactTerms.split("|").map((term) => `+${term}`).join(" AND "));
12747
+ excludeTerms && searchQuery.push(excludeTerms.split("|").map((term) => `-${term}`).join(" AND "));
12748
+ searchParams.append("query", searchQuery.join(" "));
12749
+ for (const [name, value] of Object.entries(rest)) {
12750
+ if (value)
12751
+ searchParams.append(name, `${value}`);
12752
+ }
12753
+ url.search = searchParams.toString();
12754
+ const options = {
12755
+ method: "GET",
12756
+ headers: new Headers({
12757
+ "X-API-Key": YDC_API_KEY || "",
12758
+ "User-Agent": getUserAgent()
12759
+ })
12760
+ };
12761
+ const response = await fetch(url, options);
12762
+ if (!response.ok) {
12763
+ const errorCode = response.status;
12764
+ if (errorCode === 429) {
12765
+ throw new Error("Rate limited by You.com API. Please try again later.");
12766
+ } else if (errorCode === 403) {
12767
+ throw new Error("Forbidden. Please check your You.com API key.");
12768
+ }
12769
+ throw new Error(`Failed to perform search. Error code: ${errorCode}`);
12770
+ }
12771
+ const results = await response.json();
12772
+ checkResponseForErrors(results);
12773
+ const parsedResults = SearchResponseSchema.parse(results);
12774
+ return parsedResults;
12775
+ };
12776
+ // ../api/src/shared/generate-error-report-link.ts
12777
+ var generateErrorReportLink = ({
12778
+ errorMessage,
12779
+ tool,
12780
+ clientInfo
12781
+ }) => {
12782
+ const subject = `API Issue ${clientInfo}`;
12783
+ const body = `Client: ${clientInfo}
12784
+ Tool: ${tool}
12785
+
12786
+ Error Message:
12787
+ ${errorMessage}
12788
+
12789
+ Steps to Reproduce:
12790
+ 1.
12791
+ 2.
12792
+ 3.
12793
+
12794
+ Additional Context:
12795
+ `;
12796
+ const params = new URLSearchParams({
12797
+ subject,
12798
+ body
12799
+ });
12800
+ return `mailto:support@you.com?${params.toString()}`;
12801
+ };
12802
+ // src/shared/get-logger.ts
12803
+ var getLogger = (mcp) => async (params) => {
12804
+ await mcp.server.sendLoggingMessage(params);
12805
+ };
12806
+
12807
+ // src/contents/contents.schemas.ts
12808
+ var ContentsStructuredContentSchema = object({
12809
+ count: number2().describe("URLs processed"),
12810
+ formats: array(string2()).describe("Content formats requested"),
12811
+ items: array(object({
12812
+ url: string2().describe("URL"),
12813
+ title: string2().optional().describe("Title"),
12814
+ markdown: string2().optional().describe("Markdown content"),
12815
+ html: string2().optional().describe("HTML content"),
12816
+ metadata: object({
12817
+ jsonld: array(record(string2(), unknown())).optional(),
12818
+ opengraph: record(string2(), string2()).optional(),
12819
+ twitter: record(string2(), string2()).optional()
12820
+ }).optional().describe("Structured metadata")
12821
+ })).describe("Extracted items")
12822
+ });
12823
+
12824
+ // src/contents/contents.utils.ts
12674
12825
  var formatContentsResponse = (response, formats) => {
12675
12826
  const textParts = [`Successfully extracted content from ${response.length} URL(s):
12676
12827
  `];
@@ -12833,51 +12984,8 @@ Report this issue: ${reportLink}`
12833
12984
  }
12834
12985
  });
12835
12986
  };
12836
-
12837
- // src/express/express.schemas.ts
12838
- var ExpressAgentInputSchema = object({
12839
- input: string2().min(1, "Input is required").describe("Query or prompt"),
12840
- tools: array(object({
12841
- type: _enum(["web_search"]).describe("Tool type")
12842
- })).optional().describe("Tools (web search only)")
12843
- });
12844
- var ApiSearchResultItemSchema = object({
12845
- source_type: string2().optional(),
12846
- citation_uri: string2().optional(),
12847
- url: string2(),
12848
- title: string2(),
12849
- snippet: string2(),
12850
- thumbnail_url: string2().optional(),
12851
- provider: any().optional()
12852
- });
12853
- var ExpressAgentApiOutputItemSchema = union([
12854
- object({
12855
- type: literal("web_search.results"),
12856
- content: array(ApiSearchResultItemSchema)
12857
- }),
12858
- object({
12859
- type: literal("message.answer"),
12860
- text: string2()
12861
- })
12862
- ]);
12863
- var ExpressAgentApiResponseSchema = object({
12864
- output: array(ExpressAgentApiOutputItemSchema),
12865
- agent: string2().optional().describe("Agent identifier"),
12866
- mode: string2().optional().describe("Agent mode"),
12867
- input: array(any()).optional().describe("Input messages")
12868
- }).passthrough();
12869
- var McpSearchResultItemSchema = object({
12870
- url: string2().describe("URL"),
12871
- title: string2().describe("Title"),
12872
- snippet: string2().describe("Snippet")
12873
- });
12874
- var ExpressAgentMcpResponseSchema = object({
12875
- answer: string2().describe("AI answer"),
12876
- results: object({
12877
- web: array(McpSearchResultItemSchema).describe("Web results")
12878
- }).optional().describe("Search results"),
12879
- agent: string2().optional().describe("Agent ID")
12880
- });
12987
+
12988
+ // src/express/express.schema.ts
12881
12989
  var ExpressStructuredContentSchema = object({
12882
12990
  answer: string2().describe("AI answer"),
12883
12991
  hasResults: boolean2().describe("Has web results"),
@@ -12917,71 +13025,6 @@ var formatSearchResultsText = (results) => {
12917
13025
  };
12918
13026
 
12919
13027
  // src/express/express.utils.ts
12920
- var agentThrowOnFailedStatus = async (response) => {
12921
- const errorCode = response.status;
12922
- const errorData = await response.json();
12923
- if (errorCode === 400) {
12924
- throw new Error(`Bad Request:
12925
- ${JSON.stringify(errorData)}`);
12926
- } else if (errorCode === 401) {
12927
- throw new Error(`Unauthorized: The Agent APIs require a valid You.com API key with agent access. Ensure your YDC_API_KEY has permissions for agent endpoints.`);
12928
- } else if (errorCode === 403) {
12929
- throw new Error(`Forbidden: You are not allowed to use the requested tool for this agent or tenant`);
12930
- } else if (errorCode === 429) {
12931
- throw new Error("Rate limited by You.com API. Please try again later.");
12932
- }
12933
- throw new Error(`Failed to call agent. Error code: ${errorCode}`);
12934
- };
12935
- var callExpressAgent = async ({
12936
- YDC_API_KEY = process.env.YDC_API_KEY,
12937
- agentInput: { input, tools },
12938
- getUserAgent
12939
- }) => {
12940
- const requestBody = {
12941
- agent: "express",
12942
- input,
12943
- stream: false
12944
- };
12945
- if (tools) {
12946
- requestBody.tools = tools;
12947
- }
12948
- const options = {
12949
- method: "POST",
12950
- headers: new Headers({
12951
- Authorization: `Bearer ${YDC_API_KEY || ""}`,
12952
- "Content-Type": "application/json",
12953
- Accept: "application/json",
12954
- "User-Agent": getUserAgent()
12955
- }),
12956
- body: JSON.stringify(requestBody)
12957
- };
12958
- const response = await fetch(EXPRESS_API_URL, options);
12959
- if (!response.ok) {
12960
- await agentThrowOnFailedStatus(response);
12961
- }
12962
- const jsonResponse = await response.json();
12963
- checkResponseForErrors(jsonResponse);
12964
- const apiResponse = ExpressAgentApiResponseSchema.parse(jsonResponse);
12965
- const answerItem = apiResponse.output.find((item) => item.type === "message.answer");
12966
- if (!answerItem) {
12967
- throw new Error("Express API response missing required message.answer item");
12968
- }
12969
- const searchItem = apiResponse.output.find((item) => item.type === "web_search.results");
12970
- const mcpResponse = {
12971
- answer: answerItem.text,
12972
- agent: apiResponse.agent
12973
- };
12974
- if (searchItem && "content" in searchItem && Array.isArray(searchItem.content)) {
12975
- mcpResponse.results = {
12976
- web: searchItem.content.map((item) => ({
12977
- url: item.url || item.citation_uri || "",
12978
- title: item.title || "",
12979
- snippet: item.snippet || ""
12980
- }))
12981
- };
12982
- }
12983
- return mcpResponse;
12984
- };
12985
13028
  var formatExpressAgentResponse = (response) => {
12986
13029
  const _agentId = response.agent || "express";
12987
13030
  const content = [];
@@ -15126,7 +15169,7 @@ ZodNull2.create = (params) => {
15126
15169
  });
15127
15170
  };
15128
15171
 
15129
- class ZodAny2 extends ZodType2 {
15172
+ class ZodAny extends ZodType2 {
15130
15173
  constructor() {
15131
15174
  super(...arguments);
15132
15175
  this._any = true;
@@ -15135,8 +15178,8 @@ class ZodAny2 extends ZodType2 {
15135
15178
  return OK(input.data);
15136
15179
  }
15137
15180
  }
15138
- ZodAny2.create = (params) => {
15139
- return new ZodAny2({
15181
+ ZodAny.create = (params) => {
15182
+ return new ZodAny({
15140
15183
  typeName: ZodFirstPartyTypeKind.ZodAny,
15141
15184
  ...processCreateParams(params)
15142
15185
  });
@@ -16857,7 +16900,7 @@ var dateType = ZodDate.create;
16857
16900
  var symbolType = ZodSymbol.create;
16858
16901
  var undefinedType = ZodUndefined.create;
16859
16902
  var nullType = ZodNull2.create;
16860
- var anyType = ZodAny2.create;
16903
+ var anyType = ZodAny.create;
16861
16904
  var unknownType = ZodUnknown2.create;
16862
16905
  var neverType = ZodNever2.create;
16863
16906
  var voidType = ZodVoid.create;
@@ -16924,7 +16967,7 @@ function object2(shape, params) {
16924
16967
  };
16925
16968
  return new ZodMiniObject(def);
16926
16969
  }
16927
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+ef0d3631caac8971/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
16970
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+115df24086ffac64/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
16928
16971
  function isZ4Schema(s) {
16929
16972
  const schema = s;
16930
16973
  return !!schema._zod;
@@ -17068,7 +17111,7 @@ function getLiteralValue(schema) {
17068
17111
  return;
17069
17112
  }
17070
17113
 
17071
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+ef0d3631caac8971/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
17114
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+115df24086ffac64/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
17072
17115
  function isTerminal(status) {
17073
17116
  return status === "completed" || status === "failed" || status === "cancelled";
17074
17117
  }
@@ -18309,7 +18352,7 @@ var zodToJsonSchema = (schema, options) => {
18309
18352
  }
18310
18353
  return combined;
18311
18354
  };
18312
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+ef0d3631caac8971/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
18355
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+115df24086ffac64/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
18313
18356
  function mapMiniTarget(t) {
18314
18357
  if (!t)
18315
18358
  return "draft-7";
@@ -18351,7 +18394,7 @@ function parseWithCompat(schema, data) {
18351
18394
  return result.data;
18352
18395
  }
18353
18396
 
18354
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+ef0d3631caac8971/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
18397
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+115df24086ffac64/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
18355
18398
  var DEFAULT_REQUEST_TIMEOUT_MSEC = 60000;
18356
18399
 
18357
18400
  class Protocol {
@@ -19174,7 +19217,7 @@ function mergeCapabilities(base, additional) {
19174
19217
  return result;
19175
19218
  }
19176
19219
 
19177
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+ef0d3631caac8971/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
19220
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+115df24086ffac64/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
19178
19221
  var import_ajv = __toESM(require_ajv(), 1);
19179
19222
  var import_ajv_formats = __toESM(require_dist(), 1);
19180
19223
  function createDefaultAjvInstance() {
@@ -19214,7 +19257,7 @@ class AjvJsonSchemaValidator {
19214
19257
  }
19215
19258
  }
19216
19259
 
19217
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+ef0d3631caac8971/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
19260
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+115df24086ffac64/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
19218
19261
  class ExperimentalServerTasks {
19219
19262
  constructor(_server) {
19220
19263
  this._server = _server;
@@ -19236,7 +19279,7 @@ class ExperimentalServerTasks {
19236
19279
  }
19237
19280
  }
19238
19281
 
19239
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+ef0d3631caac8971/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
19282
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+115df24086ffac64/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
19240
19283
  function assertToolsCallTaskCapability(requests, method, entityName) {
19241
19284
  if (!requests) {
19242
19285
  throw new Error(`${entityName} does not support task creation (required for ${method})`);
@@ -19271,7 +19314,7 @@ function assertClientRequestTaskCapability(requests, method, entityName) {
19271
19314
  }
19272
19315
  }
19273
19316
 
19274
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+ef0d3631caac8971/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
19317
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+115df24086ffac64/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
19275
19318
  class Server extends Protocol {
19276
19319
  constructor(_serverInfo, options) {
19277
19320
  super(options);
@@ -19604,7 +19647,7 @@ class Server extends Protocol {
19604
19647
  }
19605
19648
  }
19606
19649
 
19607
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+ef0d3631caac8971/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js
19650
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+115df24086ffac64/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js
19608
19651
  var COMPLETABLE_SYMBOL = Symbol.for("mcp.completable");
19609
19652
  function isCompletable(schema) {
19610
19653
  return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
@@ -19618,7 +19661,7 @@ var McpZodTypeKind;
19618
19661
  McpZodTypeKind2["Completable"] = "McpCompletable";
19619
19662
  })(McpZodTypeKind || (McpZodTypeKind = {}));
19620
19663
 
19621
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+ef0d3631caac8971/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js
19664
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+115df24086ffac64/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js
19622
19665
  var TOOL_NAME_REGEX = /^[A-Za-z0-9._-]{1,128}$/;
19623
19666
  function validateToolName(name) {
19624
19667
  const warnings = [];
@@ -19676,7 +19719,7 @@ function validateAndWarnToolName(name) {
19676
19719
  return result.isValid;
19677
19720
  }
19678
19721
 
19679
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+ef0d3631caac8971/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js
19722
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+115df24086ffac64/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js
19680
19723
  class ExperimentalMcpServerTasks {
19681
19724
  constructor(_mcpServer) {
19682
19725
  this._mcpServer = _mcpServer;
@@ -19691,7 +19734,7 @@ class ExperimentalMcpServerTasks {
19691
19734
  }
19692
19735
  }
19693
19736
 
19694
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+ef0d3631caac8971/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
19737
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.25.3+115df24086ffac64/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
19695
19738
  class McpServer {
19696
19739
  constructor(serverInfo, options) {
19697
19740
  this._registeredResources = {};
@@ -20410,6 +20453,75 @@ var EMPTY_COMPLETION_RESULT = {
20410
20453
  hasMore: false
20411
20454
  }
20412
20455
  };
20456
+ // package.json
20457
+ var package_default = {
20458
+ name: "@youdotcom-oss/mcp",
20459
+ version: "1.6.0",
20460
+ description: "You.com API Model Context Protocol Server - For programmatic API access, use @youdotcom-oss/api",
20461
+ license: "MIT",
20462
+ engines: {
20463
+ node: ">=18",
20464
+ bun: ">= 1.2.21"
20465
+ },
20466
+ repository: {
20467
+ type: "git",
20468
+ url: "git+https://github.com/youdotcom-oss/dx-toolkit.git",
20469
+ directory: "packages/mcp"
20470
+ },
20471
+ bugs: {
20472
+ url: "https://github.com/youdotcom-oss/dx-toolkit/issues"
20473
+ },
20474
+ homepage: "https://github.com/youdotcom-oss/dx-toolkit/tree/main/packages/mcp#readme",
20475
+ author: "You.com (https://you.com)",
20476
+ keywords: [
20477
+ "mcp",
20478
+ "web search",
20479
+ "model context protocol"
20480
+ ],
20481
+ bin: "bin/stdio.js",
20482
+ type: "module",
20483
+ exports: {
20484
+ "./http": "./src/http.ts"
20485
+ },
20486
+ files: [
20487
+ "bin/stdio.js",
20488
+ "./dist/**",
20489
+ "./src/**",
20490
+ "!./src/**/tests/*",
20491
+ "!./src/**/*.spec.@(tsx|ts)"
20492
+ ],
20493
+ publishConfig: {
20494
+ access: "public"
20495
+ },
20496
+ scripts: {
20497
+ build: "bun build ./src/stdio.ts --outfile ./bin/stdio.js --target=node",
20498
+ check: "bun run check:biome && bun run check:types && bun run check:package",
20499
+ "check:biome": "biome check",
20500
+ "check:package": "format-package --check",
20501
+ "check:types": "tsc --noEmit",
20502
+ "check:write": "biome check --write && bun run format:package",
20503
+ dev: "bun src/stdio.ts",
20504
+ "format:package": "format-package --write",
20505
+ inspect: "bash -c 'source .env 2>/dev/null || true; bunx @modelcontextprotocol/inspector -e YDC_API_KEY=$YDC_API_KEY bun dev'",
20506
+ prepublishOnly: "bun run build",
20507
+ start: "bun run src/http.ts",
20508
+ test: "bun test",
20509
+ "test:coverage": "bun test --coverage",
20510
+ "test:coverage:watch": "bun test --coverage --watch",
20511
+ "test:watch": "bun test --watch"
20512
+ },
20513
+ mcpName: "io.github.youdotcom-oss/mcp",
20514
+ dependencies: {
20515
+ "@youdotcom-oss/api": "0.1.1",
20516
+ zod: "^4.3.6",
20517
+ "@hono/mcp": "^0.2.3",
20518
+ "@modelcontextprotocol/sdk": "^1.25.3",
20519
+ hono: "^4.11.7"
20520
+ },
20521
+ devDependencies: {
20522
+ "@modelcontextprotocol/inspector": "0.19.0"
20523
+ }
20524
+ };
20413
20525
 
20414
20526
  // src/get-mcp-server.ts
20415
20527
  var getMCpServer = () => new McpServer({
@@ -20423,96 +20535,7 @@ var getMCpServer = () => new McpServer({
20423
20535
  instructions: `Use this server to search the web, get AI-powered answers with web context, and extract content from web pages using You.com. The you-contents tool extracts page content and returns it in markdown or HTML format. Use HTML format for layout preservation, interactive content, and visual fidelity; use markdown for text extraction and simpler consumption.`
20424
20536
  });
20425
20537
 
20426
- // src/search/search.schemas.ts
20427
- var SearchQuerySchema = object({
20428
- query: string2().min(1, "Query is required").describe("Search query (supports +, -, site:, filetype:, lang:)"),
20429
- count: number2().int().min(1).max(100).optional().describe("Max results per section"),
20430
- freshness: string2().optional().describe("day/week/month/year or YYYY-MM-DDtoYYYY-MM-DD"),
20431
- offset: number2().int().min(0).max(9).optional().describe("Pagination offset"),
20432
- country: _enum([
20433
- "AR",
20434
- "AU",
20435
- "AT",
20436
- "BE",
20437
- "BR",
20438
- "CA",
20439
- "CL",
20440
- "DK",
20441
- "FI",
20442
- "FR",
20443
- "DE",
20444
- "HK",
20445
- "IN",
20446
- "ID",
20447
- "IT",
20448
- "JP",
20449
- "KR",
20450
- "MY",
20451
- "MX",
20452
- "NL",
20453
- "NZ",
20454
- "NO",
20455
- "CN",
20456
- "PL",
20457
- "PT",
20458
- "PH",
20459
- "RU",
20460
- "SA",
20461
- "ZA",
20462
- "ES",
20463
- "SE",
20464
- "CH",
20465
- "TW",
20466
- "TR",
20467
- "GB",
20468
- "US"
20469
- ]).optional().describe("Country code"),
20470
- safesearch: _enum(["off", "moderate", "strict"]).optional().describe("Filter level"),
20471
- site: string2().optional().describe("Specific domain"),
20472
- fileType: string2().optional().describe("File type"),
20473
- language: string2().optional().describe("ISO 639-1 language code"),
20474
- excludeTerms: string2().optional().describe("Terms to exclude (pipe-separated)"),
20475
- exactTerms: string2().optional().describe("Exact terms (pipe-separated)"),
20476
- livecrawl: _enum(["web", "news", "all"]).optional().describe("Live-crawl sections for full content"),
20477
- livecrawl_formats: _enum(["html", "markdown"]).optional().describe("Format for crawled content")
20478
- });
20479
- var WebResultSchema = object({
20480
- url: string2().describe("URL"),
20481
- title: string2().describe("Title"),
20482
- description: string2().describe("Description"),
20483
- snippets: array(string2()).describe("Content snippets"),
20484
- page_age: string2().optional().describe("Publication timestamp"),
20485
- authors: array(string2()).optional().describe("Authors"),
20486
- thumbnail_url: string2().optional().describe("Thumbnail image URL"),
20487
- favicon_url: string2().optional().describe("Favicon URL"),
20488
- contents: object({
20489
- html: string2().optional().describe("Full HTML content"),
20490
- markdown: string2().optional().describe("Full Markdown content")
20491
- }).optional().describe("Live-crawled page content")
20492
- });
20493
- var NewsResultSchema = object({
20494
- title: string2().describe("Title"),
20495
- description: string2().describe("Description"),
20496
- page_age: string2().describe("Publication timestamp"),
20497
- url: string2().describe("URL"),
20498
- thumbnail_url: string2().optional().describe("Thumbnail image URL"),
20499
- contents: object({
20500
- html: string2().optional().describe("Full HTML content"),
20501
- markdown: string2().optional().describe("Full Markdown content")
20502
- }).optional().describe("Live-crawled page content")
20503
- });
20504
- var MetadataSchema = object({
20505
- search_uuid: string2().optional().describe("Unique search request ID"),
20506
- query: string2().describe("Query"),
20507
- latency: number2().describe("Latency in seconds")
20508
- });
20509
- var SearchResponseSchema = object({
20510
- results: object({
20511
- web: array(WebResultSchema).optional(),
20512
- news: array(NewsResultSchema).optional()
20513
- }),
20514
- metadata: MetadataSchema.partial()
20515
- });
20538
+ // src/search/search.schema.ts
20516
20539
  var SearchStructuredContentSchema = object({
20517
20540
  resultCounts: object({
20518
20541
  web: number2().describe("Web results"),
@@ -20534,50 +20557,6 @@ var SearchStructuredContentSchema = object({
20534
20557
  });
20535
20558
 
20536
20559
  // src/search/search.utils.ts
20537
- var fetchSearchResults = async ({
20538
- YDC_API_KEY = process.env.YDC_API_KEY,
20539
- searchQuery: { query, site, fileType, language, exactTerms, excludeTerms, ...rest },
20540
- getUserAgent
20541
- }) => {
20542
- const url = new URL(SEARCH_API_URL);
20543
- const searchParams = new URLSearchParams;
20544
- const searchQuery = [query];
20545
- site && searchQuery.push(`site:${site}`);
20546
- fileType && searchQuery.push(`filetype:${fileType}`);
20547
- language && searchQuery.push(`lang:${language}`);
20548
- if (exactTerms && excludeTerms) {
20549
- throw new Error("Cannot specify both exactTerms and excludeTerms - please use only one");
20550
- }
20551
- exactTerms && searchQuery.push(exactTerms.split("|").map((term) => `+${term}`).join(" AND "));
20552
- excludeTerms && searchQuery.push(excludeTerms.split("|").map((term) => `-${term}`).join(" AND "));
20553
- searchParams.append("query", searchQuery.join(" "));
20554
- for (const [name, value] of Object.entries(rest)) {
20555
- if (value)
20556
- searchParams.append(name, `${value}`);
20557
- }
20558
- url.search = searchParams.toString();
20559
- const options = {
20560
- method: "GET",
20561
- headers: new Headers({
20562
- "X-API-Key": YDC_API_KEY || "",
20563
- "User-Agent": getUserAgent()
20564
- })
20565
- };
20566
- const response = await fetch(url, options);
20567
- if (!response.ok) {
20568
- const errorCode = response.status;
20569
- if (errorCode === 429) {
20570
- throw new Error("Rate limited by You.com API. Please try again later.");
20571
- } else if (errorCode === 403) {
20572
- throw new Error("Forbidden. Please check your You.com API key.");
20573
- }
20574
- throw new Error(`Failed to perform search. Error code: ${errorCode}`);
20575
- }
20576
- const results = await response.json();
20577
- checkResponseForErrors(results);
20578
- const parsedResults = SearchResponseSchema.parse(results);
20579
- return parsedResults;
20580
- };
20581
20560
  var formatSearchResults = (response) => {
20582
20561
  let formattedResults = "";
20583
20562
  if (response.results.web?.length) {