@cyanheads/protein-mcp-server 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +416 -0
- package/CLAUDE.md +416 -0
- package/Dockerfile +121 -0
- package/LICENSE +201 -0
- package/README.md +321 -0
- package/changelog/0.1.x/0.1.0.md +21 -0
- package/changelog/template.md +127 -0
- package/dist/config/server-config.d.ts +27 -0
- package/dist/config/server-config.d.ts.map +1 -0
- package/dist/config/server-config.js +110 -0
- package/dist/config/server-config.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/resources/definitions/af-summary.resource.d.ts +29 -0
- package/dist/mcp-server/resources/definitions/af-summary.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/af-summary.resource.js +61 -0
- package/dist/mcp-server/resources/definitions/af-summary.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/index.d.ts +7 -0
- package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/index.js +7 -0
- package/dist/mcp-server/resources/definitions/index.js.map +1 -0
- package/dist/mcp-server/resources/definitions/pdb-summary.resource.d.ts +31 -0
- package/dist/mcp-server/resources/definitions/pdb-summary.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/pdb-summary.resource.js +68 -0
- package/dist/mcp-server/resources/definitions/pdb-summary.resource.js.map +1 -0
- package/dist/mcp-server/tools/definitions/_schemas.d.ts +31 -0
- package/dist/mcp-server/tools/definitions/_schemas.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/_schemas.js +82 -0
- package/dist/mcp-server/tools/definitions/_schemas.js.map +1 -0
- package/dist/mcp-server/tools/definitions/analyze-collection.tool.d.ts +61 -0
- package/dist/mcp-server/tools/definitions/analyze-collection.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/analyze-collection.tool.js +115 -0
- package/dist/mcp-server/tools/definitions/analyze-collection.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/compare-structures.tool.d.ts +49 -0
- package/dist/mcp-server/tools/definitions/compare-structures.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/compare-structures.tool.js +168 -0
- package/dist/mcp-server/tools/definitions/compare-structures.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/find-similar.tool.d.ts +67 -0
- package/dist/mcp-server/tools/definitions/find-similar.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/find-similar.tool.js +274 -0
- package/dist/mcp-server/tools/definitions/find-similar.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-annotations.tool.d.ts +58 -0
- package/dist/mcp-server/tools/definitions/get-annotations.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-annotations.tool.js +180 -0
- package/dist/mcp-server/tools/definitions/get-annotations.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-structure.tool.d.ts +78 -0
- package/dist/mcp-server/tools/definitions/get-structure.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-structure.tool.js +365 -0
- package/dist/mcp-server/tools/definitions/get-structure.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/index.d.ts +12 -0
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/index.js +12 -0
- package/dist/mcp-server/tools/definitions/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-structures.tool.d.ts +71 -0
- package/dist/mcp-server/tools/definitions/search-structures.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-structures.tool.js +216 -0
- package/dist/mcp-server/tools/definitions/search-structures.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/track-ligands.tool.d.ts +59 -0
- package/dist/mcp-server/tools/definitions/track-ligands.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/track-ligands.tool.js +195 -0
- package/dist/mcp-server/tools/definitions/track-ligands.tool.js.map +1 -0
- package/dist/services/alignment/alignment-service.d.ts +56 -0
- package/dist/services/alignment/alignment-service.d.ts.map +1 -0
- package/dist/services/alignment/alignment-service.js +129 -0
- package/dist/services/alignment/alignment-service.js.map +1 -0
- package/dist/services/alphafold/alphafold-service.d.ts +57 -0
- package/dist/services/alphafold/alphafold-service.d.ts.map +1 -0
- package/dist/services/alphafold/alphafold-service.js +84 -0
- package/dist/services/alphafold/alphafold-service.js.map +1 -0
- package/dist/services/beacons/beacons-service.d.ts +52 -0
- package/dist/services/beacons/beacons-service.d.ts.map +1 -0
- package/dist/services/beacons/beacons-service.js +63 -0
- package/dist/services/beacons/beacons-service.js.map +1 -0
- package/dist/services/foldseek/foldseek-service.d.ts +71 -0
- package/dist/services/foldseek/foldseek-service.d.ts.map +1 -0
- package/dist/services/foldseek/foldseek-service.js +131 -0
- package/dist/services/foldseek/foldseek-service.js.map +1 -0
- package/dist/services/rcsb/facets.d.ts +50 -0
- package/dist/services/rcsb/facets.d.ts.map +1 -0
- package/dist/services/rcsb/facets.js +59 -0
- package/dist/services/rcsb/facets.js.map +1 -0
- package/dist/services/rcsb/rcsb-service.d.ts +81 -0
- package/dist/services/rcsb/rcsb-service.d.ts.map +1 -0
- package/dist/services/rcsb/rcsb-service.js +473 -0
- package/dist/services/rcsb/rcsb-service.js.map +1 -0
- package/dist/services/rcsb/types.d.ts +150 -0
- package/dist/services/rcsb/types.d.ts.map +1 -0
- package/dist/services/rcsb/types.js +8 -0
- package/dist/services/rcsb/types.js.map +1 -0
- package/dist/services/shared/async.d.ts +41 -0
- package/dist/services/shared/async.d.ts.map +1 -0
- package/dist/services/shared/async.js +64 -0
- package/dist/services/shared/async.js.map +1 -0
- package/dist/services/shared/http.d.ts +54 -0
- package/dist/services/shared/http.d.ts.map +1 -0
- package/dist/services/shared/http.js +115 -0
- package/dist/services/shared/http.js.map +1 -0
- package/dist/services/shared/identifiers.d.ts +12 -0
- package/dist/services/shared/identifiers.d.ts.map +1 -0
- package/dist/services/shared/identifiers.js +23 -0
- package/dist/services/shared/identifiers.js.map +1 -0
- package/dist/services/uniprot/uniprot-service.d.ts +65 -0
- package/dist/services/uniprot/uniprot-service.d.ts.map +1 -0
- package/dist/services/uniprot/uniprot-service.js +146 -0
- package/dist/services/uniprot/uniprot-service.js.map +1 -0
- package/package.json +106 -0
- package/server.json +99 -0
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview RCSB service — wraps the RCSB Search API v2 (text / sequence /
|
|
3
|
+
* chemical search + server-side faceted aggregation), the Data API GraphQL
|
|
4
|
+
* endpoint (batched entry metadata + ligand binding-site residues via
|
|
5
|
+
* `rcsb_target_neighbors`), the REST chemical-component endpoint, and coordinate
|
|
6
|
+
* file URLs. The PDB's full query surface lives only here; predicted models are
|
|
7
|
+
* served by the AlphaFold / 3D-Beacons services.
|
|
8
|
+
* @module services/rcsb/rcsb-service
|
|
9
|
+
*/
|
|
10
|
+
import { JsonRpcErrorCode, McpError } from '@cyanheads/mcp-ts-core/errors';
|
|
11
|
+
import { fetchJson } from '../shared/http.js';
|
|
12
|
+
/** Match-all base terminal — every entry carries a release date. */
|
|
13
|
+
const MATCH_ALL = {
|
|
14
|
+
type: 'terminal',
|
|
15
|
+
service: 'text',
|
|
16
|
+
parameters: { attribute: 'rcsb_accession_info.initial_release_date', operator: 'exists' },
|
|
17
|
+
};
|
|
18
|
+
export class RcsbService {
|
|
19
|
+
searchUrl;
|
|
20
|
+
graphqlUrl;
|
|
21
|
+
dataRestBase;
|
|
22
|
+
filesBase;
|
|
23
|
+
constructor(_config, _storage, serverConfig) {
|
|
24
|
+
this.searchUrl = `${serverConfig.rcsbSearchBaseUrl}/rcsbsearch/v2/query`;
|
|
25
|
+
this.graphqlUrl = `${serverConfig.rcsbDataBaseUrl}/graphql`;
|
|
26
|
+
this.dataRestBase = `${serverConfig.rcsbDataBaseUrl}/rest/v1/core`;
|
|
27
|
+
this.filesBase = serverConfig.rcsbFilesBaseUrl;
|
|
28
|
+
}
|
|
29
|
+
// ─── Search ────────────────────────────────────────────────────────────────
|
|
30
|
+
/** Full-text / filtered structure search, optionally with a facet breakdown. */
|
|
31
|
+
async search(params, ctx, facets) {
|
|
32
|
+
const query = buildQuery(params);
|
|
33
|
+
const returnType = params.sequence ? 'polymer_entity' : 'entry';
|
|
34
|
+
const body = {
|
|
35
|
+
query,
|
|
36
|
+
return_type: returnType,
|
|
37
|
+
request_options: {
|
|
38
|
+
...contentTypeOption(params.contentType),
|
|
39
|
+
paginate: { start: params.start ?? 0, rows: params.limit ?? 25 },
|
|
40
|
+
...(facets && facets.length > 0 ? { facets: facets.map(toRcsbFacet) } : {}),
|
|
41
|
+
scoring_strategy: 'combined',
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
const raw = await this.postSearch(body, ctx, 'RcsbService.search');
|
|
45
|
+
return {
|
|
46
|
+
total: raw.total_count ?? 0,
|
|
47
|
+
hits: normalizeHits(raw.result_set),
|
|
48
|
+
...(facets && facets.length > 0 ? { facets: normalizeFacets(raw.facets, facets) } : {}),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/** mmseqs2 sequence-similarity search. Returns polymer-entity hits. */
|
|
52
|
+
async searchSequence(sequence, opts, ctx) {
|
|
53
|
+
const body = {
|
|
54
|
+
query: {
|
|
55
|
+
type: 'terminal',
|
|
56
|
+
service: 'sequence',
|
|
57
|
+
parameters: {
|
|
58
|
+
evalue_cutoff: opts.maxEvalue ?? 1,
|
|
59
|
+
identity_cutoff: opts.minIdentity ?? 0,
|
|
60
|
+
sequence_type: 'protein',
|
|
61
|
+
value: sequence,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
return_type: 'polymer_entity',
|
|
65
|
+
request_options: {
|
|
66
|
+
...contentTypeOption(opts.contentType),
|
|
67
|
+
paginate: { start: 0, rows: opts.limit ?? 25 },
|
|
68
|
+
scoring_strategy: 'sequence',
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
const raw = await this.postSearch(body, ctx, 'RcsbService.searchSequence');
|
|
72
|
+
return { total: raw.total_count ?? 0, hits: normalizeHits(raw.result_set) };
|
|
73
|
+
}
|
|
74
|
+
/** Find entries containing a given ligand (exact chemical component ID). */
|
|
75
|
+
async searchByLigand(compId, opts, ctx) {
|
|
76
|
+
const body = {
|
|
77
|
+
query: {
|
|
78
|
+
type: 'terminal',
|
|
79
|
+
service: 'text_chem',
|
|
80
|
+
parameters: {
|
|
81
|
+
attribute: 'rcsb_chem_comp_container_identifiers.comp_id',
|
|
82
|
+
operator: 'exact_match',
|
|
83
|
+
value: compId.toUpperCase(),
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
return_type: 'entry',
|
|
87
|
+
request_options: {
|
|
88
|
+
...contentTypeOption(opts.contentType ?? 'experimental'),
|
|
89
|
+
paginate: { start: 0, rows: opts.limit ?? 25 },
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
const raw = await this.postSearch(body, ctx, 'RcsbService.searchByLigand');
|
|
93
|
+
return { total: raw.total_count ?? 0, hits: normalizeHits(raw.result_set) };
|
|
94
|
+
}
|
|
95
|
+
/** Resolve a ligand name/synonym to candidate chemical component IDs. */
|
|
96
|
+
async findChemComps(query, limit, ctx) {
|
|
97
|
+
// Match the term against both the formal component name and its synonyms:
|
|
98
|
+
// common names ("heme", "aspirin") live in synonyms, not the formal name
|
|
99
|
+
// ("PROTOPORPHYRIN IX CONTAINING FE"). A plain full_text search over
|
|
100
|
+
// mol_definition matches far too broadly and buries the intended component.
|
|
101
|
+
const chemTerm = (attribute) => ({
|
|
102
|
+
type: 'terminal',
|
|
103
|
+
service: 'text_chem',
|
|
104
|
+
parameters: { attribute, operator: 'contains_words', value: query },
|
|
105
|
+
});
|
|
106
|
+
const body = {
|
|
107
|
+
query: {
|
|
108
|
+
type: 'group',
|
|
109
|
+
logical_operator: 'or',
|
|
110
|
+
nodes: [chemTerm('chem_comp.name'), chemTerm('rcsb_chem_comp_synonyms.name')],
|
|
111
|
+
},
|
|
112
|
+
return_type: 'mol_definition',
|
|
113
|
+
request_options: { paginate: { start: 0, rows: limit } },
|
|
114
|
+
};
|
|
115
|
+
const raw = await this.postSearch(body, ctx, 'RcsbService.findChemComps');
|
|
116
|
+
return normalizeHits(raw.result_set).map((h) => h.id);
|
|
117
|
+
}
|
|
118
|
+
/** Facet-only aggregation over an optional scoping query (no row pull). */
|
|
119
|
+
async analyzeFacets(params, facets, ctx) {
|
|
120
|
+
const body = {
|
|
121
|
+
query: buildQuery(params),
|
|
122
|
+
return_type: 'entry',
|
|
123
|
+
request_options: {
|
|
124
|
+
...contentTypeOption(params.contentType),
|
|
125
|
+
facets: facets.map(toRcsbFacet),
|
|
126
|
+
paginate: { start: 0, rows: 0 },
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
const raw = await this.postSearch(body, ctx, 'RcsbService.analyzeFacets');
|
|
130
|
+
return { total: raw.total_count ?? 0, facets: normalizeFacets(raw.facets, facets) };
|
|
131
|
+
}
|
|
132
|
+
// ─── GraphQL metadata ────────────────────────────────────────────────────────
|
|
133
|
+
/** Batched entry metadata for up to N PDB IDs in one GraphQL call. */
|
|
134
|
+
async getEntries(ids, ctx) {
|
|
135
|
+
if (ids.length === 0)
|
|
136
|
+
return [];
|
|
137
|
+
const data = await this.graphql(ENTRIES_QUERY, { ids: ids.map((id) => id.toUpperCase()) }, ctx, 'RcsbService.getEntries');
|
|
138
|
+
return (data.entries ?? []).filter((e) => e != null).map(normalizeEntry);
|
|
139
|
+
}
|
|
140
|
+
/** Resolve a PDB entry to its cross-referenced UniProt accession(s). */
|
|
141
|
+
async resolveUniprot(pdbId, ctx) {
|
|
142
|
+
const data = await this.graphql(XREF_QUERY, { id: pdbId.toUpperCase() }, ctx, 'RcsbService.resolveUniprot');
|
|
143
|
+
const accessions = new Set();
|
|
144
|
+
for (const entity of data.entry?.polymer_entities ?? []) {
|
|
145
|
+
for (const ref of entity.rcsb_polymer_entity_container_identifiers
|
|
146
|
+
?.reference_sequence_identifiers ?? []) {
|
|
147
|
+
if (/uniprot/i.test(ref.database_name ?? '') && ref.database_accession) {
|
|
148
|
+
accessions.add(ref.database_accession.toUpperCase());
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return [...accessions];
|
|
153
|
+
}
|
|
154
|
+
/** First polymer entity's one-letter sequence for a PDB entry. */
|
|
155
|
+
async getSequence(pdbId, ctx) {
|
|
156
|
+
const data = await this.graphql(SEQUENCE_QUERY, { id: pdbId.toUpperCase() }, ctx, 'RcsbService.getSequence');
|
|
157
|
+
const entity = data.entry?.polymer_entities?.find((e) => e.entity_poly?.pdbx_seq_one_letter_code_can);
|
|
158
|
+
const seq = entity?.entity_poly?.pdbx_seq_one_letter_code_can;
|
|
159
|
+
if (!entity || !seq)
|
|
160
|
+
return null;
|
|
161
|
+
return { entityId: entity.rcsb_id ?? pdbId, sequence: seq.replace(/\s+/g, '') };
|
|
162
|
+
}
|
|
163
|
+
/** Ligand binding-site residues for an entry, optionally filtered to one ligand. */
|
|
164
|
+
async getBindingSites(pdbId, compId, ctx) {
|
|
165
|
+
const data = await this.graphql(BINDING_SITE_QUERY, { id: pdbId.toUpperCase() }, ctx, 'RcsbService.getBindingSites');
|
|
166
|
+
const sites = [];
|
|
167
|
+
const want = compId?.toUpperCase();
|
|
168
|
+
for (const nonpoly of data.entry?.nonpolymer_entities ?? []) {
|
|
169
|
+
const ligand = nonpoly.rcsb_nonpolymer_entity_container_identifiers?.nonpolymer_comp_id;
|
|
170
|
+
if (!ligand || (want && ligand.toUpperCase() !== want))
|
|
171
|
+
continue;
|
|
172
|
+
for (const inst of nonpoly.nonpolymer_entity_instances ?? []) {
|
|
173
|
+
const neighbors = inst.rcsb_target_neighbors ?? [];
|
|
174
|
+
if (neighbors.length === 0)
|
|
175
|
+
continue;
|
|
176
|
+
sites.push({
|
|
177
|
+
ligandCompId: ligand,
|
|
178
|
+
...(inst.rcsb_nonpolymer_entity_instance_container_identifiers?.auth_asym_id
|
|
179
|
+
? {
|
|
180
|
+
ligandAsymId: inst.rcsb_nonpolymer_entity_instance_container_identifiers.auth_asym_id,
|
|
181
|
+
}
|
|
182
|
+
: {}),
|
|
183
|
+
residues: neighbors
|
|
184
|
+
.map(normalizeNeighbor)
|
|
185
|
+
.filter((r) => r != null)
|
|
186
|
+
.sort((a, b) => (a.distance ?? Infinity) - (b.distance ?? Infinity)),
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return sites;
|
|
191
|
+
}
|
|
192
|
+
// ─── REST chemical component ──────────────────────────────────────────────────
|
|
193
|
+
/** Chemical-component metadata (formula, weight, SMILES, InChIKey). */
|
|
194
|
+
async getChemComp(compId, ctx) {
|
|
195
|
+
const id = compId.toUpperCase();
|
|
196
|
+
let raw;
|
|
197
|
+
try {
|
|
198
|
+
raw = await fetchJson(`${this.dataRestBase}/chemcomp/${encodeURIComponent(id)}`, ctx, {
|
|
199
|
+
operation: 'RcsbService.getChemComp',
|
|
200
|
+
label: 'RCSB Data API',
|
|
201
|
+
baseDelayMs: 400,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
if (err instanceof McpError && err.code === JsonRpcErrorCode.NotFound)
|
|
206
|
+
return null;
|
|
207
|
+
throw err;
|
|
208
|
+
}
|
|
209
|
+
return normalizeChemComp(id, raw);
|
|
210
|
+
}
|
|
211
|
+
// ─── Files ────────────────────────────────────────────────────────────────────
|
|
212
|
+
/** Construct a coordinate-file download URL for a PDB entry. */
|
|
213
|
+
coordinateFileUrl(pdbId, format) {
|
|
214
|
+
return `${this.filesBase}/download/${pdbId.toUpperCase()}.${format}`;
|
|
215
|
+
}
|
|
216
|
+
// ─── Private ───────────────────────────────────────────────────────────────────
|
|
217
|
+
postSearch(body, ctx, operation) {
|
|
218
|
+
return fetchJson(this.searchUrl, ctx, {
|
|
219
|
+
method: 'POST',
|
|
220
|
+
body: JSON.stringify(body),
|
|
221
|
+
headers: { 'Content-Type': 'application/json' },
|
|
222
|
+
operation,
|
|
223
|
+
label: 'RCSB Search API',
|
|
224
|
+
baseDelayMs: 400,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
async graphql(query, variables, ctx, operation) {
|
|
228
|
+
const body = await fetchJson(this.graphqlUrl, ctx, {
|
|
229
|
+
method: 'POST',
|
|
230
|
+
body: JSON.stringify({ query, variables }),
|
|
231
|
+
headers: { 'Content-Type': 'application/json' },
|
|
232
|
+
operation,
|
|
233
|
+
label: 'RCSB GraphQL API',
|
|
234
|
+
baseDelayMs: 400,
|
|
235
|
+
});
|
|
236
|
+
if (body.data)
|
|
237
|
+
return body.data;
|
|
238
|
+
const message = body.errors?.[0]?.message ?? 'unknown error';
|
|
239
|
+
throw new McpError(JsonRpcErrorCode.InternalError, `RCSB GraphQL error: ${message}`, {
|
|
240
|
+
retryable: false,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
// ─── Query builders ──────────────────────────────────────────────────────────
|
|
245
|
+
/** Build the RCSB query node from search params (match-all when no constraint given). */
|
|
246
|
+
export function buildQuery(params) {
|
|
247
|
+
const nodes = [];
|
|
248
|
+
if (params.text) {
|
|
249
|
+
nodes.push({ type: 'terminal', service: 'full_text', parameters: { value: params.text } });
|
|
250
|
+
}
|
|
251
|
+
if (params.sequence) {
|
|
252
|
+
nodes.push({
|
|
253
|
+
type: 'terminal',
|
|
254
|
+
service: 'sequence',
|
|
255
|
+
parameters: {
|
|
256
|
+
evalue_cutoff: params.maxEvalue ?? 1,
|
|
257
|
+
identity_cutoff: params.minIdentity ?? 0,
|
|
258
|
+
sequence_type: 'protein',
|
|
259
|
+
value: params.sequence,
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
if (params.organism) {
|
|
264
|
+
nodes.push(textNode('rcsb_entity_source_organism.ncbi_scientific_name', 'contains_phrase', params.organism));
|
|
265
|
+
}
|
|
266
|
+
if (params.method) {
|
|
267
|
+
nodes.push(textNode('exptl.method', 'exact_match', params.method));
|
|
268
|
+
}
|
|
269
|
+
if (typeof params.maxResolution === 'number') {
|
|
270
|
+
nodes.push(textNode('rcsb_entry_info.resolution_combined', 'less_or_equal', params.maxResolution));
|
|
271
|
+
}
|
|
272
|
+
if (nodes.length === 0)
|
|
273
|
+
return MATCH_ALL;
|
|
274
|
+
if (nodes.length === 1)
|
|
275
|
+
return nodes[0];
|
|
276
|
+
return { type: 'group', logical_operator: 'and', nodes };
|
|
277
|
+
}
|
|
278
|
+
function textNode(attribute, operator, value) {
|
|
279
|
+
return { type: 'terminal', service: 'text', parameters: { attribute, operator, value } };
|
|
280
|
+
}
|
|
281
|
+
function contentTypeOption(contentType) {
|
|
282
|
+
if (!contentType)
|
|
283
|
+
return {};
|
|
284
|
+
return { results_content_type: [contentType] };
|
|
285
|
+
}
|
|
286
|
+
/** Translate a friendly FacetSpec into the RCSB facet request shape (recursively). */
|
|
287
|
+
export function toRcsbFacet(spec) {
|
|
288
|
+
const facet = {
|
|
289
|
+
name: spec.dimension,
|
|
290
|
+
aggregation_type: spec.aggregation,
|
|
291
|
+
attribute: spec.attribute,
|
|
292
|
+
min_interval_population: 1,
|
|
293
|
+
};
|
|
294
|
+
if (spec.aggregation !== 'terms' && spec.interval !== undefined)
|
|
295
|
+
facet.interval = spec.interval;
|
|
296
|
+
if (spec.child)
|
|
297
|
+
facet.facets = [toRcsbFacet(spec.child)];
|
|
298
|
+
return facet;
|
|
299
|
+
}
|
|
300
|
+
// ─── Normalizers ──────────────────────────────────────────────────────────────
|
|
301
|
+
function normalizeHits(resultSet) {
|
|
302
|
+
return (resultSet ?? []).map((r) => ({ id: r.identifier, score: r.score }));
|
|
303
|
+
}
|
|
304
|
+
function normalizeFacets(raw, specs) {
|
|
305
|
+
const byAttr = new Map((raw ?? []).map((f) => [f.attribute ?? f.name, f]));
|
|
306
|
+
return specs.map((spec) => {
|
|
307
|
+
const match = byAttr.get(spec.attribute) ?? byAttr.get(spec.dimension);
|
|
308
|
+
return {
|
|
309
|
+
dimension: spec.dimension,
|
|
310
|
+
attribute: spec.attribute,
|
|
311
|
+
buckets: normalizeBuckets(match?.buckets, spec.child),
|
|
312
|
+
};
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
function normalizeBuckets(raw, child) {
|
|
316
|
+
return (raw ?? []).map((b) => {
|
|
317
|
+
const label = b.label ?? (b.value != null ? String(b.value) : '');
|
|
318
|
+
const count = b.population ?? b.count ?? 0;
|
|
319
|
+
const bucket = { label, count };
|
|
320
|
+
if (child && b.facets) {
|
|
321
|
+
bucket.children = [
|
|
322
|
+
{
|
|
323
|
+
dimension: child.dimension,
|
|
324
|
+
attribute: child.attribute,
|
|
325
|
+
buckets: normalizeBuckets(b.facets[0]?.buckets, child.child),
|
|
326
|
+
},
|
|
327
|
+
];
|
|
328
|
+
}
|
|
329
|
+
return bucket;
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
function normalizeEntry(raw) {
|
|
333
|
+
const polymerEntities = (raw.polymer_entities ?? []).map(normalizePolymerEntity);
|
|
334
|
+
const organisms = [
|
|
335
|
+
...new Set(polymerEntities.map((e) => e.organism).filter((o) => !!o)),
|
|
336
|
+
];
|
|
337
|
+
const ligands = (raw.nonpolymer_entities ?? [])
|
|
338
|
+
.map(normalizeLigand)
|
|
339
|
+
.filter((l) => l != null);
|
|
340
|
+
const methods = (raw.exptl ?? []).map((e) => e.method).filter((m) => !!m);
|
|
341
|
+
const resolution = raw.rcsb_entry_info?.resolution_combined?.[0];
|
|
342
|
+
return {
|
|
343
|
+
id: raw.rcsb_id,
|
|
344
|
+
...(raw.struct?.title ? { title: raw.struct.title } : {}),
|
|
345
|
+
...(methods.length > 0 ? { methods } : {}),
|
|
346
|
+
...(typeof resolution === 'number' ? { resolution } : {}),
|
|
347
|
+
...(typeof raw.rcsb_entry_info?.molecular_weight === 'number'
|
|
348
|
+
? { molecularWeight: raw.rcsb_entry_info.molecular_weight }
|
|
349
|
+
: {}),
|
|
350
|
+
...(raw.rcsb_accession_info?.initial_release_date
|
|
351
|
+
? { releaseDate: raw.rcsb_accession_info.initial_release_date }
|
|
352
|
+
: {}),
|
|
353
|
+
organisms,
|
|
354
|
+
polymerEntities,
|
|
355
|
+
ligands,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
function normalizePolymerEntity(raw) {
|
|
359
|
+
const organism = raw.rcsb_entity_source_organism?.find((o) => o.ncbi_scientific_name)?.ncbi_scientific_name;
|
|
360
|
+
const chains = raw.rcsb_polymer_entity_container_identifiers?.auth_asym_ids;
|
|
361
|
+
return {
|
|
362
|
+
entityId: raw.rcsb_id ?? '',
|
|
363
|
+
...(raw.rcsb_polymer_entity?.pdbx_description
|
|
364
|
+
? { description: raw.rcsb_polymer_entity.pdbx_description }
|
|
365
|
+
: {}),
|
|
366
|
+
...(organism ? { organism } : {}),
|
|
367
|
+
...(chains && chains.length > 0 ? { chains } : {}),
|
|
368
|
+
...(typeof raw.entity_poly?.rcsb_sample_sequence_length === 'number'
|
|
369
|
+
? { sequenceLength: raw.entity_poly.rcsb_sample_sequence_length }
|
|
370
|
+
: {}),
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
function normalizeLigand(raw) {
|
|
374
|
+
const compId = raw.rcsb_nonpolymer_entity_container_identifiers?.nonpolymer_comp_id;
|
|
375
|
+
if (!compId)
|
|
376
|
+
return;
|
|
377
|
+
const chem = raw.nonpolymer_comp?.chem_comp;
|
|
378
|
+
return {
|
|
379
|
+
compId,
|
|
380
|
+
...(chem?.name ? { name: chem.name } : {}),
|
|
381
|
+
...(chem?.formula ? { formula: chem.formula } : {}),
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
function normalizeNeighbor(raw) {
|
|
385
|
+
if (!raw.target_comp_id || !raw.target_asym_id)
|
|
386
|
+
return;
|
|
387
|
+
return {
|
|
388
|
+
residueCompId: raw.target_comp_id,
|
|
389
|
+
asymId: raw.target_asym_id,
|
|
390
|
+
...(typeof raw.target_seq_id === 'number' ? { seqId: raw.target_seq_id } : {}),
|
|
391
|
+
...(typeof raw.distance === 'number' ? { distance: raw.distance } : {}),
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
function normalizeChemComp(id, raw) {
|
|
395
|
+
const descriptors = raw.rcsb_chem_comp_descriptor;
|
|
396
|
+
const smiles = descriptors?.SMILES_stereo ??
|
|
397
|
+
descriptors?.SMILES ??
|
|
398
|
+
raw.pdbx_chem_comp_descriptor?.find((d) => d.type === 'SMILES_CANONICAL')?.descriptor ??
|
|
399
|
+
raw.pdbx_chem_comp_descriptor?.find((d) => d.type === 'SMILES')?.descriptor;
|
|
400
|
+
const inchikey = descriptors?.InChIKey ??
|
|
401
|
+
raw.pdbx_chem_comp_descriptor?.find((d) => d.type === 'InChIKey')?.descriptor;
|
|
402
|
+
return {
|
|
403
|
+
compId: id,
|
|
404
|
+
...(raw.chem_comp?.name ? { name: raw.chem_comp.name } : {}),
|
|
405
|
+
...(raw.chem_comp?.formula ? { formula: raw.chem_comp.formula } : {}),
|
|
406
|
+
...(typeof raw.chem_comp?.formula_weight === 'number'
|
|
407
|
+
? { formulaWeight: raw.chem_comp.formula_weight }
|
|
408
|
+
: {}),
|
|
409
|
+
...(smiles ? { smiles } : {}),
|
|
410
|
+
...(inchikey ? { inchikey } : {}),
|
|
411
|
+
...(raw.chem_comp?.type ? { type: raw.chem_comp.type } : {}),
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
// ─── GraphQL queries ──────────────────────────────────────────────────────────
|
|
415
|
+
const ENTRIES_QUERY = `query Entries($ids: [String!]!) {
|
|
416
|
+
entries(entry_ids: $ids) {
|
|
417
|
+
rcsb_id
|
|
418
|
+
struct { title }
|
|
419
|
+
exptl { method }
|
|
420
|
+
rcsb_entry_info { resolution_combined molecular_weight }
|
|
421
|
+
rcsb_accession_info { initial_release_date }
|
|
422
|
+
polymer_entities {
|
|
423
|
+
rcsb_id
|
|
424
|
+
rcsb_polymer_entity { pdbx_description }
|
|
425
|
+
rcsb_polymer_entity_container_identifiers { auth_asym_ids }
|
|
426
|
+
entity_poly { rcsb_sample_sequence_length }
|
|
427
|
+
rcsb_entity_source_organism { ncbi_scientific_name }
|
|
428
|
+
}
|
|
429
|
+
nonpolymer_entities {
|
|
430
|
+
rcsb_nonpolymer_entity_container_identifiers { nonpolymer_comp_id }
|
|
431
|
+
nonpolymer_comp { chem_comp { name formula } }
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}`;
|
|
435
|
+
const XREF_QUERY = `query Xref($id: String!) {
|
|
436
|
+
entry(entry_id: $id) {
|
|
437
|
+
polymer_entities {
|
|
438
|
+
rcsb_polymer_entity_container_identifiers {
|
|
439
|
+
reference_sequence_identifiers { database_accession database_name }
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}`;
|
|
444
|
+
const SEQUENCE_QUERY = `query Sequence($id: String!) {
|
|
445
|
+
entry(entry_id: $id) {
|
|
446
|
+
polymer_entities {
|
|
447
|
+
rcsb_id
|
|
448
|
+
entity_poly { pdbx_seq_one_letter_code_can }
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}`;
|
|
452
|
+
const BINDING_SITE_QUERY = `query BindingSite($id: String!) {
|
|
453
|
+
entry(entry_id: $id) {
|
|
454
|
+
nonpolymer_entities {
|
|
455
|
+
rcsb_nonpolymer_entity_container_identifiers { nonpolymer_comp_id }
|
|
456
|
+
nonpolymer_entity_instances {
|
|
457
|
+
rcsb_nonpolymer_entity_instance_container_identifiers { auth_asym_id }
|
|
458
|
+
rcsb_target_neighbors { target_asym_id target_comp_id target_seq_id distance }
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}`;
|
|
463
|
+
// ─── Init/accessor ──────────────────────────────────────────────────────────────
|
|
464
|
+
let _service;
|
|
465
|
+
export function initRcsbService(config, storage, serverConfig) {
|
|
466
|
+
_service = new RcsbService(config, storage, serverConfig);
|
|
467
|
+
}
|
|
468
|
+
export function getRcsbService() {
|
|
469
|
+
if (!_service)
|
|
470
|
+
throw new Error('RcsbService not initialized — call initRcsbService() in setup()');
|
|
471
|
+
return _service;
|
|
472
|
+
}
|
|
473
|
+
//# sourceMappingURL=rcsb-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rcsb-service.js","sourceRoot":"","sources":["../../../src/services/rcsb/rcsb-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Domain types for the RCSB service — normalized shapes the tools
|
|
3
|
+
* consume, decoupled from the raw Search/GraphQL payloads. Optional fields mirror
|
|
4
|
+
* real upstream sparsity (missing = unknown, never fabricated).
|
|
5
|
+
* @module services/rcsb/types
|
|
6
|
+
*/
|
|
7
|
+
/** A single search hit before metadata enrichment. */
|
|
8
|
+
export interface SearchHit {
|
|
9
|
+
/** Identifier (PDB entry ID, polymer-entity ID, or chem-comp ID per return type). */
|
|
10
|
+
id: string;
|
|
11
|
+
/** RCSB relevance score. */
|
|
12
|
+
score: number;
|
|
13
|
+
}
|
|
14
|
+
/** One facet bucket; `children` present only for multidimensional (nested) facets. */
|
|
15
|
+
export interface FacetBucket {
|
|
16
|
+
/** Nested sub-facets for multidimensional cross-tabs. */
|
|
17
|
+
children?: FacetDimension[];
|
|
18
|
+
/** Count of entries in the bucket. */
|
|
19
|
+
count: number;
|
|
20
|
+
/** Bucket label (category value, numeric bin start, or period). */
|
|
21
|
+
label: string;
|
|
22
|
+
}
|
|
23
|
+
/** A facet dimension and its buckets. */
|
|
24
|
+
export interface FacetDimension {
|
|
25
|
+
/** RCSB attribute path the dimension aggregates on. */
|
|
26
|
+
attribute: string;
|
|
27
|
+
/** Aggregation buckets, count-descending for terms / order-preserving for histograms. */
|
|
28
|
+
buckets: FacetBucket[];
|
|
29
|
+
/** Friendly dimension name (e.g. `method`, `organism`, `release_year`). */
|
|
30
|
+
dimension: string;
|
|
31
|
+
/** True when buckets were capped by the per-dimension limit. */
|
|
32
|
+
truncated?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/** Result of a structure search. */
|
|
35
|
+
export interface SearchResult {
|
|
36
|
+
/** Optional facet breakdown when requested. */
|
|
37
|
+
facets?: FacetDimension[];
|
|
38
|
+
/** The current page of hits. */
|
|
39
|
+
hits: SearchHit[];
|
|
40
|
+
/** Total matches upstream (before pagination). */
|
|
41
|
+
total: number;
|
|
42
|
+
}
|
|
43
|
+
/** A modeled polymer (protein/nucleic) entity within an entry. */
|
|
44
|
+
export interface PolymerEntityMeta {
|
|
45
|
+
/** Author-assigned chain IDs for this entity. */
|
|
46
|
+
chains?: string[];
|
|
47
|
+
/** Free-text description (e.g. "Hemoglobin subunit alpha"). */
|
|
48
|
+
description?: string;
|
|
49
|
+
/** Entity identifier (e.g. `4HHB_1`). */
|
|
50
|
+
entityId: string;
|
|
51
|
+
/** Source organism scientific name. */
|
|
52
|
+
organism?: string;
|
|
53
|
+
/** One-letter canonical sequence (present only when explicitly requested). */
|
|
54
|
+
sequence?: string;
|
|
55
|
+
/** Residue count of the sample sequence. */
|
|
56
|
+
sequenceLength?: number;
|
|
57
|
+
}
|
|
58
|
+
/** A bound non-polymer (ligand) component within an entry. */
|
|
59
|
+
export interface LigandMeta {
|
|
60
|
+
/** Chemical component ID (e.g. `HEM`, `STI`). */
|
|
61
|
+
compId: string;
|
|
62
|
+
/** Molecular formula when available. */
|
|
63
|
+
formula?: string;
|
|
64
|
+
/** Chemical name when available. */
|
|
65
|
+
name?: string;
|
|
66
|
+
}
|
|
67
|
+
/** Normalized entry-level metadata from the GraphQL batch. */
|
|
68
|
+
export interface EntryMeta {
|
|
69
|
+
/** PDB entry ID. */
|
|
70
|
+
id: string;
|
|
71
|
+
/** Bound ligands (non-polymer entities). */
|
|
72
|
+
ligands: LigandMeta[];
|
|
73
|
+
/** Experimental method(s) (e.g. ["X-RAY DIFFRACTION"]). */
|
|
74
|
+
methods?: string[];
|
|
75
|
+
/** Deposited structure molecular weight (kDa). */
|
|
76
|
+
molecularWeight?: number;
|
|
77
|
+
/** Distinct source organisms across polymer entities. */
|
|
78
|
+
organisms: string[];
|
|
79
|
+
/** Modeled polymer entities. */
|
|
80
|
+
polymerEntities: PolymerEntityMeta[];
|
|
81
|
+
/** Initial release date (ISO 8601). */
|
|
82
|
+
releaseDate?: string;
|
|
83
|
+
/** Best resolution in Å when applicable. */
|
|
84
|
+
resolution?: number;
|
|
85
|
+
/** Structure title. */
|
|
86
|
+
title?: string;
|
|
87
|
+
}
|
|
88
|
+
/** One protein residue lining a ligand's binding pocket. */
|
|
89
|
+
export interface BindingResidue {
|
|
90
|
+
/** Author/asym chain ID the residue belongs to. */
|
|
91
|
+
asymId: string;
|
|
92
|
+
/** Contact distance to the ligand in Å. */
|
|
93
|
+
distance?: number;
|
|
94
|
+
/** Residue chemical component ID (e.g. `ASP`). */
|
|
95
|
+
residueCompId: string;
|
|
96
|
+
/** Sequence position of the residue. */
|
|
97
|
+
seqId?: number;
|
|
98
|
+
}
|
|
99
|
+
/** A ligand instance and the residues lining its pocket. */
|
|
100
|
+
export interface BindingSite {
|
|
101
|
+
/** Ligand instance chain (asym) ID. */
|
|
102
|
+
ligandAsymId?: string;
|
|
103
|
+
/** Ligand chemical component ID. */
|
|
104
|
+
ligandCompId: string;
|
|
105
|
+
/** Interacting protein residues, nearest first. */
|
|
106
|
+
residues: BindingResidue[];
|
|
107
|
+
}
|
|
108
|
+
/** Chemical-component metadata for a ligand. */
|
|
109
|
+
export interface ChemComp {
|
|
110
|
+
/** Component ID (e.g. `STI`). */
|
|
111
|
+
compId: string;
|
|
112
|
+
/** Molecular formula. */
|
|
113
|
+
formula?: string;
|
|
114
|
+
/** Formula weight (Da). */
|
|
115
|
+
formulaWeight?: number;
|
|
116
|
+
/** InChIKey when available. */
|
|
117
|
+
inchikey?: string;
|
|
118
|
+
/** Chemical name. */
|
|
119
|
+
name?: string;
|
|
120
|
+
/** Isomeric SMILES when available. */
|
|
121
|
+
smiles?: string;
|
|
122
|
+
/** Component type (e.g. "non-polymer"). */
|
|
123
|
+
type?: string;
|
|
124
|
+
}
|
|
125
|
+
/** Content-type scope for a search. */
|
|
126
|
+
export type ContentType = 'experimental' | 'computational';
|
|
127
|
+
/** Inputs to a structure search (shared by search + analyze tools). */
|
|
128
|
+
export interface StructureSearchParams {
|
|
129
|
+
/** Result content scope. */
|
|
130
|
+
contentType?: ContentType;
|
|
131
|
+
/** Page size. */
|
|
132
|
+
limit?: number;
|
|
133
|
+
/** Max E-value for a sequence query. */
|
|
134
|
+
maxEvalue?: number;
|
|
135
|
+
/** Maximum resolution in Å. */
|
|
136
|
+
maxResolution?: number;
|
|
137
|
+
/** Experimental method filter (e.g. "X-RAY DIFFRACTION"). */
|
|
138
|
+
method?: string;
|
|
139
|
+
/** Minimum sequence identity (0–1) for a sequence query. */
|
|
140
|
+
minIdentity?: number;
|
|
141
|
+
/** Source organism filter (scientific name). */
|
|
142
|
+
organism?: string;
|
|
143
|
+
/** Protein sequence (one-letter) for an mmseqs2 search. */
|
|
144
|
+
sequence?: string;
|
|
145
|
+
/** Page offset. */
|
|
146
|
+
start?: number;
|
|
147
|
+
/** Free-text query. */
|
|
148
|
+
text?: string;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/rcsb/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Domain types for the RCSB service — normalized shapes the tools
|
|
3
|
+
* consume, decoupled from the raw Search/GraphQL payloads. Optional fields mirror
|
|
4
|
+
* real upstream sparsity (missing = unknown, never fabricated).
|
|
5
|
+
* @module services/rcsb/types
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=types.js.map
|