@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,574 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `brapi_submit_observations` — submit new or updated
|
|
3
|
+
* observations for a study. Two-phase write: `mode: 'preview'` validates rows
|
|
4
|
+
* against the study's observation variables and returns a routing breakdown
|
|
5
|
+
* (POST for new rows, PUT for rows carrying `observationDbId`); `mode: 'apply'`
|
|
6
|
+
* elicits confirmation when supported, fans the rows out to POST + PUT in
|
|
7
|
+
* parallel, then verifies the post-state with a cheap `pageSize=0` count.
|
|
8
|
+
* Additive write — no observation is destroyed by this tool.
|
|
9
|
+
*
|
|
10
|
+
* @module mcp-server/tools/definitions/brapi-submit-observations.tool
|
|
11
|
+
*/
|
|
12
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
13
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
14
|
+
import { getBrapiClient } from '../../../services/brapi-client/index.js';
|
|
15
|
+
import { getCapabilityRegistry } from '../../../services/capability-registry/index.js';
|
|
16
|
+
import { DEFAULT_ALIAS, getServerRegistry } from '../../../services/server-registry/index.js';
|
|
17
|
+
import { AliasInput, buildRequestOptions, extractRows, isUpstreamNotFound, } from '../shared/find-helpers.js';
|
|
18
|
+
const ObservationRowSchema = z
|
|
19
|
+
.object({
|
|
20
|
+
observationDbId: z
|
|
21
|
+
.string()
|
|
22
|
+
.min(1)
|
|
23
|
+
.optional()
|
|
24
|
+
.describe('Server-assigned identifier of an existing observation. When present, the row updates that observation; when absent, the row creates a new one.'),
|
|
25
|
+
observationUnitDbId: z
|
|
26
|
+
.string()
|
|
27
|
+
.min(1)
|
|
28
|
+
.describe('FK to the observation unit (plot / plant / sample) the value applies to. Required.'),
|
|
29
|
+
observationVariableDbId: z
|
|
30
|
+
.string()
|
|
31
|
+
.min(1)
|
|
32
|
+
.describe('FK to the observation variable (trait) being measured. Required.'),
|
|
33
|
+
value: z
|
|
34
|
+
.string()
|
|
35
|
+
.describe('Recorded measurement value, stringified per BrAPI convention. Empty strings are flagged as warnings.'),
|
|
36
|
+
collector: z.string().optional().describe('Name or ID of the person who collected the value.'),
|
|
37
|
+
observationTimeStamp: z
|
|
38
|
+
.string()
|
|
39
|
+
.optional()
|
|
40
|
+
.describe('ISO 8601 timestamp the observation was taken.'),
|
|
41
|
+
season: z
|
|
42
|
+
.object({
|
|
43
|
+
seasonDbId: z.string().optional().describe('Server-side season identifier.'),
|
|
44
|
+
year: z.string().optional().describe('Calendar year (e.g. "2024").'),
|
|
45
|
+
season: z.string().optional().describe('Season label (e.g. "wet", "dry", "Q1").'),
|
|
46
|
+
})
|
|
47
|
+
.optional()
|
|
48
|
+
.describe('Season block. Most servers tolerate either seasonDbId or year+label.'),
|
|
49
|
+
geoCoordinates: z
|
|
50
|
+
.object({
|
|
51
|
+
type: z.literal('Feature').describe('GeoJSON feature type (always "Feature").'),
|
|
52
|
+
geometry: z
|
|
53
|
+
.object({
|
|
54
|
+
type: z.literal('Point').describe('GeoJSON geometry type (always "Point").'),
|
|
55
|
+
coordinates: z
|
|
56
|
+
.array(z.number())
|
|
57
|
+
.length(2)
|
|
58
|
+
.describe('[longitude, latitude] in WGS84 decimal degrees.'),
|
|
59
|
+
})
|
|
60
|
+
.describe('GeoJSON point geometry.'),
|
|
61
|
+
})
|
|
62
|
+
.optional()
|
|
63
|
+
.describe('Optional GeoJSON Feature carrying lon/lat for this observation.'),
|
|
64
|
+
})
|
|
65
|
+
.describe('One observation row. observationDbId presence routes to PUT vs POST.');
|
|
66
|
+
const PerRowWarningSchema = z
|
|
67
|
+
.object({
|
|
68
|
+
rowIndex: z.number().int().nonnegative().describe('Zero-based index of the row in the input.'),
|
|
69
|
+
observationVariableDbId: z
|
|
70
|
+
.string()
|
|
71
|
+
.optional()
|
|
72
|
+
.describe('Variable DbId on the row, when present.'),
|
|
73
|
+
observationUnitDbId: z.string().optional().describe('Unit DbId on the row, when present.'),
|
|
74
|
+
warning: z.string().describe('What was unusual about this row.'),
|
|
75
|
+
})
|
|
76
|
+
.describe('Per-row validation warning — does not abort the batch.');
|
|
77
|
+
const PreviewBranchSchema = z
|
|
78
|
+
.object({
|
|
79
|
+
mode: z.literal('preview').describe('Discriminator — `preview` reports validation only.'),
|
|
80
|
+
studyDbId: z.string().describe('Study the rows belong to.'),
|
|
81
|
+
studyName: z.string().optional().describe('Display name of the study, when available.'),
|
|
82
|
+
valid: z.number().int().nonnegative().describe('Rows that pass per-row validation.'),
|
|
83
|
+
invalid: z
|
|
84
|
+
.number()
|
|
85
|
+
.int()
|
|
86
|
+
.nonnegative()
|
|
87
|
+
.describe('Rows with structural problems severe enough to skip on apply (missing required FKs, etc.).'),
|
|
88
|
+
routing: z
|
|
89
|
+
.object({
|
|
90
|
+
postCount: z
|
|
91
|
+
.number()
|
|
92
|
+
.int()
|
|
93
|
+
.nonnegative()
|
|
94
|
+
.describe('Rows that would be POSTed (no observationDbId).'),
|
|
95
|
+
putCount: z
|
|
96
|
+
.number()
|
|
97
|
+
.int()
|
|
98
|
+
.nonnegative()
|
|
99
|
+
.describe('Rows that would be PUT (observationDbId present).'),
|
|
100
|
+
})
|
|
101
|
+
.describe('How rows would split across POST vs PUT.'),
|
|
102
|
+
perRowWarnings: z
|
|
103
|
+
.array(PerRowWarningSchema)
|
|
104
|
+
.describe('Per-row notes — unknown variables, empty values, missing IDs.'),
|
|
105
|
+
knownVariableCount: z
|
|
106
|
+
.number()
|
|
107
|
+
.int()
|
|
108
|
+
.nonnegative()
|
|
109
|
+
.describe('Count of variables exposed by the study (used to validate rows).'),
|
|
110
|
+
})
|
|
111
|
+
.describe('Preview output — no writes have occurred.');
|
|
112
|
+
const ApplyBranchSchema = z
|
|
113
|
+
.object({
|
|
114
|
+
mode: z.literal('apply').describe('Discriminator — `apply` reports post-write state.'),
|
|
115
|
+
studyDbId: z.string().describe('Study the rows belong to.'),
|
|
116
|
+
studyName: z.string().optional().describe('Display name of the study, when available.'),
|
|
117
|
+
posted: z
|
|
118
|
+
.array(z
|
|
119
|
+
.object({
|
|
120
|
+
observationDbId: z
|
|
121
|
+
.string()
|
|
122
|
+
.optional()
|
|
123
|
+
.describe('Server-assigned observationDbId (when echoed in the response).'),
|
|
124
|
+
observationUnitDbId: z.string().optional().describe('FK echoed from the server.'),
|
|
125
|
+
observationVariableDbId: z.string().optional().describe('FK echoed from the server.'),
|
|
126
|
+
value: z.string().optional().describe('Value echoed from the server.'),
|
|
127
|
+
})
|
|
128
|
+
.describe('One created observation as echoed by the server.'))
|
|
129
|
+
.describe('Observations created by the call (POST results).'),
|
|
130
|
+
updated: z
|
|
131
|
+
.array(z
|
|
132
|
+
.object({
|
|
133
|
+
observationDbId: z.string().describe('Existing observationDbId that was updated.'),
|
|
134
|
+
observationUnitDbId: z.string().optional().describe('FK echoed from the server.'),
|
|
135
|
+
observationVariableDbId: z.string().optional().describe('FK echoed from the server.'),
|
|
136
|
+
value: z.string().optional().describe('New value echoed from the server.'),
|
|
137
|
+
})
|
|
138
|
+
.describe('One updated observation as echoed by the server.'))
|
|
139
|
+
.describe('Observations updated by the call (PUT results).'),
|
|
140
|
+
studyObservationCount: z
|
|
141
|
+
.number()
|
|
142
|
+
.int()
|
|
143
|
+
.nonnegative()
|
|
144
|
+
.optional()
|
|
145
|
+
.describe('Total observations recorded against the study after the write (cheap probe).'),
|
|
146
|
+
latestObservationTimestamp: z
|
|
147
|
+
.string()
|
|
148
|
+
.optional()
|
|
149
|
+
.describe('Most recent `observationTimeStamp` across the rows accepted in this call.'),
|
|
150
|
+
perRowWarnings: z
|
|
151
|
+
.array(PerRowWarningSchema)
|
|
152
|
+
.describe('Per-row notes — unknown variables, empty values, missing IDs.'),
|
|
153
|
+
})
|
|
154
|
+
.describe('Apply output — writes succeeded, post-state attached.');
|
|
155
|
+
const OutputSchema = z.object({
|
|
156
|
+
alias: z.string().describe('Alias of the registered BrAPI connection the call used.'),
|
|
157
|
+
result: z
|
|
158
|
+
.discriminatedUnion('mode', [PreviewBranchSchema, ApplyBranchSchema])
|
|
159
|
+
.describe('Mode-specific result — discriminated by `mode`.'),
|
|
160
|
+
});
|
|
161
|
+
const SUBMIT_ERRORS = [
|
|
162
|
+
{
|
|
163
|
+
reason: 'observations_unsupported',
|
|
164
|
+
code: JsonRpcErrorCode.ValidationError,
|
|
165
|
+
when: 'BrAPI server does not advertise /observations',
|
|
166
|
+
recovery: 'Run brapi_server_info to inspect the advertised endpoints, or call brapi_connect with a different alias for a server that exposes /observations.',
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
reason: 'study_not_found',
|
|
170
|
+
code: JsonRpcErrorCode.NotFound,
|
|
171
|
+
when: 'Upstream returned no study record for the requested studyDbId',
|
|
172
|
+
recovery: 'Verify the studyDbId on the target server, or run brapi_find_studies to discover valid IDs before retrying.',
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
reason: 'post_unsupported',
|
|
176
|
+
code: JsonRpcErrorCode.ValidationError,
|
|
177
|
+
when: 'Server does not advertise POST on /observations but new rows were submitted',
|
|
178
|
+
recovery: 'Remove the rows that lack observationDbId (those are the new rows) before retrying, or connect to a different server that supports POST on /observations.',
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
reason: 'put_unsupported',
|
|
182
|
+
code: JsonRpcErrorCode.ValidationError,
|
|
183
|
+
when: 'Server does not advertise PUT on /observations but update rows were submitted',
|
|
184
|
+
recovery: 'Connect to a different server that supports PUT on /observations — dropping observationDbId would route as POST and create duplicates instead of updating the existing rows.',
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
reason: 'elicit_unavailable',
|
|
188
|
+
code: JsonRpcErrorCode.Forbidden,
|
|
189
|
+
when: 'Apply mode invoked but client does not expose ctx.elicit and force was false',
|
|
190
|
+
recovery: 'Set force=true only with explicit user authorization, or use a client that supports elicitation.',
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
reason: 'user_declined',
|
|
194
|
+
code: JsonRpcErrorCode.Forbidden,
|
|
195
|
+
when: 'User declined the elicitation prompt for the apply write',
|
|
196
|
+
recovery: 'Re-run the tool when the user is ready to confirm the write.',
|
|
197
|
+
},
|
|
198
|
+
];
|
|
199
|
+
export const brapiSubmitObservations = tool('brapi_submit_observations', {
|
|
200
|
+
description: 'Submit observations for a study. Default mode `preview` validates rows against the study variables and returns a routing breakdown without writing. Mode `apply` elicits confirmation when supported, then creates new rows or updates existing ones based on observationDbId presence. Additive only — no observation is destroyed.',
|
|
201
|
+
annotations: {
|
|
202
|
+
readOnlyHint: false,
|
|
203
|
+
destructiveHint: false,
|
|
204
|
+
idempotentHint: true,
|
|
205
|
+
openWorldHint: true,
|
|
206
|
+
},
|
|
207
|
+
errors: SUBMIT_ERRORS,
|
|
208
|
+
input: z.object({
|
|
209
|
+
alias: AliasInput,
|
|
210
|
+
studyDbId: z.string().min(1).describe('Study the observations are submitted against.'),
|
|
211
|
+
observations: z
|
|
212
|
+
.array(ObservationRowSchema)
|
|
213
|
+
.min(1)
|
|
214
|
+
.max(5_000)
|
|
215
|
+
.describe('1 – 5000 observation rows. Mixed POST + PUT routing is supported.'),
|
|
216
|
+
mode: z
|
|
217
|
+
.enum(['preview', 'apply'])
|
|
218
|
+
.default('preview')
|
|
219
|
+
.describe('`preview` (default) validates only; `apply` writes after eliciting confirmation when supported.'),
|
|
220
|
+
force: z
|
|
221
|
+
.boolean()
|
|
222
|
+
.default(false)
|
|
223
|
+
.describe('Bypass elicitation in apply mode. Use only when the client lacks ctx.elicit support; the agent must have explicit user authorization to apply.'),
|
|
224
|
+
}),
|
|
225
|
+
output: OutputSchema,
|
|
226
|
+
auth: ['brapi:write:observations'],
|
|
227
|
+
async handler(input, ctx) {
|
|
228
|
+
const registry = getServerRegistry();
|
|
229
|
+
const capabilities = getCapabilityRegistry();
|
|
230
|
+
const client = getBrapiClient();
|
|
231
|
+
const connection = await registry.get(ctx, input.alias ?? DEFAULT_ALIAS);
|
|
232
|
+
const capabilityLookup = {};
|
|
233
|
+
if (connection.resolvedAuth)
|
|
234
|
+
capabilityLookup.auth = connection.resolvedAuth;
|
|
235
|
+
const profile = await capabilities.profile(connection.baseUrl, ctx, capabilityLookup);
|
|
236
|
+
const obsDescriptor = profile.supported.observations;
|
|
237
|
+
const supportsPost = obsDescriptor?.methods?.includes('POST') ?? false;
|
|
238
|
+
const supportsPut = obsDescriptor?.methods?.includes('PUT') ?? false;
|
|
239
|
+
if (!obsDescriptor) {
|
|
240
|
+
throw ctx.fail('observations_unsupported', `BrAPI server at ${connection.baseUrl} does not advertise '/observations' in /calls. Cannot submit observations.`, { baseUrl: connection.baseUrl, ...ctx.recoveryFor('observations_unsupported') });
|
|
241
|
+
}
|
|
242
|
+
const studyLookup = await fetchStudyExistence(input.studyDbId, connection, client, ctx);
|
|
243
|
+
if (!studyLookup.exists) {
|
|
244
|
+
throw ctx.fail('study_not_found', `Study '${input.studyDbId}' not found on ${connection.baseUrl}.`, {
|
|
245
|
+
studyDbId: input.studyDbId,
|
|
246
|
+
baseUrl: connection.baseUrl,
|
|
247
|
+
...ctx.recoveryFor('study_not_found'),
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
const studyName = studyLookup.studyName;
|
|
251
|
+
const knownVariables = await fetchStudyVariables(input.studyDbId, connection, client, ctx);
|
|
252
|
+
const decisions = [];
|
|
253
|
+
const perRowWarnings = [];
|
|
254
|
+
let valid = 0;
|
|
255
|
+
let invalid = 0;
|
|
256
|
+
let postCount = 0;
|
|
257
|
+
let putCount = 0;
|
|
258
|
+
for (const [i, row] of input.observations.entries()) {
|
|
259
|
+
const rowWarnings = [];
|
|
260
|
+
let structurallyValid = true;
|
|
261
|
+
if (!row.observationUnitDbId) {
|
|
262
|
+
rowWarnings.push('observationUnitDbId is required.');
|
|
263
|
+
structurallyValid = false;
|
|
264
|
+
}
|
|
265
|
+
if (!row.observationVariableDbId) {
|
|
266
|
+
rowWarnings.push('observationVariableDbId is required.');
|
|
267
|
+
structurallyValid = false;
|
|
268
|
+
}
|
|
269
|
+
if (row.value === '') {
|
|
270
|
+
rowWarnings.push('value is empty — submitted as an empty string.');
|
|
271
|
+
}
|
|
272
|
+
if (row.observationVariableDbId &&
|
|
273
|
+
knownVariables.size > 0 &&
|
|
274
|
+
!knownVariables.has(row.observationVariableDbId)) {
|
|
275
|
+
rowWarnings.push(`observationVariableDbId '${row.observationVariableDbId}' is not exposed by study '${input.studyDbId}'. The server may reject the row.`);
|
|
276
|
+
}
|
|
277
|
+
const decision = {
|
|
278
|
+
rowIndex: i,
|
|
279
|
+
observationDbId: row.observationDbId,
|
|
280
|
+
warnings: rowWarnings,
|
|
281
|
+
};
|
|
282
|
+
decisions.push(decision);
|
|
283
|
+
if (structurallyValid) {
|
|
284
|
+
valid++;
|
|
285
|
+
if (row.observationDbId)
|
|
286
|
+
putCount++;
|
|
287
|
+
else
|
|
288
|
+
postCount++;
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
invalid++;
|
|
292
|
+
}
|
|
293
|
+
for (const warning of rowWarnings) {
|
|
294
|
+
const entry = { rowIndex: i, warning };
|
|
295
|
+
if (row.observationVariableDbId)
|
|
296
|
+
entry.observationVariableDbId = row.observationVariableDbId;
|
|
297
|
+
if (row.observationUnitDbId)
|
|
298
|
+
entry.observationUnitDbId = row.observationUnitDbId;
|
|
299
|
+
perRowWarnings.push(entry);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (input.mode === 'preview') {
|
|
303
|
+
const branch = {
|
|
304
|
+
mode: 'preview',
|
|
305
|
+
studyDbId: input.studyDbId,
|
|
306
|
+
valid,
|
|
307
|
+
invalid,
|
|
308
|
+
routing: { postCount, putCount },
|
|
309
|
+
perRowWarnings,
|
|
310
|
+
knownVariableCount: knownVariables.size,
|
|
311
|
+
};
|
|
312
|
+
if (studyName)
|
|
313
|
+
branch.studyName = studyName;
|
|
314
|
+
return { alias: connection.alias, result: branch };
|
|
315
|
+
}
|
|
316
|
+
if (postCount > 0 && !supportsPost) {
|
|
317
|
+
throw ctx.fail('post_unsupported', `Server does not advertise POST on /observations. ${postCount} new row(s) cannot be created.`, { baseUrl: connection.baseUrl, postCount, ...ctx.recoveryFor('post_unsupported') });
|
|
318
|
+
}
|
|
319
|
+
if (putCount > 0 && !supportsPut) {
|
|
320
|
+
throw ctx.fail('put_unsupported', `Server does not advertise PUT on /observations. ${putCount} update row(s) cannot be applied.`, { baseUrl: connection.baseUrl, putCount, ...ctx.recoveryFor('put_unsupported') });
|
|
321
|
+
}
|
|
322
|
+
await confirmApply(ctx, {
|
|
323
|
+
studyDbId: input.studyDbId,
|
|
324
|
+
studyName,
|
|
325
|
+
valid,
|
|
326
|
+
invalid,
|
|
327
|
+
postCount,
|
|
328
|
+
putCount,
|
|
329
|
+
force: input.force,
|
|
330
|
+
});
|
|
331
|
+
const validRows = decisions.flatMap((d) => {
|
|
332
|
+
if (d.warnings.some(isStructural))
|
|
333
|
+
return [];
|
|
334
|
+
const row = input.observations[d.rowIndex];
|
|
335
|
+
return row ? [row] : [];
|
|
336
|
+
});
|
|
337
|
+
const postRows = validRows.filter((r) => !r.observationDbId);
|
|
338
|
+
const putRows = validRows.filter((r) => r.observationDbId);
|
|
339
|
+
const [postedEnv, updatedEnv] = await Promise.all([
|
|
340
|
+
postRows.length > 0
|
|
341
|
+
? client.post(connection.baseUrl, '/observations', postRows, ctx, buildRequestOptions(connection))
|
|
342
|
+
: Promise.resolve(undefined),
|
|
343
|
+
putRows.length > 0
|
|
344
|
+
? client.put(connection.baseUrl, '/observations', buildPutBody(putRows), ctx, buildRequestOptions(connection))
|
|
345
|
+
: Promise.resolve(undefined),
|
|
346
|
+
]);
|
|
347
|
+
const posted = postedEnv ? extractObservationRows(postedEnv.result) : [];
|
|
348
|
+
const updated = updatedEnv
|
|
349
|
+
? extractObservationRows(updatedEnv.result).filter((r) => typeof r.observationDbId === 'string')
|
|
350
|
+
: [];
|
|
351
|
+
const studyObservationCount = await fetchStudyObservationCount(input.studyDbId, connection, client, ctx);
|
|
352
|
+
const latestTimestamp = pickLatestTimestamp(input.observations);
|
|
353
|
+
const branch = {
|
|
354
|
+
mode: 'apply',
|
|
355
|
+
studyDbId: input.studyDbId,
|
|
356
|
+
posted,
|
|
357
|
+
updated,
|
|
358
|
+
perRowWarnings,
|
|
359
|
+
};
|
|
360
|
+
if (studyName)
|
|
361
|
+
branch.studyName = studyName;
|
|
362
|
+
if (studyObservationCount !== undefined)
|
|
363
|
+
branch.studyObservationCount = studyObservationCount;
|
|
364
|
+
if (latestTimestamp)
|
|
365
|
+
branch.latestObservationTimestamp = latestTimestamp;
|
|
366
|
+
return { alias: connection.alias, result: branch };
|
|
367
|
+
},
|
|
368
|
+
format: (output) => {
|
|
369
|
+
const lines = [];
|
|
370
|
+
if (output.result.mode === 'preview') {
|
|
371
|
+
const r = output.result;
|
|
372
|
+
lines.push(`# Preview · study \`${r.studyDbId}\`${r.studyName ? ` (${r.studyName})` : ''} — \`${output.alias}\``);
|
|
373
|
+
lines.push('');
|
|
374
|
+
lines.push(`- valid: ${r.valid}`);
|
|
375
|
+
lines.push(`- invalid: ${r.invalid}`);
|
|
376
|
+
lines.push(`- routing: POST ${r.routing.postCount} · PUT ${r.routing.putCount}`);
|
|
377
|
+
lines.push(`- knownVariableCount: ${r.knownVariableCount}`);
|
|
378
|
+
lines.push('- mode: preview · no writes performed');
|
|
379
|
+
if (r.perRowWarnings.length > 0) {
|
|
380
|
+
lines.push('');
|
|
381
|
+
lines.push('## Per-row warnings');
|
|
382
|
+
for (const w of r.perRowWarnings) {
|
|
383
|
+
const id = w.observationVariableDbId ? ` var=\`${w.observationVariableDbId}\`` : '';
|
|
384
|
+
const unit = w.observationUnitDbId ? ` unit=\`${w.observationUnitDbId}\`` : '';
|
|
385
|
+
lines.push(`- row ${w.rowIndex}:${id}${unit} — ${w.warning}`);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
const r = output.result;
|
|
391
|
+
lines.push(`# Apply · study \`${r.studyDbId}\`${r.studyName ? ` (${r.studyName})` : ''} — \`${output.alias}\``);
|
|
392
|
+
lines.push('');
|
|
393
|
+
lines.push(`- posted: ${r.posted.length}`);
|
|
394
|
+
lines.push(`- updated: ${r.updated.length}`);
|
|
395
|
+
lines.push(`- studyObservationCount: ${r.studyObservationCount ?? '—'}`);
|
|
396
|
+
lines.push(`- latestObservationTimestamp: ${r.latestObservationTimestamp ?? '—'}`);
|
|
397
|
+
lines.push('- mode: apply');
|
|
398
|
+
if (r.posted.length > 0) {
|
|
399
|
+
lines.push('');
|
|
400
|
+
lines.push('## Posted (new observations)');
|
|
401
|
+
for (const p of r.posted) {
|
|
402
|
+
const parts = [];
|
|
403
|
+
if (p.observationDbId)
|
|
404
|
+
parts.push(`id=\`${p.observationDbId}\``);
|
|
405
|
+
if (p.observationVariableDbId)
|
|
406
|
+
parts.push(`var=${p.observationVariableDbId}`);
|
|
407
|
+
if (p.observationUnitDbId)
|
|
408
|
+
parts.push(`unit=${p.observationUnitDbId}`);
|
|
409
|
+
if (p.value !== undefined)
|
|
410
|
+
parts.push(`value=${p.value}`);
|
|
411
|
+
lines.push(`- ${parts.join(' · ') || '_(server returned no fields)_'}`);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
if (r.updated.length > 0) {
|
|
415
|
+
lines.push('');
|
|
416
|
+
lines.push('## Updated');
|
|
417
|
+
for (const u of r.updated) {
|
|
418
|
+
const parts = [`id=\`${u.observationDbId}\``];
|
|
419
|
+
if (u.observationVariableDbId)
|
|
420
|
+
parts.push(`var=${u.observationVariableDbId}`);
|
|
421
|
+
if (u.observationUnitDbId)
|
|
422
|
+
parts.push(`unit=${u.observationUnitDbId}`);
|
|
423
|
+
if (u.value !== undefined)
|
|
424
|
+
parts.push(`value=${u.value}`);
|
|
425
|
+
lines.push(`- ${parts.join(' · ')}`);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
if (r.perRowWarnings.length > 0) {
|
|
429
|
+
lines.push('');
|
|
430
|
+
lines.push('## Per-row warnings');
|
|
431
|
+
for (const w of r.perRowWarnings) {
|
|
432
|
+
const id = w.observationVariableDbId ? ` var=\`${w.observationVariableDbId}\`` : '';
|
|
433
|
+
const unit = w.observationUnitDbId ? ` unit=\`${w.observationUnitDbId}\`` : '';
|
|
434
|
+
lines.push(`- row ${w.rowIndex}:${id}${unit} — ${w.warning}`);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
439
|
+
},
|
|
440
|
+
});
|
|
441
|
+
function isStructural(warning) {
|
|
442
|
+
return warning.endsWith('is required.');
|
|
443
|
+
}
|
|
444
|
+
async function confirmApply(ctx, input) {
|
|
445
|
+
if (input.force)
|
|
446
|
+
return;
|
|
447
|
+
if (!ctx.elicit) {
|
|
448
|
+
throw ctx.fail('elicit_unavailable', 'Apply mode requires user confirmation. The MCP client does not expose elicitation, so set `force: true` to bypass — but only with explicit user authorization for this write.', {
|
|
449
|
+
studyDbId: input.studyDbId,
|
|
450
|
+
valid: input.valid,
|
|
451
|
+
invalid: input.invalid,
|
|
452
|
+
...ctx.recoveryFor('elicit_unavailable'),
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
const message = [
|
|
456
|
+
`Apply ${input.valid} observation row(s) to study \`${input.studyDbId}\`${input.studyName ? ` (${input.studyName})` : ''}?`,
|
|
457
|
+
`POST ${input.postCount} new · PUT ${input.putCount} update · ${input.invalid} skipped (structural errors).`,
|
|
458
|
+
].join('\n');
|
|
459
|
+
const result = await ctx.elicit(message, z.object({
|
|
460
|
+
confirm: z
|
|
461
|
+
.boolean()
|
|
462
|
+
.describe('Set to true to commit the writes; false to abort with no side effects.'),
|
|
463
|
+
}));
|
|
464
|
+
const confirmed = typeof result.data === 'object' &&
|
|
465
|
+
result.data !== null &&
|
|
466
|
+
result.data.confirm === true;
|
|
467
|
+
if (result.action !== 'accept' || !confirmed) {
|
|
468
|
+
throw ctx.fail('user_declined', 'User declined to apply observation writes.', {
|
|
469
|
+
studyDbId: input.studyDbId,
|
|
470
|
+
action: result.action,
|
|
471
|
+
...ctx.recoveryFor('user_declined'),
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
async function fetchStudyVariables(studyDbId, connection, client, ctx) {
|
|
476
|
+
try {
|
|
477
|
+
const env = await client.get(connection.baseUrl, '/variables', ctx, buildRequestOptions(connection, { studyDbId, pageSize: 1000 }));
|
|
478
|
+
const known = new Set();
|
|
479
|
+
const rows = extractRows(env.result);
|
|
480
|
+
for (const row of rows) {
|
|
481
|
+
const id = row.observationVariableDbId;
|
|
482
|
+
if (typeof id === 'string' && id.length > 0)
|
|
483
|
+
known.add(id);
|
|
484
|
+
}
|
|
485
|
+
return known;
|
|
486
|
+
}
|
|
487
|
+
catch (err) {
|
|
488
|
+
ctx.log.debug('Could not load study variables for validation', {
|
|
489
|
+
studyDbId,
|
|
490
|
+
error: err instanceof Error ? err.message : String(err),
|
|
491
|
+
});
|
|
492
|
+
return new Set();
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
async function fetchStudyExistence(studyDbId, connection, client, ctx) {
|
|
496
|
+
try {
|
|
497
|
+
const env = await client.get(connection.baseUrl, `/studies/${encodeURIComponent(studyDbId)}`, ctx, buildRequestOptions(connection));
|
|
498
|
+
const study = env.result;
|
|
499
|
+
if (!study || typeof study !== 'object' || !study.studyDbId) {
|
|
500
|
+
return { exists: false };
|
|
501
|
+
}
|
|
502
|
+
const name = study.studyName;
|
|
503
|
+
return typeof name === 'string' && name.length > 0
|
|
504
|
+
? { exists: true, studyName: name }
|
|
505
|
+
: { exists: true };
|
|
506
|
+
}
|
|
507
|
+
catch (err) {
|
|
508
|
+
if (isUpstreamNotFound(err))
|
|
509
|
+
return { exists: false };
|
|
510
|
+
// Transient errors (timeouts, 5xx) — propagate so the user sees the real cause.
|
|
511
|
+
throw err;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
async function fetchStudyObservationCount(studyDbId, connection, client, ctx) {
|
|
515
|
+
try {
|
|
516
|
+
const env = await client.get(connection.baseUrl, '/observations', ctx, buildRequestOptions(connection, { studyDbIds: [studyDbId], pageSize: 1 }));
|
|
517
|
+
const total = env.metadata?.pagination?.totalCount;
|
|
518
|
+
return typeof total === 'number' ? total : undefined;
|
|
519
|
+
}
|
|
520
|
+
catch {
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
function buildPutBody(rows) {
|
|
525
|
+
const map = {};
|
|
526
|
+
for (const row of rows) {
|
|
527
|
+
if (!row.observationDbId)
|
|
528
|
+
continue;
|
|
529
|
+
map[row.observationDbId] = row;
|
|
530
|
+
}
|
|
531
|
+
return map;
|
|
532
|
+
}
|
|
533
|
+
function extractObservationRows(result) {
|
|
534
|
+
if (!result)
|
|
535
|
+
return [];
|
|
536
|
+
let rows;
|
|
537
|
+
if (Array.isArray(result)) {
|
|
538
|
+
rows = result;
|
|
539
|
+
}
|
|
540
|
+
else if (typeof result === 'object' && Array.isArray(result.data)) {
|
|
541
|
+
rows = result.data;
|
|
542
|
+
}
|
|
543
|
+
else {
|
|
544
|
+
return [];
|
|
545
|
+
}
|
|
546
|
+
const out = [];
|
|
547
|
+
for (const entry of rows) {
|
|
548
|
+
if (typeof entry !== 'object' || entry === null)
|
|
549
|
+
continue;
|
|
550
|
+
const record = entry;
|
|
551
|
+
const item = {};
|
|
552
|
+
if (typeof record.observationDbId === 'string')
|
|
553
|
+
item.observationDbId = record.observationDbId;
|
|
554
|
+
if (typeof record.observationUnitDbId === 'string')
|
|
555
|
+
item.observationUnitDbId = record.observationUnitDbId;
|
|
556
|
+
if (typeof record.observationVariableDbId === 'string')
|
|
557
|
+
item.observationVariableDbId = record.observationVariableDbId;
|
|
558
|
+
if (typeof record.value === 'string')
|
|
559
|
+
item.value = record.value;
|
|
560
|
+
out.push(item);
|
|
561
|
+
}
|
|
562
|
+
return out;
|
|
563
|
+
}
|
|
564
|
+
function pickLatestTimestamp(rows) {
|
|
565
|
+
let best;
|
|
566
|
+
for (const row of rows) {
|
|
567
|
+
if (typeof row.observationTimeStamp !== 'string')
|
|
568
|
+
continue;
|
|
569
|
+
if (!best || row.observationTimeStamp > best)
|
|
570
|
+
best = row.observationTimeStamp;
|
|
571
|
+
}
|
|
572
|
+
return best;
|
|
573
|
+
}
|
|
574
|
+
//# sourceMappingURL=brapi-submit-observations.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brapi-submit-observations.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/brapi-submit-observations.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `brapi_walk_pedigree` — walk germplasm ancestry or
|
|
3
|
+
* descendancy as a DAG. BrAPI only exposes direct parents / direct progeny
|
|
4
|
+
* per call, so we BFS outward from each root up to `maxDepth`, deduplicate
|
|
5
|
+
* nodes (cultivars may appear on multiple paths), and break cycles.
|
|
6
|
+
* Response includes traversal stats so the agent can see how the walk
|
|
7
|
+
* terminated without re-running the tool.
|
|
8
|
+
*
|
|
9
|
+
* @module mcp-server/tools/definitions/brapi-walk-pedigree.tool
|
|
10
|
+
*/
|
|
11
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
12
|
+
export declare const brapiWalkPedigree: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
13
|
+
germplasmDbIds: z.ZodArray<z.ZodString>;
|
|
14
|
+
direction: z.ZodDefault<z.ZodEnum<{
|
|
15
|
+
ancestors: "ancestors";
|
|
16
|
+
descendants: "descendants";
|
|
17
|
+
both: "both";
|
|
18
|
+
}>>;
|
|
19
|
+
maxDepth: z.ZodDefault<z.ZodNumber>;
|
|
20
|
+
alias: z.ZodOptional<z.ZodString>;
|
|
21
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
22
|
+
alias: z.ZodString;
|
|
23
|
+
direction: z.ZodEnum<{
|
|
24
|
+
ancestors: "ancestors";
|
|
25
|
+
descendants: "descendants";
|
|
26
|
+
both: "both";
|
|
27
|
+
}>;
|
|
28
|
+
maxDepth: z.ZodNumber;
|
|
29
|
+
nodes: z.ZodArray<z.ZodObject<{
|
|
30
|
+
germplasmDbId: z.ZodString;
|
|
31
|
+
germplasmName: z.ZodOptional<z.ZodString>;
|
|
32
|
+
depth: z.ZodNumber;
|
|
33
|
+
isRoot: z.ZodBoolean;
|
|
34
|
+
}, z.core.$strip>>;
|
|
35
|
+
edges: z.ZodArray<z.ZodObject<{
|
|
36
|
+
from: z.ZodString;
|
|
37
|
+
to: z.ZodString;
|
|
38
|
+
relationship: z.ZodEnum<{
|
|
39
|
+
parent: "parent";
|
|
40
|
+
child: "child";
|
|
41
|
+
}>;
|
|
42
|
+
parentType: z.ZodOptional<z.ZodString>;
|
|
43
|
+
}, z.core.$strip>>;
|
|
44
|
+
depthReached: z.ZodNumber;
|
|
45
|
+
rootCount: z.ZodNumber;
|
|
46
|
+
leafCount: z.ZodNumber;
|
|
47
|
+
cycleCount: z.ZodNumber;
|
|
48
|
+
deadEndCount: z.ZodNumber;
|
|
49
|
+
truncated: z.ZodBoolean;
|
|
50
|
+
warnings: z.ZodArray<z.ZodString>;
|
|
51
|
+
}, z.core.$strip>, undefined>;
|
|
52
|
+
//# sourceMappingURL=brapi-walk-pedigree.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brapi-walk-pedigree.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/brapi-walk-pedigree.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAsB,CAAC,EAAE,MAAM,wBAAwB,CAAC;AA0F/D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BA0N5B,CAAC"}
|