@cyanheads/pubchem-mcp-server 0.1.23 → 0.2.0

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.
Files changed (65) hide show
  1. package/README.md +43 -8
  2. package/dist/index.js +3 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/mcp-server/resources/definitions/assay.resource.d.ts +9 -0
  5. package/dist/mcp-server/resources/definitions/assay.resource.d.ts.map +1 -0
  6. package/dist/mcp-server/resources/definitions/assay.resource.js +24 -0
  7. package/dist/mcp-server/resources/definitions/assay.resource.js.map +1 -0
  8. package/dist/mcp-server/resources/definitions/compound-bioactivity.resource.d.ts +9 -0
  9. package/dist/mcp-server/resources/definitions/compound-bioactivity.resource.d.ts.map +1 -0
  10. package/dist/mcp-server/resources/definitions/compound-bioactivity.resource.js +28 -0
  11. package/dist/mcp-server/resources/definitions/compound-bioactivity.resource.js.map +1 -0
  12. package/dist/mcp-server/resources/definitions/compound-image.resource.d.ts +11 -0
  13. package/dist/mcp-server/resources/definitions/compound-image.resource.d.ts.map +1 -0
  14. package/dist/mcp-server/resources/definitions/compound-image.resource.js +28 -0
  15. package/dist/mcp-server/resources/definitions/compound-image.resource.js.map +1 -0
  16. package/dist/mcp-server/resources/definitions/compound-safety.resource.d.ts +9 -0
  17. package/dist/mcp-server/resources/definitions/compound-safety.resource.d.ts.map +1 -0
  18. package/dist/mcp-server/resources/definitions/compound-safety.resource.js +32 -0
  19. package/dist/mcp-server/resources/definitions/compound-safety.resource.js.map +1 -0
  20. package/dist/mcp-server/resources/definitions/compound-xrefs.resource.d.ts +9 -0
  21. package/dist/mcp-server/resources/definitions/compound-xrefs.resource.d.ts.map +1 -0
  22. package/dist/mcp-server/resources/definitions/compound-xrefs.resource.js +29 -0
  23. package/dist/mcp-server/resources/definitions/compound-xrefs.resource.js.map +1 -0
  24. package/dist/mcp-server/resources/definitions/compound.resource.d.ts +9 -0
  25. package/dist/mcp-server/resources/definitions/compound.resource.d.ts.map +1 -0
  26. package/dist/mcp-server/resources/definitions/compound.resource.js +28 -0
  27. package/dist/mcp-server/resources/definitions/compound.resource.js.map +1 -0
  28. package/dist/mcp-server/resources/definitions/index.d.ts +14 -0
  29. package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -0
  30. package/dist/mcp-server/resources/definitions/index.js +19 -0
  31. package/dist/mcp-server/resources/definitions/index.js.map +1 -0
  32. package/dist/mcp-server/tools/definitions/get-bioactivity.tool.d.ts +3 -0
  33. package/dist/mcp-server/tools/definitions/get-bioactivity.tool.d.ts.map +1 -1
  34. package/dist/mcp-server/tools/definitions/get-bioactivity.tool.js +38 -6
  35. package/dist/mcp-server/tools/definitions/get-bioactivity.tool.js.map +1 -1
  36. package/dist/mcp-server/tools/definitions/get-compound-3d-structure.tool.d.ts +38 -0
  37. package/dist/mcp-server/tools/definitions/get-compound-3d-structure.tool.d.ts.map +1 -0
  38. package/dist/mcp-server/tools/definitions/get-compound-3d-structure.tool.js +133 -0
  39. package/dist/mcp-server/tools/definitions/get-compound-3d-structure.tool.js.map +1 -0
  40. package/dist/mcp-server/tools/definitions/get-compound-interactions.tool.d.ts +32 -0
  41. package/dist/mcp-server/tools/definitions/get-compound-interactions.tool.d.ts.map +1 -0
  42. package/dist/mcp-server/tools/definitions/get-compound-interactions.tool.js +92 -0
  43. package/dist/mcp-server/tools/definitions/get-compound-interactions.tool.js.map +1 -0
  44. package/dist/mcp-server/tools/definitions/get-compound-safety.tool.d.ts +19 -15
  45. package/dist/mcp-server/tools/definitions/get-compound-safety.tool.d.ts.map +1 -1
  46. package/dist/mcp-server/tools/definitions/get-compound-safety.tool.js +106 -73
  47. package/dist/mcp-server/tools/definitions/get-compound-safety.tool.js.map +1 -1
  48. package/dist/mcp-server/tools/definitions/index.d.ts +74 -12
  49. package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
  50. package/dist/mcp-server/tools/definitions/index.js +4 -0
  51. package/dist/mcp-server/tools/definitions/index.js.map +1 -1
  52. package/dist/services/pubchem/pubchem-client.d.ts +20 -1
  53. package/dist/services/pubchem/pubchem-client.d.ts.map +1 -1
  54. package/dist/services/pubchem/pubchem-client.js +158 -0
  55. package/dist/services/pubchem/pubchem-client.js.map +1 -1
  56. package/dist/services/pubchem/sdf-parser.d.ts +20 -0
  57. package/dist/services/pubchem/sdf-parser.d.ts.map +1 -0
  58. package/dist/services/pubchem/sdf-parser.js +55 -0
  59. package/dist/services/pubchem/sdf-parser.js.map +1 -0
  60. package/dist/services/pubchem/types.d.ts +44 -0
  61. package/dist/services/pubchem/types.d.ts.map +1 -1
  62. package/dist/services/pubchem/types.js.map +1 -1
  63. package/manifest.json +1 -1
  64. package/package.json +1 -1
  65. package/server.json +3 -3
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  <div align="center">
2
2
  <h1>@cyanheads/pubchem-mcp-server</h1>
3
3
  <p><b>MCP server for the PubChem chemical database. Search compounds, fetch properties, safety data, bioactivity, cross-references, and entity summaries. STDIO & Streamable HTTP.</b>
4
- <div>8 Tools</div>
4
+ <div>10 Tools • 6 Resources</div>
5
5
  </p>
6
6
  </div>
7
7
 
8
8
  <div align="center">
9
9
 
10
- [![Version](https://img.shields.io/badge/Version-0.1.23-blue.svg?style=flat-square)](./CHANGELOG.md) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![Docker](https://img.shields.io/badge/Docker-ghcr.io-2496ED?style=flat-square&logo=docker&logoColor=white)](https://github.com/users/cyanheads/packages/container/package/pubchem-mcp-server) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.29.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![npm](https://img.shields.io/npm/v/@cyanheads/pubchem-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/@cyanheads/pubchem-mcp-server) [![TypeScript](https://img.shields.io/badge/TypeScript-^6.0.3-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-^1.3.0-f472b6.svg?style=flat-square)](https://bun.sh/)
10
+ [![Version](https://img.shields.io/badge/Version-0.2.0-blue.svg?style=flat-square)](./CHANGELOG.md) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![Docker](https://img.shields.io/badge/Docker-ghcr.io-2496ED?style=flat-square&logo=docker&logoColor=white)](https://github.com/users/cyanheads/packages/container/package/pubchem-mcp-server) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.29.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![npm](https://img.shields.io/npm/v/@cyanheads/pubchem-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/@cyanheads/pubchem-mcp-server) [![TypeScript](https://img.shields.io/badge/TypeScript-^6.0.3-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-^1.3.0-f472b6.svg?style=flat-square)](https://bun.sh/)
11
11
 
12
12
  </div>
13
13
 
@@ -29,16 +29,18 @@
29
29
 
30
30
  ## Tools
31
31
 
32
- Eight tools for querying PubChem's chemical information database:
32
+ Ten tools for querying PubChem's chemical information database:
33
33
 
34
34
  | Tool Name | Description |
35
35
  |:----------|:------------|
36
36
  | `pubchem_search_compounds` | Search for compounds by name, SMILES, InChIKey, formula, substructure, superstructure, or 2D similarity. |
37
37
  | `pubchem_get_compound_details` | Get physicochemical properties, descriptions, synonyms, drug-likeness, and classification for compounds by CID. |
38
38
  | `pubchem_get_compound_image` | Fetch a 2D structure diagram (PNG) for a compound by CID. |
39
- | `pubchem_get_compound_safety` | Get GHS hazard classification and safety data for a compound. |
39
+ | `pubchem_get_compound_3d_structure` | Fetch a 3D conformer (atomic coordinates and bonds) for a compound by CID, as parsed JSON or raw SDF. |
40
40
  | `pubchem_get_compound_xrefs` | Get external database cross-references (PubMed, patents, genes, proteins, etc.). |
41
- | `pubchem_get_bioactivity` | Get a compound's bioactivity profile: assay results, targets, and activity values. |
41
+ | `pubchem_get_compound_safety` | Get GHS hazard classification and safety data for one or more compounds by CID (batch). |
42
+ | `pubchem_get_bioactivity` | Get a compound's bioactivity profile: assay results, targets, and activity values; filter by outcome or molecular target. |
43
+ | `pubchem_get_compound_interactions` | Get drug-drug, drug-food, and chemical-target interactions for a compound by CID. |
42
44
  | `pubchem_search_assays` | Find bioassays by biological target (gene symbol, protein, Gene ID, UniProt accession). |
43
45
  | `pubchem_get_summary` | Get summaries for PubChem entities: assays, genes, proteins, taxonomy. |
44
46
 
@@ -72,7 +74,7 @@ Get detailed compound information by CID.
72
74
  Get a compound's bioactivity profile from PubChem BioAssay.
73
75
 
74
76
  - Returns assay outcomes (Active/Inactive/Inconclusive), target info (protein accessions, NCBI Gene IDs), and quantitative values (IC50, EC50, Ki)
75
- - Filter by outcome to focus on active results
77
+ - Filter by outcome and/or a specific molecular target (NCBI Gene ID or protein accession)
76
78
  - Caps at 100 results per request (well-studied compounds may have thousands)
77
79
 
78
80
  ---
@@ -85,6 +87,39 @@ Get descriptive summaries for four PubChem entity types.
85
87
  - Up to 10 entities per call
86
88
  - Type-specific field extraction for clean, structured output
87
89
 
90
+ ---
91
+
92
+ ### `pubchem_get_compound_interactions`
93
+
94
+ Get a compound's interaction data by CID.
95
+
96
+ - Drug-drug interactions (DrugBank), drug-food interactions, and chemical-target binding/activity (BindingDB, ChEMBL, and others)
97
+ - Select which interaction kinds to fetch and cap entries per kind
98
+ - Each entry carries its originating source — coverage is richest for approved drugs
99
+
100
+ ---
101
+
102
+ ### `pubchem_get_compound_3d_structure`
103
+
104
+ Get a compound's default 3D conformer by CID.
105
+
106
+ - `format="json"` returns parsed atoms (element + x/y/z) and bonds for direct reasoning; `format="sdf"` returns raw V2000 SDF for passthrough to docking or rendering
107
+ - Optionally lists alternate conformer IDs
108
+ - Returns a typed not-found when PubChem has no computed 3D coordinates (large molecules, mixtures, some salts)
109
+
110
+ ## Resources
111
+
112
+ Compound and assay records are also exposed as URI-templated MCP resources, backed by the same client methods as the tools:
113
+
114
+ | URI Template | Returns |
115
+ |:-------------|:--------|
116
+ | `pubchem://compound/{cid}` | Core physicochemical properties (JSON). |
117
+ | `pubchem://compound/{cid}/safety` | GHS hazard classification (JSON). |
118
+ | `pubchem://compound/{cid}/image` | 2D structure diagram (PNG). |
119
+ | `pubchem://compound/{cid}/xrefs` | External cross-references (JSON). |
120
+ | `pubchem://compound/{cid}/bioactivity` | Bioassay activity profile (JSON). |
121
+ | `pubchem://assay/{aid}` | BioAssay summary (JSON). |
122
+
88
123
  ## Features
89
124
 
90
125
  Built on [`@cyanheads/mcp-ts-core`](https://github.com/cyanheads/mcp-ts-core):
@@ -111,7 +146,7 @@ A public instance is available at `https://pubchem.caseyjhand.com/mcp` — no in
111
146
  ```json
112
147
  {
113
148
  "mcpServers": {
114
- "pubchem": {
149
+ "pubchem-mcp-server": {
115
150
  "type": "streamable-http",
116
151
  "url": "https://pubchem.caseyjhand.com/mcp"
117
152
  }
@@ -126,7 +161,7 @@ Add to your MCP client config (e.g., `claude_desktop_config.json`):
126
161
  ```json
127
162
  {
128
163
  "mcpServers": {
129
- "pubchem": {
164
+ "pubchem-mcp-server": {
130
165
  "type": "stdio",
131
166
  "command": "bunx",
132
167
  "args": ["@cyanheads/pubchem-mcp-server@latest"],
package/dist/index.js CHANGED
@@ -5,11 +5,13 @@
5
5
  * @module index
6
6
  */
7
7
  import { createApp } from '@cyanheads/mcp-ts-core';
8
+ import { allResourceDefinitions } from './mcp-server/resources/definitions/index.js';
8
9
  import { allToolDefinitions } from './mcp-server/tools/definitions/index.js';
9
10
  import { initPubChemClient } from './services/pubchem/pubchem-client.js';
10
11
  await createApp({
11
12
  tools: allToolDefinitions,
12
- instructions: "Use the pubchem_* tools to query PubChem's chemical database. Compounds are addressed by CID, assays by AID. Most flows start at `pubchem_search_compounds` (name, SMILES, InChIKey, formula, substructure, superstructure, or 2D similarity → CIDs), then call per-CID tools for details, safety, image, cross-references, or bioactivity. For bioassays by biological target, chain `pubchem_search_assays` (gene/protein → AIDs) into `pubchem_get_bioactivity`. `pubchem_get_summary` covers assay/gene/protein/taxonomy entity lookups.",
13
+ resources: allResourceDefinitions,
14
+ instructions: "Use the pubchem_* tools to query PubChem's chemical database. Compounds are addressed by CID, assays by AID. Most flows start at `pubchem_search_compounds` (name, SMILES, InChIKey, formula, substructure, superstructure, or 2D similarity → CIDs), then call per-CID tools for details, safety, image, cross-references, bioactivity, interactions (drug-drug/drug-food/target), or 3D structure. For bioassays by biological target, chain `pubchem_search_assays` (gene/protein → AIDs) into `pubchem_get_bioactivity`. `pubchem_get_summary` covers assay/gene/protein/taxonomy entity lookups. Compound and assay records are also exposed as URI-addressable resources (e.g. `pubchem://compound/{cid}`, `pubchem://assay/{aid}`).",
13
15
  landing: {
14
16
  tagline: 'Search PubChem for chemical compounds, properties, safety, bioactivity, and cross-references.',
15
17
  repoRoot: 'https://github.com/cyanheads/pubchem-mcp-server',
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAEzE,MAAM,SAAS,CAAC;IACd,KAAK,EAAE,kBAAkB;IACzB,YAAY,EACV,8gBAA8gB;IAChhB,OAAO,EAAE;QACP,OAAO,EACL,+FAA+F;QACjG,QAAQ,EAAE,iDAAiD;QAC3D,KAAK,EAAE;YACL,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,mCAAmC,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC/E;gBACE,KAAK,EAAE,eAAe;gBACtB,IAAI,EAAE,gDAAgD;gBACtD,QAAQ,EAAE,IAAI;aACf;YACD;gBACE,KAAK,EAAE,eAAe;gBACtB,IAAI,EAAE,gDAAgD;gBACtD,QAAQ,EAAE,IAAI;aACf;SACF;KACF;IACD,KAAK;QACH,iBAAiB,EAAE,CAAC;IACtB,CAAC;CACF,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAEzE,MAAM,SAAS,CAAC;IACd,KAAK,EAAE,kBAAkB;IACzB,SAAS,EAAE,sBAAsB;IACjC,YAAY,EACV,4sBAA4sB;IAC9sB,OAAO,EAAE;QACP,OAAO,EACL,+FAA+F;QACjG,QAAQ,EAAE,iDAAiD;QAC3D,KAAK,EAAE;YACL,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,mCAAmC,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC/E;gBACE,KAAK,EAAE,eAAe;gBACtB,IAAI,EAAE,gDAAgD;gBACtD,QAAQ,EAAE,IAAI;aACf;YACD;gBACE,KAAK,EAAE,eAAe;gBACtB,IAAI,EAAE,gDAAgD;gBACtD,QAAQ,EAAE,IAAI;aACf;SACF;KACF;IACD,KAAK;QACH,iBAAiB,EAAE,CAAC;IACtB,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @fileoverview Resource — summary for a PubChem BioAssay by AID.
3
+ * @module mcp-server/resources/definitions/assay.resource
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ export declare const assayResource: import("@cyanheads/mcp-ts-core").ResourceDefinition<z.ZodObject<{
7
+ aid: z.ZodCoercedNumber<unknown>;
8
+ }, z.core.$strip>, undefined, undefined>;
9
+ //# sourceMappingURL=assay.resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assay.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/assay.resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAY,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAIrD,eAAO,MAAM,aAAa;;wCAgBxB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @fileoverview Resource — summary for a PubChem BioAssay by AID.
3
+ * @module mcp-server/resources/definitions/assay.resource
4
+ */
5
+ import { resource, z } from '@cyanheads/mcp-ts-core';
6
+ import { notFound } from '@cyanheads/mcp-ts-core/errors';
7
+ import { getPubChemClient } from '../../../services/pubchem/pubchem-client.js';
8
+ export const assayResource = resource('pubchem://assay/{aid}', {
9
+ name: 'pubchem-assay',
10
+ description: 'Summary for a PubChem BioAssay by AID (mirrors pubchem_get_summary for assays).',
11
+ mimeType: 'application/json',
12
+ params: z.object({
13
+ aid: z.coerce.number().int().positive().describe('PubChem Assay ID.'),
14
+ }),
15
+ async handler(params) {
16
+ const client = getPubChemClient();
17
+ const summary = await client.getEntitySummary('assay', params.aid);
18
+ if (!summary) {
19
+ throw notFound(`No PubChem assay found for AID ${params.aid}.`, { aid: params.aid });
20
+ }
21
+ return { aid: params.aid, summary };
22
+ },
23
+ });
24
+ //# sourceMappingURL=assay.resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assay.resource.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/assay.resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAExE,MAAM,CAAC,MAAM,aAAa,GAAG,QAAQ,CAAC,uBAAuB,EAAE;IAC7D,IAAI,EAAE,eAAe;IACrB,WAAW,EAAE,iFAAiF;IAC9F,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;KACtE,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAAM;QAClB,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QACnE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,QAAQ,CAAC,kCAAkC,MAAM,CAAC,GAAG,GAAG,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;QACvF,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC;IACtC,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @fileoverview Resource — bioassay activity profile for a compound by CID.
3
+ * @module mcp-server/resources/definitions/compound-bioactivity.resource
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ export declare const compoundBioactivityResource: import("@cyanheads/mcp-ts-core").ResourceDefinition<z.ZodObject<{
7
+ cid: z.ZodCoercedNumber<unknown>;
8
+ }, z.core.$strip>, undefined, undefined>;
9
+ //# sourceMappingURL=compound-bioactivity.resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compound-bioactivity.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/compound-bioactivity.resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAY,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAMrD,eAAO,MAAM,2BAA2B;;wCAoBtC,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @fileoverview Resource — bioassay activity profile for a compound by CID.
3
+ * @module mcp-server/resources/definitions/compound-bioactivity.resource
4
+ */
5
+ import { resource, z } from '@cyanheads/mcp-ts-core';
6
+ import { getPubChemClient } from '../../../services/pubchem/pubchem-client.js';
7
+ /** Well-studied compounds have thousands of assays — the resource read returns a head slice. */
8
+ const MAX_RESULTS = 25;
9
+ export const compoundBioactivityResource = resource('pubchem://compound/{cid}/bioactivity', {
10
+ name: 'pubchem-compound-bioactivity',
11
+ description: 'Bioassay activity profile for a PubChem compound by CID (mirrors pubchem_get_bioactivity). Returns up to 25 assays; use the tool to filter and page.',
12
+ mimeType: 'application/json',
13
+ params: z.object({
14
+ cid: z.coerce.number().int().positive().describe('PubChem Compound ID.'),
15
+ }),
16
+ async handler(params) {
17
+ const client = getPubChemClient();
18
+ const rows = await client.getAssaySummary(params.cid);
19
+ const activeCount = rows.filter((r) => r.outcome === 'Active').length;
20
+ return {
21
+ cid: params.cid,
22
+ totalAssays: rows.length,
23
+ activeCount,
24
+ results: rows.slice(0, MAX_RESULTS),
25
+ };
26
+ },
27
+ });
28
+ //# sourceMappingURL=compound-bioactivity.resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compound-bioactivity.resource.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/compound-bioactivity.resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAExE,gGAAgG;AAChG,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB,MAAM,CAAC,MAAM,2BAA2B,GAAG,QAAQ,CAAC,sCAAsC,EAAE;IAC1F,IAAI,EAAE,8BAA8B;IACpC,WAAW,EACT,sJAAsJ;IACxJ,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;KACzE,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAAM;QAClB,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACtD,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;QACtE,OAAO;YACL,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,WAAW,EAAE,IAAI,CAAC,MAAM;YACxB,WAAW;YACX,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC;SACpC,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @fileoverview Resource — a 2D structure diagram (PNG) for a compound by CID.
3
+ * @module mcp-server/resources/definitions/compound-image.resource
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ export declare const compoundImageResource: import("@cyanheads/mcp-ts-core").ResourceDefinition<z.ZodObject<{
7
+ cid: z.ZodCoercedNumber<unknown>;
8
+ }, z.core.$strip>, z.ZodObject<{
9
+ base64: z.ZodString;
10
+ }, z.core.$strip>, undefined>;
11
+ //# sourceMappingURL=compound-image.resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compound-image.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/compound-image.resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAY,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAGrD,eAAO,MAAM,qBAAqB;;;;6BAuBhC,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @fileoverview Resource — a 2D structure diagram (PNG) for a compound by CID.
3
+ * @module mcp-server/resources/definitions/compound-image.resource
4
+ */
5
+ import { resource, z } from '@cyanheads/mcp-ts-core';
6
+ import { getPubChemClient } from '../../../services/pubchem/pubchem-client.js';
7
+ export const compoundImageResource = resource('pubchem://compound/{cid}/image', {
8
+ name: 'pubchem-compound-image',
9
+ description: 'A 2D structure diagram (PNG) for a PubChem compound by CID (mirrors pubchem_get_compound_image).',
10
+ mimeType: 'image/png',
11
+ params: z.object({
12
+ cid: z.coerce.number().int().positive().describe('PubChem Compound ID.'),
13
+ }),
14
+ output: z.object({
15
+ base64: z.string().describe('Base64-encoded PNG image data.'),
16
+ }),
17
+ async handler(params) {
18
+ const client = getPubChemClient();
19
+ const buffer = await client.getImage(params.cid, 'large');
20
+ return { base64: Buffer.from(buffer).toString('base64') };
21
+ },
22
+ // Binary content: emit the PNG as a base64 blob rather than the default JSON text.
23
+ format(result, meta) {
24
+ const { base64 } = result;
25
+ return [{ uri: meta.uri.href, mimeType: meta.mimeType, blob: base64 }];
26
+ },
27
+ });
28
+ //# sourceMappingURL=compound-image.resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compound-image.resource.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/compound-image.resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAExE,MAAM,CAAC,MAAM,qBAAqB,GAAG,QAAQ,CAAC,gCAAgC,EAAE;IAC9E,IAAI,EAAE,wBAAwB;IAC9B,WAAW,EACT,kGAAkG;IACpG,QAAQ,EAAE,WAAW;IACrB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;KACzE,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;KAC9D,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAAM;QAClB,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC5D,CAAC;IAED,mFAAmF;IACnF,MAAM,CAAC,MAAM,EAAE,IAAI;QACjB,MAAM,EAAE,MAAM,EAAE,GAAG,MAA4B,CAAC;QAChD,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACzE,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @fileoverview Resource — GHS hazard classification for a compound by CID.
3
+ * @module mcp-server/resources/definitions/compound-safety.resource
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ export declare const compoundSafetyResource: import("@cyanheads/mcp-ts-core").ResourceDefinition<z.ZodObject<{
7
+ cid: z.ZodCoercedNumber<unknown>;
8
+ }, z.core.$strip>, undefined, undefined>;
9
+ //# sourceMappingURL=compound-safety.resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compound-safety.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/compound-safety.resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAY,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAGrD,eAAO,MAAM,sBAAsB;;wCAyBjC,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @fileoverview Resource — GHS hazard classification for a compound by CID.
3
+ * @module mcp-server/resources/definitions/compound-safety.resource
4
+ */
5
+ import { resource, z } from '@cyanheads/mcp-ts-core';
6
+ import { getPubChemClient } from '../../../services/pubchem/pubchem-client.js';
7
+ export const compoundSafetyResource = resource('pubchem://compound/{cid}/safety', {
8
+ name: 'pubchem-compound-safety',
9
+ description: 'GHS hazard classification for a PubChem compound by CID (mirrors pubchem_get_compound_safety).',
10
+ mimeType: 'application/json',
11
+ params: z.object({
12
+ cid: z.coerce.number().int().positive().describe('PubChem Compound ID.'),
13
+ }),
14
+ async handler(params) {
15
+ const client = getPubChemClient();
16
+ const data = await client.getSafetyData(params.cid);
17
+ if (!data)
18
+ return { cid: params.cid, hasData: false };
19
+ return {
20
+ cid: params.cid,
21
+ hasData: true,
22
+ ghs: {
23
+ signalWord: data.signalWord,
24
+ pictograms: data.pictograms,
25
+ hazardStatements: data.hazardStatements,
26
+ precautionaryStatements: data.precautionaryStatements,
27
+ },
28
+ source: data.source,
29
+ };
30
+ },
31
+ });
32
+ //# sourceMappingURL=compound-safety.resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compound-safety.resource.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/compound-safety.resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAExE,MAAM,CAAC,MAAM,sBAAsB,GAAG,QAAQ,CAAC,iCAAiC,EAAE;IAChF,IAAI,EAAE,yBAAyB;IAC/B,WAAW,EACT,gGAAgG;IAClG,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;KACzE,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAAM;QAClB,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACtD,OAAO;YACL,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,OAAO,EAAE,IAAI;YACb,GAAG,EAAE;gBACH,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;gBACvC,uBAAuB,EAAE,IAAI,CAAC,uBAAuB;aACtD;YACD,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @fileoverview Resource — external cross-references for a compound by CID.
3
+ * @module mcp-server/resources/definitions/compound-xrefs.resource
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ export declare const compoundXrefsResource: import("@cyanheads/mcp-ts-core").ResourceDefinition<z.ZodObject<{
7
+ cid: z.ZodCoercedNumber<unknown>;
8
+ }, z.core.$strip>, undefined, undefined>;
9
+ //# sourceMappingURL=compound-xrefs.resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compound-xrefs.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/compound-xrefs.resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAY,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAOrD,eAAO,MAAM,qBAAqB;;wCAoBhC,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @fileoverview Resource — external cross-references for a compound by CID.
3
+ * @module mcp-server/resources/definitions/compound-xrefs.resource
4
+ */
5
+ import { resource, z } from '@cyanheads/mcp-ts-core';
6
+ import { getPubChemClient } from '../../../services/pubchem/pubchem-client.js';
7
+ /** A focused default set for the resource read — the full tool exposes all xref types. */
8
+ const RESOURCE_XREF_TYPES = ['RN', 'RegistryID', 'PubMedID'];
9
+ const MAX_PER_TYPE = 25;
10
+ export const compoundXrefsResource = resource('pubchem://compound/{cid}/xrefs', {
11
+ name: 'pubchem-compound-xrefs',
12
+ description: 'External cross-references (CAS RN, registry IDs, PubMed) for a PubChem compound by CID (mirrors pubchem_get_compound_xrefs). Use the tool for the full set of xref types.',
13
+ mimeType: 'application/json',
14
+ params: z.object({
15
+ cid: z.coerce.number().int().positive().describe('PubChem Compound ID.'),
16
+ }),
17
+ async handler(params) {
18
+ const client = getPubChemClient();
19
+ const xrefs = [];
20
+ for (const type of RESOURCE_XREF_TYPES) {
21
+ const ids = await client.getXrefs(params.cid, type);
22
+ if (ids.length > 0) {
23
+ xrefs.push({ type, ids: ids.slice(0, MAX_PER_TYPE), totalAvailable: ids.length });
24
+ }
25
+ }
26
+ return { cid: params.cid, xrefs };
27
+ },
28
+ });
29
+ //# sourceMappingURL=compound-xrefs.resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compound-xrefs.resource.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/compound-xrefs.resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAExE,0FAA0F;AAC1F,MAAM,mBAAmB,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,UAAU,CAAU,CAAC;AACtE,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,MAAM,CAAC,MAAM,qBAAqB,GAAG,QAAQ,CAAC,gCAAgC,EAAE;IAC9E,IAAI,EAAE,wBAAwB;IAC9B,WAAW,EACT,2KAA2K;IAC7K,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;KACzE,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAAM;QAClB,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAClC,MAAM,KAAK,GAA8E,EAAE,CAAC;QAC5F,KAAK,MAAM,IAAI,IAAI,mBAAmB,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACpD,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACnB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YACpF,CAAC;QACH,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @fileoverview Resource — a compound's core physicochemical properties by CID.
3
+ * @module mcp-server/resources/definitions/compound.resource
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ export declare const compoundResource: import("@cyanheads/mcp-ts-core").ResourceDefinition<z.ZodObject<{
7
+ cid: z.ZodCoercedNumber<unknown>;
8
+ }, z.core.$strip>, undefined, undefined>;
9
+ //# sourceMappingURL=compound.resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compound.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/compound.resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAY,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAKrD,eAAO,MAAM,gBAAgB;;wCAoB3B,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @fileoverview Resource — a compound's core physicochemical properties by CID.
3
+ * @module mcp-server/resources/definitions/compound.resource
4
+ */
5
+ import { resource, z } from '@cyanheads/mcp-ts-core';
6
+ import { notFound } from '@cyanheads/mcp-ts-core/errors';
7
+ import { getPubChemClient } from '../../../services/pubchem/pubchem-client.js';
8
+ import { DEFAULT_PROPERTIES } from '../../../services/pubchem/types.js';
9
+ export const compoundResource = resource('pubchem://compound/{cid}', {
10
+ name: 'pubchem-compound',
11
+ description: 'Core physicochemical properties for a PubChem compound by CID (mirrors pubchem_get_compound_details).',
12
+ mimeType: 'application/json',
13
+ params: z.object({
14
+ cid: z.coerce.number().int().positive().describe('PubChem Compound ID.'),
15
+ }),
16
+ async handler(params) {
17
+ const client = getPubChemClient();
18
+ const rows = await client.getProperties([params.cid], [...DEFAULT_PROPERTIES]);
19
+ const row = rows[0];
20
+ // PubChem returns HTTP 200 with a {CID}-only row for a nonexistent CID — treat as not-found.
21
+ if (!row || !Object.keys(row).some((k) => k !== 'CID')) {
22
+ throw notFound(`No PubChem compound found for CID ${params.cid}.`, { cid: params.cid });
23
+ }
24
+ const { CID: _CID, ...properties } = row;
25
+ return { cid: params.cid, properties };
26
+ },
27
+ });
28
+ //# sourceMappingURL=compound.resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compound.resource.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/compound.resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,MAAM,CAAC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,0BAA0B,EAAE;IACnE,IAAI,EAAE,kBAAkB;IACxB,WAAW,EACT,uGAAuG;IACzG,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;KACzE,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAAM;QAClB,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC;QAC/E,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,6FAA6F;QAC7F,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YACvD,MAAM,QAAQ,CAAC,qCAAqC,MAAM,CAAC,GAAG,GAAG,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;QAC1F,CAAC;QACD,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,UAAU,EAAE,GAAG,GAAG,CAAC;QACzC,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,CAAC;IACzC,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @fileoverview Resource definition barrel — all PubChem MCP resources.
3
+ * @module mcp-server/resources/definitions
4
+ */
5
+ export declare const allResourceDefinitions: (import("@cyanheads/mcp-ts-core").ResourceDefinition<import("zod").ZodObject<{
6
+ aid: import("zod").ZodCoercedNumber<unknown>;
7
+ }, import("zod/v4/core").$strip>, undefined, undefined> | import("@cyanheads/mcp-ts-core").ResourceDefinition<import("zod").ZodObject<{
8
+ cid: import("zod").ZodCoercedNumber<unknown>;
9
+ }, import("zod/v4/core").$strip>, undefined, undefined> | import("@cyanheads/mcp-ts-core").ResourceDefinition<import("zod").ZodObject<{
10
+ cid: import("zod").ZodCoercedNumber<unknown>;
11
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
12
+ base64: import("zod").ZodString;
13
+ }, import("zod/v4/core").$strip>, undefined>)[];
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,eAAO,MAAM,sBAAsB;;;;;;;;+CAOlC,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @fileoverview Resource definition barrel — all PubChem MCP resources.
3
+ * @module mcp-server/resources/definitions
4
+ */
5
+ import { assayResource } from './assay.resource.js';
6
+ import { compoundResource } from './compound.resource.js';
7
+ import { compoundBioactivityResource } from './compound-bioactivity.resource.js';
8
+ import { compoundImageResource } from './compound-image.resource.js';
9
+ import { compoundSafetyResource } from './compound-safety.resource.js';
10
+ import { compoundXrefsResource } from './compound-xrefs.resource.js';
11
+ export const allResourceDefinitions = [
12
+ compoundResource,
13
+ compoundSafetyResource,
14
+ compoundImageResource,
15
+ compoundXrefsResource,
16
+ compoundBioactivityResource,
17
+ assayResource,
18
+ ];
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAErE,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,gBAAgB;IAChB,sBAAsB;IACtB,qBAAqB;IACrB,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;CACd,CAAC"}
@@ -11,6 +11,8 @@ export declare const getBioactivity: import("@cyanheads/mcp-ts-core").ToolDefini
11
11
  inactive: "inactive";
12
12
  all: "all";
13
13
  }>>;
14
+ targetGeneId: z.ZodOptional<z.ZodNumber>;
15
+ targetAccession: z.ZodOptional<z.ZodString>;
14
16
  maxResults: z.ZodDefault<z.ZodNumber>;
15
17
  }, z.core.$strip>, z.ZodObject<{
16
18
  cid: z.ZodNumber;
@@ -31,6 +33,7 @@ export declare const getBioactivity: import("@cyanheads/mcp-ts-core").ToolDefini
31
33
  }, z.core.$strip>>;
32
34
  }, z.core.$strip>, undefined, {
33
35
  readonly outcomeFilter: z.ZodString;
36
+ readonly targetFilter: z.ZodOptional<z.ZodString>;
34
37
  readonly filteredCount: z.ZodNumber;
35
38
  readonly returnedCount: z.ZodNumber;
36
39
  readonly notice: z.ZodOptional<z.ZodString>;
@@ -1 +1 @@
1
- {"version":3,"file":"get-bioactivity.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-bioactivity.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAGjD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsKzB,CAAC"}
1
+ {"version":3,"file":"get-bioactivity.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-bioactivity.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAGjD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0MzB,CAAC"}
@@ -7,7 +7,7 @@ import { tool, z } from '@cyanheads/mcp-ts-core';
7
7
  import { getPubChemClient } from '../../../services/pubchem/pubchem-client.js';
8
8
  export const getBioactivity = tool('pubchem_get_bioactivity', {
9
9
  title: 'Get Bioactivity',
10
- description: "Get a compound's bioactivity profile: which assays tested it, activity outcomes (Active/Inactive/Inconclusive), target identifiers (NCBI Gene ID, UniProt/GenBank accession), and quantitative values (IC50, EC50, Ki, etc.). Filter by outcome to focus on active results.",
10
+ description: 'Get a compound\'s bioactivity profile: which assays tested it, activity outcomes (Active/Inactive/Inconclusive), target identifiers (NCBI Gene ID, UniProt/GenBank accession), and quantitative values (IC50, EC50, Ki, etc.). Filter by outcome and/or a specific molecular target (NCBI Gene ID or protein accession) to focus the profile — e.g. "is this compound active against target T?".',
11
11
  annotations: {
12
12
  readOnlyHint: true,
13
13
  idempotentHint: true,
@@ -23,6 +23,16 @@ export const getBioactivity = tool('pubchem_get_bioactivity', {
23
23
  .enum(['active', 'inactive', 'all'])
24
24
  .default('all')
25
25
  .describe('Filter by activity outcome. "active" shows only assays where the compound showed activity — most useful for understanding biological profile. Default: "all".'),
26
+ targetGeneId: z
27
+ .number()
28
+ .int()
29
+ .positive()
30
+ .optional()
31
+ .describe('Filter to assays against this NCBI Gene ID. Obtain Gene IDs from pubchem_search_assays or the targetGeneId field of an unfiltered result here. Combine with outcomeFilter="active" to answer "is this compound active against target T?".'),
32
+ targetAccession: z
33
+ .string()
34
+ .optional()
35
+ .describe('Filter to assays against this target protein accession (UniProt/GenBank), e.g. "P35354". Obtain accessions from pubchem_search_assays or the targetAccession field of an unfiltered result here.'),
26
36
  maxResults: z
27
37
  .number()
28
38
  .min(1)
@@ -72,9 +82,13 @@ export const getBioactivity = tool('pubchem_get_bioactivity', {
72
82
  // and content[]; keys disjoint from output (cid/totalAssays live there).
73
83
  enrichment: {
74
84
  outcomeFilter: z.string().describe('Outcome filter applied: active, inactive, or all.'),
85
+ targetFilter: z
86
+ .string()
87
+ .optional()
88
+ .describe('Target filter applied (gene ID and/or protein accession), when set.'),
75
89
  filteredCount: z
76
90
  .number()
77
- .describe('Assays matching the outcome filter, before the maxResults cap.'),
91
+ .describe('Assays matching the outcome and target filters, before the maxResults cap.'),
78
92
  returnedCount: z.number().describe('Assays returned after the maxResults cap.'),
79
93
  notice: z
80
94
  .string()
@@ -86,19 +100,33 @@ export const getBioactivity = tool('pubchem_get_bioactivity', {
86
100
  const allRows = await client.getAssaySummary(input.cid);
87
101
  const activeCount = allRows.filter((r) => r.outcome === 'Active').length;
88
102
  const inactiveCount = allRows.filter((r) => r.outcome === 'Inactive').length;
89
- // Filter by outcome
103
+ // Filter by outcome, then by target — pure filters on rows already in hand
104
+ // (targetGeneId/targetAccession are populated on every row by the assay summary parser).
90
105
  let filtered = allRows;
91
106
  if (input.outcomeFilter === 'active') {
92
- filtered = allRows.filter((r) => r.outcome === 'Active');
107
+ filtered = filtered.filter((r) => r.outcome === 'Active');
93
108
  }
94
109
  else if (input.outcomeFilter === 'inactive') {
95
- filtered = allRows.filter((r) => r.outcome === 'Inactive');
110
+ filtered = filtered.filter((r) => r.outcome === 'Inactive');
111
+ }
112
+ const targetLabel = [
113
+ input.targetGeneId != null ? `GeneID:${input.targetGeneId}` : undefined,
114
+ input.targetAccession ? `accession:${input.targetAccession}` : undefined,
115
+ ]
116
+ .filter(Boolean)
117
+ .join(' ');
118
+ if (input.targetGeneId != null) {
119
+ filtered = filtered.filter((r) => r.targetGeneId === input.targetGeneId);
120
+ }
121
+ if (input.targetAccession) {
122
+ filtered = filtered.filter((r) => r.targetAccession === input.targetAccession);
96
123
  }
97
124
  const results = filtered.slice(0, input.maxResults);
98
125
  ctx.log.info('Bioactivity fetched', {
99
126
  cid: input.cid,
100
127
  total: allRows.length,
101
128
  active: activeCount,
129
+ filtered: filtered.length,
102
130
  returned: results.length,
103
131
  });
104
132
  ctx.enrich({
@@ -106,11 +134,15 @@ export const getBioactivity = tool('pubchem_get_bioactivity', {
106
134
  filteredCount: filtered.length,
107
135
  returnedCount: results.length,
108
136
  });
137
+ if (targetLabel)
138
+ ctx.enrich({ targetFilter: targetLabel });
109
139
  if (allRows.length === 0) {
110
140
  ctx.enrich.notice(`No bioactivity data found for CID ${input.cid}. The compound may be uncharacterized, or verify the CID with pubchem_search_compounds.`);
111
141
  }
112
142
  else if (filtered.length === 0) {
113
- ctx.enrich.notice(`CID ${input.cid} has ${allRows.length} assay(s) but none match outcomeFilter="${input.outcomeFilter}". Use outcomeFilter="all" to see them.`);
143
+ ctx.enrich.notice(targetLabel
144
+ ? `CID ${input.cid} has ${allRows.length} assay(s) but none match the target filter (${targetLabel})${input.outcomeFilter !== 'all' ? ` with outcomeFilter="${input.outcomeFilter}"` : ''}. Verify the target identifier appears in this compound's assays, or widen the filter.`
145
+ : `CID ${input.cid} has ${allRows.length} assay(s) but none match outcomeFilter="${input.outcomeFilter}". Use outcomeFilter="all" to see them.`);
114
146
  }
115
147
  return {
116
148
  cid: input.cid,