@czi-sds/mcp 0.19.0 → 0.20.1

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.
@@ -24,12 +24,13 @@ The viewer fills its parent. Mol\* sizes its canvas from the laid-out container,
24
24
 
25
25
  ### **Default ProteinStructureViewer**
26
26
 
27
- Raw PDB text is the only required prop. Supplying per-residue `plddt` scores on a 0-1 scale colors the structure by confidence and puts the pLDDT key in the legend.
27
+ The structure to render, as raw PDB or mmCIF (PDBx) text, is the only required prop. Supplying per-residue `plddt` scores on a 0-1 scale colors the structure by confidence and puts the pLDDT key in the legend.
28
28
 
29
29
  **Example: DefaultProteinStructureViewer**
30
30
 
31
31
  ```tsx
32
- // Raw PDB text is the only required prop. Adding per-residue pLDDT scores on a
32
+ // The structure to render, as raw PDB or mmCIF (PDBx) text, is the only
33
+ // required prop. Adding per-residue pLDDT scores on a
33
34
  // 0-1 scale colors the structure by confidence and puts the pLDDT key in the
34
35
  // legend.
35
36
  //
@@ -244,7 +245,101 @@ function App() {
244
245
  return (
245
246
  <div className="app" style={{ height: 480 }}>
246
247
  <ProteinStructureViewer
247
- pdb={PDB}
248
+ structure={PDB}
249
+ plddt={PLDDT}
250
+ stats={[
251
+ { label: "Known", value: "62%" },
252
+ { label: "pTM", value: "0.874" },
253
+ { label: "Mean pLDDT", value: "0.781" },
254
+ ]}
255
+ />
256
+ </div>
257
+ );
258
+ }
259
+
260
+ export default App;
261
+ ```
262
+
263
+ ### PDB and mmCIF
264
+
265
+ `structure` is the structure text, not a filename, and it accepts both legacy PDB and mmCIF (PDBx). The viewer detects the format from the contents: a `data_` block or an `_atom_site.` loop is treated as mmCIF, everything else as PDB. Binary CIF (`.bcif`) is not accepted.
266
+
267
+ **Example: MmcifProteinStructureViewer**
268
+
269
+ ```tsx
270
+ // `structure` accepts mmCIF (PDBx) as well as PDB. The viewer detects the
271
+ // format from the text.
272
+ //
273
+ // The structure below is crambin (PDB 1CRN), trimmed to the backbone atoms the
274
+ // polymer cartoon traces. A chain needs enough residues to trace: a single
275
+ // residue renders an empty canvas.
276
+
277
+ import { ProteinStructureViewer } from "@czi-sds/data-viz";
278
+
279
+ const MMCIF = `data_1CRN
280
+ #
281
+ loop_
282
+ _atom_site.group_PDB
283
+ _atom_site.id
284
+ _atom_site.type_symbol
285
+ _atom_site.label_atom_id
286
+ _atom_site.label_alt_id
287
+ _atom_site.label_comp_id
288
+ _atom_site.label_asym_id
289
+ _atom_site.label_entity_id
290
+ _atom_site.label_seq_id
291
+ _atom_site.pdbx_PDB_ins_code
292
+ _atom_site.Cartn_x
293
+ _atom_site.Cartn_y
294
+ _atom_site.Cartn_z
295
+ _atom_site.occupancy
296
+ _atom_site.B_iso_or_equiv
297
+ _atom_site.auth_seq_id
298
+ _atom_site.auth_comp_id
299
+ _atom_site.auth_asym_id
300
+ _atom_site.auth_atom_id
301
+ _atom_site.pdbx_PDB_model_num
302
+ ATOM 1 N N . THR A 1 1 ? 17.047 14.099 3.625 1.00 13.79 1 THR A N 1
303
+ ATOM 2 C CA . THR A 1 1 ? 16.967 12.784 4.338 1.00 10.80 1 THR A CA 1
304
+ ATOM 3 C C . THR A 1 1 ? 15.685 12.755 5.133 1.00 9.19 1 THR A C 1
305
+ ATOM 4 O O . THR A 1 1 ? 15.268 13.825 5.594 1.00 9.85 1 THR A O 1
306
+ ATOM 5 N N . THR A 1 2 ? 15.115 11.555 5.265 1.00 7.81 2 THR A N 1
307
+ ATOM 6 C CA . THR A 1 2 ? 13.856 11.469 6.066 1.00 8.31 2 THR A CA 1
308
+ ATOM 7 C C . THR A 1 2 ? 14.164 10.785 7.379 1.00 5.80 2 THR A C 1
309
+ ATOM 8 O O . THR A 1 2 ? 14.993 9.862 7.443 1.00 6.94 2 THR A O 1
310
+ ATOM 9 N N . CYS A 1 3 ? 13.488 11.241 8.417 1.00 5.24 3 CYS A N 1
311
+ ATOM 10 C CA . CYS A 1 3 ? 13.660 10.707 9.787 1.00 5.39 3 CYS A CA 1
312
+ ATOM 11 C C . CYS A 1 3 ? 12.269 10.431 10.323 1.00 4.45 3 CYS A C 1
313
+ ATOM 12 O O . CYS A 1 3 ? 11.393 11.308 10.185 1.00 6.54 3 CYS A O 1
314
+ ATOM 13 N N . CYS A 1 4 ? 12.019 9.272 10.928 1.00 3.90 4 CYS A N 1
315
+ ATOM 14 C CA . CYS A 1 4 ? 10.646 8.991 11.408 1.00 4.24 4 CYS A CA 1
316
+ ATOM 15 C C . CYS A 1 4 ? 10.654 8.793 12.919 1.00 3.72 4 CYS A C 1
317
+ ATOM 16 O O . CYS A 1 4 ? 11.659 8.296 13.491 1.00 5.30 4 CYS A O 1
318
+ ATOM 17 N N . PRO A 1 5 ? 9.561 9.108 13.563 1.00 3.96 5 PRO A N 1
319
+ ATOM 18 C CA . PRO A 1 5 ? 9.448 9.034 15.012 1.00 4.25 5 PRO A CA 1
320
+ ATOM 19 C C . PRO A 1 5 ? 9.288 7.670 15.606 1.00 4.96 5 PRO A C 1
321
+ ATOM 20 O O . PRO A 1 5 ? 9.490 7.519 16.819 1.00 7.44 5 PRO A O 1
322
+ ATOM 21 N N . SER A 1 6 ? 8.875 6.686 14.796 1.00 4.83 6 SER A N 1
323
+ ATOM 22 C CA . SER A 1 6 ? 8.673 5.314 15.279 1.00 4.45 6 SER A CA 1
324
+ ATOM 23 C C . SER A 1 6 ? 8.753 4.376 14.083 1.00 4.99 6 SER A C 1
325
+ ATOM 24 O O . SER A 1 6 ? 8.726 4.858 12.923 1.00 4.61 6 SER A O 1
326
+ ATOM 25 N N . ILE A 1 7 ? 8.881 3.075 14.358 1.00 4.94 7 ILE A N 1
327
+ ATOM 26 C CA . ILE A 1 7 ? 8.912 2.083 13.258 1.00 6.33 7 ILE A CA 1
328
+ ATOM 27 C C . ILE A 1 7 ? 7.581 2.090 12.506 1.00 5.32 7 ILE A C 1
329
+ ATOM 28 O O . ILE A 1 7 ? 7.670 2.031 11.245 1.00 6.85 7 ILE A O 1
330
+ ATOM 29 N N . VAL A 1 8 ? 6.458 2.162 13.159 1.00 5.02 8 VAL A N 1
331
+ ATOM 30 C CA . VAL A 1 8 ? 5.145 2.209 12.453 1.00 6.93 8 VAL A CA 1
332
+ ATOM 31 C C . VAL A 1 8 ? 5.115 3.379 11.461 1.00 5.39 8 VAL A C 1
333
+ ATOM 32 O O . VAL A 1 8 ? 4.664 3.268 10.343 1.00 6.30 8 VAL A O 1
334
+ #`;
335
+
336
+ const PLDDT = [0.45, 0.515, 0.557, 0.569, 0.567, 0.578, 0.618, 0.681];
337
+
338
+ function App() {
339
+ return (
340
+ <div className="app" style={{ height: 480 }}>
341
+ <ProteinStructureViewer
342
+ structure={MMCIF}
248
343
  plddt={PLDDT}
249
344
  stats={[
250
345
  { label: "Known", value: "62%" },
@@ -494,7 +589,7 @@ function App() {
494
589
  return (
495
590
  <div className="app" style={{ height: 480 }}>
496
591
  <ProteinStructureViewer
497
- pdb={PDB}
592
+ structure={PDB}
498
593
  residueOverlay={{
499
594
  colorScale: PLASMA_COLOR_SCALE,
500
595
  label: "Feature activation",
@@ -516,10 +611,14 @@ export default App;
516
611
 
517
612
  ### Selection and stats
518
613
 
519
- Selection is controlled through one prop. Every way of making one - clicking a residue, dragging across the sequence, clicking a chain's caption - arrives through `onSelectionChange`; echoing it back through `selection` frames it, and setting `null` zooms back out. Clicking empty space calls `onSelectionChange` with `null`.
614
+ Selection works out of the box: clicking a residue zooms in on it, and clicking empty space zooms back out, with no state on your side. Every way of making one - clicking a residue, dragging across the sequence, clicking a chain's caption - is reported through `onSelectionChange`, and clicking empty space reports `null`.
615
+
616
+ Passing `selection` takes it over, the same way `hiddenChains` takes over visibility. A click then moves the camera only once you echo `onSelectionChange` back through `selection`, and setting `null` zooms back out. Pass `null` for nothing selected rather than leaving it undefined, which hands the selection back to the viewer.
520
617
 
521
618
  A `StructureSelection` says what is selected in either of two ways, which combine: `residues` is a list of 0-based indices, and `chains` names whole chains by `chainId`. A drag across the sequence comes back as `residues`, a chain caption as `chains`, so a whole-chain selection survives the round trip at its original size rather than as the hundreds of indices it stands for. The camera frames whatever the selection covers, so a range or a chain is fitted to the view rather than approached as a point.
522
619
 
620
+ The two are shown differently, because they are different sizes of answer. Selected residues are drawn in ball-and-stick over the cartoon, with the residues around them, which is the point of looking at a site. A selected chain is left exactly as it was and the other chains dim around it - the same way pointing at a chain's name behaves, and for the same reason: a whole chain is already visible, so anything painted over it would only hide it.
621
+
523
622
  `onResidueClick` and `onResidueHover` are separate, and still report a single `ResidueRef`: they describe the residue under the pointer, which is a different fact from what the selection covers. Use them for a readout that follows the cursor, and `onSelectionChange` for what the user has actually chosen.
524
623
 
525
624
  A `ResidueRef` carries the residue in each addressing scheme a caller might need. `index` is the viewer's own key, shared with `plddt` and `residueOverlay`, and counts residues in file order straight through a chain break. `chainId` and `seqId` are what the file says, which is what the sequence panel displays and what the system that produced the structure will recognise. On a single chain numbered from 1 the two agree; on a complex they do not, so map a click back onto your own numbering with `chainId` and `seqId` rather than arithmetic on `index`.
@@ -760,7 +859,7 @@ function App() {
760
859
  : next
761
860
  )
762
861
  }
763
- pdb={PDB}
862
+ structure={PDB}
764
863
  plddt={PLDDT}
765
864
  selection={selection}
766
865
  stats={[
@@ -778,11 +877,11 @@ export default App;
778
877
 
779
878
  ### Complexes and chains
780
879
 
781
- A multi-chain structure needs nothing special: pass the whole complex as one PDB string and the viewer finds the chains itself, reporting them through `onChainsChange` as `ChainRef`s. It draws one cartoon per chain, splits the sequence panel into one grid per chain, and - when neither `plddt` nor `residueOverlay` is coloring the structure - paints each chain its own color and shows a chain legend with a swatch and a visibility toggle for each.
880
+ A multi-chain structure needs nothing special: pass the whole complex as one structure string and the viewer finds the chains itself, reporting them through `onChainsChange` as `ChainRef`s. It draws one cartoon per chain, splits the sequence panel into one grid per chain, and - when neither `plddt` nor `residueOverlay` is coloring the structure - paints each chain its own color and shows a chain legend with a swatch and a visibility toggle for each.
782
881
 
783
882
  Visibility works out of the box: the toggles own it unless you pass `hiddenChains`, which takes it over and leaves the toggles reporting through `onChainVisibilityChange`. Hiding a chain removes everything it is drawn with, which also takes it out of reach of hover and click; its sequence stays in the panel, dimmed, so the panel does not reflow on every toggle. `chainColors` overrides the palette per chain.
784
883
 
785
- Pointing at a chain's name, in the legend or above its grid in the sequence panel, lights that chain's cartoon up in the 3D view. The highlight is pink rather than the theme's usual hover tint, so it cannot be mistaken for the chain palette, the pLDDT bands or an overlay underneath it. Keyboard focus does the same, and nothing is reported to the consumer - it answers "which one is this?" without changing what is selected. `disableChainHighlightOnHover` turns it off.
884
+ Pointing at a chain's name, in the legend or above its grid in the sequence panel, dims every other chain in the 3D view so the one under the pointer stands out. The hovered chain keeps whatever coloring it already has, rather than being washed in a highlight color that would hide it. Keyboard focus does the same, and nothing is reported to the consumer - it answers "which one is this?" without changing what is selected. `disableChainHighlightOnHover` turns it off.
786
885
 
787
886
  Residue indices run straight through the chain break: on the pair below, barnase occupies 0-109 and barstar 110-198, so `plddt` is one flat array over the whole complex and one `residueOverlay` map spans both chains. Because a file numbers a complex however it likes - barstar here starts at residue 111, not 1 - `index` and `seqId` part company, so map a click back onto your own data with `chainId` and `seqId` rather than arithmetic on `index`.
788
887
 
@@ -798,7 +897,7 @@ import { useState } from "react";
798
897
 
799
898
  // A two-chain complex: barnase (chain A) with barstar (chain B) bound to it,
800
899
  // which is the shape a designed binder arrives in alongside its target. The
801
- // whole complex goes in as one `pdb` string; the viewer finds the chains and
900
+ // whole complex goes in as one `structure` string; the viewer finds the chains and
802
901
  // draws one cartoon per chain.
803
902
  //
804
903
  // Trimmed to the first 30 residues of each chain and to backbone atoms, which
@@ -1075,7 +1174,7 @@ export default function App(): JSX.Element {
1075
1174
  // produced the structure will recognise.
1076
1175
  console.log(residue.chainId, residue.seqId, residue.index)
1077
1176
  }
1078
- pdb={PDB}
1177
+ structure={PDB}
1079
1178
  plddt={PLDDT}
1080
1179
  selection={selection}
1081
1180
  stats={[
@@ -1091,7 +1190,7 @@ export default function App(): JSX.Element {
1091
1190
 
1092
1191
  ### Ligands and ions
1093
1192
 
1094
- Whatever a PDB entry carries besides its protein - ligands, ions, glycans, lipids - is drawn as ball-and-stick alongside the cartoon, with no prop to turn on. A cartoon traces a polymer backbone and a heme has none, so the two halves of a chain need two representations between them.
1193
+ Whatever a structure file carries besides its protein - ligands, ions, glycans, lipids - is drawn as ball-and-stick alongside the cartoon, with no prop to turn on. A cartoon traces a polymer backbone and a heme has none, so the two halves of a chain need two representations between them.
1095
1194
 
1096
1195
  The residue holding a ligand is drawn as sticks too, one bond out, which is what makes the ligand look bound rather than dropped in. Myoglobin's heme is held by His93, and without it the heme floats loose in the middle of a cartoon it is visibly bonded to. Covalent and metallic-coordination bonds both count - the heme's iron is held by the latter - and only the residue that holds the ligand comes, not that residue's own neighbours.
1097
1196
 
@@ -1327,7 +1426,7 @@ function App() {
1327
1426
  return (
1328
1427
  <div className="app" style={{ height: 240 }}>
1329
1428
  <ProteinStructureViewer
1330
- pdb={PDB}
1429
+ structure={PDB}
1331
1430
  plddt={PLDDT}
1332
1431
  showAxes={false}
1333
1432
  showLegend={false}
@@ -1345,7 +1444,7 @@ export default App;
1345
1444
 
1346
1445
  The viewer reads the active SDS theme for its hover and selection colors and for the sequence panel, and picks a light or dark canvas background to match. Two props override those backgrounds independently: `backgroundColor` for the 3D canvas and `sequenceViewerBackgroundColor` for the sequence panel.
1347
1446
 
1348
- The two accept different formats. Mol\* needs the canvas color as a concrete `#RRGGBB` value, so `backgroundColor` is limited to hex. The sequence panel is styled with CSS, so `sequenceViewerBackgroundColor` takes any CSS color. It paints the panel, the fade that masks residues scrolling under the header, and the "no structure available" state, so the panel stays one color throughout.
1447
+ The two accept different formats. Mol\* needs the canvas color as a concrete `#RRGGBB` value, so `backgroundColor` is limited to hex. The sequence panel is styled with CSS, so `sequenceViewerBackgroundColor` takes any CSS color. It paints the panel, the fades that mask residues scrolling past its top and bottom edges, and the "no structure available" state, so the panel stays one color throughout.
1349
1448
 
1350
1449
  ## Downloading an image
1351
1450
 
@@ -1355,7 +1454,7 @@ Passing `download` adds a capture button beneath the reset-camera control, which
1355
1454
 
1356
1455
  ```tsx
1357
1456
  <ProteinStructureViewer
1358
- pdb={PDB}
1457
+ structure={PDB}
1359
1458
  download={{ resolution: "high", filename: "barnase-barstar" }}
1360
1459
  />
1361
1460
  ```
@@ -1381,7 +1480,7 @@ Anything named in it wins, and anything left out keeps the viewer's default. So
1381
1480
  import { PluginConfig } from "molstar/lib/mol-plugin/config";
1382
1481
 
1383
1482
  <ProteinStructureViewer
1384
- pdb={PDB}
1483
+ structure={PDB}
1385
1484
  molstarSpec={{
1386
1485
  canvas3d: {
1387
1486
  // Slow the trackball down, leaving the rest of it alone.
@@ -1403,7 +1502,7 @@ The full set of settings is documented by Mol* rather than here, since it is Mol
1403
1502
  - [Canvas3D props](https://molstar.org/docs/plugin/canvas3d/) - `renderer`, `camera`, `postprocessing`, `trackball`, `marking`, and lighting.
1404
1503
  - [Plugin config](https://molstar.org/docs/plugin/config/) - the `PluginConfig` items the `config` list takes.
1405
1504
 
1406
- Two things to know about how it is applied. List-valued keys - `behaviors`, `config`, `actions`, `animations`, `customFormats`, `customParamEditors` - are appended to rather than replaced. For `config` that is what makes an override work, since Mol* reads the list in order and a later entry wins. It also means a behavior cannot be taken away: the viewer removes Mol*'s click-to-zoom camera so that `selection` alone drives the camera, and that stays removed.
1505
+ Two things to know about how it is applied. List-valued keys - `behaviors`, `config`, `actions`, `animations`, `customFormats`, `customParamEditors` - are appended to rather than replaced. For `config` that is what makes an override work, since Mol* reads the list in order and a later entry wins. It also means a behavior cannot be taken away: the viewer removes Mol*'s click-to-zoom camera so that the selection alone drives the camera, and that stays removed.
1407
1506
 
1408
1507
  And it is read once, when the plugin is created - except for `canvas3d`, which is re-applied whenever it changes. Creating the plugin throws away the camera, so the rest is deliberately not reactive; pass a `key` to remount the viewer if you need to change it.
1409
1508
 
@@ -1411,29 +1510,29 @@ And it is read once, when the plugin is created - except for `canvas3d`, which i
1411
1510
 
1412
1511
  The viewer spreads any remaining props onto its root div, so standard HTML attributes such as `className`, `id`, and `data-testid` work as usual.
1413
1512
 
1414
- | Name | Type | Default | Description |
1415
- | ------------------------------- | ----------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1416
- | `pdb` | `string` | - (required) | The structure to render, as raw PDB text. |
1417
- | `plddt` | `number[] \| null` | - | Per-residue pLDDT confidence on a 0-1 scale, in chain order. When supplied, the structure is colored by confidence unless `residueOverlay` takes over. Residues past the end of the array fall back to mid confidence. |
1418
- | `residueOverlay` | `ResidueValueOverlay \| null` | - | Per-residue values painted over the structure, replacing pLDDT coloring while set. See the table below for its shape. |
1419
- | `selection` | `StructureSelection \| null` | `null` | What is selected. Controlled: the camera frames whatever it covers, and clearing it zooms back out. See the table below for its shape. |
1420
- | `hiddenChains` | `string[]` | - | Chains hidden from the 3D view, by `chainId`. Leave undefined to let the chain legend's toggles own visibility; passing it takes that over, and the toggles then only report through `onChainVisibilityChange`. |
1421
- | `chainColors` | `Record<string, string>` | - | Color per chain, by `chainId`, as `#RRGGBB`. Chains left out fall back to the viewer's palette. Only visible while chain coloring is what is on screen, which is when neither `plddt` nor `residueOverlay` is set. |
1422
- | `showChainLegend` | `boolean` | `true` | Show the chain legend, which lists each chain with its color and a visibility toggle. Ignored on a single-chain structure, where there is nothing to tell apart or hide. |
1423
- | `disableChainHighlightOnHover` | `boolean` | `false` | Stop a chain from lighting up in the 3D view while its name is pointed at, in the legend or above its grid in the sequence panel. Turn it off where the movement is more distracting than the answer is useful. |
1424
- | `download` | `StructureDownload \| null` | - | Adds a capture button beneath the reset-camera control, which downloads a PNG of the structure. Omit for no button. See _Downloading an image_ above. |
1425
- | `molstarSpec` | `Partial<PluginUISpec>` | - | Mol* plugin spec laid over the viewer's own, which is how the whole of Mol*'s configuration is reachable without a prop here for each setting. Anything named wins; list-valued keys are appended to. Read once at creation, except `canvas3d`, which is re-applied when it changes. See _Configuring Mol\*_ above. |
1426
- | `stats` | `(StructureStat \| null)[]` | - | Up to three whole-structure stats shown along the bottom. A `null` entry reserves its column without rendering anything, so the columns never shift as values come and go. |
1427
- | `backgroundColor` | `string` | - | Canvas background, as `#RRGGBB`. Defaults to the SDS theme's base background, so the canvas follows the surrounding page in both modes. |
1428
- | `sequenceViewerBackgroundColor` | `string` | - | Sequence panel background, as any CSS color. Defaults to the SDS theme's primary surface, so the panel follows the surrounding page in both modes. |
1429
- | `showAxes` | `boolean` | `true` | Show the orientation axes widget and the reset-camera button. |
1430
- | `showSequenceViewer` | `boolean` | `true` | Show the sequence panel pinned along the bottom of the viewer. |
1431
- | `showLegend` | `boolean` | `true` | Show the stats and color scale legend overlaid on the viewer. |
1432
- | `onResidueClick` | `function` | - | `(residue: ResidueRef) => void`. Called with the residue under the pointer: `index` (0-based, across the whole structure), `compId`, `chainId`, `seqId` and `insCode`. What the click _selected_ comes through `onSelectionChange`, which a drag makes a range. |
1433
- | `onResidueHover` | `function` | - | `(residue: ResidueRef \| null) => void`. Called as the pointer moves over residues, and with `null` when it leaves the structure. |
1434
- | `onSelectionChange` | `function` | - | `(selection: StructureSelection \| null) => void`. Called with the new selection whenever the user makes one - clicking a residue, dragging across the sequence, clicking a chain caption - and with `null` when they click empty space to clear it. A whole-chain selection arrives as `{ chains: [id] }` rather than as every index on it. |
1435
- | `onChainsChange` | `function` | - | `(chains: ChainRef[]) => void`. Called with the chains found in the structure, whenever a structure is loaded. Fires with `[]` when the structure holds none. |
1436
- | `onChainVisibilityChange` | `function` | - | `(hiddenChains: string[]) => void`. Called with the chains now hidden when a visibility toggle is used. Fires whether or not `hiddenChains` is controlled, so a consumer can follow the viewer's own state without owning it. |
1513
+ | Name | Type | Default | Description |
1514
+ | ------------------------------- | ----------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1515
+ | `structure` | `string` | - (required) | The structure to render, as raw PDB or mmCIF (PDBx) text. |
1516
+ | `plddt` | `number[] \| null` | - | Per-residue pLDDT confidence on a 0-1 scale, in chain order. When supplied, the structure is colored by confidence unless `residueOverlay` takes over. Residues past the end of the array fall back to mid confidence. |
1517
+ | `residueOverlay` | `ResidueValueOverlay \| null` | - | Per-residue values painted over the structure, replacing pLDDT coloring while set. See the table below for its shape. |
1518
+ | `selection` | `StructureSelection \| null` | - | What is selected. Leave undefined to let the viewer own it, so a click zooms in on a residue with no state on your side; passing it takes that over, and a click then moves the camera only once `onSelectionChange` is echoed back. Either way the camera frames whatever it covers, and clearing it zooms back out. Residues are drawn in ball-and-stick; a whole chain dims the chains around it instead. See the table below for its shape. |
1519
+ | `hiddenChains` | `string[]` | - | Chains hidden from the 3D view, by `chainId`. Leave undefined to let the chain legend's toggles own visibility; passing it takes that over, and the toggles then only report through `onChainVisibilityChange`. |
1520
+ | `chainColors` | `Record<string, string>` | - | Color per chain, by `chainId`, as `#RRGGBB`. Chains left out fall back to the viewer's palette. Only visible while chain coloring is what is on screen, which is when neither `plddt` nor `residueOverlay` is set. |
1521
+ | `showChainLegend` | `boolean` | `true` | Show the chain legend, which lists each chain with its color and a visibility toggle. Ignored on a single-chain structure, where there is nothing to tell apart or hide. |
1522
+ | `disableChainHighlightOnHover` | `boolean` | `false` | Stop other chains from dimming in the 3D view while a chain's name is pointed at, in the legend or above its grid in the sequence panel. Turn it off where the movement is more distracting than the answer is useful. |
1523
+ | `download` | `StructureDownload \| null` | - | Adds a capture button beneath the reset-camera control, which downloads a PNG of the structure. Omit for no button. See _Downloading an image_ above. |
1524
+ | `molstarSpec` | `Partial<PluginUISpec>` | - | Mol* plugin spec laid over the viewer's own, which is how the whole of Mol*'s configuration is reachable without a prop here for each setting. Anything named wins; list-valued keys are appended to. Read once at creation, except `canvas3d`, which is re-applied when it changes. See _Configuring Mol\*_ above. |
1525
+ | `stats` | `(StructureStat \| null)[]` | - | Up to three whole-structure stats shown along the bottom. A `null` entry reserves its column without rendering anything, so the columns never shift as values come and go. |
1526
+ | `backgroundColor` | `string` | - | Canvas background, as `#RRGGBB`. Defaults to the SDS theme's base background, so the canvas follows the surrounding page in both modes. |
1527
+ | `sequenceViewerBackgroundColor` | `string` | - | Sequence panel background, as any CSS color. Defaults to the SDS theme's primary surface, so the panel follows the surrounding page in both modes. |
1528
+ | `showAxes` | `boolean` | `true` | Show the orientation axes widget and the reset-camera button. |
1529
+ | `showSequenceViewer` | `boolean` | `true` | Show the sequence panel pinned along the bottom of the viewer. |
1530
+ | `showLegend` | `boolean` | `true` | Show the stats and color scale legend overlaid on the viewer. |
1531
+ | `onResidueClick` | `function` | - | `(residue: ResidueRef) => void`. Called with the residue under the pointer: `index` (0-based, across the whole structure), `compId`, `chainId`, `seqId` and `insCode`. What the click _selected_ comes through `onSelectionChange`, which a drag makes a range. |
1532
+ | `onResidueHover` | `function` | - | `(residue: ResidueRef \| null) => void`. Called as the pointer moves over residues, and with `null` when it leaves the structure. |
1533
+ | `onSelectionChange` | `function` | - | `(selection: StructureSelection \| null) => void`. Called with the new selection whenever the user makes one - clicking a residue, dragging across the sequence, clicking a chain caption - and with `null` when they click empty space to clear it. A whole-chain selection arrives as `{ chains: [id] }` rather than as every index on it. Fires whether or not `selection` is controlled, so a consumer can follow the viewer's own selection without owning it. |
1534
+ | `onChainsChange` | `function` | - | `(chains: ChainRef[]) => void`. Called with the chains found in the structure, whenever a structure is loaded. Fires with `[]` when the structure holds none. |
1535
+ | `onChainVisibilityChange` | `function` | - | `(hiddenChains: string[]) => void`. Called with the chains now hidden when a visibility toggle is used. Fires whether or not `hiddenChains` is controlled, so a consumer can follow the viewer's own state without owning it. |
1437
1536
 
1438
1537
  ### StructureSelection
1439
1538
 
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "disableChainHighlightOnHover": {
30
30
  "defaultValue": false,
31
- "description": "Stop a chain from lighting up in the 3D view while its name is pointed at,\nin the legend or above its grid in the sequence panel.\n\nThe highlight is on by default, since on a complex it is how a reader\nfinds out which chain is which. Turn it off where the movement is more\ndistracting than the answer is useful - a grid of viewers a pointer\ncrosses on its way somewhere else, or a page driving its own highlighting\nthrough `selection`.",
31
+ "description": "Stop other chains from dimming in the 3D view while a chain's name is\npointed at, in the legend or above its grid in the sequence panel.\n\nThe dim is on by default, since on a complex it is how a reader finds out\nwhich chain is which. Turn it off where the movement is more distracting\nthan the answer is useful - a grid of viewers a pointer crosses on its way\nsomewhere else, or a page driving its own highlighting through `selection`.",
32
32
  "isRequired": false,
33
33
  "type": "boolean"
34
34
  },
@@ -77,9 +77,9 @@
77
77
  "isRequired": false,
78
78
  "type": "string"
79
79
  },
80
- "pdb": {
80
+ "structure": {
81
81
  "defaultValue": "- (required)",
82
- "description": "Structure to render, as raw PDB text.",
82
+ "description": "Structure to render, as raw PDB or mmCIF (PDBx) text.",
83
83
  "isRequired": true,
84
84
  "type": "string"
85
85
  },
@@ -94,8 +94,7 @@
94
94
  "type": "ResidueValueOverlay | null"
95
95
  },
96
96
  "selection": {
97
- "defaultValue": null,
98
- "description": "What is selected, or null when nothing is. Controlled: the camera frames\nwhatever the selection covers, and clearing it zooms back out to the\ndefault view.",
97
+ "description": "What is selected, or null when nothing is. Leave undefined to let the\nviewer own the selection, so clicking a residue zooms in on it with no\nstate on the consumer's side; passing it takes that over, and a click then\nmoves the camera only once `onSelectionChange` is echoed back here.\n\nEither way the camera frames whatever the selection covers, and clearing\nit zooms back out to the default view. Residues are drawn in\nball-and-stick over the cartoon; whole chains are left as they are and the\nchains around them dim, the same as hovering a chain's name.",
99
98
  "isRequired": false,
100
99
  "type": "StructureSelection | null"
101
100
  },
@@ -110,7 +109,7 @@
110
109
  "type": "(residue: ResidueRef | null) => void"
111
110
  },
112
111
  "onSelectionChange": {
113
- "description": "Called with the new selection whenever the user makes one - clicking a\nresidue, dragging across the sequence, clicking a chain caption - and with\n`null` when they click empty space to clear it.\n\nA whole-chain selection arrives as `{ chains: [id] }` rather than as every\nindex on it, so echoing it straight back into `selection` costs nothing.",
112
+ "description": "Called with the new selection whenever the user makes one - clicking a\nresidue, dragging across the sequence, clicking a chain caption - and with\n`null` when they click empty space to clear it.\n\nA whole-chain selection arrives as `{ chains: [id] }` rather than as every\nindex on it, so echoing it straight back into `selection` costs nothing.\nFires whether or not `selection` is controlled, so a consumer can follow\nthe viewer's own selection without owning it.",
114
113
  "isRequired": false,
115
114
  "type": "(selection: StructureSelection | null) => void"
116
115
  },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@czi-sds/mcp",
3
3
  "description": "The official MCP server for SDS",
4
- "version": "0.19.0",
4
+ "version": "0.20.1",
5
5
  "main": "dist/stdio.js",
6
6
  "files": [
7
7
  "dist",
@@ -66,5 +66,5 @@
66
66
  "turndown": "^7.2.4",
67
67
  "typescript": "^5.9.2"
68
68
  },
69
- "gitHead": "d2e4320c4fe8a6a90abde1ce2633faa76d4c73fa"
69
+ "gitHead": "52f0027db4ead40a4a311a27aefd762ed8823d47"
70
70
  }