Proving Lab · Recipes
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.
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.
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 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.
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"]
}
}
}
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"])
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.
| The endpoint | The extension | |
|---|---|---|
| Runs | on a server, anonymous | in your browser, logged in |
| Gives you | the reference | the reference and the document |
| Behind a login | no | yes |
| Cost per source | none, scriptable | one click |
| Output | RIS + BibTeX | PDF 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.
These recipes are also published as a machine-readable skill, alongside the measurement methods:
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
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.
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.
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 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.
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"]
}
}
}
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"])
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.
| Der Endpunkt | Die Erweiterung | |
|---|---|---|
| Läuft | auf einem Server, anonym | in Ihrem Browser, angemeldet |
| Liefert | die Literaturangabe | die Literaturangabe und das Dokument |
| Hinter einem Login | nein | ja |
| Aufwand pro Quelle | keiner, skriptfähig | ein Klick |
| Ausgabe | RIS + BibTeX | PDF 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.
Diese Rezepte liegen auch als maschinenlesbarer Skill vor, zusammen mit den Messmethoden:
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
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.
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.
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 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.
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"]
}
}
}
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"])
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.
| El endpoint | La extensión | |
|---|---|---|
| Se ejecuta | en un servidor, anónimo | en tu navegador, con sesión iniciada |
| Te da | la referencia | la referencia y el documento |
| Detrás de un login | no | sí |
| Coste por fuente | ninguno, scriptable | un clic |
| Salida | RIS + BibTeX | PDF 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.
Estas recetas también se publican como un skill legible por máquinas, junto a los métodos de medición:
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
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.
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.
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 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.
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"]
}
}
}
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"])
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.
| Le point d'accès | L'extension | |
|---|---|---|
| S'exécute | sur un serveur, anonyme | dans votre navigateur, connecté |
| Vous donne | la référence | la référence et le document |
| Derrière un login | non | oui |
| Coût par source | aucun, scriptable | un clic |
| Sortie | RIS + BibTeX | PDF 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.
Ces recettes sont aussi publiées comme skill lisible par machine, aux côtés des méthodes de mesure :
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
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.
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.
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 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.
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"]
}
}
}
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"])
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.
| L'endpoint | L'estensione | |
|---|---|---|
| Gira | su un server, anonimo | nel tuo browser, connesso |
| Ti dà | il riferimento | il riferimento e il documento |
| Dietro un login | no | sì |
| Costo per fonte | nessuno, scriptabile | un clic |
| Output | RIS + BibTeX | PDF 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.
Queste ricette sono pubblicate anche come skill leggibile dalle macchine, insieme ai metodi di misurazione:
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 を確認して
ください —— 拒否されたレコードにもタイトルは残り、著作物のように
読めてしまいます。
ほとんどの人が本当に欲しいレシピ。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 mcp add --transport http provinglab https://provinglab.dev/mcp
claude mcp list が ✔ Connected と表示します。あとは
「この 4 つのリンクを参考文献用に引用して」と言うだけ —— それぞれに
ツールが呼び出され、壁の向こうにあるものは捏造ではなく、壁があるとその
通りに報告されます。
https://provinglab.dev/mcp をリモート MCP サーバー
として追加します(トランスポート: streamable HTTP)。認証は提供されて
いますが必須ではなく、匿名リクエストにも同じ回答が返ります。ローカル
サーバーしか受け付けないクライアントでは、おなじみのブリッジが使えます:
{
"mcpServers": {
"provinglab": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://provinglab.dev/mcp"]
}
}
}
標準ライブラリは 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"])
作業の 2 つの半分は、ファイルシステムの境界の両側にあります。大学 ログインの向こうにある情報源はブラウザでしかキャプチャできず、その ファイルをシェルから見つける必要があります。
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
コマンドの直後に貼るか、ファイルを読める AI ツールとのチャットに貼って
ください。同じキャプチャの RIS レコードは、同じ名前に .ris
拡張子を付けて PDF の隣に保存されています。
| エンドポイント | 拡張機能 | |
|---|---|---|
| 動作場所 | サーバー上、匿名 | あなたのブラウザ内、ログイン済み |
| 得られるもの | 書誌情報 | 書誌情報とドキュメント |
| ログインの向こう | 不可 | 可能 |
| 1 件あたりのコスト | ゼロ、スクリプト可 | 1 クリック |
| 出力 | RIS + BibTeX | フィールドを内蔵した PDF、加えて RIS |
つまりこの分担は妥協ではありません:件数にはエンドポイント、 拒否されたものには拡張機能。どちらも同じ RIS 形式を出力するので、 経路に関係なくすべて 1 つの Zotero または Citavi ライブラリに収まります。 最初のパスの拒否リストが、2 番目の経路が必要な情報源を教えてくれます。
これらのレシピは、測定方法と並んで、機械可読のスキルとしても公開して います:
引用レコードは、ページが自分について宣言していることを示すだけです。 著作物が実在すること、DOI がそれに解決されること、ページが正直である ことを確認するものではありません —— データが薄い 18 プラットフォーム中 8 件では、それが重要です。画面キャプチャも同様に、画面の画像であり、 適格な電子文書ではありません。内容がものを 言う場面では、情報源そのものを読んでください。
開示:このサイトは、このページで名前の挙がっている拡張機能 Full Page PDF Snap の開発者が運営しています。ブラウザ自身の PDF 印刷との比較測定では、印刷が勝る場合も含めています。訂正: GitHub issues · 免責事項
Proving Lab · Receitas
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.
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.
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 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.
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"]
}
}
}
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"])
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.
| O endpoint | A extensão | |
|---|---|---|
| Roda | em um servidor, anônimo | no seu navegador, logado |
| Entrega | a referência | a referência e o documento |
| Atrás de um login | não | sim |
| Custo por fonte | nenhum, scriptável | um clique |
| Saída | RIS + BibTeX | PDF 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.
Estas receitas também são publicadas como um skill legível por máquina, junto aos métodos de medição:
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, прежде чем сохранить результат
— отклонённая запись всё равно несёт заголовок и будет читаться как
произведение.
Рецепт, который большинству действительно нужен. По одному 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 mcp add --transport http provinglab https://provinglab.dev/mcp
claude mcp list затем показывает ✔ Connected. После
этого можно просто сказать: «процитируй эти четыре ссылки для моей
библиографии» — инструмент вызывается для каждой, а те, что за
барьером, так и докладываются — вместо того чтобы выдумываться.
Добавьте https://provinglab.dev/mcp как удалённый
MCP-сервер (транспорт: streamable HTTP). Аутентификация
предлагается, но не требуется; анонимные запросы получают идентичные
ответы. В клиентах, принимающих только локальные серверы, работает
обычный мост:
{
"mcpServers": {
"provinglab": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://provinglab.dev/mcp"]
}
}
}
Стандартная библиотека представляется как 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"])
Две половины работы находятся по разные стороны границы файловых систем. Источник за университетским логином можно захватить только в браузере, а файл затем нужно найти из командной строки.
В 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 + BibTeX | PDF с полями внутри, плюс 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
—— 被拒绝的记录仍带有标题,读起来会像一件作品。
大多数人真正想要的配方。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 mcp add --transport http provinglab https://provinglab.dev/mcp
claude mcp list 随后会显示 ✔ Connected。之后你只需说:
"为我的参考文献引用这四个链接" —— 每个链接都会调用该工具,被墙
挡住的会如实报告,而不是凭空编造。
将 https://provinglab.dev/mcp 添加为远程 MCP 服务器
(传输方式:streamable HTTP)。提供身份验证但非必需;匿名请求会得到完全
相同的回答。在只接受本地服务器的客户端中,常用的桥接方式可行:
{
"mcpServers": {
"provinglab": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://provinglab.dev/mcp"]
}
}
}
标准库会自报为 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"])
工作的两半位于文件系统边界的两侧。大学登录墙后面的来源只能在浏览器里 捕获,然后还要能从 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 · 免责声明