searchByTitle
Search for scientific papers by title in Crossref to find academic publications and retrieve structured metadata about scholarly works.
Instructions
Search for scientific papers by title in Crossref
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | The title to search for | |
| rows | No | Number of results to return |
Implementation Reference
- mcp-server.js:32-106 (handler)Primary handler implementation for the 'searchByTitle' tool. Fetches academic works from Crossref API using the provided title query, limits results with 'rows', formats them using formatWorkToJson helper, and returns structured JSON response or error.async ({ title, rows }) => { try { const url = `${CROSSREF_API_BASE}/works?query.title=${encodeURIComponent( title )}&rows=${rows}&select=${CROSSREF_SELECT_FIELDS}`; 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 works = data.message?.items || []; if (works.length === 0) { return { content: [ { type: "text", text: JSON.stringify( { status: "no_results", query: { title, rows }, results: [], }, null, 2 ), }, ], }; } const formattedWorks = works.map((work) => formatWorkToJson(work)); return { content: [ { type: "text", text: JSON.stringify( { status: "success", query: { title, rows }, count: formattedWorks.length, results: formattedWorks, }, null, 2 ), }, ], }; } catch (error) { return { content: [ { type: "text", text: JSON.stringify( { status: "error", message: error.message, query: { title, rows }, }, null, 2 ), }, ], }; } }
- mcp-server.js:24-31 (schema)Input schema validation using Zod for the searchByTitle tool parameters.{ title: z.string().describe("The title to search for"), rows: z .number() .optional() .default(5) .describe("Number of results to return"), },
- mcp-server.js:21-107 (registration)Registration of the 'searchByTitle' tool on the MCP server, specifying name, description, input schema, and handler function.server.tool( "searchByTitle", "Search for scientific papers by title in Crossref", { title: z.string().describe("The title to search for"), rows: z .number() .optional() .default(5) .describe("Number of results to return"), }, async ({ title, rows }) => { try { const url = `${CROSSREF_API_BASE}/works?query.title=${encodeURIComponent( title )}&rows=${rows}&select=${CROSSREF_SELECT_FIELDS}`; 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 works = data.message?.items || []; if (works.length === 0) { return { content: [ { type: "text", text: JSON.stringify( { status: "no_results", query: { title, rows }, results: [], }, null, 2 ), }, ], }; } const formattedWorks = works.map((work) => formatWorkToJson(work)); return { content: [ { type: "text", text: JSON.stringify( { status: "success", query: { title, rows }, count: formattedWorks.length, results: formattedWorks, }, null, 2 ), }, ], }; } catch (error) { return { content: [ { type: "text", text: JSON.stringify( { status: "error", message: error.message, query: { title, rows }, }, null, 2 ), }, ], }; } } );
- mcp-server-utils.js:2-29 (helper)Helper function to format Crossref work data into a clean JSON structure, used by the searchByTitle handler to process API responses.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, }; };
- mcp-server-test-handlers.js:7-81 (handler)Test or alternative handler implementation for searchByTitle in the test handlers file, nearly identical to the main handler.searchByTitle: async ({ title, rows = 5 }) => { try { const url = `https://api.crossref.org/works?query.title=${encodeURIComponent( title )}&rows=${rows}`; const response = await fetch(url, { headers: { "User-Agent": "Crossref MCP Server Test", }, }); if (!response.ok) { throw new Error(`API request failed with status ${response.status}`); } const data = await response.json(); const works = data.message?.items || []; if (works.length === 0) { return { content: [ { type: "text", text: JSON.stringify( { status: "no_results", query: { title, rows }, results: [], }, null, 2 ), }, ], }; } const formattedWorks = works.map((work) => formatWorkToJson(work)); return { content: [ { type: "text", text: JSON.stringify( { status: "success", query: { title, rows }, count: formattedWorks.length, results: formattedWorks, }, null, 2 ), }, ], }; } catch (error) { return { content: [ { type: "text", text: JSON.stringify( { status: "error", message: error.message, query: { title, rows }, }, null, 2 ), }, ], }; } },