1.10¶
Scholar MCP 1.10 replaces its two separate background-task systems with one:
every tool whose work can run long now promotes to a background job on the
same schedule and is polled with a single new tool, get_job_result. The
patent tools gain a real retry against EPO's throttling instead of one that
never actually asked EPO again, two gaps in the advertised tool metadata are
closed, and fetch_and_convert stops re-running its most expensive step when
a cached result already exists.
One background-job queue instead of two¶
The server used to carry two background-task systems that had drifted apart:
a bespoke, in-process queue that did the actual work behind get_task_result
and list_tasks, and a separate fastmcp-pvl-core task backend that
make_server() configured but that no tool in the domain code used. As the
tracking issue put it,
an operator who pointed SCHOLAR_MCP_KV_STORE_URL at Redis would silently
gain a Redis-backed core queue while list_tasks stayed in-process and lost
every job on restart, and any future improvement to task durability or
cancellation would land in the system the domain tools never touched.
1.10 consolidates onto one queue. Every tool whose work can run long,
covering PDF download and conversion, patent search, paper, book and
citation lookups, citation-graph traversal, cross-source identifier
resolution, and standards lookups, is promoted to a background job once it
runs past SCHOLAR_MCP_JOBS_SOFT_DEADLINE_S (25 seconds by default) rather
than branching on which upstream error it hit. A promoted call returns a
handle:
{"status": "working", "job_id": "hwex4wg6taLmasPZWPM7gQ", "poll_with": "get_job_result",
"retry_after_s": 5.0, "message": "..."}
and the new get_job_result tool polls it through to completed or
failed. get_task_result and list_tasks are gone. If you restrict the
exposed tool surface with SCHOLAR_MCP_TOOLS_ALLOW (or an equivalent
allowlist elsewhere) and named either of those, add get_job_result in their
place: an allowlist matches by name, so a name that no longer resolves to
anything is silently ignored rather than rejected, and a job handle with no
tool able to poll it becomes unresolvable.
Two new variables round out the tuning surface, both documented in the
configuration guide:
SCHOLAR_MCP_JOBS_RESULT_TTL_S (how long a job record is kept, one hour by
default) and SCHOLAR_MCP_JOBS_MAX_PER_SUBJECT (the live-job cap per caller,
256 by default). Job records live in SCHOLAR_MCP_KV_STORE_URL, the same
backend as everything else stateful; that is a different variable from
SCHOLAR_MCP_TASKS_URL, which configured the old queue. A restart does not
resume promoted work: a poll afterward reports working until the record's
TTL runs out, rather than inventing a result.
Several tools now return a JSON object where they used to return a JSON
string (generate_citations, batch_resolve, and others); the tools
reference documents the new shape for each. That is a
change to the MCP tool surface, not a breaking one: a fresh client
connection re-discovers it automatically.
More accurate error reporting for patents and rate-limited papers¶
Wrapping the patent tools in the same jobs mechanism surfaced something the
old queue had never actually fixed: EPO Open Patent Services fails within
milliseconds when its traffic light is not green, so a queued retry ran
immediately against the same 60-second-cached light and failed again
without ever asking EPO a second time. 1.10 gives the patent tools a real
backoff whose waits are deliberately longer than that 60-second cache
lifetime, so a retry asks EPO again instead of re-reading a stale answer.
An exhausted daily quota is now its own error, reported at once with
"retryable": false, since it will not clear before tomorrow and waiting
would only cost the caller time for a known answer.
Two related reporting gaps are fixed alongside it. batch_resolve, which
resolves identifiers across patents and papers in one call, used to fold an
exhausted EPO quota into a generic failure for that entry; it now reports
the same retryable shape as the dedicated patent tools, for that entry
only, without failing the rest of the batch. And enrich_paper used to
report a rate-limited Semantic Scholar lookup as not_found, which told a
calling model to stop asking about a paper that exists; it now reports
{"error": "rate_limited", "retryable": true}.
Tool surface fixes¶
Two mismatches between what the tool registry advertised and what the code actually did are fixed:
fetch_patent_pdfwas missing thepatenttag its three sibling patent tools carry, so it stayed listed, and callable, when no EPO credentials were configured, where it could only ever answer with an error. It now carries both tags and is hidden along with the rest of the patent surface when EPO is unconfigured.get_book'sinclude_editionsparameter was accepted and documented but read by nothing. It is dropped rather than implemented, since nothing referenced it; a client that still passes it now gets a clear validation error instead of a silently ignored argument.
A new test enumerates the full tool registry, not just the shorter listing a
read-only or credential-free server exposes, and asserts every tool carries
a title and a readOnlyHint. All 29 currently registered tools already
carried a title by the time this landed; the test is what keeps that true
for tools added later.
fetch_and_convert reuses its cached Markdown¶
fetch_and_convert downloads a paper's PDF and converts it to Markdown in
one call. Its sibling conversion tools, convert_pdf_to_markdown and
fetch_pdf_by_url, have always reused an existing Markdown file instead of
re-running the conversion on a repeat call; fetch_and_convert never did,
so calling it twice for the same paper paid for a second docling conversion,
the most expensive operation this server performs, and overwrote an
identical file. It now checks for a cached Markdown file the same way its
siblings do. Nothing in the tool forces a fresh conversion yet: deleting
the cached .md file remains how to get one, for all four conversion
tools alike.
MCP registry listing catches up¶
v1.9.1 published everywhere except the MCP
Registry: the publish step
rejected it because the server's advertised description had grown past the
registry's 100-character cap, to 128 characters. 1.10 shortens the
description to 93 characters (FastMCP server for scholarly papers,
patents, books and standards with docling PDF conversion), keeping the
broader scope the longer wording was meant to convey. Since the registry
entry is a rolling pointer to the newest release rather than a per-version
record, this release is what closes the gap; nothing needed publishing by
hand.
Upgrading¶
No environment variable, configuration file, or public Python import was
removed or changed in this release; every new variable above is additive.
The one action item is the tool-allowlist note under One background-job
queue instead of two: add
get_job_result to any allowlist that used to name get_task_result or
list_tasks.