@cyanheads/pubmed-mcp-server 1.1.4 → 1.2.2
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/README.md +10 -12
- package/dist/mcp-server/server.d.ts +0 -7
- package/dist/mcp-server/server.js +17 -53
- package/dist/mcp-server/tools/fetchPubMedContent/logic.d.ts +6 -2
- package/dist/mcp-server/tools/fetchPubMedContent/logic.js +94 -202
- package/dist/mcp-server/tools/fetchPubMedContent/registration.js +43 -7
- package/dist/mcp-server/tools/generatePubMedChart/logic.d.ts +9 -28
- package/dist/mcp-server/tools/generatePubMedChart/logic.js +133 -192
- package/dist/mcp-server/tools/generatePubMedChart/registration.js +57 -13
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic/citationFormatter.d.ts +1 -1
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic/elinkHandler.d.ts +1 -1
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic/index.d.ts +27 -4
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic/index.js +50 -45
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic/types.d.ts +1 -1
- package/dist/mcp-server/tools/getPubMedArticleConnections/registration.d.ts +0 -24
- package/dist/mcp-server/tools/getPubMedArticleConnections/registration.js +51 -45
- package/dist/mcp-server/tools/pubmedResearchAgent/logic.d.ts +2 -4
- package/dist/mcp-server/tools/pubmedResearchAgent/logic.js +7 -41
- package/dist/mcp-server/tools/pubmedResearchAgent/registration.js +49 -8
- package/dist/mcp-server/tools/searchPubMedArticles/logic.d.ts +12 -10
- package/dist/mcp-server/tools/searchPubMedArticles/logic.js +68 -126
- package/dist/mcp-server/tools/searchPubMedArticles/registration.js +46 -6
- package/dist/mcp-server/transports/{authentication → auth/core}/authContext.d.ts +2 -2
- package/dist/mcp-server/transports/{authentication → auth/core}/authContext.js +1 -1
- package/dist/mcp-server/transports/{authentication/types.d.ts → auth/core/authTypes.d.ts} +1 -1
- package/dist/mcp-server/transports/{authentication/types.js → auth/core/authTypes.js} +1 -1
- package/dist/mcp-server/transports/{authentication → auth/core}/authUtils.d.ts +1 -1
- package/dist/mcp-server/transports/{authentication → auth/core}/authUtils.js +3 -3
- package/dist/mcp-server/transports/auth/index.d.ts +10 -0
- package/dist/mcp-server/transports/auth/index.js +9 -0
- package/dist/mcp-server/transports/{authentication/authMiddleware.d.ts → auth/strategies/jwt/jwtMiddleware.d.ts} +4 -12
- package/dist/mcp-server/transports/{authentication/authMiddleware.js → auth/strategies/jwt/jwtMiddleware.js} +36 -43
- package/dist/mcp-server/transports/{authentication → auth/strategies/oauth}/oauthMiddleware.d.ts +2 -6
- package/dist/mcp-server/transports/{authentication → auth/strategies/oauth}/oauthMiddleware.js +33 -18
- package/dist/mcp-server/transports/httpErrorHandler.d.ts +26 -0
- package/dist/mcp-server/transports/httpErrorHandler.js +73 -0
- package/dist/mcp-server/transports/httpTransport.d.ts +11 -14
- package/dist/mcp-server/transports/httpTransport.js +91 -389
- package/package.json +13 -21
- package/dist/mcp-server/resources/echoResource/echoResourceLogic.d.ts +0 -79
- package/dist/mcp-server/resources/echoResource/echoResourceLogic.js +0 -82
- package/dist/mcp-server/resources/echoResource/index.d.ts +0 -13
- package/dist/mcp-server/resources/echoResource/index.js +0 -13
- package/dist/mcp-server/resources/echoResource/registration.d.ts +0 -30
- package/dist/mcp-server/resources/echoResource/registration.js +0 -168
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic.d.ts +0 -6
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic.js +0 -6
|
@@ -3,13 +3,36 @@
|
|
|
3
3
|
* Orchestrates calls to ELink or citation formatting handlers.
|
|
4
4
|
* @module src/mcp-server/tools/getPubMedArticleConnections/logic/index
|
|
5
5
|
*/
|
|
6
|
-
import
|
|
6
|
+
import { z } from "zod";
|
|
7
7
|
import { RequestContext } from "../../../../utils/index.js";
|
|
8
|
-
import type {
|
|
8
|
+
import type { ToolOutputData } from "./types.js";
|
|
9
|
+
/**
|
|
10
|
+
* Zod schema for the input parameters of the 'get_pubmed_article_connections' tool.
|
|
11
|
+
*/
|
|
12
|
+
export declare const GetPubMedArticleConnectionsInputSchema: z.ZodObject<{
|
|
13
|
+
sourcePmid: z.ZodString;
|
|
14
|
+
relationshipType: z.ZodDefault<z.ZodEnum<["pubmed_similar_articles", "pubmed_citedin", "pubmed_references", "citation_formats"]>>;
|
|
15
|
+
maxRelatedResults: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
16
|
+
citationStyles: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodEnum<["ris", "bibtex", "apa_string", "mla_string"]>, "many">>>;
|
|
17
|
+
}, "strip", z.ZodTypeAny, {
|
|
18
|
+
sourcePmid: string;
|
|
19
|
+
relationshipType: "pubmed_similar_articles" | "pubmed_citedin" | "pubmed_references" | "citation_formats";
|
|
20
|
+
maxRelatedResults: number;
|
|
21
|
+
citationStyles: ("ris" | "bibtex" | "apa_string" | "mla_string")[];
|
|
22
|
+
}, {
|
|
23
|
+
sourcePmid: string;
|
|
24
|
+
relationshipType?: "pubmed_similar_articles" | "pubmed_citedin" | "pubmed_references" | "citation_formats" | undefined;
|
|
25
|
+
maxRelatedResults?: number | undefined;
|
|
26
|
+
citationStyles?: ("ris" | "bibtex" | "apa_string" | "mla_string")[] | undefined;
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Type alias for the validated input of the 'get_pubmed_article_connections' tool.
|
|
30
|
+
*/
|
|
31
|
+
export type GetPubMedArticleConnectionsInput = z.infer<typeof GetPubMedArticleConnectionsInputSchema>;
|
|
9
32
|
/**
|
|
10
33
|
* Main handler for the 'get_pubmed_article_connections' tool.
|
|
11
34
|
* @param {GetPubMedArticleConnectionsInput} input - Validated input parameters.
|
|
12
35
|
* @param {RequestContext} context - The request context for this tool invocation.
|
|
13
|
-
* @returns {Promise<
|
|
36
|
+
* @returns {Promise<ToolOutputData>} The result of the tool call.
|
|
14
37
|
*/
|
|
15
|
-
export declare function handleGetPubMedArticleConnections(input: GetPubMedArticleConnectionsInput, context: RequestContext): Promise<
|
|
38
|
+
export declare function handleGetPubMedArticleConnections(input: GetPubMedArticleConnectionsInput, context: RequestContext): Promise<ToolOutputData>;
|
|
@@ -3,15 +3,47 @@
|
|
|
3
3
|
* Orchestrates calls to ELink or citation formatting handlers.
|
|
4
4
|
* @module src/mcp-server/tools/getPubMedArticleConnections/logic/index
|
|
5
5
|
*/
|
|
6
|
+
import { z } from "zod";
|
|
6
7
|
import { BaseErrorCode, McpError } from "../../../../types-global/errors.js";
|
|
7
8
|
import { logger, requestContextService, sanitizeInputForLogging, } from "../../../../utils/index.js";
|
|
8
9
|
import { handleCitationFormats } from "./citationFormatter.js";
|
|
9
10
|
import { handleELinkRelationships } from "./elinkHandler.js";
|
|
11
|
+
/**
|
|
12
|
+
* Zod schema for the input parameters of the 'get_pubmed_article_connections' tool.
|
|
13
|
+
*/
|
|
14
|
+
export const GetPubMedArticleConnectionsInputSchema = z.object({
|
|
15
|
+
sourcePmid: z
|
|
16
|
+
.string()
|
|
17
|
+
.regex(/^\d+$/)
|
|
18
|
+
.describe("The PubMed Unique Identifier (PMID) of the source article for which to find connections or format citations. This PMID must be a valid number string."),
|
|
19
|
+
relationshipType: z
|
|
20
|
+
.enum([
|
|
21
|
+
"pubmed_similar_articles",
|
|
22
|
+
"pubmed_citedin",
|
|
23
|
+
"pubmed_references",
|
|
24
|
+
"citation_formats",
|
|
25
|
+
])
|
|
26
|
+
.default("pubmed_similar_articles")
|
|
27
|
+
.describe("Specifies the type of connection or action: \n- 'pubmed_similar_articles': Finds articles similar to the source PMID (uses ELink `cmd=neighbor`). \n- 'pubmed_citedin': Finds articles in PubMed that cite the source PMID (uses ELink `linkname=pubmed_pubmed_citedin`). \n- 'pubmed_references': Finds articles in PubMed referenced by the source PMID (uses ELink `linkname=pubmed_pubmed_refs`). \n- 'citation_formats': Retrieves data for the source PMID and formats it into specified citation styles (RIS, BibTeX, APA, MLA via NCBI EFetch and server-side formatting)."),
|
|
28
|
+
maxRelatedResults: z
|
|
29
|
+
.number()
|
|
30
|
+
.int()
|
|
31
|
+
.positive()
|
|
32
|
+
.max(50, "Maximum 50 related results can be requested.")
|
|
33
|
+
.optional()
|
|
34
|
+
.default(5)
|
|
35
|
+
.describe("Maximum number of related articles to retrieve when 'relationshipType' is 'pubmed_similar_articles', 'pubmed_citedin', or 'pubmed_references'. ELink results from NCBI will be truncated by the server if they exceed this number. Default is 5, maximum is 50."),
|
|
36
|
+
citationStyles: z
|
|
37
|
+
.array(z.enum(["ris", "bibtex", "apa_string", "mla_string"]))
|
|
38
|
+
.optional()
|
|
39
|
+
.default(["ris"])
|
|
40
|
+
.describe("An array of citation styles to format the source article into when 'relationshipType' is 'citation_formats'. Supported styles: 'ris', 'bibtex', 'apa_string', 'mla_string'. Default is ['ris']. Formatting is performed server-side based on data fetched via EFetch."),
|
|
41
|
+
});
|
|
10
42
|
/**
|
|
11
43
|
* Main handler for the 'get_pubmed_article_connections' tool.
|
|
12
44
|
* @param {GetPubMedArticleConnectionsInput} input - Validated input parameters.
|
|
13
45
|
* @param {RequestContext} context - The request context for this tool invocation.
|
|
14
|
-
* @returns {Promise<
|
|
46
|
+
* @returns {Promise<ToolOutputData>} The result of the tool call.
|
|
15
47
|
*/
|
|
16
48
|
export async function handleGetPubMedArticleConnections(input, context) {
|
|
17
49
|
const toolLogicContext = requestContextService.createRequestContext({
|
|
@@ -30,47 +62,23 @@ export async function handleGetPubMedArticleConnections(input, context) {
|
|
|
30
62
|
eUtilityUrl: undefined,
|
|
31
63
|
message: undefined,
|
|
32
64
|
};
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
throw new McpError(BaseErrorCode.VALIDATION_ERROR, `Unsupported relationshipType: ${input.relationshipType}`, { receivedType: input.relationshipType });
|
|
45
|
-
}
|
|
46
|
-
if (outputData.retrievedCount === 0 &&
|
|
47
|
-
!outputData.message &&
|
|
48
|
-
(input.relationshipType !== "citation_formats" ||
|
|
49
|
-
Object.keys(outputData.citations).length === 0)) {
|
|
50
|
-
outputData.message = "No results found for the given parameters.";
|
|
51
|
-
}
|
|
65
|
+
switch (input.relationshipType) {
|
|
66
|
+
case "pubmed_similar_articles":
|
|
67
|
+
case "pubmed_citedin":
|
|
68
|
+
case "pubmed_references":
|
|
69
|
+
await handleELinkRelationships(input, outputData, toolLogicContext);
|
|
70
|
+
break;
|
|
71
|
+
case "citation_formats":
|
|
72
|
+
await handleCitationFormats(input, outputData, toolLogicContext);
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
throw new McpError(BaseErrorCode.VALIDATION_ERROR, `Unsupported relationshipType: ${input.relationshipType}`, { ...toolLogicContext, receivedType: input.relationshipType });
|
|
52
76
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
: "An unexpected error occurred while processing the request.";
|
|
59
|
-
const errorDetails = error instanceof McpError
|
|
60
|
-
? error.details
|
|
61
|
-
: { originalError: error.message };
|
|
62
|
-
const errorPayload = {
|
|
63
|
-
...outputData,
|
|
64
|
-
error: {
|
|
65
|
-
code: error.code || BaseErrorCode.INTERNAL_ERROR,
|
|
66
|
-
message: outputData.message,
|
|
67
|
-
details: errorDetails,
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
const content = [
|
|
71
|
-
{ type: "text", text: JSON.stringify(errorPayload) },
|
|
72
|
-
];
|
|
73
|
-
return { content, isError: true };
|
|
77
|
+
if (outputData.retrievedCount === 0 &&
|
|
78
|
+
!outputData.message &&
|
|
79
|
+
(input.relationshipType !== "citation_formats" ||
|
|
80
|
+
Object.keys(outputData.citations).length === 0)) {
|
|
81
|
+
outputData.message = "No results found for the given parameters.";
|
|
74
82
|
}
|
|
75
83
|
logger.notice("Successfully executed get_pubmed_article_connections tool.", {
|
|
76
84
|
...toolLogicContext,
|
|
@@ -78,8 +86,5 @@ export async function handleGetPubMedArticleConnections(input, context) {
|
|
|
78
86
|
retrievedCount: outputData.retrievedCount,
|
|
79
87
|
citationsGenerated: Object.keys(outputData.citations).length,
|
|
80
88
|
});
|
|
81
|
-
|
|
82
|
-
{ type: "text", text: JSON.stringify(outputData) },
|
|
83
|
-
];
|
|
84
|
-
return { content: responseContent, isError: false };
|
|
89
|
+
return outputData;
|
|
85
90
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @fileoverview Shared type definitions for the getPubMedArticleConnections tool logic.
|
|
3
3
|
* @module src/mcp-server/tools/getPubMedArticleConnections/logic/types
|
|
4
4
|
*/
|
|
5
|
-
import type { GetPubMedArticleConnectionsInput } from "
|
|
5
|
+
import type { GetPubMedArticleConnectionsInput } from "./index.js";
|
|
6
6
|
export interface RelatedArticle {
|
|
7
7
|
pmid: string;
|
|
8
8
|
title?: string;
|
|
@@ -4,30 +4,6 @@
|
|
|
4
4
|
* @module src/mcp-server/tools/getPubMedArticleConnections/registration
|
|
5
5
|
*/
|
|
6
6
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
|
-
import { z } from "zod";
|
|
8
|
-
/**
|
|
9
|
-
* Zod schema for the input parameters of the 'get_pubmed_article_connections' tool.
|
|
10
|
-
*/
|
|
11
|
-
export declare const GetPubMedArticleConnectionsInputSchema: z.ZodObject<{
|
|
12
|
-
sourcePmid: z.ZodString;
|
|
13
|
-
relationshipType: z.ZodDefault<z.ZodEnum<["pubmed_similar_articles", "pubmed_citedin", "pubmed_references", "citation_formats"]>>;
|
|
14
|
-
maxRelatedResults: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
15
|
-
citationStyles: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodEnum<["ris", "bibtex", "apa_string", "mla_string"]>, "many">>>;
|
|
16
|
-
}, "strip", z.ZodTypeAny, {
|
|
17
|
-
sourcePmid: string;
|
|
18
|
-
relationshipType: "pubmed_similar_articles" | "pubmed_citedin" | "pubmed_references" | "citation_formats";
|
|
19
|
-
maxRelatedResults: number;
|
|
20
|
-
citationStyles: ("ris" | "bibtex" | "apa_string" | "mla_string")[];
|
|
21
|
-
}, {
|
|
22
|
-
sourcePmid: string;
|
|
23
|
-
relationshipType?: "pubmed_similar_articles" | "pubmed_citedin" | "pubmed_references" | "citation_formats" | undefined;
|
|
24
|
-
maxRelatedResults?: number | undefined;
|
|
25
|
-
citationStyles?: ("ris" | "bibtex" | "apa_string" | "mla_string")[] | undefined;
|
|
26
|
-
}>;
|
|
27
|
-
/**
|
|
28
|
-
* Type alias for the validated input of the 'get_pubmed_article_connections' tool.
|
|
29
|
-
*/
|
|
30
|
-
export type GetPubMedArticleConnectionsInput = z.infer<typeof GetPubMedArticleConnectionsInputSchema>;
|
|
31
7
|
/**
|
|
32
8
|
* Registers the 'get_pubmed_article_connections' tool with the given MCP server instance.
|
|
33
9
|
* @param {McpServer} server - The MCP server instance.
|
|
@@ -3,63 +3,69 @@
|
|
|
3
3
|
* This tool finds articles related to a source PMID or retrieves citation formats.
|
|
4
4
|
* @module src/mcp-server/tools/getPubMedArticleConnections/registration
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
import { BaseErrorCode } from "../../../types-global/errors.js";
|
|
6
|
+
import { BaseErrorCode, McpError } from "../../../types-global/errors.js";
|
|
8
7
|
import { ErrorHandler, logger, requestContextService, } from "../../../utils/index.js";
|
|
9
|
-
import { handleGetPubMedArticleConnections } from "./logic.js";
|
|
10
|
-
/**
|
|
11
|
-
* Zod schema for the input parameters of the 'get_pubmed_article_connections' tool.
|
|
12
|
-
*/
|
|
13
|
-
export const GetPubMedArticleConnectionsInputSchema = z.object({
|
|
14
|
-
sourcePmid: z
|
|
15
|
-
.string()
|
|
16
|
-
.regex(/^\d+$/)
|
|
17
|
-
.describe("The PubMed Unique Identifier (PMID) of the source article for which to find connections or format citations. This PMID must be a valid number string."),
|
|
18
|
-
relationshipType: z
|
|
19
|
-
.enum([
|
|
20
|
-
"pubmed_similar_articles",
|
|
21
|
-
"pubmed_citedin",
|
|
22
|
-
"pubmed_references",
|
|
23
|
-
"citation_formats",
|
|
24
|
-
])
|
|
25
|
-
.default("pubmed_similar_articles")
|
|
26
|
-
.describe("Specifies the type of connection or action: \n- 'pubmed_similar_articles': Finds articles similar to the source PMID (uses ELink `cmd=neighbor`). \n- 'pubmed_citedin': Finds articles in PubMed that cite the source PMID (uses ELink `linkname=pubmed_pubmed_citedin`). \n- 'pubmed_references': Finds articles in PubMed referenced by the source PMID (uses ELink `linkname=pubmed_pubmed_refs`). \n- 'citation_formats': Retrieves data for the source PMID and formats it into specified citation styles (RIS, BibTeX, APA, MLA via NCBI EFetch and server-side formatting)."),
|
|
27
|
-
maxRelatedResults: z
|
|
28
|
-
.number()
|
|
29
|
-
.int()
|
|
30
|
-
.positive()
|
|
31
|
-
.max(50, "Maximum 50 related results can be requested.")
|
|
32
|
-
.optional()
|
|
33
|
-
.default(5)
|
|
34
|
-
.describe("Maximum number of related articles to retrieve when 'relationshipType' is 'pubmed_similar_articles', 'pubmed_citedin', or 'pubmed_references'. ELink results from NCBI will be truncated by the server if they exceed this number. Default is 5, maximum is 50."),
|
|
35
|
-
citationStyles: z
|
|
36
|
-
.array(z.enum(["ris", "bibtex", "apa_string", "mla_string"]))
|
|
37
|
-
.optional()
|
|
38
|
-
.default(["ris"])
|
|
39
|
-
.describe("An array of citation styles to format the source article into when 'relationshipType' is 'citation_formats'. Supported styles: 'ris', 'bibtex', 'apa_string', 'mla_string'. Default is ['ris']. Formatting is performed server-side based on data fetched via EFetch."),
|
|
40
|
-
});
|
|
8
|
+
import { GetPubMedArticleConnectionsInputSchema, handleGetPubMedArticleConnections, } from "./logic/index.js";
|
|
41
9
|
/**
|
|
42
10
|
* Registers the 'get_pubmed_article_connections' tool with the given MCP server instance.
|
|
43
11
|
* @param {McpServer} server - The MCP server instance.
|
|
44
12
|
*/
|
|
45
13
|
export async function registerGetPubMedArticleConnectionsTool(server) {
|
|
46
14
|
const operation = "registerGetPubMedArticleConnectionsTool";
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
});
|
|
50
|
-
await ErrorHandler.tryCatch(() => {
|
|
51
|
-
server.tool(
|
|
52
|
-
const
|
|
53
|
-
parentRequestId:
|
|
15
|
+
const toolName = "get_pubmed_article_connections";
|
|
16
|
+
const toolDescription = "Finds articles related to a source PubMed ID (PMID) or retrieves formatted citations for it. Supports finding similar articles, articles that cite the source, articles referenced by the source (via NCBI ELink), or fetching data to generate citations in various styles (RIS, BibTeX, APA, MLA via NCBI EFetch and server-side formatting). Returns a JSON object detailing the connections or formatted citations.";
|
|
17
|
+
const context = requestContextService.createRequestContext({ operation });
|
|
18
|
+
await ErrorHandler.tryCatch(async () => {
|
|
19
|
+
server.tool(toolName, toolDescription, GetPubMedArticleConnectionsInputSchema.shape, async (input, mcpProvidedContext) => {
|
|
20
|
+
const richContext = requestContextService.createRequestContext({
|
|
21
|
+
parentRequestId: context.requestId,
|
|
54
22
|
operation: "getPubMedArticleConnectionsToolHandler",
|
|
55
|
-
mcpToolContext:
|
|
23
|
+
mcpToolContext: mcpProvidedContext,
|
|
24
|
+
input,
|
|
56
25
|
});
|
|
57
|
-
|
|
26
|
+
try {
|
|
27
|
+
const result = await handleGetPubMedArticleConnections(input, richContext);
|
|
28
|
+
return {
|
|
29
|
+
content: [
|
|
30
|
+
{ type: "text", text: JSON.stringify(result, null, 2) },
|
|
31
|
+
],
|
|
32
|
+
isError: false,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
const handledError = ErrorHandler.handleError(error, {
|
|
37
|
+
operation: "getPubMedArticleConnectionsToolHandler",
|
|
38
|
+
context: richContext,
|
|
39
|
+
input,
|
|
40
|
+
rethrow: false,
|
|
41
|
+
});
|
|
42
|
+
const mcpError = handledError instanceof McpError
|
|
43
|
+
? handledError
|
|
44
|
+
: new McpError(BaseErrorCode.INTERNAL_ERROR, "An unexpected error occurred while getting PubMed article connections.", {
|
|
45
|
+
originalErrorName: handledError.name,
|
|
46
|
+
originalErrorMessage: handledError.message,
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
content: [
|
|
50
|
+
{
|
|
51
|
+
type: "text",
|
|
52
|
+
text: JSON.stringify({
|
|
53
|
+
error: {
|
|
54
|
+
code: mcpError.code,
|
|
55
|
+
message: mcpError.message,
|
|
56
|
+
details: mcpError.details,
|
|
57
|
+
},
|
|
58
|
+
}),
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
isError: true,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
58
64
|
});
|
|
59
|
-
logger.notice(
|
|
65
|
+
logger.notice(`Tool '${toolName}' registered.`, context);
|
|
60
66
|
}, {
|
|
61
67
|
operation,
|
|
62
|
-
context
|
|
68
|
+
context,
|
|
63
69
|
errorCode: BaseErrorCode.INITIALIZATION_FAILED,
|
|
64
70
|
critical: true,
|
|
65
71
|
});
|
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
* designed to be completed by a calling LLM (the MCP Client).
|
|
5
5
|
* @module pubmedResearchAgent/logic
|
|
6
6
|
*/
|
|
7
|
-
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
8
7
|
import { RequestContext } from "../../../utils/index.js";
|
|
9
|
-
import { PubMedResearchAgentInput,
|
|
10
|
-
export
|
|
11
|
-
export declare function pubmedResearchAgentLogic(input: PubMedResearchAgentInput, parentRequestContext: RequestContext): Promise<CallToolResult>;
|
|
8
|
+
import { PubMedResearchAgentInput, PubMedResearchPlanGeneratedOutput } from "./logic/index.js";
|
|
9
|
+
export declare function pubmedResearchAgentLogic(input: PubMedResearchAgentInput, parentRequestContext: RequestContext): Promise<PubMedResearchPlanGeneratedOutput>;
|
|
@@ -4,10 +4,8 @@
|
|
|
4
4
|
* designed to be completed by a calling LLM (the MCP Client).
|
|
5
5
|
* @module pubmedResearchAgent/logic
|
|
6
6
|
*/
|
|
7
|
-
import { BaseErrorCode, McpError } from "../../../types-global/errors.js";
|
|
8
7
|
import { logger, requestContextService, sanitizeInputForLogging, } from "../../../utils/index.js";
|
|
9
|
-
import { generateFullResearchPlanOutline,
|
|
10
|
-
export { PubMedResearchAgentInputSchema };
|
|
8
|
+
import { generateFullResearchPlanOutline, } from "./logic/index.js";
|
|
11
9
|
export async function pubmedResearchAgentLogic(input, parentRequestContext) {
|
|
12
10
|
const operationContext = requestContextService.createRequestContext({
|
|
13
11
|
parentRequestId: parentRequestContext.requestId,
|
|
@@ -15,42 +13,10 @@ export async function pubmedResearchAgentLogic(input, parentRequestContext) {
|
|
|
15
13
|
input: sanitizeInputForLogging(input),
|
|
16
14
|
});
|
|
17
15
|
logger.info(`Executing 'pubmed_research_agent' to generate research plan outline. Keywords: ${input.research_keywords.join(", ")}`, operationContext);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
content: [
|
|
26
|
-
{ type: "text", text: JSON.stringify(researchPlanOutline, null, 2) },
|
|
27
|
-
],
|
|
28
|
-
isError: false,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
catch (error) {
|
|
32
|
-
logger.error("Execution failed for 'pubmed_research_agent'", error, operationContext);
|
|
33
|
-
const mcpError = error instanceof McpError
|
|
34
|
-
? error
|
|
35
|
-
: new McpError(BaseErrorCode.INTERNAL_ERROR, `'pubmed_research_agent' tool failed during plan outline generation: ${error.message || "Internal server error."}`, {
|
|
36
|
-
originalErrorName: error.name,
|
|
37
|
-
requestId: operationContext.requestId,
|
|
38
|
-
inputKeywords: input.research_keywords,
|
|
39
|
-
});
|
|
40
|
-
return {
|
|
41
|
-
content: [
|
|
42
|
-
{
|
|
43
|
-
type: "text",
|
|
44
|
-
text: JSON.stringify({
|
|
45
|
-
error: {
|
|
46
|
-
code: mcpError.code,
|
|
47
|
-
message: mcpError.message,
|
|
48
|
-
details: mcpError.details,
|
|
49
|
-
},
|
|
50
|
-
}),
|
|
51
|
-
},
|
|
52
|
-
],
|
|
53
|
-
isError: true,
|
|
54
|
-
};
|
|
55
|
-
}
|
|
16
|
+
const researchPlanOutline = generateFullResearchPlanOutline(input, operationContext);
|
|
17
|
+
logger.notice("Successfully generated research plan outline.", {
|
|
18
|
+
...operationContext,
|
|
19
|
+
projectTitle: input.project_title_suggestion,
|
|
20
|
+
});
|
|
21
|
+
return researchPlanOutline;
|
|
56
22
|
}
|
|
@@ -2,26 +2,67 @@
|
|
|
2
2
|
* @fileoverview Registration for the pubmed_research_agent tool.
|
|
3
3
|
* @module pubmedResearchAgent/registration
|
|
4
4
|
*/
|
|
5
|
-
import { BaseErrorCode } from "../../../types-global/errors.js";
|
|
5
|
+
import { BaseErrorCode, McpError } from "../../../types-global/errors.js";
|
|
6
6
|
import { ErrorHandler, logger, requestContextService, } from "../../../utils/index.js";
|
|
7
|
-
import {
|
|
7
|
+
import { pubmedResearchAgentLogic } from "./logic.js";
|
|
8
|
+
import { PubMedResearchAgentInputSchema, } from "./logic/index.js";
|
|
8
9
|
/**
|
|
9
10
|
* Registers the pubmed_research_agent tool with the MCP server.
|
|
10
11
|
* @param server - The McpServer instance.
|
|
11
12
|
*/
|
|
12
13
|
export async function registerPubMedResearchAgentTool(server) {
|
|
13
14
|
const operation = "registerPubMedResearchAgentTool";
|
|
15
|
+
const toolName = "pubmed_research_agent";
|
|
16
|
+
const toolDescription = "Generates a standardized JSON research plan outline from component details you provide. It accepts granular inputs for all research phases (conception, data collection, analysis, dissemination, cross-cutting concerns). If `include_detailed_prompts_for_agent` is true, the output plan will embed instructive prompts and detailed guidance notes to aid the research agent. The tool's primary function is to organize and structure your rough ideas into a formal, machine-readable plan. This plan is intended for further processing; as the research agent, you should then utilize your full suite of tools (e.g., file manipulation, `get_pubmed_article_connections` for literature/data search via PMID) to execute the outlined research, tailored to the user's request.";
|
|
14
17
|
const context = requestContextService.createRequestContext({ operation });
|
|
15
|
-
await ErrorHandler.tryCatch(() => {
|
|
16
|
-
server.tool(
|
|
17
|
-
const
|
|
18
|
+
await ErrorHandler.tryCatch(async () => {
|
|
19
|
+
server.tool(toolName, toolDescription, PubMedResearchAgentInputSchema.shape, async (input, mcpProvidedContext) => {
|
|
20
|
+
const richContext = requestContextService.createRequestContext({
|
|
18
21
|
parentRequestId: context.requestId,
|
|
19
|
-
operation: "
|
|
22
|
+
operation: "pubmedResearchAgentToolHandler",
|
|
20
23
|
mcpToolContext: mcpProvidedContext,
|
|
24
|
+
input,
|
|
21
25
|
});
|
|
22
|
-
|
|
26
|
+
try {
|
|
27
|
+
const result = await pubmedResearchAgentLogic(input, richContext);
|
|
28
|
+
return {
|
|
29
|
+
content: [
|
|
30
|
+
{ type: "text", text: JSON.stringify(result, null, 2) },
|
|
31
|
+
],
|
|
32
|
+
isError: false,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
const handledError = ErrorHandler.handleError(error, {
|
|
37
|
+
operation: "pubmedResearchAgentToolHandler",
|
|
38
|
+
context: richContext,
|
|
39
|
+
input,
|
|
40
|
+
rethrow: false,
|
|
41
|
+
});
|
|
42
|
+
const mcpError = handledError instanceof McpError
|
|
43
|
+
? handledError
|
|
44
|
+
: new McpError(BaseErrorCode.INTERNAL_ERROR, "An unexpected error occurred while generating the research plan.", {
|
|
45
|
+
originalErrorName: handledError.name,
|
|
46
|
+
originalErrorMessage: handledError.message,
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
content: [
|
|
50
|
+
{
|
|
51
|
+
type: "text",
|
|
52
|
+
text: JSON.stringify({
|
|
53
|
+
error: {
|
|
54
|
+
code: mcpError.code,
|
|
55
|
+
message: mcpError.message,
|
|
56
|
+
details: mcpError.details,
|
|
57
|
+
},
|
|
58
|
+
}),
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
isError: true,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
23
64
|
});
|
|
24
|
-
logger.notice(`Tool '
|
|
65
|
+
logger.notice(`Tool '${toolName}' registered.`, context);
|
|
25
66
|
}, {
|
|
26
67
|
operation,
|
|
27
68
|
context,
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* the NcbiService, and formatting the results.
|
|
5
5
|
* @module src/mcp-server/tools/searchPubMedArticles/logic
|
|
6
6
|
*/
|
|
7
|
-
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
8
7
|
import { z } from "zod";
|
|
8
|
+
import { ParsedBriefSummary } from "../../../types-global/pubmedXml.js";
|
|
9
9
|
import { RequestContext } from "../../../utils/index.js";
|
|
10
10
|
export declare const SearchPubMedArticlesInputSchema: z.ZodObject<{
|
|
11
11
|
queryTerm: z.ZodString;
|
|
@@ -50,12 +50,14 @@ export declare const SearchPubMedArticlesInputSchema: z.ZodObject<{
|
|
|
50
50
|
fetchBriefSummaries?: number | undefined;
|
|
51
51
|
}>;
|
|
52
52
|
export type SearchPubMedArticlesInput = z.infer<typeof SearchPubMedArticlesInputSchema>;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
export type SearchPubMedArticlesOutput = {
|
|
54
|
+
searchParameters: SearchPubMedArticlesInput;
|
|
55
|
+
effectiveESearchTerm: string;
|
|
56
|
+
totalFound: number;
|
|
57
|
+
retrievedPmidCount: number;
|
|
58
|
+
pmids: string[];
|
|
59
|
+
briefSummaries: ParsedBriefSummary[];
|
|
60
|
+
eSearchUrl: string;
|
|
61
|
+
eSummaryUrl?: string;
|
|
62
|
+
};
|
|
63
|
+
export declare function searchPubMedArticlesLogic(input: SearchPubMedArticlesInput, parentRequestContext: RequestContext): Promise<SearchPubMedArticlesOutput>;
|