Skip to main content
Glama

getWorkByDOI

Retrieve scientific papers using their DOI identifiers to access structured metadata for academic research and citation purposes.

Instructions

Retrieve a specific scientific paper by its DOI

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
doiYesThe DOI to look up

Implementation Reference

  • mcp-server.js:199-281 (registration)
    MCP server.tool() registration for 'getWorkByDOI', including description, input schema, and full inline handler implementation that fetches Crossref API and returns formatted JSON.
    server.tool( "getWorkByDOI", "Retrieve a specific scientific paper by its DOI", { doi: z.string().describe("The DOI to look up"), }, async ({ doi }) => { try { // Remove any URL prefix if present const cleanDoi = doi.replace(/^https?:\/\/doi.org\//, ""); // Use the direct Crossref API endpoint const url = `${CROSSREF_API_BASE}/works/${cleanDoi}`; const response = await fetch(url, { headers: { "User-Agent": "Crossref MCP Server", }, }); if (!response.ok) { throw new Error(`API request failed with status ${response.status}`); } const data = await response.json(); const work = data.message; if (!work) { return { content: [ { type: "text", text: JSON.stringify( { status: "not_found", query: { doi }, message: `No work found with DOI: ${doi}`, }, null, 2 ), }, ], }; } const formattedWork = formatWorkToJson(work); return { content: [ { type: "text", text: JSON.stringify( { status: "success", query: { doi }, result: formattedWork, }, null, 2 ), }, ], }; } catch (error) { return { content: [ { type: "text", text: JSON.stringify( { status: "error", message: error.message, query: { doi }, }, null, 2 ), }, ], }; } } );
  • Input schema definition using Zod for the 'doi' parameter.
    { doi: z.string().describe("The DOI to look up"), },
  • The core handler logic for getWorkByDOI: cleans DOI, fetches data from Crossref API, handles not found and errors, formats result with helper, returns standardized MCP text content with JSON.
    async ({ doi }) => { try { // Remove any URL prefix if present const cleanDoi = doi.replace(/^https?:\/\/doi.org\//, ""); // Use the direct Crossref API endpoint const url = `${CROSSREF_API_BASE}/works/${cleanDoi}`; const response = await fetch(url, { headers: { "User-Agent": "Crossref MCP Server", }, }); if (!response.ok) { throw new Error(`API request failed with status ${response.status}`); } const data = await response.json(); const work = data.message; if (!work) { return { content: [ { type: "text", text: JSON.stringify( { status: "not_found", query: { doi }, message: `No work found with DOI: ${doi}`, }, null, 2 ), }, ], }; } const formattedWork = formatWorkToJson(work); return { content: [ { type: "text", text: JSON.stringify( { status: "success", query: { doi }, result: formattedWork, }, null, 2 ), }, ], }; } catch (error) { return { content: [ { type: "text", text: JSON.stringify( { status: "error", message: error.message, query: { doi }, }, null, 2 ), }, ], }; } }
  • Supporting utility function formatWorkToJson that transforms raw Crossref work data into a clean, structured JSON object with fields like title, authors, published dates, DOI, etc.
    export const formatWorkToJson = (work) => { if (!work) return { error: "No data available" }; return { title: work.title?.[0] || null, authors: work.author ? work.author.map((a) => ({ given: a.given || null, family: a.family || null, name: `${a.given || ""} ${a.family || ""}`.trim(), })) : [], published: work.published ? { dateParts: work.published["date-parts"]?.[0] || [], dateString: work.published["date-parts"]?.[0]?.join("-") || null, } : null, type: work.type || null, doi: work.DOI || null, url: work.URL || null, container: work["container-title"]?.[0] || null, publisher: work.publisher || null, issue: work.issue || null, volume: work.volume || null, abstract: work.abstract || null, }; };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/botanicastudios/crossref-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server