Skip to main content
Glama
smeet666

mcp-archiveorg

mcp-archiveorg

npm CI license MCP Registry Glama M8ven LobeHub Install in Cursor Install in VS Code

The Internet Archive is a non-profit library that keeps what the world publishes: scanned books, films, recorded music, radio, software, and the pages of the web itself, captured over and over since 1996 in the Wayback Machine. Millions of its books and documents have been run through optical character recognition, so the words inside them can be searched, and the Open Library index beside it describes works, their editions and their subjects.

This server connects a chat client to that library. You can search the full text inside its documents, search its catalogue of items, read one item's record and its files, look up a book by subject, place, period or person, and read the web as it stood on a given day. It needs no API key and no account.

Version française


Install

One-click install

Install in Cursor Install in VS Code

Claude Code

claude mcp add archiveorg -- npx -y mcp-archiveorg

Claude Desktop, Cursor, and any client using the standard config format

{
  "mcpServers": {
    "archiveorg": {
      "command": "npx",
      "args": ["-y", "mcp-archiveorg"]
    }
  }
}

Node 24 or later is required, and no environment variable has to be set.

With Docker

{
  "mcpServers": {
    "archiveorg": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-archiveorg:2.0.2"]
    }
  }
}

-i keeps stdin open, which is where the protocol travels, and -t is left out because a TTY rewrites the stream. The container needs outbound HTTPS to archive.org, web.archive.org and openlibrary.org, and nothing else: no volume, no port, no credential.

Bundle, without npm

Download mcp-archiveorg-2.0.2.mcpb from the latest release and open it. A client that supports MCP bundles installs it on its own, with no npm and no configuration file to edit. The bundle carries its dependencies, so nothing is fetched at install time.

Related MCP server: anna-book-search

What you can ask

  • "Which books mention the Beaumont light-house?"

  • "Find me items about the 1906 San Francisco earthquake."

  • "What files does that item hold, and what licence is it under?"

  • "Find me books on beekeeping in France published before 1900."

  • "What did that website look like in March 2001?"

The ordinary path runs from a search to a record: a row carries an identifier, and get_item reads it.

Tools

Tool

What it does

search_inside

Searches the words inside the archive's scanned documents.

search_items

Searches the catalogue by title, creator, subject and media type.

get_item

Reads one item's record, its files and its licence.

search_books

Finds books by subject, place, period, person, length or year.

list_snapshots

Lists the captures the Wayback Machine holds for an address.

get_snapshot

Reads one capture of an address, at or near a date.

search_inside

Searches the text inside the archive's documents, which came off the page through optical character recognition, so a passage carries the misreadings of that process.

Argument

Type

Required

What it does

query

string, 2 to 300 characters

yes

The phrase to look for inside the documents.

limit

integer, 1 to 50, default 10

no

Matches to serve.

page

integer, 1 to 100, default 1

no

Which page of matches.

max_excerpt_chars

integer, 80 to 1200, default 300

no

How much of a passage to serve.

max_excerpts_per_match

integer, 1 to 10, default 3

no

Passages served per matching document.

In return: hits, each carrying identifier, which get_item takes; title, creator and year; excerpts, the passages as a machine read them off the page; matched_file, naming what actually holds the passage; and source_url. inside_container is true when the item bundles several documents and the passage sits in one of them, in which case the title, the creator and the year belong to the container.

total counts documents, and it pages. It is a number of documents and the last page of a match set is shorter than the first. No page number is available: the index reports where the text sits inside the item, which is 1 on nearly every match, so nothing here states a page of a book and no link claims one.

search_items

Searches the catalogue itself, across every kind of thing the archive holds.

Argument

Type

Required

What it does

query

string, 1 to 300 characters

yes

Words to look for in the catalogue.

media_type

texts, movies, audio, image, software, data or web

no

The kind of thing to keep.

year_from

integer, 1 to 2200

no

Earliest year.

year_to

integer, 1 to 2200

no

Latest year.

sort

relevance, downloads, newest, oldest or title, default relevance

no

How the rows are ordered.

limit

integer, 1 to 50, default 10

no

Rows to serve.

page

integer, 1 to 100, default 1

no

Which page of rows.

In return: items, each carrying identifier, title, creator, year, media_type, downloads and source_url, a field the record leaves empty being null. total counts the items matching across the catalogue, which is more than the number returned.

get_item

Reads one item's record. The heavier parts are asked for rather than served by default, since a record can run long.

Argument

Type

Required

What it does

identifier

string, 1 to 200 characters

yes

The identifier a search row carries.

sections

array of basic, files, full_metadata, default ["basic"]

no

Which parts to return.

file_format

string, up to 60 characters

no

Keep the files of one format.

max_files

integer, 1 to 200, default 25

no

Ceiling on the files returned.

max_description_chars

integer, 100 to 20000, default 2000

no

How much of the description to serve.

In return: the item with its title, creator, year, media_type and source_url, plus description, date, publisher, language, collections and license_url, each null where the record states nothing. file_count counts the files the item holds whatever this answer returned, and total_bytes their weight. files and full_metadata are present only when asked for in sections.

search_books

Finds books through the index of works beside the archive, which describes a work and its editions rather than one scanned copy.

Argument

Type

Required

What it does

query

string, 2 to 300 characters

no

Free text, when there is any.

subject

string, 2 to 100 characters

no

A subject the index files works under.

place

string, 2 to 100 characters

no

A place a work is about.

time

string, 2 to 100 characters

no

A period a work is about.

person

string, 2 to 100 characters

no

A person a work is about.

language

string, 2 to 20 characters

no

The language of the work.

year_from

integer, 1 to 2200

no

Earliest first publication.

year_to

integer, 1 to 2200

no

Latest first publication.

pages_min

integer, 1 to 100000

no

Shortest acceptable work.

pages_max

integer, 1 to 100000

no

Longest acceptable work.

sort

relevance, rating, readers, newest or oldest, default relevance

no

How the rows are ordered.

limit

integer, 1 to 50, default 10

no

Rows to serve.

page

integer, 1 to 100, default 1

no

Which page of rows.

In return: books, each carrying title, authors, first_published_year, edition_count, archive_identifiers for the scanned copies the archive holds, scan_count, page_count as a median across editions, subjects and source_url. searched_for says in words what this answer answers, free text and every criterion applied, and query is null when the search was made of criteria alone. total counts the works matching.

list_snapshots

Lists the captures the Wayback Machine holds for one address.

Argument

Type

Required

What it does

url

string, 3 to 2000 characters

yes

The address to look up.

limit

integer, 1 to 100, default 20

no

Captures to serve.

cursor

string, up to 500 characters

no

The next_cursor a previous answer named.

In return: snapshots, each with its captured_at as an ISO timestamp in UTC, the url of the capture itself, and the status the crawl recorded. first and last describe this answer rather than the whole history, and next_cursor continues the listing.

get_snapshot

Reads one capture of an address, at a date or near it.

Argument

Type

Required

What it does

url

string, 3 to 2000 characters

yes

The address to look up.

at

YYYY-MM-DD or an ISO timestamp

no

The date to aim for. The newest capture by default.

In return: the snapshot with its captured_at and its address, beside the requested_url and requested_at, so the distance between the date asked for and the capture served is visible. The Wayback Machine answers a date it has no capture for with the nearest one it holds.

What excerpts are worth

The text inside a scanned document came off the page through optical character recognition. A passage therefore carries the misreadings of that process, and it is served as it was read rather than corrected: a word that reads oddly is what the machine saw. Quote a passage as an excerpt of a scan, and link the item so a reader can look at the page.

Configuration

Every variable is optional. Set them in the env block of your client config.

Variable

Default

What it does

IA_USER_AGENT

the project identity

Names your application to the archive, with an address where a person can be reached.

IA_MIN_INTERVAL_MS

1000

Gap between two requests, from 500 to 60000.

IA_TIMEOUT_MS

20000

Deadline for one request, from 1000 to 120000.

IA_HISTORY_TIMEOUT_MS

60000

Deadline for a Wayback Machine history, from 5000 to 180000.

IA_MAX_RETRIES

3

Attempts after a transient failure, from 0 to 8.

IA_CACHE_TTL_MS

900000

How long an answer stays in memory, from 0 to 86400000.

IA_CACHE_MAX_ENTRIES

200

Answers held in memory at once, from 1 to 5000.

IA_LOG_LEVEL

error

silent, error, info or debug, written to stderr.

A value outside its range falls back to the default, and the reason is written to stderr.

Errors

Every failure carries one of six codes, a message, and where it helps a hint naming the next move.

Code

What happened

What to do

not_found

The archive answered, and holds no such item.

Check the identifier with search_items.

invalid_input

The arguments were refused before any request went out.

Read the message, which names the argument.

rate_limited

The archive asked this client to slow down.

Wait the number of seconds the hint names and call again with the same arguments. The item is still there.

parse_failure

The answer arrived in a shape this client cannot read.

Report it at the issue tracker.

network_error

The request did not complete.

Try again shortly.

timeout

The request passed its deadline.

Raise IA_TIMEOUT_MS, or IA_HISTORY_TIMEOUT_MS for a capture history.

As a library

The layer reading the archive is published on its own, with its pacing, its cache and its errors, and with no protocol attached.

import { ArchiveClient } from "mcp-archiveorg/client";

const client = new ArchiveClient();
const { data, cached } = await client.searchItems({ query: "san francisco earthquake" });
console.log(data.total, cached);

Each read answers { data, cached }, and throws an error carrying one of the six codes. The floor between two requests holds here as well.

Pacing and attribution

Requests go out one at a time with at least a second between them, and the floor of half a second holds however the server is configured. The User-Agent always ends with the project identity and an address where a person can be reached. The Internet Archive is a non-profit library, and a search inside its documents is one of the more expensive questions it answers.

Every result carries the address of the page it was read from. The items belong to the people and institutions who deposited them, under the terms each record states in license_url.

This MCP server is an unofficial project, with no affiliation to the Internet Archive.

Privacy

This server collects nothing about you and sends nothing to its author. It runs on your machine, contacts archive.org, web.archive.org and openlibrary.org and nothing else, holds its answers in memory while it runs, and writes nothing to disk. PRIVACY.md states what a request carries and which settings change any of it.

Development

npm install
npm run build:fixtures
npm test
npm run check

Tests run against generated fixtures and make no network request. The live suite, npm run test:live, makes one request per route and runs nightly against the archive itself.

Contributing

Bugs, questions and ideas belong in the issue tracker. Pull requests are welcome; opening an issue first helps agree on the shape of the change. See CONTRIBUTING.md.

License

MIT, see LICENSE. The items belong to their depositors, under the terms each record states.


mcp-archiveorg (français)

English version

L'Internet Archive est une bibliothèque à but non lucratif qui conserve ce que le monde publie : livres numérisés, films, musique enregistrée, radio, logiciels, et les pages du web elles-mêmes, capturées encore et encore depuis 1996 dans la Wayback Machine. Des millions de ses livres et documents sont passés par la reconnaissance optique de caractères, si bien que les mots qu'ils contiennent sont cherchables, et l'index Open Library qui la côtoie décrit les œuvres, leurs éditions et leurs sujets.

Ce serveur relie un client de conversation à cette bibliothèque. On peut y chercher dans le texte intégral de ses documents, chercher dans son catalogue, lire la fiche d'un document et ses fichiers, trouver un livre par sujet, lieu, période ou personne, et lire le web tel qu'il était un jour donné. Aucune clé d'API, aucun compte.

Installation

Installation en un clic

Install in Cursor Install in VS Code

Claude Code

claude mcp add archiveorg -- npx -y mcp-archiveorg

Claude Desktop, Cursor, et tout client au format de configuration standard

{
  "mcpServers": {
    "archiveorg": {
      "command": "npx",
      "args": ["-y", "mcp-archiveorg"]
    }
  }
}

Node 24 ou plus récent est nécessaire, et aucune variable d'environnement n'est à renseigner.

Avec Docker

{
  "mcpServers": {
    "archiveorg": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-archiveorg:2.0.2"]
    }
  }
}

-i garde l'entrée standard ouverte, qui est le canal du protocole, et -t est omis parce qu'un TTY réécrit le flux. Le conteneur a besoin d'un accès HTTPS sortant vers archive.org, web.archive.org et openlibrary.org, et de rien d'autre : aucun volume, aucun port, aucun identifiant.

Bundle, sans npm

Téléchargez mcp-archiveorg-2.0.2.mcpb depuis la dernière publication et ouvrez-le. Un client qui gère les bundles MCP l'installe seul, sans npm et sans fichier de configuration à modifier. Le bundle emporte ses dépendances, donc rien n'est téléchargé à l'installation.

Ce qu'on peut demander

  • « Quels livres mentionnent le phare de Beaumont ? »

  • « Trouve-moi des documents sur le tremblement de terre de San Francisco en 1906. »

  • « Quels fichiers contient ce document, et sous quelle licence ? »

  • « Trouve-moi des livres sur l'apiculture en France publiés avant 1900. »

  • « À quoi ressemblait ce site en mars 2001 ? »

Le chemin ordinaire va d'une recherche à une fiche : une ligne porte un identifier, et get_item le lit.

Les outils

Outil

Ce qu'il fait

search_inside

Cherche dans les mots contenus dans les documents numérisés.

search_items

Cherche dans le catalogue par titre, auteur, sujet et type de média.

get_item

Lit la fiche d'un document, ses fichiers et sa licence.

search_books

Trouve des livres par sujet, lieu, période, personne, longueur ou année.

list_snapshots

Liste les captures que la Wayback Machine garde d'une adresse.

get_snapshot

Lit une capture d'une adresse, à une date ou près d'elle.

search_inside

Cherche dans le texte contenu dans les documents, texte issu de la reconnaissance optique de caractères, donc un passage porte les erreurs de lecture de ce procédé.

Argument

Type

Requis

Ce qu'il fait

query

chaîne, 2 à 300 caractères

oui

La phrase à chercher dans les documents.

limit

entier, 1 à 50, défaut 10

non

Correspondances à servir.

page

entier, 1 à 100, défaut 1

non

Quelle page de correspondances.

max_excerpt_chars

entier, 80 à 1200, défaut 300

non

La longueur de passage à servir.

max_excerpts_per_match

entier, 1 à 10, défaut 3

non

Passages servis par document correspondant.

En retour : hits, chacun portant identifier, que get_item reprend ; title, creator et year ; excerpts, les passages tels qu'une machine les a lus sur la page ; matched_file, qui nomme ce qui contient réellement le passage ; et source_url. inside_container est vrai quand le document en rassemble plusieurs et que le passage se trouve dans l'un d'eux, auquel cas le titre, l'auteur et l'année appartiennent au contenant.

total compte des documents, et il pagine. C'est un nombre de documents et la dernière page d'un ensemble est plus courte que la première. Aucun numéro de page n'est disponible : l'index indique où le texte se trouve dans le document, ce qui vaut 1 sur presque toutes les correspondances, donc rien ici n'énonce une page de livre et aucun lien n'en revendique.

search_items

Cherche dans le catalogue lui-même, à travers tout ce que l'archive conserve.

Argument

Type

Requis

Ce qu'il fait

query

chaîne, 1 à 300 caractères

oui

Les mots à chercher au catalogue.

media_type

texts, movies, audio, image, software, data ou web

non

Le type de chose à garder.

year_from

entier, 1 à 2200

non

Année la plus ancienne.

year_to

entier, 1 à 2200

non

Année la plus récente.

sort

relevance, downloads, newest, oldest ou title, défaut relevance

non

L'ordre des lignes.

limit

entier, 1 à 50, défaut 10

non

Lignes à servir.

page

entier, 1 à 100, défaut 1

non

Quelle page de lignes.

En retour : items, chacun portant identifier, title, creator, year, media_type, downloads et source_url, un champ que la fiche laisse vide valant null. total compte les documents correspondants dans tout le catalogue, ce qui dépasse le nombre rendu.

get_item

Lit la fiche d'un document. Les parties lourdes se demandent au lieu d'être servies par défaut, une fiche pouvant être longue.

Argument

Type

Requis

Ce qu'il fait

identifier

chaîne, 1 à 200 caractères

oui

L'identifiant que porte une ligne.

sections

tableau de basic, files, full_metadata, défaut ["basic"]

non

Les parties à rendre.

file_format

chaîne, jusqu'à 60 caractères

non

Ne garder que les fichiers d'un format.

max_files

entier, 1 à 200, défaut 25

non

Plafond sur les fichiers rendus.

max_description_chars

entier, 100 à 20000, défaut 2000

non

La longueur de description à servir.

En retour : le document avec son title, creator, year, media_type et source_url, plus description, date, publisher, language, collections et license_url, chacun null là où la fiche n'indique rien. file_count compte les fichiers que le document contient quel que soit ce que cette réponse a rendu, et total_bytes leur poids. files et full_metadata ne sont là que lorsqu'ils sont demandés dans sections.

search_books

Trouve des livres via l'index d'œuvres qui côtoie l'archive, lequel décrit une œuvre et ses éditions plutôt qu'un exemplaire numérisé.

Argument

Type

Requis

Ce qu'il fait

query

chaîne, 2 à 300 caractères

non

Du texte libre, quand il y en a.

subject

chaîne, 2 à 100 caractères

non

Un sujet sous lequel l'index classe.

place

chaîne, 2 à 100 caractères

non

Un lieu dont une œuvre traite.

time

chaîne, 2 à 100 caractères

non

Une période dont une œuvre traite.

person

chaîne, 2 à 100 caractères

non

Une personne dont une œuvre traite.

language

chaîne, 2 à 20 caractères

non

La langue de l'œuvre.

year_from

entier, 1 à 2200

non

Première publication la plus ancienne.

year_to

entier, 1 à 2200

non

Première publication la plus récente.

pages_min

entier, 1 à 100000

non

Œuvre la plus courte acceptable.

pages_max

entier, 1 à 100000

non

Œuvre la plus longue acceptable.

sort

relevance, rating, readers, newest ou oldest, défaut relevance

non

L'ordre des lignes.

limit

entier, 1 à 50, défaut 10

non

Lignes à servir.

page

entier, 1 à 100, défaut 1

non

Quelle page de lignes.

En retour : books, chacun portant title, authors, first_published_year, edition_count, archive_identifiers pour les exemplaires numérisés que l'archive détient, scan_count, page_count comme médiane sur les éditions, subjects et source_url. searched_for dit en mots ce à quoi cette réponse répond, texte libre et chaque critère appliqué, et query vaut null quand la recherche était faite de critères seuls. total compte les œuvres correspondantes.

list_snapshots

Liste les captures que la Wayback Machine garde d'une adresse.

Argument

Type

Requis

Ce qu'il fait

url

chaîne, 3 à 2000 caractères

oui

L'adresse à consulter.

limit

entier, 1 à 100, défaut 20

non

Captures à servir.

cursor

chaîne, jusqu'à 500 caractères

non

Le next_cursor nommé par une réponse précédente.

En retour : snapshots, chacune avec son captured_at en horodatage ISO UTC, l'url de la capture elle-même, et le status que la collecte a enregistré. first et last décrivent cette réponse plutôt que tout l'historique, et next_cursor poursuit la liste.

get_snapshot

Lit une capture d'une adresse, à une date ou près d'elle.

Argument

Type

Requis

Ce qu'il fait

url

chaîne, 3 à 2000 caractères

oui

L'adresse à consulter.

at

AAAA-MM-JJ ou horodatage ISO

non

La date visée. La capture la plus récente par défaut.

En retour : la snapshot avec son captured_at et son adresse, à côté de requested_url et requested_at, si bien que l'écart entre la date demandée et la capture servie est visible. La Wayback Machine répond à une date dont elle n'a aucune capture par la plus proche qu'elle détient.

Ce que valent les extraits

Le texte contenu dans un document numérisé est issu de la reconnaissance optique de caractères. Un passage porte donc les erreurs de lecture de ce procédé, et il est servi tel qu'il a été lu plutôt que corrigé : un mot qui se lit bizarrement est ce que la machine a vu. Citez un passage comme l'extrait d'une numérisation, et liez le document pour qu'un lecteur puisse regarder la page.

Configuration

Chaque variable est facultative. Elles se posent dans le bloc env de la configuration du client.

Variable

Défaut

Ce qu'elle fait

IA_USER_AGENT

l'identité du projet

Nomme votre application auprès de l'archive, avec une adresse où joindre une personne.

IA_MIN_INTERVAL_MS

1000

Écart entre deux requêtes, de 500 à 60000.

IA_TIMEOUT_MS

20000

Délai d'une requête, de 1000 à 120000.

IA_HISTORY_TIMEOUT_MS

60000

Délai d'un historique Wayback Machine, de 5000 à 180000.

IA_MAX_RETRIES

3

Tentatives après un échec passager, de 0 à 8.

IA_CACHE_TTL_MS

900000

Durée pendant laquelle une réponse reste en mémoire, de 0 à 86400000.

IA_CACHE_MAX_ENTRIES

200

Réponses gardées en mémoire à la fois, de 1 à 5000.

IA_LOG_LEVEL

error

silent, error, info ou debug, écrit sur la sortie d'erreur.

Une valeur hors de sa plage retombe sur le défaut, et la raison est écrite sur la sortie d'erreur.

Erreurs

Chaque échec porte un des six codes, un message, et quand cela aide une indication du geste suivant.

Code

Ce qui s'est passé

Que faire

not_found

L'archive a répondu, et n'a pas ce document.

Vérifiez l'identifiant avec search_items.

invalid_input

Les arguments ont été refusés avant toute requête.

Lisez le message, qui nomme l'argument.

rate_limited

L'archive demande à ce client de ralentir.

Attendez les secondes indiquées et rappelez avec les mêmes arguments. Le document est toujours là.

parse_failure

La réponse est arrivée dans une forme illisible ici.

Signalez-le sur le suivi d'incidents.

network_error

La requête n'a pas abouti.

Réessayez sous peu.

timeout

La requête a dépassé son délai.

Augmentez IA_TIMEOUT_MS, ou IA_HISTORY_TIMEOUT_MS pour un historique.

Comme bibliothèque

La couche qui lit l'archive est publiée seule, avec son rythme, son cache et ses erreurs, sans protocole attaché.

import { ArchiveClient } from "mcp-archiveorg/client";

const client = new ArchiveClient();
const { data, cached } = await client.searchItems({ query: "san francisco earthquake" });
console.log(data.total, cached);

Chaque lecture répond { data, cached }, et lève une erreur portant un des six codes. Le plancher entre deux requêtes tient également ici.

Rythme et attribution

Les requêtes partent une à une avec au moins une seconde entre elles, et le plancher d'une demi-seconde tient quelle que soit la configuration. Le User-Agent se termine toujours par l'identité du projet et une adresse où joindre une personne. L'Internet Archive est une bibliothèque à but non lucratif, et une recherche dans le texte de ses documents est l'une des questions les plus coûteuses qu'elle traite.

Chaque résultat porte l'adresse de la page d'où il a été lu. Les documents appartiennent aux personnes et aux institutions qui les ont déposés, sous les conditions que chaque fiche indique dans license_url.

Ce MCP est un projet non officiel, sans affiliation à l'Internet Archive.

Confidentialité

Ce serveur ne collecte rien sur vous et n'envoie rien à son auteur. Il tourne sur votre machine, ne joint que archive.org, web.archive.org et openlibrary.org, garde ses réponses en mémoire le temps qu'il tourne, et n'écrit rien sur le disque. PRIVACY.md dit ce qu'une requête emporte et quels réglages changent cela.

Développement

npm install
npm run build:fixtures
npm test
npm run check

Les tests s'exécutent sur des fixtures engendrées et n'émettent aucune requête. La suite en direct, npm run test:live, émet une requête par route et tourne chaque nuit contre l'archive elle-même.

Contribuer

Les anomalies, les questions et les idées ont leur place dans le suivi d'incidents. Les propositions de modification sont bienvenues ; ouvrir un ticket d'abord aide à s'accorder sur la forme du changement. Voir CONTRIBUTING.md.

Licence

MIT, voir LICENSE. Les documents appartiennent à ceux qui les ont déposés, sous les conditions que chaque fiche indique.

Available Tools

6 tools
get_itemRead an itemA
Read-onlyIdempotent

Read one Internet Archive item by its identifier, as returned by search_items or search_inside. Sections are opt-in: 'basic' is the default and covers what a description needs. 'files' lists the downloadable files, which on a scanned film or book run to dozens of derivatives, so filter by format when a particular one is wanted. 'full_metadata' returns every field the Archive publishes for the item, which is large and rarely needed. 'file_count' and 'total_bytes' are always reported, whether or not the file list was asked for.

ParametersJSON Schema
NameRequiredDescriptionDefault
sectionsNoWhich parts to return. Each one beyond 'basic' adds to the size of the answer.
max_filesNoCeiling on files returned.
identifierYesArchive identifier, such as 'nasa'. It is the last part of an item's address rather than the address itself, and it is matched exactly, capitals included.
file_formatNoKeep only files of this format, such as 'PDF' or 'MP3'. Matched case-insensitively.
max_description_charsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
dateYes
itemYes
filesNo
notesYes
languageYes
publisherYes
file_countYesFiles the item holds, whatever this answer returned.
collectionsYesCollections the item sits in.
descriptionYes
license_urlYesTerms the uploader attached, when they attached any.
total_bytesYes
full_metadataNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/idempotent/non-destructive annotations, the description reveals default behavior (basic section), the potentially large size of files list, the always-reported file_count and total_bytes, and the trade-off of full_metadata. This gives the agent a clear picture of output size and how to control it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences deliver all key information with no padding. The first sentence states the core purpose, the second explains default behavior, the third details the optional sections and filtering, and the fourth reveals an always-returned metric. Each sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity, output schema presence, and strong annotations, the description covers everything an agent needs: how to get the item, what sections are available, size implications, and default metrics. No critical gaps remain for selecting and invoking the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 80% schema coverage, the baseline is 3, but the description adds meaningful semantics: it explains what 'basic' covers, that 'files' lists derivatives and can be filtered by format, and that full_metadata is rarely needed. It does not mention max_description_chars, but the schema already provides bounds; overall the description enriches the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Read one Internet Archive item by its identifier,' which clearly states a specific verb (read) and resource (item). It distinguishes from sibling search/list tools by targeting a single known item rather than searching, and it references the upstream search tools that produce the identifier.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains that identifiers come from search_items or search_inside, implicitly guiding when to use this tool (after searching). It also provides clear guidance on section selection, advising against full_metadata as 'large and rarely needed' and recommending format filtering for files, which helps choose the right parameters.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_snapshotRead a page as it wasA
Read-onlyIdempotent

Find the Wayback Machine capture of a web page closest to a given date. Give 'at' to ask for a moment in time; leave it out for the most recent capture. The answer always states 'days_from_requested', because the closest capture can be years away from the date asked for: read it before describing what the page said on that date. It also states the address the capture is of, which the Wayback Machine can resolve to a neighbouring form of the one asked about. This finds the capture and links to it. It does not return the page's contents.

ParametersJSON Schema
NameRequiredDescriptionDefault
atNoDate to aim for, as YYYY-MM-DD or a full ISO 8601 timestamp. Omit for the newest capture.
urlYesAddress to look up, such as 'lemonde.fr' or a full URL.

Output Schema

ParametersJSON Schema
NameRequiredDescription
notesYes
snapshotYes
requested_atYes
requested_urlYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint, idempotentHint), the description adds significant behavioral context: the response always includes 'days_from_requested', the URL can resolve to a neighboring form, and it does not return the page's contents. These are not in the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is relatively long but front-loaded with the main purpose. Every sentence adds value, covering purpose, parameter usage, key caveats, and non-behavior, making it appropriately sized for the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with only two parameters, an output schema, and strong annotations, the description is thorough: it explains the main purpose, parameter semantics, important behavioral nuances, and explicitly states what the tool does not do. No significant gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema already has 100% parameter coverage, and the description adds extra meaning by explaining how to use 'at' (omit for most recent) and that the URL may resolve to a neighboring form. This goes beyond the schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool finds the Wayback Machine capture of a web page closest to a given date, using a specific verb and resource. It also differentiates from sibling tools by noting it links to the capture but does not return page contents.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear guidance on when to use it (closest capture to a date) and explains the 'at' parameter's behavior, but does not explicitly name alternative tools for different needs, such as searching inside content.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_snapshotsList captures of a pageA
Read-onlyIdempotent

List Wayback Machine captures of a web page, oldest first, with the dates they were taken. Answers how long a page has been archived and how often, which get_snapshot cannot. A capture whose content repeats the row before it is left out of the index answer. The index also holds one site under several addresses at once, such as its www form, its https form and a form carrying credentials, and returns them interleaved, so two consecutive rows can differ because the address differs rather than because the page did. Every row names the address it captured; read that before counting the captures of any one of them. A capture records when the crawler came, not when the page changed: the change happened somewhere between two dates. This route is slow, tens of seconds on a heavily archived address, and it is paged for that reason. To walk further back, pass the 'next_cursor' from the previous answer as 'cursor'. The index counts rows rather than positions, so there is no page number and no arithmetic to do: a null 'next_cursor' means the end of what it holds.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesAddress to look up.
limitNoCaptures to return.
cursorNoThe 'next_cursor' from a previous answer. Omit to start at the oldest capture.

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlYes
lastYesLatest capture in this answer, not in the whole history.
firstYesEarliest capture in this answer, not in the whole history.
notesYes
returnedYesCaptures in this answer.
snapshotsYes
next_cursorYesPass back as 'cursor' to read the window after this one. Null at the end of the history.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds extensive behavior beyond the read-only annotations: deduplication of repeated captures, interleaving of multiple site addresses, the difference between capture date and change date, and the row-based index count. It also discloses the performance characteristic ('tens of seconds') and pagination mechanics. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Although lengthy, every sentence carries critical caveats. It is front-loaded with a clear one-sentence purpose followed by well-organized behavioral details. The density of information is high, and the structure supports easy scanning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity—pagination, deduplication, multi-address handling, and interpretation of capture dates—the description covers all essential caveats. An output schema exists, so return fields are not needed. It also sets performance expectations, making the description complete for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for all three parameters, so the baseline is 3. The description adds extra meaning about cursor usage ('pass the next_cursor from the previous answer') and clarifies the pagination model ('rows rather than positions, so there is no page number and no arithmetic to do'), which goes beyond the schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'List Wayback Machine captures of a web page, oldest first, with the dates they were taken.' It explicitly differentiates from the sibling get_snapshot: 'Answers how long a page has been archived and how often, which get_snapshot cannot.' This makes the purpose unmistakable and distinct.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use guidance by contrasting with get_snapshot and advises on the tool's slowness: 'This route is slow, tens of seconds on a heavily archived address.' It also explains how to paginate with the cursor, so the agent knows exactly when to use this tool and how to proceed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_booksSearch works and editionsA
Read-onlyIdempotent

Find a book on Open Library, the Internet Archive's catalogue of works, either by name or by description. Pass 'query' when you know what you are looking for: a title, an author. Free text matches parts of words and reads titles and authors together, so a name also finds works by authors whose name merely contains it: read 'authors' on each row before treating a result as that author's work. Pass the criteria instead when you do not, and they combine: 'subject' for what a work is catalogued under, 'place' for where it is set, 'time' for the period it treats, 'person' for who it is about, plus ranges on the year of first publication and on the page count. 'sort' by rating or by readers answers 'what is worth reading', which relevance alone does not. 'first_published_year' is the year Open Library derives from its edition records, and a reissue or a mistyped edition can put it centuries from the real date; 'newest' and 'oldest' rank on that field, so the rows carrying the doubtful years lead the order. Answers who wrote a book, when it first appeared and how many editions exist, which the item catalogue describes poorly because it holds one upload at a time. 'archive_identifiers' lists up to 3 scans of the work: pass one to get_item, or use it to read the book itself. 'scan_count' says how many the work has. A scan is one edition, and a work first printed centuries ago is often held only as a later reissue or a translation, so read the scan's own record before dating what it holds. Use this to identify a work, and search_inside to find a phrase within one.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo
sortNo'rating' is how readers scored it, 'readers' is how many recorded reading it, and both answer a question relevance cannot. 'newest' and 'oldest' rank on 'first_published_year', which the index takes from edition records: read that field on each row against the work's page before repeating it.relevance
timeNoThe period the work treats, such as '20th century'.
limitNo
placeNoWhere the work is set, such as 'Shanghai'.
queryNoTitle or author, as free text. Optional when a criterion below is given.
personNoWho the work is about, such as 'Napoleon'.
subjectNoWhat the work is catalogued under, such as 'grief' or 'spy stories'. Also carries prizes and lists, such as 'Booker Prize'.
year_toNoLatest first publication.
languageNoThree-letter code of the language, such as 'eng' or 'fre'.
pages_maxNoLongest acceptable work. The count is a median across editions.
pages_minNoShortest acceptable work.
year_fromNoEarliest first publication.

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageYes
booksYes
notesYes
queryYesThe free text the caller sent, as it was sent. Null when the search was made of criteria alone.
totalYesWorks matching, not the number returned.
searched_forYesWhat this answer answers, in words: the free text and every criterion applied.

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark readOnlyHint, openWorldHint, and idempotentHint. The description adds meaningful caveats beyond annotations: free-text matching reads titles and authors together, first_published_year is derived from edition records and can be inaccurate, and archive_identifiers lists up to 3 scans. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but front-loaded with the main purpose and every sentence carries non-redundant value, such as the warning to read authors before treating a result and the explanation of scan vs. edition. For a 13-parameter tool, this density is appropriate.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the rich input schema, output schema, and annotations, the description fully covers the two search modes, sorting rationale, data-quality caveats, scan/archive handling, and sibling tool connections. It provides sufficient context for an agent to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Even though schema coverage is high (85%), the description adds important semantics: it distinguishes query from criteria, explains that criteria combine, clarifies subject can carry prizes/lists, and describes how sort options like newest/oldest rank on a potentially unreliable field. This goes well beyond the schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Find a book on Open Library, the Internet Archive's catalogue of works.' It clearly differentiates from siblings by explaining that search_inside finds a phrase within a work and that this tool identifies a work, while comparing it to the item catalogue.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states when to use 'query' vs. 'criteria' ('Pass query when you know what you are looking for... Pass the criteria instead when you do not'), explains when to use sort by rating/readers, and names alternates: use search_inside for phrases and pass archive_identifiers to get_item. This gives clear decision guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_insideSearch inside scanned pagesA
Read-onlyIdempotent

Search the text inside digitised books, newspapers and documents on the Internet Archive. This reads what optical recognition took off the scanned pages, so it finds a phrase that appears nowhere in a title or a catalogue record. Put a phrase in double quotes to hold the words together in that order. The index folds accents, case and punctuation before it matches, so the letters are not held: a quoted "bûcher" comes back on pages printing Bücher and Bucher. Read an excerpt before repeating a quoted query as the spelling a page carries. Without quotes the words are matched separately, which finds far more. 'total' counts the documents that match, and they page: ask for page 2, 3 and so on to see beyond the first answer. It is not a count of how many times the phrase occurs. The index reports no page number, so a match names the item and the passage, never a leaf. Follow source_url and search the item to find where the passage sits. When 'inside_container' is true the passage came from a document bundled inside the item, and the title, creator and year describe the container rather than the text that matched: read 'matched_file' for what actually holds it. Use search_items or search_books instead when looking for a work by its title, author or subject.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoWhich page of matches, from 1. Paging stops at 100.
limitNoMatches to return.
queryYesWords or a quoted phrase, such as '"call me ishmael"'.
max_excerpt_charsNoBudget for one passage. Read it together with 'max_excerpts_per_match': the size of the answer is the product of the two and the number of matches.
max_excerpts_per_matchNoPassages to keep per match. The index finds several in a long work, and the later ones rarely say anything the first did not.

Output Schema

ParametersJSON Schema
NameRequiredDescription
hitsYes
pageYes
notesYes
queryYes
totalYesDocuments that match, not the number returned and not a count of occurrences. Raise 'page' to read further into it.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint, the description discloses key behaviors: accent/case/punctuation folding, quoted phrase preservation, unquoted tokenization, the meaning of 'total' (document count, not occurrence count), lack of page numbers, and the inside_container nuance with matched_file. This is substantial behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence earns its place. It opens with the core purpose, then logically covers query syntax, matching behavior, pagination, result semantics, and edge cases, ending with alternatives. No fluff or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema already documents return values, the description covers essential edge cases (accent folding, quoted vs unquoted, container documents, page limitations) and provides enough context for an agent to invoke the tool correctly. It feels complete for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with thorough parameter descriptions. The description adds extra semantics for the query parameter (quoting, accent folding) and mentions paging behavior. It does not deeply explain limit or excerpt parameters, but schema already covers them, so the added value is meaningful without being fully compensatory.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool searches full text inside scanned documents, explicitly distinguishing it from metadata search. It names the resource (digitised books, newspapers, documents) and the specific capability (optical recognition text), making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use this tool vs siblings: 'Use search_items or search_books instead when looking for a work by its title, author or subject.' It also explains quoting, accent folding, and paging behavior, giving clear usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_itemsSearch the catalogueA
Read-onlyIdempotent

Search the Internet Archive catalogue: films, books, recordings, images, software and datasets. This matches titles, creators and descriptions, so a compilation whose notes mention a name ranks alongside that person's own work: read 'creator' on each row before treating a result as theirs. It does not read the contents of a scan; use search_inside for a phrase within a book. Set 'media_type' whenever the kind of thing is known, because one title exists across several media and mixing them makes a result list unreadable. 'oldest', 'newest', 'year_from' and 'year_to' all read one field: the date a depositor typed into the record. An item with no date carries a placeholder the index sorts as a real one, a date written as a fragment is filed at the year that fragment reads as, and the field holds no era, so a Babylonian tablet of 1712 BCE answers a search of 1700 to 1750. Read an order or a range as a statement about that field. Every row carries an 'identifier', which get_item takes.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo
sortNo'downloads' surfaces what people actually read, which relevance alone often buries. 'oldest' and 'newest' rank on a declared date, not on when a thing was made.relevance
limitNo
queryYesWords to look for in titles, creators and descriptions.
year_toNoLatest year, inclusive, on the record's declared date, which carries no era.
year_fromNoEarliest year, inclusive, on the record's declared date, which carries no era.
media_typeNoNarrow to one kind of thing. Strongly recommended.

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageYes
itemsYes
notesYes
queryYes
totalYesItems matching across the catalogue, not the number returned.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/openWorld/idempotent annotations, the description discloses important quirks: matching covers titles/creators/descriptions, not scan contents; the year fields reflect a depositor-typed date with placeholder/fragment/era issues; and sorting on 'oldest'/'newest' uses declared dates. This is substantive behavioral context that the annotations do not provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is longer than the ideal but remains front-loaded with the core purpose in the first sentence. Every sentence earns its place, covering matching semantics, date quirks, and alternatives. It is verbose in places (e.g., the date fragment sentence) but stays focused and logically organized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the presence of an output schema and strong annotations, the description only needed to explain behavior, and it does so thoroughly. It covers matching, date-side-effects, media type guidance, sort semantics, and how to proceed to get_item. No critical context is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 71%, but the description adds meaning beyond the schema: it explains that year_from/year_to operate on the declared date with no era (so 1712 BCE matches 1700–1750), clarifies sort behavior, and explains the rationale for media_type. Although page and limit are not elaborated, they are self-evident. This compensates well for any gaps.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource: 'Search the Internet Archive catalogue: films, books, recordings, images, software and datasets.' It clearly states the scope and distinguishes from siblings by naming search_inside and get_item. This fully clarifies what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly directs when to use alternatives: 'use search_inside for a phrase within a book' and mentions that get_item takes the identifier. It also strongly recommends setting media_type. This provides clear when-to-use and when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv1.5.0
    • Changedget_item2 fields changed
      • changedInput schema / properties / identifier / description
        Previous value: -"Archive identifier, such as 'nasa'."New value: +"Archive identifier, such as 'nasa'. It is the last part of an item's address rather than the address itself, and it is matched exactly, capitals included."
      • changedOutput schema / properties / item / properties / media_type / description
        Previous value: -"texts, movies, audio, image, software or data."New value: +"The kind the catalogue files this row under, in the Archive's own words. Most rows carry one of texts, movies, audio, image, software or data, and some carry a kind the filter cannot ask for, such as 'collection' for a page gathering items rather than an item itself."
    • Changedget_snapshot3 fields changed
      • addedOutput schema / properties / snapshot / properties / address
        Added value: +{
        +  "description": "The address this capture is of. The Wayback Machine indexes a site under several addresses at once, such as its www form, its https form and a form carrying credentials, so this can differ from the address that was asked about.",
        +  "type": "string"
        +}
      • changedOutput schema / properties / snapshot / properties / days_from_requested / description
        Previous value: -"Whole days between this capture and the date asked for. Null when no date was given."New value: +"Whole days between this capture and the moment asked for, counted down: a capture taken on the day asked about, when no time was given, is 0. Null when no date was given."
      • changedOutput schema / properties / snapshot / required
        Previous value: -[
        -  "captured_at",
        -  "url",
        -  "status",
        -  "days_from_requested"
        -]New value: +[
        +  "captured_at",
        +  "url",
        +  "address",
        +  "status",
        +  "days_from_requested"
        +]
    • Changedlist_snapshots2 fields changed
      • addedOutput schema / properties / snapshots / items / properties / address
        Added value: +{
        +  "description": "The address this capture is of. The Wayback Machine indexes a site under several addresses at once, such as its www form, its https form and a form carrying credentials, so this can differ from the address that was asked about.",
        +  "type": "string"
        +}
      • changedOutput schema / properties / snapshots / items / required
        Previous value: -[
        -  "captured_at",
        -  "url",
        -  "status"
        -]New value: +[
        +  "captured_at",
        +  "url",
        +  "address",
        +  "status"
        +]
    • Changedsearch_books5 fields changed
      • addedOutput schema / properties / query / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / properties / query / description
        Previous value: -"What was searched for, criteria included."New value: +"The free text the caller sent, as it was sent. Null when the search was made of criteria alone."
      • removedOutput schema / properties / query / type
        Removed value: -"string"
      • addedOutput schema / properties / searched_for
        Added value: +{
        +  "description": "What this answer answers, in words: the free text and every criterion applied.",
        +  "type": "string"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "query",
        -  "total",
        -  "page",
        -  "books",
        -  "notes"
        -]New value: +[
        +  "query",
        +  "searched_for",
        +  "total",
        +  "page",
        +  "books",
        +  "notes"
        +]
    • Changedsearch_inside1 field changed
      • changedInput schema / properties / page / description
        Previous value: -"Which page of matches, from 1."New value: +"Which page of matches, from 1. Paging stops at 100."
    • Changedsearch_items3 fields changed
      • changedInput schema / properties / year_from / description
        Previous value: -"Earliest year, inclusive."New value: +"Earliest year, inclusive, on the record's declared date, which carries no era."
      • changedInput schema / properties / year_to / description
        Previous value: -"Latest year, inclusive."New value: +"Latest year, inclusive, on the record's declared date, which carries no era."
      • changedOutput schema / properties / items / items / properties / media_type / description
        Previous value: -"texts, movies, audio, image, software or data."New value: +"The kind the catalogue files this row under, in the Archive's own words. Most rows carry one of texts, movies, audio, image, software or data, and some carry a kind the filter cannot ask for, such as 'collection' for a page gathering items rather than an item itself."
  2. 1 tool updatev1.4.0
    • Changedsearch_items1 field changed
      • changedInput schema / properties / sort / description
        Previous value: -"'downloads' surfaces what people actually read, which relevance alone often buries."New value: +"'downloads' surfaces what people actually read, which relevance alone often buries. 'oldest' and 'newest' rank on a declared date, not on when a thing was made."
  3. 6 tool updatesv1.3.0
    • Changedget_item1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedget_snapshot1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedlist_snapshots1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedsearch_books6 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / sort / description
        Previous value: -"'rating' is how readers scored it, 'readers' is how many recorded reading it, and both answer a question relevance cannot."New value: +"'rating' is how readers scored it, 'readers' is how many recorded reading it, and both answer a question relevance cannot. 'newest' and 'oldest' rank on 'first_published_year', which the index takes from edition records: read that field on each row against the work's page before repeating it."
      • changedOutput schema / properties / books / items / properties / archive_identifiers / description
        Previous value: -"Scans of this work held by the Archive. Pass one to get_item."New value: +"Scans of this work held by the Archive. Pass one to get_item. At most 3 are listed, so the list is a sample whenever 'scan_count' is larger; the work's page on Open Library holds them all."
      • addedOutput schema / properties / books / items / properties / first_published_year / description
        Added value: +"The year Open Library derives from its edition records. A reissue or a mistyped edition can put it centuries from the date the work first appeared, so check it against the work's page before citing it."
      • addedOutput schema / properties / books / items / properties / scan_count
        Added value: +{
        +  "description": "Scans of this work the Archive holds, whatever the list above shows.",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • changedOutput schema / properties / books / items / required
        Previous value: -[
        -  "title",
        -  "authors",
        -  "first_published_year",
        -  "edition_count",
        -  "archive_identifiers",
        -  "page_count",
        -  "subjects",
        -  "source_url"
        -]New value: +[
        +  "title",
        +  "authors",
        +  "first_published_year",
        +  "edition_count",
        +  "archive_identifiers",
        +  "scan_count",
        +  "page_count",
        +  "subjects",
        +  "source_url"
        +]
    • Changedsearch_inside1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedsearch_items1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
  4. 1 tool updatev1.1.0
    • Changedsearch_books16 fields changed
      • addedInput schema / properties / language
        Added value: +{
        +  "description": "Three-letter code of the language, such as 'eng' or 'fre'.",
        +  "maxLength": 20,
        +  "minLength": 2,
        +  "type": "string"
        +}
      • addedInput schema / properties / pages_max
        Added value: +{
        +  "description": "Longest acceptable work. The count is a median across editions.",
        +  "maximum": 100000,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / pages_min
        Added value: +{
        +  "description": "Shortest acceptable work.",
        +  "maximum": 100000,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / person
        Added value: +{
        +  "description": "Who the work is about, such as 'Napoleon'.",
        +  "maxLength": 100,
        +  "minLength": 2,
        +  "type": "string"
        +}
      • addedInput schema / properties / place
        Added value: +{
        +  "description": "Where the work is set, such as 'Shanghai'.",
        +  "maxLength": 100,
        +  "minLength": 2,
        +  "type": "string"
        +}
      • changedInput schema / properties / query / description
        Previous value: -"Title, author or subject."New value: +"Title or author, as free text. Optional when a criterion below is given."
      • addedInput schema / properties / sort
        Added value: +{
        +  "default": "relevance",
        +  "description": "'rating' is how readers scored it, 'readers' is how many recorded reading it, and both answer a question relevance cannot.",
        +  "enum": [
        +    "relevance",
        +    "rating",
        +    "readers",
        +    "newest",
        +    "oldest"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / subject
        Added value: +{
        +  "description": "What the work is catalogued under, such as 'grief' or 'spy stories'. Also carries prizes and lists, such as 'Booker Prize'.",
        +  "maxLength": 100,
        +  "minLength": 2,
        +  "type": "string"
        +}
      • addedInput schema / properties / time
        Added value: +{
        +  "description": "The period the work treats, such as '20th century'.",
        +  "maxLength": 100,
        +  "minLength": 2,
        +  "type": "string"
        +}
      • addedInput schema / properties / year_from
        Added value: +{
        +  "description": "Earliest first publication.",
        +  "maximum": 2200,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / year_to
        Added value: +{
        +  "description": "Latest first publication.",
        +  "maximum": 2200,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "query"
        -]
      • addedOutput schema / properties / books / items / properties / page_count
        Added value: +{
        +  "anyOf": [
        +    {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Median pages across editions, which is what the index holds."
        +}
      • addedOutput schema / properties / books / items / properties / subjects
        Added value: +{
        +  "description": "What the work is catalogued under, trimmed to the most prominent.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • changedOutput schema / properties / books / items / required
        Previous value: -[
        -  "title",
        -  "authors",
        -  "first_published_year",
        -  "edition_count",
        -  "archive_identifiers",
        -  "source_url"
        -]New value: +[
        +  "title",
        +  "authors",
        +  "first_published_year",
        +  "edition_count",
        +  "archive_identifiers",
        +  "page_count",
        +  "subjects",
        +  "source_url"
        +]
      • addedOutput schema / properties / query / description
        Added value: +"What was searched for, criteria included."
  5. 6 tool updatesv0.1.0
    • First observedget_item
    • First observedget_snapshot
    • First observedlist_snapshots
    • First observedsearch_books
    • First observedsearch_inside
    • First observedsearch_items

TDQS

A4.7/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: search_inside searches full text of scanned documents, search_items searches Internet Archive metadata, search_books searches Open Library metadata, get_item retrieves a specific item, and get_snapshot/list_snapshots handle Wayback captures. The descriptions explicitly call out when to use one over the other, eliminating ambiguity.

Naming Consistency5/5

All tool names follow a consistent lower_snake_case verb_noun pattern: search_*, get_item, list_snapshots. The verbs (search, get, list) accurately describe the action, and the nouns (inside, items, books, item, snapshot, snapshots) clearly indicate the resource. There is no mixing of styles or vague verbs.

Tool Count5/5

With 6 tools, the set is well-scoped and each tool earns its place. It covers the core domains of Internet Archive search, item retrieval, and Wayback Machine snapshot access without unnecessary fragmentation or bloat. The count is within the ideal range for a focused server.

Completeness4/5

The tool surface covers the primary read-oriented workflows: finding items by metadata, finding text inside scans, identifying works via Open Library, retrieving item details, and exploring Wayback captures. Minor gaps exist, such as the inability to download file content directly or to search the Wayback Machine by text, but these are not essential for the server's apparent purpose and can be worked around using the provided links and identifiers.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    MCP server for the Internet Archive's Wayback Machine. Search archived snapshots, extract page text from a specific date, track how a site has changed over time, check if broken links are recoverable, and perform research across Internet Archive collections.
    6
    3
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Self-hosted MCP server for searching and discovering books using Anna's Archive and Goodreads datasets, enabling full-text search, ISBN/md5 lookup, similarity matching, and optional download URL retrieval.
    7
    2
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    MCP server and CLI tool for interacting with the Internet Archive's Wayback Machine, supporting full CDX search, snapshot retrieval, screenshot listing, snapshot comparison, and optional authentication.
    8
    776
    50
    Creative Commons Attribution Non Commercial Share Alike 4.0 International