/** * @fileoverview crossref_search_works — searches the Crossref works index by free text and/or * filters. The result list pages two ways: by offset up to a ~10K ceiling, and by cursor, which * has none. A cursor walk with a query term and no sort is sent as `sort=score`, since Crossref * otherwise walks in registration order. A cursor walk ends on the first empty page — any token that page carries is withheld * rather than relayed, and every empty page carries a notice naming which of its three causes * applies; `format()` renders nothing for such a page, so that notice leads `content[]`. Each * work's author list is capped per work by authorLimit, with authorCount carrying the full * deposited total and crossref_get_work as the route to the authors a cap left out. Update links * (`updatedBy`, `updateTo`) share their shape and line with crossref_get_work. `fields` * accepts only the select names the summary projects, and a blank optional input is read as * omitted. * @module mcp-server/tools/definitions/search-works.tool */ import { z } from '@cyanheads/mcp-ts-core'; import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors'; export declare const searchWorksTool: import("@cyanheads/mcp-ts-core").ToolDefinition; queryBibliographic: z.ZodOptional; queryTitle: z.ZodOptional; queryAuthor: z.ZodOptional; queryContainerTitle: z.ZodOptional; filter: z.ZodOptional>; fields: z.ZodOptional>>; rows: z.ZodDefault; authorLimit: z.ZodDefault; offset: z.ZodOptional; cursor: z.ZodOptional; sort: z.ZodOptional, z.ZodEnum<{ created: "created"; deposited: "deposited"; indexed: "indexed"; "is-referenced-by-count": "is-referenced-by-count"; published: "published"; "published-online": "published-online"; "published-print": "published-print"; "references-count": "references-count"; relevance: "relevance"; score: "score"; updated: "updated"; }>]>>; order: z.ZodOptional, z.ZodEnum<{ asc: "asc"; desc: "desc"; }>]>>; }, z.core.$strip>, z.ZodObject<{ works: z.ZodArray; issue: z.ZodOptional; page: z.ZodOptional; articleNumber: z.ZodOptional; updatedBy: z.ZodOptional; updated: z.ZodOptional; month: z.ZodOptional; day: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>>>; updateTo: z.ZodOptional; updated: z.ZodOptional; month: z.ZodOptional; day: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>>>; doi: z.ZodString; title: z.ZodOptional; type: z.ZodOptional; authors: z.ZodOptional; family: z.ZodOptional; name: z.ZodOptional; }, z.core.$strip>>>; authorCount: z.ZodOptional; published: z.ZodOptional; month: z.ZodOptional; day: z.ZodOptional; }, z.core.$strip>>; containerTitle: z.ZodOptional; issn: z.ZodOptional>; publisher: z.ZodOptional; isReferencedByCount: z.ZodOptional; score: z.ZodOptional; abstract: z.ZodOptional; }, z.core.$strip>>; nextCursor: z.ZodOptional; }, z.core.$strip>, readonly [{ readonly reason: 'rate_limited'; readonly code: JsonRpcErrorCode.RateLimited; readonly thrownBy: 'service'; readonly when: 'Crossref answered HTTP 429 and the limit did not clear inside the retry budget.'; readonly recovery: 'Crossref named no wait interval, so back off at least a minute before reissuing the same call, and lower the request rate. Setting CROSSREF_MAILTO on the server moves requests into the polite pool, which has higher limits.'; }, { readonly reason: 'upstream_unavailable'; readonly code: JsonRpcErrorCode.ServiceUnavailable; readonly thrownBy: 'service'; readonly when: 'Crossref was unreachable, returned a 5xx status, or served an HTML error page instead of JSON.'; readonly recovery: 'The request was accepted as well-formed and Crossref failed to serve it — retry the same call in a minute rather than rewriting the query, and check https://status.crossref.org if it keeps failing.'; }, { readonly reason: 'malformed_response'; readonly code: JsonRpcErrorCode.SerializationError; readonly thrownBy: 'service'; readonly retryable: false; readonly when: 'Crossref returned HTTP 200 with a body that is not valid JSON.'; readonly recovery: 'Do not repeat the call unchanged — the body is corrupt rather than transient. Request less of the record (fewer rows, a narrower select) so a smaller response is serialized, or report the query that reproduces it.'; }, { readonly reason: 'request_timeout'; readonly code: JsonRpcErrorCode.Timeout; readonly thrownBy: 'service'; readonly when: 'Crossref did not respond within CROSSREF_TIMEOUT_MS, or answered HTTP 408/504.'; readonly recovery: 'Ask for less work per call — lower rows, drop select fields, or split a broad query — or raise CROSSREF_TIMEOUT_MS on the server, then retry.'; }, { readonly reason: 'unknown_filter'; readonly code: JsonRpcErrorCode.ValidationError; readonly thrownBy: 'service'; readonly when: 'Crossref rejected a filter key it does not recognize (filter-not-available).'; readonly recovery: "Use Crossref's hyphenated filter keys — has-abstract, from-pub-date, has-full-text, has-references — taking the key the error message suggests when it names one. Crossref has no open-access flag; for openly licensed content filter on license.url with a Creative Commons license URL, e.g. http://creativecommons.org/licenses/by/4.0/."; }, { readonly reason: 'sort_cursor_conflict'; readonly code: JsonRpcErrorCode.ValidationError; readonly thrownBy: 'service'; readonly when: 'A publication-date sort (published, published-print, published-online) was combined with cursor paging, which Crossref refuses.'; readonly recovery: 'Drop sort, or switch to one Crossref walks by cursor — created, deposited, indexed, updated, score, is-referenced-by-count, or references-count — or page with offset instead of cursor to keep the publication-date sort.'; }, { readonly reason: 'invalid_cursor'; readonly code: JsonRpcErrorCode.ValidationError; readonly thrownBy: 'service'; readonly when: 'Crossref did not recognize the cursor token (HTTP 404 cursor-invalid).'; readonly recovery: 'Restart the walk by passing "*" as cursor (works_cursor on the journal and funder works lists), then chain only the continuation token each response returns (nextCursor, or nextWorksCursor on those lists), passed back unmodified.'; }, { readonly reason: 'invalid_parameter'; readonly code: JsonRpcErrorCode.ValidationError; readonly thrownBy: 'service'; readonly when: 'Crossref rejected a parameter value (a filter value of the wrong type or form), or answered HTTP 400 with a body that did not parse.'; readonly recovery: 'Correct the value the error message names to the form it states — a type from the listed values, true or false for a has- flag, a yyyy-mm-dd date — then reissue the call.'; }, { readonly reason: "cursor_offset_conflict"; readonly code: JsonRpcErrorCode.ValidationError; readonly when: "Both cursor and offset were supplied in the same request."; readonly recovery: "Use cursor or offset, not both. Pass cursor=\"*\" to start cursor-based paging; use offset only for the first ~10K results."; }, { readonly reason: "offset_too_large"; readonly code: JsonRpcErrorCode.ValidationError; readonly when: "The requested offset exceeds the ~10K Crossref limit for offset-based paging."; readonly recovery: "Switch to cursor-based paging by passing cursor=\"*\" on the first request, then chaining the nextCursor token from each response."; }], { readonly totalResults: z.ZodNumber; readonly returned: z.ZodNumber; readonly truncated: z.ZodOptional; readonly cap: z.ZodOptional; readonly notice: z.ZodOptional; }>; //# sourceMappingURL=search-works.tool.d.ts.map