{"_id":"@botanicastudios/crossref-mcp","_rev":"5-23ff492bb5a1a95b59a16258a0e3b720","name":"@botanicastudios/crossref-mcp","dist-tags":{"latest":"0.0.5"},"versions":{"0.0.1":{"name":"@botanicastudios/crossref-mcp","version":"0.0.1","_id":"@botanicastudios/crossref-mcp@0.0.1","maintainers":[{"name":"tnjm","email":"toby.m@rsden.com"}],"bin":{"crossref-mcp":"mcp-server.js"},"dist":{"shasum":"3adbd2eaf3c86078448b3609b75659ca699fef35","tarball":"https://registry.npmjs.org/@botanicastudios/crossref-mcp/-/crossref-mcp-0.0.1.tgz","fileCount":8,"integrity":"sha512-JPirrHhgLG7IAkM5Y2qrVjrEq0S8jYBRWMgkf/+wPJQ62CKx18S/jnmyqjIGhD9i33ltfYT+zmLKgA9+YQ99Qw==","signatures":[{"sig":"MEUCIHIhnl6kaBYkLWtoB6i3LqlxfimCH/E5R39JZxtLRFUEAiEAmyRUKW8tzqeR+XQYQkrGYyODSIyNzjAj78W6g7prr+k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34117},"main":"mcp-server.js","type":"module","gitHead":"3100c50e8df3b55282cd322180d43f9a47c75344","scripts":{"test":"vitest run","start":"node mcp-server.js"},"_npmUser":{"name":"tnjm","email":"toby.m@rsden.com"},"_npmVersion":"10.8.2","description":"MCP server for Crossref API","directories":{},"_nodeVersion":"20.18.1","dependencies":{"zod":"^3.22.4","node-fetch":"^3.3.2","@modelcontextprotocol/sdk":"^1.7.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.3.0"},"_npmOperationalInternal":{"tmp":"tmp/crossref-mcp_0.0.1_1743034481405_0.8002959583953768","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@botanicastudios/crossref-mcp","version":"0.0.2","_id":"@botanicastudios/crossref-mcp@0.0.2","maintainers":[{"name":"tnjm","email":"toby.m@rsden.com"}],"bin":{"crossref-mcp":"mcp-server.js"},"dist":{"shasum":"b0c4d1cad18a2045bf62b75ef7622af3fc629eab","tarball":"https://registry.npmjs.org/@botanicastudios/crossref-mcp/-/crossref-mcp-0.0.2.tgz","fileCount":8,"integrity":"sha512-UVvThAaXmbkLvLQB/FmkZ7kwM3O+yg2tjYssYzJFsDXXi0FIxamkpNxXkItiFIab8ZjOSCZo9I/ht9R5WrOjTw==","signatures":[{"sig":"MEYCIQC1IUqt70o4w7LLUpyYBOgUixAU2vLvf7dMxDKaWkCOmwIhAIKPZe4ySXAaLATEIUqB9fhd23DkqCKDDn2KomKCA3FE","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34100},"main":"mcp-server.js","type":"module","engines":{"node":">=18.0.0"},"gitHead":"e0e1f6f783eb121bb88900581c8f280fce9d961b","scripts":{"test":"vitest run","start":"node mcp-server.js"},"_npmUser":{"name":"tnjm","email":"toby.m@rsden.com"},"_npmVersion":"10.8.2","description":"MCP server for Crossref API","directories":{},"_nodeVersion":"20.18.1","dependencies":{"zod":"^3.22.4","@modelcontextprotocol/sdk":"^1.7.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.3.0"},"_npmOperationalInternal":{"tmp":"tmp/crossref-mcp_0.0.2_1743035469802_0.5444476112382701","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@botanicastudios/crossref-mcp","version":"0.0.3","_id":"@botanicastudios/crossref-mcp@0.0.3","maintainers":[{"name":"tnjm","email":"toby.m@rsden.com"}],"bin":{"crossref-mcp":"mcp-server.js"},"dist":{"shasum":"23901b995a28740c6037affd5aafa6157213a333","tarball":"https://registry.npmjs.org/@botanicastudios/crossref-mcp/-/crossref-mcp-0.0.3.tgz","fileCount":8,"integrity":"sha512-wwuaNFahriMb9I0K6xzubFIXFprVNfs5XCx/YRfy0q3QAx+nalDSHgaWOKyXsFcYxnrWGZn74WMrp+IkNvB+pw==","signatures":[{"sig":"MEQCIGZ9XOjAOWotVOcuPWnWFPJqVE2513EDA3XzA4FnXsubAiBWi56STBBKzdPOnIoGgY5HQLdenbQhe4FILFRkw4cYow==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":33399},"main":"mcp-server.js","type":"module","engines":{"node":">=18.0.0"},"gitHead":"c9a6f9ecb0d60ff51c6f1c785ee1ed8a7c05337c","scripts":{"test":"vitest run","start":"node mcp-server.js"},"_npmUser":{"name":"tnjm","email":"toby.m@rsden.com"},"_npmVersion":"10.8.2","description":"MCP server for Crossref API","directories":{},"_nodeVersion":"20.18.1","dependencies":{"zod":"^3.22.4","@modelcontextprotocol/sdk":"^1.7.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.3.0"},"_npmOperationalInternal":{"tmp":"tmp/crossref-mcp_0.0.3_1743036940974_0.37324949890536496","host":"s3://npm-registry-packages-npm-production"}},"0.0.4":{"name":"@botanicastudios/crossref-mcp","version":"0.0.4","_id":"@botanicastudios/crossref-mcp@0.0.4","maintainers":[{"name":"tnjm","email":"toby.m@rsden.com"}],"bin":{"crossref-mcp":"mcp-server.js"},"dist":{"shasum":"22c40db99a1e8e59a374b8e3c96e9a63785d0891","tarball":"https://registry.npmjs.org/@botanicastudios/crossref-mcp/-/crossref-mcp-0.0.4.tgz","fileCount":8,"integrity":"sha512-g30QptuvE2RaFuwR54Gig5oJloxbJAQrZtbV16CZ/bdlYm7pnkUC+4Qm8JH4dethmly/vC8xU/FRS9p37mU6AA==","signatures":[{"sig":"MEUCIHlxhc8rDMY1voisYDJp3U/na71ZOe72yBDDumHgNv0JAiEA8DwcC2fXRovU8qHN9g1g04R/5qMr6qFPoAiZtWyKARo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":33456},"main":"mcp-server.js","type":"module","engines":{"node":">=18.0.0"},"gitHead":"8ad5f8ee05d1fa95a02ddb22820bc25c8f22444d","scripts":{"test":"vitest run","start":"node mcp-server.js"},"_npmUser":{"name":"tnjm","email":"toby.m@rsden.com"},"_npmVersion":"10.8.2","description":"MCP server for Crossref API","directories":{},"_nodeVersion":"20.18.1","dependencies":{"zod":"^3.22.4","@modelcontextprotocol/sdk":"^1.7.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.3.0"},"_npmOperationalInternal":{"tmp":"tmp/crossref-mcp_0.0.4_1743038308929_0.5157031274316917","host":"s3://npm-registry-packages-npm-production"}},"0.0.5":{"name":"@botanicastudios/crossref-mcp","version":"0.0.5","description":"MCP server for Crossref API","main":"mcp-server.js","type":"module","bin":{"crossref-mcp":"mcp-server.js"},"scripts":{"start":"node mcp-server.js","test":"vitest run"},"dependencies":{"@modelcontextprotocol/sdk":"^1.7.0","zod":"^3.22.4"},"devDependencies":{"vitest":"^1.3.0"},"engines":{"node":">=18.0.0"},"_id":"@botanicastudios/crossref-mcp@0.0.5","gitHead":"12ed5e547cd3a6a6fdd84135a664a3488203d076","_nodeVersion":"20.18.1","_npmVersion":"10.8.2","dist":{"integrity":"sha512-D5zWBbed6ZPmsDXKk2nF48vLyViNtBw7DI8gZgppImJSwhTP9EvJQYPBosvBxyA8CIdr50FE6RkQURxsuN8PDA==","shasum":"6c7caf48c3192ffe93637cc26c955f5674ea620a","tarball":"https://registry.npmjs.org/@botanicastudios/crossref-mcp/-/crossref-mcp-0.0.5.tgz","fileCount":8,"unpackedSize":33423,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD2qeURt0giKgCygiMNxHDS01FJotF5lOQHIW8WNFBlfQIgQPmG6s+9X9UphWyK6nNICHWU6jUwSL3rDlD2D2NsTFY="}]},"_npmUser":{"name":"tnjm","email":"toby.m@rsden.com"},"directories":{},"maintainers":[{"name":"tnjm","email":"toby.m@rsden.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/crossref-mcp_0.0.5_1743039042341_0.4641030621750293"},"_hasShrinkwrap":false}},"time":{"created":"2025-03-27T00:14:41.300Z","modified":"2025-03-27T01:30:42.715Z","0.0.1":"2025-03-27T00:14:41.635Z","0.0.2":"2025-03-27T00:31:10.069Z","0.0.3":"2025-03-27T00:55:41.131Z","0.0.4":"2025-03-27T01:18:29.124Z","0.0.5":"2025-03-27T01:30:42.533Z"},"description":"MCP server for Crossref API","maintainers":[{"name":"tnjm","email":"toby.m@rsden.com"}],"readme":"# Crossref MCP Server\n\nA Model Context Protocol (MCP) server for interacting with the Crossref API.\n\n## Features\n\n- Search works by title\n- Search works by author\n- Get work details by DOI\n\n## Installation\n\n```\n{\n  \"mcpServers\": {\n    \"crossref\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"-y\",\n        \"@botanicastudios/crossref-mcp\"\n      ]\n    }\n  }\n}\n```\n\n## Usage\n\nThe server provides three main tools:\n\n### 1. Search by Title\n\nSearch for works in Crossref by title:\n\n```javascript\n// Example: Search for works containing \"quantum computing\" in the title\n{\n  \"title\": \"quantum computing\",\n  \"rows\": 5  // Optional, defaults to 5\n}\n```\n\n### 2. Search by Author\n\nSearch for works in Crossref by author:\n\n```javascript\n// Example: Search for works by \"Einstein\"\n{\n  \"author\": \"Einstein\",\n  \"rows\": 5  // Optional, defaults to 5\n}\n```\n\n### 3. Get Work by DOI\n\nRetrieve a specific work using its DOI:\n\n```javascript\n// Example: Get work with DOI \"10.1088/1742-6596/1398/1/012023\"\n{\n  \"doi\": \"10.1088/1742-6596/1398/1/012023\"\n}\n```\n\n## Response Format\n\nAll responses are returned as structured JSON objects with the following format:\n\n### For successful searches:\n\n```json\n{\n  \"status\": \"success\",\n  \"query\": {\n    /* the original query parameters */\n  },\n  \"count\": 5,\n  \"results\": [\n    {\n      \"title\": \"Work title\",\n      \"authors\": [\n        {\n          \"given\": \"First name\",\n          \"family\": \"Last name\",\n          \"name\": \"First name Last name\"\n        }\n      ],\n      \"published\": {\n        \"dateParts\": [2023, 1, 15],\n        \"dateString\": \"2023-1-15\"\n      },\n      \"type\": \"journal-article\",\n      \"doi\": \"10.xxxx/xxxxx\",\n      \"url\": \"https://doi.org/10.xxxx/xxxxx\",\n      \"container\": \"Journal Name\",\n      \"publisher\": \"Publisher Name\",\n      \"issue\": \"1\",\n      \"volume\": \"42\",\n      \"abstract\": \"This is the abstract of the work, if available.\"\n    }\n    // additional results...\n  ]\n}\n```\n\n### For single DOI lookup:\n\n```json\n{\n  \"status\": \"success\",\n  \"query\": { \"doi\": \"10.xxxx/xxxxx\" },\n  \"result\": {\n    // work details as shown above\n  }\n}\n```\n\n### For errors or no results:\n\n```json\n{\n  \"status\": \"error\" | \"no_results\" | \"not_found\",\n  \"message\": \"Error message\" | null,\n  \"query\": { /* the original query parameters */ }\n}\n```\n\n## Testing\n\nThe server comes with a comprehensive test suite using Vitest. Tests cover all available tools and include various scenarios including successful responses, empty results, and error handling.\n\n### Running Tests\n\n```\nnpm test\n```\n\n### Test Structure\n\nThe tests use Vitest's mocking capabilities to simulate Crossref API responses without making actual network requests. The test structure includes:\n\n1. **Mock Data**: Sample responses for title searches, author searches, and DOI lookups\n2. **Mock Handlers**: Testing versions of the handler functions in `mcp-server-test-handlers.js`\n3. **Test Cases**: Tests for all tools covering:\n   - Successful API responses\n   - Empty result sets\n   - Error handling and network failures\n\n### Extending Tests\n\nTo add more test cases:\n\n1. Add new mock data to the test file if needed\n2. Create additional test cases in the relevant describe block\n3. Use the `mockFetchResponse()` helper to simulate API responses\n\nExample:\n\n```javascript\nit(\"should handle a new edge case\", async () => {\n  // Mock the response\n  mockFetchResponse({\n    // Your sample response data\n  });\n\n  // Call the handler\n  const result = await handlers.searchByTitle({ title: \"example\" });\n\n  // Assert the expected results\n  expect(result).toMatchObject({\n    // Expected response structure\n  });\n});\n```\n","readmeFilename":"README.md"}