@cyanheads/protein-mcp-server 0.4.0 → 0.4.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 (70) hide show
  1. package/AGENTS.md +32 -25
  2. package/CLAUDE.md +32 -25
  3. package/Dockerfile +16 -7
  4. package/LICENSE +1 -1
  5. package/README.md +8 -6
  6. package/changelog/0.4.x/0.4.1.md +32 -0
  7. package/changelog/0.4.x/0.4.2.md +16 -0
  8. package/changelog/template.md +60 -19
  9. package/dist/mcp-server/resources/definitions/af-summary.resource.d.ts.map +1 -1
  10. package/dist/mcp-server/resources/definitions/af-summary.resource.js +8 -1
  11. package/dist/mcp-server/resources/definitions/af-summary.resource.js.map +1 -1
  12. package/dist/mcp-server/tools/definitions/_schemas.d.ts +34 -6
  13. package/dist/mcp-server/tools/definitions/_schemas.d.ts.map +1 -1
  14. package/dist/mcp-server/tools/definitions/_schemas.js +149 -9
  15. package/dist/mcp-server/tools/definitions/_schemas.js.map +1 -1
  16. package/dist/mcp-server/tools/definitions/analyze-collection.tool.d.ts +9 -4
  17. package/dist/mcp-server/tools/definitions/analyze-collection.tool.d.ts.map +1 -1
  18. package/dist/mcp-server/tools/definitions/analyze-collection.tool.js +42 -13
  19. package/dist/mcp-server/tools/definitions/analyze-collection.tool.js.map +1 -1
  20. package/dist/mcp-server/tools/definitions/compare-structures.tool.d.ts +6 -4
  21. package/dist/mcp-server/tools/definitions/compare-structures.tool.d.ts.map +1 -1
  22. package/dist/mcp-server/tools/definitions/compare-structures.tool.js +24 -7
  23. package/dist/mcp-server/tools/definitions/compare-structures.tool.js.map +1 -1
  24. package/dist/mcp-server/tools/definitions/get-annotations.tool.d.ts +1 -1
  25. package/dist/mcp-server/tools/definitions/get-structure.tool.d.ts +2 -2
  26. package/dist/mcp-server/tools/definitions/get-structure.tool.d.ts.map +1 -1
  27. package/dist/mcp-server/tools/definitions/get-structure.tool.js +30 -7
  28. package/dist/mcp-server/tools/definitions/get-structure.tool.js.map +1 -1
  29. package/dist/mcp-server/tools/definitions/search-structures.tool.d.ts +5 -3
  30. package/dist/mcp-server/tools/definitions/search-structures.tool.d.ts.map +1 -1
  31. package/dist/mcp-server/tools/definitions/search-structures.tool.js +22 -15
  32. package/dist/mcp-server/tools/definitions/search-structures.tool.js.map +1 -1
  33. package/dist/mcp-server/tools/definitions/track-ligands.tool.d.ts +2 -2
  34. package/dist/services/alignment/alignment-service.d.ts +7 -0
  35. package/dist/services/alignment/alignment-service.d.ts.map +1 -1
  36. package/dist/services/alignment/alignment-service.js +22 -3
  37. package/dist/services/alignment/alignment-service.js.map +1 -1
  38. package/dist/services/alphafold/alphafold-service.d.ts.map +1 -1
  39. package/dist/services/alphafold/alphafold-service.js +1 -0
  40. package/dist/services/alphafold/alphafold-service.js.map +1 -1
  41. package/dist/services/beacons/beacons-service.d.ts.map +1 -1
  42. package/dist/services/foldseek/foldseek-service.d.ts +1 -1
  43. package/dist/services/foldseek/foldseek-service.d.ts.map +1 -1
  44. package/dist/services/foldseek/foldseek-service.js +5 -1
  45. package/dist/services/foldseek/foldseek-service.js.map +1 -1
  46. package/dist/services/rcsb/facets.d.ts +19 -19
  47. package/dist/services/rcsb/facets.d.ts.map +1 -1
  48. package/dist/services/rcsb/rcsb-service.d.ts +2 -2
  49. package/dist/services/rcsb/rcsb-service.d.ts.map +1 -1
  50. package/dist/services/rcsb/rcsb-service.js +24 -4
  51. package/dist/services/rcsb/rcsb-service.js.map +1 -1
  52. package/dist/services/rcsb/types.d.ts +14 -3
  53. package/dist/services/rcsb/types.d.ts.map +1 -1
  54. package/dist/services/shared/attribution.d.ts +6 -3
  55. package/dist/services/shared/attribution.d.ts.map +1 -1
  56. package/dist/services/shared/attribution.js +12 -2
  57. package/dist/services/shared/attribution.js.map +1 -1
  58. package/dist/services/shared/http.d.ts +7 -2
  59. package/dist/services/shared/http.d.ts.map +1 -1
  60. package/dist/services/shared/http.js +8 -18
  61. package/dist/services/shared/http.js.map +1 -1
  62. package/dist/services/shared/identifiers.d.ts +7 -0
  63. package/dist/services/shared/identifiers.d.ts.map +1 -1
  64. package/dist/services/shared/identifiers.js +14 -1
  65. package/dist/services/shared/identifiers.js.map +1 -1
  66. package/dist/services/uniprot/uniprot-service.d.ts.map +1 -1
  67. package/dist/services/uniprot/uniprot-service.js +1 -0
  68. package/dist/services/uniprot/uniprot-service.js.map +1 -1
  69. package/package.json +11 -10
  70. package/server.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"af-summary.resource.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/af-summary.resource.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"af-summary.resource.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/af-summary.resource.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAE1F,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC,gBAAgB,EAAE;IAC1D,IAAI,EAAE,6BAA6B;IACnC,KAAK,EAAE,6BAA6B;IACpC,WAAW,EACT,wIAAwI;IAC1I,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;KACjE,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QAC3D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;QACxF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;QAC3E,iBAAiB,EAAE,CAAC;aACjB,MAAM,CAAC;YACN,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;YACzD,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;YACtD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;YAC5D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;SAC3D,CAAC;aACD,QAAQ,EAAE;aACV,QAAQ,CAAC,wCAAwC,CAAC;QACrD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAC5D,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;QAClF,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;QACxE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;QACpE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;QACzE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;QAC1E,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;KACxF,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG;QACvB,2EAA2E;QAC3E,4EAA4E;QAC5E,8EAA8E;QAC9E,kDAAkD;QAClD,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC;YAC5E,MAAM,aAAa,CACjB,IAAI,MAAM,CAAC,OAAO,6IAA6I,EAC/J,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAC5B,CAAC;QACJ,MAAM,KAAK,GAAG,MAAM,mBAAmB,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC7E,IAAI,CAAC,KAAK;YACR,MAAM,QAAQ,CAAC,gCAAgC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,EAAE;gBAC7E,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB,CAAC,CAAC;QACL,OAAO;YACL,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;YACxC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,GAAG,CAAC,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9E,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClF,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAAK,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrF,GAAG,CAAC,OAAO,KAAK,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvF,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC3D,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -1,12 +1,25 @@
1
1
  /**
2
- * @fileoverview Shared Zod output schemas and helpers for the facet breakdown
3
- * surfaced by `protein_analyze_collection` and `protein_search_structures`. Nesting
4
- * is bounded to two levels (a dimension's buckets may each carry one child
5
- * dimension), matching the deepest cross-tab the facet engine produces.
2
+ * @fileoverview Shared schemas and helpers for the two tools that expose a facet
3
+ * breakdown and a `content_type` scope `protein_analyze_collection` and
4
+ * `protein_search_structures`. Facet nesting is bounded to two levels (a
5
+ * dimension's buckets may each carry one child dimension), matching the deepest
6
+ * cross-tab the facet engine produces. Every dimension position also reports its
7
+ * coverage gap, so buckets that sum to less than the stated total say so.
6
8
  * @module mcp-server/tools/definitions/_schemas
7
9
  */
8
10
  import { z } from '@cyanheads/mcp-ts-core';
9
11
  import type { FacetDimension } from '../../../services/rcsb/types.js';
12
+ /**
13
+ * The agent-facing `content_type` scope → the RCSB content universes it selects.
14
+ * `all` names both members explicitly: omitting `results_content_type` upstream
15
+ * is experimental-only, not a union. Shared so the two tools that expose the
16
+ * enum cannot drift apart on what a scope means.
17
+ */
18
+ export declare const CONTENT_TYPE_SCOPES: {
19
+ experimental: "experimental"[];
20
+ predicted: "computational"[];
21
+ all: ("computational" | "experimental")[];
22
+ };
10
23
  /** A facet dimension and its buckets. */
11
24
  export declare const facetDimensionSchema: z.ZodObject<{
12
25
  dimension: z.ZodString;
@@ -24,15 +37,30 @@ export declare const facetDimensionSchema: z.ZodObject<{
24
37
  rangeTo: z.ZodOptional<z.ZodNumber>;
25
38
  }, z.core.$strip>>;
26
39
  truncated: z.ZodOptional<z.ZodBoolean>;
40
+ missingValueCount: z.ZodNumber;
27
41
  }, z.core.$strip>>>;
28
42
  }, z.core.$strip>>;
29
43
  truncated: z.ZodOptional<z.ZodBoolean>;
44
+ missingValueCount: z.ZodNumber;
30
45
  }, z.core.$strip>;
31
46
  export type FacetDimensionOutput = z.infer<typeof facetDimensionSchema>;
32
- /** Project a domain {@link FacetDimension} to the output shape, capping buckets. */
33
- export declare function toFacetOutput(facet: FacetDimension, cap: number): FacetDimensionOutput;
47
+ /**
48
+ * Project a domain {@link FacetDimension} to the output shape, capping buckets.
49
+ * `total` is the population the buckets describe — the response total for a
50
+ * top-level dimension, and the parent bucket's count for a nested one.
51
+ */
52
+ export declare function toFacetOutput(facet: FacetDimension, cap: number, total: number): FacetDimensionOutput;
34
53
  /** Render a list of facet dimensions to markdown lines for `format()` parity. */
35
54
  export declare function renderFacets(facets: FacetDimensionOutput[]): string[];
55
+ /**
56
+ * Advisory fragments for the dimensions whose coverage gap is material, ready to
57
+ * join into the shared `notice` field alongside a caller's other advisories.
58
+ *
59
+ * A dimension that aggregated to nothing at all is skipped: the empty-dimension
60
+ * line in `format()` (and, where it applies, the caller's scope notice) already
61
+ * report it, and quantifying a 100% gap on top adds nothing.
62
+ */
63
+ export declare function coverageNotices(facets: FacetDimensionOutput[], total: number): string[];
36
64
  /** License + citation for one upstream data source that contributed to a response. */
37
65
  export declare const attributionSchema: z.ZodObject<{
38
66
  source: z.ZodString;
@@ -1 +1 @@
1
- {"version":3,"file":"_schemas.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/_schemas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AA4D/D,yCAAyC;AACzC,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;iBAW4B,CAAC;AAE9D,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAWxE,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,oBAAoB,CAsBtF;AAkBD,iFAAiF;AACjF,wBAAgB,YAAY,CAAC,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,CAarE;AAED,sFAAsF;AACtF,eAAO,MAAM,iBAAiB;;;;;iBAWmD,CAAC;AAElF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,gGAAgG;AAChG,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,iBAAiB,EAAE,GAAG,MAAM,EAAE,CAM7E"}
1
+ {"version":3,"file":"_schemas.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/_schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAC3C,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE5E;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;CAIuC,CAAC;AAiExE,yCAAyC;AACzC,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;iBAgB4B,CAAC;AAE9D,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAgCxE;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,cAAc,EACrB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GACZ,oBAAoB,CAwBtB;AA0CD,iFAAiF;AACjF,wBAAgB,YAAY,CAAC,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,CAoBrE;AAuDD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,oBAAoB,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAcvF;AAED,sFAAsF;AACtF,eAAO,MAAM,iBAAiB;;;;;iBAWmD,CAAC;AAElF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,gGAAgG;AAChG,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,iBAAiB,EAAE,GAAG,MAAM,EAAE,CAM7E"}
@@ -1,11 +1,24 @@
1
1
  /**
2
- * @fileoverview Shared Zod output schemas and helpers for the facet breakdown
3
- * surfaced by `protein_analyze_collection` and `protein_search_structures`. Nesting
4
- * is bounded to two levels (a dimension's buckets may each carry one child
5
- * dimension), matching the deepest cross-tab the facet engine produces.
2
+ * @fileoverview Shared schemas and helpers for the two tools that expose a facet
3
+ * breakdown and a `content_type` scope `protein_analyze_collection` and
4
+ * `protein_search_structures`. Facet nesting is bounded to two levels (a
5
+ * dimension's buckets may each carry one child dimension), matching the deepest
6
+ * cross-tab the facet engine produces. Every dimension position also reports its
7
+ * coverage gap, so buckets that sum to less than the stated total say so.
6
8
  * @module mcp-server/tools/definitions/_schemas
7
9
  */
8
10
  import { z } from '@cyanheads/mcp-ts-core';
11
+ /**
12
+ * The agent-facing `content_type` scope → the RCSB content universes it selects.
13
+ * `all` names both members explicitly: omitting `results_content_type` upstream
14
+ * is experimental-only, not a union. Shared so the two tools that expose the
15
+ * enum cannot drift apart on what a scope means.
16
+ */
17
+ export const CONTENT_TYPE_SCOPES = {
18
+ experimental: ['experimental'],
19
+ predicted: ['computational'],
20
+ all: ['experimental', 'computational'],
21
+ };
9
22
  /** A flat (leaf) facet bucket. */
10
23
  const leafBucketSchema = z
11
24
  .object({
@@ -30,6 +43,9 @@ const childDimensionSchema = z
30
43
  .boolean()
31
44
  .optional()
32
45
  .describe('True when this nested bucket list was capped by the per-dimension bucket limit.'),
46
+ missingValueCount: z
47
+ .number()
48
+ .describe('Matches inside the parent bucket that carry no value for this nested attribute, so they fall in no nested bucket. 0 when the nested buckets account for the whole parent bucket.'),
33
49
  })
34
50
  .describe('A nested cross-tab dimension within a parent bucket.');
35
51
  /** A top-level facet bucket, optionally carrying a nested cross-tab dimension. */
@@ -62,6 +78,9 @@ export const facetDimensionSchema = z
62
78
  .boolean()
63
79
  .optional()
64
80
  .describe('True when buckets were capped by the per-dimension bucket limit.'),
81
+ missingValueCount: z
82
+ .number()
83
+ .describe('Matches in scope that carry no value for this attribute, so they count toward the response total but fall in no bucket (e.g. computed models have no experimental method; solution-NMR entries have no diffraction resolution). Independent of truncation — measured before the bucket cap is applied. 0 means no shortfall was detectable: a multi-valued attribute such as organism can place one match in several buckets, which offsets the shortfall rather than adding to it.'),
65
84
  })
66
85
  .describe('A facet dimension and its aggregation buckets.');
67
86
  /** Copy the numeric-histogram range onto an output bucket when present. */
@@ -70,8 +89,32 @@ function withRange(b) {
70
89
  ? { rangeFrom: b.rangeFrom, rangeTo: b.rangeTo }
71
90
  : {};
72
91
  }
73
- /** Project a domain {@link FacetDimension} to the output shape, capping buckets. */
74
- export function toFacetOutput(facet, cap) {
92
+ /**
93
+ * How many of `total` the buckets leave unaccounted for — matches carrying no
94
+ * value for the faceted attribute, which land in no bucket.
95
+ *
96
+ * Two properties carry the correctness:
97
+ *
98
+ * - `buckets` must be the UNCAPPED list. Measured after {@link toFacetOutput}
99
+ * slices to the bucket cap, the difference would fold in what the cap removed
100
+ * — a separate condition the response already discloses through `truncated` /
101
+ * `shown` / `cap`.
102
+ * - The result floors at 0. A multi-valued attribute puts one match in several
103
+ * buckets (an entry with two source organisms lands in both), so the sum can
104
+ * legitimately exceed the total. That is over-counting, a different phenomenon
105
+ * from missing coverage, and this field does not claim to describe it. On a
106
+ * dimension that is both multi-valued and sparse the two net out, so 0 means
107
+ * "no shortfall detectable", not proof that every match reached a bucket.
108
+ */
109
+ function missingValueCount(buckets, total) {
110
+ return Math.max(0, total - buckets.reduce((sum, b) => sum + b.count, 0));
111
+ }
112
+ /**
113
+ * Project a domain {@link FacetDimension} to the output shape, capping buckets.
114
+ * `total` is the population the buckets describe — the response total for a
115
+ * top-level dimension, and the parent bucket's count for a nested one.
116
+ */
117
+ export function toFacetOutput(facet, cap, total) {
75
118
  const truncated = facet.buckets.length > cap;
76
119
  return {
77
120
  dimension: facet.dimension,
@@ -87,11 +130,13 @@ export function toFacetOutput(facet, cap) {
87
130
  .slice(0, cap)
88
131
  .map((cb) => ({ label: cb.label, count: cb.count, ...withRange(cb) })),
89
132
  ...(c.buckets.length > cap ? { truncated: true } : {}),
133
+ missingValueCount: missingValueCount(c.buckets, b.count),
90
134
  })),
91
135
  }
92
136
  : {}),
93
137
  })),
94
138
  ...(truncated ? { truncated: true } : {}),
139
+ missingValueCount: missingValueCount(facet.buckets, total),
95
140
  };
96
141
  }
97
142
  /**
@@ -103,21 +148,116 @@ function renderBucket(b) {
103
148
  const range = b.rangeFrom !== undefined && b.rangeTo !== undefined ? ` [${b.rangeFrom}–${b.rangeTo})` : '';
104
149
  return `${b.label}${range}: ${b.count}`;
105
150
  }
151
+ /**
152
+ * Stands in for a dimension that aggregated to nothing. A bare `**dimension**`
153
+ * heading with no buckets under it reads as a broken response; say the scope
154
+ * produced no data instead. Why it is empty (a zero-hit query, or an attribute
155
+ * the scoped content universe does not carry) is the caller's notice to give.
156
+ */
157
+ const EMPTY_DIMENSION_LINE = '_No data for this dimension in the current scope._';
158
+ /** Inline twin of {@link EMPTY_DIMENSION_LINE} for a nested cross-tab child that aggregated to nothing. */
159
+ const EMPTY_CHILD_DIMENSION_TEXT = '_no data in this scope_';
160
+ /**
161
+ * The parenthetical after a dimension's name: the bucket-cap marker and the
162
+ * coverage gap, in one group so a dimension carrying both does not sprout two
163
+ * sets of parentheses.
164
+ */
165
+ function dimensionFlags(d) {
166
+ const flags = [
167
+ d.truncated ? 'truncated' : '',
168
+ d.missingValueCount > 0 ? `${d.missingValueCount} with no value` : '',
169
+ ].filter(Boolean);
170
+ return flags.length > 0 ? ` (${flags.join('; ')})` : '';
171
+ }
106
172
  /** Render a list of facet dimensions to markdown lines for `format()` parity. */
107
173
  export function renderFacets(facets) {
108
174
  const lines = [];
109
175
  for (const f of facets) {
110
- lines.push(`\n**${f.dimension}**${f.truncated ? ' (truncated)' : ''}`);
176
+ lines.push(`\n**${f.dimension}**${dimensionFlags(f)}`);
177
+ if (f.buckets.length === 0) {
178
+ lines.push(EMPTY_DIMENSION_LINE);
179
+ continue;
180
+ }
111
181
  for (const b of f.buckets) {
112
182
  lines.push(`- ${renderBucket(b)}`);
113
183
  for (const c of b.children ?? []) {
114
- const inner = c.buckets.map(renderBucket).join(', ');
115
- lines.push(` - ${c.dimension} → ${inner}${c.truncated ? ' (truncated)' : ''}`);
184
+ const inner = c.buckets.length === 0
185
+ ? EMPTY_CHILD_DIMENSION_TEXT
186
+ : c.buckets.map(renderBucket).join(', ');
187
+ lines.push(` - ${c.dimension} → ${inner}${dimensionFlags(c)}`);
116
188
  }
117
189
  }
118
190
  }
119
191
  return lines;
120
192
  }
193
+ /**
194
+ * Share of a dimension's scope that must carry no value before the coverage gap
195
+ * earns prose on top of the always-present `missingValueCount` field.
196
+ *
197
+ * 1% separates the two regimes seen in the live data. Below it the difference is
198
+ * rounding-scale against the distribution the buckets describe — `method` under
199
+ * `content_type: "experimental"` misses 0.09% — and prose on every response
200
+ * would be noise. At or above it the buckets describe a visibly different
201
+ * population than the stated total: `resolution` under `"experimental"` misses
202
+ * 3.8% to entries with no diffraction resolution, and every experimental-only
203
+ * dimension misses ~45% of a mixed `"all"` scope.
204
+ */
205
+ const MATERIAL_COVERAGE_GAP = 0.01;
206
+ /**
207
+ * Flatten a facet tree to one entry per dimension position. A child dimension
208
+ * repeats under every parent bucket, so its counts are summed into a single
209
+ * position — otherwise a 50-bucket cross-tab would yield fifty advisories about
210
+ * the same attribute. Parent buckets the cap removed are not represented, which
211
+ * is correct: the aggregate then describes exactly the buckets the response shows.
212
+ */
213
+ function coveragePositions(facets, total) {
214
+ const positions = [];
215
+ for (const f of facets) {
216
+ positions.push({
217
+ dimension: f.dimension,
218
+ missing: f.missingValueCount,
219
+ scope: total,
220
+ bucketCount: f.buckets.length,
221
+ });
222
+ const children = new Map();
223
+ for (const b of f.buckets) {
224
+ for (const c of b.children ?? []) {
225
+ const acc = children.get(c.dimension) ?? { missing: 0, scope: 0, bucketCount: 0 };
226
+ acc.missing += c.missingValueCount;
227
+ acc.scope += b.count;
228
+ acc.bucketCount += c.buckets.length;
229
+ children.set(c.dimension, acc);
230
+ }
231
+ }
232
+ for (const [dimension, acc] of children)
233
+ positions.push({ dimension, ...acc });
234
+ }
235
+ return positions;
236
+ }
237
+ /**
238
+ * Advisory fragments for the dimensions whose coverage gap is material, ready to
239
+ * join into the shared `notice` field alongside a caller's other advisories.
240
+ *
241
+ * A dimension that aggregated to nothing at all is skipped: the empty-dimension
242
+ * line in `format()` (and, where it applies, the caller's scope notice) already
243
+ * report it, and quantifying a 100% gap on top adds nothing.
244
+ */
245
+ export function coverageNotices(facets, total) {
246
+ const seen = new Set();
247
+ const notices = [];
248
+ for (const p of coveragePositions(facets, total)) {
249
+ if (p.scope <= 0 || p.bucketCount === 0)
250
+ continue;
251
+ if (p.missing / p.scope < MATERIAL_COVERAGE_GAP)
252
+ continue;
253
+ if (seen.has(p.dimension))
254
+ continue;
255
+ seen.add(p.dimension);
256
+ const pct = ((p.missing / p.scope) * 100).toFixed(1);
257
+ notices.push(`${p.dimension} buckets cover ${p.scope - p.missing} of ${p.scope} matches; the other ${p.missing} (${pct}%) carry no ${p.dimension} value and fall in no bucket.`);
258
+ }
259
+ return notices;
260
+ }
121
261
  /** License + citation for one upstream data source that contributed to a response. */
122
262
  export const attributionSchema = z
123
263
  .object({
@@ -1 +1 @@
1
- {"version":3,"file":"_schemas.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/_schemas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"_schemas.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/_schemas.ts"],"names":[],"mappings":"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"}
@@ -11,25 +11,25 @@ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
11
11
  export declare const analyzeCollection: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
12
12
  group_by: z.ZodArray<z.ZodEnum<{
13
13
  method: "method";
14
- organism: "organism";
15
- resolution: "resolution";
16
14
  molecular_weight: "molecular_weight";
15
+ organism: "organism";
17
16
  polymer_type: "polymer_type";
18
17
  release_year: "release_year";
18
+ resolution: "resolution";
19
19
  }>>;
20
20
  query: z.ZodOptional<z.ZodString>;
21
21
  organism: z.ZodOptional<z.ZodString>;
22
22
  method: z.ZodOptional<z.ZodString>;
23
23
  max_resolution: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
24
24
  content_type: z.ZodDefault<z.ZodEnum<{
25
+ all: "all";
25
26
  experimental: "experimental";
26
27
  predicted: "predicted";
27
- all: "all";
28
28
  }>>;
29
29
  interval: z.ZodOptional<z.ZodUnion<readonly [z.ZodCoercedNumber<unknown>, z.ZodEnum<{
30
- year: "year";
31
30
  month: "month";
32
31
  quarter: "quarter";
32
+ year: "year";
33
33
  }>]>>;
34
34
  bucket_limit: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
35
35
  }, z.core.$strip>, z.ZodObject<{
@@ -50,9 +50,11 @@ export declare const analyzeCollection: import("@cyanheads/mcp-ts-core").ToolDef
50
50
  rangeTo: z.ZodOptional<z.ZodNumber>;
51
51
  }, z.core.$strip>>;
52
52
  truncated: z.ZodOptional<z.ZodBoolean>;
53
+ missingValueCount: z.ZodNumber;
53
54
  }, z.core.$strip>>>;
54
55
  }, z.core.$strip>>;
55
56
  truncated: z.ZodOptional<z.ZodBoolean>;
57
+ missingValueCount: z.ZodNumber;
56
58
  }, z.core.$strip>>;
57
59
  }, z.core.$strip>, readonly [{
58
60
  readonly reason: "unknown_dimension";
@@ -62,5 +64,8 @@ export declare const analyzeCollection: import("@cyanheads/mcp-ts-core").ToolDef
62
64
  }], {
63
65
  readonly scope: z.ZodOptional<z.ZodString>;
64
66
  readonly notice: z.ZodOptional<z.ZodString>;
67
+ readonly truncated: z.ZodOptional<z.ZodBoolean>;
68
+ readonly shown: z.ZodOptional<z.ZodNumber>;
69
+ readonly cap: z.ZodOptional<z.ZodNumber>;
65
70
  }>;
66
71
  //# sourceMappingURL=analyze-collection.tool.d.ts.map
@@ -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;AAOjE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4H5B,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;AAwBjE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuJ5B,CAAC"}
@@ -9,9 +9,16 @@
9
9
  import { tool, z } from '@cyanheads/mcp-ts-core';
10
10
  import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
11
11
  import { getServerConfig } from '../../../config/server-config.js';
12
- import { buildFacetSpec, FACET_DIMENSION_NAMES } from '../../../services/rcsb/facets.js';
12
+ import { buildFacetSpec, FACET_DIMENSION_NAMES, } from '../../../services/rcsb/facets.js';
13
13
  import { getRcsbService } from '../../../services/rcsb/rcsb-service.js';
14
- import { facetDimensionSchema, renderFacets, toFacetOutput } from './_schemas.js';
14
+ import { CONTENT_TYPE_SCOPES, coverageNotices, facetDimensionSchema, renderFacets, toFacetOutput, } from './_schemas.js';
15
+ /**
16
+ * Dimensions RCSB cannot aggregate over computed models: an AlphaFold /
17
+ * ModelArchive record carries no experimental method or resolution, so the
18
+ * facet key is absent from the response rather than returning empty buckets.
19
+ * The other four dimensions aggregate normally under predicted content.
20
+ */
21
+ const EXPERIMENTAL_ONLY_DIMENSIONS = new Set(['method', 'resolution']);
15
22
  export const analyzeCollection = tool('protein_analyze_collection', {
16
23
  title: 'protein-mcp-server: analyze collection',
17
24
  description: 'Profile the PDB into distributions and trends over an optional scoping query: counts by method, ' +
@@ -48,7 +55,8 @@ export const analyzeCollection = tool('protein_analyze_collection', {
48
55
  content_type: z
49
56
  .enum(['experimental', 'predicted', 'all'])
50
57
  .default('experimental')
51
- .describe('Which structure universe to profile. Default experimental.'),
58
+ .describe('Which structure universe to profile. Default experimental. Computed models carry no ' +
59
+ 'experimental metadata, so method and resolution return nothing under "predicted".'),
52
60
  interval: z
53
61
  .union([
54
62
  // Coerce the numeric arm: many clients stringify tool args, and "0.5" must
@@ -76,17 +84,21 @@ export const analyzeCollection = tool('protein_analyze_collection', {
76
84
  }),
77
85
  enrichment: {
78
86
  scope: z.string().optional().describe('Echoed scope description for follow-up calls.'),
79
- notice: z.string().optional().describe('Advisory note (e.g. bucket truncation, empty scope).'),
87
+ notice: z
88
+ .string()
89
+ .optional()
90
+ .describe('Advisory note (bucket truncation, empty scope, dimensions with no data under the requested content_type, dimensions whose buckets cover materially less than the total). Carries every applicable advisory in one string.'),
91
+ truncated: z
92
+ .boolean()
93
+ .optional()
94
+ .describe('True when a dimension had more buckets than the applied cap.'),
95
+ shown: z.number().optional().describe('Buckets returned for the capped dimension.'),
96
+ cap: z.number().optional().describe('Per-dimension bucket cap that was applied.'),
80
97
  },
81
98
  async handler(input, ctx) {
82
99
  const cfg = getServerConfig();
83
100
  const rcsb = getRcsbService();
84
101
  const cap = input.bucket_limit ?? cfg.facetBucketCap;
85
- const contentType = input.content_type === 'all'
86
- ? undefined
87
- : input.content_type === 'predicted'
88
- ? 'computational'
89
- : 'experimental';
90
102
  const [primary, secondary] = input.group_by;
91
103
  if (!primary)
92
104
  throw ctx.fail('unknown_dimension', 'group_by requires at least one dimension.', {
@@ -100,12 +112,29 @@ export const analyzeCollection = tool('protein_analyze_collection', {
100
112
  ...(typeof input.max_resolution === 'number'
101
113
  ? { maxResolution: input.max_resolution }
102
114
  : {}),
103
- ...(contentType ? { contentType } : {}),
115
+ contentType: CONTENT_TYPE_SCOPES[input.content_type],
104
116
  }, [spec], ctx);
105
- const out = facets.map((f) => toFacetOutput(f, cap));
106
- if (out.some((f) => f.truncated)) {
107
- ctx.enrich.notice(`One or more dimensions exceeded ${cap} buckets and were capped; scope the query tighter for the long tail.`);
117
+ const out = facets.map((f) => toFacetOutput(f, cap, total));
118
+ // Every advisory writes the same `notice` field (ctx.enrich.truncated routes
119
+ // through it and is last-wins), and a cross-tab under predicted content can
120
+ // trip several at once — collect the fragments and emit them as ONE notice.
121
+ const notices = [];
122
+ const capped = out.find((f) => f.truncated);
123
+ if (capped) {
124
+ ctx.enrich({ truncated: true, shown: capped.buckets.length, cap });
125
+ notices.push(`One or more dimensions exceeded ${cap} buckets and were capped; scope the query tighter for the long tail.`);
126
+ }
127
+ if (input.content_type === 'predicted') {
128
+ // Deduped: group_by permits the same dimension twice, and "method and
129
+ // method" would read as two findings.
130
+ const blind = [...new Set(input.group_by.filter((d) => EXPERIMENTAL_ONLY_DIMENSIONS.has(d)))];
131
+ if (blind.length > 0) {
132
+ notices.push(`${blind.join(' and ')} ${blind.length > 1 ? 'are' : 'is'} empty under content_type "predicted": computed models carry no experimental method or resolution metadata. Use content_type "experimental" or "all", or group by organism, polymer_type, release_year, or molecular_weight.`);
133
+ }
108
134
  }
135
+ notices.push(...coverageNotices(out, total));
136
+ if (notices.length > 0)
137
+ ctx.enrich.notice(notices.join(' '));
109
138
  const scopeBits = [input.query, input.organism, input.method].filter(Boolean);
110
139
  if (scopeBits.length > 0)
111
140
  ctx.enrich({ scope: scopeBits.join(' · ') });
@@ -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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"}
@@ -13,13 +13,13 @@ export declare const compareStructures: import("@cyanheads/mcp-ts-core").ToolDef
13
13
  chain: z.ZodOptional<z.ZodString>;
14
14
  }, z.core.$strip>>;
15
15
  reference: z.ZodDefault<z.ZodEnum<{
16
- first: "first";
17
16
  all_pairs: "all_pairs";
17
+ first: "first";
18
18
  }>>;
19
19
  method: z.ZodDefault<z.ZodEnum<{
20
- "tm-align": "tm-align";
21
- "fatcat-rigid": "fatcat-rigid";
22
20
  "fatcat-flexible": "fatcat-flexible";
21
+ "fatcat-rigid": "fatcat-rigid";
22
+ "tm-align": "tm-align";
23
23
  }>>;
24
24
  timeout_s: z.ZodOptional<z.ZodNumber>;
25
25
  resume: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -30,8 +30,8 @@ export declare const compareStructures: import("@cyanheads/mcp-ts-core").ToolDef
30
30
  }, z.core.$strip>, z.ZodObject<{
31
31
  method: z.ZodString;
32
32
  reference: z.ZodEnum<{
33
- first: "first";
34
33
  all_pairs: "all_pairs";
34
+ first: "first";
35
35
  }>;
36
36
  pairs: z.ZodArray<z.ZodObject<{
37
37
  a: z.ZodString;
@@ -44,6 +44,8 @@ export declare const compareStructures: import("@cyanheads/mcp-ts-core").ToolDef
44
44
  tmScore: z.ZodOptional<z.ZodNumber>;
45
45
  rmsd: z.ZodOptional<z.ZodNumber>;
46
46
  alignedResidues: z.ZodOptional<z.ZodNumber>;
47
+ modeledResidues: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
48
+ coverage: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
47
49
  uuid: z.ZodOptional<z.ZodString>;
48
50
  error: z.ZodOptional<z.ZodString>;
49
51
  }, z.core.$strip>>;
@@ -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;AAwGjE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmI5B,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;AAsHjE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8I5B,CAAC"}
@@ -77,6 +77,16 @@ const outputSchema = z.object({
77
77
  'rmsd and alignedResidues to spot such cases.'),
78
78
  rmsd: z.number().optional().describe('RMSD in Å over aligned residues.'),
79
79
  alignedResidues: z.number().optional().describe('Number of aligned residue pairs.'),
80
+ modeledResidues: z
81
+ .array(z.number())
82
+ .length(2)
83
+ .optional()
84
+ .describe('Modeled residue count per structure, ordered [a, b] to match this pair. A large gap between the two is the terminal-length asymmetry that can depress tmScore.'),
85
+ coverage: z
86
+ .array(z.number())
87
+ .length(2)
88
+ .optional()
89
+ .describe("Alignment coverage per structure as a 0–100 percentage of that structure's own modeled-residue count — not of the full sequence and not of the shorter structure — ordered [a, b] to match this pair. Read alongside modeledResidues: equal aligned counts give the shorter structure the higher coverage."),
80
90
  uuid: z
81
91
  .string()
82
92
  .optional()
@@ -94,10 +104,11 @@ export const compareStructures = tool('protein_compare_structures', {
94
104
  'job, fanned out with a concurrency cap and per-pair partial success — a pair still computing when the ' +
95
105
  'budget elapses returns status "computing" with its job UUID, and a failed pair degrades its row without ' +
96
106
  "sinking the others. Re-call with a matching entry in resume[] to poll a computing pair's UUID instead " +
97
- 'of resubmitting. Returns TM-score, RMSD, and aligned-residue count per pair. TM-score is ' +
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 ' +
98
109
  'length-normalized and can shift sharply between structures that differ only by a terminal residue or ' +
99
- 'two — the greedy superposition can settle into a worse local optimum — so read tmScore alongside rmsd ' +
100
- 'and alignedResidues, the columns that make such cases diagnosable.',
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.',
101
112
  annotations: { readOnlyHint: true, openWorldHint: true },
102
113
  errors: [
103
114
  {
@@ -157,6 +168,10 @@ export const compareStructures = tool('protein_compare_structures', {
157
168
  ...(typeof outcome.scores.alignedResidues === 'number'
158
169
  ? { alignedResidues: outcome.scores.alignedResidues }
159
170
  : {}),
171
+ ...(outcome.scores.modeledResidues
172
+ ? { modeledResidues: outcome.scores.modeledResidues }
173
+ : {}),
174
+ ...(outcome.scores.coverage ? { coverage: outcome.scores.coverage } : {}),
160
175
  };
161
176
  }
162
177
  if (outcome.status === 'computing') {
@@ -177,13 +192,15 @@ export const compareStructures = tool('protein_compare_structures', {
177
192
  },
178
193
  format: (result) => {
179
194
  const lines = [`## Structure comparison (${result.method}, ${result.reference})`];
180
- lines.push('\n| Pair | Status | TM-score | RMSD (Å) | Aligned |');
181
- lines.push('|---|---|---|---|---|');
195
+ lines.push('\n| Pair | Status | TM-score | RMSD (Å) | Aligned | Modeled a / b | Coverage % a / b |');
196
+ lines.push('|---|---|---|---|---|---|---|');
182
197
  for (const p of result.pairs) {
183
198
  const tm = typeof p.tmScore === 'number' ? p.tmScore.toFixed(3) : '—';
184
199
  const rmsd = typeof p.rmsd === 'number' ? p.rmsd.toFixed(2) : '—';
185
200
  const aligned = typeof p.alignedResidues === 'number' ? String(p.alignedResidues) : '—';
186
- lines.push(`| ${p.a} ${p.b} | ${p.status} | ${tm} | ${rmsd} | ${aligned} |`);
201
+ const modeled = p.modeledResidues ? p.modeledResidues.join(' / ') : '—';
202
+ const coverage = p.coverage ? p.coverage.join(' / ') : '—';
203
+ lines.push(`| ${p.a} ↔ ${p.b} | ${p.status} | ${tm} | ${rmsd} | ${aligned} | ${modeled} | ${coverage} |`);
187
204
  }
188
205
  const notes = result.pairs.filter((p) => p.error || p.uuid);
189
206
  if (notes.length > 0) {
@@ -231,6 +248,6 @@ function label(s) {
231
248
  * resume entry matches its pair regardless of which side the client copied first.
232
249
  */
233
250
  function pairKey(a, b) {
234
- return [a.toUpperCase(), b.toUpperCase()].sort().join('');
251
+ return [a.toUpperCase(), b.toUpperCase()].sort().join('\u0000');
235
252
  }
236
253
  //# sourceMappingURL=compare-structures.tool.js.map