@cyanheads/openalex-mcp-server 0.7.5 → 0.7.7

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 (40) hide show
  1. package/AGENTS.md +1 -1
  2. package/CLAUDE.md +1 -1
  3. package/README.md +9 -8
  4. package/dist/mcp-server/prompts/definitions/research-landscape.prompt.js +1 -1
  5. package/dist/mcp-server/tools/definitions/analyze-trends.tool.d.ts +6 -0
  6. package/dist/mcp-server/tools/definitions/analyze-trends.tool.d.ts.map +1 -1
  7. package/dist/mcp-server/tools/definitions/analyze-trends.tool.js +18 -0
  8. package/dist/mcp-server/tools/definitions/analyze-trends.tool.js.map +1 -1
  9. package/dist/mcp-server/tools/definitions/citation-graph.tool.d.ts +6 -0
  10. package/dist/mcp-server/tools/definitions/citation-graph.tool.d.ts.map +1 -1
  11. package/dist/mcp-server/tools/definitions/citation-graph.tool.js +18 -0
  12. package/dist/mcp-server/tools/definitions/citation-graph.tool.js.map +1 -1
  13. package/dist/mcp-server/tools/definitions/describe-fields.tool.d.ts.map +1 -1
  14. package/dist/mcp-server/tools/definitions/describe-fields.tool.js +10 -0
  15. package/dist/mcp-server/tools/definitions/describe-fields.tool.js.map +1 -1
  16. package/dist/mcp-server/tools/definitions/resolve-name.tool.d.ts +9 -2
  17. package/dist/mcp-server/tools/definitions/resolve-name.tool.d.ts.map +1 -1
  18. package/dist/mcp-server/tools/definitions/resolve-name.tool.js +71 -20
  19. package/dist/mcp-server/tools/definitions/resolve-name.tool.js.map +1 -1
  20. package/dist/mcp-server/tools/definitions/search-entities.tool.d.ts +6 -0
  21. package/dist/mcp-server/tools/definitions/search-entities.tool.d.ts.map +1 -1
  22. package/dist/mcp-server/tools/definitions/search-entities.tool.js +62 -16
  23. package/dist/mcp-server/tools/definitions/search-entities.tool.js.map +1 -1
  24. package/dist/mcp-server/tools/render-budget.d.ts +16 -0
  25. package/dist/mcp-server/tools/render-budget.d.ts.map +1 -0
  26. package/dist/mcp-server/tools/render-budget.js +36 -0
  27. package/dist/mcp-server/tools/render-budget.js.map +1 -0
  28. package/dist/services/openalex/budget.d.ts +59 -0
  29. package/dist/services/openalex/budget.d.ts.map +1 -0
  30. package/dist/services/openalex/budget.js +65 -0
  31. package/dist/services/openalex/budget.js.map +1 -0
  32. package/dist/services/openalex/field-catalog.json +10 -0
  33. package/dist/services/openalex/openalex-service.d.ts +41 -1
  34. package/dist/services/openalex/openalex-service.d.ts.map +1 -1
  35. package/dist/services/openalex/openalex-service.js +202 -16
  36. package/dist/services/openalex/openalex-service.js.map +1 -1
  37. package/dist/services/openalex/types.d.ts +6 -1
  38. package/dist/services/openalex/types.d.ts.map +1 -1
  39. package/package.json +1 -1
  40. package/server.json +3 -3
@@ -4,30 +4,51 @@
4
4
  */
5
5
  import { tool, z } from '@cyanheads/mcp-ts-core';
6
6
  import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
7
+ import { renderBudgetTrailer } from '../../../mcp-server/tools/render-budget.js';
7
8
  import { renderEntityRecord } from '../../../mcp-server/tools/render-entity-record.js';
8
9
  import { getOpenAlexService } from '../../../services/openalex/openalex-service.js';
9
10
  import { ENTITY_TYPES } from '../../../services/openalex/types.js';
10
11
  const SEMANTIC_PER_PAGE_CAP = 50;
11
12
  const SAMPLE_MAX = 100;
12
- function buildSearchEcho(input) {
13
- const parts = [`entity_type=${input.entity_type}`];
14
- if (input.id)
15
- parts.push(`id=${input.id}`);
13
+ /**
14
+ * The parameters that shape a *list* query, each paired with its echo rendering. Ground truth
15
+ * is `OpenAlexService.search()`: its `id` branch requests `/{entity_type}/{id}` with `select`
16
+ * alone, so every parameter named here is dropped on that path — by OpenAlex itself, which
17
+ * answers an entity-by-ID URL identically whether or not search params ride along.
18
+ *
19
+ * Pagination (`per_page`, `cursor`) is deliberately absent: a singleton lookup is one record by
20
+ * definition, and `per_page` always carries its schema default, so a caller's intent there
21
+ * cannot be told apart from the absence of one. Naming it would be noise, not a warning.
22
+ */
23
+ function searchOnlyParams(input) {
24
+ const parts = [];
16
25
  if (input.query)
17
- parts.push(`query="${input.query}"`);
26
+ parts.push({ name: 'query', rendered: `query="${input.query}"` });
18
27
  if (input.search_mode && input.search_mode !== 'keyword') {
19
- parts.push(`search_mode=${input.search_mode}`);
28
+ parts.push({ name: 'search_mode', rendered: `search_mode=${input.search_mode}` });
20
29
  }
21
30
  if (input.filters && Object.keys(input.filters).length > 0) {
22
- parts.push(`filters=${JSON.stringify(input.filters)}`);
31
+ parts.push({ name: 'filters', rendered: `filters=${JSON.stringify(input.filters)}` });
23
32
  }
24
33
  if (input.sort)
25
- parts.push(`sort=${input.sort}`);
26
- if (input.sample !== undefined)
27
- parts.push(`sample=${input.sample}`);
34
+ parts.push({ name: 'sort', rendered: `sort=${input.sort}` });
35
+ if (input.sample !== undefined) {
36
+ parts.push({ name: 'sample', rendered: `sample=${input.sample}` });
37
+ }
28
38
  if (input.seed !== undefined)
29
- parts.push(`seed=${input.seed}`);
30
- return parts.join(' | ');
39
+ parts.push({ name: 'seed', rendered: `seed=${input.seed}` });
40
+ return parts;
41
+ }
42
+ /**
43
+ * Echo the criteria that actually ran. An `id` lookup echoes `entity_type` and `id` only —
44
+ * echoing a filter the singleton path never applied reads as confirmation that it did, which
45
+ * is the one thing this field exists not to do.
46
+ */
47
+ function buildSearchEcho(input) {
48
+ const parts = [`entity_type=${input.entity_type}`];
49
+ if (input.id)
50
+ return [...parts, `id=${input.id}`].join(' | ');
51
+ return [...parts, ...searchOnlyParams(input).map((part) => part.rendered)].join(' | ');
31
52
  }
32
53
  export const searchEntitiesTool = tool('openalex_search_entities', {
33
54
  description: 'Search, filter, sort, or retrieve by ID. Covers all OpenAlex entity types (works, authors, sources, institutions, topics, keywords, publishers, funders). Pass `id` to retrieve a single entity. Otherwise, use `query` and/or `filters` for discovery. Supports keyword search with boolean operators, exact phrase matching, and AI semantic search. Use openalex_resolve_name to resolve names to IDs before filtering. Searches and ID lookups return a curated set of fields by default; pass `select` to override with specific fields, or `["*"]` for the full record.',
@@ -140,7 +161,7 @@ export const searchEntitiesTool = tool('openalex_search_entities', {
140
161
  id: z
141
162
  .string()
142
163
  .optional()
143
- .describe('Retrieve a single entity by ID. Supports: OpenAlex ID ("W2741809807"), DOI ("10.1038/nature12373"), ORCID ("0000-0002-1825-0097"), ROR ("https://ror.org/00hx57361"), PMID ("12345678"), PMCID ("PMC1234567"), ISSN ("1234-5678"). When provided, other search/filter/sort params are ignored — but `select` still applies: the curated per-entity-type default is returned unless you pass `select` (use `["*"]` for the complete record). Use openalex_resolve_name to find the ID if unknown.'),
164
+ .describe('Retrieve a single entity by ID. Supports: OpenAlex ID ("W2741809807"), DOI ("10.1038/nature12373"), ORCID ("0000-0002-1825-0097"), ROR ("https://ror.org/00hx57361"), PMID ("12345678"), PMCID ("PMC1234567"), ISSN ("1234-5678"). When provided, `query`, `search_mode`, `filters`, `sort`, `sample`, and `seed` are not applied — the returned record is the entity at that ID regardless of them, and the response `notice` names any you passed. `select` still applies: the curated per-entity-type default is returned unless you pass `select` (use `["*"]` for the complete record). To filter, drop `id` and search. Use openalex_resolve_name to find the ID if unknown.'),
144
165
  query: z
145
166
  .string()
146
167
  .optional()
@@ -214,16 +235,33 @@ export const searchEntitiesTool = tool('openalex_search_entities', {
214
235
  enrichment: {
215
236
  echo: z
216
237
  .string()
217
- .describe('Compact echo of the input criteria (entity_type, query, filters, sort, search_mode) — surfaces what was actually searched when results are empty.'),
238
+ .describe('Compact echo of the criteria that actually ran (entity_type, query, filters, sort, search_mode) — surfaces what was searched when results are empty. An `id` lookup echoes entity_type and id alone, because the search criteria are not applied on that path.'),
218
239
  totalCount: z.number().describe('Total results matching the query/filters across all pages.'),
219
240
  notice: z
220
241
  .string()
221
242
  .optional()
222
- .describe('Recovery guidance when results are empty — echoes the criteria and suggests how to broaden. Absent on successful result pages.'),
243
+ .describe('Guidance notice. Set when results are empty (echoes the criteria and suggests how to broaden) or when an `id` lookup was passed search criteria it does not apply (names them). Absent otherwise.'),
244
+ budget: z
245
+ .object({
246
+ costUsd: z
247
+ .number()
248
+ .describe('USD this call spent. 0 for an `id` lookup — OpenAlex does not bill single-entity fetches, so batching known IDs beats paging a filtered list.'),
249
+ remainingUsd: z.number().describe("USD left in today's OpenAlex budget after this call."),
250
+ resetsInSeconds: z
251
+ .number()
252
+ .describe('Seconds until the daily budget refills (midnight UTC).'),
253
+ prepaidRemainingUsd: z
254
+ .number()
255
+ .optional()
256
+ .describe('USD left in the prepaid balance — a separate pool OpenAlex draws on only after the daily allowance runs out, and which the daily reset does not refill. Add it to `remainingUsd` for the full spendable amount. Absent when the account holds no prepaid balance.'),
257
+ })
258
+ .optional()
259
+ .describe('What this call cost against the OpenAlex daily budget and what is left of it. Price a full traversal before committing to it: `totalCount` ÷ `per_page` × `costUsd` against `remainingUsd`. Absent when OpenAlex omitted the accounting headers.'),
223
260
  },
224
261
  enrichmentTrailer: {
225
262
  echo: { label: 'Query' },
226
263
  totalCount: { label: 'Total' },
264
+ budget: { render: renderBudgetTrailer },
227
265
  },
228
266
  async handler(input, ctx) {
229
267
  if (input.search_mode === 'semantic' && input.per_page > SEMANTIC_PER_PAGE_CAP) {
@@ -263,7 +301,15 @@ export const searchEntitiesTool = tool('openalex_search_entities', {
263
301
  });
264
302
  const echo = buildSearchEcho(input);
265
303
  ctx.enrich({ echo, totalCount: result.meta.count });
266
- if (result.results.length === 0) {
304
+ // An `id` lookup always returns its one record or throws, so it never reaches the
305
+ // empty-results notice — the two branches are exclusive, and the dropped-parameter
306
+ // warning is the more useful of the two on that path.
307
+ const ignored = input.id ? searchOnlyParams(input).map((part) => part.name) : [];
308
+ if (ignored.length > 0) {
309
+ const [verb, pronoun] = ignored.length === 1 ? ['was', 'it'] : ['were', 'them'];
310
+ ctx.enrich.notice(`\`id\` takes precedence — ${ignored.join(', ')} ${verb} not applied, and the record below is the entity at that ID regardless of ${pronoun}. Drop \`id\` to run ${pronoun} as a search.`);
311
+ }
312
+ else if (result.results.length === 0) {
267
313
  ctx.enrich.notice(`No matches for ${echo}. Try broadening the query, removing filters, or switching search_mode.`);
268
314
  }
269
315
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"search-entities.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-entities.tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-entities.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-entities.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @fileoverview Markdown rendering for the `budget` enrichment field — shared by the
3
+ * `enrichmentTrailer` of every tool that calls the OpenAlex API. Collapses the three
4
+ * numeric fields to one trailer line; `structuredContent` keeps the numbers.
5
+ * @module mcp-server/tools/render-budget
6
+ */
7
+ import type { UpstreamBudget } from '../../services/openalex/budget.js';
8
+ /**
9
+ * One-line budget trailer. `costUsd: 0` renders as "free" rather than `$0.0000` because it
10
+ * carries real signal — it means the call was a singleton ID lookup, which OpenAlex does not
11
+ * bill, so batching by ID beats paging a filtered list. The prepaid segment appears only for
12
+ * an account holding that balance: without it, "left today" is the whole spendable figure;
13
+ * with it, the daily line alone reads as broke on an account that keeps serving.
14
+ */
15
+ export declare function renderBudgetTrailer(budget: UpstreamBudget | undefined): string;
16
+ //# sourceMappingURL=render-budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-budget.d.ts","sourceRoot":"","sources":["../../../src/mcp-server/tools/render-budget.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAgBpE;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,GAAG,MAAM,CAQ9E"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @fileoverview Markdown rendering for the `budget` enrichment field — shared by the
3
+ * `enrichmentTrailer` of every tool that calls the OpenAlex API. Collapses the three
4
+ * numeric fields to one trailer line; `structuredContent` keeps the numbers.
5
+ * @module mcp-server/tools/render-budget
6
+ */
7
+ /** OpenAlex prices calls in fractions of a cent — four places keeps them out of exponent form. */
8
+ const USD_DECIMALS = 4;
9
+ function formatUsd(value) {
10
+ return `$${value.toFixed(USD_DECIMALS)}`;
11
+ }
12
+ function formatCountdown(seconds) {
13
+ if (seconds < 60)
14
+ return `${Math.round(seconds)}s`;
15
+ const minutes = Math.round(seconds / 60);
16
+ if (minutes < 60)
17
+ return `${minutes}m`;
18
+ return `${Math.floor(minutes / 60)}h ${minutes % 60}m`;
19
+ }
20
+ /**
21
+ * One-line budget trailer. `costUsd: 0` renders as "free" rather than `$0.0000` because it
22
+ * carries real signal — it means the call was a singleton ID lookup, which OpenAlex does not
23
+ * bill, so batching by ID beats paging a filtered list. The prepaid segment appears only for
24
+ * an account holding that balance: without it, "left today" is the whole spendable figure;
25
+ * with it, the daily line alone reads as broke on an account that keeps serving.
26
+ */
27
+ export function renderBudgetTrailer(budget) {
28
+ if (!budget)
29
+ return '';
30
+ const cost = budget.costUsd === 0 ? 'free' : formatUsd(budget.costUsd);
31
+ const prepaid = budget.prepaidRemainingUsd === undefined
32
+ ? ''
33
+ : ` + ${formatUsd(budget.prepaidRemainingUsd)} prepaid`;
34
+ return `**Budget:** ${cost} this call · ${formatUsd(budget.remainingUsd)} left today${prepaid} (resets in ${formatCountdown(budget.resetsInSeconds)})`;
35
+ }
36
+ //# sourceMappingURL=render-budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-budget.js","sourceRoot":"","sources":["../../../src/mcp-server/tools/render-budget.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,kGAAkG;AAClG,MAAM,YAAY,GAAG,CAAC,CAAC;AAEvB,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;AAC3C,CAAC;AAED,SAAS,eAAe,CAAC,OAAe;IACtC,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACzC,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,GAAG,CAAC;IACvC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,KAAK,OAAO,GAAG,EAAE,GAAG,CAAC;AACzD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAkC;IACpE,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvE,MAAM,OAAO,GACX,MAAM,CAAC,mBAAmB,KAAK,SAAS;QACtC,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,MAAM,SAAS,CAAC,MAAM,CAAC,mBAAmB,CAAC,UAAU,CAAC;IAC5D,OAAO,eAAe,IAAI,gBAAgB,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,cAAc,OAAO,eAAe,eAAe,CAAC,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC;AACzJ,CAAC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @fileoverview Reads OpenAlex's per-request usage accounting off the `X-RateLimit-*`
3
+ * response headers and accumulates it across the requests one tool call issues.
4
+ * @module services/openalex/budget
5
+ */
6
+ /**
7
+ * What a tool call spent against the OpenAlex daily budget, and what is left.
8
+ *
9
+ * OpenAlex bills usage in dollars against a daily allowance (roughly $0.10/day anonymous,
10
+ * $1/day with a free account key) that refills at midnight UTC. It reports the accounting
11
+ * on every successful response's headers. `X-RateLimit-Remaining` is a *credit* count
12
+ * against a separate 1000-credit ceiling — proportional to the dollar figure and therefore
13
+ * redundant — so only the `-USD` headers are carried here. `X-RateLimit-Onetime-Remaining`
14
+ * is excluded on the same grounds and one more: it carries no unit, and OpenAlex documents
15
+ * neither the header nor any matching field on its `/rate-limit` endpoint, so there is no
16
+ * way to say what a caller could spend it on.
17
+ */
18
+ export interface UpstreamBudget {
19
+ /** USD this call spent, summed over every upstream request it issued. */
20
+ costUsd: number;
21
+ /**
22
+ * USD left in the prepaid balance — a separate pool OpenAlex draws on once the daily
23
+ * allowance is spent, and which does not refill at the reset. Omitted when the account
24
+ * holds none, which is every anonymous call.
25
+ */
26
+ prepaidRemainingUsd?: number;
27
+ /** USD left in today's budget as of the most recent upstream response. */
28
+ remainingUsd: number;
29
+ /** Seconds until the daily budget refills. */
30
+ resetsInSeconds: number;
31
+ }
32
+ /**
33
+ * Extract the budget accounting from a successful OpenAlex response.
34
+ *
35
+ * All three headers are emitted together on every 200 — a list, a group_by, an autocomplete,
36
+ * and a singleton `/works/{id}` lookup alike. Singleton lookups are the reason this reads
37
+ * headers rather than the parsed body: they carry no `meta` wrapper at all, so the body's
38
+ * `cost_usd` (present and identical on the other shapes) is unavailable exactly where
39
+ * `costUsd: 0` is the most interesting signal — fetching by ID is free.
40
+ *
41
+ * Returns `undefined` unless the full set parses. A partial read would report a cost with no
42
+ * budget to weigh it against, which is worse than reporting nothing. The prepaid balance sits
43
+ * outside that gate — it is an independent pool most accounts don't hold, so its absence says
44
+ * nothing about whether the daily accounting is readable.
45
+ */
46
+ export declare function parseUpstreamBudget(headers: Headers): UpstreamBudget | undefined;
47
+ /**
48
+ * Fold one response's accounting into the running total for a tool call.
49
+ *
50
+ * Cost adds up — a single tool call can issue several billed requests (a sampled search pairs
51
+ * the sample with a population count; the citation-graph walk gates on a seed lookup), and the
52
+ * caller pays for each. The counters run *down*, so the smaller reading is the more recent
53
+ * one; taking the minimum also stays deterministic when requests are issued in parallel and
54
+ * resolve in arbitrary order. The prepaid balance follows the same rule with an absent side
55
+ * read as zero — one request seeing the pool empty means it is empty — which lands back on
56
+ * the omit-when-nothing-is-left convention `parseUpstreamBudget` sets.
57
+ */
58
+ export declare function mergeUpstreamBudget(previous: UpstreamBudget | undefined, next: UpstreamBudget): UpstreamBudget;
59
+ //# sourceMappingURL=budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../../src/services/openalex/budget.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,eAAe,EAAE,MAAM,CAAC;CACzB;AASD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,GAAG,SAAS,CAgBhF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,cAAc,GAAG,SAAS,EACpC,IAAI,EAAE,cAAc,GACnB,cAAc,CAYhB"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @fileoverview Reads OpenAlex's per-request usage accounting off the `X-RateLimit-*`
3
+ * response headers and accumulates it across the requests one tool call issues.
4
+ * @module services/openalex/budget
5
+ */
6
+ function readNumericHeader(headers, name) {
7
+ const raw = headers.get(name);
8
+ if (raw === null)
9
+ return;
10
+ const value = Number(raw);
11
+ return Number.isFinite(value) ? value : undefined;
12
+ }
13
+ /**
14
+ * Extract the budget accounting from a successful OpenAlex response.
15
+ *
16
+ * All three headers are emitted together on every 200 — a list, a group_by, an autocomplete,
17
+ * and a singleton `/works/{id}` lookup alike. Singleton lookups are the reason this reads
18
+ * headers rather than the parsed body: they carry no `meta` wrapper at all, so the body's
19
+ * `cost_usd` (present and identical on the other shapes) is unavailable exactly where
20
+ * `costUsd: 0` is the most interesting signal — fetching by ID is free.
21
+ *
22
+ * Returns `undefined` unless the full set parses. A partial read would report a cost with no
23
+ * budget to weigh it against, which is worse than reporting nothing. The prepaid balance sits
24
+ * outside that gate — it is an independent pool most accounts don't hold, so its absence says
25
+ * nothing about whether the daily accounting is readable.
26
+ */
27
+ export function parseUpstreamBudget(headers) {
28
+ const costUsd = readNumericHeader(headers, 'x-ratelimit-cost-usd');
29
+ const remainingUsd = readNumericHeader(headers, 'x-ratelimit-remaining-usd');
30
+ const resetsInSeconds = readNumericHeader(headers, 'x-ratelimit-reset');
31
+ if (costUsd === undefined || remainingUsd === undefined || resetsInSeconds === undefined)
32
+ return;
33
+ const prepaidRemainingUsd = readNumericHeader(headers, 'x-ratelimit-prepaid-remaining-usd');
34
+ return {
35
+ costUsd,
36
+ remainingUsd,
37
+ resetsInSeconds,
38
+ // A zero reading is the no-prepaid-balance case, indistinguishable from an account that
39
+ // has spent it — either way there is nothing extra to spend, so report nothing extra.
40
+ ...(prepaidRemainingUsd !== undefined && prepaidRemainingUsd > 0 && { prepaidRemainingUsd }),
41
+ };
42
+ }
43
+ /**
44
+ * Fold one response's accounting into the running total for a tool call.
45
+ *
46
+ * Cost adds up — a single tool call can issue several billed requests (a sampled search pairs
47
+ * the sample with a population count; the citation-graph walk gates on a seed lookup), and the
48
+ * caller pays for each. The counters run *down*, so the smaller reading is the more recent
49
+ * one; taking the minimum also stays deterministic when requests are issued in parallel and
50
+ * resolve in arbitrary order. The prepaid balance follows the same rule with an absent side
51
+ * read as zero — one request seeing the pool empty means it is empty — which lands back on
52
+ * the omit-when-nothing-is-left convention `parseUpstreamBudget` sets.
53
+ */
54
+ export function mergeUpstreamBudget(previous, next) {
55
+ if (previous === undefined)
56
+ return next;
57
+ const prepaidRemainingUsd = Math.min(previous.prepaidRemainingUsd ?? 0, next.prepaidRemainingUsd ?? 0);
58
+ return {
59
+ costUsd: previous.costUsd + next.costUsd,
60
+ remainingUsd: Math.min(previous.remainingUsd, next.remainingUsd),
61
+ resetsInSeconds: Math.min(previous.resetsInSeconds, next.resetsInSeconds),
62
+ ...(prepaidRemainingUsd > 0 && { prepaidRemainingUsd }),
63
+ };
64
+ }
65
+ //# sourceMappingURL=budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.js","sourceRoot":"","sources":["../../../src/services/openalex/budget.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA6BH,SAAS,iBAAiB,CAAC,OAAgB,EAAE,IAAY;IACvD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO;IACzB,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACpD,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;IACnE,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,EAAE,2BAA2B,CAAC,CAAC;IAC7E,MAAM,eAAe,GAAG,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;IAExE,IAAI,OAAO,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS,IAAI,eAAe,KAAK,SAAS;QAAE,OAAO;IAEjG,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,OAAO,EAAE,mCAAmC,CAAC,CAAC;IAC5F,OAAO;QACL,OAAO;QACP,YAAY;QACZ,eAAe;QACf,wFAAwF;QACxF,sFAAsF;QACtF,GAAG,CAAC,mBAAmB,KAAK,SAAS,IAAI,mBAAmB,GAAG,CAAC,IAAI,EAAE,mBAAmB,EAAE,CAAC;KAC7F,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAoC,EACpC,IAAoB;IAEpB,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,mBAAmB,GAAG,IAAI,CAAC,GAAG,CAClC,QAAQ,CAAC,mBAAmB,IAAI,CAAC,EACjC,IAAI,CAAC,mBAAmB,IAAI,CAAC,CAC9B,CAAC;IACF,OAAO;QACL,OAAO,EAAE,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO;QACxC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC;QAChE,eAAe,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,eAAe,EAAE,IAAI,CAAC,eAAe,CAAC;QACzE,GAAG,CAAC,mBAAmB,GAAG,CAAC,IAAI,EAAE,mBAAmB,EAAE,CAAC;KACxD,CAAC;AACJ,CAAC"}
@@ -288,6 +288,7 @@
288
288
  "has_orcid",
289
289
  "id",
290
290
  "ids.openalex",
291
+ "last_known_authorships.institutions.lineage",
291
292
  "last_known_institutions.continent",
292
293
  "last_known_institutions.country_code",
293
294
  "last_known_institutions.id",
@@ -306,6 +307,7 @@
306
307
  "summary_stats.2yr_mean_citedness",
307
308
  "summary_stats.h_index",
308
309
  "summary_stats.i10_index",
310
+ "text.search",
309
311
  "to_created_date",
310
312
  "to_updated_date",
311
313
  "topic_share.id",
@@ -369,6 +371,7 @@
369
371
  "is_in_jstage_since_year",
370
372
  "is_oa",
371
373
  "is_ojs",
374
+ "is_preprint_repository",
372
375
  "issn",
373
376
  "issn_l",
374
377
  "last_publication_year",
@@ -378,6 +381,7 @@
378
381
  "summary_stats.2yr_mean_citedness",
379
382
  "summary_stats.h_index",
380
383
  "summary_stats.i10_index",
384
+ "text.search",
381
385
  "to_created_date",
382
386
  "to_updated_date",
383
387
  "topic_share.id",
@@ -408,6 +412,7 @@
408
412
  "is_in_jstage_since_year",
409
413
  "is_in_scielo",
410
414
  "is_ojs",
415
+ "is_preprint_repository",
411
416
  "is_indexed_in_scopus",
412
417
  "is_core",
413
418
  "oa_flip_year",
@@ -461,6 +466,7 @@
461
466
  "summary_stats.2yr_mean_citedness",
462
467
  "summary_stats.h_index",
463
468
  "summary_stats.i10_index",
469
+ "text.search",
464
470
  "topic_share.id",
465
471
  "topics.id",
466
472
  "type",
@@ -517,6 +523,7 @@
517
523
  "keywords.search",
518
524
  "openalex",
519
525
  "subfield.id",
526
+ "text.search",
520
527
  "works_count"
521
528
  ],
522
529
  "select": [
@@ -546,6 +553,7 @@
546
553
  "display_name.search",
547
554
  "from_created_date",
548
555
  "id",
556
+ "text.search",
549
557
  "works_count"
550
558
  ],
551
559
  "select": [
@@ -582,6 +590,7 @@
582
590
  "summary_stats.2yr_mean_citedness",
583
591
  "summary_stats.h_index",
584
592
  "summary_stats.i10_index",
593
+ "text.search",
585
594
  "wikidata",
586
595
  "works_count"
587
596
  ],
@@ -633,6 +642,7 @@
633
642
  "summary_stats.2yr_mean_citedness",
634
643
  "summary_stats.h_index",
635
644
  "summary_stats.i10_index",
645
+ "text.search",
636
646
  "wikidata",
637
647
  "works_count"
638
648
  ],
@@ -3,17 +3,43 @@
3
3
  * @module services/openalex/openalex-service
4
4
  */
5
5
  import type { Context } from '@cyanheads/mcp-ts-core';
6
- import { type AnalyzeParams, type AnalyzeResult, type AutocompleteParams, type AutocompleteResult, type EntityType, type SearchParams, type SearchResult } from './types.js';
6
+ import { type AnalyzeParams, type AnalyzeResult, type AutocompleteParams, type AutocompleteRecord, type AutocompleteResult, type EntityRecord, type EntityType, type SearchParams, type SearchResult } from './types.js';
7
7
  /**
8
8
  * Detect ID format and return the API path segment.
9
9
  * "10.1038/nature12373" → "doi:10.1038/nature12373"
10
10
  * "https://doi.org/10.1038/nature12373" → "doi:10.1038/nature12373"
11
11
  * "0000-0002-1825-0097" → "orcid:0000-0002-1825-0097"
12
+ * "https://orcid.org/0000-0002-1825-0097" → "orcid:https://orcid.org/0000-0002-1825-0097"
12
13
  * "https://ror.org/00hx57361" → "ror:https://ror.org/00hx57361"
14
+ * "013meh722" → "ror:013meh722"
13
15
  * "PMC1234567" → "pmcid:PMC1234567"
14
16
  * "W2741809807" → "W2741809807"
15
17
  */
16
18
  export declare function normalizeId(id: string): string;
19
+ /** An identifier the deterministic by-ID path can resolve, with the scheme it was read as. */
20
+ export interface ResolvedIdentifier {
21
+ entityType: EntityType;
22
+ /** The value in the form the OpenAlex path segment expects (`doi:10.1038/…`, `W2741809807`). */
23
+ id: string;
24
+ /** Identifier scheme, for caller-facing messages: `doi`, `orcid`, `openalex`, … */
25
+ scheme: string;
26
+ }
27
+ /**
28
+ * Classify a query as an identifier, or return `undefined` for a name.
29
+ *
30
+ * `normalizeId()` already knows every shape the by-ID lookup accepts, bare and URL-form alike,
31
+ * and stamps external ones with their scheme prefix — so detection reduces to reading back what
32
+ * it produced. Names never survive that: a name with a colon in it yields a prefix that is in no
33
+ * scheme table, and anything else fails the native-ID pattern.
34
+ */
35
+ export declare function inferIdentifier(query: string): ResolvedIdentifier | undefined;
36
+ /**
37
+ * Shape a singleton entity record like an autocomplete match, so both resolution paths of
38
+ * `openalex_resolve_name` return one result type. `entity_type` is singularized to match what
39
+ * the autocomplete endpoint emits (`work`, not `works`), and `works_count` stays null on works —
40
+ * a work has no works of its own, which is the same thing autocomplete reports.
41
+ */
42
+ export declare function toAutocompleteRecord(entityType: EntityType, record: EntityRecord): AutocompleteRecord;
17
43
  declare class OpenAlexService {
18
44
  private readonly baseUrl;
19
45
  private readonly apiKey;
@@ -27,6 +53,20 @@ declare class OpenAlexService {
27
53
  search(params: SearchParams, ctx: Context): Promise<SearchResult>;
28
54
  /** Group-by aggregation. */
29
55
  analyze(params: AnalyzeParams, ctx: Context): Promise<AnalyzeResult>;
56
+ /**
57
+ * Resolve an identifier to the single entity it addresses, shaped as an autocomplete match.
58
+ *
59
+ * Autocomplete matches on `display_name` and the external-ID URL, so whether an identifier
60
+ * resolves through it depends on scheme, bare-vs-URL form, and entity type — a bare ORCID or
61
+ * a funder's own OpenAlex ID find nothing, while the identical query on works succeeds. This
62
+ * path goes to `/{entity_type}/{id}` instead, where every accepted shape resolves or does not,
63
+ * with no in-between.
64
+ *
65
+ * A miss returns no results rather than throwing. Autocomplete answers an unmatched query with
66
+ * an empty list, and routing identifiers through here is meant to make them behave *more* like
67
+ * the front door, not to hand one class of query a hard failure the rest never sees.
68
+ */
69
+ resolveIdentifier(identifier: ResolvedIdentifier, ctx: Context): Promise<AutocompleteResult>;
30
70
  /** Autocomplete name resolution. */
31
71
  autocomplete(params: AutocompleteParams, ctx: Context): Promise<AutocompleteResult>;
32
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"openalex-service.d.ts","sourceRoot":"","sources":["../../../src/services/openalex/openalex-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAsBtD,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EAIvB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AAsDpB;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CA6C9C;AA8gBD,cAAM,eAAe;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,cAKC;IAED,yFAAyF;IACzF,OAAO,CAAC,OAAO;IAyCf,OAAO,CAAC,2BAA2B;IAoEnC,OAAO,CAAC,aAAa;IAqCrB,sEAAsE;IAChE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CA0FtE;IAED,4BAA4B;IACtB,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAkDzE;IAED,oCAAoC;IAC9B,YAAY,CAAC,MAAM,EAAE,kBAAkB,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAsBxF;CACF;AAID,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAgB,kBAAkB,IAAI,eAAe,CAIpD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAE5F"}
1
+ {"version":3,"file":"openalex-service.d.ts","sourceRoot":"","sources":["../../../src/services/openalex/openalex-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAuBtD,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EAGvB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AAgEpB;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAuD9C;AAoCD,8FAA8F;AAC9F,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,UAAU,CAAC;IACvB,gGAAgG;IAChG,EAAE,EAAE,MAAM,CAAC;IACX,mFAAmF;IACnF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAa7E;AAuJD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,YAAY,GACnB,kBAAkB,CAUpB;AAicD,cAAM,eAAe;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,cAKC;IAED,yFAAyF;IACzF,OAAO,CAAC,OAAO;IAiDf,OAAO,CAAC,2BAA2B;IAoEnC,OAAO,CAAC,aAAa;IAqCrB,sEAAsE;IAChE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CA0FtE;IAED,4BAA4B;IACtB,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAkDzE;IAED;;;;;;;;;;;;OAYG;IACG,iBAAiB,CACrB,UAAU,EAAE,kBAAkB,EAC9B,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,kBAAkB,CAAC,CAkB7B;IAED,oCAAoC;IAC9B,YAAY,CAAC,MAAM,EAAE,kBAAkB,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAsBxF;CACF;AAID,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAgB,kBAAkB,IAAI,eAAe,CAIpD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAE5F"}