MCP Open Library
Um servidor Model Context Protocol (MCP) para a API do Open Library que permite que assistentes de IA pesquisem informações sobre livros e autores.
Documentação
MCP Open Library
Um servidor Model Context Protocol (MCP) para a API Open Library que permite que assistentes de IA pesquisem informações sobre livros e autores.
Visão Geral
Este projeto implementa um servidor MCP que fornece ferramentas para assistentes de IA interagirem com a Open Library. Ele permite pesquisar no catálogo por título, autor, assunto e outros campos, pesquisar autores por nome, obter informações detalhadas de autores usando sua chave Open Library e obter URLs para capas de livros e fotos de autores. O servidor retorna projeções JSON das respostas da Open Library em vez dos payloads brutos.
Recursos
- Pesquisa de Livros: Pesquise em títulos, autores, assuntos, locais, pessoas, editoras e ISBNs, com ordenação e paginação (
search_books). - Pesquisa de Livros por Título: Pesquise livros usando seu título (
get_book_by_title). - Pesquisa de Autores por Nome: Pesquise autores usando seu nome, com paginação (
get_authors_by_name). - Obter Detalhes do Autor: Recupere informações detalhadas de um autor específico usando sua chave Open Library (
get_author_info). - Obter Foto do Autor: Obtenha a URL da foto de um autor usando seu ID Open Library (OLID) (
get_author_photo). - Obter Capa do Livro: Obtenha a URL da imagem da capa de um livro usando vários identificadores (ISBN, OCLC, LCCN, OLID, ID) (
get_book_cover). - Obter Livro por ID: Recupere informações detalhadas do livro usando vários identificadores (ISBN, LCCN, OCLC, OLID) (
get_book_by_id).
Os resultados da pesquisa são paginados — cada ferramenta de pesquisa retorna no máximo limit resultados (padrão 10, máximo 50) juntamente com num_found, o número total de correspondências, que você percorre com offset (máximo 1000). As duas ferramentas de capa verificam se uma imagem realmente existe e informam quando não existe, em vez de devolver uma URL que resolve para um espaço reservado em branco.
Cada ferramenta é uma consulta somente leitura e se anuncia como tal com as anotações readOnlyHint e openWorldHint, o que pode permitir que um cliente ignore o prompt de confirmação que mostra para ferramentas que poderiam alterar algo. Estas são dicas: a especificação MCP faz com que os clientes tratem as anotações como não confiáveis, a menos que o servidor seja confiável, então a política de confirmação é decisão do cliente. Falhas — uma API inacessível, um argumento rejeitado — retornam como um resultado de ferramenta sinalizado como isError, para que um assistente possa ler o que deu errado e corrigir sua próxima chamada em vez de a solicitação falhar completamente.
Instalação
Início Rápido
Nada para instalar ou compilar. Aponte um cliente MCP para o pacote com npx e ele
será buscado na primeira execução:
{
"mcpServers": {
"mcp-open-library": {
"command": "npx",
"args": ["-y", "mcp-open-library"]
}
}
}
No Claude Desktop isso vai em claude_desktop_config.json; outros clientes usam a
mesma estrutura. Reinicie o cliente e as sete ferramentas abaixo ficam disponíveis.
Registro MCP
Este servidor publica no Registro MCP oficial como
io.github.8enSmith/mcp-open-library a partir da v1.0.3. Clientes que
suportam o registro podem instalá-lo por esse nome.
Para inspecionar a listagem publicada:
curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.8enSmith/mcp-open-library"
Instalação Manual
# Clone the repository
git clone https://github.com/8enSmith/mcp-open-library.git
cd mcp-open-library
# Install dependencies
npm install
# Build the project
npm run build
Uso
Executando o Servidor
- Certifique-se de estar executando o node v22.21.1 (provavelmente funcionará em uma versão mais recente do node, mas é o que estou usando para este teste). Se você tiver
nvminstalado, executenvm use. - No diretório raiz
mcp-open-library, executenpm run build - Em seguida, execute
npm run inspector. Após a compilação, clique na URL com o parâmetro de string de consultaMCP_PROXY_AUTH_TOKENpara abrir o Inspector. - No Inspector, escolha o transporte 'STDIO'
- Certifique-se de que o comando esteja definido como 'build/index.js'
- Clique no botão 'Connect' no Inspector — você se conectará ao servidor
- Clique em 'Tools' na barra de menu superior direita
- Tente executar uma ferramenta, por exemplo, clique em get_book_by_title
- Pesquise um livro, por exemplo, no campo de título digite 'The Hobbit' e clique em 'Run Tool'. O servidor retornará os detalhes do livro.
Usando com um Cliente MCP
Este servidor implementa o Model Context Protocol, o que significa que pode ser usado por qualquer assistente de IA ou cliente compatível com MCP, por exemplo, Claude Desktop. O servidor expõe as seguintes ferramentas:
search_books: Pesquise no catálogo por qualquer combinação de consulta, título, autor, assunto, local, pessoa, editora e ISBNget_book_by_title: Pesquise informações de livros por títuloget_authors_by_name: Pesquise informações de autores por nomeget_author_info: Obtenha informações detalhadas de um autor específico usando sua Chave de Autor Open Libraryget_author_photo: Obtenha a URL da foto de um autor usando seu ID de Autor Open Library (OLID)get_book_cover: Obtenha a URL da imagem da capa de um livro usando um identificador específico (ISBN, OCLC, LCCN, OLID ou ID)get_book_by_id: Obtenha informações detalhadas do livro usando um identificador específico (ISBN, LCCN, OCLC ou OLID)
Exemplo de entrada search_books:
{
"author": "Ursula K. Le Guin",
"subject": "fantasy",
"sort": "old",
"limit": 2
}
Exemplo de saída search_books:
{
"num_found": 51,
"offset": 0,
"limit": 2,
"results": [
{
"title": "A Wizard of Earthsea",
"authors": ["Ursula K. Le Guin"],
"first_publish_year": 1968,
"open_library_work_key": "/works/OL59798W",
"edition_count": 87,
"author_keys": ["OL31353A"],
"best_edition": {
"edition_key": "OL5613890M"
},
"cover_url": "https://covers.openlibrary.org/b/id/13617691-M.jpg",
"ratings_average": 3.95,
"ebook_access": "borrowable"
}
]
}
best_edition é uma edição específica da obra — aquela que a Open Library classifica melhor para sua consulta — carregando os identificadores próprios dessa edição. Os resultados da pesquisa, caso contrário, identificam uma obra (open_library_work_key), que nenhuma ferramenta aceita, então esta é a rota de um resultado de pesquisa para um livro concreto.
Seu edition_key é um OLID que você pode passar diretamente para get_book_by_id para obter o registro completo da edição, incluindo seus arrays completos de ISBN:
{ "idType": "olid", "idValue": "OL5613890M" }
Os campos isbn_13 / isbn_10 são omitidos quando a Open Library não possui ISBN para aquela edição — como no exemplo acima, e em aproximadamente um terço dos resultados — enquanto edition_key está essencialmente sempre presente. Quando uma edição lista vários ISBNs de um tipo, o primeiro é relatado; get_book_by_id retorna todos eles.
A ferramenta search_books aceita os seguintes parâmetros:
- Pelo menos um de
q,title,author,subject,place,person,publisherouisbn— a solicitação é rejeitada sem um, pois uma pesquisa sem filtro corresponde ao catálogo inteiro.qaceita uma consulta Solr de forma livre, comosubject:cyberpunk AND first_publish_year:[1980 TO 1990] language: Código de idioma MARC opcional de 3 letras (por exemplo,eng,fre)sort: Ordenação opcional —new,old,random,key,rating,readinglog,want_to_read,currently_reading,already_readoutitle. Omita para relevâncialimit: Opcional, 1–50, padrão 10offset: Opcional, 0–1000, padrão 0
Exemplo de entrada get_book_by_title:
{
"title": "The Hobbit",
"limit": 1
}
Exemplo de saída get_book_by_title:
{
"num_found": 224,
"offset": 0,
"limit": 1,
"results": [
{
"title": "The Hobbit",
"authors": ["J.R.R. Tolkien"],
"first_publish_year": 1937,
"open_library_work_key": "/works/OL27482W",
"edition_count": 481,
"author_keys": ["OL26320A"],
"best_edition": {
"edition_key": "OL51709286M",
"isbn_13": "9780395520215",
"isbn_10": "0395520215"
},
"cover_url": "https://covers.openlibrary.org/b/id/14627509-M.jpg",
"ratings_average": 4.29,
"ebook_access": "borrowable"
}
]
}
Exemplo de entrada get_authors_by_name:
{
"name": "J. R. R. Tolkien",
"limit": 2
}
Exemplo de saída get_authors_by_name:
O key de cada resultado pode ser passado para get_author_info para obter o registro completo desse autor. alternate_names é abreviado aqui.
{
"num_found": 2,
"offset": 0,
"limit": 2,
"results": [
{
"key": "OL26320A",
"name": "J.R.R. Tolkien",
"alternate_names": ["John Ronald Reuel Tolkien", "Tolkien"],
"birth_date": "3 January 1892",
"top_work": "The Hobbit",
"work_count": 355
},
{
"key": "OL332676A",
"name": "J. R. R. Tolkien Centenary Conference (1992 Keble College, Oxford)",
"top_work": "Proceedings of the J.R.R. Tolkien Centenary Conference, 1992",
"work_count": 2
}
]
}
Exemplo de entrada get_author_info:
{
"author_key": "OL26320A"
}
Exemplo de saída get_author_info:
{
"name": "J. R. R. Tolkien",
"personal_name": "John Ronald Reuel Tolkien",
"birth_date": "3 January 1892",
"death_date": "2 September 1973",
"bio": "John Ronald Reuel Tolkien (1892-1973) was a major scholar of the English language, specializing in Old and Middle English. He served as the Rawlinson and Bosworth Professor of Anglo-Saxon and later the Merton Professor of English Language and Literature at Oxford University.",
"alternate_names": ["John Ronald Reuel Tolkien"],
"photos": [6791763],
"key": "/authors/OL26320A",
"remote_ids": {
"viaf": "95218067",
"wikidata": "Q892"
},
"revision": 43,
"last_modified": {
"type": "/type/datetime",
"value": "2023-02-12T05:50:22.881"
}
}
Exemplo de entrada get_author_photo:
{
"olid": "OL26320A"
}
Exemplo de saída get_author_photo:
https://covers.openlibrary.org/a/olid/OL26320A-L.jpg
Quando a Open Library não tem foto para esse autor, a ferramenta informa isso em vez de retornar uma URL:
No author photo available for OLID OL99999999A.
Exemplo de entrada get_book_cover:
{
"key": "ISBN",
"value": "9780547928227",
"size": "L"
}
Exemplo de saída get_book_cover:
https://covers.openlibrary.org/b/isbn/9780547928227-L.jpg
Assim como nas fotos de autores, um livro sem capa produz uma mensagem em vez de uma URL:
No cover image available for OLID OL00000000M.
A ferramenta get_book_cover aceita os seguintes parâmetros:
key: O tipo de identificador (um de:ISBN,OCLC,LCCN,OLIDouID)value: O valor do identificadorsize: Tamanho da capa opcional (Spara pequeno,Mpara médio,Lpara grande, padrãoL)
Exemplo de entrada get_book_by_id:
{
"idType": "isbn",
"idValue": "9780547928227"
}
Exemplo de saída get_book_by_id:
{
"title": "The Hobbit",
"authors": [
"J. R. R. Tolkien"
],
"publishers": [
"Houghton Mifflin Harcourt"
],
"publish_date": "October 21, 2012",
"number_of_pages": 300,
"isbn_13": [
"9780547928227"
],
"isbn_10": [
"054792822X"
],
"oclc": [
"794607877"
],
"olid": [
"OL25380781M"
],
"open_library_edition_key": "/books/OL25380781M",
"open_library_work_key": "/works/OL45883W",
"cover_url": "https://covers.openlibrary.org/b/id/8231496-M.jpg",
"info_url": "https://openlibrary.org/books/OL25380781M/The_Hobbit",
"preview_url": "https://archive.org/details/hobbit00tolkien"
}
A ferramenta get_book_by_id aceita os seguintes parâmetros:
idType: O tipo de identificador (um de:isbn,lccn,oclc,olid)idValue: O valor do identificador
Um exemplo desta ferramenta sendo usada no Claude Desktop pode ser visto aqui:
Docker
Você pode testar este servidor MCP usando Docker. Para fazer isso, primeiro execute:
docker build -t mcp-open-library .
docker run -p 8080:8080 mcp-open-library
Você pode então testar o servidor rodando dentro do Docker via o inspector, por exemplo:
npm run inspector http://localhost:8080
Desenvolvimento
Estrutura do Projeto
src/index.ts- O servidor MCP: constrói os clientes HTTP e aciona ambos os manipuladores de solicitação a partir do registro de ferramentassrc/index.test.ts- Testes para a fiação do servidor, incluindo um snapshot dos esquemas de ferramentas publicadossrc/tools/<tool-name>/- Um diretório por ferramenta, cada um contendoindex.ts(o manipulador, seu esquema de argumentos Zod e seuToolDefinition),index.test.tse — para ferramentas com uma resposta de API não trivial — umtypes.tsdescrevendo essa forma de respostasrc/tools/registry.ts- O arrayTOOLS, a lista única do que o servidor expõesrc/tools/types.ts- Os contratosToolDefinitioneToolHandlersrc/utils/- Infraestrutura compartilhada:http.ts(os clientes Axios da API e de capas),errors.ts(análise de argumentos e resultados de erro),results.ts,schema.ts(Zod → JSON Schema),search.ts(a projeção de pesquisa compartilhada e esquemas de paginação),covers.tsscripts/- Automação de lançamento (sync-server-json.mjs,promote-changelog.mjs,assert-release-consistency.mjs) e seus testes
O contrato de entrada de uma ferramenta é declarado uma vez, como um esquema Zod. O JSON Schema que os clientes MCP
veem é gerado a partir dele por toInputSchema, então os dois não podem divergir. As descrições de campos vêm
de .describe() no esquema Zod. Observe que as restrições .refine() são descartadas na
tradução — uma regra entre campos precisa ser declarada também no description da ferramenta, ou os clientes
nunca ficarão sabendo dela.
Adicionar uma ferramenta significa criar o diretório e adicionar uma entrada ao TOOLS em
src/tools/registry.ts. src/index.test.ts deriva suas expectativas desse array, então a
única mudança de teste é um snapshot de esquema atualizado (npx vitest run -u).
Scripts Disponíveis
npm run build- Compilar o código TypeScriptnpm run watch- Observar mudanças e recompilarnpm test- Executar a suíte de testes em modo de observaçãonpm run test:precommit- Executar a suíte de testes uma vez e sairnpm run lint/npm run lint:fix- Lintsrcescriptscom ESLintnpm run format- Formatar código com Prettiernpm run inspector- Executar o MCP Inspector contra o servidor
Executando Testes
npm test inicia o Vitest em modo de observação:
npm test
Para uma única execução — o que o hook de pré-commit e o CI executam — use:
npm run test:precommit
Para executar um arquivo ou um caso de teste:
npx vitest run src/tools/get-book-by-id/index.test.ts
npx vitest run -t "should return book details when given a valid OLID"
Lançamento
Os lançamentos são automatizados. Enviar uma tag v* aciona
publish-mcp.yml, que executa as verificações, publica o pacote
no npm, registra a nova versão no Registro MCP e então cria um GitHub Release usando
a seção CHANGELOG.md dessa versão como notas. Tanto o npm quanto o registro autenticam via
GitHub OIDC, então não há segredos de publicação para gerenciar.
O version de package.json é a fonte única de verdade. npm version deriva todo o resto
dele via um hook de ciclo de vida version, então um lançamento é um único comando:
npm version patch # or minor / major
git push --follow-tags
Esse único comando incrementa package.json, reescreve server.json para corresponder, promove o cabeçalho
## [Unreleased] do changelog para a nova versão e a data de hoje, e confirma tudo sob uma única tag.
Duas coisas para saber antes de executar:
- Escreva suas entradas de changelog primeiro. Elas ficam sob um título
## [Unreleased]emCHANGELOG.mdconforme você integra o trabalho.npm versionfalha se esse título estiver ausente, em vez de publicar algo sem documentação. Se falhar, desfaça o incremento parcial comgit restore --source=HEAD --staged --worktree package.json package-lock.json server.json. - A árvore de trabalho deve estar limpa, e o hook de pré-commit (lint + suíte de testes completa) é executado dentro
de
npm version.
O CI reafirma que a tag, package.json, server.json e CHANGELOG.md estão todos de acordo antes de
qualquer coisa ser publicada — veja scripts/assert-release-consistency.mjs. A mesma verificação é executada em pull
requests que alteram esses arquivos.
npm version não é uma repetição
Assim que ele imprime a nova tag, o commit e a tag existem e o release está concluído localmente — o próximo passo é
git push --follow-tags, não executar npm version novamente. Uma segunda execução tenta a versão seguinte
e falhará no título ## [Unreleased] ausente (que a primeira execução consumiu). Essa
falha é segura por design, mas deixa package.json, package-lock.json e server.json
incrementados e não commitados. Desfaça com:
git restore --source=HEAD --staged --worktree package.json package-lock.json server.json
Se o workflow de publicação falhar
Reexecutar o job na aba Actions só ajuda em uma falha transitória. O GitHub executa o workflow
como ele existia no commit da tag, então um bug no próprio workflow ou no server.json não pode ser
corrigido por uma reexecução — a correção precisa estar no commit para o qual a tag aponta.
Nada é publicado até o workflow alcançar a etapa npm, então se ele falhou antes disso, a versão ainda está livre e você pode mover a tag:
# fix the problem on main and commit it first
VERSION="$(node -p "require('./package.json').version")"
git push origin ":v${VERSION}" # delete the remote tag e.g. git push origin :v1.0.3
git tag -d "v${VERSION}" # delete it locally
git tag -a "v${VERSION}" -m "${VERSION}" # re-tag at the fixed commit
git push origin "v${VERSION}"
O commit de correção deve deixar package.json na mesma versão, ou a verificação de consistência rejeitará
a tag. Se o npm já publicou, não reutilize a versão — esse release é imutável. Incremente para
o próximo patch; a etapa npm protegida significa que uma reexecução pula o que já foi concluído com sucesso.
Contribuindo
Contribuições são bem-vindas! Sinta-se à vontade para enviar um pull request.
