@cyanheads/protein-mcp-server 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/AGENTS.md +44 -20
  2. package/CLAUDE.md +44 -20
  3. package/README.md +76 -88
  4. package/changelog/0.8.x/0.8.1.md +29 -0
  5. package/changelog/0.8.x/0.8.2.md +24 -0
  6. package/changelog/template.md +9 -26
  7. package/dist/index.js +3 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/mcp-server/tools/definitions/analyze-collection.tool.d.ts.map +1 -1
  10. package/dist/mcp-server/tools/definitions/analyze-collection.tool.js +4 -16
  11. package/dist/mcp-server/tools/definitions/analyze-collection.tool.js.map +1 -1
  12. package/dist/mcp-server/tools/definitions/compare-structures.tool.d.ts.map +1 -1
  13. package/dist/mcp-server/tools/definitions/compare-structures.tool.js +2 -15
  14. package/dist/mcp-server/tools/definitions/compare-structures.tool.js.map +1 -1
  15. package/dist/mcp-server/tools/definitions/find-similar.tool.d.ts +5 -0
  16. package/dist/mcp-server/tools/definitions/find-similar.tool.d.ts.map +1 -1
  17. package/dist/mcp-server/tools/definitions/find-similar.tool.js +6 -0
  18. package/dist/mcp-server/tools/definitions/find-similar.tool.js.map +1 -1
  19. package/dist/mcp-server/tools/definitions/get-annotations.tool.d.ts.map +1 -1
  20. package/dist/mcp-server/tools/definitions/get-annotations.tool.js +2 -11
  21. package/dist/mcp-server/tools/definitions/get-annotations.tool.js.map +1 -1
  22. package/dist/mcp-server/tools/definitions/search-structures.tool.d.ts.map +1 -1
  23. package/dist/mcp-server/tools/definitions/search-structures.tool.js +1 -9
  24. package/dist/mcp-server/tools/definitions/search-structures.tool.js.map +1 -1
  25. package/dist/mcp-server/tools/definitions/track-ligands.tool.d.ts.map +1 -1
  26. package/dist/mcp-server/tools/definitions/track-ligands.tool.js +1 -8
  27. package/dist/mcp-server/tools/definitions/track-ligands.tool.js.map +1 -1
  28. package/package.json +10 -9
  29. package/server.json +3 -3
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  <div align="center">
9
9
 
10
- [![Version](https://img.shields.io/badge/Version-0.8.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/protein-mcp-server) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^2.0.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![npm](https://img.shields.io/npm/v/@cyanheads/protein-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/@cyanheads/protein-mcp-server) [![TypeScript](https://img.shields.io/badge/TypeScript-^7.0.2-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-v1.4.0-blueviolet.svg?style=flat-square)](https://bun.sh/)
10
+ [![Version](https://img.shields.io/badge/Version-0.8.2-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/protein-mcp-server) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^2.0.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![npm](https://img.shields.io/npm/v/@cyanheads/protein-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/@cyanheads/protein-mcp-server) [![TypeScript](https://img.shields.io/badge/TypeScript-^7.0.2-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-v1.4.0%2B-blueviolet.svg?style=flat-square)](https://bun.sh/)
11
11
 
12
12
  </div>
13
13
 
@@ -27,9 +27,11 @@
27
27
 
28
28
  ---
29
29
 
30
- ## Tools
30
+ ## Overview
31
31
 
32
- Seven tools spanning the structure-research arc — discover, fetch, find homologs, track ligands, compare, profile the corpus, and annotate — over experimental (PDB) and predicted (AlphaFold) structures from one surface:
32
+ Experimental (PDB) and predicted (AlphaFold) protein structures, federated behind one surface. Search, fetch, align, compare, and annotate structures and their ligands across RCSB, AlphaFold DB, 3D-Beacons, UniProt, InterPro, and Foldseek — all keyless. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
33
+
34
+ ### Tools
33
35
 
34
36
  | Tool | Description |
35
37
  |:---|:---|
@@ -41,122 +43,107 @@ Seven tools spanning the structure-research arc — discover, fetch, find homolo
41
43
  | `protein_analyze_collection` | Profile the PDB into distributions and trends with server-side facets — counts, histograms, timelines, and cross-tabs. |
42
44
  | `protein_get_annotations` | Fetch UniProt features and natural variants plus InterPro domain/family memberships with GO terms. |
43
45
 
44
- ### `protein_search_structures`
46
+ ### Resources
47
+
48
+ | Resource | Description |
49
+ |:---|:---|
50
+ | `pdb://{entry_id}` | Experimental structure summary for a PDB entry — title, method, resolution, organism, bound ligands, and per-entity chain IDs in both the author (`authAsymIds`) and mmCIF label (`labelAsymIds`) namespaces. |
51
+ | `af://{uniprot}` | Predicted-structure summary for a UniProt accession from AlphaFold DB — mean pLDDT, confidence-band fractions, model URLs, and version. |
52
+
53
+ All resource data is also reachable via tools — `pdb://{entry_id}` mirrors `protein_get_structure` for `source: experimental`, and `af://{uniprot}` mirrors it for `source: predicted`. Many MCP clients are tool-only and don't surface resources; the summaries remain reachable through the tools.
54
+
55
+ ## Capability reference
45
56
 
46
- Federated search across experimental (PDB) and predicted (computed-model) structures via RCSB Search v2.
57
+ ### `protein_search_structures` <sub>tool</sub>
47
58
 
48
59
  - Free-text, protein-sequence (triggers an mmseqs2 similarity search), and organism / method / resolution filters
49
- - `content_type` scopes the search to `experimental`, `predicted`, or `all` — the default `all` is a genuine union of both universes, so computed models appear alongside PDB entries
50
- - Every hit names its `source`; experimental sequence hits expose a chainable PDB entry `id` plus the matched polymer `entityId`, with title, method, resolution, and organism enrichment, while computed models retain their complete model ID and parsed UniProt accession
60
+ - `content_type` scopes the search to `experimental`, `predicted`, or `all` (default) — `all` is a genuine union, so computed models appear alongside PDB entries
61
+ - Every hit names its `source`; experimental sequence hits expose a chainable PDB entry `id` plus the matched polymer `entityId`, with title, method, resolution, and organism enrichment; computed models retain their complete model ID and parsed UniProt accession
51
62
  - `start` and `limit` page through ranked results; `nextStart` is returned while another page remains
52
- - Optional `facets` return a method / organism / release-year breakdown alongside the hits at no extra call, each reporting how many matches carry no value for that dimension; each dimension may be listed once. A dimension whose buckets hit the server-side cap is named in `notice`, with `protein_analyze_collection` and a larger `bucket_limit` as the route to the long tail (a sequence search gets a narrowing step instead, since that tool has no sequence input)
63
+ - Optional `facets` return a method / organism / release-year breakdown alongside the hits — each dimension may be listed once and reports how many matches carry no value for it; a capped dimension is named in `notice`, with `protein_analyze_collection` (larger `bucket_limit`) as the route to the long tail
53
64
  - Chain hit IDs straight into `protein_get_structure`
54
65
 
55
66
  ---
56
67
 
57
- ### `protein_get_structure`
58
-
59
- Fetch structures with metadata and coordinate-file URLs, resolving across providers by `source`.
68
+ ### `protein_get_structure` <sub>tool</sub>
60
69
 
61
- - `source: experimental` takes PDB entry IDs, batched in one RCSB GraphQL call; it also resolves the computed-model IDs search returns (`AF_*` / `MA_*`), which come back as `source: predicted` credited to their modelling provider
62
- - `source: predicted` takes UniProt accessions and returns the AlphaFold model with pLDDT/PAE confidence
63
- - `source: best_available` takes UniProt accessions and returns the top federated model (experimental if one exists, else the best prediction)
64
- - Per-ID partial success — unresolved IDs are listed in `failed[]`, not a batch-level error
65
- - Batch cap disclosure — `requested` is the original request length and `processed` the count after the cap, so IDs dropped beyond the cap are visible rather than silently discarded; every advisory (cap, partial failure, coordinate overflow, failed inlining) is joined into one `notice`
66
- - Records served by the RCSB entry endpoint also carry `polymerEntities` (with both `authAsymIds` and `labelAsymIds`), `ligands`, `molecularWeight`, and `releaseDate`
67
- - `include_coords` inlines coordinate content, subject to the response budget: a batch over budget returns a per-structure size outline you can re-call with `sections: [ids]`, and a single file over budget is withheld with a pointer to its `coordinateUrls` (a `sections` re-call would return the same bytes). A `sections` re-call is not re-gated — `structuredContent` carries the named payload whole at any size, while the token-bounded text surface withholds anything over the budget and points at `coordinateUrls` instead of truncating it
68
- - Every response carries an `attribution` block naming the upstream data licenses and citations (see [Upstream data licensing](#upstream-data-licensing))
70
+ - `source: experimental` batches PDB entry IDs (also resolving computed-model IDs like `AF_*`/`MA_*` from search, tagged `source: predicted` with their provider); `source: predicted` takes UniProt accessions for AlphaFold models with pLDDT/PAE; `source: best_available` takes UniProt accessions and returns the top federated model (highest-resolution experimental if one exists, else the best prediction)
71
+ - Per-ID partial success — unresolved IDs land in `failed[]`; `requested`/`processed` disclose IDs dropped beyond the batch cap, and every advisory (cap, failure, overflow) joins into one `notice`
72
+ - Records served by the RCSB entry endpoint also carry `polymerEntities` (both `authAsymIds` and `labelAsymIds`), `ligands`, `molecularWeight`, and `releaseDate`
73
+ - `include_coords` inlines coordinate content, subject to a response budget — an over-budget batch returns a per-structure size outline (re-call with `sections: [ids]`), and a single oversized file is withheld with a pointer to its `coordinateUrls`
74
+ - Every response carries an `attribution` block naming upstream data licenses and citations
69
75
 
70
76
  ---
71
77
 
72
- ### `protein_find_similar`
78
+ ### `protein_find_similar` <sub>tool</sub>
73
79
 
74
- Find structurally or evolutionarily related proteins, by sequence or by fold.
75
-
76
- - `by: sequence` runs a synchronous RCSB mmseqs2 search; `by: structure` runs an asynchronous Foldseek search against experimental and predicted databases
77
- - Query from a raw one-letter sequence, a PDB ID, or a UniProt accession
78
- - Both modes accept `start` with `limit` and report `totalCount`, echoing `start` and returning `nextStart` while another page remains
80
+ - `by: sequence` runs a synchronous RCSB mmseqs2 search; `by: structure` runs an asynchronous Foldseek search against experimental and predicted databases — query from a raw sequence, a PDB ID, or a UniProt accession
81
+ - Both modes accept `start`/`limit` and report `totalCount`, echoing `start` and returning `nextStart` while another page remains
79
82
  - Foldseek targets default to `pdb100` + `afdb50`; override via `databases` (e.g. `afdb-swissprot`, `BFVD`)
80
- - Async jobs that exceed the poll budget return `status: computing` with a `ticketId` — re-call with `ticket_id` set to that value to poll the same job instead of resubmitting. A completed structure search returns the same ticket, so a new `start` pages the finished job without resubmitting the structure
81
- - Each mode reads only its own controls — `sequence`, `max_evalue` and `min_identity` under `by: sequence`; `ticket_id` and `databases` under `by: structure`; `pdb_id`, `uniprot`, `start` and `limit` shared — and a field the selected mode cannot consume is rejected rather than ignored
83
+ - An async job that exceeds the poll budget returns `status: computing` with a `ticketId` — re-call with `ticket_id` to resume; a completed structure search returns the same ticket so a new `start` pages the finished job
84
+ - Each mode reads only its own controls (`sequence`, `max_evalue`, `min_identity` under `by: sequence`; `ticket_id`, `databases` under `by: structure`) — a field the selected mode can't consume is rejected, not ignored
82
85
  - Each hit names the engine and source database it came from
83
86
 
84
87
  ---
85
88
 
86
- ### `protein_track_ligands`
87
-
88
- Ligand discovery and binding-site analysis across the PDB.
89
+ ### `protein_track_ligands` <sub>tool</sub>
89
90
 
90
- - `mode: find_ligand` resolves a name or formula to chemical component IDs with formula, weight, SMILES, and InChIKey
91
- - A formula-shaped `query` matches on exact composition — spaced (`C29 H31 N7 O`) or unspaced (`C29H31N7O`), either resolves the same component; anything else, a component ID included, matches on name and synonyms and is ranked by deposition frequency
92
- - `mode: structures_with_ligand` returns PDB entries containing a ligand by exact component ID
93
- - `mode: structures_with_ligand` accepts `start` with `limit` and returns `nextStart` while another page remains
91
+ - `mode: find_ligand` resolves a name or formula to chemical component IDs with formula, weight, SMILES, and InChIKey — ranked by deposition frequency, most-common match first
92
+ - A formula-shaped `query` matches on exact composition, spaced (`C29 H31 N7 O`) or unspaced; anything else (a component ID included) matches on name and synonyms
93
+ - `mode: structures_with_ligand` returns PDB entries containing a ligand by exact component ID, with `start`/`limit` paging and `nextStart` while another page remains
94
94
  - `mode: binding_site` returns the protein residues lining a ligand's pocket in a structure, with contact distances
95
- - Binding sites are experimental-only — computed from deposited coordinates (predicted models carry no bound ligands)
96
-
97
- Paged RCSB results preserve the upstream order within each response. Resolution ties and changes in the live corpus mean traversal is best-effort across calls, not a stable export snapshot.
95
+ - Binding sites are experimental-only — computed from deposited coordinates; predicted models carry no bound ligands
98
96
 
99
97
  ---
100
98
 
101
- ### `protein_compare_structures`
102
-
103
- Structural alignment of multiple structures (up to the configured `PROTEIN_MAX_COMPARE_STRUCTURES` cap) via the RCSB Structural Comparison service.
99
+ ### `protein_compare_structures` <sub>tool</sub>
104
100
 
105
- - Methods: `tm-align`, `fatcat-rigid`, `fatcat-flexible`
106
- - `reference: first` aligns every structure to the first; `reference: all_pairs` computes the full pairwise matrix
107
- - Optional per-structure `chain` restricts the alignment to a single chain
108
- - A structure repeated in `structures[]` is compared once — the repeat would only add a self-alignment and a mirrored pair, which the resume mechanism cannot tell apart from the original
109
- - Each pair is an independent async job, fanned out with a concurrency cap and per-pair partial success — a pair still computing when the budget elapses returns `status: computing` with its job `uuid`, and a failed pair degrades its row without sinking the others
110
- - Re-call with a matching `{ a, b, uuid }` entry in `resume[]` (copied from a prior response's `pairs[]`) to poll a computing pair's job instead of resubmitting
111
- - Returns TM-score, RMSD, and aligned-residue count per pair, plus `modeledResidues` and `coverage` — each a `[a, b]` tuple, with coverage a 0–100 percentage of that structure's own modeled-residue count
101
+ - Aligns 2 to the configured cap (default 10, max 25) structures per call, via `tm-align`, `fatcat-rigid`, or `fatcat-flexible`; optional per-structure `chain` restricts the alignment to a single mmCIF label chain
102
+ - `reference: first` aligns every structure to the first; `reference: all_pairs` computes the full pairwise matrix; a structure repeated in `structures[]` is compared once
103
+ - Each pair is an independent async job with per-pair partial success — a pair still computing when the poll budget elapses returns `status: computing` with a job `uuid`; a failed pair degrades only its own row
104
+ - Re-call with a matching `{ a, b, uuid }` entry in `resume[]` to poll a computing pair instead of resubmitting
105
+ - Returns TM-score, RMSD, and aligned-residue count per pair, plus each structure's `modeledResidues` and 0–100 `coverage`
112
106
 
113
107
  ---
114
108
 
115
- ### `protein_analyze_collection`
116
-
117
- Profile the PDB into distributions and trends over an optional scoping query — backed by RCSB's server-side facet engine (one call, compact buckets, no row pull).
109
+ ### `protein_analyze_collection` <sub>tool</sub>
118
110
 
119
111
  - Group by `method`, `organism`, `polymer_type`, `resolution`, `release_year`, or `molecular_weight`
120
112
  - One `group_by` dimension for a breakdown, or two distinct dimensions for a cross-tab (the first nests the second); a repeated dimension is rejected
121
- - `interval` sets the bin width for a value histogram (a number, for `resolution` or `molecular_weight`) or the period for a date histogram (`year` — the only period RCSB accepts). It applies to whichever requested `group_by` dimension can consume that value type, primary or nested child, so `["method", "resolution"]` bins its nested `resolution` child; when both dimensions can consume it the primary takes it and the child keeps its default, and when neither can the call is rejected rather than silently ignoring the override
113
+ - `interval` sets a histogram bin width (a number, for `resolution` or `molecular_weight`) or date-histogram period (`year`, the only one RCSB accepts) — applies to whichever requested dimension can consume that type; rejected when neither can
122
114
  - Scope with a free-text `query`, `organism`, `method`, or `max_resolution`; `content_type` selects the structure universe
123
- - `bucket_limit` caps buckets per dimension level, not per response — a cross-tab applies it separately to the parent dimension and to the nested child inside each parent bucket, so up to `bucket_limit × (1 + bucket_limit)` buckets come back. Each level flags its own truncation, `notice` names every capped position (the top-level dimension and each nested child, with how many parent buckets it was capped under), and `bucketsReturned` gives the realized total
124
- - Every dimension reports `missingValueCount` — matches in scope carrying no value for that attribute, which therefore fall in no bucket (a `resolution` breakdown does not cover NMR entries, and neither `method` nor `resolution` covers computed models)
115
+ - `bucket_limit` caps buckets per dimension level, not per response — a cross-tab applies it separately to the parent and each nested child, up to `bucket_limit × (1 + bucket_limit)` buckets; `notice` names every capped position and `bucketsReturned` gives the realized total
116
+ - Every dimension reports `missingValueCount` — matches carrying no value for that attribute (e.g. a `resolution` breakdown excludes NMR entries; computed models have neither `method` nor `resolution`)
125
117
 
126
118
  ---
127
119
 
128
- ### `protein_get_annotations`
120
+ ### `protein_get_annotations` <sub>tool</sub>
129
121
 
130
- Sequence and functional annotation for a protein.
131
-
132
- - UniProt features (domains, binding sites, PTMs) and natural sequence variants
133
- - InterPro domain/family memberships (Pfam, PROSITE, …) with associated GO terms
134
- - Provide a UniProt accession directly, or a PDB ID — resolved to a UniProt accession via the structure's sequence cross-reference
135
- - A multi-chain PDB entry can map to several accessions; the default is the deterministic lowest-author-chain pick, with the alternatives listed under `ambiguity`. Pass `chain` (an author chain ID, e.g. `A`) to select a specific one
136
- - `include` scopes which annotation classes are fetched: `features`, `domains`, `variants`, or `all`
122
+ - UniProt features (domains, binding sites, PTMs) and natural variants, plus InterPro domain/family memberships (Pfam, PROSITE, …) with associated GO terms
123
+ - Provide a UniProt accession directly, or a PDB ID — resolved via the structure's sequence cross-reference
124
+ - A multi-chain PDB entry can map to several accessions; the default is the deterministic lowest-author-chain pick, with alternatives listed under `ambiguity` — pass `chain` (an author chain ID) to select a specific one
125
+ - `include` scopes which classes are fetched (`features`, `domains`, `variants`, `all`); `limit` caps each class independently (1–200, default 50), with a truncated class disclosed in `notice`
137
126
  - Every response carries an `attribution` block naming the upstream data licenses and citations (see [Upstream data licensing](#upstream-data-licensing))
138
127
 
139
- ## Resources
128
+ ---
140
129
 
141
- | Type | Name | Description |
142
- |:---|:---|:---|
143
- | Resource | `pdb://{entry_id}` | Experimental structure summary for a PDB entry — title, method, resolution, organism, bound ligands, and per-entity chain IDs in both the author (`authAsymIds`) and mmCIF label (`labelAsymIds`) namespaces. |
144
- | Resource | `af://{uniprot}` | Predicted-structure summary for a UniProt accession from AlphaFold DB — mean pLDDT, confidence-band fractions, model URLs, and version. |
130
+ ### `pdb://{entry_id}` <sub>resource</sub>
145
131
 
146
- All resource data is also reachable via tools — `pdb://{entry_id}` mirrors `protein_get_structure` for `source: experimental`, and `af://{uniprot}` mirrors it for `source: predicted`. Many MCP clients are tool-only and don't surface resources; the summaries remain reachable through the tools.
132
+ - Experimental structure summary as `application/json` — title, method, resolution, organism, bound ligands, and per-entity chain IDs in both the author (`authAsymIds`) and mmCIF label (`labelAsymIds`) namespaces
133
+ - Mirrors `protein_get_structure` for `source: experimental`; `entry_id` is a PDB entry ID (e.g. `4HHB`)
147
134
 
148
- ## Features
135
+ ---
149
136
 
150
- Built on [`@cyanheads/mcp-ts-core`](https://www.npmjs.com/package/@cyanheads/mcp-ts-core):
137
+ ### `af://{uniprot}` <sub>resource</sub>
151
138
 
152
- - Declarative tool and resource definitions — single file per primitive, framework handles registration and validation
153
- - Unified error handling — handlers throw, framework catches, classifies, and formats
154
- - Pluggable auth: `none`, `jwt`, `oauth`
155
- - Swappable storage backends: `in-memory`, `filesystem`, `Supabase`, `Cloudflare KV/R2/D1`
156
- - Structured logging with optional OpenTelemetry tracing
157
- - STDIO and Streamable HTTP transports
139
+ - Predicted-structure summary as `application/json` — mean pLDDT, confidence-band fractions, model URLs (`cif`/`pdb`/`bcif`), and AlphaFold model version
140
+ - `uniprot` accepts a UniProt accession or an AlphaFold DB entry ID (e.g. `AF-P69905-F1`); mirrors `protein_get_structure` for `source: predicted`
158
141
 
159
- Protein-specific:
142
+ ## Features
143
+
144
+ Built on [`@cyanheads/mcp-ts-core`](https://github.com/cyanheads/mcp-ts-core): stdio and Streamable HTTP transports, pluggable auth (`none` / `jwt` / `oauth`), swappable storage (`in-memory`, `filesystem`, `Supabase`, `Cloudflare KV/R2/D1`), structured logging with optional OpenTelemetry tracing.
145
+
146
+ PDB / AlphaFold-specific:
160
147
 
161
148
  - One federated surface over experimental (PDB) and predicted (AlphaFold / 3D-Beacons) structures — search, fetch, and compare treat both universes the same
162
149
  - Keyless across every upstream — RCSB, AlphaFold DB, 3D-Beacons, UniProt, InterPro, and Foldseek, no API keys to provision
@@ -186,7 +173,7 @@ A public instance is available at `https://protein.caseyjhand.com/mcp` — no in
186
173
  }
187
174
  ```
188
175
 
189
- ### Self-hosted
176
+ ### Self-Hosted / Local
190
177
 
191
178
  Add the following to your MCP client configuration file. No API key is required — every upstream provider is keyless.
192
179
 
@@ -247,7 +234,7 @@ MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
247
234
 
248
235
  ### Prerequisites
249
236
 
250
- - [Bun v1.3.2](https://bun.sh/) or higher (or Node.js v24+).
237
+ - [Bun v1.4.0](https://bun.sh/) or higher (or Node.js v24+).
251
238
  - No accounts or API keys — RCSB, AlphaFold DB, 3D-Beacons, UniProt, InterPro, and Foldseek are all public and keyless.
252
239
 
253
240
  ### Installation
@@ -286,6 +273,7 @@ All upstream providers are keyless, so the server runs out of the box with no co
286
273
  | `FOLDSEEK_BASE_URL` | Base URL for the Foldseek structural-similarity search service. | `https://search.foldseek.com` |
287
274
  | `MCP_TRANSPORT_TYPE` | Transport: `stdio` or `http`. | `stdio` |
288
275
  | `MCP_HTTP_PORT` | Port for the HTTP server. | `3010` |
276
+ | `MCP_SESSION_MODE` | HTTP session mode: `stateless`, `stateful`, or `auto`. The server declares `stateless` in code; set this to override it. | `stateless` |
289
277
  | `MCP_AUTH_MODE` | Auth mode: `none`, `jwt`, or `oauth`. | `none` |
290
278
  | `MCP_LOG_LEVEL` | Log level (RFC 5424). | `info` |
291
279
  | `OTEL_ENABLED` | Enable [OpenTelemetry instrumentation](https://github.com/cyanheads/mcp-ts-core/tree/main/docs/telemetry). | `false` |
@@ -333,7 +321,7 @@ The Dockerfile defaults to HTTP transport, stateless session mode, and logs to `
333
321
  | `src/config` | Server-specific environment variable parsing and validation with Zod. |
334
322
  | `src/mcp-server/tools` | Tool definitions (`*.tool.ts`). |
335
323
  | `src/mcp-server/resources` | Resource definitions (`*.resource.ts`). |
336
- | `src/services` | Provider service layer — RCSB, AlphaFold, 3D-Beacons, UniProt, InterPro, Foldseek, and shared HTTP/identifier helpers. |
324
+ | `src/services` | Provider service layer — RCSB (search, data, facets), AlphaFold, 3D-Beacons (best-available), UniProt (incl. InterPro/GO), Structural Comparison alignment, Foldseek, and shared HTTP/identifier/concurrency helpers. |
337
325
  | `tests/` | Unit and integration tests mirroring `src/`. |
338
326
 
339
327
  ## Development guide
@@ -345,15 +333,6 @@ See [`CLAUDE.md`/`AGENTS.md`](./CLAUDE.md) for development guidelines and archit
345
333
  - Register new tools and resources via the barrels in `src/mcp-server/*/definitions/index.ts`
346
334
  - Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
347
335
 
348
- ## Contributing
349
-
350
- Issues and pull requests are welcome. Run checks and tests before submitting:
351
-
352
- ```sh
353
- bun run devcheck
354
- bun run test
355
- ```
356
-
357
336
  ## Upstream data licensing
358
337
 
359
338
  Structure and annotation data comes from public upstream databases, each under its own license. `protein_get_structure` and `protein_get_annotations` carry an `attribution` block on every response — the license, citation, and homepage for each source that contributed to that specific response — so the attribution obligation travels with the data to downstream consumers rather than living only here. CC BY / CC BY-SA sources require attribution on redistribution; CC0 sources are citation-only (attribution encouraged, not required).
@@ -371,6 +350,15 @@ Structure and annotation data comes from public upstream databases, each under i
371
350
 
372
351
  `best_available` federates predicted models through [3D-Beacons](https://3d-beacons.org/), so the `attribution` block credits the actual contributing provider (AlphaFold DB, SWISS-MODEL, BFVD, …); a provider without a curated license entry carries a `See provider terms` fallback pointing back to 3D-Beacons rather than a fabricated license. InterPro's own domain/family classifications are CC0; the GO terms carried alongside them are separately CC BY 4.0, so each is credited independently only when it actually contributes. Full citations for each source travel in the `attribution` block of the relevant tool responses. This covers upstream *data* licensing — the server's own code is licensed separately (see [License](#license)).
373
352
 
353
+ ## Contributing
354
+
355
+ Issues are welcome. Run checks and tests before submitting:
356
+
357
+ ```sh
358
+ bun run devcheck
359
+ bun run test
360
+ ```
361
+
374
362
  ## License
375
363
 
376
364
  Apache-2.0 — see [LICENSE](LICENSE) for details.
@@ -0,0 +1,29 @@
1
+ ---
2
+ summary: "Adopts @cyanheads/mcp-ts-core 0.13.2, declaring stateless HTTP session mode in source, plus dependency and skills-tree maintenance."
3
+ breaking: false
4
+ security: false
5
+ ---
6
+
7
+ # 0.8.1 — 2026-09-16
8
+
9
+ ## Changed
10
+
11
+ - **Session mode** — the server declares `stateless` HTTP session mode in source (`createApp({ sessionMode: 'stateless' })`). With `MCP_SESSION_MODE` unset, an HTTP run now serves `stateless` — previously the schema default `auto` resolved to `stateful`; an explicit `MCP_SESSION_MODE` value still overrides it. The Docker image already set `stateless`.
12
+ - **`/.well-known/mcp.json`** — the server card now publishes the resolved session mode under the `_meta` key `io.github.cyanheads.mcp-ts-core/sessionMode`.
13
+ - **Shutdown** — `SIGTERM` and `SIGINT` now end the process once shutdown settles.
14
+ - **`skills/` → `framework-skills/`** — the framework's development skills moved, so a plugin install no longer hands them to the installing agent.
15
+
16
+ ## Fixed
17
+
18
+ - **Landing page** — the curl snippet now sends a handshake `initialize` accepts.
19
+ - **`.env.example`** — session and host comments corrected (`MCP_HTTP_HOST` default `127.0.0.1`); README gains an `MCP_SESSION_MODE` row.
20
+
21
+ ## Dependencies
22
+
23
+ - `@cyanheads/mcp-ts-core` ^0.12.7 → ^0.13.2
24
+ - Bun engines floor `>=1.3.0` → `>=1.4.0`
25
+ - `zod` ^4.5.4 → ^4.6.4
26
+ - `@biomejs/biome` 2.5.12 → 2.5.13
27
+ - `@types/node` 26.4.1 → 26.5.1
28
+ - `ignore` ^7.0.8 → ^7.0.9
29
+ - `tsc-alias` ^1.9.4 → ^1.9.5
@@ -0,0 +1,24 @@
1
+ ---
2
+ summary: "Adopts mcp-ts-core 0.13.6's argument-rejection recovery hints and pre-validation aliasing; rewrites server instructions for workflow chaining."
3
+ breaking: false
4
+ security: false
5
+ ---
6
+
7
+ # 0.8.2 — 2026-09-21
8
+
9
+ ## Changed
10
+
11
+ - **Server instructions** — rewritten as three sentences addressed to the calling agent: where a workflow starts, what a PDB ID chains into, and how a running Foldseek search or structural alignment resumes.
12
+ - **Argument-rejection recovery** — an unknown or mistyped tool argument now carries `data.reason: "invalid_arguments"` and a `Recovery:` hint naming the accepted keys or expected type; an omitted required enum field reads as missing rather than as a wrong choice.
13
+ - **Argument pre-validation** — a differently-cased key naming exactly one declared parameter is rewritten (`pdbId` → `pdb_id`), and a JSON-stringified array argument is repaired and re-parsed once; an undeclared key is still rejected.
14
+ - **Tool-error text** — closes with `(reason <reason>)`, adding `· retryable` or `· not retryable` when the reason declares it.
15
+ - **Tool/field descriptions** — five definitions (`protein_analyze_collection`, `protein_compare_structures`, `protein_get_annotations`, `protein_search_structures`, `protein_track_ligands`) converted from `+`-joined strings to single string literals; advertised `tools/list` text is unchanged ([#38](https://github.com/cyanheads/protein-mcp-server/issues/38)).
16
+ - **Repo hygiene** — framework skills, the definition linter (config-driven truncation allowlist via `devcheck.config.json`), issue forms, and devcheck synced to the current template; adds `.github/workflows/codeql.yml`.
17
+
18
+ ## Dependencies
19
+
20
+ - `@cyanheads/mcp-ts-core` ^0.13.2 → ^0.13.6
21
+ - `zod` ^4.6.4 → ^4.6.5
22
+ - `@biomejs/biome` 2.5.13 → 2.5.14
23
+ - `@types/node` 26.5.1 → 26.6.2
24
+ - `vitest` ^5.0.0 → ^5.0.1
@@ -6,8 +6,8 @@
6
6
 
7
7
  # Required. One-line GitHub Release-style headline. 350 character cap — a
8
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
10
- # headline, like a tag's theme line. Quotes required: unquoted YAML treats
9
+ # unrelated changes with commas/semicolons into an inventory — pick the one
10
+ # headline the release is about. Quotes required: unquoted YAML treats
11
11
  # `: ` inside the value as a key separator and fails GitHub's strict parser.
12
12
  summary: ""
13
13
 
@@ -117,30 +117,13 @@ security: false
117
117
  in that unrelated item's metadata.
118
118
 
119
119
  TAG ANNOTATIONS — the annotated tag body renders as the GitHub Release body
120
- via `gh release create --notes-from-tag`. The tag is a derivative of this
121
- changelog entry — a condensed, scannable version, not a copy. Format:
122
-
123
- <theme — omit version number, GitHub prepends it>
124
- ← blank line
125
- <1-2 sentence context: what this release does>
126
- ← blank line
127
- Dependency bumps: ← section header
128
- ← blank line
129
- - `@cyanheads/mcp-ts-core` ^0.9.1 → ^0.9.6 ← bullet
130
- ← blank line
131
- Changed: ← only sections with entries
132
- ← blank line
133
- - `format()` output includes `query` in text mode
134
- ← blank line
135
- Added:
136
- ← blank line
137
- - `manifest.json` scaffolded for MCPB bundle support
138
- - Install badges (Claude Desktop, Cursor, VS Code)
139
- ← blank line
140
- <N> tests pass; `bun run devcheck` clean. ← footer
141
-
142
- Never a flat comma-separated string. Always structured markdown with
143
- sections. The tag must scan well as a rendered GitHub Release page.
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.
144
127
  -->
145
128
 
146
129
  ## Added
package/dist/index.js CHANGED
@@ -31,6 +31,8 @@ await createApp({
31
31
  prompts: [],
32
32
  // Public, keyless data server — serve the full inventory to unauthenticated callers.
33
33
  landing: { requireAuth: false },
34
+ // No tool gates on ctx.requestInput, so HTTP serving needs no live session.
35
+ sessionMode: 'stateless',
34
36
  /**
35
37
  * Cache hints for protocol revision 2026-07-28. Every listing is static per
36
38
  * build and identical for every caller — no auth-gated definitions, no
@@ -46,7 +48,7 @@ await createApp({
46
48
  'server/discover': { ttlMs: 3_600_000, cacheScope: 'public' },
47
49
  'resources/read': { ttlMs: 3_600_000, cacheScope: 'public' },
48
50
  },
49
- instructions: 'protein-mcp-server federates experimental (PDB) and predicted (AlphaFold) protein structures: search structures by text, sequence, or organism/method/resolution (protein_search_structures); fetch metadata and coordinate URLs for PDB IDs or UniProt accessions (protein_get_structure); find sequence or fold homologs via mmseqs2 or Foldseek (protein_find_similar); resolve ligands and map binding-site residues (protein_track_ligands); align 2–10 structures with TM-align or jFATCAT (protein_compare_structures); profile the PDB with server-side facet distributions and trends (protein_analyze_collection); and pull UniProt features plus InterPro domains and GO terms (protein_get_annotations).',
51
+ instructions: 'Find structures with protein_search_structures, then pass the returned IDs to protein_get_structure for metadata and coordinate URLs, or pass UniProt accessions there for AlphaFold predictions and the best available model. A PDB ID also chains into protein_get_annotations, protein_track_ligands, protein_find_similar, and protein_compare_structures for annotations, binding sites, homologs, and structural alignment, while protein_analyze_collection profiles the whole PDB without pulling rows. A Foldseek search or structural alignment still running when the poll budget elapses returns status "computing" with a ticket (protein_find_similar) or a job UUID (protein_compare_structures); re-call with it to resume that job rather than resubmitting.',
50
52
  setup(core) {
51
53
  const serverConfig = getServerConfig();
52
54
  initRcsbService(core.config, core.storage, serverConfig);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACpG,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,YAAY,GACb,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAE3E,MAAM,SAAS,CAAC;IACd,IAAI,EAAE,oBAAoB;IAC1B,KAAK,EAAE,oBAAoB;IAC3B,KAAK,EAAE;QACL,gBAAgB;QAChB,YAAY;QACZ,WAAW;QACX,YAAY;QACZ,iBAAiB;QACjB,iBAAiB;QACjB,cAAc;KACf;IACD,SAAS,EAAE,CAAC,kBAAkB,EAAE,iBAAiB,CAAC;IAClD,OAAO,EAAE,EAAE;IACX,qFAAqF;IACrF,OAAO,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;IAC/B;;;;;;;OAOG;IACH,UAAU,EAAE;QACV,YAAY,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;QACxD,gBAAgB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;QAC5D,0BAA0B,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;QACtE,iBAAiB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;QAC7D,gBAAgB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;KAC7D;IACD,YAAY,EACV,srBAAsrB;IACxrB,KAAK,CAAC,IAAI;QACR,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;QACvC,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACzD,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC9D,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC5D,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC5D,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC9D,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC/D,CAAC;CACF,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACpG,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,YAAY,GACb,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAE3E,MAAM,SAAS,CAAC;IACd,IAAI,EAAE,oBAAoB;IAC1B,KAAK,EAAE,oBAAoB;IAC3B,KAAK,EAAE;QACL,gBAAgB;QAChB,YAAY;QACZ,WAAW;QACX,YAAY;QACZ,iBAAiB;QACjB,iBAAiB;QACjB,cAAc;KACf;IACD,SAAS,EAAE,CAAC,kBAAkB,EAAE,iBAAiB,CAAC;IAClD,OAAO,EAAE,EAAE;IACX,qFAAqF;IACrF,OAAO,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;IAC/B,4EAA4E;IAC5E,WAAW,EAAE,WAAW;IACxB;;;;;;;OAOG;IACH,UAAU,EAAE;QACV,YAAY,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;QACxD,gBAAgB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;QAC5D,0BAA0B,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;QACtE,iBAAiB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;QAC7D,gBAAgB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;KAC7D;IACD,YAAY,EACV,+uBAA+uB;IACjvB,KAAK,CAAC,IAAI;QACR,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;QACvC,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACzD,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC9D,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC5D,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC5D,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC9D,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC/D,CAAC;CACF,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"analyze-collection.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/analyze-collection.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAuCjE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0M5B,CAAC"}
1
+ {"version":3,"file":"analyze-collection.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/analyze-collection.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAuCjE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8L5B,CAAC"}
@@ -31,13 +31,7 @@ const ZERO_MATCH_NOTICE = {
31
31
  };
32
32
  export const analyzeCollection = tool('protein_analyze_collection', {
33
33
  title: 'protein-mcp-server: analyze collection',
34
- description: 'Profile the PDB into distributions and trends over an optional scoping query: counts by method, ' +
35
- 'organism, or polymer composition; resolution and molecular-weight histograms; release-year timelines; ' +
36
- 'and multidimensional cross-tabs (e.g. method × release_year). Aggregation runs server-side at RCSB — ' +
37
- 'one call returns compact buckets, no row pull. Pass one group_by dimension for a single breakdown, or ' +
38
- 'two distinct dimensions for a cross-tab (the first nests the second). bucket_limit caps each dimension ' +
39
- 'level separately rather than the response, so a cross-tab returns up to that many nested buckets under ' +
40
- 'each of its capped parent buckets; bucketsReturned reports the realized total.',
34
+ description: 'Profile the PDB into distributions and trends over an optional scoping query: counts by method, organism, or polymer composition; resolution and molecular-weight histograms; release-year timelines; and multidimensional cross-tabs (e.g. method × release_year). Aggregation runs server-side at RCSB — one call returns compact buckets, no row pull. Pass one group_by dimension for a single breakdown, or two distinct dimensions for a cross-tab (the first nests the second). bucket_limit caps each dimension level separately rather than the response, so a cross-tab returns up to that many nested buckets under each of its capped parent buckets; bucketsReturned reports the realized total.',
41
35
  annotations: { readOnlyHint: true, openWorldHint: true },
42
36
  errors: [
43
37
  {
@@ -73,8 +67,7 @@ export const analyzeCollection = tool('protein_analyze_collection', {
73
67
  content_type: z
74
68
  .enum(['experimental', 'predicted', 'all'])
75
69
  .default('experimental')
76
- .describe('Which structure universe to profile. Default experimental. Computed models carry no ' +
77
- 'experimental metadata, so method and resolution return nothing under "predicted".'),
70
+ .describe('Which structure universe to profile. Default experimental. Computed models carry no experimental metadata, so method and resolution return nothing under "predicted".'),
78
71
  interval: z
79
72
  .union([
80
73
  // Coerce the numeric arm: many clients stringify tool args, and "0.5" must
@@ -99,10 +92,7 @@ export const analyzeCollection = tool('protein_analyze_collection', {
99
92
  .min(1)
100
93
  .max(500)
101
94
  .optional()
102
- .describe('Max buckets per dimension level, not per response. A cross-tab applies the cap separately to the ' +
103
- 'parent dimension and to the nested child inside each parent bucket, so up to ' +
104
- 'bucket_limit × (1 + bucket_limit) buckets can come back — 2550 at the default 50. The realized ' +
105
- 'count comes back as bucketsReturned. Defaults to the server PROTEIN_FACET_BUCKET_CAP.'),
95
+ .describe('Max buckets per dimension level, not per response. A cross-tab applies the cap separately to the parent dimension and to the nested child inside each parent bucket, so up to bucket_limit × (1 + bucket_limit) buckets can come back — 2550 at the default 50. The realized count comes back as bucketsReturned. Defaults to the server PROTEIN_FACET_BUCKET_CAP.'),
106
96
  }),
107
97
  output: z.object({
108
98
  total: z.number().describe('Total entries in the scoped collection.'),
@@ -120,9 +110,7 @@ export const analyzeCollection = tool('protein_analyze_collection', {
120
110
  .describe('True when at least one dimension position — the top-level dimension or a nested cross-tab child — had more buckets than the applied cap. Which positions, and by how much, is named in notice.'),
121
111
  bucketsReturned: z
122
112
  .number()
123
- .describe('Buckets in this response, summed over every dimension level: the top-level buckets plus, for a ' +
124
- 'cross-tab, the nested child buckets under each of them. Since bucket_limit caps each level ' +
125
- 'separately, this is the size those caps actually produced — always present, cross-tab or not.'),
113
+ .describe('Buckets in this response, summed over every dimension level: the top-level buckets plus, for a cross-tab, the nested child buckets under each of them. Since bucket_limit caps each level separately, this is the size those caps actually produced — always present, cross-tab or not.'),
126
114
  },
127
115
  async handler(input, ctx) {
128
116
  const cfg = getServerConfig();
@@ -1 +1 @@
1
- {"version":3,"file":"analyze-collection.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/analyze-collection.tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analyze-collection.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/analyze-collection.tool.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"compare-structures.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/compare-structures.tool.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAwHjE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmK5B,CAAC"}
1
+ {"version":3,"file":"compare-structures.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/compare-structures.tool.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAqHjE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwJ5B,CAAC"}
@@ -71,10 +71,7 @@ const outputSchema = z.object({
71
71
  tmScore: z
72
72
  .number()
73
73
  .optional()
74
- .describe('TM-score (0–1; higher is more similar). Length-normalized, so it can be sensitive to ' +
75
- 'terminal length differences between the two structures — a one-residue overhang can flip ' +
76
- 'the greedy superposition into a worse local optimum, dropping the score sharply. Cross-check ' +
77
- 'rmsd and alignedResidues to spot such cases.'),
74
+ .describe('TM-score (0–1; higher is more similar). Length-normalized, so it can be sensitive to terminal length differences between the two structures — a one-residue overhang can flip the greedy superposition into a worse local optimum, dropping the score sharply. Cross-check rmsd and alignedResidues to spot such cases.'),
78
75
  rmsd: z.number().optional().describe('RMSD in Å over aligned residues.'),
79
76
  alignedResidues: z.number().optional().describe('Number of aligned residue pairs.'),
80
77
  modeledResidues: z
@@ -98,17 +95,7 @@ const outputSchema = z.object({
98
95
  });
99
96
  export const compareStructures = tool('protein_compare_structures', {
100
97
  title: 'protein-mcp-server: compare structures',
101
- description: 'Structurally align multiple structures (up to the configured batch cap) via the RCSB Structural ' +
102
- 'Comparison service (TM-align / jFATCAT). reference:"first" aligns every structure to the first; ' +
103
- 'reference:"all_pairs" computes the full pairwise matrix. Each pair is an independent async alignment ' +
104
- 'job, fanned out with a concurrency cap and per-pair partial success — a pair still computing when the ' +
105
- 'budget elapses returns status "computing" with its job UUID, and a failed pair degrades its row without ' +
106
- "sinking the others. Re-call with a matching entry in resume[] to poll a computing pair's UUID instead " +
107
- "of resubmitting. Returns TM-score, RMSD, and aligned-residue count per pair, plus each structure's " +
108
- 'modeled-residue count and alignment coverage. TM-score is ' +
109
- 'length-normalized and can shift sharply between structures that differ only by a terminal residue or ' +
110
- 'two — the greedy superposition can settle into a worse local optimum — so read tmScore alongside rmsd, ' +
111
- 'alignedResidues, modeledResidues and coverage, the columns that make such cases diagnosable.',
98
+ description: `Structurally align multiple structures (up to the configured batch cap) via the RCSB Structural Comparison service (TM-align / jFATCAT). reference:"first" aligns every structure to the first; reference:"all_pairs" computes the full pairwise matrix. Each pair is an independent async alignment job, fanned out with a concurrency cap and per-pair partial success — a pair still computing when the budget elapses returns status "computing" with its job UUID, and a failed pair degrades its row without sinking the others. Re-call with a matching entry in resume[] to poll a computing pair's UUID instead of resubmitting. Returns TM-score, RMSD, and aligned-residue count per pair, plus each structure's modeled-residue count and alignment coverage. TM-score is length-normalized and can shift sharply between structures that differ only by a terminal residue or two — the greedy superposition can settle into a worse local optimum — so read tmScore alongside rmsd, alignedResidues, modeledResidues and coverage, the columns that make such cases diagnosable.`,
112
99
  annotations: { readOnlyHint: true, openWorldHint: true },
113
100
  errors: [
114
101
  {