Proving Lab · Recipes

Recipes: turn a web source into a citation

Short, complete instructions for the citation endpoint at /mcp — in a terminal, in WSL, in Python, and in AI tools that speak MCP. Every one of them was run on 3 August 2026 before it was written down; an untested recipe is a claim.

No account and no key · fair use, please · what the endpoint is and what it refuses

What you get back

For a page that is a work: authors, title, journal, year, volume, pages, DOI, ISSN and licence — plus a ready-to-import RIS record and a BibTeX entry. For a page that is a paywall, an error or a bot check: complete: false and a warning naming the wall. Test complete before you file the result — a refused record still carries a title, and it will read like a work.

A reading list becomes a .ris file

The recipe most people actually want. One URL per line in reading-list.txt, one importable file out. Sources that cannot be read are named on stderr and left out of the file rather than half-imported.

while read -r u; do
  curl -sX POST https://provinglab.dev/mcp \
    -H 'content-type: application/json' \
    -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",
         \"params\":{\"name\":\"extract_citation\",\"arguments\":{\"url\":\"$u\"}}}" \
  | python3 -c 'import json,sys
d = json.loads(json.load(sys.stdin)["result"]["content"][0]["text"])
sys.stdout.write(d["ris"]) if d.get("complete") else \
  sys.stderr.write("skipped: " + d.get("warning","") + "\n")'
done < reading-list.txt > literature.ris

Then Zotero → File → Import, or Citavi → Import → RIS. Measured on three scholarly URLs: three records, under two seconds, imported without editing.

Claude Code, in one line

claude mcp add --transport http provinglab https://provinglab.dev/mcp

claude mcp list then reports ✔ Connected. After that you can simply say: "cite these four links for my bibliography" — the tool is called for each one, and the ones behind a wall are reported as such instead of invented.

Claude Desktop and other MCP clients

Add https://provinglab.dev/mcp as a remote MCP server (transport: streamable HTTP). Authentication is offered but not required; anonymous requests get identical answers. In clients that only accept local servers, the usual bridge works:

{
  "mcpServers": {
    "provinglab": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://provinglab.dev/mcp"]
    }
  }
}

Python — mind the user agent

The standard library identifies itself as Python-urllib, and the CDN in front of this site answers that with HTTP 403 before the worker ever sees the request. Any user agent of your own is enough. This is not a rule against automation — it is a filter that does not know the difference.

import json, urllib.request

def cite(url):
    body = json.dumps({"jsonrpc": "2.0", "id": 1, "method": "tools/call",
        "params": {"name": "extract_citation", "arguments": {"url": url}}}).encode()
    req = urllib.request.Request("https://provinglab.dev/mcp", body, {
        "content-type": "application/json",
        "user-agent": "my-bibliography-script/1.0",   # <- without this: 403
    })
    answer = json.loads(urllib.request.urlopen(req, timeout=60).read())
    return json.loads(answer["result"]["content"][0]["text"])

record = cite("https://doi.org/10.1038/s41586-020-2649-2")
if record.get("complete"):
    print(record["ris"])
else:
    print("not usable:", record["warning"])

WSL: from the browser into the terminal

The two halves of the work sit on different sides of the filesystem boundary. A source behind a university login can only be captured in the browser, and the file then has to be found from a shell.

In Full Page PDF Snap, switch on Copy file path after saving and set the format to WSL under Settings. After a capture the path is on the clipboard in the shape a Linux shell understands:

/mnt/c/Users/<you>/Downloads/Full Page PDF Snap/pubmed_2026-08-03_0911_0001.pdf

Paste it straight after a command, or into a chat with an AI tool that can read files. The RIS record for the same capture sits next to the PDF with the same name and a .ris extension.

Which of the two routes for which source

The endpointThe extension
Runson a server, anonymousin your browser, logged in
Gives youthe referencethe reference and the document
Behind a loginnoyes
Cost per sourcenone, scriptableone click
OutputRIS + BibTeXPDF with the fields inside, plus RIS

So the division is not a compromise: the endpoint for volume, the extension for the ones it refuses. Both emit the same RIS format, so everything lands in one Zotero or Citavi library regardless of the route. The refusal list from the first pass tells you which sources need the second.

For an agent rather than a person

These recipes are also published as a machine-readable skill, alongside the measurement methods:

What none of this proves

A citation record says what a page declares about itself. It is not a check that the work exists, that the DOI resolves to it, or that the page is honest — for the eight of eighteen platforms where the data is thin, that matters. A screen capture, likewise, is a picture of a screen and not a qualified electronic document. Where the content decides something, read the source.

Disclosure: this site is run by the developer of Full Page PDF Snap, the extension named on this page. The browser's own print-to-PDF is measured against it, including where print wins. Corrections: GitHub issues · Disclaimer

Proving Lab · Rezepte

Rezepte: aus einer Webquelle eine Literaturangabe machen

Kurze, vollständige Anleitungen für den Zitations-Endpunkt unter /mcp — im Terminal, in WSL, in Python und in KI-Werkzeugen, die MCP sprechen. Jede einzelne wurde am 3. August 2026 ausgeführt, bevor sie aufgeschrieben wurde; ein ungetestetes Rezept ist eine Behauptung.

Kein Konto und kein Schlüssel · bitte fair nutzen · was der Endpunkt ist und was er ablehnt

Was zurückkommt

Für eine Seite, die ein Werk ist: Autor:innen, Titel, Zeitschrift, Jahr, Jahrgang, Seiten, DOI, ISSN und Lizenz — dazu ein importfertiger RIS-Datensatz und ein BibTeX-Eintrag. Für eine Seite, die eine Paywall, ein Fehler oder eine Bot-Prüfung ist: complete: false und eine Warnung, die die Sperre benennt. Prüfen Sie complete, bevor Sie das Ergebnis ablegen — ein abgelehnter Datensatz trägt trotzdem einen Titel und liest sich wie ein Werk.

Aus einer Leseliste wird eine .ris-Datei

Das Rezept, das die meisten tatsächlich wollen. Eine URL pro Zeile in reading-list.txt, eine importierbare Datei als Ergebnis. Quellen, die nicht gelesen werden können, werden auf stderr genannt und bleiben aus der Datei draußen, statt halb importiert zu werden.

while read -r u; do
  curl -sX POST https://provinglab.dev/mcp \
    -H 'content-type: application/json' \
    -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",
         \"params\":{\"name\":\"extract_citation\",\"arguments\":{\"url\":\"$u\"}}}" \
  | python3 -c 'import json,sys
d = json.loads(json.load(sys.stdin)["result"]["content"][0]["text"])
sys.stdout.write(d["ris"]) if d.get("complete") else \
  sys.stderr.write("skipped: " + d.get("warning","") + "\n")'
done < reading-list.txt > literature.ris

Dann Zotero → Datei → Importieren oder Citavi → Importieren → RIS. Gemessen an drei wissenschaftlichen URLs: drei Datensätze, unter zwei Sekunden, ohne Nachbearbeitung importiert.

Claude Code, in einer Zeile

claude mcp add --transport http provinglab https://provinglab.dev/mcp

claude mcp list meldet danach ✔ Connected. Ab dann genügt: „zitiere diese vier Links für mein Literaturverzeichnis" — das Werkzeug wird für jeden aufgerufen, und die hinter einer Sperre werden als solche gemeldet statt erfunden.

Claude Desktop und andere MCP-Clients

https://provinglab.dev/mcp als entfernten MCP-Server eintragen (Transport: streamable HTTP). Eine Anmeldung wird angeboten, ist aber nicht nötig; anonyme Anfragen bekommen identische Antworten. In Clients, die nur lokale Server akzeptieren, funktioniert die übliche Brücke:

{
  "mcpServers": {
    "provinglab": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://provinglab.dev/mcp"]
    }
  }
}

Python — den User-Agent beachten

Die Standardbibliothek meldet sich als Python-urllib, und das CDN vor dieser Seite antwortet darauf mit HTTP 403, bevor der Worker die Anfrage überhaupt sieht. Jeder eigene User-Agent genügt. Das ist keine Regel gegen Automatisierung — es ist ein Filter, der den Unterschied nicht kennt.

import json, urllib.request

def cite(url):
    body = json.dumps({"jsonrpc": "2.0", "id": 1, "method": "tools/call",
        "params": {"name": "extract_citation", "arguments": {"url": url}}}).encode()
    req = urllib.request.Request("https://provinglab.dev/mcp", body, {
        "content-type": "application/json",
        "user-agent": "my-bibliography-script/1.0",   # <- without this: 403
    })
    answer = json.loads(urllib.request.urlopen(req, timeout=60).read())
    return json.loads(answer["result"]["content"][0]["text"])

record = cite("https://doi.org/10.1038/s41586-020-2649-2")
if record.get("complete"):
    print(record["ris"])
else:
    print("not usable:", record["warning"])

WSL: vom Browser ins Terminal

Die beiden Hälften der Arbeit liegen auf verschiedenen Seiten der Dateisystem-Grenze. Eine Quelle hinter einem Hochschul-Login lässt sich nur im Browser erfassen, und die Datei muss danach von einer Shell aus zu finden sein.

In Full Page PDF Snap Copy file path after saving einschalten und in den Einstellungen das Format WSL wählen. Nach einer Erfassung liegt der Pfad in der Zwischenablage in der Form, die eine Linux-Shell versteht:

/mnt/c/Users/<you>/Downloads/Full Page PDF Snap/pubmed_2026-08-03_0911_0001.pdf

Fügen Sie ihn direkt hinter einen Befehl ein oder in einen Chat mit einem KI-Werkzeug, das Dateien lesen kann. Der RIS-Datensatz zur selben Erfassung liegt mit gleichem Namen und der Endung .ris neben der PDF.

Welcher der beiden Wege für welche Quelle

Der EndpunktDie Erweiterung
Läuftauf einem Server, anonymin Ihrem Browser, angemeldet
Liefertdie Literaturangabedie Literaturangabe und das Dokument
Hinter einem Loginneinja
Aufwand pro Quellekeiner, skriptfähigein Klick
AusgabeRIS + BibTeXPDF mit den Feldern darin, plus RIS

Die Aufteilung ist also kein Kompromiss: der Endpunkt für die Menge, die Erweiterung für die, die er ablehnt. Beide geben dasselbe RIS-Format aus, also landet alles in derselben Zotero- oder Citavi-Bibliothek, egal über welchen Weg. Die Ablehnungsliste aus dem ersten Durchlauf sagt, welche Quellen den zweiten brauchen.

Für einen Agenten statt für einen Menschen

Diese Rezepte liegen auch als maschinenlesbarer Skill vor, zusammen mit den Messmethoden:

Was all das nicht beweist

Ein Zitationsdatensatz sagt, was eine Seite über sich selbst deklariert. Er prüft nicht, ob das Werk existiert, ob die DOI darauf auflöst oder ob die Seite ehrlich ist — für die acht von achtzehn Plattformen, bei denen die Daten dünn sind, ist das relevant. Eine Bildschirmaufnahme ist ebenfalls ein Bild eines Bildschirms und kein qualifiziertes elektronisches Dokument. Wo der Inhalt etwas entscheidet, lesen Sie die Quelle.

Offenlegung: Diese Seite wird vom Entwickler von Full Page PDF Snap betrieben, der auf dieser Seite genannten Erweiterung. Der eigene Druck-zu-PDF des Browsers ist dagegen gemessen, einschließlich der Fälle, in denen Drucken gewinnt. Korrekturen: GitHub Issues · Haftungsausschluss

Proving Lab · Recetas

Recetas: convierte una fuente web en una cita

Instrucciones cortas y completas para el endpoint de citas en /mcp — en un terminal, en WSL, en Python y en herramientas de IA que hablan MCP. Cada una se ejecutó el 3 de agosto de 2026 antes de escribirse; una receta no probada es una afirmación.

Sin cuenta y sin clave · uso justo, por favor · qué es el endpoint y qué rechaza

Lo que recibes de vuelta

Para una página que es una obra: autores, título, revista, año, volumen, páginas, DOI, ISSN y licencia — además de un registro RIS listo para importar y una entrada BibTeX. Para una página que es un muro de pago, un error o una prueba anti-bots: complete: false y una advertencia que nombra el muro. Comprueba complete antes de archivar el resultado — un registro rechazado sigue llevando un título y se leerá como una obra.

Una lista de lectura se convierte en un archivo .ris

La receta que la mayoría realmente quiere. Una URL por línea en reading-list.txt, un archivo importable como resultado. Las fuentes que no se pueden leer se nombran en stderr y quedan fuera del archivo en lugar de importarse a medias.

while read -r u; do
  curl -sX POST https://provinglab.dev/mcp \
    -H 'content-type: application/json' \
    -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",
         \"params\":{\"name\":\"extract_citation\",\"arguments\":{\"url\":\"$u\"}}}" \
  | python3 -c 'import json,sys
d = json.loads(json.load(sys.stdin)["result"]["content"][0]["text"])
sys.stdout.write(d["ris"]) if d.get("complete") else \
  sys.stderr.write("skipped: " + d.get("warning","") + "\n")'
done < reading-list.txt > literature.ris

Después, Zotero → Archivo → Importar, o Citavi → Importar → RIS. Medido con tres URL académicas: tres registros, menos de dos segundos, importados sin edición.

Claude Code, en una línea

claude mcp add --transport http provinglab https://provinglab.dev/mcp

claude mcp list informa entonces ✔ Connected. Después basta decir: "cita estos cuatro enlaces para mi bibliografía" — la herramienta se llama para cada uno, y los que están detrás de un muro se reportan como tales en lugar de inventarse.

Claude Desktop y otros clientes MCP

Añade https://provinglab.dev/mcp como servidor MCP remoto (transporte: streamable HTTP). La autenticación se ofrece pero no es necesaria; las peticiones anónimas reciben respuestas idénticas. En clientes que solo aceptan servidores locales, el puente habitual funciona:

{
  "mcpServers": {
    "provinglab": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://provinglab.dev/mcp"]
    }
  }
}

Python — cuidado con el user agent

La biblioteca estándar se identifica como Python-urllib, y el CDN delante de este sitio responde a eso con HTTP 403 antes de que el worker llegue a ver la petición. Cualquier user agent propio es suficiente. No es una regla contra la automatización — es un filtro que no conoce la diferencia.

import json, urllib.request

def cite(url):
    body = json.dumps({"jsonrpc": "2.0", "id": 1, "method": "tools/call",
        "params": {"name": "extract_citation", "arguments": {"url": url}}}).encode()
    req = urllib.request.Request("https://provinglab.dev/mcp", body, {
        "content-type": "application/json",
        "user-agent": "my-bibliography-script/1.0",   # <- without this: 403
    })
    answer = json.loads(urllib.request.urlopen(req, timeout=60).read())
    return json.loads(answer["result"]["content"][0]["text"])

record = cite("https://doi.org/10.1038/s41586-020-2649-2")
if record.get("complete"):
    print(record["ris"])
else:
    print("not usable:", record["warning"])

WSL: del navegador al terminal

Las dos mitades del trabajo están a lados distintos de la frontera del sistema de archivos. Una fuente detrás de un login universitario solo puede capturarse en el navegador, y luego hay que encontrar el archivo desde una shell.

En Full Page PDF Snap, activa Copy file path after saving y pon el formato WSL en Settings. Tras una captura, la ruta queda en el portapapeles en la forma que entiende una shell de Linux:

/mnt/c/Users/<you>/Downloads/Full Page PDF Snap/pubmed_2026-08-03_0911_0001.pdf

Pégala directamente tras un comando, o en un chat con una herramienta de IA que pueda leer archivos. El registro RIS de la misma captura está junto al PDF con el mismo nombre y la extensión .ris.

Cuál de las dos rutas para cada fuente

El endpointLa extensión
Se ejecutaen un servidor, anónimoen tu navegador, con sesión iniciada
Te dala referenciala referencia y el documento
Detrás de un loginno
Coste por fuenteninguno, scriptableun clic
SalidaRIS + BibTeXPDF con los campos dentro, más RIS

Así que la división no es un compromiso: el endpoint para el volumen, la extensión para las que rechaza. Ambos emiten el mismo formato RIS, así que todo llega a la misma biblioteca de Zotero o Citavi sea cual sea la ruta. La lista de rechazos del primer paso te dice qué fuentes necesitan la segunda.

Para un agente en lugar de una persona

Estas recetas también se publican como un skill legible por máquinas, junto a los métodos de medición:

Lo que nada de esto demuestra

Un registro de cita dice lo que una página declara sobre sí misma. No comprueba que la obra exista, que el DOI resuelva a ella o que la página sea honesta — para las ocho de dieciocho plataformas donde los datos son escasos, eso importa. Una captura de pantalla, igualmente, es una imagen de una pantalla y no un documento electrónico cualificado. Donde el contenido decide algo, lee la fuente.

Aviso: este sitio lo gestiona el desarrollador de Full Page PDF Snap, la extensión nombrada en esta página. La impresión a PDF del propio navegador está medida contra ella, incluyendo dónde gana la impresión. Correcciones: issues de GitHub · Aviso legal

Proving Lab · Recettes

Recettes : transformer une source web en citation

Des instructions courtes et complètes pour le point d'accès de citation sous /mcp — dans un terminal, dans WSL, en Python et dans des outils d'IA qui parlent MCP. Chacune a été exécutée le 3 août 2026 avant d'être écrite ; une recette non testée est une affirmation.

Ni compte ni clé · usage équitable, merci · ce qu'est le point d'accès et ce qu'il refuse

Ce que vous récupérez

Pour une page qui est une œuvre : auteurs, titre, revue, année, volume, pages, DOI, ISSN et licence — plus un enregistrement RIS prêt à importer et une entrée BibTeX. Pour une page qui est un mur payant, une erreur ou un contrôle anti-robots : complete: false et un avertissement qui nomme le mur. Testez complete avant d'archiver le résultat — un enregistrement refusé porte toujours un titre et se lira comme une œuvre.

Une liste de lecture devient un fichier .ris

La recette que la plupart veulent vraiment. Une URL par ligne dans reading-list.txt, un fichier importable en sortie. Les sources illisibles sont nommées sur stderr et laissées hors du fichier plutôt qu'importées à moitié.

while read -r u; do
  curl -sX POST https://provinglab.dev/mcp \
    -H 'content-type: application/json' \
    -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",
         \"params\":{\"name\":\"extract_citation\",\"arguments\":{\"url\":\"$u\"}}}" \
  | python3 -c 'import json,sys
d = json.loads(json.load(sys.stdin)["result"]["content"][0]["text"])
sys.stdout.write(d["ris"]) if d.get("complete") else \
  sys.stderr.write("skipped: " + d.get("warning","") + "\n")'
done < reading-list.txt > literature.ris

Puis Zotero → Fichier → Importer, ou Citavi → Importer → RIS. Mesuré sur trois URL universitaires : trois enregistrements, moins de deux secondes, importés sans retouche.

Claude Code, en une ligne

claude mcp add --transport http provinglab https://provinglab.dev/mcp

claude mcp list affiche alors ✔ Connected. Ensuite, il suffit de dire : « cite ces quatre liens pour ma bibliographie » — l'outil est appelé pour chacun, et ceux derrière un mur sont signalés comme tels au lieu d'être inventés.

Claude Desktop et les autres clients MCP

Ajoutez https://provinglab.dev/mcp comme serveur MCP distant (transport : streamable HTTP). L'authentification est proposée mais pas requise ; les requêtes anonymes obtiennent des réponses identiques. Dans les clients qui n'acceptent que des serveurs locaux, le pont habituel fonctionne :

{
  "mcpServers": {
    "provinglab": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://provinglab.dev/mcp"]
    }
  }
}

Python — attention au user agent

La bibliothèque standard s'identifie comme Python-urllib, et le CDN devant ce site répond par HTTP 403 avant même que le worker voie la requête. N'importe quel user agent à vous suffit. Ce n'est pas une règle contre l'automatisation — c'est un filtre qui ne connaît pas la différence.

import json, urllib.request

def cite(url):
    body = json.dumps({"jsonrpc": "2.0", "id": 1, "method": "tools/call",
        "params": {"name": "extract_citation", "arguments": {"url": url}}}).encode()
    req = urllib.request.Request("https://provinglab.dev/mcp", body, {
        "content-type": "application/json",
        "user-agent": "my-bibliography-script/1.0",   # <- without this: 403
    })
    answer = json.loads(urllib.request.urlopen(req, timeout=60).read())
    return json.loads(answer["result"]["content"][0]["text"])

record = cite("https://doi.org/10.1038/s41586-020-2649-2")
if record.get("complete"):
    print(record["ris"])
else:
    print("not usable:", record["warning"])

WSL : du navigateur au terminal

Les deux moitiés du travail se situent de part et d'autre de la frontière du système de fichiers. Une source derrière un login universitaire ne peut être capturée que dans le navigateur, et le fichier doit ensuite être retrouvé depuis un shell.

Dans Full Page PDF Snap, activez Copy file path after saving et réglez le format sur WSL dans les paramètres. Après une capture, le chemin est dans le presse-papiers dans la forme qu'un shell Linux comprend :

/mnt/c/Users/<you>/Downloads/Full Page PDF Snap/pubmed_2026-08-03_0911_0001.pdf

Collez-le directement après une commande, ou dans un chat avec un outil d'IA capable de lire des fichiers. L'enregistrement RIS de la même capture se trouve à côté du PDF, avec le même nom et l'extension .ris.

Laquelle des deux voies pour quelle source

Le point d'accèsL'extension
S'exécutesur un serveur, anonymedans votre navigateur, connecté
Vous donnela référencela référence et le document
Derrière un loginnonoui
Coût par sourceaucun, scriptableun clic
SortieRIS + BibTeXPDF avec les champs dedans, plus RIS

La répartition n'est donc pas un compromis : le point d'accès pour le volume, l'extension pour celles qu'il refuse. Les deux émettent le même format RIS, donc tout aboutit dans une même bibliothèque Zotero ou Citavi, quelle que soit la voie. La liste des refus du premier passage indique quelles sources ont besoin de la seconde.

Pour un agent plutôt qu'une personne

Ces recettes sont aussi publiées comme skill lisible par machine, aux côtés des méthodes de mesure :

Ce que rien de tout cela ne prouve

Un enregistrement de citation dit ce qu'une page déclare d'elle-même. Il ne vérifie ni que l'œuvre existe, ni que le DOI mène à elle, ni que la page est honnête — pour les huit plateformes sur dix-huit où les données sont minces, cela compte. Une capture d'écran, de même, est l'image d'un écran et pas un document électronique qualifié. Là où le contenu décide, lisez la source.

Transparence : ce site est géré par le développeur de Full Page PDF Snap, l'extension nommée sur cette page. L'impression en PDF du navigateur est mesurée face à elle, y compris là où l'impression gagne. Corrections : issues GitHub · Mentions légales

Proving Lab · Ricette

Ricette: trasforma una fonte web in una citazione

Istruzioni brevi e complete per l'endpoint di citazione su /mcp — in un terminale, in WSL, in Python e negli strumenti di IA che parlano MCP. Ognuna è stata eseguita il 3 agosto 2026 prima di essere scritta; una ricetta non testata è un'affermazione.

Nessun account e nessuna chiave · uso corretto, per favore · cos'è l'endpoint e cosa rifiuta

Cosa ricevi indietro

Per una pagina che è un'opera: autori, titolo, rivista, anno, volume, pagine, DOI, ISSN e licenza — più un record RIS pronto per l'importazione e una voce BibTeX. Per una pagina che è un paywall, un errore o un controllo anti-bot: complete: false e un avviso che nomina il muro. Verifica complete prima di archiviare il risultato — un record rifiutato porta comunque un titolo e si leggerà come un'opera.

Una lista di lettura diventa un file .ris

La ricetta che la maggior parte delle persone vuole davvero. Un URL per riga in reading-list.txt, un file importabile in uscita. Le fonti che non si possono leggere vengono nominate su stderr e lasciate fuori dal file invece di essere importate a metà.

while read -r u; do
  curl -sX POST https://provinglab.dev/mcp \
    -H 'content-type: application/json' \
    -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",
         \"params\":{\"name\":\"extract_citation\",\"arguments\":{\"url\":\"$u\"}}}" \
  | python3 -c 'import json,sys
d = json.loads(json.load(sys.stdin)["result"]["content"][0]["text"])
sys.stdout.write(d["ris"]) if d.get("complete") else \
  sys.stderr.write("skipped: " + d.get("warning","") + "\n")'
done < reading-list.txt > literature.ris

Poi Zotero → File → Importa, oppure Citavi → Importa → RIS. Misurato su tre URL accademici: tre record, meno di due secondi, importati senza modifiche.

Claude Code, in una riga

claude mcp add --transport http provinglab https://provinglab.dev/mcp

claude mcp list riporta quindi ✔ Connected. Dopo puoi semplicemente dire: "cita questi quattro link per la mia bibliografia" — lo strumento viene chiamato per ciascuno, e quelli dietro un muro vengono segnalati come tali invece di essere inventati.

Claude Desktop e altri client MCP

Aggiungi https://provinglab.dev/mcp come server MCP remoto (trasporto: streamable HTTP). L'autenticazione è offerta ma non richiesta; le richieste anonime ricevono risposte identiche. Nei client che accettano solo server locali, il solito bridge funziona:

{
  "mcpServers": {
    "provinglab": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://provinglab.dev/mcp"]
    }
  }
}

Python — attenzione allo user agent

La libreria standard si identifica come Python-urllib, e il CDN davanti a questo sito risponde con HTTP 403 prima ancora che il worker veda la richiesta. Qualsiasi user agent tuo è sufficiente. Non è una regola contro l'automazione — è un filtro che non conosce la differenza.

import json, urllib.request

def cite(url):
    body = json.dumps({"jsonrpc": "2.0", "id": 1, "method": "tools/call",
        "params": {"name": "extract_citation", "arguments": {"url": url}}}).encode()
    req = urllib.request.Request("https://provinglab.dev/mcp", body, {
        "content-type": "application/json",
        "user-agent": "my-bibliography-script/1.0",   # <- without this: 403
    })
    answer = json.loads(urllib.request.urlopen(req, timeout=60).read())
    return json.loads(answer["result"]["content"][0]["text"])

record = cite("https://doi.org/10.1038/s41586-020-2649-2")
if record.get("complete"):
    print(record["ris"])
else:
    print("not usable:", record["warning"])

WSL: dal browser al terminale

Le due metà del lavoro stanno ai lati opposti del confine del filesystem. Una fonte dietro un login universitario può essere catturata solo nel browser, e il file va poi ritrovato da una shell.

In Full Page PDF Snap, attiva Copy file path after saving e imposta il formato WSL nelle impostazioni. Dopo una cattura il percorso è negli appunti nella forma che una shell Linux capisce:

/mnt/c/Users/<you>/Downloads/Full Page PDF Snap/pubmed_2026-08-03_0911_0001.pdf

Incollalo direttamente dopo un comando, o in una chat con uno strumento di IA che sa leggere i file. Il record RIS della stessa cattura si trova accanto al PDF con lo stesso nome e l'estensione .ris.

Quale delle due vie per quale fonte

L'endpointL'estensione
Girasu un server, anonimonel tuo browser, connesso
Ti dàil riferimentoil riferimento e il documento
Dietro un loginno
Costo per fontenessuno, scriptabileun clic
OutputRIS + BibTeXPDF con i campi dentro, più RIS

Quindi la divisione non è un compromesso: l'endpoint per il volume, l'estensione per quelle che rifiuta. Entrambi emettono lo stesso formato RIS, così tutto finisce in un'unica biblioteca Zotero o Citavi indipendentemente dalla via. L'elenco dei rifiuti del primo passaggio ti dice quali fonti hanno bisogno della seconda.

Per un agente invece che per una persona

Queste ricette sono pubblicate anche come skill leggibile dalle macchine, insieme ai metodi di misurazione:

Cosa tutto questo non dimostra

Un record di citazione dice ciò che una pagina dichiara di sé. Non verifica che l'opera esista, che il DOI rimandi a lei o che la pagina sia onesta — per le otto piattaforme su diciotto in cui i dati sono scarsi, questo conta. Una cattura dello schermo, allo stesso modo, è l'immagine di uno schermo e non un documento elettronico qualificato. Dove il contenuto decide qualcosa, leggi la fonte.

Trasparenza: questo sito è gestito dallo sviluppatore di Full Page PDF Snap, l'estensione nominata in questa pagina. La stampa in PDF del browser è misurata a confronto, incluso dove la stampa vince. Correzioni: issue su GitHub · Disclaimer

Proving Lab · レシピ

レシピ:ウェブの情報源を引用情報に変える

/mcp の引用エンドポイントのための、短く完全な手順集 —— ターミナル、WSL、Python、そして MCP を話す AI ツール向け。すべて 2026年8月3日に実行してから書き起こしています。テストしていない レシピは主張にすぎません。

アカウントもキーも不要 · 公正な利用をお願いします · エンドポイントの概要と拒否するもの

返ってくるもの

著作物であるページの場合:著者、タイトル、雑誌名、年、巻、ページ、DOI、 ISSN、ライセンス —— 加えて、そのままインポートできる RIS レコードBibTeX エントリ。ペイウォール、エラー、 ボットチェックのページの場合:complete: false と、その壁を 名指しする警告。結果を保存する前に complete を確認して ください —— 拒否されたレコードにもタイトルは残り、著作物のように 読めてしまいます。

読書リストが .ris ファイルになる

ほとんどの人が本当に欲しいレシピ。reading-list.txt に 1 行 1 URL、出力はインポート可能な 1 ファイル。読み取れない情報源は stderr に名前が出て、半端にインポートされるのではなくファイルから外されます。

while read -r u; do
  curl -sX POST https://provinglab.dev/mcp \
    -H 'content-type: application/json' \
    -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",
         \"params\":{\"name\":\"extract_citation\",\"arguments\":{\"url\":\"$u\"}}}" \
  | python3 -c 'import json,sys
d = json.loads(json.load(sys.stdin)["result"]["content"][0]["text"])
sys.stdout.write(d["ris"]) if d.get("complete") else \
  sys.stderr.write("skipped: " + d.get("warning","") + "\n")'
done < reading-list.txt > literature.ris

あとは Zotero → ファイル → インポート、または Citavi → インポート → RIS。学術系 URL 3 件で実測:レコード 3 件、2 秒 未満、編集不要でインポート完了。

Claude Code、たった 1 行

claude mcp add --transport http provinglab https://provinglab.dev/mcp

claude mcp list✔ Connected と表示します。あとは 「この 4 つのリンクを参考文献用に引用して」と言うだけ —— それぞれに ツールが呼び出され、壁の向こうにあるものは捏造ではなく、壁があるとその 通りに報告されます。

Claude Desktop とその他の MCP クライアント

https://provinglab.dev/mcpリモート MCP サーバー として追加します(トランスポート: streamable HTTP)。認証は提供されて いますが必須ではなく、匿名リクエストにも同じ回答が返ります。ローカル サーバーしか受け付けないクライアントでは、おなじみのブリッジが使えます:

{
  "mcpServers": {
    "provinglab": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://provinglab.dev/mcp"]
    }
  }
}

Python —— ユーザーエージェントに注意

標準ライブラリは Python-urllib と名乗ります。このサイトの前段の CDN は、worker がリクエストを見る前に HTTP 403 を返します。 自分のユーザーエージェントを 1 つ設定すれば十分です。これは自動化への 禁止ではありません —— 区別のつかないフィルターです。

import json, urllib.request

def cite(url):
    body = json.dumps({"jsonrpc": "2.0", "id": 1, "method": "tools/call",
        "params": {"name": "extract_citation", "arguments": {"url": url}}}).encode()
    req = urllib.request.Request("https://provinglab.dev/mcp", body, {
        "content-type": "application/json",
        "user-agent": "my-bibliography-script/1.0",   # <- without this: 403
    })
    answer = json.loads(urllib.request.urlopen(req, timeout=60).read())
    return json.loads(answer["result"]["content"][0]["text"])

record = cite("https://doi.org/10.1038/s41586-020-2649-2")
if record.get("complete"):
    print(record["ris"])
else:
    print("not usable:", record["warning"])

WSL:ブラウザからターミナルへ

作業の 2 つの半分は、ファイルシステムの境界の両側にあります。大学 ログインの向こうにある情報源はブラウザでしかキャプチャできず、その ファイルをシェルから見つける必要があります。

Full Page PDF SnapCopy file path after saving をオンにし、設定でフォーマットを WSL にします。キャプチャ後、パスは Linux シェルが理解できる形でクリップ ボードに入ります:

/mnt/c/Users/<you>/Downloads/Full Page PDF Snap/pubmed_2026-08-03_0911_0001.pdf

コマンドの直後に貼るか、ファイルを読める AI ツールとのチャットに貼って ください。同じキャプチャの RIS レコードは、同じ名前に .ris 拡張子を付けて PDF の隣に保存されています。

2 つの経路、どちらをどの情報源に

エンドポイント拡張機能
動作場所サーバー上、匿名あなたのブラウザ内、ログイン済み
得られるもの書誌情報書誌情報ドキュメント
ログインの向こう不可可能
1 件あたりのコストゼロ、スクリプト可1 クリック
出力RIS + BibTeXフィールドを内蔵した PDF、加えて RIS

つまりこの分担は妥協ではありません:件数にはエンドポイント、 拒否されたものには拡張機能。どちらも同じ RIS 形式を出力するので、 経路に関係なくすべて 1 つの Zotero または Citavi ライブラリに収まります。 最初のパスの拒否リストが、2 番目の経路が必要な情報源を教えてくれます。

人ではなくエージェントへ

これらのレシピは、測定方法と並んで、機械可読のスキルとしても公開して います:

これらが証明しないこと

引用レコードは、ページが自分について宣言していることを示すだけです。 著作物が実在すること、DOI がそれに解決されること、ページが正直である ことを確認するものではありません —— データが薄い 18 プラットフォーム中 8 件では、それが重要です。画面キャプチャも同様に、画面の画像であり、 適格な電子文書ではありません。内容がものを 言う場面では、情報源そのものを読んでください。

開示:このサイトは、このページで名前の挙がっている拡張機能 Full Page PDF Snap の開発者が運営しています。ブラウザ自身の PDF 印刷との比較測定では、印刷が勝る場合も含めています。訂正: GitHub issues · 免責事項

Proving Lab · Receitas

Receitas: transforme uma fonte da web em uma citação

Instruções curtas e completas para o endpoint de citação em /mcp — em um terminal, no WSL, em Python e em ferramentas de IA que falam MCP. Cada uma foi executada em 3 de agosto de 2026 antes de ser escrita; uma receita não testada é uma alegação.

Sem conta e sem chave · uso justo, por favor · o que é o endpoint e o que ele recusa

O que você recebe de volta

Para uma página que é uma obra: autores, título, periódico, ano, volume, páginas, DOI, ISSN e licença — além de um registro RIS pronto para importar e uma entrada BibTeX. Para uma página que é um paywall, um erro ou uma verificação de bot: complete: false e um aviso que nomeia o muro. Teste complete antes de arquivar o resultado — um registro recusado ainda carrega um título e vai se ler como uma obra.

Uma lista de leitura vira um arquivo .ris

A receita que a maioria realmente quer. Uma URL por linha em reading-list.txt, um arquivo importável como saída. Fontes que não podem ser lidas são nomeadas no stderr e ficam fora do arquivo em vez de serem importadas pela metade.

while read -r u; do
  curl -sX POST https://provinglab.dev/mcp \
    -H 'content-type: application/json' \
    -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",
         \"params\":{\"name\":\"extract_citation\",\"arguments\":{\"url\":\"$u\"}}}" \
  | python3 -c 'import json,sys
d = json.loads(json.load(sys.stdin)["result"]["content"][0]["text"])
sys.stdout.write(d["ris"]) if d.get("complete") else \
  sys.stderr.write("skipped: " + d.get("warning","") + "\n")'
done < reading-list.txt > literature.ris

Depois, Zotero → Arquivo → Importar, ou Citavi → Importar → RIS. Medido em três URLs acadêmicas: três registros, menos de dois segundos, importados sem edição.

Claude Code, em uma linha

claude mcp add --transport http provinglab https://provinglab.dev/mcp

claude mcp list então reporta ✔ Connected. Depois disso, basta dizer: "cite estes quatro links para a minha bibliografia" — a ferramenta é chamada para cada um, e os que estão atrás de um muro são reportados como tal em vez de inventados.

Claude Desktop e outros clientes MCP

Adicione https://provinglab.dev/mcp como servidor MCP remoto (transporte: streamable HTTP). A autenticação é oferecida, mas não é obrigatória; requisições anônimas recebem respostas idênticas. Em clientes que só aceitam servidores locais, a ponte habitual funciona:

{
  "mcpServers": {
    "provinglab": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://provinglab.dev/mcp"]
    }
  }
}

Python — atenção ao user agent

A biblioteca padrão se identifica como Python-urllib, e o CDN à frente deste site responde a isso com HTTP 403 antes mesmo de o worker ver a requisição. Qualquer user agent seu é suficiente. Isso não é uma regra contra automação — é um filtro que não conhece a diferença.

import json, urllib.request

def cite(url):
    body = json.dumps({"jsonrpc": "2.0", "id": 1, "method": "tools/call",
        "params": {"name": "extract_citation", "arguments": {"url": url}}}).encode()
    req = urllib.request.Request("https://provinglab.dev/mcp", body, {
        "content-type": "application/json",
        "user-agent": "my-bibliography-script/1.0",   # <- without this: 403
    })
    answer = json.loads(urllib.request.urlopen(req, timeout=60).read())
    return json.loads(answer["result"]["content"][0]["text"])

record = cite("https://doi.org/10.1038/s41586-020-2649-2")
if record.get("complete"):
    print(record["ris"])
else:
    print("not usable:", record["warning"])

WSL: do navegador para o terminal

As duas metades do trabalho ficam em lados diferentes da fronteira do sistema de arquivos. Uma fonte atrás de um login universitário só pode ser capturada no navegador, e o arquivo precisa então ser encontrado a partir de um shell.

No Full Page PDF Snap, ative Copy file path after saving e defina o formato WSL nas configurações. Após uma captura, o caminho está na área de transferência na forma que um shell Linux entende:

/mnt/c/Users/<you>/Downloads/Full Page PDF Snap/pubmed_2026-08-03_0911_0001.pdf

Cole diretamente após um comando, ou em um chat com uma ferramenta de IA que saiba ler arquivos. O registro RIS da mesma captura fica ao lado do PDF com o mesmo nome e a extensão .ris.

Qual das duas rotas para qual fonte

O endpointA extensão
Rodaem um servidor, anônimono seu navegador, logado
Entregaa referênciaa referência e o documento
Atrás de um loginnãosim
Custo por fontenenhum, scriptávelum clique
SaídaRIS + BibTeXPDF com os campos dentro, mais RIS

Então a divisão não é um compromisso: o endpoint para o volume, a extensão para as que ele recusa. Ambos emitem o mesmo formato RIS, então tudo cai na mesma biblioteca do Zotero ou Citavi, qualquer que seja a rota. A lista de recusas da primeira passada diz quais fontes precisam da segunda.

Para um agente, não para uma pessoa

Estas receitas também são publicadas como um skill legível por máquina, junto aos métodos de medição:

O que nada disso prova

Um registro de citação diz o que uma página declara sobre si mesma. Não verifica se a obra existe, se o DOI resolve para ela ou se a página é honesta — para as oito de dezoito plataformas em que os dados são escassos, isso importa. Uma captura de tela, da mesma forma, é a imagem de uma tela e não um documento eletrônico qualificado. Onde o conteúdo decide algo, leia a fonte.

Transparência: este site é mantido pelo desenvolvedor do Full Page PDF Snap, a extensão citada nesta página. A impressão em PDF do próprio navegador é medida em comparação, incluindo onde a impressão vence. Correções: issues no GitHub · Aviso legal

Proving Lab · Рецепты

Рецепты: превратить веб-источник в библиографическую запись

Короткие, полные инструкции для конечной точки цитирования по адресу /mcp — в терминале, в WSL, в Python и в ИИ-инструментах, говорящих на MCP. Каждая была выполнена 3 августа 2026 года до того, как была записана; непроверенный рецепт — это утверждение.

Без аккаунта и без ключа · пожалуйста, используйте умеренно · что такое эта конечная точка и что она отклоняет

Что вы получаете обратно

Для страницы, которая является произведением: авторы, название, журнал, год, том, страницы, DOI, ISSN и лицензия — плюс готовая к импорту запись RIS и запись BibTeX. Для страницы, которая является платным барьером, ошибкой или проверкой на бота: complete: false и предупреждение, называющее барьер. Проверяйте complete, прежде чем сохранить результат — отклонённая запись всё равно несёт заголовок и будет читаться как произведение.

Список чтения превращается в файл .ris

Рецепт, который большинству действительно нужен. По одному URL на строку в reading-list.txt — на выходе один импортируемый файл. Источники, которые не удалось прочитать, называются в stderr и не попадают в файл, вместо того чтобы импортироваться наполовину.

while read -r u; do
  curl -sX POST https://provinglab.dev/mcp \
    -H 'content-type: application/json' \
    -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",
         \"params\":{\"name\":\"extract_citation\",\"arguments\":{\"url\":\"$u\"}}}" \
  | python3 -c 'import json,sys
d = json.loads(json.load(sys.stdin)["result"]["content"][0]["text"])
sys.stdout.write(d["ris"]) if d.get("complete") else \
  sys.stderr.write("skipped: " + d.get("warning","") + "\n")'
done < reading-list.txt > literature.ris

Затем Zotero → Файл → Импорт или Citavi → Импорт → RIS. Замерено на трёх научных URL: три записи, меньше двух секунд, импортированы без правок.

Claude Code, одной строкой

claude mcp add --transport http provinglab https://provinglab.dev/mcp

claude mcp list затем показывает ✔ Connected. После этого можно просто сказать: «процитируй эти четыре ссылки для моей библиографии» — инструмент вызывается для каждой, а те, что за барьером, так и докладываются — вместо того чтобы выдумываться.

Claude Desktop и другие MCP-клиенты

Добавьте https://provinglab.dev/mcp как удалённый MCP-сервер (транспорт: streamable HTTP). Аутентификация предлагается, но не требуется; анонимные запросы получают идентичные ответы. В клиентах, принимающих только локальные серверы, работает обычный мост:

{
  "mcpServers": {
    "provinglab": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://provinglab.dev/mcp"]
    }
  }
}

Python — не забудьте про user agent

Стандартная библиотека представляется как Python-urllib, и CDN перед этим сайтом отвечает на это HTTP 403 ещё до того, как worker увидит запрос. Достаточно любого собственного user agent. Это не правило против автоматизации — это фильтр, который не знает разницы.

import json, urllib.request

def cite(url):
    body = json.dumps({"jsonrpc": "2.0", "id": 1, "method": "tools/call",
        "params": {"name": "extract_citation", "arguments": {"url": url}}}).encode()
    req = urllib.request.Request("https://provinglab.dev/mcp", body, {
        "content-type": "application/json",
        "user-agent": "my-bibliography-script/1.0",   # <- without this: 403
    })
    answer = json.loads(urllib.request.urlopen(req, timeout=60).read())
    return json.loads(answer["result"]["content"][0]["text"])

record = cite("https://doi.org/10.1038/s41586-020-2649-2")
if record.get("complete"):
    print(record["ris"])
else:
    print("not usable:", record["warning"])

WSL: из браузера в терминал

Две половины работы находятся по разные стороны границы файловых систем. Источник за университетским логином можно захватить только в браузере, а файл затем нужно найти из командной строки.

В Full Page PDF Snap включите Copy file path after saving и установите формат WSL в настройках. После захвата путь лежит в буфере обмена в виде, понятном Linux-оболочке:

/mnt/c/Users/<you>/Downloads/Full Page PDF Snap/pubmed_2026-08-03_0911_0001.pdf

Вставьте его сразу после команды или в чат с ИИ-инструментом, умеющим читать файлы. Запись RIS для того же захвата лежит рядом с PDF с тем же именем и расширением .ris.

Какой из двух путей — для какого источника

Конечная точкаРасширение
Работаетна сервере, анонимнов вашем браузере, с логином
Выдаётбиблиографическое описаниеописание и документ
За логиномнетда
Цена за источникноль, скриптуетсяодин клик
ВыводRIS + BibTeXPDF с полями внутри, плюс RIS

Так что разделение — не компромисс: конечная точка — для объёма, расширение — для тех, кого она отклоняет. Обе выдают один и тот же формат RIS, поэтому всё попадает в одну библиотеку Zotero или Citavi независимо от пути. Список отказов первого прохода подскажет, каким источникам нужен второй.

Для агента, а не для человека

Эти рецепты также опубликованы как машиночитаемый навык, рядом с методами измерений:

Чего всё это не доказывает

Библиографическая запись говорит лишь то, что страница заявляет о себе. Она не проверяет, существует ли произведение, ведёт ли DOI на него и честна ли страница — для восьми из восемнадцати платформ, где данные скудны, это важно. Снимок экрана, так же, — это изображение экрана, а не квалифицированный электронный документ. Там, где решает содержание, читайте источник.

Раскрытие информации: этот сайт ведёт разработчик Full Page PDF Snap — расширения, названного на этой странице. Собственная печать в PDF браузера измерена в сравнении с ним, включая случаи, где печать выигрывает. Исправления: GitHub issues · Отказ от ответственности

Proving Lab · 配方

配方:把网页来源变成引文

/mcp 引文端点的简短完整用法说明 —— 可在终端、WSL、Python 以及支持 MCP 的 AI 工具中使用。每一条都在 2026 年 8 月 3 日实际运行 过之后才被写下来;未经测试的配方只是空谈。

无需账户和密钥 · 请合理使用 · 该端点是什么、会拒绝什么

你会得到什么

对于是作品的页面:作者、标题、期刊、年份、卷、页码、DOI、ISSN 和许可 —— 外加可直接导入的 RIS 记录BibTeX 条目。 对于付费墙、错误页或机器人检查页:complete: false 和一条 指明是哪堵墙的警告。在归档结果之前先检查 complete —— 被拒绝的记录仍带有标题,读起来会像一件作品。

阅读清单变成 .ris 文件

大多数人真正想要的配方。reading-list.txt 中每行一个 URL, 产出一个可导入的文件。无法读取的来源会在 stderr 中列名,并从文件中 剔除,而不是导入一半。

while read -r u; do
  curl -sX POST https://provinglab.dev/mcp \
    -H 'content-type: application/json' \
    -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",
         \"params\":{\"name\":\"extract_citation\",\"arguments\":{\"url\":\"$u\"}}}" \
  | python3 -c 'import json,sys
d = json.loads(json.load(sys.stdin)["result"]["content"][0]["text"])
sys.stdout.write(d["ris"]) if d.get("complete") else \
  sys.stderr.write("skipped: " + d.get("warning","") + "\n")'
done < reading-list.txt > literature.ris

然后 Zotero → 文件 → 导入,或 Citavi → 导入 → RIS。在三个学术 URL 上实测:三条记录,不到两秒,无需编辑即可导入。

Claude Code,一行搞定

claude mcp add --transport http provinglab https://provinglab.dev/mcp

claude mcp list 随后会显示 ✔ Connected。之后你只需说: "为我的参考文献引用这四个链接" —— 每个链接都会调用该工具,被墙 挡住的会如实报告,而不是凭空编造。

Claude Desktop 和其他 MCP 客户端

https://provinglab.dev/mcp 添加为远程 MCP 服务器 (传输方式:streamable HTTP)。提供身份验证但非必需;匿名请求会得到完全 相同的回答。在只接受本地服务器的客户端中,常用的桥接方式可行:

{
  "mcpServers": {
    "provinglab": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://provinglab.dev/mcp"]
    }
  }
}

Python —— 注意 user agent

标准库会自报为 Python-urllib,本站前面的 CDN 会在 worker 看到 请求之前就对其返回 HTTP 403。随便设置一个自己的 user agent 即可。这不是针对自动化的规定 —— 而是一个分不清区别的过滤器。

import json, urllib.request

def cite(url):
    body = json.dumps({"jsonrpc": "2.0", "id": 1, "method": "tools/call",
        "params": {"name": "extract_citation", "arguments": {"url": url}}}).encode()
    req = urllib.request.Request("https://provinglab.dev/mcp", body, {
        "content-type": "application/json",
        "user-agent": "my-bibliography-script/1.0",   # <- without this: 403
    })
    answer = json.loads(urllib.request.urlopen(req, timeout=60).read())
    return json.loads(answer["result"]["content"][0]["text"])

record = cite("https://doi.org/10.1038/s41586-020-2649-2")
if record.get("complete"):
    print(record["ris"])
else:
    print("not usable:", record["warning"])

WSL:从浏览器到终端

工作的两半位于文件系统边界的两侧。大学登录墙后面的来源只能在浏览器里 捕获,然后还要能从 shell 里找到这个文件。

Full Page PDF Snap 中打开 Copy file path after saving,并在设置里把格式设为 WSL。 捕获之后,路径会以 Linux shell 能看懂的形式放进剪贴板:

/mnt/c/Users/<you>/Downloads/Full Page PDF Snap/pubmed_2026-08-03_0911_0001.pdf

直接粘贴在命令后面,或粘贴到能读取文件的 AI 工具聊天里。同一次捕获的 RIS 记录就以相同的文件名加 .ris 扩展名保存在 PDF 旁边。

两条路线,分别适合什么来源

端点扩展
运行位置服务器上,匿名你的浏览器里,已登录
给你参考文献条目条目文档
登录墙之后不行可以
每个来源的成本零,可脚本化一次点击
输出RIS + BibTeX内嵌字段的 PDF,外加 RIS

所以这种分工不是妥协:批量走端点,被端点拒绝的走扩展。 两者输出相同的 RIS 格式,因此无论走哪条路线,所有内容都会进入同一个 Zotero 或 Citavi 库。第一遍的拒绝列表会告诉你哪些来源需要第二条路线。

面向代理而非人类

这些配方还以机器可读的 skill 形式发布,与测量方法放在一起:

这些都不能证明什么

一条引文记录只能说明页面如何自我声明。它不验证作品是否存在、DOI 是否 解析到它、页面是否诚实 —— 在十八个平台中有八个数据稀薄,这一点很 重要。屏幕截图同样只是屏幕的图像,并非合格的 电子文档。在内容起决定作用的地方,请阅读原文。

披露:本站由本页提到的扩展 Full Page PDF Snap 的开发者运营。浏览器自带的打印为 PDF 已与之对比测量,包括打印胜出的情形。更正:GitHub issues · 免责声明