OpenAlex MCP Demo
by geraldineco.huggingface.geraldine/openalex-mcp
Search scholarly works through the openalex database.
- Remote endpoint
- 9 tools
Uptime
Checked · every day
98.87%from 4 days of checks
Up without downtime on 3 of 4 days with data; down 60 minutes in all, on 31 October.
- No downtime
- Degraded
- Down over 5 minutes
- No data
- Not checked yet
Response time
Median 1313 ms, slowest 5% 1611 ms for the handshake and the tool list, over 30 days.
How far each check got
- Reached the address 93.7%
- Completed the handshake 25.0%
- Listed its tools 25.0%
9 tools at the last answer.
Every day
| Day | Result | Checks | Median |
|---|---|---|---|
| 3 Nov (today) | No downtime | 1 | 1611 ms |
| 2 Nov | No downtime | 1of 1 | 1313 ms |
| 1 Nov | No downtime | 1of 1 | 1465 ms |
| 31 Oct | Down 60 minutes | 13 | 1150 ms |
A failure counts as down time only when a second check five minutes later fails too. How we check
Connect to the publisher's own endpoint
Paste into Settings › Connectors › Add custom connector:
https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse Run in a terminal:
claude mcp add --transport sse openalex-mcp https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse Add to ~/.cursor/mcp.json:
Add to ~/.config/devin/mcp_config.json:
Add to mcp.json (Program › Install › Edit mcp.json):
Add to ~/.gemini/settings.json:
Add to config.json in oterm's data folder (~/Library/Application Support/oterm on macOS, ~/.local/share/oterm on Linux, %APPDATA%\oterm on Windows):
Add to ~/.config/eca/config.json (global) or .eca/config.json in the project:
{
"mcpServers": {
"openalex-mcp": {
"url": "https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse"
}
}
} Add to .vscode/mcp.json:
{
"servers": {
"openalex-mcp": {
"type": "sse",
"url": "https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse"
}
}
} Add to ~/.config/zed/settings.json:
{
"context_servers": {
"openalex-mcp": {
"url": "https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse"
}
}
} This server's endpoint speaks only SSE, which this client's documentation does not list among its transports; use another client for it.
Add to cline_mcp_settings.json (MCP Servers › Configure › Configure MCP Servers):
Add to anythingllm_mcp_servers.json in the AnythingLLM storage plugins directory:
Add to Augment Settings Panel – MCP section – Import from JSON (VS Code extension):
{
"mcpServers": {
"openalex-mcp": {
"type": "sse",
"url": "https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse"
}
}
} Add to ~/.continue/config.yaml:
mcpServers:
- name: "openalex-mcp"
type: sse
url: "https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse" Add to ~/.config/goose/config.yaml:
extensions:
"openalex-mcp":
type: streamable_http
name: "openalex-mcp"
enabled: true
uri: "https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse"
headers: {}
env_keys: []
envs: {}
timeout: 300 This server's endpoint speaks only SSE, which this client's documentation does not list among its transports; use another client for it.
Run in a terminal:
codex mcp add openalex-mcp --url https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse This server's endpoint speaks only SSE, which this client's documentation does not list among its transports; use another client for it.
Add to ~/.llm/config.json:
Add to resources/assets/config/mcp.json in the installed app:
Add to ~/.boltai/mcp.json:
Add to ~/.bob/settings/mcp.json (global) or .bob/mcp.json (project):
Add to ~/.kiro/settings/mcp.json (user) or .kiro/settings/mcp.json (workspace):
Add to ~/.kiro/settings/mcp.json (user) or .kiro/settings/mcp.json (workspace):
{
"mcpServers": {
"openalex-mcp": {
"url": "https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse"
}
}
} This server's endpoint speaks only SSE, which this client's documentation does not list among its transports; use another client for it.
Add to ~/.config/agenvoy/mcp.json:
{
"servers": {
"openalex-mcp": {
"url": "https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse"
}
}
} This server's endpoint speaks only SSE, which this client's documentation does not list among its transports; use another client for it.
Add to ~/.config/amp/settings.json (user) or .amp/settings.json (workspace):
{
"amp.mcpServers": {
"openalex-mcp": {
"url": "https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse"
}
}
} For agents: the install prompt
Every step above as one Markdown text, for an assistant installing it for you.
# Install the MCP server OpenAlex MCP Demo (`co.huggingface.geraldine/openalex-mcp`)
Its page: https://plug.directory/servers/co.huggingface.geraldine/openalex-mcp
It runs on the publisher's servers; the client connects to its URL.
Use the section for the person's client.
## Claude Desktop
Paste into Settings › Connectors › Add custom connector:
```text
https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse
```
## Claude Code
Run in a terminal:
```sh
claude mcp add --transport sse openalex-mcp https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse
```
## Cursor, Devin Desktop, LM Studio, Gemini CLI, oterm, ECA
Merge into the place for the person's client:
- Cursor: ~/.cursor/mcp.json
- Devin Desktop: ~/.config/devin/mcp_config.json
- LM Studio: mcp.json (Program › Install › Edit mcp.json)
- Gemini CLI: ~/.gemini/settings.json
- oterm: config.json in oterm's data folder (~/Library/Application Support/oterm on macOS, ~/.local/share/oterm on Linux, %APPDATA%\oterm on Windows)
- ECA: ~/.config/eca/config.json (global) or .eca/config.json in the project
```json
{
"mcpServers": {
"openalex-mcp": {
"url": "https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse"
}
}
}
```
## VS Code
Merge into .vscode/mcp.json:
```json
{
"servers": {
"openalex-mcp": {
"type": "sse",
"url": "https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse"
}
}
}
```
## Zed
This server's endpoint speaks only SSE, which this client's documentation does not list among its transports; use another client for it.
## Cline, AnythingLLM, Augment Code
Merge into the place for the person's client:
- Cline: cline_mcp_settings.json (MCP Servers › Configure › Configure MCP Servers)
- AnythingLLM: anythingllm_mcp_servers.json in the AnythingLLM storage plugins directory
- Augment Code: Augment Settings Panel – MCP section – Import from JSON (VS Code extension)
```json
{
"mcpServers": {
"openalex-mcp": {
"type": "sse",
"url": "https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse"
}
}
}
```
## Continue
Merge into ~/.continue/config.yaml:
```yaml
mcpServers:
- name: "openalex-mcp"
type: sse
url: "https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse"
```
## Goose
This server's endpoint speaks only SSE, which this client's documentation does not list among its transports; use another client for it.
## Codex
This server's endpoint speaks only SSE, which this client's documentation does not list among its transports; use another client for it.
## mcp-client-cli, TUUI, BoltAI, Bob Shell, Kiro, Kiro CLI
This server's endpoint speaks only SSE, which this client's documentation does not list among its transports; use another client for it.
## Agenvoy
This server's endpoint speaks only SSE, which this client's documentation does not list among its transports; use another client for it.
## Amp
Merge into ~/.config/amp/settings.json (user) or .amp/settings.json (workspace):
```json
{
"amp.mcpServers": {
"openalex-mcp": {
"url": "https://geraldine-openalex-mcp.hf.space/gradio_api/mcp/sse"
}
}
}
```
Then restart the client, or reload its MCP servers, and ask it to list the server's tools to confirm it started.
Tools 9
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}
From Hugging Face Spaces. Report a problem