format_citation
Format a DOI into a citation string. Select from APA, MLA, Chicago, Harvard, IEEE, Vancouver, BibTeX, or CSL JSON style and specify a locale.
Instructions
Format a DOI as a citation string. Supports APA, MLA, Chicago, Harvard, IEEE, Vancouver, BibTeX, and CSL JSON styles.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| doi | Yes | ||
| style | No | apa | |
| locale | No | en-US |
Implementation Reference
- src/tools/format-citation.ts:21-49 (handler)The registerTool function that registers and implements the 'format_citation' tool. It takes a DOI and optional style/locale, normalizes the DOI, builds an appropriate Accept header, fetches the citation from doi.org, and returns the formatted citation as JSON.
export function registerTool(server: McpServer): void { server.tool( "format_citation", "Format a DOI as a citation string. Supports APA, MLA, Chicago, Harvard, IEEE, Vancouver, BibTeX, and CSL JSON styles.", FormatCitationSchema.shape, async (params) => { const input = FormatCitationSchema.parse(params); const doi = normalizeDoi(input.doi); const accept = getAcceptHeader(input.style, input.locale); const url = `https://doi.org/${doi}`; try { const citation = await dataciteClient.getText(url, accept); return { content: [ { type: "text" as const, text: JSON.stringify({ citation: citation.trim(), style: input.style, doi }, null, 2), }, ], }; } catch (err) { const msg = err instanceof Error ? err.message : String(err); throw apiError(msg); } } ); } - src/tools/format-citation.ts:7-13 (schema)Zod schema defining the input for format_citation: doi (required string), style (enum with default 'apa'), and locale (string, default 'en-US').
const FormatCitationSchema = z.object({ doi: z.string().min(1), style: z .enum(["apa", "mla", "chicago", "harvard", "ieee", "vancouver", "bibtex", "citeproc-json"]) .default("apa"), locale: z.string().default("en-US"), }); - src/tools/index.ts:4-15 (registration)Import and registration of format_citation in the central tool registration index.
import { registerTool as registerFormatCitation } from "./format-citation.js"; import { registerTool as registerGetDoiMetrics } from "./get-doi-metrics.js"; import { registerTool as registerGetRelatedWorks } from "./get-related-works.js"; import { registerTool as registerSearchByPerson } from "./search-by-person.js"; import { registerTool as registerListRepositories } from "./list-repositories.js"; import { registerTool as registerGetRepository } from "./get-repository.js"; import { registerTool as registerGetDoiSchemaXml } from "./get-doi-schema-xml.js"; export function registerAllTools(server: McpServer): void { registerSearchDois(server); registerGetDoi(server); registerFormatCitation(server); - src/tools/format-citation.ts:15-19 (helper)Helper function getAcceptHeader that maps style names to HTTP Accept headers (e.g., bibtex -> application/x-bibtex, citeproc-json -> application/vnd.citationstyles.csl+json, or text/x-bibliography with style/locale parameters).
function getAcceptHeader(style: string, locale: string): string { if (style === "bibtex") return "application/x-bibtex"; if (style === "citeproc-json") return "application/vnd.citationstyles.csl+json"; return `text/x-bibliography; style=${style}; locale=${locale}`; } - src/datacite/doi-normalizer.ts:11-34 (helper)Helper function normalizeDoi that strips URL/DOI prefixes and lowercases the prefix portion.
export function normalizeDoi(input: string): string { let doi = input.trim(); // Strip URL prefixes if (doi.toLowerCase().startsWith("https://doi.org/")) { doi = doi.slice("https://doi.org/".length); } else if (doi.toLowerCase().startsWith("http://doi.org/")) { doi = doi.slice("http://doi.org/".length); } else if (doi.toLowerCase().startsWith("doi:")) { doi = doi.slice("doi:".length); } // Lowercase only the prefix (registrant prefix, e.g. "10.5061") const slashIndex = doi.indexOf("/"); if (slashIndex !== -1) { const prefix = doi.slice(0, slashIndex).toLowerCase(); const suffix = doi.slice(slashIndex + 1); doi = `${prefix}/${suffix}`; } else { doi = doi.toLowerCase(); } return doi; }