@cyanheads/pubchem-mcp-server 1.0.1 → 1.0.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/dist/mcp-server/server.js +2 -2
- package/dist/mcp-server/tools/fetchCompoundProperties/logic.js +19 -9
- package/dist/mcp-server/tools/fetchSubstanceDetails/registration.js +1 -1
- package/dist/mcp-server/tools/getSummary/index.d.ts +5 -0
- package/dist/mcp-server/tools/getSummary/index.js +5 -0
- package/dist/mcp-server/tools/getSummary/logic.d.ts +184 -0
- package/dist/mcp-server/tools/getSummary/logic.js +230 -0
- package/dist/mcp-server/tools/getSummary/registration.d.ts +12 -0
- package/dist/mcp-server/tools/getSummary/registration.js +50 -0
- package/package.json +1 -1
- package/dist/mcp-server/tools/fetchAssaySummary/index.d.ts +0 -7
- package/dist/mcp-server/tools/fetchAssaySummary/index.js +0 -7
- package/dist/mcp-server/tools/fetchAssaySummary/logic.d.ts +0 -71
- package/dist/mcp-server/tools/fetchAssaySummary/logic.js +0 -96
- package/dist/mcp-server/tools/fetchAssaySummary/registration.d.ts +0 -12
- package/dist/mcp-server/tools/fetchAssaySummary/registration.js +0 -68
|
@@ -24,7 +24,7 @@ import { registerPubchemSearchCompoundsByStructureTool } from "./tools/searchCom
|
|
|
24
24
|
import { registerPubchemSearchCompoundsBySimilarityTool } from "./tools/searchCompoundsBySimilarity/index.js";
|
|
25
25
|
import { registerPubchemSearchCompoundsByFormulaTool } from "./tools/searchCompoundsByFormula/index.js";
|
|
26
26
|
import { registerPubchemFetchSubstanceDetailsTool } from "./tools/fetchSubstanceDetails/index.js";
|
|
27
|
-
import {
|
|
27
|
+
import { registerPubchemGetSummaryTool } from "./tools/getSummary/index.js";
|
|
28
28
|
import { registerPubchemSearchAssaysByTargetTool } from "./tools/searchAssaysByTarget/index.js";
|
|
29
29
|
import { registerPubchemFetchCompoundXrefsTool } from "./tools/fetchCompoundXrefs/index.js";
|
|
30
30
|
import { startHttpTransport } from "./transports/httpTransport.js";
|
|
@@ -62,7 +62,7 @@ async function createMcpServerInstance() {
|
|
|
62
62
|
await registerPubchemSearchCompoundsBySimilarityTool(server);
|
|
63
63
|
await registerPubchemSearchCompoundsByFormulaTool(server);
|
|
64
64
|
await registerPubchemFetchSubstanceDetailsTool(server);
|
|
65
|
-
await
|
|
65
|
+
await registerPubchemGetSummaryTool(server);
|
|
66
66
|
await registerPubchemSearchAssaysByTargetTool(server);
|
|
67
67
|
await registerPubchemFetchCompoundXrefsTool(server);
|
|
68
68
|
logger.info("Resources and tools registered successfully", context);
|
|
@@ -81,19 +81,29 @@ export async function pubchemFetchCompoundPropertiesLogic(params, context) {
|
|
|
81
81
|
params,
|
|
82
82
|
});
|
|
83
83
|
const { cids, properties } = params;
|
|
84
|
-
const cidsString = cids.join(",");
|
|
85
84
|
const propertiesString = properties.join(",");
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
85
|
+
const promises = cids.map(async (cid) => {
|
|
86
|
+
const path = `/compound/cid/${cid}/property/${propertiesString}/JSON`;
|
|
87
|
+
try {
|
|
88
|
+
const response = await pubChemApiClient.get(path, context);
|
|
89
|
+
return response?.PropertyTable?.Properties || [];
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
logger.warning(`Failed to fetch properties for CID ${cid}`, {
|
|
93
|
+
...context,
|
|
94
|
+
cid,
|
|
95
|
+
error,
|
|
96
|
+
});
|
|
97
|
+
return []; // Return empty array for this CID on failure
|
|
98
|
+
}
|
|
91
99
|
});
|
|
92
|
-
|
|
93
|
-
|
|
100
|
+
const results = await Promise.all(promises);
|
|
101
|
+
const allProperties = results.flat();
|
|
102
|
+
if (allProperties.length === 0) {
|
|
103
|
+
throw new McpError(BaseErrorCode.NOT_FOUND, "Could not fetch properties for any of the provided CIDs.", { ...context, cids });
|
|
94
104
|
}
|
|
95
105
|
const result = {
|
|
96
|
-
results:
|
|
106
|
+
results: allProperties,
|
|
97
107
|
};
|
|
98
108
|
logger.info(`Successfully fetched properties for ${result.results.length} CIDs.`, context);
|
|
99
109
|
return result;
|
|
@@ -13,7 +13,7 @@ import { PubchemFetchSubstanceDetailsInputSchema, pubchemFetchSubstanceDetailsLo
|
|
|
13
13
|
*/
|
|
14
14
|
export const registerPubchemFetchSubstanceDetailsTool = async (server) => {
|
|
15
15
|
const toolName = "pubchem_fetch_substance_details";
|
|
16
|
-
const toolDescription = "Retrieves
|
|
16
|
+
const toolDescription = "Retrieves a comprehensive record for a PubChem Substance ID (SID), including its source, deposition/modification dates, synonyms, associated Compound IDs (CIDs), and full cross-reference (xref) and compound data structures if available.";
|
|
17
17
|
server.tool(toolName, toolDescription, PubchemFetchSubstanceDetailsInputSchema.shape, async (params, mcpContext) => {
|
|
18
18
|
const handlerContext = requestContextService.createRequestContext({
|
|
19
19
|
operation: "HandleToolRequest",
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Defines the core logic, schemas, and types for the unified `pubchem_get_summary` tool.
|
|
3
|
+
* @module src/mcp-server/tools/getSummary/logic
|
|
4
|
+
*/
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { type RequestContext } from "../../../utils/index.js";
|
|
7
|
+
declare const AssaySummarySchema: z.ZodObject<{
|
|
8
|
+
aid: z.ZodNumber;
|
|
9
|
+
name: z.ZodString;
|
|
10
|
+
description: z.ZodString;
|
|
11
|
+
sourceName: z.ZodString;
|
|
12
|
+
numSids: z.ZodNumber;
|
|
13
|
+
numActive: z.ZodNumber;
|
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
|
15
|
+
name: string;
|
|
16
|
+
description: string;
|
|
17
|
+
aid: number;
|
|
18
|
+
sourceName: string;
|
|
19
|
+
numSids: number;
|
|
20
|
+
numActive: number;
|
|
21
|
+
}, {
|
|
22
|
+
name: string;
|
|
23
|
+
description: string;
|
|
24
|
+
aid: number;
|
|
25
|
+
sourceName: string;
|
|
26
|
+
numSids: number;
|
|
27
|
+
numActive: number;
|
|
28
|
+
}>;
|
|
29
|
+
declare const GeneSummarySchema: z.ZodObject<{
|
|
30
|
+
geneId: z.ZodNumber;
|
|
31
|
+
symbol: z.ZodString;
|
|
32
|
+
name: z.ZodString;
|
|
33
|
+
taxonomyId: z.ZodNumber;
|
|
34
|
+
taxonomy: z.ZodString;
|
|
35
|
+
description: z.ZodOptional<z.ZodString>;
|
|
36
|
+
synonyms: z.ZodArray<z.ZodString, "many">;
|
|
37
|
+
}, "strip", z.ZodTypeAny, {
|
|
38
|
+
symbol: string;
|
|
39
|
+
name: string;
|
|
40
|
+
synonyms: string[];
|
|
41
|
+
geneId: number;
|
|
42
|
+
taxonomyId: number;
|
|
43
|
+
taxonomy: string;
|
|
44
|
+
description?: string | undefined;
|
|
45
|
+
}, {
|
|
46
|
+
symbol: string;
|
|
47
|
+
name: string;
|
|
48
|
+
synonyms: string[];
|
|
49
|
+
geneId: number;
|
|
50
|
+
taxonomyId: number;
|
|
51
|
+
taxonomy: string;
|
|
52
|
+
description?: string | undefined;
|
|
53
|
+
}>;
|
|
54
|
+
declare const ProteinSummarySchema: z.ZodObject<{
|
|
55
|
+
proteinAccession: z.ZodString;
|
|
56
|
+
name: z.ZodString;
|
|
57
|
+
taxonomyId: z.ZodNumber;
|
|
58
|
+
taxonomy: z.ZodString;
|
|
59
|
+
synonyms: z.ZodArray<z.ZodString, "many">;
|
|
60
|
+
}, "strip", z.ZodTypeAny, {
|
|
61
|
+
name: string;
|
|
62
|
+
synonyms: string[];
|
|
63
|
+
taxonomyId: number;
|
|
64
|
+
taxonomy: string;
|
|
65
|
+
proteinAccession: string;
|
|
66
|
+
}, {
|
|
67
|
+
name: string;
|
|
68
|
+
synonyms: string[];
|
|
69
|
+
taxonomyId: number;
|
|
70
|
+
taxonomy: string;
|
|
71
|
+
proteinAccession: string;
|
|
72
|
+
}>;
|
|
73
|
+
declare const PathwaySummarySchema: z.ZodObject<{
|
|
74
|
+
pathwayAccession: z.ZodString;
|
|
75
|
+
sourceName: z.ZodString;
|
|
76
|
+
sourceId: z.ZodString;
|
|
77
|
+
name: z.ZodString;
|
|
78
|
+
type: z.ZodString;
|
|
79
|
+
category: z.ZodString;
|
|
80
|
+
description: z.ZodOptional<z.ZodString>;
|
|
81
|
+
taxonomyId: z.ZodNumber;
|
|
82
|
+
taxonomy: z.ZodString;
|
|
83
|
+
}, "strip", z.ZodTypeAny, {
|
|
84
|
+
type: string;
|
|
85
|
+
name: string;
|
|
86
|
+
sourceId: string;
|
|
87
|
+
sourceName: string;
|
|
88
|
+
taxonomyId: number;
|
|
89
|
+
taxonomy: string;
|
|
90
|
+
pathwayAccession: string;
|
|
91
|
+
category: string;
|
|
92
|
+
description?: string | undefined;
|
|
93
|
+
}, {
|
|
94
|
+
type: string;
|
|
95
|
+
name: string;
|
|
96
|
+
sourceId: string;
|
|
97
|
+
sourceName: string;
|
|
98
|
+
taxonomyId: number;
|
|
99
|
+
taxonomy: string;
|
|
100
|
+
pathwayAccession: string;
|
|
101
|
+
category: string;
|
|
102
|
+
description?: string | undefined;
|
|
103
|
+
}>;
|
|
104
|
+
declare const TaxonomySummarySchema: z.ZodObject<{
|
|
105
|
+
taxonomyId: z.ZodNumber;
|
|
106
|
+
scientificName: z.ZodString;
|
|
107
|
+
commonName: z.ZodOptional<z.ZodString>;
|
|
108
|
+
rank: z.ZodString;
|
|
109
|
+
rankedLineage: z.ZodArray<z.ZodObject<{
|
|
110
|
+
rank: z.ZodString;
|
|
111
|
+
name: z.ZodString;
|
|
112
|
+
taxId: z.ZodNumber;
|
|
113
|
+
}, "strip", z.ZodTypeAny, {
|
|
114
|
+
name: string;
|
|
115
|
+
rank: string;
|
|
116
|
+
taxId: number;
|
|
117
|
+
}, {
|
|
118
|
+
name: string;
|
|
119
|
+
rank: string;
|
|
120
|
+
taxId: number;
|
|
121
|
+
}>, "many">;
|
|
122
|
+
}, "strip", z.ZodTypeAny, {
|
|
123
|
+
taxonomyId: number;
|
|
124
|
+
scientificName: string;
|
|
125
|
+
rank: string;
|
|
126
|
+
rankedLineage: {
|
|
127
|
+
name: string;
|
|
128
|
+
rank: string;
|
|
129
|
+
taxId: number;
|
|
130
|
+
}[];
|
|
131
|
+
commonName?: string | undefined;
|
|
132
|
+
}, {
|
|
133
|
+
taxonomyId: number;
|
|
134
|
+
scientificName: string;
|
|
135
|
+
rank: string;
|
|
136
|
+
rankedLineage: {
|
|
137
|
+
name: string;
|
|
138
|
+
rank: string;
|
|
139
|
+
taxId: number;
|
|
140
|
+
}[];
|
|
141
|
+
commonName?: string | undefined;
|
|
142
|
+
}>;
|
|
143
|
+
declare const CellSummarySchema: z.ZodObject<{
|
|
144
|
+
cellAccession: z.ZodString;
|
|
145
|
+
name: z.ZodString;
|
|
146
|
+
sex: z.ZodOptional<z.ZodString>;
|
|
147
|
+
category: z.ZodString;
|
|
148
|
+
sourceTissue: z.ZodString;
|
|
149
|
+
sourceOrganism: z.ZodString;
|
|
150
|
+
sourceTaxonomyId: z.ZodNumber;
|
|
151
|
+
synonyms: z.ZodArray<z.ZodString, "many">;
|
|
152
|
+
}, "strip", z.ZodTypeAny, {
|
|
153
|
+
name: string;
|
|
154
|
+
synonyms: string[];
|
|
155
|
+
category: string;
|
|
156
|
+
cellAccession: string;
|
|
157
|
+
sourceTissue: string;
|
|
158
|
+
sourceOrganism: string;
|
|
159
|
+
sourceTaxonomyId: number;
|
|
160
|
+
sex?: string | undefined;
|
|
161
|
+
}, {
|
|
162
|
+
name: string;
|
|
163
|
+
synonyms: string[];
|
|
164
|
+
category: string;
|
|
165
|
+
cellAccession: string;
|
|
166
|
+
sourceTissue: string;
|
|
167
|
+
sourceOrganism: string;
|
|
168
|
+
sourceTaxonomyId: number;
|
|
169
|
+
sex?: string | undefined;
|
|
170
|
+
}>;
|
|
171
|
+
export declare const PubchemGetSummaryInputSchema: z.ZodObject<{
|
|
172
|
+
summaryType: z.ZodEnum<["assay", "gene", "protein", "pathway", "taxonomy", "cell"]>;
|
|
173
|
+
identifiers: z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "many">;
|
|
174
|
+
}, "strip", z.ZodTypeAny, {
|
|
175
|
+
identifiers: (string | number)[];
|
|
176
|
+
summaryType: "taxonomy" | "assay" | "gene" | "protein" | "pathway" | "cell";
|
|
177
|
+
}, {
|
|
178
|
+
identifiers: (string | number)[];
|
|
179
|
+
summaryType: "taxonomy" | "assay" | "gene" | "protein" | "pathway" | "cell";
|
|
180
|
+
}>;
|
|
181
|
+
export type PubchemGetSummaryInput = z.infer<typeof PubchemGetSummaryInputSchema>;
|
|
182
|
+
export type PubchemGetSummaryOutput = z.infer<typeof AssaySummarySchema>[] | z.infer<typeof GeneSummarySchema>[] | z.infer<typeof ProteinSummarySchema>[] | z.infer<typeof PathwaySummarySchema>[] | z.infer<typeof TaxonomySummarySchema>[] | z.infer<typeof CellSummarySchema>[];
|
|
183
|
+
export declare function pubchemGetSummaryLogic(params: PubchemGetSummaryInput, context: RequestContext): Promise<PubchemGetSummaryOutput>;
|
|
184
|
+
export {};
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Defines the core logic, schemas, and types for the unified `pubchem_get_summary` tool.
|
|
3
|
+
* @module src/mcp-server/tools/getSummary/logic
|
|
4
|
+
*/
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { pubChemApiClient } from "../../../services/pubchem/pubchemApiClient.js";
|
|
7
|
+
import { BaseErrorCode, McpError } from "../../../types-global/errors.js";
|
|
8
|
+
import { logger } from "../../../utils/index.js";
|
|
9
|
+
// Define individual summary schemas
|
|
10
|
+
const AssaySummarySchema = z.object({
|
|
11
|
+
aid: z.number().int(),
|
|
12
|
+
name: z.string(),
|
|
13
|
+
description: z.string(),
|
|
14
|
+
sourceName: z.string(),
|
|
15
|
+
numSids: z.number().int(),
|
|
16
|
+
numActive: z.number().int(),
|
|
17
|
+
});
|
|
18
|
+
const GeneSummarySchema = z.object({
|
|
19
|
+
geneId: z.number().int(),
|
|
20
|
+
symbol: z.string(),
|
|
21
|
+
name: z.string(),
|
|
22
|
+
taxonomyId: z.number().int(),
|
|
23
|
+
taxonomy: z.string(),
|
|
24
|
+
description: z.string().optional(),
|
|
25
|
+
synonyms: z.array(z.string()),
|
|
26
|
+
});
|
|
27
|
+
const ProteinSummarySchema = z.object({
|
|
28
|
+
proteinAccession: z.string(),
|
|
29
|
+
name: z.string(),
|
|
30
|
+
taxonomyId: z.number().int(),
|
|
31
|
+
taxonomy: z.string(),
|
|
32
|
+
synonyms: z.array(z.string()),
|
|
33
|
+
});
|
|
34
|
+
const PathwaySummarySchema = z.object({
|
|
35
|
+
pathwayAccession: z.string(),
|
|
36
|
+
sourceName: z.string(),
|
|
37
|
+
sourceId: z.string(),
|
|
38
|
+
name: z.string(),
|
|
39
|
+
type: z.string(),
|
|
40
|
+
category: z.string(),
|
|
41
|
+
description: z.string().optional(),
|
|
42
|
+
taxonomyId: z.number().int(),
|
|
43
|
+
taxonomy: z.string(),
|
|
44
|
+
});
|
|
45
|
+
const TaxonomySummarySchema = z.object({
|
|
46
|
+
taxonomyId: z.number().int(),
|
|
47
|
+
scientificName: z.string(),
|
|
48
|
+
commonName: z.string().optional(),
|
|
49
|
+
rank: z.string(),
|
|
50
|
+
rankedLineage: z.array(z.object({
|
|
51
|
+
rank: z.string(),
|
|
52
|
+
name: z.string(),
|
|
53
|
+
taxId: z.number().int(),
|
|
54
|
+
})),
|
|
55
|
+
});
|
|
56
|
+
const CellSummarySchema = z.object({
|
|
57
|
+
cellAccession: z.string(),
|
|
58
|
+
name: z.string(),
|
|
59
|
+
sex: z.string().optional(),
|
|
60
|
+
category: z.string(),
|
|
61
|
+
sourceTissue: z.string(),
|
|
62
|
+
sourceOrganism: z.string(),
|
|
63
|
+
sourceTaxonomyId: z.number().int(),
|
|
64
|
+
synonyms: z.array(z.string()),
|
|
65
|
+
});
|
|
66
|
+
// Input Schema
|
|
67
|
+
export const PubchemGetSummaryInputSchema = z.object({
|
|
68
|
+
summaryType: z.enum(["assay", "gene", "protein", "pathway", "taxonomy", "cell"])
|
|
69
|
+
.describe("The type of PubChem entity for which to fetch a summary."),
|
|
70
|
+
identifiers: z.array(z.union([z.string(), z.number().int().positive()]))
|
|
71
|
+
.min(1)
|
|
72
|
+
.describe("An array of identifiers for the specified entity type. Examples: " +
|
|
73
|
+
"Assay (AID): [1000], " +
|
|
74
|
+
"Gene (GeneID): [1956], " +
|
|
75
|
+
"Protein (Accession): [\"P00533\"], " +
|
|
76
|
+
"Pathway (Accession with prefix): [\"Reactome:R-HSA-70171\"], " +
|
|
77
|
+
"Taxonomy (TaxID): [9606], " +
|
|
78
|
+
"Cell (Accession): [\"CVCL_0030\"]"),
|
|
79
|
+
});
|
|
80
|
+
// Logic
|
|
81
|
+
async function fetchAssaySummary(identifiers, context) {
|
|
82
|
+
const promises = identifiers.map(async (id) => {
|
|
83
|
+
const path = `/assay/aid/${id}/summary/JSON`;
|
|
84
|
+
const response = await pubChemApiClient.get(path, context);
|
|
85
|
+
logger.debug(`Response for assay ID ${id}`, { ...context, response });
|
|
86
|
+
return response?.AssaySummaries?.AssaySummary || [];
|
|
87
|
+
});
|
|
88
|
+
const results = await Promise.all(promises);
|
|
89
|
+
const summaries = results.flat();
|
|
90
|
+
if (summaries.length === 0) {
|
|
91
|
+
throw new McpError(BaseErrorCode.NOT_FOUND, "No assay summaries found for the provided identifiers.", context);
|
|
92
|
+
}
|
|
93
|
+
return summaries.map((s) => ({
|
|
94
|
+
aid: s.AID,
|
|
95
|
+
name: s.Name,
|
|
96
|
+
description: Array.isArray(s.Description) ? s.Description.join("\\n") : s.Description,
|
|
97
|
+
sourceName: s.SourceName,
|
|
98
|
+
numSids: s.SIDCountAll,
|
|
99
|
+
numActive: s.CIDCountActive,
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
async function fetchGeneSummary(identifiers, context) {
|
|
103
|
+
const promises = identifiers.map(async (id) => {
|
|
104
|
+
const path = `/gene/geneid/${id}/summary/JSON`;
|
|
105
|
+
const response = await pubChemApiClient.get(path, context);
|
|
106
|
+
logger.debug(`Response for gene ID ${id}`, { ...context, response });
|
|
107
|
+
return response?.GeneSummaries?.GeneSummary || [];
|
|
108
|
+
});
|
|
109
|
+
const results = await Promise.all(promises);
|
|
110
|
+
const summaries = results.flat();
|
|
111
|
+
if (summaries.length === 0) {
|
|
112
|
+
throw new McpError(BaseErrorCode.NOT_FOUND, "No gene summaries found for the provided identifiers.", context);
|
|
113
|
+
}
|
|
114
|
+
return summaries.map((s) => ({
|
|
115
|
+
geneId: s.GeneID,
|
|
116
|
+
symbol: s.Symbol,
|
|
117
|
+
name: s.Name,
|
|
118
|
+
taxonomyId: s.TaxonomyID,
|
|
119
|
+
taxonomy: s.Taxonomy,
|
|
120
|
+
description: s.Description,
|
|
121
|
+
synonyms: s.Synonym || [],
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
async function fetchProteinSummary(identifiers, context) {
|
|
125
|
+
const promises = identifiers.map(async (id) => {
|
|
126
|
+
const path = `/protein/accession/${id}/summary/JSON`;
|
|
127
|
+
const response = await pubChemApiClient.get(path, context);
|
|
128
|
+
logger.debug(`Response for protein accession ${id}`, { ...context, response });
|
|
129
|
+
return response?.ProteinSummaries?.ProteinSummary || [];
|
|
130
|
+
});
|
|
131
|
+
const results = await Promise.all(promises);
|
|
132
|
+
const summaries = results.flat();
|
|
133
|
+
if (summaries.length === 0) {
|
|
134
|
+
throw new McpError(BaseErrorCode.NOT_FOUND, "No protein summaries found for the provided identifiers.", context);
|
|
135
|
+
}
|
|
136
|
+
return summaries.map((s) => ({
|
|
137
|
+
proteinAccession: s.ProteinAccession,
|
|
138
|
+
name: s.Name,
|
|
139
|
+
taxonomyId: s.TaxonomyID,
|
|
140
|
+
taxonomy: s.Taxonomy,
|
|
141
|
+
synonyms: s.Synonym || [],
|
|
142
|
+
}));
|
|
143
|
+
}
|
|
144
|
+
async function fetchPathwaySummary(identifiers, context) {
|
|
145
|
+
const promises = identifiers.map(async (id) => {
|
|
146
|
+
const path = `/pathway/pwacc/${id}/summary/JSON`;
|
|
147
|
+
const response = await pubChemApiClient.get(path, context);
|
|
148
|
+
logger.debug(`Response for pathway accession ${id}`, { ...context, response });
|
|
149
|
+
return response?.PathwaySummaries?.PathwaySummary || [];
|
|
150
|
+
});
|
|
151
|
+
const results = await Promise.all(promises);
|
|
152
|
+
const summaries = results.flat();
|
|
153
|
+
if (summaries.length === 0) {
|
|
154
|
+
throw new McpError(BaseErrorCode.NOT_FOUND, "No pathway summaries found for the provided identifiers.", context);
|
|
155
|
+
}
|
|
156
|
+
return summaries.map((s) => ({
|
|
157
|
+
pathwayAccession: s.PathwayAccession,
|
|
158
|
+
sourceName: s.SourceName,
|
|
159
|
+
sourceId: s.SourceID,
|
|
160
|
+
name: s.Name,
|
|
161
|
+
type: s.Type,
|
|
162
|
+
category: s.Category,
|
|
163
|
+
description: s.Description,
|
|
164
|
+
taxonomyId: s.TaxonomyID,
|
|
165
|
+
taxonomy: s.Taxonomy,
|
|
166
|
+
}));
|
|
167
|
+
}
|
|
168
|
+
async function fetchTaxonomySummary(identifiers, context) {
|
|
169
|
+
const promises = identifiers.map(async (id) => {
|
|
170
|
+
const path = `/taxonomy/taxid/${id}/summary/JSON`;
|
|
171
|
+
const response = await pubChemApiClient.get(path, context);
|
|
172
|
+
logger.debug(`Response for taxonomy ID ${id}`, { ...context, response });
|
|
173
|
+
return response?.TaxonomySummaries?.TaxonomySummary || [];
|
|
174
|
+
});
|
|
175
|
+
const results = await Promise.all(promises);
|
|
176
|
+
const summaries = results.flat();
|
|
177
|
+
if (summaries.length === 0) {
|
|
178
|
+
throw new McpError(BaseErrorCode.NOT_FOUND, "No taxonomy summaries found for the provided identifiers.", context);
|
|
179
|
+
}
|
|
180
|
+
return summaries.map((s) => ({
|
|
181
|
+
taxonomyId: s.TaxonomyID,
|
|
182
|
+
scientificName: s.ScientificName,
|
|
183
|
+
commonName: s.CommonName,
|
|
184
|
+
rank: s.Rank,
|
|
185
|
+
rankedLineage: s.RankedLineage || [],
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
async function fetchCellSummary(identifiers, context) {
|
|
189
|
+
const promises = identifiers.map(async (id) => {
|
|
190
|
+
const path = `/cell/cellacc/${id}/summary/JSON`;
|
|
191
|
+
const response = await pubChemApiClient.get(path, context);
|
|
192
|
+
logger.debug(`Response for cell accession ${id}`, { ...context, response });
|
|
193
|
+
return response?.CellSummaries?.CellSummary || [];
|
|
194
|
+
});
|
|
195
|
+
const results = await Promise.all(promises);
|
|
196
|
+
const summaries = results.flat();
|
|
197
|
+
if (summaries.length === 0) {
|
|
198
|
+
throw new McpError(BaseErrorCode.NOT_FOUND, "No cell summaries found for the provided identifiers.", context);
|
|
199
|
+
}
|
|
200
|
+
return summaries.map((s) => ({
|
|
201
|
+
cellAccession: s.CellAccession,
|
|
202
|
+
name: s.Name,
|
|
203
|
+
sex: s.Sex,
|
|
204
|
+
category: s.Category,
|
|
205
|
+
sourceTissue: s.SourceTissue,
|
|
206
|
+
sourceOrganism: s.SourceOrganism,
|
|
207
|
+
sourceTaxonomyId: s.SourceTaxonomyID,
|
|
208
|
+
synonyms: s.Synonym || [],
|
|
209
|
+
}));
|
|
210
|
+
}
|
|
211
|
+
export async function pubchemGetSummaryLogic(params, context) {
|
|
212
|
+
logger.debug("Processing pubchem_get_summary logic...", { ...context, params });
|
|
213
|
+
const { summaryType, identifiers } = params;
|
|
214
|
+
switch (summaryType) {
|
|
215
|
+
case "assay":
|
|
216
|
+
return fetchAssaySummary(identifiers, context);
|
|
217
|
+
case "gene":
|
|
218
|
+
return fetchGeneSummary(identifiers, context);
|
|
219
|
+
case "protein":
|
|
220
|
+
return fetchProteinSummary(identifiers, context);
|
|
221
|
+
case "pathway":
|
|
222
|
+
return fetchPathwaySummary(identifiers, context);
|
|
223
|
+
case "taxonomy":
|
|
224
|
+
return fetchTaxonomySummary(identifiers, context);
|
|
225
|
+
case "cell":
|
|
226
|
+
return fetchCellSummary(identifiers, context);
|
|
227
|
+
default:
|
|
228
|
+
throw new McpError(BaseErrorCode.INVALID_INPUT, `Invalid summary type: ${summaryType}`, context);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Handles the registration of the `pubchem_get_summary` tool with the MCP server.
|
|
3
|
+
* @module src/mcp-server/tools/getSummary/registration
|
|
4
|
+
*/
|
|
5
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
|
+
/**
|
|
7
|
+
* Registers the 'pubchem_get_summary' tool with the provided MCP server instance.
|
|
8
|
+
* This tool retrieves a summary for various PubChem data types.
|
|
9
|
+
*
|
|
10
|
+
* @param {McpServer} server - The MCP server instance to register the tool with.
|
|
11
|
+
*/
|
|
12
|
+
export declare const registerPubchemGetSummaryTool: (server: McpServer) => Promise<void>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Handles the registration of the `pubchem_get_summary` tool with the MCP server.
|
|
3
|
+
* @module src/mcp-server/tools/getSummary/registration
|
|
4
|
+
*/
|
|
5
|
+
import { ErrorHandler, logger, requestContextService, } from "../../../utils/index.js";
|
|
6
|
+
import { PubchemGetSummaryInputSchema, pubchemGetSummaryLogic, } from "./logic.js";
|
|
7
|
+
/**
|
|
8
|
+
* Registers the 'pubchem_get_summary' tool with the provided MCP server instance.
|
|
9
|
+
* This tool retrieves a summary for various PubChem data types.
|
|
10
|
+
*
|
|
11
|
+
* @param {McpServer} server - The MCP server instance to register the tool with.
|
|
12
|
+
*/
|
|
13
|
+
export const registerPubchemGetSummaryTool = async (server) => {
|
|
14
|
+
const toolName = "pubchem_get_summary";
|
|
15
|
+
const toolDescription = "Fetches a summary for a given PubChem entity type (assay, gene, protein, pathway, taxonomy, cell) and a list of identifiers.";
|
|
16
|
+
server.tool(toolName, toolDescription, PubchemGetSummaryInputSchema.shape, async (params, mcpContext) => {
|
|
17
|
+
const handlerContext = requestContextService.createRequestContext({
|
|
18
|
+
operation: "HandleToolRequest",
|
|
19
|
+
toolName,
|
|
20
|
+
mcpToolContext: mcpContext,
|
|
21
|
+
input: params,
|
|
22
|
+
});
|
|
23
|
+
try {
|
|
24
|
+
logger.info(`Initiating tool request for ${toolName} with type: ${params.summaryType}`, handlerContext);
|
|
25
|
+
const result = await pubchemGetSummaryLogic(params, handlerContext);
|
|
26
|
+
return {
|
|
27
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
28
|
+
isError: false,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
const handledError = ErrorHandler.handleError(error, {
|
|
33
|
+
operation: "pubchemGetSummaryToolHandler",
|
|
34
|
+
context: handlerContext,
|
|
35
|
+
input: params,
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
content: [
|
|
39
|
+
{
|
|
40
|
+
type: "text",
|
|
41
|
+
text: JSON.stringify({
|
|
42
|
+
error: ErrorHandler.formatError(handledError),
|
|
43
|
+
}),
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
isError: true,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Barrel file for the `pubchem_fetch_assay_summary` tool.
|
|
3
|
-
* This file serves as the public interface for the tool module,
|
|
4
|
-
* primarily exporting the `registerPubchemFetchAssaySummaryTool` function.
|
|
5
|
-
* @module src/mcp-server/tools/fetchAssaySummary/index
|
|
6
|
-
*/
|
|
7
|
-
export { registerPubchemFetchAssaySummaryTool } from "./registration.js";
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Barrel file for the `pubchem_fetch_assay_summary` tool.
|
|
3
|
-
* This file serves as the public interface for the tool module,
|
|
4
|
-
* primarily exporting the `registerPubchemFetchAssaySummaryTool` function.
|
|
5
|
-
* @module src/mcp-server/tools/fetchAssaySummary/index
|
|
6
|
-
*/
|
|
7
|
-
export { registerPubchemFetchAssaySummaryTool } from "./registration.js";
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Defines the core logic, schemas, and types for the `pubchem_fetch_assay_summary` tool.
|
|
3
|
-
* @module src/mcp-server/tools/fetchAssaySummary/logic
|
|
4
|
-
*/
|
|
5
|
-
import { z } from "zod";
|
|
6
|
-
import { type RequestContext } from "../../../utils/index.js";
|
|
7
|
-
export declare const PubchemFetchAssaySummaryInputSchema: z.ZodObject<{
|
|
8
|
-
aids: z.ZodArray<z.ZodNumber, "many">;
|
|
9
|
-
}, "strip", z.ZodTypeAny, {
|
|
10
|
-
aids: number[];
|
|
11
|
-
}, {
|
|
12
|
-
aids: number[];
|
|
13
|
-
}>;
|
|
14
|
-
export type PubchemFetchAssaySummaryInput = z.infer<typeof PubchemFetchAssaySummaryInputSchema>;
|
|
15
|
-
export declare const AssaySummarySchema: z.ZodObject<{
|
|
16
|
-
aid: z.ZodNumber;
|
|
17
|
-
name: z.ZodString;
|
|
18
|
-
description: z.ZodString;
|
|
19
|
-
sourceName: z.ZodString;
|
|
20
|
-
numSids: z.ZodNumber;
|
|
21
|
-
numActive: z.ZodNumber;
|
|
22
|
-
targets: z.ZodArray<z.ZodObject<{
|
|
23
|
-
name: z.ZodString;
|
|
24
|
-
geneId: z.ZodOptional<z.ZodNumber>;
|
|
25
|
-
geneSymbol: z.ZodOptional<z.ZodString>;
|
|
26
|
-
}, "strip", z.ZodTypeAny, {
|
|
27
|
-
name: string;
|
|
28
|
-
geneId?: number | undefined;
|
|
29
|
-
geneSymbol?: string | undefined;
|
|
30
|
-
}, {
|
|
31
|
-
name: string;
|
|
32
|
-
geneId?: number | undefined;
|
|
33
|
-
geneSymbol?: string | undefined;
|
|
34
|
-
}>, "many">;
|
|
35
|
-
}, "strip", z.ZodTypeAny, {
|
|
36
|
-
name: string;
|
|
37
|
-
description: string;
|
|
38
|
-
aid: number;
|
|
39
|
-
sourceName: string;
|
|
40
|
-
numSids: number;
|
|
41
|
-
numActive: number;
|
|
42
|
-
targets: {
|
|
43
|
-
name: string;
|
|
44
|
-
geneId?: number | undefined;
|
|
45
|
-
geneSymbol?: string | undefined;
|
|
46
|
-
}[];
|
|
47
|
-
}, {
|
|
48
|
-
name: string;
|
|
49
|
-
description: string;
|
|
50
|
-
aid: number;
|
|
51
|
-
sourceName: string;
|
|
52
|
-
numSids: number;
|
|
53
|
-
numActive: number;
|
|
54
|
-
targets: {
|
|
55
|
-
name: string;
|
|
56
|
-
geneId?: number | undefined;
|
|
57
|
-
geneSymbol?: string | undefined;
|
|
58
|
-
}[];
|
|
59
|
-
}>;
|
|
60
|
-
export type AssaySummary = z.infer<typeof AssaySummarySchema>;
|
|
61
|
-
export type PubchemFetchAssaySummaryOutput = AssaySummary[];
|
|
62
|
-
/**
|
|
63
|
-
* Core logic for the `pubchem_fetch_assay_summary` tool. It retrieves a summary
|
|
64
|
-
* for a specified list of PubChem BioAssay IDs (AIDs).
|
|
65
|
-
*
|
|
66
|
-
* @param {PubchemFetchAssaySummaryInput} params - The validated input parameters, containing the AIDs.
|
|
67
|
-
* @param {RequestContext} context - The request context for logging, tracing, and error handling.
|
|
68
|
-
* @returns {Promise<PubchemFetchAssaySummaryOutput>} A promise that resolves with an array of structured assay summaries.
|
|
69
|
-
* @throws {McpError} Throws a structured error if the API request fails, any AID is not found, or the response is malformed.
|
|
70
|
-
*/
|
|
71
|
-
export declare function pubchemFetchAssaySummaryLogic(params: PubchemFetchAssaySummaryInput, context: RequestContext): Promise<PubchemFetchAssaySummaryOutput>;
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Defines the core logic, schemas, and types for the `pubchem_fetch_assay_summary` tool.
|
|
3
|
-
* @module src/mcp-server/tools/fetchAssaySummary/logic
|
|
4
|
-
*/
|
|
5
|
-
import { z } from "zod";
|
|
6
|
-
import { pubChemApiClient } from "../../../services/pubchem/pubchemApiClient.js";
|
|
7
|
-
import { BaseErrorCode, McpError } from "../../../types-global/errors.js";
|
|
8
|
-
import { logger } from "../../../utils/index.js";
|
|
9
|
-
// 1. Define and export the Zod schema for input validation
|
|
10
|
-
export const PubchemFetchAssaySummaryInputSchema = z.object({
|
|
11
|
-
aids: z
|
|
12
|
-
.array(z.number().int().positive())
|
|
13
|
-
.min(1, "At least one Assay ID (AID) must be provided.")
|
|
14
|
-
.max(5, "A maximum of 5 Assay IDs (AIDs) can be provided.")
|
|
15
|
-
.describe("An array of PubChem BioAssay IDs (AIDs). Must contain 1 to 5 positive integers."),
|
|
16
|
-
});
|
|
17
|
-
// 3. Define and export the Zod schema for a single assay summary object
|
|
18
|
-
export const AssaySummarySchema = z.object({
|
|
19
|
-
aid: z.number().int().describe("The unique PubChem BioAssay ID (AID)."),
|
|
20
|
-
name: z.string().describe("The official name of the bioassay."),
|
|
21
|
-
description: z
|
|
22
|
-
.string()
|
|
23
|
-
.describe("A detailed description of the assay's purpose and methods."),
|
|
24
|
-
sourceName: z
|
|
25
|
-
.string()
|
|
26
|
-
.describe("The name of the institution or entity that provided the assay."),
|
|
27
|
-
numSids: z
|
|
28
|
-
.number()
|
|
29
|
-
.int()
|
|
30
|
-
.describe("The total number of substances (SIDs) tested in the assay."),
|
|
31
|
-
numActive: z
|
|
32
|
-
.number()
|
|
33
|
-
.int()
|
|
34
|
-
.describe("The number of substances found to be active in the assay."),
|
|
35
|
-
targets: z
|
|
36
|
-
.array(z.object({
|
|
37
|
-
name: z.string().describe("Name of the biological target."),
|
|
38
|
-
geneId: z
|
|
39
|
-
.number()
|
|
40
|
-
.int()
|
|
41
|
-
.optional()
|
|
42
|
-
.describe("NCBI Gene ID, if available."),
|
|
43
|
-
geneSymbol: z
|
|
44
|
-
.string()
|
|
45
|
-
.optional()
|
|
46
|
-
.describe("Official gene symbol, if available."),
|
|
47
|
-
}))
|
|
48
|
-
.describe("Biological targets of the assay. Note: This is often empty as the summary endpoint may not provide target details."),
|
|
49
|
-
});
|
|
50
|
-
/**
|
|
51
|
-
* Core logic for the `pubchem_fetch_assay_summary` tool. It retrieves a summary
|
|
52
|
-
* for a specified list of PubChem BioAssay IDs (AIDs).
|
|
53
|
-
*
|
|
54
|
-
* @param {PubchemFetchAssaySummaryInput} params - The validated input parameters, containing the AIDs.
|
|
55
|
-
* @param {RequestContext} context - The request context for logging, tracing, and error handling.
|
|
56
|
-
* @returns {Promise<PubchemFetchAssaySummaryOutput>} A promise that resolves with an array of structured assay summaries.
|
|
57
|
-
* @throws {McpError} Throws a structured error if the API request fails, any AID is not found, or the response is malformed.
|
|
58
|
-
*/
|
|
59
|
-
export async function pubchemFetchAssaySummaryLogic(params, context) {
|
|
60
|
-
logger.debug("Processing pubchem_fetch_assay_summary logic...", {
|
|
61
|
-
...context,
|
|
62
|
-
params,
|
|
63
|
-
});
|
|
64
|
-
const { aids } = params;
|
|
65
|
-
const path = `/assay/aid/${aids.join(",")}/summary/JSON`;
|
|
66
|
-
const response = await pubChemApiClient.get(path, context);
|
|
67
|
-
logger.debug("Raw PubChem response for pubchem_fetch_assay_summary", {
|
|
68
|
-
...context,
|
|
69
|
-
aids,
|
|
70
|
-
response,
|
|
71
|
-
});
|
|
72
|
-
const summaries = response?.AssaySummaries?.AssaySummary;
|
|
73
|
-
if (!summaries || summaries.length === 0) {
|
|
74
|
-
throw new McpError(BaseErrorCode.NOT_FOUND, `No assay summaries found for AIDs [${aids.join(", ")}], or the response from PubChem was malformed.`, { ...context, aids, response });
|
|
75
|
-
}
|
|
76
|
-
const results = summaries.map((summary) => {
|
|
77
|
-
// Safely extract description, handling both string and array formats.
|
|
78
|
-
let description = "No description provided.";
|
|
79
|
-
if (summary.Description) {
|
|
80
|
-
description = Array.isArray(summary.Description)
|
|
81
|
-
? summary.Description.join("\n")
|
|
82
|
-
: summary.Description;
|
|
83
|
-
}
|
|
84
|
-
return {
|
|
85
|
-
aid: summary.AID ?? 0,
|
|
86
|
-
name: summary.Name ?? "N/A",
|
|
87
|
-
description,
|
|
88
|
-
sourceName: summary.SourceName ?? "N/A",
|
|
89
|
-
numSids: summary.SIDCountAll ?? 0,
|
|
90
|
-
numActive: summary.CIDCountActive ?? 0,
|
|
91
|
-
targets: [], // The summary endpoint does not provide target details. This is expected.
|
|
92
|
-
};
|
|
93
|
-
});
|
|
94
|
-
logger.info(`Successfully fetched ${results.length} summaries for AIDs [${aids.join(", ")}].`, context);
|
|
95
|
-
return results;
|
|
96
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Handles the registration of the `pubchem_fetch_assay_summary` tool with the MCP server.
|
|
3
|
-
* @module src/mcp-server/tools/fetchAssaySummary/registration
|
|
4
|
-
*/
|
|
5
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
|
-
/**
|
|
7
|
-
* Registers the 'pubchem_fetch_assay_summary' tool with the provided MCP server instance.
|
|
8
|
-
* This tool retrieves a detailed summary for a given PubChem BioAssay ID (AID).
|
|
9
|
-
*
|
|
10
|
-
* @param {McpServer} server - The MCP server instance to register the tool with.
|
|
11
|
-
*/
|
|
12
|
-
export declare const registerPubchemFetchAssaySummaryTool: (server: McpServer) => Promise<void>;
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Handles the registration of the `pubchem_fetch_assay_summary` tool with the MCP server.
|
|
3
|
-
* @module src/mcp-server/tools/fetchAssaySummary/registration
|
|
4
|
-
*/
|
|
5
|
-
import { ErrorHandler, logger, requestContextService, } from "../../../utils/index.js";
|
|
6
|
-
import { PubchemFetchAssaySummaryInputSchema, pubchemFetchAssaySummaryLogic, } from "./logic.js";
|
|
7
|
-
/**
|
|
8
|
-
* Registers the 'pubchem_fetch_assay_summary' tool with the provided MCP server instance.
|
|
9
|
-
* This tool retrieves a detailed summary for a given PubChem BioAssay ID (AID).
|
|
10
|
-
*
|
|
11
|
-
* @param {McpServer} server - The MCP server instance to register the tool with.
|
|
12
|
-
*/
|
|
13
|
-
export const registerPubchemFetchAssaySummaryTool = async (server) => {
|
|
14
|
-
const toolName = "pubchem_fetch_assay_summary";
|
|
15
|
-
const toolDescription = "Fetches detailed summaries for a list of up to 5 PubChem BioAssay IDs (AIDs), including their names, descriptions, sources, and statistics. This is useful for obtaining metadata about multiple biological assays in a single request.";
|
|
16
|
-
server.tool(toolName, toolDescription, PubchemFetchAssaySummaryInputSchema.shape, async (params, mcpContext) => {
|
|
17
|
-
const handlerContext = requestContextService.createRequestContext({
|
|
18
|
-
operation: "HandleToolRequest",
|
|
19
|
-
toolName,
|
|
20
|
-
mcpToolContext: mcpContext,
|
|
21
|
-
input: params,
|
|
22
|
-
});
|
|
23
|
-
try {
|
|
24
|
-
logger.info(`Initiating tool request for ${toolName} with AIDs: ${params.aids.join(", ")}`, handlerContext);
|
|
25
|
-
const result = await pubchemFetchAssaySummaryLogic(params, handlerContext);
|
|
26
|
-
// Custom stringify to make large arrays of numbers more compact
|
|
27
|
-
const placeholderPrefix = "##JSON_STRINGIFY_PLACEHOLDER##";
|
|
28
|
-
let placeholderIndex = 0;
|
|
29
|
-
const placeholders = [];
|
|
30
|
-
const replacer = (key, value) => {
|
|
31
|
-
if (Array.isArray(value) &&
|
|
32
|
-
value.every((item) => typeof item === "number")) {
|
|
33
|
-
const placeholder = `${placeholderPrefix}${placeholderIndex++}`;
|
|
34
|
-
placeholders.push(JSON.stringify(value));
|
|
35
|
-
return placeholder;
|
|
36
|
-
}
|
|
37
|
-
return value;
|
|
38
|
-
};
|
|
39
|
-
let text = JSON.stringify(result, replacer, 2);
|
|
40
|
-
for (let i = 0; i < placeholders.length; i++) {
|
|
41
|
-
text = text.replace(`"${placeholderPrefix}${i}"`, placeholders[i]);
|
|
42
|
-
}
|
|
43
|
-
return {
|
|
44
|
-
content: [{ type: "text", text }],
|
|
45
|
-
isError: false,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
catch (error) {
|
|
49
|
-
const handledError = ErrorHandler.handleError(error, {
|
|
50
|
-
operation: "pubchemFetchAssaySummaryToolHandler",
|
|
51
|
-
context: handlerContext,
|
|
52
|
-
input: params,
|
|
53
|
-
});
|
|
54
|
-
// No need to log here, handleError already does it.
|
|
55
|
-
return {
|
|
56
|
-
content: [
|
|
57
|
-
{
|
|
58
|
-
type: "text",
|
|
59
|
-
text: JSON.stringify({
|
|
60
|
-
error: ErrorHandler.formatError(handledError),
|
|
61
|
-
}),
|
|
62
|
-
},
|
|
63
|
-
],
|
|
64
|
-
isError: true,
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
};
|