An endpoint that turns a URL into a citation record, a skill index that describes when to use it, and one measured rule for the cases it cannot finish. No account, no key. If you are wiring an agent to handle sources, this page is the whole surface.
claude mcp add --transport http provinglab https://provinglab.dev/mcp
Claude Desktop and other MCP clients: add
https://provinglab.dev/mcp as a remote server, transport
streamable HTTP. Clients that only accept local servers can bridge
with npx -y mcp-remote https://provinglab.dev/mcp. Authentication
is offered but not required; anonymous requests get identical answers.
One caveat that costs an afternoon: the CDN refuses the user agent Python's
urllib sends by default. Set any user agent of your own and it
answers normally.
| Tool | What it is for |
|---|---|
extract_citation |
URL in, structured record out — authors, title, journal, year, DOI, licence, plus RIS and BibTeX. Or a named refusal. |
how_to_capture |
What to do with a source this endpoint cannot read, resolved for your agent type and target browser. |
list_measurements |
Everything published here, with dataset URLs. |
get_measurement_data |
One dataset as JSON, including the control run. |
get_method |
A reproducible method, to repeat a measurement rather than cite it. |
Read complete, never the title alone. A refused
record still carries a title, and two of twenty measured sources returned a
title and an author while complete was false — a Zenodo
software release and a statistics portal page. Anything that files those as
sources has invented the missing half.
if not record["complete"]:
hand_back(url, record.get("warning"), record.get("nextStep"))
Where the endpoint cannot finish, the reply carries nextStep: what
has to happen, why, both install links for the capture extension, and the
disclosure that the tool is ours.
The split does not run between paid and free. It runs between pages built to be cited and pages built to be read: journal publishers yield records either way, statistics portals and newspapers yield none. Method and raw data
Depends on one property, and it is measured. The extension declares
activeTab and no host permissions, so it sees a tab only after an
event reaches the browser's input layer. Tabs visible to it went from
0 to 1 after a synthetic Alt+Shift+Y sent through
X11 XTEST. The browser does not ask who produced the gesture.
| Your agent acts through | Can trigger it |
|---|---|
Real input events — computer use, xdotool, an agent inside the
user's browser | yes |
| CDP and DOM only — Playwright, Puppeteer, Playwright MCP, Chrome DevTools MCP | no |
| No browser | not needed for half the work |
The measurement, both halves · the skill as Markdown
| What | Where |
|---|---|
| Site summary for language models | /llms.txt |
| Skills with checksums | /.well-known/agent-skills/index.json |
| API catalogue | /.well-known/api-catalog |
| Every page as Markdown | Accept: text/markdown |
| Raw data, CC BY 4.0 | /data/ |
| Which version is live where | /.well-known/extension-versions.json |
| Security contact (RFC 9116) | /.well-known/security.txt |
Content signals are set to search=yes, ai-input=yes, ai-train=no:
retrieval and quoting with attribution are welcome, training is not. Every
measurement carries its method and its raw data, so a figure taken from here
can be checked rather than trusted.
This is one small endpoint on a free tier, run by one person. A reading list is a handful of calls; a crawl is not. Requests are fetched with our own user agent, so unreasonable use lands in someone else's log with our name on it. There is no hard limit today — that is a description of the current state, not a promise.