@cyanheads/openalex-mcp-server 0.8.0 → 0.10.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.
- package/AGENTS.md +25 -7
- package/CLAUDE.md +25 -7
- package/Dockerfile +17 -8
- package/README.md +28 -19
- package/changelog/0.10.x/0.10.0.md +30 -0
- package/changelog/0.9.x/0.9.0.md +48 -0
- package/dist/config/server-config.d.ts +2 -0
- package/dist/config/server-config.d.ts.map +1 -1
- package/dist/config/server-config.js +10 -0
- package/dist/config/server-config.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/prompts/definitions/literature-review.prompt.js +1 -1
- package/dist/mcp-server/prompts/definitions/research-landscape.prompt.js +1 -1
- package/dist/mcp-server/tools/definitions/analyze-trends.tool.d.ts +35 -4
- package/dist/mcp-server/tools/definitions/analyze-trends.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/analyze-trends.tool.js +86 -41
- package/dist/mcp-server/tools/definitions/analyze-trends.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/citation-graph.tool.d.ts +48 -5
- package/dist/mcp-server/tools/definitions/citation-graph.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/citation-graph.tool.js +77 -24
- package/dist/mcp-server/tools/definitions/citation-graph.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/describe-fields.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/describe-fields.tool.js +34 -4
- package/dist/mcp-server/tools/definitions/describe-fields.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/resolve-name.tool.d.ts +43 -1
- package/dist/mcp-server/tools/definitions/resolve-name.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/resolve-name.tool.js +182 -40
- package/dist/mcp-server/tools/definitions/resolve-name.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-entities.tool.d.ts +64 -6
- package/dist/mcp-server/tools/definitions/search-entities.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-entities.tool.js +138 -35
- package/dist/mcp-server/tools/definitions/search-entities.tool.js.map +1 -1
- package/dist/mcp-server/tools/page-size.d.ts +18 -0
- package/dist/mcp-server/tools/page-size.d.ts.map +1 -0
- package/dist/mcp-server/tools/page-size.js +28 -0
- package/dist/mcp-server/tools/page-size.js.map +1 -0
- package/dist/mcp-server/tools/render-budget.d.ts +4 -2
- package/dist/mcp-server/tools/render-budget.d.ts.map +1 -1
- package/dist/mcp-server/tools/render-budget.js +4 -2
- package/dist/mcp-server/tools/render-budget.js.map +1 -1
- package/dist/mcp-server/tools/response-budget.d.ts +3 -3
- package/dist/mcp-server/tools/response-budget.d.ts.map +1 -1
- package/dist/mcp-server/tools/response-budget.js +64 -35
- package/dist/mcp-server/tools/response-budget.js.map +1 -1
- package/dist/services/openalex/budget.d.ts +3 -1
- package/dist/services/openalex/budget.d.ts.map +1 -1
- package/dist/services/openalex/budget.js +3 -1
- package/dist/services/openalex/budget.js.map +1 -1
- package/dist/services/openalex/field-catalog.json +50 -1
- package/dist/services/openalex/filter-values.d.ts +48 -0
- package/dist/services/openalex/filter-values.d.ts.map +1 -0
- package/dist/services/openalex/filter-values.js +350 -0
- package/dist/services/openalex/filter-values.js.map +1 -0
- package/dist/services/openalex/iso-codes.json +1565 -0
- package/dist/services/openalex/openalex-service.d.ts +176 -20
- package/dist/services/openalex/openalex-service.d.ts.map +1 -1
- package/dist/services/openalex/openalex-service.js +573 -127
- package/dist/services/openalex/openalex-service.js.map +1 -1
- package/dist/services/openalex/provider-text.d.ts +7 -6
- package/dist/services/openalex/provider-text.d.ts.map +1 -1
- package/dist/services/openalex/provider-text.js +485 -61
- package/dist/services/openalex/provider-text.js.map +1 -1
- package/dist/services/openalex/types.d.ts +5 -2
- package/dist/services/openalex/types.d.ts.map +1 -1
- package/package.json +14 -12
- package/server.json +35 -21
|
@@ -9,11 +9,79 @@ import { escapeMarkdown } from '../escape-markdown.js';
|
|
|
9
9
|
import { renderBudgetTrailer } from '../render-budget.js';
|
|
10
10
|
import { getOpenAlexService, inferIdentifier, PMCID_NOT_INDEXED_HINT, } from '../../../services/openalex/openalex-service.js';
|
|
11
11
|
import { ENTITY_TYPES } from '../../../services/openalex/types.js';
|
|
12
|
+
/** The singular noun for an entity type, as a record of it is named: `funders` → `funder`. */
|
|
13
|
+
function entityNoun(entityType) {
|
|
14
|
+
return entityType.replace(/s$/, '');
|
|
15
|
+
}
|
|
16
|
+
function withArticle(noun) {
|
|
17
|
+
return `${/^[aeiou]/.test(noun) ? 'an' : 'a'} ${noun}`;
|
|
18
|
+
}
|
|
19
|
+
/** `a`, `a or b`, `a, b, or c`. */
|
|
20
|
+
function orList(words) {
|
|
21
|
+
return words.length < 3
|
|
22
|
+
? words.join(' or ')
|
|
23
|
+
: `${words.slice(0, -1).join(', ')}, or ${words.at(-1)}`;
|
|
24
|
+
}
|
|
25
|
+
function hasFilters(input) {
|
|
26
|
+
return input.filters !== undefined && Object.keys(input.filters).length > 0;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Where a name search looked: ` among institutions with filters={…}`, or ` across all entity
|
|
30
|
+
* types`. The filters are JSON-encoded, the form the search tools echo them in, so a quote or
|
|
31
|
+
* line break in a value cannot leave the notice's line.
|
|
32
|
+
*/
|
|
33
|
+
function nameSearchScope(input) {
|
|
34
|
+
const types = input.entity_type ? ` among ${input.entity_type}` : ' across all entity types';
|
|
35
|
+
return hasFilters(input) ? `${types} with filters=${JSON.stringify(input.filters)}` : types;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* What to try after a name search matched nothing. Filters come first when they applied, since
|
|
39
|
+
* one may exclude the match; omitting entity_type is never offered alongside them, as filters
|
|
40
|
+
* apply to a name search only with entity_type. With no entity_type, a typed search is the
|
|
41
|
+
* suggestion: cross-type autocomplete misses names a one-type search finds (`p53` among keywords).
|
|
42
|
+
*/
|
|
43
|
+
function nameMissAdvice(input) {
|
|
44
|
+
if (hasFilters(input)) {
|
|
45
|
+
return 'Loosen or drop filters first — they may exclude the match — then try a shorter name or alternate spelling.';
|
|
46
|
+
}
|
|
47
|
+
return input.entity_type
|
|
48
|
+
? 'Try a shorter name, alternate spelling, or omit entity_type to search across all types.'
|
|
49
|
+
: 'Try a shorter name or alternate spelling, or pass entity_type to search one type — a one-type search can find names the cross-type search misses.';
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The notice for a bare OpenAlex ID that resolved nothing (`missed` names that), followed by
|
|
53
|
+
* what its name search did: the matches it found, nothing, a failure upstream — or, with
|
|
54
|
+
* `filters` and no entity_type, no name search at all.
|
|
55
|
+
*/
|
|
56
|
+
function idMissNotice(missed, nameFallback, matched, input) {
|
|
57
|
+
if (!nameFallback) {
|
|
58
|
+
return `${missed}. It was not searched as a name: filters apply to a name search only with entity_type — pass entity_type to search one type by name with these filters, or drop filters to search every type.`;
|
|
59
|
+
}
|
|
60
|
+
if (nameFallback.failedReason !== undefined) {
|
|
61
|
+
return `${missed}, and the name search it fell back to failed upstream (reason ${nameFallback.failedReason}) — call again to complete it.`;
|
|
62
|
+
}
|
|
63
|
+
return matched > 0
|
|
64
|
+
? `${missed}, so it was searched as a name${nameSearchScope(input)} instead.`
|
|
65
|
+
: `${missed}, and as a name it matched nothing${nameSearchScope(input)}. ${nameMissAdvice(input)}`;
|
|
66
|
+
}
|
|
12
67
|
export const resolveNameTool = tool('openalex_resolve_name', {
|
|
13
|
-
description: "Resolve a name or an identifier to an OpenAlex ID. ALWAYS use this before filtering by entity — names are ambiguous, IDs are not. A name returns up to 10 autocomplete matches with disambiguation hints. An identifier — OpenAlex ID, DOI, ORCID, ROR, PMID, or ISSN, bare or in URL form — resolves directly to the
|
|
68
|
+
description: "Resolve a name or an identifier to an OpenAlex ID. ALWAYS use this before filtering by entity — names are ambiguous, IDs are not. A name returns up to 10 autocomplete matches with disambiguation hints. An identifier — OpenAlex ID, DOI, ORCID, ROR, PMID, or ISSN, bare or in URL form — resolves directly to the record it addresses instead of running a name search. Short names share the bare OpenAlex ID shape (keyword p53 reads as publisher ID P53), so a bare OpenAlex ID that resolves nothing is searched as a name next. Two identifiers can address more than one entity type: a ROR names an organization's institution, funder, and publisher records alike, so it returns each one that exists (institution first) unless entity_type picks one of those three; and a Crossref Funder Registry DOI (10.13039/…) resolves to the funder unless entity_type is works. A PMCID is recognized as well, bare or as a PubMed Central URL, but OpenAlex indexes no PMCIDs, so it resolves nothing — pass the work's PMID or DOI instead.",
|
|
14
69
|
sourceUrl: 'https://github.com/cyanheads/openalex-mcp-server/blob/main/src/mcp-server/tools/definitions/resolve-name.tool.ts',
|
|
15
70
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
|
|
16
71
|
errors: [
|
|
72
|
+
{
|
|
73
|
+
reason: 'unmatched_quote_in_filter_value',
|
|
74
|
+
code: JsonRpcErrorCode.ValidationError,
|
|
75
|
+
when: 'A filter value sent unquoted has an unmatched double quote.',
|
|
76
|
+
recovery: 'Pair double quotes used for a search phrase, or remove the stray quote.',
|
|
77
|
+
thrownBy: 'service',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
reason: 'filters_without_entity_type',
|
|
81
|
+
code: JsonRpcErrorCode.ValidationError,
|
|
82
|
+
when: 'A name `query` passed `filters` without `entity_type`. Filter fields belong to one entity type, and a name search across every type takes no filters.',
|
|
83
|
+
recovery: 'Add entity_type naming the type the filter fields belong to, or drop `filters` to search every entity type by name.',
|
|
84
|
+
},
|
|
17
85
|
{
|
|
18
86
|
reason: 'rate_limited',
|
|
19
87
|
code: JsonRpcErrorCode.RateLimited,
|
|
@@ -30,6 +98,14 @@ export const resolveNameTool = tool('openalex_resolve_name', {
|
|
|
30
98
|
recovery: "This server's daily OpenAlex budget is spent and refills at midnight UTC — retrying before then will not succeed.",
|
|
31
99
|
thrownBy: 'service',
|
|
32
100
|
},
|
|
101
|
+
{
|
|
102
|
+
reason: 'upstream_plan_required',
|
|
103
|
+
code: JsonRpcErrorCode.Forbidden,
|
|
104
|
+
when: 'A filter is one OpenAlex serves only on a paid plan — created_date, updated_date, or a from_/to_ form of either (HTTP 429 "Plan upgrade required").',
|
|
105
|
+
retryable: false,
|
|
106
|
+
recovery: 'Drop the plan-gated filter and rerun; retrying it unchanged will not succeed. To bound works by date, filter on publication_date, from_publication_date, or to_publication_date, which need no paid plan.',
|
|
107
|
+
thrownBy: 'service',
|
|
108
|
+
},
|
|
33
109
|
{
|
|
34
110
|
reason: 'upstream_timeout',
|
|
35
111
|
code: JsonRpcErrorCode.Timeout,
|
|
@@ -60,13 +136,41 @@ export const resolveNameTool = tool('openalex_resolve_name', {
|
|
|
60
136
|
recovery: 'Confirm the API key has access to autocomplete, then retry the request.',
|
|
61
137
|
thrownBy: 'service',
|
|
62
138
|
},
|
|
139
|
+
{
|
|
140
|
+
reason: 'id_dot_segment',
|
|
141
|
+
code: JsonRpcErrorCode.ValidationError,
|
|
142
|
+
when: 'An identifier `query` holds a `.` or `..` path segment, written plainly or percent-encoded.',
|
|
143
|
+
recovery: 'Pass the identifier itself — an OpenAlex ID, DOI, ORCID, ROR, PMID, or ISSN — with no relative path segments, or pass a name to search for instead.',
|
|
144
|
+
thrownBy: 'service',
|
|
145
|
+
},
|
|
63
146
|
{
|
|
64
147
|
reason: 'comma_in_filter_value',
|
|
65
148
|
code: JsonRpcErrorCode.InvalidParams,
|
|
66
|
-
when: 'A `filters` value contains a comma, which collides with the OpenAlex filter separator.',
|
|
149
|
+
when: 'A `filters` value contains a comma, which collides with the OpenAlex filter separator, on a field that takes no phrase. Free-text search filters (any `.search` key, such as display_name.search) and fields matched as whole text (display_name, awards.funder_display_name, awards.funder_award_id, geo.city, geo.region, raw_affiliation_strings, block_key, parsed_longest_name, biblio fields) are exempt: a comma there is sent quoted, as part of the phrase.',
|
|
67
150
|
recovery: 'Use `|` for OR within a filter value (e.g. "2020|2021"), or move a free-text phrase containing commas into the `query` parameter.',
|
|
68
151
|
thrownBy: 'service',
|
|
69
152
|
},
|
|
153
|
+
{
|
|
154
|
+
reason: 'invalid_country_code',
|
|
155
|
+
code: JsonRpcErrorCode.ValidationError,
|
|
156
|
+
when: 'A country filter (a key ending in country_code, country_codes, or countries) holds a segment that cannot be a country code, such as a misspelled name, an unassigned number, "unknown", or two codes joined by a space ("DE US").',
|
|
157
|
+
recovery: 'Pass the country as an ISO 3166-1 alpha-2 code such as DE, US, or GB (an alpha-3 code, numeric code, or English name is converted), or null for records with no country.',
|
|
158
|
+
thrownBy: 'service',
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
reason: 'mixed_and_or_in_filter_value',
|
|
162
|
+
code: JsonRpcErrorCode.ValidationError,
|
|
163
|
+
when: 'A `filters` value puts "|" (OR) beside an AND operator — a "+", or a space on a field where words mean AND (on a country field a space is always part of a country name, and inside a language name it is part of the name). OpenAlex splits the value on "|" first and drops every alternative that ANDs more than one value, so no single value can carry both.',
|
|
164
|
+
recovery: 'Keep "|" and the AND operator in separate filter keys: OR the alternatives in this key and put the AND in a second key that reaches the same values — on works, {"authorships.institutions.country_code": "DE|FR", "institutions.country_code": "US"} matches (DE or FR) and US. The filters object holds each key once, so where no second key fits, run one call per alternative instead.',
|
|
165
|
+
thrownBy: 'service',
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
reason: 'quote_in_filter_value',
|
|
169
|
+
code: JsonRpcErrorCode.ValidationError,
|
|
170
|
+
when: 'A `filters` value sent to OpenAlex double-quoted holds a double quote inside its outer pair — a value the server quotes (a multi-word value on a field matched as whole text, or a value holding a comma on such a field or on a free-text search filter), or one the caller wrapped in double quotes on any filter but a free-text search.',
|
|
171
|
+
recovery: 'Remove the double quote from the value; a phrase is matched without quoting its own text.',
|
|
172
|
+
thrownBy: 'service',
|
|
173
|
+
},
|
|
70
174
|
{
|
|
71
175
|
reason: 'upstream_invalid_params',
|
|
72
176
|
code: JsonRpcErrorCode.InvalidParams,
|
|
@@ -109,15 +213,15 @@ export const resolveNameTool = tool('openalex_resolve_name', {
|
|
|
109
213
|
entity_type: z
|
|
110
214
|
.enum(ENTITY_TYPES)
|
|
111
215
|
.optional()
|
|
112
|
-
.describe('Entity type to search. Omit for cross-entity search (useful when entity type is unknown).
|
|
216
|
+
.describe('Entity type to search. Omit for cross-entity search (useful when entity type is unknown). With an identifier `query` it narrows only an identifier that can address more than one type: a ROR to institutions, funders, or publishers (omit it to get every one of the three that exists), and a Funder Registry DOI (10.13039/…) to works instead of the funder. Every other identifier resolves as the type it belongs to, whatever this names — except under keywords, where a bare OpenAlex ID shape ("P53") is searched as a keyword name, since keyword IDs are slugs.'),
|
|
113
217
|
query: z
|
|
114
218
|
.string()
|
|
115
219
|
.min(1)
|
|
116
|
-
.describe('Name or partial name to resolve. Also accepts an identifier, bare or in URL form — OpenAlex ID ("W2741809807", "F4320332161"), DOI ("10.1038/nature12373"), ORCID ("0000-0002-1825-0097"), ROR ("https://ror.org/00hx57361"), PMID ("12345678" or "https://pubmed.ncbi.nlm.nih.gov/12345678"), ISSN ("1234-5678") — which resolves straight to
|
|
220
|
+
.describe('Name or partial name to resolve. Also accepts an identifier, bare or in URL form — OpenAlex ID ("W2741809807", "F4320332161", or an OpenAlex record-page or API URL such as "https://openalex.org/works/W2741809807"), DOI ("10.1038/nature12373", or a funder\'s Funder Registry DOI such as "10.13039/100000001"), ORCID ("0000-0002-1825-0097"), ROR ("https://ror.org/00hx57361"), PMID ("12345678" or "https://pubmed.ncbi.nlm.nih.gov/12345678"), ISSN ("1234-5678") — which resolves straight to the record it addresses, or for a ROR up to three (see entity_type), instead of running a name search. A bare OpenAlex ID that resolves nothing is then searched as a name — under entity_type when given, and not at all when filters come without entity_type — since short names share its shape ("P53" is a keyword); under entity_type keywords it is searched as a name from the start. A keyword URL ("https://openalex.org/keywords/groundwater") resolves the same way; a bare keyword slug reads as a name and runs a name search, which finds it too. A PMCID ("PMC1234567" or a PubMed Central URL) is recognized but OpenAlex indexes no PMCIDs, so it resolves nothing — pass the work\'s PMID or DOI instead.'),
|
|
117
221
|
filters: z
|
|
118
222
|
.record(z.string(), z.string())
|
|
119
223
|
.optional()
|
|
120
|
-
.describe('Narrow autocomplete results with
|
|
224
|
+
.describe('Narrow autocomplete results with a filter record object, using the openalex_search_entities value syntax; native string input is unavailable here. Example: restrict to a specific country or publication year range. Country fields take ISO 3166-1 alpha-2 codes ({"country_code": "DE"} on institutions) and `language` takes ISO 639-1 codes ("en"); alpha-3, numeric, ISO 639-2, and English-name forms are converted — a multi-word name is one value, so "South Korea|Japan" ORs two countries — and a value that cannot be a country code is rejected. A multi-word value on a field matched as whole text (display_name, geo.city, geo.region, awards.funder_display_name) matches as one phrase ({"geo.city": "New York"} on institutions; a comma, as in "University of California, Berkeley", is part of it, and it cannot contain a double quote of its own), "!" and "|" included, but cannot be ANDed with "+" in the same field. A value sent unquoted must have paired double quotes; balanced search phrases remain valid. A value mixing "|" with an AND operator — a "+", or a space on a field where words mean AND — is rejected, since OpenAlex drops every "|" alternative that ANDs more than one value; put the AND in a second key instead. Requires entity_type — filter fields belong to one entity type, so a name search across every type takes none, and a name query passing filters without entity_type is rejected. Applies to name queries only — an identifier lookup returns the records it addresses regardless.'),
|
|
121
225
|
}),
|
|
122
226
|
output: z.object({
|
|
123
227
|
results: z
|
|
@@ -148,7 +252,7 @@ export const resolveNameTool = tool('openalex_resolve_name', {
|
|
|
148
252
|
.describe('Disambiguation context as plain text — last institution (authors), host organization (sources), place or country (institutions); author names (works) from a name search, publication year from an identifier lookup. null when the record carries none.'),
|
|
149
253
|
})
|
|
150
254
|
.describe('A single autocomplete match with its ID, name, entity type, activity stats, and a disambiguation hint.'))
|
|
151
|
-
.describe('
|
|
255
|
+
.describe('Matches: up to 10 autocomplete matches for a name; for an identifier, the record it addresses — for a ROR, up to three, institution then funder then publisher — or none.'),
|
|
152
256
|
}),
|
|
153
257
|
// Agent-facing success-path context — a notice when the query matched nothing so the
|
|
154
258
|
// caller sees explicit guidance rather than a silent empty array, plus the OpenAlex budget
|
|
@@ -158,7 +262,7 @@ export const resolveNameTool = tool('openalex_resolve_name', {
|
|
|
158
262
|
notice: z
|
|
159
263
|
.string()
|
|
160
264
|
.optional()
|
|
161
|
-
.describe('Guidance notice. Set when nothing matched (echoes the query and suggests corrections) or when an identifier query was passed name-search parameters that do not apply to it. Absent otherwise.'),
|
|
265
|
+
.describe('Guidance notice. Set when nothing matched (echoes the query, and the filters when a name search applied them, and suggests corrections), when a bare OpenAlex ID resolved nothing and the query was searched as a name instead (names both outcomes, or why the name search did not run or finish), when an identifier query was passed name-search parameters that do not apply to it, or when one of the lookups for a ROR failed upstream (names the entity type whose record may be missing). Absent otherwise.'),
|
|
162
266
|
budget: z
|
|
163
267
|
.object({
|
|
164
268
|
costUsd: z
|
|
@@ -181,51 +285,88 @@ export const resolveNameTool = tool('openalex_resolve_name', {
|
|
|
181
285
|
},
|
|
182
286
|
async handler(input, ctx) {
|
|
183
287
|
const service = getOpenAlexService();
|
|
184
|
-
// An identifier addresses
|
|
185
|
-
//
|
|
186
|
-
//
|
|
187
|
-
const identifier = inferIdentifier(input.query);
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
:
|
|
191
|
-
|
|
288
|
+
// An identifier addresses its own record, so it goes to the deterministic by-ID lookup.
|
|
289
|
+
// Autocomplete only ever matched identifiers by accident — it indexes the external-ID URL,
|
|
290
|
+
// so the bare forms and several native OpenAlex IDs miss.
|
|
291
|
+
const identifier = inferIdentifier(input.query, input.entity_type);
|
|
292
|
+
const nameSearch = {
|
|
293
|
+
entityType: input.entity_type,
|
|
294
|
+
query: input.query,
|
|
295
|
+
filters: input.filters,
|
|
296
|
+
};
|
|
297
|
+
// JSON-encoded so a line break in the query cannot start a heading or end a blockquote.
|
|
298
|
+
const query = JSON.stringify(input.query);
|
|
299
|
+
if (!identifier) {
|
|
300
|
+
// Cross-entity autocomplete rejects `filter` outright, so this pair can only fail upstream.
|
|
301
|
+
if (hasFilters(input) && !input.entity_type) {
|
|
302
|
+
throw ctx.fail('filters_without_entity_type', '`filters` applies to a name search only with entity_type — filter fields belong to one entity type, and a search across every type takes none.');
|
|
303
|
+
}
|
|
304
|
+
const result = await service.autocomplete(nameSearch, ctx);
|
|
305
|
+
ctx.log.info('Name resolved', {
|
|
192
306
|
query: input.query,
|
|
193
|
-
|
|
194
|
-
|
|
307
|
+
entityType: input.entity_type ?? 'all',
|
|
308
|
+
resolvedVia: 'autocomplete',
|
|
309
|
+
matchCount: result.results.length,
|
|
310
|
+
});
|
|
311
|
+
if (result.results.length === 0) {
|
|
312
|
+
ctx.enrich.notice(`No matches for ${query}${nameSearchScope(input)}. ${nameMissAdvice(input)}`);
|
|
313
|
+
}
|
|
314
|
+
return result;
|
|
315
|
+
}
|
|
316
|
+
// A bare OpenAlex ID shape is also a short name's, so one that resolves nothing is searched
|
|
317
|
+
// as a name next — unless filters came without entity_type, which no name search takes.
|
|
318
|
+
const canSearchByName = identifier.mayBeName === true && (input.entity_type !== undefined || !hasFilters(input));
|
|
319
|
+
const { results, failedEntityTypes, nameFallback } = await service.resolveIdentifier(identifier, ctx, canSearchByName ? nameSearch : undefined, input.query);
|
|
195
320
|
ctx.log.info('Name resolved', {
|
|
196
321
|
query: input.query,
|
|
197
|
-
entityType: identifier
|
|
198
|
-
resolvedVia:
|
|
199
|
-
matchCount:
|
|
322
|
+
entityType: identifier.entityTypes.join(','),
|
|
323
|
+
resolvedVia: nameFallback ? 'autocomplete' : identifier.scheme,
|
|
324
|
+
matchCount: results.length,
|
|
200
325
|
});
|
|
326
|
+
const scheme = identifier.scheme === 'openalex' ? 'OpenAlex ID' : identifier.scheme.toUpperCase();
|
|
327
|
+
const nouns = identifier.entityTypes.map(entityNoun);
|
|
328
|
+
const missed = `No ${orList(nouns)} in OpenAlex for ${scheme} ${query}`;
|
|
329
|
+
// A bare ID that missed was read as a name next, so its notice covers both readings.
|
|
330
|
+
if (identifier.mayBeName && (nameFallback || results.length === 0)) {
|
|
331
|
+
ctx.enrich.notice(idMissNotice(missed, nameFallback, results.length, input));
|
|
332
|
+
return { results };
|
|
333
|
+
}
|
|
201
334
|
const notices = [];
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
if (result.results.length === 0) {
|
|
335
|
+
const ignored = [];
|
|
336
|
+
if (input.entity_type && !identifier.entityTypes.includes(input.entity_type)) {
|
|
337
|
+
ignored.push(`entity_type="${input.entity_type}"`);
|
|
338
|
+
}
|
|
339
|
+
if (hasFilters(input))
|
|
340
|
+
ignored.push('filters');
|
|
341
|
+
if (ignored.length > 0) {
|
|
342
|
+
const addressed = nouns.length === 1 ? `one ${nouns[0]}` : orList(nouns.map(withArticle));
|
|
343
|
+
notices.push(`Resolved ${query} by ${scheme} — it identifies ${addressed} directly, so ${ignored.join(' and ')} did not apply.`);
|
|
344
|
+
}
|
|
345
|
+
if (results.length === 0) {
|
|
346
|
+
if (identifier.scheme === 'pmcid') {
|
|
215
347
|
// A PMCID is the one identifier whose miss says nothing about the identifier: it is
|
|
216
348
|
// well formed and OpenAlex still holds no record for it, so "check it for a typo"
|
|
217
349
|
// sends the caller to re-check something that was never wrong.
|
|
218
|
-
notices.push(
|
|
219
|
-
|
|
220
|
-
|
|
350
|
+
notices.push(`${missed}. ${PMCID_NOT_INDEXED_HINT}`);
|
|
351
|
+
}
|
|
352
|
+
else if (identifier.scheme === 'ror' && input.entity_type && nouns.length === 1) {
|
|
353
|
+
notices.push(`${missed} under entity_type="${input.entity_type}". One ROR can name an institution, a funder, and a publisher — omit entity_type to look up all three.`);
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
notices.push(`${missed}. An identifier either resolves or does not — check it for a typo, or search for the entity by name instead.`);
|
|
357
|
+
if (identifier.scheme === 'doi' && identifier.entityTypes[0] === 'funders') {
|
|
358
|
+
notices.push('Some works carry a Funder Registry DOI too — pass entity_type="works" to look it up as a work.');
|
|
359
|
+
}
|
|
221
360
|
}
|
|
222
361
|
}
|
|
223
|
-
|
|
224
|
-
|
|
362
|
+
if (failedEntityTypes) {
|
|
363
|
+
const failed = failedEntityTypes.map(entityNoun);
|
|
364
|
+
const lookups = failed.length === 1 ? 'lookup' : 'lookups';
|
|
365
|
+
notices.push(`The ${failed.join(' and ')} ${lookups} failed upstream, so any ${orList(failed)} record for ${scheme} ${query} is missing from these results — call again to complete them.`);
|
|
225
366
|
}
|
|
226
367
|
if (notices.length > 0)
|
|
227
368
|
ctx.enrich.notice(notices.join(' '));
|
|
228
|
-
return
|
|
369
|
+
return { results };
|
|
229
370
|
},
|
|
230
371
|
format: (result) => {
|
|
231
372
|
if (result.results.length === 0) {
|
|
@@ -240,7 +381,8 @@ export const resolveNameTool = tool('openalex_resolve_name', {
|
|
|
240
381
|
if (r.external_id)
|
|
241
382
|
details.push(escapeMarkdown(r.external_id));
|
|
242
383
|
details.push(`${r.cited_by_count} citations`);
|
|
243
|
-
|
|
384
|
+
if (r.works_count !== null)
|
|
385
|
+
details.push(`${r.works_count} works`);
|
|
244
386
|
if (r.hint)
|
|
245
387
|
details.push(escapeMarkdown(r.hint));
|
|
246
388
|
lines.push(details.join(' | '));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-name.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/resolve-name.tool.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"resolve-name.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/resolve-name.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,10 +22,13 @@ export declare const searchEntitiesTool: import("@cyanheads/mcp-ts-core").ToolDe
|
|
|
22
22
|
keyword: "keyword";
|
|
23
23
|
semantic: "semantic";
|
|
24
24
|
}>>;
|
|
25
|
-
filters: z.ZodOptional<z.
|
|
25
|
+
filters: z.ZodOptional<z.ZodPreprocess<z.ZodObject<{
|
|
26
|
+
value: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
27
|
+
converted: z.ZodBoolean;
|
|
28
|
+
}, z.core.$strip>, unknown>>;
|
|
26
29
|
sort: z.ZodOptional<z.ZodString>;
|
|
27
30
|
select: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
28
|
-
per_page: z.ZodDefault<z.ZodNumber
|
|
31
|
+
per_page: z.ZodDefault<z.ZodLazy<z.ZodNumber>>;
|
|
29
32
|
cursor: z.ZodOptional<z.ZodString>;
|
|
30
33
|
page: z.ZodOptional<z.ZodNumber>;
|
|
31
34
|
sample: z.ZodOptional<z.ZodNumber>;
|
|
@@ -65,6 +68,24 @@ export declare const searchEntitiesTool: import("@cyanheads/mcp-ts-core").ToolDe
|
|
|
65
68
|
}, z.core.$strip>>>;
|
|
66
69
|
over_budget: z.ZodOptional<z.ZodBoolean>;
|
|
67
70
|
}, z.core.$strip>, readonly [{
|
|
71
|
+
readonly reason: "invalid_filter_string";
|
|
72
|
+
readonly code: JsonRpcErrorCode.ValidationError;
|
|
73
|
+
readonly when: "A native filter string has an incomplete clause or unmatched double quotes.";
|
|
74
|
+
readonly recovery: "Pass filters as a record object with one key per field, and pair any double quotes in search phrases.";
|
|
75
|
+
readonly thrownBy: "service";
|
|
76
|
+
}, {
|
|
77
|
+
readonly reason: "duplicate_filter_string_key";
|
|
78
|
+
readonly code: JsonRpcErrorCode.ValidationError;
|
|
79
|
+
readonly when: "A native filter string repeats an exact key.";
|
|
80
|
+
readonly recovery: "A filters record object holds one key per field; combine alternatives with \"|\", or run separate calls.";
|
|
81
|
+
readonly thrownBy: "service";
|
|
82
|
+
}, {
|
|
83
|
+
readonly reason: "unmatched_quote_in_filter_value";
|
|
84
|
+
readonly code: JsonRpcErrorCode.ValidationError;
|
|
85
|
+
readonly when: "A filter value sent unquoted has an unmatched double quote.";
|
|
86
|
+
readonly recovery: "Pair double quotes used for a search phrase, or remove the stray quote.";
|
|
87
|
+
readonly thrownBy: "service";
|
|
88
|
+
}, {
|
|
68
89
|
readonly reason: "semantic_per_page_cap";
|
|
69
90
|
readonly code: JsonRpcErrorCode.ValidationError;
|
|
70
91
|
readonly when: "A search (no `id`) set per_page above the semantic-search cap of 50.";
|
|
@@ -118,7 +139,19 @@ export declare const searchEntitiesTool: import("@cyanheads/mcp-ts-core").ToolDe
|
|
|
118
139
|
readonly reason: "slice_field_not_array";
|
|
119
140
|
readonly code: JsonRpcErrorCode.ValidationError;
|
|
120
141
|
readonly when: "The `slice` field is `*`, or is not an array on the record at `id` — absent, null, a scalar, or an object.";
|
|
121
|
-
readonly recovery: "Name a top-level array field of that record, such as authorships, referenced_works, or locations; openalex_describe_fields(entity_type, \"select\") lists the field names.";
|
|
142
|
+
readonly recovery: "Name a top-level array field of that record, such as authorships, author_list, referenced_works, or locations; openalex_describe_fields(entity_type, \"select\") lists the field names.";
|
|
143
|
+
}, {
|
|
144
|
+
readonly reason: "id_type_mismatch";
|
|
145
|
+
readonly code: JsonRpcErrorCode.ValidationError;
|
|
146
|
+
readonly when: "`id` is a native OpenAlex ID whose letter names another entity type than `entity_type`, or a concept ID (C…), a type this server does not serve.";
|
|
147
|
+
readonly recovery: "Pass the entity_type the ID letter names — W works, A authors, S sources, I institutions, T topics, P publishers, F funders. A concept ID (C…) has no entity_type here; search topics for the concept by name with openalex_resolve_name instead.";
|
|
148
|
+
readonly thrownBy: "service";
|
|
149
|
+
}, {
|
|
150
|
+
readonly reason: "id_dot_segment";
|
|
151
|
+
readonly code: JsonRpcErrorCode.ValidationError;
|
|
152
|
+
readonly when: "`id` holds a `.` or `..` path segment, written plainly or percent-encoded.";
|
|
153
|
+
readonly recovery: "Pass the identifier itself — an OpenAlex ID, DOI, ORCID, ROR, PMID, or ISSN — with no relative path segments, or drop `id` and search with `query` or `filters`.";
|
|
154
|
+
readonly thrownBy: "service";
|
|
122
155
|
}, {
|
|
123
156
|
readonly reason: "entity_not_found";
|
|
124
157
|
readonly code: JsonRpcErrorCode.NotFound;
|
|
@@ -139,6 +172,13 @@ export declare const searchEntitiesTool: import("@cyanheads/mcp-ts-core").ToolDe
|
|
|
139
172
|
readonly retryable: false;
|
|
140
173
|
readonly recovery: "This server's daily OpenAlex budget is spent and refills at midnight UTC — retrying before then will not succeed.";
|
|
141
174
|
readonly thrownBy: "service";
|
|
175
|
+
}, {
|
|
176
|
+
readonly reason: "upstream_plan_required";
|
|
177
|
+
readonly code: JsonRpcErrorCode.Forbidden;
|
|
178
|
+
readonly when: "A filter is one OpenAlex serves only on a paid plan — created_date, updated_date, or a from_/to_ form of either (HTTP 429 \"Plan upgrade required\").";
|
|
179
|
+
readonly retryable: false;
|
|
180
|
+
readonly recovery: "Drop the plan-gated filter and rerun; retrying it unchanged will not succeed. To bound works by date, filter on publication_date, from_publication_date, or to_publication_date, which need no paid plan.";
|
|
181
|
+
readonly thrownBy: "service";
|
|
142
182
|
}, {
|
|
143
183
|
readonly reason: "upstream_timeout";
|
|
144
184
|
readonly code: JsonRpcErrorCode.Timeout;
|
|
@@ -149,7 +189,7 @@ export declare const searchEntitiesTool: import("@cyanheads/mcp-ts-core").ToolDe
|
|
|
149
189
|
}, {
|
|
150
190
|
readonly reason: "upstream_unavailable";
|
|
151
191
|
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
152
|
-
readonly when: "OpenAlex was unreachable or unusable — HTTP 503, a connection failure,
|
|
192
|
+
readonly when: "OpenAlex was unreachable or unusable — HTTP 503, a connection failure, a body that was empty, HTML, or unparseable JSON, or a semantic search whose query embedding failed upstream (HTTP 400 `Failed to embed query:`, or semantic search not configured).";
|
|
153
193
|
readonly retryable: true;
|
|
154
194
|
readonly recovery: "Wait and retry; check https://openalex.org for service status if the outage persists.";
|
|
155
195
|
readonly thrownBy: "service";
|
|
@@ -168,8 +208,26 @@ export declare const searchEntitiesTool: import("@cyanheads/mcp-ts-core").ToolDe
|
|
|
168
208
|
}, {
|
|
169
209
|
readonly reason: "comma_in_filter_value";
|
|
170
210
|
readonly code: JsonRpcErrorCode.InvalidParams;
|
|
171
|
-
readonly when: "A filter value contains a comma, which collides with the OpenAlex filter separator.";
|
|
172
|
-
readonly recovery: "Use `|` for OR within a filter value (e.g. \"2020|2021\"), or
|
|
211
|
+
readonly when: "A filter value contains a comma, which collides with the OpenAlex filter separator, on a field that takes no phrase. Free-text search filters (any `.search` key, such as title.search or abstract.search.exact) and fields matched as whole text (display_name, awards.funder_display_name, awards.funder_award_id, geo.city, geo.region, raw_affiliation_strings, block_key, parsed_longest_name, biblio fields) are exempt: a comma there is sent quoted, as part of the phrase.";
|
|
212
|
+
readonly recovery: "Use `|` for OR within a filter value (e.g. \"2020|2021\"), or move a phrase that contains commas into a free-text search filter such as title.search or raw_affiliation_strings.search, or into the `query` parameter.";
|
|
213
|
+
readonly thrownBy: "service";
|
|
214
|
+
}, {
|
|
215
|
+
readonly reason: "invalid_country_code";
|
|
216
|
+
readonly code: JsonRpcErrorCode.ValidationError;
|
|
217
|
+
readonly when: "A country filter (a key ending in country_code, country_codes, or countries) holds a segment that cannot be a country code, such as a misspelled name, an unassigned number, \"unknown\", or two codes joined by a space (\"DE US\").";
|
|
218
|
+
readonly recovery: "Pass the country as an ISO 3166-1 alpha-2 code such as DE, US, or GB (an alpha-3 code, numeric code, or English name is converted), or null for records with no country.";
|
|
219
|
+
readonly thrownBy: "service";
|
|
220
|
+
}, {
|
|
221
|
+
readonly reason: "mixed_and_or_in_filter_value";
|
|
222
|
+
readonly code: JsonRpcErrorCode.ValidationError;
|
|
223
|
+
readonly when: "A filter value puts \"|\" (OR) beside an AND operator — a \"+\", or a space on a field where words mean AND (on a country field a space is always part of a country name, and inside a language name it is part of the name). OpenAlex splits the value on \"|\" first and drops every alternative that ANDs more than one value, so no single value can carry both.";
|
|
224
|
+
readonly recovery: "Keep \"|\" and the AND operator in separate filter keys: OR the alternatives in this key and put the AND in a second key that reaches the same values — on works, {\"authorships.institutions.country_code\": \"DE|FR\", \"institutions.country_code\": \"US\"} matches (DE or FR) and US. The filters object holds each key once, so where no second key fits, run one call per alternative instead.";
|
|
225
|
+
readonly thrownBy: "service";
|
|
226
|
+
}, {
|
|
227
|
+
readonly reason: "quote_in_filter_value";
|
|
228
|
+
readonly code: JsonRpcErrorCode.ValidationError;
|
|
229
|
+
readonly when: "A filter value sent to OpenAlex double-quoted holds a double quote inside its outer pair — a value the server quotes (a multi-word value on a field matched as whole text, or a value holding a comma on such a field or on a free-text search filter), or one the caller wrapped in double quotes on any filter but a free-text search.";
|
|
230
|
+
readonly recovery: "Remove the double quote from the value; a phrase is matched without quoting its own text.";
|
|
173
231
|
readonly thrownBy: "service";
|
|
174
232
|
}, {
|
|
175
233
|
readonly reason: "upstream_invalid_params";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-entities.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-entities.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"search-entities.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-entities.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AA4HjE,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqsB7B,CAAC"}
|