@cyanheads/brapi-mcp-server 0.3.5
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/CLAUDE.md +391 -0
- package/Dockerfile +99 -0
- package/LICENSE +201 -0
- package/README.md +590 -0
- package/changelog/0.1.x/0.1.0.md +19 -0
- package/changelog/0.1.x/0.1.1.md +27 -0
- package/changelog/0.1.x/0.1.2.md +22 -0
- package/changelog/0.2.x/0.2.0.md +35 -0
- package/changelog/0.2.x/0.2.1.md +36 -0
- package/changelog/0.3.x/0.3.0.md +38 -0
- package/changelog/0.3.x/0.3.1.md +40 -0
- package/changelog/0.3.x/0.3.2.md +29 -0
- package/changelog/0.3.x/0.3.3.md +19 -0
- package/changelog/0.3.x/0.3.4.md +33 -0
- package/changelog/0.3.x/0.3.5.md +24 -0
- package/changelog/template.md +51 -0
- package/dist/config/alias-credentials.d.ts +82 -0
- package/dist/config/alias-credentials.d.ts.map +1 -0
- package/dist/config/alias-credentials.js +159 -0
- package/dist/config/alias-credentials.js.map +1 -0
- package/dist/config/server-config.d.ts +39 -0
- package/dist/config/server-config.d.ts.map +1 -0
- package/dist/config/server-config.js +128 -0
- package/dist/config/server-config.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +85 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/brapi-eda-study.prompt.d.ts +14 -0
- package/dist/mcp-server/prompts/definitions/brapi-eda-study.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/brapi-eda-study.prompt.js +75 -0
- package/dist/mcp-server/prompts/definitions/brapi-eda-study.prompt.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/brapi-meta-analysis.prompt.d.ts +16 -0
- package/dist/mcp-server/prompts/definitions/brapi-meta-analysis.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/brapi-meta-analysis.prompt.js +109 -0
- package/dist/mcp-server/prompts/definitions/brapi-meta-analysis.prompt.js.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-calls.resource.d.ts +11 -0
- package/dist/mcp-server/resources/definitions/brapi-calls.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-calls.resource.js +46 -0
- package/dist/mcp-server/resources/definitions/brapi-calls.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-dataset.resource.d.ts +13 -0
- package/dist/mcp-server/resources/definitions/brapi-dataset.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-dataset.resource.js +26 -0
- package/dist/mcp-server/resources/definitions/brapi-dataset.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-filters.resource.d.ts +19 -0
- package/dist/mcp-server/resources/definitions/brapi-filters.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-filters.resource.js +45 -0
- package/dist/mcp-server/resources/definitions/brapi-filters.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-germplasm.resource.d.ts +18 -0
- package/dist/mcp-server/resources/definitions/brapi-germplasm.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-germplasm.resource.js +34 -0
- package/dist/mcp-server/resources/definitions/brapi-germplasm.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-server-info.resource.d.ts +11 -0
- package/dist/mcp-server/resources/definitions/brapi-server-info.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-server-info.resource.js +28 -0
- package/dist/mcp-server/resources/definitions/brapi-server-info.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-study.resource.d.ts +18 -0
- package/dist/mcp-server/resources/definitions/brapi-study.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-study.resource.js +34 -0
- package/dist/mcp-server/resources/definitions/brapi-study.resource.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-connect.tool.d.ts +82 -0
- package/dist/mcp-server/tools/definitions/brapi-connect.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-connect.tool.js +106 -0
- package/dist/mcp-server/tools/definitions/brapi-connect.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-describe-filters.tool.d.ts +41 -0
- package/dist/mcp-server/tools/definitions/brapi-describe-filters.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-describe-filters.tool.js +88 -0
- package/dist/mcp-server/tools/definitions/brapi-describe-filters.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-genotype-calls.tool.d.ts +74 -0
- package/dist/mcp-server/tools/definitions/brapi-find-genotype-calls.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-genotype-calls.tool.js +386 -0
- package/dist/mcp-server/tools/definitions/brapi-find-genotype-calls.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-germplasm.tool.d.ts +72 -0
- package/dist/mcp-server/tools/definitions/brapi-find-germplasm.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-germplasm.tool.js +290 -0
- package/dist/mcp-server/tools/definitions/brapi-find-germplasm.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-images.tool.d.ts +65 -0
- package/dist/mcp-server/tools/definitions/brapi-find-images.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-images.tool.js +243 -0
- package/dist/mcp-server/tools/definitions/brapi-find-images.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-locations.tool.d.ts +63 -0
- package/dist/mcp-server/tools/definitions/brapi-find-locations.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-locations.tool.js +278 -0
- package/dist/mcp-server/tools/definitions/brapi-find-locations.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-observations.tool.d.ts +74 -0
- package/dist/mcp-server/tools/definitions/brapi-find-observations.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-observations.tool.js +288 -0
- package/dist/mcp-server/tools/definitions/brapi-find-observations.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-studies.tool.d.ts +69 -0
- package/dist/mcp-server/tools/definitions/brapi-find-studies.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-studies.tool.js +243 -0
- package/dist/mcp-server/tools/definitions/brapi-find-studies.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-variables.tool.d.ts +86 -0
- package/dist/mcp-server/tools/definitions/brapi-find-variables.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-variables.tool.js +337 -0
- package/dist/mcp-server/tools/definitions/brapi-find-variables.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-variants.tool.d.ts +59 -0
- package/dist/mcp-server/tools/definitions/brapi-find-variants.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-variants.tool.js +248 -0
- package/dist/mcp-server/tools/definitions/brapi-find-variants.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-get-germplasm.tool.d.ts +59 -0
- package/dist/mcp-server/tools/definitions/brapi-get-germplasm.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-get-germplasm.tool.js +306 -0
- package/dist/mcp-server/tools/definitions/brapi-get-germplasm.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-get-image.tool.d.ts +57 -0
- package/dist/mcp-server/tools/definitions/brapi-get-image.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-get-image.tool.js +291 -0
- package/dist/mcp-server/tools/definitions/brapi-get-image.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-get-study.tool.d.ts +75 -0
- package/dist/mcp-server/tools/definitions/brapi-get-study.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-get-study.tool.js +323 -0
- package/dist/mcp-server/tools/definitions/brapi-get-study.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-manage-dataset.tool.d.ts +87 -0
- package/dist/mcp-server/tools/definitions/brapi-manage-dataset.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-manage-dataset.tool.js +296 -0
- package/dist/mcp-server/tools/definitions/brapi-manage-dataset.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-raw-get.tool.d.ts +35 -0
- package/dist/mcp-server/tools/definitions/brapi-raw-get.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-raw-get.tool.js +148 -0
- package/dist/mcp-server/tools/definitions/brapi-raw-get.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-raw-search.tool.d.ts +33 -0
- package/dist/mcp-server/tools/definitions/brapi-raw-search.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-raw-search.tool.js +126 -0
- package/dist/mcp-server/tools/definitions/brapi-raw-search.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-server-info.tool.d.ts +51 -0
- package/dist/mcp-server/tools/definitions/brapi-server-info.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-server-info.tool.js +41 -0
- package/dist/mcp-server/tools/definitions/brapi-server-info.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-submit-observations.tool.d.ts +117 -0
- package/dist/mcp-server/tools/definitions/brapi-submit-observations.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-submit-observations.tool.js +574 -0
- package/dist/mcp-server/tools/definitions/brapi-submit-observations.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-walk-pedigree.tool.d.ts +52 -0
- package/dist/mcp-server/tools/definitions/brapi-walk-pedigree.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-walk-pedigree.tool.js +420 -0
- package/dist/mcp-server/tools/definitions/brapi-walk-pedigree.tool.js.map +1 -0
- package/dist/mcp-server/tools/shared/connect-auth-schema.d.ts +29 -0
- package/dist/mcp-server/tools/shared/connect-auth-schema.d.ts.map +1 -0
- package/dist/mcp-server/tools/shared/connect-auth-schema.js +55 -0
- package/dist/mcp-server/tools/shared/connect-auth-schema.js.map +1 -0
- package/dist/mcp-server/tools/shared/find-helpers.d.ts +143 -0
- package/dist/mcp-server/tools/shared/find-helpers.d.ts.map +1 -0
- package/dist/mcp-server/tools/shared/find-helpers.js +319 -0
- package/dist/mcp-server/tools/shared/find-helpers.js.map +1 -0
- package/dist/mcp-server/tools/shared/orientation-envelope.d.ts +97 -0
- package/dist/mcp-server/tools/shared/orientation-envelope.d.ts.map +1 -0
- package/dist/mcp-server/tools/shared/orientation-envelope.js +254 -0
- package/dist/mcp-server/tools/shared/orientation-envelope.js.map +1 -0
- package/dist/mcp-server/tools/shared/raw-routing-hints.d.ts +10 -0
- package/dist/mcp-server/tools/shared/raw-routing-hints.d.ts.map +1 -0
- package/dist/mcp-server/tools/shared/raw-routing-hints.js +46 -0
- package/dist/mcp-server/tools/shared/raw-routing-hints.js.map +1 -0
- package/dist/services/brapi-client/brapi-client.d.ts +76 -0
- package/dist/services/brapi-client/brapi-client.d.ts.map +1 -0
- package/dist/services/brapi-client/brapi-client.js +320 -0
- package/dist/services/brapi-client/brapi-client.js.map +1 -0
- package/dist/services/brapi-client/index.d.ts +9 -0
- package/dist/services/brapi-client/index.d.ts.map +1 -0
- package/dist/services/brapi-client/index.js +7 -0
- package/dist/services/brapi-client/index.js.map +1 -0
- package/dist/services/brapi-client/types.d.ts +82 -0
- package/dist/services/brapi-client/types.d.ts.map +1 -0
- package/dist/services/brapi-client/types.js +8 -0
- package/dist/services/brapi-client/types.js.map +1 -0
- package/dist/services/brapi-filters/catalog.d.ts +14 -0
- package/dist/services/brapi-filters/catalog.d.ts.map +1 -0
- package/dist/services/brapi-filters/catalog.js +490 -0
- package/dist/services/brapi-filters/catalog.js.map +1 -0
- package/dist/services/brapi-filters/index.d.ts +8 -0
- package/dist/services/brapi-filters/index.d.ts.map +1 -0
- package/dist/services/brapi-filters/index.js +7 -0
- package/dist/services/brapi-filters/index.js.map +1 -0
- package/dist/services/brapi-filters/types.d.ts +23 -0
- package/dist/services/brapi-filters/types.d.ts.map +1 -0
- package/dist/services/brapi-filters/types.js +9 -0
- package/dist/services/brapi-filters/types.js.map +1 -0
- package/dist/services/capability-registry/capability-registry.d.ts +51 -0
- package/dist/services/capability-registry/capability-registry.d.ts.map +1 -0
- package/dist/services/capability-registry/capability-registry.js +234 -0
- package/dist/services/capability-registry/capability-registry.js.map +1 -0
- package/dist/services/capability-registry/index.d.ts +9 -0
- package/dist/services/capability-registry/index.d.ts.map +1 -0
- package/dist/services/capability-registry/index.js +7 -0
- package/dist/services/capability-registry/index.js.map +1 -0
- package/dist/services/capability-registry/types.d.ts +67 -0
- package/dist/services/capability-registry/types.d.ts.map +1 -0
- package/dist/services/capability-registry/types.js +9 -0
- package/dist/services/capability-registry/types.js.map +1 -0
- package/dist/services/dataset-store/dataset-store.d.ts +35 -0
- package/dist/services/dataset-store/dataset-store.d.ts.map +1 -0
- package/dist/services/dataset-store/dataset-store.js +190 -0
- package/dist/services/dataset-store/dataset-store.js.map +1 -0
- package/dist/services/dataset-store/index.d.ts +8 -0
- package/dist/services/dataset-store/index.d.ts.map +1 -0
- package/dist/services/dataset-store/index.js +7 -0
- package/dist/services/dataset-store/index.js.map +1 -0
- package/dist/services/dataset-store/types.d.ts +65 -0
- package/dist/services/dataset-store/types.d.ts.map +1 -0
- package/dist/services/dataset-store/types.js +8 -0
- package/dist/services/dataset-store/types.js.map +1 -0
- package/dist/services/ontology-resolver/index.d.ts +8 -0
- package/dist/services/ontology-resolver/index.d.ts.map +1 -0
- package/dist/services/ontology-resolver/index.js +7 -0
- package/dist/services/ontology-resolver/index.js.map +1 -0
- package/dist/services/ontology-resolver/ontology-resolver.d.ts +49 -0
- package/dist/services/ontology-resolver/ontology-resolver.d.ts.map +1 -0
- package/dist/services/ontology-resolver/ontology-resolver.js +99 -0
- package/dist/services/ontology-resolver/ontology-resolver.js.map +1 -0
- package/dist/services/ontology-resolver/types.d.ts +38 -0
- package/dist/services/ontology-resolver/types.d.ts.map +1 -0
- package/dist/services/ontology-resolver/types.js +8 -0
- package/dist/services/ontology-resolver/types.js.map +1 -0
- package/dist/services/reference-data-cache/index.d.ts +9 -0
- package/dist/services/reference-data-cache/index.d.ts.map +1 -0
- package/dist/services/reference-data-cache/index.js +7 -0
- package/dist/services/reference-data-cache/index.js.map +1 -0
- package/dist/services/reference-data-cache/reference-data-cache.d.ts +31 -0
- package/dist/services/reference-data-cache/reference-data-cache.d.ts.map +1 -0
- package/dist/services/reference-data-cache/reference-data-cache.js +131 -0
- package/dist/services/reference-data-cache/reference-data-cache.js.map +1 -0
- package/dist/services/reference-data-cache/types.d.ts +42 -0
- package/dist/services/reference-data-cache/types.d.ts.map +1 -0
- package/dist/services/reference-data-cache/types.js +9 -0
- package/dist/services/reference-data-cache/types.js.map +1 -0
- package/dist/services/server-registry/index.d.ts +9 -0
- package/dist/services/server-registry/index.d.ts.map +1 -0
- package/dist/services/server-registry/index.js +7 -0
- package/dist/services/server-registry/index.js.map +1 -0
- package/dist/services/server-registry/server-registry.d.ts +57 -0
- package/dist/services/server-registry/server-registry.d.ts.map +1 -0
- package/dist/services/server-registry/server-registry.js +210 -0
- package/dist/services/server-registry/server-registry.js.map +1 -0
- package/dist/services/server-registry/types.d.ts +43 -0
- package/dist/services/server-registry/types.d.ts.map +1 -0
- package/dist/services/server-registry/types.js +10 -0
- package/dist/services/server-registry/types.js.map +1 -0
- package/package.json +86 -0
- package/server.json +99 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `brapi_find_variants` — find variant records by variant set,
|
|
3
|
+
* reference, or genomic region. Standard find_* pattern — distributions +
|
|
4
|
+
* dataset spillover. Note: the BrAPI filter catalog uses `start` / `end` as
|
|
5
|
+
* single scalars (1-based inclusive / exclusive) per the spec.
|
|
6
|
+
*
|
|
7
|
+
* @module mcp-server/tools/definitions/brapi-find-variants.tool
|
|
8
|
+
*/
|
|
9
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
10
|
+
import { getServerConfig } from '../../../config/server-config.js';
|
|
11
|
+
import { getBrapiClient } from '../../../services/brapi-client/index.js';
|
|
12
|
+
import { getCapabilityRegistry } from '../../../services/capability-registry/index.js';
|
|
13
|
+
import { getDatasetStore } from '../../../services/dataset-store/index.js';
|
|
14
|
+
import { DEFAULT_ALIAS, getServerRegistry } from '../../../services/server-registry/index.js';
|
|
15
|
+
import { AliasInput, asString, buildRefinementHint, computeDistribution, DatasetHandleSchema, ExtraFiltersInput, LoadLimitInput, loadInitialPage, maybeSpill, mergeFilters, renderDatasetHandle, renderDistributions, } from '../shared/find-helpers.js';
|
|
16
|
+
const VariantRowSchema = z
|
|
17
|
+
.object({
|
|
18
|
+
variantDbId: z.string().describe('Server-side identifier for the variant.'),
|
|
19
|
+
variantNames: z
|
|
20
|
+
.array(z.string().describe('Variant name or alias.'))
|
|
21
|
+
.optional()
|
|
22
|
+
.describe('Known names / aliases for this variant.'),
|
|
23
|
+
variantSetDbId: z
|
|
24
|
+
.union([
|
|
25
|
+
z.string().describe('Single variant-set FK (older BrAPI servers).'),
|
|
26
|
+
z
|
|
27
|
+
.array(z.string().describe('One variant-set FK.'))
|
|
28
|
+
.describe('Variant-set FK array — a variant may belong to multiple sets.'),
|
|
29
|
+
])
|
|
30
|
+
.optional()
|
|
31
|
+
.describe('FK to the variant set(s) this variant belongs to. May be a string or string[] depending on server.'),
|
|
32
|
+
variantSetDbIds: z
|
|
33
|
+
.array(z.string().describe('Variant-set FK.'))
|
|
34
|
+
.optional()
|
|
35
|
+
.describe('Plural-form FK array per BrAPI v2.1 spec, when the server uses it.'),
|
|
36
|
+
variantType: z.string().nullish().describe('Variant type (e.g. "SNP", "INDEL", "DUP").'),
|
|
37
|
+
referenceBases: z
|
|
38
|
+
.string()
|
|
39
|
+
.nullish()
|
|
40
|
+
.describe('Reference allele sequence at the variant position.'),
|
|
41
|
+
alternateBases: z
|
|
42
|
+
.array(z.string().describe('Alternate allele sequence.'))
|
|
43
|
+
.nullish()
|
|
44
|
+
.describe('Alternate alleles observed at this position.'),
|
|
45
|
+
referenceName: z.string().nullish().describe('Reference sequence name (e.g. "chr01").'),
|
|
46
|
+
start: z.number().nullish().describe('1-based inclusive start position.'),
|
|
47
|
+
end: z.number().nullish().describe('1-based exclusive end position.'),
|
|
48
|
+
filtersPassed: z.boolean().nullish().describe('True when the variant passed all QC filters.'),
|
|
49
|
+
filtersApplied: z
|
|
50
|
+
.boolean()
|
|
51
|
+
.nullish()
|
|
52
|
+
.describe('True when QC filters were evaluated on this variant.'),
|
|
53
|
+
filtersFailed: z
|
|
54
|
+
.array(z.string().describe('Filter ID that failed.'))
|
|
55
|
+
.nullish()
|
|
56
|
+
.describe('IDs of QC filters this variant failed, when any.'),
|
|
57
|
+
})
|
|
58
|
+
.passthrough()
|
|
59
|
+
.describe('One BrAPI variant record.');
|
|
60
|
+
const OutputSchema = z.object({
|
|
61
|
+
alias: z.string().describe('Alias of the registered BrAPI connection the call used.'),
|
|
62
|
+
results: z
|
|
63
|
+
.array(VariantRowSchema)
|
|
64
|
+
.describe('Variant rows returned in-context (up to loadLimit).'),
|
|
65
|
+
returnedCount: z.number().int().nonnegative().describe('Length of `results[]`.'),
|
|
66
|
+
totalCount: z.number().int().nonnegative().describe('Total rows reported by the server.'),
|
|
67
|
+
hasMore: z.boolean().describe('True when more rows exist beyond the returned set.'),
|
|
68
|
+
distributions: z
|
|
69
|
+
.object({
|
|
70
|
+
variantType: z
|
|
71
|
+
.record(z.string(), z.number())
|
|
72
|
+
.describe('Variant type → count of variants of that type.'),
|
|
73
|
+
referenceName: z
|
|
74
|
+
.record(z.string(), z.number())
|
|
75
|
+
.describe('Reference sequence name → count of variants on that reference.'),
|
|
76
|
+
variantSetDbId: z
|
|
77
|
+
.record(z.string(), z.number())
|
|
78
|
+
.describe('Variant set ID → count of variants in that set.'),
|
|
79
|
+
})
|
|
80
|
+
.describe('Value frequency per field across the full result set.'),
|
|
81
|
+
refinementHint: z
|
|
82
|
+
.string()
|
|
83
|
+
.optional()
|
|
84
|
+
.describe('Suggested next-step query refinement when the result set is large.'),
|
|
85
|
+
dataset: DatasetHandleSchema.optional().describe('Dataset handle when the full result set was persisted to DatasetStore.'),
|
|
86
|
+
warnings: z
|
|
87
|
+
.array(z.string())
|
|
88
|
+
.describe('Advisory messages (filter overrides, partial data, capability gaps, etc.).'),
|
|
89
|
+
appliedFilters: z
|
|
90
|
+
.record(z.string(), z.unknown())
|
|
91
|
+
.describe('The final filter map sent to the server (named + extraFilters).'),
|
|
92
|
+
});
|
|
93
|
+
export const brapiFindVariants = tool('brapi_find_variants', {
|
|
94
|
+
description: 'Find variant records by variant set, reference sequence, or genomic region (start/end, 1-based inclusive / exclusive). Returns a dataset handle when the upstream total exceeds loadLimit.',
|
|
95
|
+
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
96
|
+
input: z.object({
|
|
97
|
+
alias: AliasInput,
|
|
98
|
+
variantSets: z.array(z.string()).optional().describe('Filter by variantSetDbIds.'),
|
|
99
|
+
variants: z.array(z.string()).optional().describe('Filter by variantDbIds.'),
|
|
100
|
+
references: z.array(z.string()).optional().describe('Filter by referenceDbIds.'),
|
|
101
|
+
referenceName: z.string().optional().describe('Reference display name (e.g. "chr01", "chr1").'),
|
|
102
|
+
start: z.number().int().nonnegative().optional().describe('Inclusive 1-based start.'),
|
|
103
|
+
end: z.number().int().positive().optional().describe('Exclusive 1-based end.'),
|
|
104
|
+
loadLimit: LoadLimitInput,
|
|
105
|
+
extraFilters: ExtraFiltersInput,
|
|
106
|
+
}),
|
|
107
|
+
output: OutputSchema,
|
|
108
|
+
async handler(input, ctx) {
|
|
109
|
+
const registry = getServerRegistry();
|
|
110
|
+
const capabilities = getCapabilityRegistry();
|
|
111
|
+
const client = getBrapiClient();
|
|
112
|
+
const datasetStore = getDatasetStore();
|
|
113
|
+
const config = getServerConfig();
|
|
114
|
+
const connection = await registry.get(ctx, input.alias ?? DEFAULT_ALIAS);
|
|
115
|
+
const capabilityLookup = {};
|
|
116
|
+
if (connection.resolvedAuth)
|
|
117
|
+
capabilityLookup.auth = connection.resolvedAuth;
|
|
118
|
+
await capabilities.ensure(connection.baseUrl, { service: 'variants', method: 'GET' }, ctx, capabilityLookup);
|
|
119
|
+
const warnings = [];
|
|
120
|
+
if (input.start !== undefined && input.end !== undefined && input.start >= input.end) {
|
|
121
|
+
warnings.push('start >= end; upstream will likely return an empty result set.');
|
|
122
|
+
}
|
|
123
|
+
const filters = mergeFilters({
|
|
124
|
+
variantSetDbIds: input.variantSets,
|
|
125
|
+
variantDbIds: input.variants,
|
|
126
|
+
referenceDbIds: input.references,
|
|
127
|
+
referenceName: input.referenceName,
|
|
128
|
+
start: input.start,
|
|
129
|
+
end: input.end,
|
|
130
|
+
}, input.extraFilters, warnings);
|
|
131
|
+
const loadLimit = input.loadLimit ?? config.loadLimit;
|
|
132
|
+
const firstPage = await loadInitialPage(client, connection, '/variants', filters, loadLimit, ctx);
|
|
133
|
+
const { fullRows, dataset: datasetMeta } = await maybeSpill({
|
|
134
|
+
firstPage,
|
|
135
|
+
client,
|
|
136
|
+
connection,
|
|
137
|
+
path: '/variants',
|
|
138
|
+
filters,
|
|
139
|
+
source: 'find_variants',
|
|
140
|
+
loadLimit,
|
|
141
|
+
ctx,
|
|
142
|
+
store: datasetStore,
|
|
143
|
+
});
|
|
144
|
+
const distributions = {
|
|
145
|
+
variantType: computeDistribution(fullRows, (r) => asString(r.variantType)),
|
|
146
|
+
referenceName: computeDistribution(fullRows, (r) => asString(r.referenceName)),
|
|
147
|
+
variantSetDbId: computeDistribution(fullRows, (r) => collectVariantSetIds(r)),
|
|
148
|
+
};
|
|
149
|
+
const totalCount = firstPage.totalCount ?? firstPage.rows.length;
|
|
150
|
+
const refinementHint = buildRefinementHint(totalCount, loadLimit, distributions);
|
|
151
|
+
const result = {
|
|
152
|
+
alias: connection.alias,
|
|
153
|
+
results: firstPage.rows,
|
|
154
|
+
returnedCount: firstPage.rows.length,
|
|
155
|
+
totalCount,
|
|
156
|
+
hasMore: firstPage.hasMore,
|
|
157
|
+
distributions,
|
|
158
|
+
warnings,
|
|
159
|
+
appliedFilters: filters,
|
|
160
|
+
};
|
|
161
|
+
if (refinementHint)
|
|
162
|
+
result.refinementHint = refinementHint;
|
|
163
|
+
if (datasetMeta)
|
|
164
|
+
result.dataset = datasetMeta;
|
|
165
|
+
return result;
|
|
166
|
+
},
|
|
167
|
+
format: (result) => {
|
|
168
|
+
const lines = [];
|
|
169
|
+
lines.push(`# ${result.returnedCount} of ${result.totalCount} variants — \`${result.alias}\``);
|
|
170
|
+
lines.push('');
|
|
171
|
+
if (result.hasMore) {
|
|
172
|
+
lines.push(`⚠ More rows exist beyond the returned set. ${result.dataset ? `Full set persisted as dataset \`${result.dataset.datasetId}\`.` : 'Narrow filters or raise loadLimit.'}`);
|
|
173
|
+
lines.push('');
|
|
174
|
+
}
|
|
175
|
+
if (result.refinementHint) {
|
|
176
|
+
lines.push(`**Refinement hint:** ${result.refinementHint}`);
|
|
177
|
+
lines.push('');
|
|
178
|
+
}
|
|
179
|
+
lines.push(`Applied filters: \`${JSON.stringify(result.appliedFilters)}\``);
|
|
180
|
+
lines.push('');
|
|
181
|
+
lines.push('## Distributions');
|
|
182
|
+
lines.push(renderDistributions(result.distributions) || '_No values to summarize._');
|
|
183
|
+
lines.push('');
|
|
184
|
+
lines.push('## Variants');
|
|
185
|
+
if (result.results.length === 0) {
|
|
186
|
+
lines.push('_No rows returned._');
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
for (const v of result.results) {
|
|
190
|
+
const label = v.variantNames?.[0] ?? v.variantDbId;
|
|
191
|
+
const parts = [`**${label}**`];
|
|
192
|
+
parts.push(`id=\`${v.variantDbId}\``);
|
|
193
|
+
if (v.variantType)
|
|
194
|
+
parts.push(`type=${v.variantType}`);
|
|
195
|
+
const setIds = collectVariantSetIds(v);
|
|
196
|
+
if (setIds && setIds.length > 0)
|
|
197
|
+
parts.push(`set=${setIds.join(',')}`);
|
|
198
|
+
if (v.referenceName)
|
|
199
|
+
parts.push(`ref=${v.referenceName}`);
|
|
200
|
+
if (v.start != null)
|
|
201
|
+
parts.push(`start=${v.start}`);
|
|
202
|
+
if (v.end != null)
|
|
203
|
+
parts.push(`end=${v.end}`);
|
|
204
|
+
if (v.referenceBases)
|
|
205
|
+
parts.push(`refBases=${v.referenceBases}`);
|
|
206
|
+
if (v.alternateBases?.length)
|
|
207
|
+
parts.push(`altBases=${v.alternateBases.join(',')}`);
|
|
208
|
+
if (v.filtersApplied != null)
|
|
209
|
+
parts.push(`filtersApplied=${v.filtersApplied}`);
|
|
210
|
+
if (v.filtersPassed != null)
|
|
211
|
+
parts.push(`filtersPassed=${v.filtersPassed}`);
|
|
212
|
+
if (v.filtersFailed?.length)
|
|
213
|
+
parts.push(`filtersFailed=${v.filtersFailed.join(',')}`);
|
|
214
|
+
if (v.variantNames?.length)
|
|
215
|
+
parts.push(`names=${v.variantNames.join(',')}`);
|
|
216
|
+
lines.push(`- ${parts.join(' · ')}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (result.dataset) {
|
|
220
|
+
lines.push('');
|
|
221
|
+
lines.push('## Dataset handle');
|
|
222
|
+
lines.push(...renderDatasetHandle(result.dataset));
|
|
223
|
+
}
|
|
224
|
+
if (result.warnings.length > 0) {
|
|
225
|
+
lines.push('');
|
|
226
|
+
lines.push('## Warnings');
|
|
227
|
+
for (const w of result.warnings)
|
|
228
|
+
lines.push(`- ${w}`);
|
|
229
|
+
}
|
|
230
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
function collectVariantSetIds(row) {
|
|
234
|
+
const ids = new Set();
|
|
235
|
+
const collect = (value) => {
|
|
236
|
+
if (typeof value === 'string' && value.length > 0)
|
|
237
|
+
ids.add(value);
|
|
238
|
+
else if (Array.isArray(value)) {
|
|
239
|
+
for (const v of value)
|
|
240
|
+
if (typeof v === 'string' && v.length > 0)
|
|
241
|
+
ids.add(v);
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
collect(row.variantSetDbId);
|
|
245
|
+
collect(row.variantSetDbIds);
|
|
246
|
+
return ids.size > 0 ? Array.from(ids) : undefined;
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=brapi-find-variants.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brapi-find-variants.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/brapi-find-variants.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `brapi_get_germplasm` — fetch a single germplasm with
|
|
3
|
+
* attributes and direct parents, plus companion counts (studies the
|
|
4
|
+
* germplasm has appeared in, direct parents, direct descendants) to signal
|
|
5
|
+
* where to drill next.
|
|
6
|
+
*
|
|
7
|
+
* @module mcp-server/tools/definitions/brapi-get-germplasm.tool
|
|
8
|
+
*/
|
|
9
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
10
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
11
|
+
export declare const brapiGetGermplasm: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
12
|
+
germplasmDbId: z.ZodString;
|
|
13
|
+
alias: z.ZodOptional<z.ZodString>;
|
|
14
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
15
|
+
alias: z.ZodString;
|
|
16
|
+
germplasm: z.ZodObject<{
|
|
17
|
+
germplasmDbId: z.ZodString;
|
|
18
|
+
germplasmName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
19
|
+
germplasmPUI: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
20
|
+
commonCropName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
21
|
+
accessionNumber: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
22
|
+
genus: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
23
|
+
species: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
24
|
+
subtaxa: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
25
|
+
defaultDisplayName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
26
|
+
pedigree: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
27
|
+
biologicalStatusOfAccessionDescription: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
28
|
+
germplasmOrigin: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{}, z.core.$loose>>>>;
|
|
29
|
+
countryOfOriginCode: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
30
|
+
collection: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
31
|
+
instituteCode: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
32
|
+
instituteName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
33
|
+
synonyms: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
34
|
+
synonym: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
35
|
+
type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
36
|
+
}, z.core.$loose>>>>;
|
|
37
|
+
}, z.core.$loose>;
|
|
38
|
+
parents: z.ZodArray<z.ZodObject<{
|
|
39
|
+
germplasmDbId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
40
|
+
germplasmName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
41
|
+
parentType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
42
|
+
}, z.core.$loose>>;
|
|
43
|
+
attributes: z.ZodArray<z.ZodObject<{
|
|
44
|
+
attributeDbId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
45
|
+
attributeName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
46
|
+
attributeValue: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
47
|
+
determinedDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
48
|
+
}, z.core.$loose>>;
|
|
49
|
+
studyCount: z.ZodOptional<z.ZodNumber>;
|
|
50
|
+
directParentCount: z.ZodNumber;
|
|
51
|
+
directDescendantCount: z.ZodOptional<z.ZodNumber>;
|
|
52
|
+
warnings: z.ZodArray<z.ZodString>;
|
|
53
|
+
}, z.core.$strip>, readonly [{
|
|
54
|
+
readonly reason: "germplasm_not_found";
|
|
55
|
+
readonly code: JsonRpcErrorCode.NotFound;
|
|
56
|
+
readonly when: "Upstream returned no germplasm record for the requested DbId";
|
|
57
|
+
readonly recovery: "Verify the germplasmDbId on the target server, or run brapi_find_germplasm to discover valid IDs.";
|
|
58
|
+
}]>;
|
|
59
|
+
//# sourceMappingURL=brapi-get-germplasm.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brapi-get-germplasm.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/brapi-get-germplasm.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAkGjE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8M5B,CAAC"}
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `brapi_get_germplasm` — fetch a single germplasm with
|
|
3
|
+
* attributes and direct parents, plus companion counts (studies the
|
|
4
|
+
* germplasm has appeared in, direct parents, direct descendants) to signal
|
|
5
|
+
* where to drill next.
|
|
6
|
+
*
|
|
7
|
+
* @module mcp-server/tools/definitions/brapi-get-germplasm.tool
|
|
8
|
+
*/
|
|
9
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
10
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
11
|
+
import { getBrapiClient } from '../../../services/brapi-client/index.js';
|
|
12
|
+
import { getCapabilityRegistry } from '../../../services/capability-registry/index.js';
|
|
13
|
+
import { DEFAULT_ALIAS, getServerRegistry } from '../../../services/server-registry/index.js';
|
|
14
|
+
import { AliasInput, buildRequestOptions, isUpstreamNotFound } from '../shared/find-helpers.js';
|
|
15
|
+
const GermplasmSchema = z
|
|
16
|
+
.object({
|
|
17
|
+
germplasmDbId: z.string().describe('Server-side identifier for the germplasm.'),
|
|
18
|
+
germplasmName: z.string().nullish().describe('Display name.'),
|
|
19
|
+
germplasmPUI: z.string().nullish().describe('Persistent unique identifier (URI).'),
|
|
20
|
+
commonCropName: z.string().nullish().describe('Common crop name.'),
|
|
21
|
+
accessionNumber: z.string().nullish().describe('Gene-bank catalog number.'),
|
|
22
|
+
genus: z.string().nullish().describe('Botanical genus.'),
|
|
23
|
+
species: z.string().nullish().describe('Botanical species.'),
|
|
24
|
+
subtaxa: z.string().nullish().describe('Botanical subtaxa.'),
|
|
25
|
+
defaultDisplayName: z.string().nullish().describe('Preferred display label.'),
|
|
26
|
+
pedigree: z.string().nullish().describe('Pedigree as a free-text string.'),
|
|
27
|
+
biologicalStatusOfAccessionDescription: z
|
|
28
|
+
.string()
|
|
29
|
+
.nullish()
|
|
30
|
+
.describe('MCPD biological-status label.'),
|
|
31
|
+
germplasmOrigin: z
|
|
32
|
+
.array(z
|
|
33
|
+
.object({})
|
|
34
|
+
.passthrough()
|
|
35
|
+
.describe('One origin record (collection coordinates and uncertainty per BrAPI v2).'))
|
|
36
|
+
.nullish()
|
|
37
|
+
.describe('Origin records — array of collection-site objects per BrAPI v2.'),
|
|
38
|
+
countryOfOriginCode: z.string().nullish().describe('ISO 3166-1 alpha-3 country code.'),
|
|
39
|
+
collection: z.string().nullish().describe('Collection name.'),
|
|
40
|
+
instituteCode: z.string().nullish().describe('FAO WIEWS institute code.'),
|
|
41
|
+
instituteName: z.string().nullish().describe('Display name of the holding institute.'),
|
|
42
|
+
synonyms: z
|
|
43
|
+
.array(z
|
|
44
|
+
.object({
|
|
45
|
+
synonym: z.string().nullish().describe('Synonym value.'),
|
|
46
|
+
type: z.string().nullish().describe('Synonym type (e.g. "COMMON", "SYNONYM").'),
|
|
47
|
+
})
|
|
48
|
+
.passthrough()
|
|
49
|
+
.describe('Registered synonym for this germplasm.'))
|
|
50
|
+
.nullish()
|
|
51
|
+
.describe('All registered synonyms.'),
|
|
52
|
+
})
|
|
53
|
+
.passthrough();
|
|
54
|
+
const ParentSchema = z
|
|
55
|
+
.object({
|
|
56
|
+
germplasmDbId: z.string().nullish().describe('FK to the parent germplasm.'),
|
|
57
|
+
germplasmName: z.string().nullish().describe('Display name of the parent germplasm.'),
|
|
58
|
+
parentType: z.string().nullish().describe('E.g. "MALE", "FEMALE", "SELF".'),
|
|
59
|
+
})
|
|
60
|
+
.passthrough()
|
|
61
|
+
.describe('One direct parent of the germplasm.');
|
|
62
|
+
const AttributeSchema = z
|
|
63
|
+
.object({
|
|
64
|
+
attributeDbId: z.string().nullish().describe('Attribute identifier.'),
|
|
65
|
+
attributeName: z.string().nullish().describe('Attribute display name.'),
|
|
66
|
+
attributeValue: z.string().nullish().describe('Recorded value (stringified).'),
|
|
67
|
+
determinedDate: z.string().nullish().describe('ISO 8601 date the attribute was determined.'),
|
|
68
|
+
})
|
|
69
|
+
.passthrough()
|
|
70
|
+
.describe('One germplasm attribute record.');
|
|
71
|
+
const OutputSchema = z.object({
|
|
72
|
+
alias: z.string().describe('Alias of the registered BrAPI connection the call used.'),
|
|
73
|
+
germplasm: GermplasmSchema.describe('Canonical germplasm record as returned by `/germplasm/{id}`.'),
|
|
74
|
+
parents: z.array(ParentSchema).describe('Direct parents from /germplasm/{id}/pedigree.'),
|
|
75
|
+
attributes: z
|
|
76
|
+
.array(AttributeSchema)
|
|
77
|
+
.describe('Germplasm attributes from /germplasm/{id}/attributes.'),
|
|
78
|
+
studyCount: z
|
|
79
|
+
.number()
|
|
80
|
+
.int()
|
|
81
|
+
.nonnegative()
|
|
82
|
+
.optional()
|
|
83
|
+
.describe('How many studies this germplasm has appeared in.'),
|
|
84
|
+
directParentCount: z.number().int().nonnegative().describe('Count of direct parents.'),
|
|
85
|
+
directDescendantCount: z
|
|
86
|
+
.number()
|
|
87
|
+
.int()
|
|
88
|
+
.nonnegative()
|
|
89
|
+
.optional()
|
|
90
|
+
.describe('Count of direct descendants from /germplasm/{id}/progeny.'),
|
|
91
|
+
warnings: z
|
|
92
|
+
.array(z.string())
|
|
93
|
+
.describe('Advisory messages — failed sub-endpoint lookups, missing counts.'),
|
|
94
|
+
});
|
|
95
|
+
export const brapiGetGermplasm = tool('brapi_get_germplasm', {
|
|
96
|
+
description: 'Fetch a single germplasm by DbId with attributes and direct parents. Response companions report study count, direct parent count, and direct descendant count — signals for pedigree depth and observation coverage.',
|
|
97
|
+
annotations: { readOnlyHint: true, idempotentHint: true },
|
|
98
|
+
errors: [
|
|
99
|
+
{
|
|
100
|
+
reason: 'germplasm_not_found',
|
|
101
|
+
code: JsonRpcErrorCode.NotFound,
|
|
102
|
+
when: 'Upstream returned no germplasm record for the requested DbId',
|
|
103
|
+
recovery: 'Verify the germplasmDbId on the target server, or run brapi_find_germplasm to discover valid IDs.',
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
input: z.object({
|
|
107
|
+
germplasmDbId: z.string().min(1).describe('Germplasm identifier.'),
|
|
108
|
+
alias: AliasInput,
|
|
109
|
+
}),
|
|
110
|
+
output: OutputSchema,
|
|
111
|
+
async handler(input, ctx) {
|
|
112
|
+
const registry = getServerRegistry();
|
|
113
|
+
const capabilities = getCapabilityRegistry();
|
|
114
|
+
const client = getBrapiClient();
|
|
115
|
+
const connection = await registry.get(ctx, input.alias ?? DEFAULT_ALIAS);
|
|
116
|
+
const capabilityLookup = {};
|
|
117
|
+
if (connection.resolvedAuth)
|
|
118
|
+
capabilityLookup.auth = connection.resolvedAuth;
|
|
119
|
+
await capabilities.ensure(connection.baseUrl, { service: 'germplasm', method: 'GET' }, ctx, capabilityLookup);
|
|
120
|
+
const id = encodeURIComponent(input.germplasmDbId);
|
|
121
|
+
const warnings = [];
|
|
122
|
+
let germplasmEnv;
|
|
123
|
+
try {
|
|
124
|
+
germplasmEnv = await client.get(connection.baseUrl, `/germplasm/${id}`, ctx, buildRequestOptions(connection));
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
if (isUpstreamNotFound(err)) {
|
|
128
|
+
throw ctx.fail('germplasm_not_found', `Germplasm '${input.germplasmDbId}' not found on ${connection.baseUrl}.`, {
|
|
129
|
+
germplasmDbId: input.germplasmDbId,
|
|
130
|
+
baseUrl: connection.baseUrl,
|
|
131
|
+
...ctx.recoveryFor('germplasm_not_found'),
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
throw err;
|
|
135
|
+
}
|
|
136
|
+
const germplasm = germplasmEnv.result;
|
|
137
|
+
if (!germplasm || typeof germplasm !== 'object' || !germplasm.germplasmDbId) {
|
|
138
|
+
throw ctx.fail('germplasm_not_found', `Germplasm '${input.germplasmDbId}' not found on ${connection.baseUrl}.`, {
|
|
139
|
+
germplasmDbId: input.germplasmDbId,
|
|
140
|
+
baseUrl: connection.baseUrl,
|
|
141
|
+
...ctx.recoveryFor('germplasm_not_found'),
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
const profile = await capabilities.profile(connection.baseUrl, ctx, capabilityLookup);
|
|
145
|
+
const supportsPedigree = Boolean(profile.supported['germplasm/{germplasmDbId}/pedigree']);
|
|
146
|
+
const supportsAttributes = Boolean(profile.supported['germplasm/{germplasmDbId}/attributes']);
|
|
147
|
+
const supportsProgeny = Boolean(profile.supported['germplasm/{germplasmDbId}/progeny']);
|
|
148
|
+
const supportsStudies = profile.supported.studies?.methods?.includes('GET') ?? false;
|
|
149
|
+
const [pedigree, attributes, studyCount, progenyCount] = await Promise.all([
|
|
150
|
+
supportsPedigree
|
|
151
|
+
? fetchPedigree(client, connection.baseUrl, id, ctx, buildRequestOptions(connection)).catch((err) => recordWarning(warnings, 'pedigree lookup failed', err))
|
|
152
|
+
: Promise.resolve(undefined),
|
|
153
|
+
supportsAttributes
|
|
154
|
+
? fetchAttributes(client, connection.baseUrl, id, ctx, buildRequestOptions(connection)).catch((err) => recordWarning(warnings, 'attributes lookup failed', err))
|
|
155
|
+
: Promise.resolve(undefined),
|
|
156
|
+
supportsStudies
|
|
157
|
+
? fetchTotalCount(client, connection.baseUrl, '/studies', ctx, buildRequestOptions(connection, {
|
|
158
|
+
germplasmDbIds: [input.germplasmDbId],
|
|
159
|
+
pageSize: 1,
|
|
160
|
+
})).catch((err) => recordWarning(warnings, 'study count probe failed', err))
|
|
161
|
+
: Promise.resolve(undefined),
|
|
162
|
+
supportsProgeny
|
|
163
|
+
? fetchTotalCount(client, connection.baseUrl, `/germplasm/${id}/progeny`, ctx, buildRequestOptions(connection, { pageSize: 1 })).catch((err) => recordWarning(warnings, 'progeny count probe failed', err))
|
|
164
|
+
: Promise.resolve(undefined),
|
|
165
|
+
]);
|
|
166
|
+
const parents = pedigree?.parents ?? [];
|
|
167
|
+
const attrList = attributes ?? [];
|
|
168
|
+
const result = {
|
|
169
|
+
alias: connection.alias,
|
|
170
|
+
germplasm: germplasm,
|
|
171
|
+
parents,
|
|
172
|
+
attributes: attrList,
|
|
173
|
+
directParentCount: parents.length,
|
|
174
|
+
warnings,
|
|
175
|
+
};
|
|
176
|
+
if (typeof studyCount === 'number')
|
|
177
|
+
result.studyCount = studyCount;
|
|
178
|
+
if (typeof progenyCount === 'number')
|
|
179
|
+
result.directDescendantCount = progenyCount;
|
|
180
|
+
return result;
|
|
181
|
+
},
|
|
182
|
+
format: (result) => {
|
|
183
|
+
const lines = [];
|
|
184
|
+
const g = result.germplasm;
|
|
185
|
+
lines.push(`# ${g.germplasmName ?? g.defaultDisplayName ?? g.germplasmDbId}`);
|
|
186
|
+
lines.push('');
|
|
187
|
+
lines.push(`- **germplasmDbId:** \`${g.germplasmDbId}\``);
|
|
188
|
+
if (g.germplasmName)
|
|
189
|
+
lines.push(`- **germplasmName:** ${g.germplasmName}`);
|
|
190
|
+
if (g.germplasmPUI)
|
|
191
|
+
lines.push(`- **germplasmPUI:** ${g.germplasmPUI}`);
|
|
192
|
+
if (g.commonCropName)
|
|
193
|
+
lines.push(`- **commonCropName:** ${g.commonCropName}`);
|
|
194
|
+
if (g.accessionNumber)
|
|
195
|
+
lines.push(`- **accessionNumber:** ${g.accessionNumber}`);
|
|
196
|
+
if (g.genus)
|
|
197
|
+
lines.push(`- **genus:** ${g.genus}`);
|
|
198
|
+
if (g.species)
|
|
199
|
+
lines.push(`- **species:** ${g.species}`);
|
|
200
|
+
if (g.subtaxa)
|
|
201
|
+
lines.push(`- **subtaxa:** ${g.subtaxa}`);
|
|
202
|
+
if (g.defaultDisplayName)
|
|
203
|
+
lines.push(`- **defaultDisplayName:** ${g.defaultDisplayName}`);
|
|
204
|
+
if (g.pedigree)
|
|
205
|
+
lines.push(`- **pedigree (string):** ${g.pedigree}`);
|
|
206
|
+
if (g.biologicalStatusOfAccessionDescription)
|
|
207
|
+
lines.push(`- **biologicalStatus:** ${g.biologicalStatusOfAccessionDescription}`);
|
|
208
|
+
if (g.germplasmOrigin?.length)
|
|
209
|
+
lines.push(`- **germplasmOrigin:** ${g.germplasmOrigin.length} record(s)`);
|
|
210
|
+
if (g.countryOfOriginCode)
|
|
211
|
+
lines.push(`- **countryOfOriginCode:** ${g.countryOfOriginCode}`);
|
|
212
|
+
if (g.collection)
|
|
213
|
+
lines.push(`- **collection:** ${g.collection}`);
|
|
214
|
+
if (g.instituteCode)
|
|
215
|
+
lines.push(`- **instituteCode:** ${g.instituteCode}`);
|
|
216
|
+
if (g.instituteName)
|
|
217
|
+
lines.push(`- **instituteName:** ${g.instituteName}`);
|
|
218
|
+
if (g.synonyms?.length) {
|
|
219
|
+
const synStr = g.synonyms
|
|
220
|
+
.map((s) => `${s.synonym ?? '?'}${s.type ? ` (${s.type})` : ''}`)
|
|
221
|
+
.join(', ');
|
|
222
|
+
lines.push(`- **synonyms:** ${synStr}`);
|
|
223
|
+
}
|
|
224
|
+
lines.push(`- **alias:** ${result.alias}`);
|
|
225
|
+
lines.push('');
|
|
226
|
+
lines.push(`## Parents (${result.directParentCount})`);
|
|
227
|
+
if (result.parents.length === 0) {
|
|
228
|
+
lines.push('_No parents recorded._');
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
for (const p of result.parents) {
|
|
232
|
+
const parts = [];
|
|
233
|
+
if (p.germplasmName)
|
|
234
|
+
parts.push(p.germplasmName);
|
|
235
|
+
if (p.germplasmDbId)
|
|
236
|
+
parts.push(`id=\`${p.germplasmDbId}\``);
|
|
237
|
+
if (p.parentType)
|
|
238
|
+
parts.push(`type=${p.parentType}`);
|
|
239
|
+
lines.push(`- ${parts.join(' · ')}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
lines.push('');
|
|
243
|
+
lines.push(`## Attributes (${result.attributes.length})`);
|
|
244
|
+
if (result.attributes.length === 0) {
|
|
245
|
+
lines.push('_No attributes recorded._');
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
for (const a of result.attributes) {
|
|
249
|
+
const parts = [];
|
|
250
|
+
if (a.attributeName)
|
|
251
|
+
parts.push(a.attributeName);
|
|
252
|
+
if (a.attributeDbId)
|
|
253
|
+
parts.push(`(id=\`${a.attributeDbId}\`)`);
|
|
254
|
+
if (a.attributeValue != null)
|
|
255
|
+
parts.push(`= ${a.attributeValue}`);
|
|
256
|
+
if (a.determinedDate)
|
|
257
|
+
parts.push(`[determined ${a.determinedDate}]`);
|
|
258
|
+
lines.push(`- ${parts.join(' ')}`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
lines.push('');
|
|
262
|
+
lines.push('## Drill-down signals');
|
|
263
|
+
lines.push(`- studyCount: ${result.studyCount ?? '—'}`);
|
|
264
|
+
lines.push(`- directParentCount: ${result.directParentCount}`);
|
|
265
|
+
lines.push(`- directDescendantCount: ${result.directDescendantCount ?? '—'}`);
|
|
266
|
+
if (result.warnings.length > 0) {
|
|
267
|
+
lines.push('');
|
|
268
|
+
lines.push('## Warnings');
|
|
269
|
+
for (const w of result.warnings)
|
|
270
|
+
lines.push(`- ${w}`);
|
|
271
|
+
}
|
|
272
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
273
|
+
},
|
|
274
|
+
});
|
|
275
|
+
function recordWarning(warnings, label, err) {
|
|
276
|
+
warnings.push(`${label}: ${err instanceof Error ? err.message : String(err)}`);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
async function fetchPedigree(client, baseUrl, id, ctx, options) {
|
|
280
|
+
const env = await client.get(baseUrl, `/germplasm/${id}/pedigree`, ctx, options);
|
|
281
|
+
const result = env.result;
|
|
282
|
+
if (!result || typeof result !== 'object')
|
|
283
|
+
return { parents: [] };
|
|
284
|
+
const rawParents = result.parents;
|
|
285
|
+
if (!Array.isArray(rawParents))
|
|
286
|
+
return { parents: [] };
|
|
287
|
+
return {
|
|
288
|
+
parents: rawParents.filter((p) => typeof p === 'object' && p !== null),
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
async function fetchAttributes(client, baseUrl, id, ctx, options) {
|
|
292
|
+
const env = await client.get(baseUrl, `/germplasm/${id}/attributes`, ctx, options);
|
|
293
|
+
const result = env.result;
|
|
294
|
+
const rows = Array.isArray(result)
|
|
295
|
+
? result
|
|
296
|
+
: Array.isArray(result?.data)
|
|
297
|
+
? result.data
|
|
298
|
+
: [];
|
|
299
|
+
return rows.filter((r) => typeof r === 'object' && r !== null);
|
|
300
|
+
}
|
|
301
|
+
async function fetchTotalCount(client, baseUrl, path, ctx, options) {
|
|
302
|
+
const env = await client.get(baseUrl, path, ctx, options);
|
|
303
|
+
const total = env.metadata?.pagination?.totalCount;
|
|
304
|
+
return typeof total === 'number' ? total : undefined;
|
|
305
|
+
}
|
|
306
|
+
//# sourceMappingURL=brapi-get-germplasm.tool.js.map
|