@cyanheads/pubchem-mcp-server 0.6.2 → 0.6.4
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/AGENTS.md +371 -0
- package/CLAUDE.md +371 -0
- package/README.md +217 -87
- package/changelog/0.1.x/0.1.21.md +23 -0
- package/changelog/0.1.x/0.1.22.md +14 -0
- package/changelog/0.1.x/0.1.23.md +18 -0
- package/changelog/0.2.x/0.2.0.md +24 -0
- package/changelog/0.2.x/0.2.1.md +14 -0
- package/changelog/0.2.x/0.2.2.md +17 -0
- package/changelog/0.2.x/0.2.3.md +27 -0
- package/changelog/0.2.x/0.2.4.md +27 -0
- package/changelog/0.3.x/0.3.0.md +31 -0
- package/changelog/0.3.x/0.3.1.md +19 -0
- package/changelog/0.4.x/0.4.0.md +15 -0
- package/changelog/0.4.x/0.4.1.md +12 -0
- package/changelog/0.4.x/0.4.2.md +41 -0
- package/changelog/0.4.x/0.4.3.md +18 -0
- package/changelog/0.5.x/0.5.0.md +24 -0
- package/changelog/0.5.x/0.5.1.md +24 -0
- package/changelog/0.5.x/0.5.2.md +21 -0
- package/changelog/0.6.x/0.6.0.md +15 -0
- package/changelog/0.6.x/0.6.1.md +40 -0
- package/changelog/0.6.x/0.6.2.md +29 -0
- package/changelog/0.6.x/0.6.3.md +40 -0
- package/changelog/0.6.x/0.6.4.md +23 -0
- package/changelog/template.md +151 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/resources/definitions/assay.resource.js +1 -1
- package/dist/mcp-server/resources/definitions/assay.resource.js.map +1 -1
- package/dist/mcp-server/resources/definitions/compound-bioactivity.resource.js +1 -1
- package/dist/mcp-server/resources/definitions/compound-bioactivity.resource.js.map +1 -1
- package/dist/mcp-server/resources/definitions/compound-image.resource.js +1 -1
- package/dist/mcp-server/resources/definitions/compound-image.resource.js.map +1 -1
- package/dist/mcp-server/resources/definitions/compound-safety.resource.js +1 -1
- package/dist/mcp-server/resources/definitions/compound-safety.resource.js.map +1 -1
- package/dist/mcp-server/resources/definitions/compound-xrefs.resource.js +1 -1
- package/dist/mcp-server/resources/definitions/compound-xrefs.resource.js.map +1 -1
- package/dist/mcp-server/resources/definitions/compound.resource.js +1 -1
- package/dist/mcp-server/resources/definitions/compound.resource.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-bioactivity.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-bioactivity.tool.js +6 -2
- package/dist/mcp-server/tools/definitions/get-bioactivity.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-compound-3d-structure.tool.d.ts +1 -0
- package/dist/mcp-server/tools/definitions/get-compound-3d-structure.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-compound-3d-structure.tool.js +6 -3
- package/dist/mcp-server/tools/definitions/get-compound-3d-structure.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-compound-details.tool.js +1 -1
- package/dist/mcp-server/tools/definitions/get-compound-details.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-compound-image.tool.d.ts +1 -0
- package/dist/mcp-server/tools/definitions/get-compound-image.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-compound-image.tool.js +4 -1
- package/dist/mcp-server/tools/definitions/get-compound-image.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-compound-interactions.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-compound-interactions.tool.js +4 -1
- package/dist/mcp-server/tools/definitions/get-compound-interactions.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-compound-safety.tool.js +1 -1
- package/dist/mcp-server/tools/definitions/get-compound-safety.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-compound-xrefs.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-compound-xrefs.tool.js +5 -1
- package/dist/mcp-server/tools/definitions/get-compound-xrefs.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/index.d.ts +4 -2
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-assays.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-assays.tool.js +3 -0
- package/dist/mcp-server/tools/definitions/search-assays.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-compounds.tool.d.ts +2 -2
- package/dist/mcp-server/tools/definitions/search-compounds.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-compounds.tool.js +8 -5
- package/dist/mcp-server/tools/definitions/search-compounds.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/untrusted-text.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/untrusted-text.js +8 -1
- package/dist/mcp-server/tools/definitions/untrusted-text.js.map +1 -1
- package/dist/services/pubchem/pubchem-client.d.ts.map +1 -1
- package/dist/services/pubchem/pubchem-client.js +51 -11
- package/dist/services/pubchem/pubchem-client.js.map +1 -1
- package/manifest.json +1 -1
- package/package.json +19 -9
- package/server.json +3 -3
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Fix silent data loss in pubchem_get_compound_safety (precautionary statements) and pubchem_get_compound_details (FDA pharmacological classification), both parsing PubChem's real shapes; add a maxSynonyms cap; correct the server assay-routing instructions; adopt mcp-ts-core ^0.10.10; clear 8 transitive security advisories"
|
|
3
|
+
breaking: false
|
|
4
|
+
security: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.3.0 — 2026-06-30
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`maxSynonyms`** — `pubchem_get_compound_details` gains an integer input (1–100, default 20) that caps the synonyms returned per compound, with a new optional **`synonymsTotal`** output reporting the full count before truncation. The structured surface was previously uncapped (697 synonyms for aspirin) and disagreed with `format()`'s 20-item view; both now share the head-of-list cap, preserving PubChem's relevance ordering. Mirrors the existing `maxDescriptions`/`descriptionsTotal` pattern. ([#24](https://github.com/cyanheads/pubchem-mcp-server/issues/24))
|
|
12
|
+
|
|
13
|
+
## Changed
|
|
14
|
+
|
|
15
|
+
- **Server `instructions`** — the target-centric routing hint pointed `pubchem_search_assays` (→ AIDs) into `pubchem_get_bioactivity`, which takes a compound `cid`, not AIDs. Reworded to the two real paths: assays-for-a-target chains `search_assays` → `pubchem_get_summary` (`entityType: assay`) per AID, and compound-active-against-a-target calls `get_bioactivity` with a `cid` plus `targetGeneId`/`targetAccession`. ([#25](https://github.com/cyanheads/pubchem-mcp-server/issues/25))
|
|
16
|
+
|
|
17
|
+
## Fixed
|
|
18
|
+
|
|
19
|
+
- **`pubchem_get_compound_safety` precautionary statements** — always returned `[]`. PubChem deposits precautionary statements as a single comma-separated P-code list (codes only, no descriptive text), which the `Pxxx: text` parser matched on neither shape. A dedicated `parsePrecautionaryCodes()` splits the list into code-only entries, preserving combined `Pxxx+Pyyy` (and triple) codes and stripping the terminal Oxford "and"; `format()` renders a bare code when no text is present. No standard P-statement text is fabricated. ([#22](https://github.com/cyanheads/pubchem-mcp-server/issues/22))
|
|
20
|
+
- **`pubchem_get_compound_details` FDA pharmacological classification** — `fdaClasses` and `fdaMechanisms` were always `[]` while MeSH classes and ATC codes in the same response parsed, because the parser gated every string on a `Pharmacological Classes:` prefix PubChem never emits. Now parses PubChem's two real shapes — individual (`<Type> [TAG] - <Name>`) and combined (`<Name> [TAG]; …`) — bucketing `EPC` → `fdaClasses` and `MoA` → `fdaMechanisms` (CS/PE have no output field). ([#23](https://github.com/cyanheads/pubchem-mcp-server/issues/23))
|
|
21
|
+
|
|
22
|
+
## Security
|
|
23
|
+
|
|
24
|
+
- Clears the 8 transitive advisories `bun audit` flagged on 0.2.4 (2 high, 6 moderate) — notably the high-severity `vite` `server.fs.deny` bypass and `hono` CORS reflecting any origin with credentials — via the lockfile re-resolve: `hono` `4.12.26 → 4.12.27`, `vite` `8.0.14 → 8.1.2`, and `js-yaml` `3.14.2 → 3.15.0` (merge-key quadratic DoS). All transitive — this server declares no direct dependency on them — and `bun audit` now reports no vulnerabilities.
|
|
25
|
+
|
|
26
|
+
## Dependencies
|
|
27
|
+
|
|
28
|
+
- `@cyanheads/mcp-ts-core` `^0.10.9 → ^0.10.10` — adopts the in-framework js-yaml v4 → v5 migration (preserves YAML 1.1 load semantics; not breaking for this server, which doesn't install js-yaml directly).
|
|
29
|
+
- `@biomejs/biome` `^2.5.0 → ^2.5.1`
|
|
30
|
+
- `@types/node` `^26.0.0 → ^26.0.1`
|
|
31
|
+
- Lockfile re-resolve also refreshed other transitive packages; the security-relevant bumps are listed under Security.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Validate CID-shaped structure queries and blank/non-numeric target queries in pubchem_search_compounds and pubchem_search_assays before the upstream call; surface identifier-mode partial-batch misses and CID collisions via a new unresolvedIdentifiers field; add an empty-result notice to pubchem_get_compound_xrefs"
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.3.1 — 2026-07-03
|
|
8
|
+
|
|
9
|
+
## Fixed
|
|
10
|
+
|
|
11
|
+
- **`pubchem_search_compounds`** — structure/similarity searches with `queryType: "cid"` accepted non-CID-shaped strings and forwarded them to PubChem, producing a raw upstream 400 instead of a typed error. Now validates the query is a positive integer before the call, throwing `invalid_cid_query` with recovery guidance. ([#26](https://github.com/cyanheads/pubchem-mcp-server/issues/26))
|
|
12
|
+
- **`pubchem_search_assays`** — a blank or whitespace-only `targetQuery` was treated as a meaningful (empty) search instead of an invalid input. Now rejects blank/whitespace `targetQuery` (`blank_target_query`) and non-numeric `geneid` queries (`invalid_geneid_query`) before the upstream call. ([#26](https://github.com/cyanheads/pubchem-mcp-server/issues/26))
|
|
13
|
+
- **`pubchem_search_compounds` identifier mode** — a partial-batch miss (some identifiers resolve, others don't) was silently dropped: `results` held only the hits, with no signal of which inputs failed. Now returns an optional **`unresolvedIdentifiers`** output field plus an enrichment notice naming the misses; an identifier resolving to an already-claimed CID emits a collision notice, and the CID's echoed identifier is now the first requester in input order (previously last-write-wins). ([#29](https://github.com/cyanheads/pubchem-mcp-server/issues/29))
|
|
14
|
+
- **`pubchem_get_compound_xrefs`** — returned bare empty arrays for both a nonexistent CID and a real compound with none of the requested xref types, with no way to tell them apart. Now emits an enrichment notice when every requested xref type returns zero IDs, pointing at CID verification. ([#30](https://github.com/cyanheads/pubchem-mcp-server/issues/30))
|
|
15
|
+
|
|
16
|
+
## Dependencies
|
|
17
|
+
|
|
18
|
+
- `@biomejs/biome` `^2.5.1 → ^2.5.2`
|
|
19
|
+
- `@types/node` `^26.0.1 → ^26.1.0`
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Add maxAtoms/maxBonds/includeRawSdf output controls with truncation disclosure to pubchem_get_compound_3d_structure; frame upstream free text (descriptions, synonyms, interaction statements, GHS text, raw SDF) as delimited data in content[] to neutralize markdown-structure injection across six tools"
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.4.0 — 2026-07-03
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`pubchem_get_compound_3d_structure`** — optional `maxAtoms`/`maxBonds` cap the atom/bond preview (default 200 each); `includeRawSdf` opts into the full raw SDF past a 500-line safe default. `atomCount`/`bondCount` always report the full totals; capping surfaces via a new `truncated`/`shownAtoms`/`shownBonds`/`atomCap`/`bondCap`/`shownSdfLines` enrichment block with a recovery notice. ([#28](https://github.com/cyanheads/pubchem-mcp-server/issues/28))
|
|
12
|
+
|
|
13
|
+
## Changed
|
|
14
|
+
|
|
15
|
+
- **Output-boundary hardening** — upstream free text (descriptions, synonyms, lineage, interaction statements, assay names, GHS hazard/precautionary statement text, raw SDF) is now framed as delimited data in `content[]` via new `inlineData`/`quoteData`/`fencedData` helpers, neutralizing markdown-structure injection from PubChem-controlled strings. Applied to `pubchem_get_compound_details`, `pubchem_get_summary`, `pubchem_get_compound_interactions`, `pubchem_get_compound_3d_structure` (SDF fencing), `pubchem_get_bioactivity`, and `pubchem_get_compound_safety`. `structuredContent` is unchanged — raw values pass through verbatim. ([#27](https://github.com/cyanheads/pubchem-mcp-server/issues/27))
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Decode GHS precautionary (P-code) statements to standard text via a new lookup table in pubchem_get_compound_safety; append the asserted uM unit to target-kind activity values in pubchem_get_compound_interactions"
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.4.1 — 2026-07-03
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- **`pubchem_get_compound_safety`** — precautionary (P-code) statements now decode to standard UN GHS Rev. 10 Annex 3 text via a new `PRECAUTIONARY_STATEMENTS` table (mirrors the existing `PICTOGRAM_LABELS` pattern); `statement` was previously always `""`. Codes with no Rev. 10 text (free-fill placeholders, deleted codes) still fall back to `""`. ([#31](https://github.com/cyanheads/pubchem-mcp-server/issues/31))
|
|
12
|
+
- **`pubchem_get_compound_interactions`** — target-kind activity values now carry the asserted `uM` unit (e.g. `"Ki = 0.0005 uM"`), grounded in PubChem's documented micromolar deposit convention; previously unitless. ([#32](https://github.com/cyanheads/pubchem-mcp-server/issues/32))
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Distinguish nonexistent CIDs from no-data compounds in pubchem_get_compound_safety; mark undecoded GHS P-codes explicitly; drop the dead severity field from pubchem_get_compound_interactions; fix two GHS-statement parsing bugs; adopt mcp-ts-core ^0.11.0"
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.4.2 — 2026-07-28
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`bunfig.toml`** — `minimumReleaseAge` (3-day supply-chain guard against freshly published package versions, excluded for `@cyanheads/mcp-ts-core`) and the Socket install scanner (`@socketsecurity/bun-security-scanner`), scanning every package before install.
|
|
12
|
+
- **`scripts/clean-mcpb.ts` / `scripts/lint-packaging.ts`** — the `.mcpb` bundle strip now also removes platform-specific native binding entries (e.g. `@duckdb/node-bindings-*`), alongside the existing agent-doc strip, so a bundle built on one platform doesn't silently ship a binding that only runs there.
|
|
13
|
+
- **`.github/SECURITY.md`**, **`.github/FUNDING.yml`**, **`.gitattributes`** — repo governance and hygiene files vendored from the mcp-ts-core scaffold.
|
|
14
|
+
|
|
15
|
+
## Changed
|
|
16
|
+
|
|
17
|
+
- **`pubchem_get_compound_safety`** — CID lookups now report a `status` of `ok`, `no_ghs_data`, or `cid_not_found` instead of a single `hasData` boolean; the notice and rendered text lead with CID-verification guidance for unrecognized CIDs, separately from the no-classification case for compounds that exist. `pubchem://compound/{cid}/safety` carries the same discriminator. ([#42](https://github.com/cyanheads/pubchem-mcp-server/issues/42))
|
|
18
|
+
- **`pubchem_get_compound_safety`** — precautionary statement entries now carry a `decoded` boolean; a P-code absent from the static lookup table (free-fill placeholder or decoder-coverage gap) renders as `(not decoded)` instead of a bare or blank statement. ([#34](https://github.com/cyanheads/pubchem-mcp-server/issues/34))
|
|
19
|
+
- **`scripts/devcheck.ts`** outdated check — no longer flags peer-dependency rows or versions held back by `minimumReleaseAge`; only packages actually behind their declared range fail the gate.
|
|
20
|
+
- **`scripts/check-dependency-specifiers.ts`** — the floating-specifier check now also scans `package.json`'s `overrides` section.
|
|
21
|
+
- `package.json` `author` field and the `LICENSE` copyright line reformatted to match the current scaffold convention.
|
|
22
|
+
|
|
23
|
+
## Removed
|
|
24
|
+
|
|
25
|
+
- **`pubchem_get_compound_interactions`** — dropped the `severity` field from the output schema, type, and formatter. No fetch path (`getDrugDrugInteractions`, `getDrugFoodInteractions`, `getTargetInteractions`) ever populated it, and the underlying `drugbankddi` SDQ collection has no severity-bearing column to project. ([#43](https://github.com/cyanheads/pubchem-mcp-server/issues/43))
|
|
26
|
+
|
|
27
|
+
## Fixed
|
|
28
|
+
|
|
29
|
+
- **GHS hazard/precautionary parsing** — `parseCodedStatement` no longer drops statements carrying a depositor-agreement percentage (`H319 (100%): ...`) or asterisk marker (`H370 **: ...`) between the code and separator, and now accepts subcategory-suffixed codes (`H350i`, `H360D`, `H361fd`) as distinct entries instead of failing the match.
|
|
30
|
+
- **GHS precautionary code parsing** — `parsePrecautionaryCodes` now scans the list for P-code shapes instead of matching each comma-split token against an anchored pattern; the anchored form silently dropped whichever code PubChem's trailing prose ("click each P-code to see the statement") was glued to, most often the final code (P501, the disposal statement).
|
|
31
|
+
|
|
32
|
+
## Dependencies
|
|
33
|
+
|
|
34
|
+
- `@cyanheads/mcp-ts-core` `^0.10.10 → ^0.11.0`
|
|
35
|
+
- `typescript` `^6.0.3 → ^7.0.2`
|
|
36
|
+
- `@biomejs/biome` `^2.5.2 → 2.5.5` (pinned exact)
|
|
37
|
+
- `@types/node` `^26.1.0 → 26.1.1` (pinned exact)
|
|
38
|
+
- `tsc-alias` `^1.8.17 → ^1.9.1`
|
|
39
|
+
- `vitest` `^4.1.9 → ^4.1.10`
|
|
40
|
+
- `ignore` `^7.0.5 → ^7.0.6`
|
|
41
|
+
- `@socketsecurity/bun-security-scanner` added `^1.1.2`
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Fix content[] truncation that hid data structuredContent already returned; fix assay/taxonomy field mapping in pubchem_get_summary; remove implementation and audience leaks from tool/resource descriptions"
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.4.3 — 2026-07-28
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- **`pubchem_get_compound_xrefs`**, **`pubchem_get_summary`**, **`pubchem_get_compound_details`** — `format()` no longer re-slices arrays that `structuredContent` already returns in full; xref IDs, gene/taxonomy synonyms and lineage, and MeSH classes now render completely instead of stopping at 20/10/3 items with a `(+N more)` note. ([#37](https://github.com/cyanheads/pubchem-mcp-server/issues/37))
|
|
12
|
+
- **`pubchem_get_compound_details`**, **`pubchem_get_summary`** — MeSH classes render one per line and synonym/lineage/array fields join on `" | "` instead of `"; "`/`", "`, so a value carrying its own comma or semicolon (CAS-inverted names, MeSH scope notes) can't be misread as an entry boundary.
|
|
13
|
+
- **Tool and resource descriptions** — removed reader-naming ("the model can reason over"), internal API-call-count framing ("one extra API call", "efficiently batches"), and maintainer shorthand ("mirrors pubchem_*") from `get-compound-3d-structure`, `get-compound-details`, and all 6 resource definitions; `pubchem://compound/{cid}/image` now states its fixed 300x300 output instead of implying tool-equivalent sizing. ([#35](https://github.com/cyanheads/pubchem-mcp-server/issues/35))
|
|
14
|
+
|
|
15
|
+
## Fixed
|
|
16
|
+
|
|
17
|
+
- **`pubchem_get_summary`** — assay summaries now read substance counts from `SIDCountAll`/`SIDCountActive` instead of keys PubChem's `assay/aid/{aid}/summary` endpoint never emits (`NumberOfSubstances`, `TotalSIDCount`, `ActiveSidCount`, `ActiveCount`), so `numSubstances`/`numActive` populate instead of silently omitting. ([#39](https://github.com/cyanheads/pubchem-mcp-server/issues/39))
|
|
18
|
+
- **`pubchem_get_summary`** — taxonomy summaries now flatten the `RankedLineage` object (most-inclusive-first, blank ranks dropped) into `lineage`, and map the top-level `Synonym` array into `synonyms`; both previously read nonexistent keys (`Lineage`, `ParentTaxList`) and stayed empty. ([#39](https://github.com/cyanheads/pubchem-mcp-server/issues/39))
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Bound pubchem_search_compounds fast searches with PubChem's MaxRecords instead of pulling the full match set, reporting a totalFoundAtLeast floor when saturated; add offset pagination to pubchem_get_bioactivity. Breaking: outputSchema.required changes on both tools."
|
|
3
|
+
breaking: true
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.5.0 — 2026-07-28
|
|
8
|
+
|
|
9
|
+
## Migration
|
|
10
|
+
|
|
11
|
+
| Tool | `outputSchema.required` before | After |
|
|
12
|
+
|:--|:--|:--|
|
|
13
|
+
| `pubchem_search_compounds` | `results`, `searchType`, `totalFound` | `totalFound` drops out of `required` (now optional). A caller reading it unconditionally must handle its absence — check the new optional `totalFoundAtLeast` instead, populated when a bounded search (`formula`/`substructure`/`superstructure`/`similarity`) saturated its cap and the exact count is unknowable. `identifier` searches are unbounded and always report an exact `totalFound`. |
|
|
14
|
+
| `pubchem_get_bioactivity` | 8 entries | Gains `offset` (9 entries). Additive and always populated on success, so no existing reader breaks — but the advertised schema changes. |
|
|
15
|
+
|
|
16
|
+
## Added
|
|
17
|
+
|
|
18
|
+
- **`pubchem_get_bioactivity`** — `offset` input paginates past the first page of filtered assay results, applied after `outcomeFilter`/`targetGeneId`/`targetAccession` and before the `maxResults` slice. Enrichment gains `offset` (now required) and an optional `nextOffset` to pass into the next call; an offset past the end of the filtered set returns an empty page with a notice instead of erroring. ([#33](https://github.com/cyanheads/pubchem-mcp-server/issues/33))
|
|
19
|
+
|
|
20
|
+
## Changed
|
|
21
|
+
|
|
22
|
+
- **`pubchem_search_compounds`** — formula, substructure, superstructure, and similarity searches now bound the upstream request with PubChem's `MaxRecords` parameter (`maxResults + 1`) instead of pulling the entire match set; a benzoic-acid substructure query that previously moved a 16.2 MB, 1,000,000-CID upstream payload now moves 316 bytes, cutting latency from 8.7s to 1.1s. `identifier` searches (name/SMILES/InChIKey) are unbounded and unaffected. See Migration for the `totalFound`/`totalFoundAtLeast` output change. ([#41](https://github.com/cyanheads/pubchem-mcp-server/issues/41))
|
|
23
|
+
- **`pubchem://compound/{cid}/bioactivity`** resource description now points at the new `offset` input instead of only mentioning `outcomeFilter`/target filtering.
|
|
24
|
+
- **`.dockerignore`**, **`vitest.config.ts`**, **`.github/ISSUE_TEMPLATE/bug_report.yml`**, **`.github/ISSUE_TEMPLATE/feature_request.yml`** — realigned to the current mcp-ts-core scaffold: `.agents` added to the Docker ignore list, `vitest.config.ts` adopts Vitest 4 `projects` (an `unit` project today, commented-out `smoke`/`fuzz`/`integration` slots for later), and both issue templates gained secondary-label guidance and dropped the `@cyanheads/` scope from their descriptions.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Add offset pagination to pubchem_get_compound_xrefs and pubchem_search_assays; add synonymOffset/descriptionOffset paging plus PUG View fan-out disclosure to pubchem_get_compound_details; fix README overclaims on synonym coverage and bioactivity paging."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.5.1 — 2026-07-28
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`pubchem_get_compound_xrefs`** — `offset` input paginates past the first page of each requested xref type; enrichment gains `offset` (required) and an optional `nextOffset`. `nextOffset`'s stride comes from a returned page's length rather than from `maxPerType`, which accepts a non-integer value that would otherwise produce a `nextOffset` the tool's own `offset` validator rejects. ([#38](https://github.com/cyanheads/pubchem-mcp-server/issues/38))
|
|
12
|
+
- **`pubchem_search_assays`** — `offset` input mirrors the paging added to `pubchem_get_bioactivity` in 0.5.0; enrichment gains `offset` (required) and an optional `nextOffset`. ([#38](https://github.com/cyanheads/pubchem-mcp-server/issues/38))
|
|
13
|
+
- **`pubchem_get_compound_details`** — `synonymOffset` and `descriptionOffset` inputs page each compound's synonym/description list at a shared batch-wide offset; enrichment gains optional `synonymOffset`/`nextSynonymOffset` and `descriptionOffset`/`nextDescriptionOffset`. ([#38](https://github.com/cyanheads/pubchem-mcp-server/issues/38))
|
|
14
|
+
- **`pubchem_get_compound_details`** — the PUG View fan-out cap (10 CIDs per call, for `includeDescription`/`includeClassification`) is now disclosed via enrichment: `enrichedCids` and `skippedCids` list which CIDs were and weren't fetched, with a notice explaining a skipped CID's absent description means "not requested," not "PubChem has none." Previously only logged, never surfaced to the caller. ([#40](https://github.com/cyanheads/pubchem-mcp-server/issues/40))
|
|
15
|
+
|
|
16
|
+
## Changed
|
|
17
|
+
|
|
18
|
+
- **`pubchem_get_compound_xrefs`**, **`pubchem_search_assays`**, **`pubchem_get_compound_details`** — tool/input descriptions and `format()` output reworded from "capped"/"truncated" to page-relative language ("this page", "past this page") now that offset paging exists alongside the existing caps.
|
|
19
|
+
- **`pubchem://compound/{cid}/xrefs`** resource description now mentions `pubchem_get_compound_xrefs`'s `offset` paging.
|
|
20
|
+
- **README** — dropped the "all known synonyms" overclaim (synonyms are paged, not exhaustive), clarified the synonym/description paging behavior, and reworded the bioactivity bullet to mention `offset` instead of implying a hard 100-result cap.
|
|
21
|
+
|
|
22
|
+
## Fixed
|
|
23
|
+
|
|
24
|
+
- **`pubchem_get_compound_xrefs`** — the empty-result notice previously fired whenever every requested type's returned page was empty, which misfired when an `offset` simply ran past the data; it now distinguishes a genuinely empty compound (`totalAvailable === 0` for every type) from an offset past the end (a dedicated notice naming the largest available total).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Add offset pagination to pubchem_search_compounds and pubchem_get_compound_interactions, completing #38; switch the interactions SDQ query to a select projection for exact per-kind totals."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.5.2 — 2026-07-28
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`pubchem_search_compounds`** — `offset` input (0–10000) pages CIDs past `maxResults`; enrichment gains `offset` (required) and an optional `nextOffset`. Identifier-mode paging re-slices the already-resolved CID set; the bounded formula/substructure/superstructure/similarity searches widen the upstream record window to `offset + maxResults + 1` to reach a page, so deep pages cost progressively more upstream. ([#38](https://github.com/cyanheads/pubchem-mcp-server/issues/38))
|
|
12
|
+
- **`pubchem_get_compound_interactions`** — `offset` input (0–2147483646, the upstream `start` cursor's signed-32-bit ceiling) pages each requested kind past `maxEntries`. Output gains a `paging` array (one entry per resolved kind: `kind`, `returnedCount`, `totalRecords`, optional `nextOffset`, `truncated`); enrichment gains `offset` (required) and `nextOffset` (reported only when exactly one requested kind still has records remaining — with more than one, read `paging[].nextOffset` instead). ([#38](https://github.com/cyanheads/pubchem-mcp-server/issues/38))
|
|
13
|
+
|
|
14
|
+
## Changed
|
|
15
|
+
|
|
16
|
+
- **`pubchem_search_compounds`** — tool/input descriptions and notices reworded from "raise maxResults" to offset-paging language; an empty page now distinguishes "nothing matched" from "the offset ran past the matches" and names the bound to page back inside.
|
|
17
|
+
- **`pubchem_get_compound_interactions`**'s `target` kind switched its SDQ query from a `download` to a `select` projection, returning an exact per-kind `totalRecords` in the same round trip instead of inferring a floor from a saturated window. A side effect: some rows that rendered their activity value in exponential notation under `download` (e.g. `1e-06`) now render as a plain decimal (`0.000001`) — the underlying number is unchanged, with no precision or trailing-zero loss.
|
|
18
|
+
- **`pubchem_get_compound_interactions`**'s `fetchSdq` now also treats a `status.error` inside a 2xx SDQ response body as a rejection, alongside the existing non-2xx handling, so a malformed query can't read as an empty page if SDQ ever wraps a rejection in a 200.
|
|
19
|
+
- **README** — documents both tools' new `offset` ceilings and the interactions tool's per-kind paging.
|
|
20
|
+
|
|
21
|
+
Completes [#38](https://github.com/cyanheads/pubchem-mcp-server/issues/38).
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Constrain four per-page cap inputs to integers, rejecting fractional values that were previously silently floored or forwarded upstream."
|
|
3
|
+
breaking: true
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.6.0 — 2026-07-28
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- **`pubchem_get_compound_xrefs`**'s `maxPerType`, **`pubchem_search_assays`**'s `maxResults`, **`pubchem_get_bioactivity`**'s `maxResults`, and **`pubchem_search_compounds`**'s `maxResults` now advertise `integer` instead of an unconstrained `number`. All nine cap inputs across the server (these four plus the already-integer `maxSynonyms`, `maxDescriptions`, `maxAtoms`, `maxBonds`, `maxEntries`) now advertise `integer` consistently. ([#44](https://github.com/cyanheads/pubchem-mcp-server/issues/44))
|
|
12
|
+
|
|
13
|
+
**Migration:** a call passing a fractional value to any of the four inputs above now fails input validation instead of succeeding. Previously, `pubchem_get_compound_xrefs.maxPerType`, `pubchem_search_assays.maxResults`, and `pubchem_get_bioactivity.maxResults` silently floored a fractional cap via `Array.prototype.slice`, returning fewer results than the schema implied without any error. `pubchem_search_compounds.maxResults` is a narrower case: for formula, substructure, superstructure, and similarity searches the handler derives the upstream record window directly from this input, so a fractional value previously reached PubChem verbatim and the call already failed — with an upstream HTTP 400 rather than a local validation error. For that one input the change moves an existing failure earlier and makes it legible; for the other three it is a new rejection where a call previously succeeded. Round every value passed to these four inputs to a whole number before calling.
|
|
14
|
+
|
|
15
|
+
Completes [#44](https://github.com/cyanheads/pubchem-mcp-server/issues/44).
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Adopts mcp-ts-core ^0.12.3 and MCP SDK v2 — tool arguments are strict and the advertised schemas change shape — and three tools gain a top-level `truncated` flag in their enrichment."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.6.1 — 2026-08-21
|
|
8
|
+
|
|
9
|
+
Every wire-level change below comes from the framework bump; no tool's own input or output contract changed.
|
|
10
|
+
|
|
11
|
+
## Added
|
|
12
|
+
|
|
13
|
+
- **`truncated`** — a required boolean in the enrichment of `pubchem_get_compound_xrefs`, `pubchem_get_compound_interactions`, and `pubchem_get_compound_details`, stating at the top level that the response is not the whole set. The per-item detail stays where it was (`xrefs[].truncated`, `paging[].truncated`, `compounds[].synonymsTotal`); on `pubchem_get_compound_details` the flag also covers the PUG View fan-out cap, so a response with skipped CIDs reads as incomplete even when no list was paged.
|
|
14
|
+
- **`.github/CONTRIBUTING.md`** and **`.github/CODE_OF_CONDUCT.md`** — community-health files from the mcp-ts-core scaffold.
|
|
15
|
+
|
|
16
|
+
## Changed
|
|
17
|
+
|
|
18
|
+
- **Tool arguments are strict.** An argument key a tool does not declare is rejected by name instead of being silently stripped, and every advertised `inputSchema` carries `additionalProperties: false`. Root level only — a nested object still strips.
|
|
19
|
+
- **The advertised `outputSchema` declares the error envelope.** Success fields become optional and `error` is declared, so a client that validates `structuredContent` without checking `isError` no longer rejects an error result with `-32602`.
|
|
20
|
+
- **Advertised JSON Schema is 2020-12**, not draft-07.
|
|
21
|
+
- **`ctx.log` output reaches the client** as `notifications/message`, gated by the client's `logging/setLevel`.
|
|
22
|
+
- **The Docker build stage is pinned to `$BUILDPLATFORM`** ([cyanheads/mcp-ts-core#370](https://github.com/cyanheads/mcp-ts-core/issues/370)). Bun 1.4.0's JavaScriptCore aborts under QEMU, so the cross-architecture half of a multi-arch build failed on an arm64 host; the stage emits platform-independent JavaScript and only `dist/` is copied forward, so building it natively is equivalent.
|
|
23
|
+
- **Bun pins move to 1.4.0** — both `Dockerfile` stages and `packageManager`. `engines.bun` stays `>=1.3.0`.
|
|
24
|
+
- **The production Docker install omits optional peers** — `--omit=peer` on both the `bun install` and the OpenTelemetry `bun add`, so the runtime image no longer carries the framework's opt-in tiers.
|
|
25
|
+
- **`tsconfig.json` typechecks `tests/`.** It now covers `src/` and `tests/` with `noEmit`, and `tsconfig.build.json` carries the emit path (`rootDir: src`).
|
|
26
|
+
- **Security reports route to `security@caseyjhand.com`** (`.github/SECURITY.md`).
|
|
27
|
+
- **`PubChemClient`** raises its two SDQ failures through the `serviceUnavailable()` factory instead of constructing `McpError` directly.
|
|
28
|
+
- Internal tooling tracked the framework: `scripts/lint-packaging.ts` checks `@modelcontextprotocol/server` as the runtime-critical path, and `scripts/lint-mcp.ts` dropped its task-definition branch.
|
|
29
|
+
|
|
30
|
+
## Fixed
|
|
31
|
+
|
|
32
|
+
- **`bun run tree` honors directory-only gitignore patterns.** `.claude/` and its siblings were listed in `docs/tree.md` despite being ignored — `ignore` reads a trailing slash off the tested path, which `isIgnored` never supplied.
|
|
33
|
+
|
|
34
|
+
## Dependencies
|
|
35
|
+
|
|
36
|
+
- `@cyanheads/mcp-ts-core` `^0.11.0 → ^0.12.3` — MCP SDK v2: the framework now builds on `@modelcontextprotocol/server` `^2.0.0` in place of `@modelcontextprotocol/sdk` `^1.x`
|
|
37
|
+
- `@biomejs/biome` `2.5.5 → 2.5.9`
|
|
38
|
+
- `@types/node` `26.1.1 → 26.2.0`
|
|
39
|
+
- `tsc-alias` `^1.9.1 → ^1.9.2`
|
|
40
|
+
- `vitest` `^4.1.10 → ^4.1.11`
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Framework adoption and HTTP retry handling"
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.6.2 — 2026-09-13
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- **HTTP deployments default to stateless sessions** in the published server metadata and example configuration; PubChem tools do not require multi-request session state.
|
|
12
|
+
- **Framework development skills moved to `framework-skills/`** with package checks, contributor links, and generated tree documentation updated for the new location.
|
|
13
|
+
- **Empty and whole-value placeholder environment variables now resolve as unset** through `@cyanheads/mcp-ts-core`, so optional values remain absent and defaulted values use their schema defaults.
|
|
14
|
+
- **Invalid tool arguments return a structured `InvalidParams` error** through the framework's current JSON-RPC error path.
|
|
15
|
+
- **Project metadata and local gates track the current framework templates**, including plugin validation, issue forms, Bun 1.4 support, and Vitest 5.
|
|
16
|
+
|
|
17
|
+
## Fixed
|
|
18
|
+
|
|
19
|
+
- **PubChem HTTP retries honor framework retry classification**: an upstream 500 retries once, while a 501 marked `retryable: false` fails immediately.
|
|
20
|
+
|
|
21
|
+
## Dependencies
|
|
22
|
+
|
|
23
|
+
- `@cyanheads/mcp-ts-core` ^0.12.3 → ^0.13.0
|
|
24
|
+
- `zod` ^4.4.3 → ^4.6.1
|
|
25
|
+
- `@biomejs/biome` 2.5.9 → 2.5.13
|
|
26
|
+
- `@types/node` 26.2.0 → 26.5.1
|
|
27
|
+
- `ignore` ^7.0.6 → ^7.0.9
|
|
28
|
+
- `tsc-alias` ^1.9.2 → ^1.9.4
|
|
29
|
+
- `vitest` ^4.1.11 → ^5.0.0
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Adopts mcp-ts-core through 0.13.6: input aliases on four tools, a declared stateless session mode, structured argument-rejection errors, and CodeQL fixes for regex backtracking and an upstream URL leak in error data."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.6.3 — 2026-09-19
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`sessionMode: 'stateless'` declared in `src/index.ts`** — with `MCP_SESSION_MODE` unset the HTTP transport serves stateless; an exported `MCP_SESSION_MODE` value still overrides the declaration.
|
|
12
|
+
- **`GET /.well-known/mcp.json` reports the resolved session mode** under `_meta["io.github.cyanheads.mcp-ts-core/sessionMode"]`.
|
|
13
|
+
- **`inputAliases` on four tools** — `pubchem_search_assays` accepts `query`/`target` for `targetQuery`, `pubchem_get_compound_xrefs` accepts `maxResults` for `maxPerType`, `pubchem_get_compound_interactions` accepts `maxResults` for `maxEntries`, and `pubchem_get_bioactivity` accepts `geneId`/`accession` for `targetGeneId`/`targetAccession`. Advertised `inputSchema` is unchanged.
|
|
14
|
+
|
|
15
|
+
## Changed
|
|
16
|
+
|
|
17
|
+
- **A rejected tool argument answers `-32602`** with `data.reason: "invalid_arguments"`, a `data.recovery.hint` naming the accepted keys, and a matching `Recovery:` line in `content[0].text`.
|
|
18
|
+
- **`thrownBy: 'service'`** on the `cid_not_found` and `no_3d_structure` error contract reasons, which the service layer raises.
|
|
19
|
+
- **`.env.example` and the README config table now match the current framework scaffold** — session mode, resumability, body cap, public URL, and memory settings; the port comment corrected to `3010`.
|
|
20
|
+
- **CLAUDE.md gains an `AGENTS.md` twin** and documents the gated release-PR flow; both files, plus `changelog/`, now ship in the npm package.
|
|
21
|
+
- **CodeQL workflow added** (`.github/workflows/codeql.yml`) — the one GitHub Actions workflow this server carries; local gates cover the rest.
|
|
22
|
+
- **22 framework skills and 6 dev scripts re-synced** from `@cyanheads/mcp-ts-core` 0.13.1–0.13.6.
|
|
23
|
+
|
|
24
|
+
## Fixed
|
|
25
|
+
|
|
26
|
+
- **`untrusted-text`'s inline escaping covers a lone backslash**, so an upstream `\*` cannot re-arm as a live `*` after escaping, and a SMILES stereo bond (`C/C=C\C`) no longer ends its line as a CommonMark hard break.
|
|
27
|
+
- **GHS statement parsing (`parseCodedStatement`) matches an annotated code in linear time** — a code followed by a long run of `*` no longer backtracks exponentially; the same statements still parse.
|
|
28
|
+
|
|
29
|
+
## Security
|
|
30
|
+
|
|
31
|
+
- **Upstream PubChem error data no longer carries the request URL**, which echoed the caller's own query (a name, SMILES string, or SDQ blob). The message still names PubChem and the HTTP status, and `data.fault` still carries PubChem's parsed fault text.
|
|
32
|
+
|
|
33
|
+
## Dependencies
|
|
34
|
+
|
|
35
|
+
- `@cyanheads/mcp-ts-core` ^0.13.0 → ^0.13.6
|
|
36
|
+
- `zod` ^4.6.1 → ^4.6.5
|
|
37
|
+
- `@biomejs/biome` 2.5.13 → 2.5.14
|
|
38
|
+
- `@types/node` 26.5.1 → 26.6.1
|
|
39
|
+
- `tsc-alias` ^1.9.4 → ^1.9.5
|
|
40
|
+
- `vitest` ^5.0.0 → ^5.0.1
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "pubchem_search_compounds names each mode's required fields and rejects a blank formula or query before calling PubChem, failed PubChem requests log their URL server-side, and integer inputs advertise minimum: 1 instead of exclusiveMinimum."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.6.4 — 2026-09-24
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **Failed PubChem requests log the request URL server-side** ([#50](https://github.com/cyanheads/pubchem-mcp-server/issues/50)) — one module `logger` line per failure after any retry, carrying `url`, `method`, and the HTTP `status` and `fault` or the error message: `debug` for a 404, `warning` for any other non-2xx, a network error, a 30 s timeout, or an SDQ rejection inside a 2xx. The client-facing `error.data` still carries no URL.
|
|
12
|
+
|
|
13
|
+
## Fixed
|
|
14
|
+
|
|
15
|
+
- **`pubchem_search_compounds` `searchType` names each mode's required fields** ([#45](https://github.com/cyanheads/pubchem-mcp-server/issues/45)) — identifier needs `identifierType` + `identifiers`, formula needs `formula`, substructure/superstructure/similarity need `query` + `queryType`. The input root stays a flat object.
|
|
16
|
+
- **A whitespace-only `formula` or `query` fails as `missing_formula` / `missing_structure_args`** before any PubChem request, instead of returning unrelated compounds or an upstream HTTP 500. A padded formula such as `" C9H8O4 "` still resolves.
|
|
17
|
+
- **Integer inputs use `.min(1)` instead of `.positive()`** ([#51](https://github.com/cyanheads/pubchem-mcp-server/issues/51)) — ten inputs across seven tools now advertise `minimum: 1` rather than a numeric `exclusiveMinimum`, which Microsoft Copilot Studio fails to parse; accepted values are unchanged. The six resource templates' `cid`/`aid` params match.
|
|
18
|
+
- **README VS Code install badge** URL-encodes the `/` in `@cyanheads/pubchem-mcp-server`.
|
|
19
|
+
|
|
20
|
+
## Dependencies
|
|
21
|
+
|
|
22
|
+
- `@socketsecurity/bun-security-scanner` ^1.1.2 → ^1.1.3
|
|
23
|
+
- `@types/node` 26.6.1 → 26.6.2
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
# FORMAT REFERENCE — do not edit. Copy this file to
|
|
3
|
+
# `changelog/<major.minor>.x/<version>.md` (e.g. `changelog/0.8.x/0.8.6.md`)
|
|
4
|
+
# to author a new release. Set that file's H1 to `# <version> — YYYY-MM-DD`
|
|
5
|
+
# with a concrete date.
|
|
6
|
+
|
|
7
|
+
# Required. One-line GitHub Release-style headline. 350 character cap — a
|
|
8
|
+
# ceiling, not a target. Default short and scannable. Don't pad, don't stitch
|
|
9
|
+
# unrelated changes with commas/semicolons into an inventory — pick the one
|
|
10
|
+
# headline the release is about. Quotes required: unquoted YAML treats
|
|
11
|
+
# `: ` inside the value as a key separator and fails GitHub's strict parser.
|
|
12
|
+
summary: ""
|
|
13
|
+
|
|
14
|
+
# Set `true` when consumers must change code to upgrade: API removals,
|
|
15
|
+
# signature changes, config renames, behavior changes that break existing
|
|
16
|
+
# usage. Flagged as `Breaking` in the rollup.
|
|
17
|
+
breaking: false
|
|
18
|
+
|
|
19
|
+
# Set `true` ONLY for a security fix in THIS project's own source code — a
|
|
20
|
+
# vulnerability or hardening in code you ship. A dependency or transitive CVE
|
|
21
|
+
# bump is routine maintenance, NOT a security release: record it under
|
|
22
|
+
# `## Dependencies` (with the advisory ID) and leave this `false`. When true,
|
|
23
|
+
# pairs with the `## Security` section below and flags `Security` in the rollup.
|
|
24
|
+
security: false
|
|
25
|
+
|
|
26
|
+
# Optional free-form notes for maintenance agents processing this release.
|
|
27
|
+
# Not rendered in CHANGELOG — consumed by agents running `maintenance` on
|
|
28
|
+
# downstream servers. ADOPTION STEPS ONLY — new files to create, fields to
|
|
29
|
+
# populate, one-time migration steps. Never a second rendering of the body:
|
|
30
|
+
# if a body bullet already says it, name the bullet's symbol instead of
|
|
31
|
+
# re-explaining. Omit the field entirely when there's nothing to say.
|
|
32
|
+
# agent-notes: |
|
|
33
|
+
# <instructions for downstream maintenance agents>
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
# <version> — YYYY-MM-DD
|
|
37
|
+
|
|
38
|
+
<!--
|
|
39
|
+
AUTHORING GUIDE — applies to the new per-version file you create from this
|
|
40
|
+
template.
|
|
41
|
+
|
|
42
|
+
Audience: someone scanning release notes to decide what affects them. Lead
|
|
43
|
+
each bullet with the symbol or concept name in **bold** so they can skip
|
|
44
|
+
what's irrelevant and zoom in on what's not.
|
|
45
|
+
|
|
46
|
+
Tone: terse, fact-dense, not verbose. Bullet shape: **symbol** + what
|
|
47
|
+
changed + at most one consumer-facing caveat. One sentence by default, two
|
|
48
|
+
when the second carries weight — a bullet past ~40 words or three sentences
|
|
49
|
+
is wrong. The depth lives one hop away: the linked issue carries the why,
|
|
50
|
+
the commit diff carries the how. The changelog names what changed and what
|
|
51
|
+
a consumer does about it; a reader who wants mechanism opens the link.
|
|
52
|
+
|
|
53
|
+
Model length on THIS guide, never on the previous entry — entries modeled
|
|
54
|
+
on entries compound.
|
|
55
|
+
|
|
56
|
+
Cut (each has shipped as a wall of text; these are the cruft):
|
|
57
|
+
- History/justification narration — how the bug worked, why the old
|
|
58
|
+
behavior was wrong. One short clause at most; the issue carries the story.
|
|
59
|
+
- Design-rationale defense — "chosen over Y because…", "guarding the
|
|
60
|
+
getter is not enough…". That is the author arguing with a reviewer;
|
|
61
|
+
reviewers read the PR, not the changelog.
|
|
62
|
+
- Defensive unchanged-clauses — "X is unchanged", "byte-identical to
|
|
63
|
+
<prev>". Keep one only where its absence would cause a real misread,
|
|
64
|
+
as a short parenthetical.
|
|
65
|
+
- Edge-case inventories — marker lists, not-flagged lists, escape tables.
|
|
66
|
+
Tests and the issue carry those.
|
|
67
|
+
- Mechanism walkthroughs (JSDoc, CLAUDE.md/AGENTS.md, or the relevant
|
|
68
|
+
skill own those), ceremonial framings ("This release introduces…"),
|
|
69
|
+
backwards-compat paragraphs, file-by-file test enumerations. Prefer
|
|
70
|
+
code/symbol names over English re-explanations.
|
|
71
|
+
|
|
72
|
+
Verified ≠ included: the every-claim-verified-from-the-diff rule bounds
|
|
73
|
+
the TRUTH of what you write, never the AMOUNT.
|
|
74
|
+
|
|
75
|
+
Example — same fact, right size:
|
|
76
|
+
|
|
77
|
+
TOO LONG: **`fetchWithTimeout`'s `timeoutMs` bounds the whole exchange**
|
|
78
|
+
(#341). `fetch` resolves once headers arrive and the deadline was
|
|
79
|
+
cleared as the helper returned, so a peer that answered promptly and
|
|
80
|
+
then stalled the stream held the request open indefinitely. A 2xx
|
|
81
|
+
carrying a body now comes back as a passthrough wrapper that disarms
|
|
82
|
+
the deadline when the body closes, errors, or is cancelled; …
|
|
83
|
+
[+90 more words of mechanism and edge cases]
|
|
84
|
+
|
|
85
|
+
RIGHT: **`fetchWithTimeout`'s `timeoutMs` now bounds the whole
|
|
86
|
+
exchange, not just the headers** (#341). A stalled body aborts with
|
|
87
|
+
the same `Timeout` error; the returned `Response` is a wrapper, so
|
|
88
|
+
identity assertions (`toBe(response)`) no longer hold.
|
|
89
|
+
|
|
90
|
+
Narrative intro: skip by default. Add one short sentence only when the
|
|
91
|
+
release theme genuinely needs framing the bullets can't carry. When many
|
|
92
|
+
bullets share one upgrade consequence, state it ONCE — intro line or
|
|
93
|
+
agent-notes — never per bullet.
|
|
94
|
+
|
|
95
|
+
Sections: Keep a Changelog order — Added, Changed, Deprecated, Removed,
|
|
96
|
+
Fixed, Security. Include only sections with entries; delete the rest
|
|
97
|
+
(including the commented-out scaffolding below). Don't ship empty headers.
|
|
98
|
+
|
|
99
|
+
Include: every distinct fact a reader needs to adopt or audit the release —
|
|
100
|
+
new exports, signatures, lint rule IDs, env vars, breaking changes, version
|
|
101
|
+
bumps on shipped skills. Nothing more.
|
|
102
|
+
|
|
103
|
+
Links: link issues, PRs, docs, or skills where they help a reader jump to
|
|
104
|
+
context. Once per item per entry — don't re-link the same issue in summary,
|
|
105
|
+
narrative, and bullet. Skip links for inline symbol names; code spans speak
|
|
106
|
+
for themselves.
|
|
107
|
+
|
|
108
|
+
Issue/PR URLs: use full URLs. GitHub's bare `#NN` auto-link only resolves
|
|
109
|
+
inside its own UI, not in npm reads or local editors.
|
|
110
|
+
|
|
111
|
+
[#38](https://github.com/cyanheads/mcp-ts-core/issues/38) ← issue
|
|
112
|
+
[#42](https://github.com/cyanheads/mcp-ts-core/pull/42) ← PR
|
|
113
|
+
|
|
114
|
+
Verify numbers exist before linking (`gh issue view NN`, `gh pr view NN`).
|
|
115
|
+
Never speculate on a future number — `#42` for an upcoming PR silently
|
|
116
|
+
resolves to whatever real item already owns 42, and timeline previews pull
|
|
117
|
+
in that unrelated item's metadata.
|
|
118
|
+
|
|
119
|
+
TAG ANNOTATIONS — the annotated tag body renders as the GitHub Release body
|
|
120
|
+
via `gh release create --notes-from-tag`. It is a condensed digest of this
|
|
121
|
+
entry, never a copy, and its format is owned by the `release-and-publish`
|
|
122
|
+
skill (step 4, "Create the annotated tag"): a short subject line without the
|
|
123
|
+
version, flat headline bullets — no Keep-a-Changelog section headers, no
|
|
124
|
+
gates line — at most one deps line, issue backlinks, and the changelog link
|
|
125
|
+
last. In release-PR mode the `git-wrapup` skill authors those bullets as the
|
|
126
|
+
PR body's `## Changes` and the tag copies them.
|
|
127
|
+
-->
|
|
128
|
+
|
|
129
|
+
## Added
|
|
130
|
+
|
|
131
|
+
-
|
|
132
|
+
|
|
133
|
+
## Changed
|
|
134
|
+
|
|
135
|
+
-
|
|
136
|
+
|
|
137
|
+
<!-- ## Deprecated
|
|
138
|
+
|
|
139
|
+
- -->
|
|
140
|
+
|
|
141
|
+
<!-- ## Removed
|
|
142
|
+
|
|
143
|
+
- -->
|
|
144
|
+
|
|
145
|
+
## Fixed
|
|
146
|
+
|
|
147
|
+
-
|
|
148
|
+
|
|
149
|
+
<!-- ## Security
|
|
150
|
+
|
|
151
|
+
- -->
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,10 @@ import { initPubChemClient } from './services/pubchem/pubchem-client.js';
|
|
|
11
11
|
await createApp({
|
|
12
12
|
name: 'pubchem-mcp-server',
|
|
13
13
|
title: 'pubchem-mcp-server',
|
|
14
|
+
/** No tool gates on `ctx.requestInput`, so nothing here needs a session to survive
|
|
15
|
+
* between round trips. Declared in code rather than left to `MCP_SESSION_MODE` so a
|
|
16
|
+
* deployment that never sets the variable still serves statelessly. */
|
|
17
|
+
sessionMode: 'stateless',
|
|
14
18
|
tools: allToolDefinitions,
|
|
15
19
|
resources: allResourceDefinitions,
|
|
16
20
|
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. To find assays for a biological target, chain `pubchem_search_assays` (gene/protein → AIDs) into `pubchem_get_summary` (`entityType: assay`) per AID; to check whether a compound is active against a target, call `pubchem_get_bioactivity` with a `cid` plus `targetGeneId`/`targetAccession`. `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}`).",
|
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,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,IAAI,EAAE,oBAAoB;IAC1B,KAAK,EAAE,oBAAoB;IAC3B,KAAK,EAAE,kBAAkB;IACzB,SAAS,EAAE,sBAAsB;IACjC,YAAY,EACV,q3BAAq3B;IACv3B,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,IAAI,EAAE,oBAAoB;IAC1B,KAAK,EAAE,oBAAoB;IAC3B;;2EAEuE;IACvE,WAAW,EAAE,WAAW;IACxB,KAAK,EAAE,kBAAkB;IACzB,SAAS,EAAE,sBAAsB;IACjC,YAAY,EACV,q3BAAq3B;IACv3B,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"}
|
|
@@ -10,7 +10,7 @@ export const assayResource = resource('pubchem://assay/{aid}', {
|
|
|
10
10
|
description: 'Summary for a PubChem BioAssay by AID — name, description, source, protocol, and substance counts.',
|
|
11
11
|
mimeType: 'application/json',
|
|
12
12
|
params: z.object({
|
|
13
|
-
aid: z.coerce.number().int().
|
|
13
|
+
aid: z.coerce.number().int().min(1).describe('PubChem Assay ID.'),
|
|
14
14
|
}),
|
|
15
15
|
async handler(params) {
|
|
16
16
|
const client = getPubChemClient();
|
|
@@ -1 +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,EACT,oGAAoG;IACtG,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,
|
|
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,EACT,oGAAoG;IACtG,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC;KAClE,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"}
|
|
@@ -11,7 +11,7 @@ export const compoundBioactivityResource = resource('pubchem://compound/{cid}/bi
|
|
|
11
11
|
description: 'Bioassay activity profile for a PubChem compound by CID. Returns up to 25 assays; use pubchem_get_bioactivity to filter by outcome or molecular target, raise the cap, and page through the rest with offset.',
|
|
12
12
|
mimeType: 'application/json',
|
|
13
13
|
params: z.object({
|
|
14
|
-
cid: z.coerce.number().int().
|
|
14
|
+
cid: z.coerce.number().int().min(1).describe('PubChem Compound ID.'),
|
|
15
15
|
}),
|
|
16
16
|
async handler(params) {
|
|
17
17
|
const client = getPubChemClient();
|
|
@@ -1 +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,+MAA+M;IACjN,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,
|
|
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,+MAA+M;IACjN,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC;KACrE,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"}
|
|
@@ -9,7 +9,7 @@ export const compoundImageResource = resource('pubchem://compound/{cid}/image',
|
|
|
9
9
|
description: 'A 2D structure diagram (PNG, 300x300) for a PubChem compound by CID. Use pubchem_get_compound_image to choose the image size.',
|
|
10
10
|
mimeType: 'image/png',
|
|
11
11
|
params: z.object({
|
|
12
|
-
cid: z.coerce.number().int().
|
|
12
|
+
cid: z.coerce.number().int().min(1).describe('PubChem Compound ID.'),
|
|
13
13
|
}),
|
|
14
14
|
output: z.object({
|
|
15
15
|
base64: z.string().describe('Base64-encoded PNG image data.'),
|
|
@@ -1 +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,+HAA+H;IACjI,QAAQ,EAAE,WAAW;IACrB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,
|
|
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,+HAA+H;IACjI,QAAQ,EAAE,WAAW;IACrB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC;KACrE,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"}
|