Skip to main content
Glama
botanicastudios

Crossref MCP Server

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,
      };
    };
Install Server

Other Tools

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