/** * @fileoverview crossref_search_funders — finds funders in the Crossref Funder Registry by name or * DOI, optionally returning a page of works funded by the matched funder. The funder list and the * funded-works list page independently, and their upstream offset ceilings differ by an order of * magnitude; the funded-works list also pages by cursor, which has no ceiling and runs * newest-registered first rather than newest-published first. A name query * matching more than one funder is rejected rather than silently resolved, and a funder the * registry has deprecated is reported with its successor's ID rather than redirected to it. A * blank `query` or `funder_doi` is read as omitted, and a page with no funder renders nothing of * its own, so the notice naming why leads `content[]`. * @module mcp-server/tools/definitions/search-funders.tool */ import { z } from '@cyanheads/mcp-ts-core'; import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors'; export declare const searchFundersTool: import("@cyanheads/mcp-ts-core").ToolDefinition; funder_doi: z.ZodOptional, z.ZodString]>>; include_works: z.ZodDefault; rows: z.ZodDefault; offset: z.ZodDefault; works_offset: z.ZodDefault; works_cursor: z.ZodOptional; }, z.core.$strip>, z.ZodObject<{ funders: z.ZodArray; name: z.ZodOptional; altNames: z.ZodOptional>; country: z.ZodOptional; uri: z.ZodOptional; worksCount: z.ZodOptional; replacedBy: z.ZodOptional>; replaces: z.ZodOptional>; }, z.core.$strip>>; fundedWorks: z.ZodOptional; type: z.ZodOptional; published: z.ZodOptional; month: z.ZodOptional; }, z.core.$strip>>; isReferencedByCount: z.ZodOptional; }, z.core.$strip>>>; }, 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: '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: "funder_not_found"; readonly code: JsonRpcErrorCode.NotFound; readonly when: "Funder DOI lookup returned 404 — funder is not in the Crossref Funder Registry."; readonly recovery: "Verify the registry ID (100000001) or full funder DOI (10.13039/100000001) is correct, or use a name query instead."; }, { readonly reason: "ambiguous_funder"; readonly code: JsonRpcErrorCode.ValidationError; readonly when: "include_works is true but the name query matched more than one funder, making the target ambiguous."; readonly recovery: "Re-run with funder_doi set to one of the registry IDs listed in the error message and in the candidates field of the error data, or narrow the query when the funder you want is not among them."; }, { readonly reason: "offset_too_large"; readonly code: JsonRpcErrorCode.ValidationError; readonly when: "offset + rows exceeds the 100000-record ceiling Crossref allows on funder name search."; readonly recovery: "Narrow the name query so the funders you want fall within the first 100000 matches."; }, { readonly reason: "works_offset_too_large"; readonly code: JsonRpcErrorCode.ValidationError; readonly when: "works_offset + rows exceeds the 10000-record ceiling Crossref allows on a funded-works list."; readonly recovery: "Restart the funded-works list with works_cursor=\"*\" and chain the nextWorksCursor token from each response — cursor paging has no offset ceiling and reaches the whole list."; }, { readonly reason: "works_cursor_offset_conflict"; readonly code: JsonRpcErrorCode.ValidationError; readonly when: "include_works is true and works_cursor was supplied alongside a works_offset above zero."; readonly recovery: "Page the funded-works list one way or the other. Keep works_cursor and drop works_offset to walk the whole list, or drop works_cursor to stay on offset paging."; }], { readonly funderCount: z.ZodNumber; readonly fundersTotal: z.ZodNumber; readonly nextOffset: z.ZodOptional; readonly fundedWorksTotal: z.ZodOptional; readonly nextWorksOffset: z.ZodOptional; readonly nextWorksCursor: z.ZodOptional; readonly notice: z.ZodOptional; }>; //# sourceMappingURL=search-funders.tool.d.ts.map