OpenAlex MCP Demo
by geraldineco.huggingface.geraldine/openalex-mcp
- Remote endpoint
- 9 tools
Tools
openalex_mcp_browse_topicsExplore the OpenAlex "aboutness" hierarchy. Four levels: 4 domains, 26 fields, 252 subfields, 4516 topics. Each record carries the short id, its parent levels, works_count and the filter key for that level — feed the id back into search_works or group_by. Returns: {"source": "openalex", "command": "browse_topics", "total_found": int, "returned": int, "results": [{"source": "openalex", "id": str, "url": str, "display_name": str, "level": str, "description": str | null, "works_count": int | null, "filter_key": str, "subfield": object, "field": object, "domain": object}], "level": str, "query_used": str | null, "filters_used": [str], "cost_usd": float | null, "error": str | null}openalex_mcp_classify_textPlace a text in the OpenAlex topic hierarchy. OpenAlex retired its /text endpoint. This tool rebuilds the capability: one semantic search finds the nearest works, then their topics are aggregated weighted by relevance and rolled up to subfields, fields and domains. It returns real OpenAlex identifiers at all four levels plus the filter keys needed to reuse them — feed the ids straight back into search_works. Returns its own shape, not the record envelope: this tool returns no records. Calls run on the anonymous daily budget unless an X-Openalex-Api-Key request header is sent, or the deployment configured a key of its own. Returns: {"source": "openalex", "command": "classify_text", "query_used": str, "truncated": bool, "based_on_works": int, "topics": [{"id": str, "display_name": str, "score": float, "works": int}], "subfields": [object], "fields": [object], "domains": [object], "keywords": [str], "filter_keys": object, "cost_usd": float | null, "error": str | null}openalex_mcp_get_citing_worksFetch the works that cite a given OpenAlex work, most-cited first. Forward citation lookup: who built on this paper. Resolve a DOI with lookup_by_doi first if you only have one — this tool takes an OpenAlex id. Calls run on the anonymous daily budget unless an X-Openalex-Api-Key request header is sent, or the deployment configured a key of its own. Returns: {"source": "openalex", "command": "get_citing_works", "total_found": int, "returned": int, "cited_work_id": str, "cost_usd": float | null, "results": [{"source": "openalex", "id": str, "title": str, "authors": [str], "doi": str | null, "url": str, "year": int | null, "journal": str | null, "cited_by_count": int}], "error": str | null}openalex_mcp_group_byCount along a dimension without retrieving any record. Answers "how many", "which are the top" and "how has it evolved" in one call, at the price of a single request whatever the size of the set being aggregated — the cheapest way to frame a corpus before walking it. Returns its own shape, not the record envelope: this tool returns no records. Returns: {"source": "openalex", "command": "group_by", "entity": str, "dimension": str, "query_used": str | null, "filters_used": str | null, "total_found": int | null, "groups_count": int | null, "groups": [{"key": str, "key_url": str | null, "key_display_name": str | null, "count": int}], "oql": str | null, "cost_usd": float | null, "error": str | null}openalex_mcp_lookup_by_doiResolve one or more DOIs to full OpenAlex work records. Free — single-entity lookups are not billed. Use this when the DOI is already known: it is exact, unlike search_works, and it answers for several DOIs in a single call. A DOI OpenAlex does not index is simply absent from the results. Returns: {"source": "openalex", "command": "lookup_by_doi", "total_found": int, "returned": int, "requested": int, "cost_usd": float | null, "results": [{"source": "openalex", "id": str, "title": str, "authors": [str], "doi": str | null, "url": str, "year": int | null, "journal": str | null}], "error": str | null}openalex_mcp_resolve_entityResolve a name to an OpenAlex entity — id, external id, and filter key. Free and fast. Backed by /autocomplete, which returns a filter_key alongside each suggestion: the API itself saying which filter that identifier belongs in ("authorships.institutions.lineage" for an institution, "topics.id" for a topic). Run this before filtering on a name. Autocomplete is prefix-based and diacritic-sensitive, and the two combine badly: "strasbourg" alone finds nothing because it is not a prefix of the name, and "universite de stras" finds nothing either because the name is spelled "Université". "université de stras" finds it on the first try. When the prefix match is empty, a widened search is tried and what it finds goes into "suggestions", never into "results", with "error" still set — the caller chooses. Returns: {"source": "openalex", "command": "resolve_entity", "total_found": int, "returned": int, "results": [{"source": "openalex", "id": str, "url": str, "display_name": str, "entity_type": sopenalex_mcp_search_semanticSearch OpenAlex by meaning rather than by keyword. Ranks works by semantic proximity to a descriptive text, so a paper matches even when it shares none of the words used to ask for it. Give it a sentence or a whole abstract, not two keywords. Use search_works instead when a keyword genuinely names the subject. Three limits come from the endpoint: no paging past the result cap, "total_found" always null because OpenAlex reports the cap and not a count, and date bounds expressed as years — the from/to dates search_works accepts are rejected here. Topic filters are rejected too. Calls run on the anonymous daily budget unless an X-Openalex-Api-Key request header is sent, or the deployment configured a key of its own. Returns: {"source": "openalex", "command": "search_semantic", "total_found": null, "returned": int, "query_used": str, "filters_used": [str], "truncated": bool, "cost_usd": float | null, "results": [{"source": "openalex", "id": str, "title": str, "authors": [str], "doi": str |openalex_mcp_search_worksSearch OpenAlex for academic works by keyword query. Query syntax: "phrase in quotes", "near each other"~5, fuzzy~2, AND/OR/NOT in uppercase. Wildcards (* and ?) work only with exact=true. Calls run on the anonymous daily budget unless an X-Openalex-Api-Key request header is sent, or the deployment configured a key of its own. Returns: {"source": "openalex", "command": "search_works", "total_found": int, "returned": int, "query_used": str, "filters_used": [str], "corpus": str, "oql": str | null, "cost_usd": float | null, "results": [{"source": "openalex", "id": str, "title": str, "authors": [str], "doi": str | null, "url": str, "year": int | null, "journal": str | null, "fwci": float | null, "primary_topic": object | null, "topics": [object]}], "error": str | null}openalex_mcp_translate_queryTranslate a query between OQL, OQO and a REST URL, and validate it. Three forms of the same query: OQL (readable text, "works where institution is Sorbonne Université"), OQO (a JSON object) and oxurl (the REST URL). "form" names what you are giving it. Translation never touches the index and is billed at the cheapest rate, so it is the way to check a filter before paying to run it — and how you find out that "institution is X" compiles to authorships.institutions.lineage rather than .id. Returns its own shape, not the record envelope: this tool returns no records. An invalid query comes back valid:false with the parser's own message — a diagnosis, not a failure. Returns: {"source": "openalex", "command": "translate_query", "form": str, "query_used": str, "valid": bool, "oql": str | null, "oql_oneline": str | null, "oqo": object | null, "oxurl": str | null, "api_url": str | null, "diagnostics": [object], "error": str | null}
No tool matches.
As the server's own listing gives them. We never call a tool.