mcp-server-opencitations 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +39 -1
- package/dist/lib.js +39 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
6
6
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
// Import API client functions from lib.ts
|
|
9
|
-
import { getCitationCount, getCitations, getReferenceCount, getReferences, formatDoi, formatCitationsAsText, } from "./lib.js";
|
|
9
|
+
import { getCitation, getCitationCount, getCitations, getReferenceCount, getReferences, getVenueCitationCount, formatDoi, formatIssn, formatCitationAsText, formatCitationsAsText, } from "./lib.js";
|
|
10
10
|
// -----------------------------------------------------------------------------
|
|
11
11
|
// CONFIGURATION
|
|
12
12
|
// -----------------------------------------------------------------------------
|
|
@@ -103,6 +103,44 @@ server.registerTool("get_references", {
|
|
|
103
103
|
content: [{ type: "text", text }],
|
|
104
104
|
};
|
|
105
105
|
});
|
|
106
|
+
// Tool: Get single citation by OCI
|
|
107
|
+
server.registerTool("get_citation", {
|
|
108
|
+
description: "Get metadata for a specific citation using its Open Citation Identifier (OCI). " +
|
|
109
|
+
"An OCI is a unique identifier for a citation link between two papers. " +
|
|
110
|
+
"Example OCI: '06101801781-06180334099'.",
|
|
111
|
+
inputSchema: {
|
|
112
|
+
oci: z.string().describe("Open Citation Identifier (e.g., '06101801781-06180334099')"),
|
|
113
|
+
},
|
|
114
|
+
}, async (args) => {
|
|
115
|
+
// Remove 'oci:' prefix if present
|
|
116
|
+
const oci = args.oci.replace(/^oci:/, "");
|
|
117
|
+
const citation = await getCitation(oci, ACCESS_TOKEN);
|
|
118
|
+
if (!citation) {
|
|
119
|
+
return {
|
|
120
|
+
content: [{ type: "text", text: `No citation found for OCI: ${args.oci}` }],
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
content: [{ type: "text", text: formatCitationAsText(citation) }],
|
|
125
|
+
};
|
|
126
|
+
});
|
|
127
|
+
// Tool: Get venue citation count
|
|
128
|
+
server.registerTool("venue_citation_count", {
|
|
129
|
+
description: "Get the total number of citations for all papers published in a journal/venue. " +
|
|
130
|
+
"Provide an ISSN like '0138-9130' or 'issn:0138-9130'.",
|
|
131
|
+
inputSchema: {
|
|
132
|
+
issn: z.string().describe("ISSN of the journal (e.g., '0138-9130')"),
|
|
133
|
+
},
|
|
134
|
+
}, async (args) => {
|
|
135
|
+
const id = formatIssn(args.issn);
|
|
136
|
+
const count = await getVenueCitationCount(id, ACCESS_TOKEN);
|
|
137
|
+
return {
|
|
138
|
+
content: [{
|
|
139
|
+
type: "text",
|
|
140
|
+
text: `Total citations for venue ${args.issn}: ${count}`,
|
|
141
|
+
}],
|
|
142
|
+
};
|
|
143
|
+
});
|
|
106
144
|
// -----------------------------------------------------------------------------
|
|
107
145
|
// START SERVER
|
|
108
146
|
// -----------------------------------------------------------------------------
|
package/dist/lib.js
CHANGED
|
@@ -89,6 +89,20 @@ export async function getCitation(oci, accessToken) {
|
|
|
89
89
|
const data = await apiRequest(`/citation/${oci}`, accessToken);
|
|
90
90
|
return data.length > 0 ? data[0] : null;
|
|
91
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Get the total citation count for all papers in a venue (journal)
|
|
94
|
+
*
|
|
95
|
+
* @param issn - ISSN of the venue (e.g., "issn:0138-9130")
|
|
96
|
+
* @param accessToken - Optional access token
|
|
97
|
+
* @returns Total citation count for the venue
|
|
98
|
+
*/
|
|
99
|
+
export async function getVenueCitationCount(issn, accessToken) {
|
|
100
|
+
const data = await apiRequest(`/venue-citation-count/${issn}`, accessToken);
|
|
101
|
+
if (data.length === 0) {
|
|
102
|
+
return 0;
|
|
103
|
+
}
|
|
104
|
+
return parseInt(data[0].count, 10);
|
|
105
|
+
}
|
|
92
106
|
// -----------------------------------------------------------------------------
|
|
93
107
|
// Utility Functions
|
|
94
108
|
// -----------------------------------------------------------------------------
|
|
@@ -105,6 +119,31 @@ export function formatDoi(doi) {
|
|
|
105
119
|
}
|
|
106
120
|
return doi;
|
|
107
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Format an ISSN into the API's expected format
|
|
124
|
+
*/
|
|
125
|
+
export function formatIssn(issn) {
|
|
126
|
+
// Add "issn:" prefix if not present
|
|
127
|
+
if (!issn.startsWith("issn:")) {
|
|
128
|
+
return `issn:${issn}`;
|
|
129
|
+
}
|
|
130
|
+
return issn;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Format a single Citation into a readable string
|
|
134
|
+
*/
|
|
135
|
+
export function formatCitationAsText(citation) {
|
|
136
|
+
const lines = [
|
|
137
|
+
`OCI: ${citation.oci}`,
|
|
138
|
+
`Citing: ${citation.citing}`,
|
|
139
|
+
`Cited: ${citation.cited}`,
|
|
140
|
+
`Date: ${citation.creation || "N/A"}`,
|
|
141
|
+
`Timespan: ${citation.timespan || "N/A"}`,
|
|
142
|
+
`Journal self-citation: ${citation.journal_sc || "no"}`,
|
|
143
|
+
`Author self-citation: ${citation.author_sc || "no"}`,
|
|
144
|
+
];
|
|
145
|
+
return lines.join("\n");
|
|
146
|
+
}
|
|
108
147
|
/**
|
|
109
148
|
* Format citations into a readable string
|
|
110
149
|
*/
|