@cyanheads/brapi-mcp-server 0.6.4 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +11 -4
- package/README.md +7 -3
- package/changelog/0.7.x/0.7.0.md +23 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/resources/definitions/brapi-variable.resource.d.ts +30 -0
- package/dist/mcp-server/resources/definitions/brapi-variable.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-variable.resource.js +78 -0
- package/dist/mcp-server/resources/definitions/brapi-variable.resource.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-build-phenotype-matrix.tool.d.ts +81 -0
- package/dist/mcp-server/tools/definitions/brapi-build-phenotype-matrix.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-build-phenotype-matrix.tool.js +366 -0
- package/dist/mcp-server/tools/definitions/brapi-build-phenotype-matrix.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-export-genotype-matrix.tool.d.ts +88 -0
- package/dist/mcp-server/tools/definitions/brapi-export-genotype-matrix.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-export-genotype-matrix.tool.js +494 -0
- package/dist/mcp-server/tools/definitions/brapi-export-genotype-matrix.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-genotype-calls.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/brapi-find-genotype-calls.tool.js +17 -93
- package/dist/mcp-server/tools/definitions/brapi-find-genotype-calls.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/brapi-germplasm-performance.tool.d.ts +60 -0
- package/dist/mcp-server/tools/definitions/brapi-germplasm-performance.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-germplasm-performance.tool.js +416 -0
- package/dist/mcp-server/tools/definitions/brapi-germplasm-performance.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/index.d.ts +148 -0
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/index.js +6 -0
- package/dist/mcp-server/tools/definitions/index.js.map +1 -1
- package/dist/mcp-server/tools/shared/canvas-columns.d.ts +32 -0
- package/dist/mcp-server/tools/shared/canvas-columns.d.ts.map +1 -0
- package/dist/mcp-server/tools/shared/canvas-columns.js +98 -0
- package/dist/mcp-server/tools/shared/canvas-columns.js.map +1 -0
- package/dist/mcp-server/tools/shared/genotype-calls.d.ts +81 -0
- package/dist/mcp-server/tools/shared/genotype-calls.d.ts.map +1 -0
- package/dist/mcp-server/tools/shared/genotype-calls.js +172 -0
- package/dist/mcp-server/tools/shared/genotype-calls.js.map +1 -0
- package/dist/mcp-server/tools/shared/observations.d.ts +87 -0
- package/dist/mcp-server/tools/shared/observations.d.ts.map +1 -0
- package/dist/mcp-server/tools/shared/observations.js +285 -0
- package/dist/mcp-server/tools/shared/observations.js.map +1 -0
- package/manifest.json +1 -1
- package/package.json +3 -3
- package/server.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genotype-calls.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/shared/genotype-calls.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAgB,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,SAAS,GAAG,MAAM,CAAC;AAEzB,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC;KAC3B,MAAM,CAAC;IACN,WAAW,EAAE,CAAC;SACX,MAAM,EAAE;SACR,OAAO,EAAE;SACT,QAAQ,CAAC,sEAAsE,CAAC;IACnF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;IAC3E,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;IAC7E,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;IAClF,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;IAC3F,QAAQ,EAAE,CAAC;SACR,MAAM,CAAC;QACN,MAAM,EAAE,CAAC;aACN,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC;aACtD,OAAO,EAAE;aACT,QAAQ,CAAC,qEAAqE,CAAC;KACnF,CAAC;SACD,WAAW,EAAE;SACb,OAAO,EAAE;SACT,QAAQ,CACP,mFAAmF,CACpF;IACH,aAAa,EAAE,CAAC;SACb,MAAM,EAAE;SACR,OAAO,EAAE;SACT,QAAQ,CACP,uFAAuF,CACxF;IACH,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,OAAO,EAAE;SACT,QAAQ,CAAC,kEAAkE,CAAC;CAChF,CAAC;KACD,WAAW,EAAE;KACb,QAAQ,CAAC,wBAAwB,CAAC,CAAC;AA0BtC;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAOpC;IACC,MAAM,IAAI,GAA4B,EAAE,CAAC;IACzC,IAAI,KAAK,CAAC,cAAc;QAAE,IAAI,CAAC,eAAe,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACxE,IAAI,KAAK,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC;QAClC,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,IAAI,CAC/B,IAAI,GAAG,CAAC,CAAC,GAAG,CAAE,IAAI,CAAC,eAA4B,IAAI,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC,eAAe,CAAC,CAAC,CACnF,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,cAAc,EAAE,MAAM;QAAE,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC;IAC7E,IAAI,KAAK,CAAC,YAAY,EAAE,MAAM;QAAE,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IACvE,IAAI,KAAK,CAAC,YAAY,EAAE,MAAM;QAAE,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IACvE,IAAI,KAAK,CAAC,UAAU;QAAE,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;IACzD,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;IAC1B,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAwB;IACzD,MAAM,IAAI,GAAc,EAAE,CAAC;IAC3B,IAAI,cAAc,GAAmB,EAAE,CAAC;IACxC,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,MAAM,SAAS,GAAG,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC7C,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,UAAU,CACzC,KAAK,CAAC,UAAU,CAAC,OAAO,EACxB,OAAO,EACP,SAAS,EACT,KAAK,CAAC,GAAG,EACT,mBAAmB,CAAC,KAAK,CAAC,UAAU,CAAC,CACtC,CAAC;IAEF,IAAI,QAAiD,CAAC;IACtD,IAAI,iBAAqC,CAAC;IAC1C,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC1B,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAC5B,CAAC;SAAM,CAAC;QACN,iBAAiB,GAAG,KAAK,CAAC,iBAAiB,CAAC;QAC5C,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAC5C,KAAK,CAAC,UAAU,CAAC,OAAO,EACxB,OAAO,EACP,KAAK,CAAC,iBAAiB,EACvB,KAAK,CAAC,GAAG,EACT,mBAAmB,CAAC,KAAK,CAAC,UAAU,CAAC,CACtC,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE;QACjC,cAAc,GAAG,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,UAAU,CAAC;IAE7D,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;QACpD,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YAClC,SAAS,GAAG,IAAI,CAAC;YACjB,MAAM;QACR,CAAC;QACD,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO;YAAE,MAAM;QACpC,IAAI,YAAqD,CAAC;QAC1D,IAAI,iBAAiB,EAAE,CAAC;YACtB,YAAY,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAChD,KAAK,CAAC,UAAU,CAAC,OAAO,EACxB,OAAO,EACP,iBAAiB,EACjB,KAAK,CAAC,GAAG,EACT,mBAAmB,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CACrE,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,UAAU,CAC9C,KAAK,CAAC,UAAU,CAAC,OAAO,EACxB,OAAO,EACP,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EACvB,KAAK,CAAC,GAAG,EACT,mBAAmB,CAAC,KAAK,CAAC,UAAU,CAAC,CACtC,CAAC;YACF,IAAI,UAAU,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC/B,YAAY,GAAG,UAAU,CAAC,QAAQ,CAAC;YACrC,CAAC;iBAAM,CAAC;gBACN,YAAY,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAChD,KAAK,CAAC,UAAU,CAAC,OAAO,EACxB,OAAO,EACP,UAAU,CAAC,iBAAiB,EAC5B,KAAK,CAAC,GAAG,EACT,mBAAmB,CAAC,KAAK,CAAC,UAAU,CAAC,CACtC,CAAC;YACJ,CAAC;QACH,CAAC;QACD,WAAW,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE;YACrC,cAAc,GAAG,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC;QAC7B,SAAS,GAAG,IAAI,CAAC;QACjB,KAAK,CAAC,QAAQ,CAAC,IAAI,CACjB,2CAA2C,KAAK,CAAC,QAAQ,mGAAmG,CAC7J,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC;AAC7C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,QAAiD,EACjD,IAAe,EACf,iBAA8C;IAE9C,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC/B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO;IAClD,MAAM,MAAM,GAAG,MAAiC,CAAC;IACjD,MAAM,EAAE,GAAmB,EAAE,CAAC;IAC9B,IAAI,OAAO,MAAM,CAAC,iBAAiB,KAAK,SAAS;QAC/C,EAAE,CAAC,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAClD,IAAI,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ;QAAE,EAAE,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC;IACtF,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;QAAE,EAAE,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IAC1E,IAAI,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ;QAAE,EAAE,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IAChF,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAEtB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACzB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO;IACjC,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;QACzB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAChD,IAAI,CAAC,IAAI,CAAC,KAAgB,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,GAAY,EACZ,cAA8B,EAC9B,MAAgB;IAEhB,MAAM,OAAO,GAAG,cAAc,CAAC,aAAa,IAAI,GAAG,CAAC;IACpD,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC;IACpC,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,SAAS,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,WAAW,IAAI,GAAG,CAAC,CAAC;QAC7F,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IACD,IAAI,GAAG,CAAC,aAAa;QAAE,OAAO,GAAG,CAAC,aAAa,CAAC;IAChD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared observation-pull logic for the phenotype tools
|
|
3
|
+
* (`brapi_build_phenotype_matrix`, `brapi_germplasm_performance`). Owns the
|
|
4
|
+
* study-anchored observation collection strategy and the raw/normalized row
|
|
5
|
+
* shapes, so both tools pull observations identically without duplicating the
|
|
6
|
+
* server-dependent fallback chain.
|
|
7
|
+
*
|
|
8
|
+
* Observation pull strategy (server-dependent), per study:
|
|
9
|
+
* 1. Prefer `/observations?studyDbId=…` (BrAPI spec path).
|
|
10
|
+
* 2. Fall back to `/observationunits?studyDbId=…` with embedded
|
|
11
|
+
* `observations[]` arrays when `/observations` returns empty or the dialect
|
|
12
|
+
* drops the study filter — required for the BrAPI Community Test Server,
|
|
13
|
+
* where `/observations?studyDbId` is not honored.
|
|
14
|
+
* 3. When units carry `germplasmDbId`s but no embedded observations, pull
|
|
15
|
+
* `/observations?germplasmDbId=…` per germplasm and filter back to the
|
|
16
|
+
* study — stays study-anchored without an unbounded scan.
|
|
17
|
+
*
|
|
18
|
+
* `pullStudyObservations` returns `null` only when no usable observation path
|
|
19
|
+
* exists for the study (caller throws its typed `no_observation_path` error);
|
|
20
|
+
* an empty array means the paths exist but yielded no rows.
|
|
21
|
+
*
|
|
22
|
+
* @module mcp-server/tools/shared/observations
|
|
23
|
+
*/
|
|
24
|
+
import type { Context } from '@cyanheads/mcp-ts-core';
|
|
25
|
+
import type { ServerConfig } from '../../../config/server-config.js';
|
|
26
|
+
import { type BrapiClient } from '../../../services/brapi-client/index.js';
|
|
27
|
+
import type { BrapiDialect } from '../../../services/brapi-dialect/index.js';
|
|
28
|
+
import type { CallDescriptor } from '../../../services/capability-registry/types.js';
|
|
29
|
+
import type { RegisteredServer } from '../../../services/server-registry/index.js';
|
|
30
|
+
/** Raw BrAPI `/observations` row shape (passthrough). */
|
|
31
|
+
export interface RawObservationRow {
|
|
32
|
+
germplasmDbId?: string | null;
|
|
33
|
+
germplasmName?: string | null;
|
|
34
|
+
observationDbId?: string | null;
|
|
35
|
+
observationVariableDbId?: string | null;
|
|
36
|
+
observationVariableName?: string | null;
|
|
37
|
+
season?: unknown;
|
|
38
|
+
seasonDbId?: string | null;
|
|
39
|
+
studyDbId?: string | null;
|
|
40
|
+
value?: string | null;
|
|
41
|
+
[key: string]: unknown;
|
|
42
|
+
}
|
|
43
|
+
/** Normalized observation — required fields are non-empty strings after extraction. */
|
|
44
|
+
export interface NormObs {
|
|
45
|
+
germplasmDbId: string;
|
|
46
|
+
germplasmName: string;
|
|
47
|
+
observationVariableDbId: string;
|
|
48
|
+
observationVariableName: string;
|
|
49
|
+
/** Human season label (`"spring 2013"` / seasonDbId), when the row carries one. */
|
|
50
|
+
season?: string;
|
|
51
|
+
studyDbId: string;
|
|
52
|
+
value: string;
|
|
53
|
+
}
|
|
54
|
+
/** Filters that scope an observation pull beyond the study anchor. */
|
|
55
|
+
export interface ObservationPullFilters {
|
|
56
|
+
extraFilters?: Record<string, unknown> | undefined;
|
|
57
|
+
germplasm?: string[] | undefined;
|
|
58
|
+
variables?: string[] | undefined;
|
|
59
|
+
}
|
|
60
|
+
export interface PullStudyObservationsArgs {
|
|
61
|
+
client: BrapiClient;
|
|
62
|
+
config: ServerConfig;
|
|
63
|
+
connection: RegisteredServer;
|
|
64
|
+
ctx: Context;
|
|
65
|
+
dialect: BrapiDialect;
|
|
66
|
+
input: ObservationPullFilters;
|
|
67
|
+
loadLimit: number;
|
|
68
|
+
profile: Record<string, CallDescriptor>;
|
|
69
|
+
studyDbId: string;
|
|
70
|
+
warnings: string[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Collect observations for a single study, trying `/observations` first and
|
|
74
|
+
* falling back to `/observationunits` (embedded, then germplasm-anchored).
|
|
75
|
+
* Returns `null` when no usable path exists; `[]` when paths exist but are
|
|
76
|
+
* empty.
|
|
77
|
+
*/
|
|
78
|
+
export declare function pullStudyObservations(args: PullStudyObservationsArgs): Promise<NormObs[] | null>;
|
|
79
|
+
/** Normalise a raw /observations row; drops rows missing any required field. */
|
|
80
|
+
export declare function normalizeObsRow(row: RawObservationRow): NormObs | null;
|
|
81
|
+
/**
|
|
82
|
+
* Derive a human season label from a BrAPI observation row. Servers carry
|
|
83
|
+
* season either as a nested object (`{ seasonName, year, seasonDbId }`) or a
|
|
84
|
+
* flat `seasonDbId` string. Returns undefined when neither is present.
|
|
85
|
+
*/
|
|
86
|
+
export declare function seasonLabel(row: RawObservationRow): string | undefined;
|
|
87
|
+
//# sourceMappingURL=observations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observations.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/shared/observations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,KAAK,WAAW,EAAuB,MAAM,kCAAkC,CAAC;AACzF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAQ5E,yDAAyD;AACzD,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,uFAAuF;AACvF,MAAM,WAAW,OAAO;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC;IAChC,uBAAuB,EAAE,MAAM,CAAC;IAChC,mFAAmF;IACnF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,sEAAsE;AACtE,MAAM,WAAW,sBAAsB;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACnD,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,sBAAsB,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAyH3B;AAyKD,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,GAAG,IAAI,CAuBtE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,iBAAiB,GAAG,MAAM,GAAG,SAAS,CAetE"}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared observation-pull logic for the phenotype tools
|
|
3
|
+
* (`brapi_build_phenotype_matrix`, `brapi_germplasm_performance`). Owns the
|
|
4
|
+
* study-anchored observation collection strategy and the raw/normalized row
|
|
5
|
+
* shapes, so both tools pull observations identically without duplicating the
|
|
6
|
+
* server-dependent fallback chain.
|
|
7
|
+
*
|
|
8
|
+
* Observation pull strategy (server-dependent), per study:
|
|
9
|
+
* 1. Prefer `/observations?studyDbId=…` (BrAPI spec path).
|
|
10
|
+
* 2. Fall back to `/observationunits?studyDbId=…` with embedded
|
|
11
|
+
* `observations[]` arrays when `/observations` returns empty or the dialect
|
|
12
|
+
* drops the study filter — required for the BrAPI Community Test Server,
|
|
13
|
+
* where `/observations?studyDbId` is not honored.
|
|
14
|
+
* 3. When units carry `germplasmDbId`s but no embedded observations, pull
|
|
15
|
+
* `/observations?germplasmDbId=…` per germplasm and filter back to the
|
|
16
|
+
* study — stays study-anchored without an unbounded scan.
|
|
17
|
+
*
|
|
18
|
+
* `pullStudyObservations` returns `null` only when no usable observation path
|
|
19
|
+
* exists for the study (caller throws its typed `no_observation_path` error);
|
|
20
|
+
* an empty array means the paths exist but yielded no rows.
|
|
21
|
+
*
|
|
22
|
+
* @module mcp-server/tools/shared/observations
|
|
23
|
+
*/
|
|
24
|
+
import { isDialectAllDropped } from '../../../services/brapi-client/index.js';
|
|
25
|
+
import { companionRequestOptions, extractRows, mergeFilters, } from './find-helpers.js';
|
|
26
|
+
/**
|
|
27
|
+
* Collect observations for a single study, trying `/observations` first and
|
|
28
|
+
* falling back to `/observationunits` (embedded, then germplasm-anchored).
|
|
29
|
+
* Returns `null` when no usable path exists; `[]` when paths exist but are
|
|
30
|
+
* empty.
|
|
31
|
+
*/
|
|
32
|
+
export async function pullStudyObservations(args) {
|
|
33
|
+
const { studyDbId, input, client, connection, dialect, config, loadLimit, warnings, ctx } = args;
|
|
34
|
+
// Build named filters for observations endpoint
|
|
35
|
+
const namedFilters = {
|
|
36
|
+
studyDbIds: [studyDbId],
|
|
37
|
+
};
|
|
38
|
+
if (input.variables?.length)
|
|
39
|
+
namedFilters.observationVariableDbIds = input.variables;
|
|
40
|
+
if (input.germplasm?.length)
|
|
41
|
+
namedFilters.germplasmDbIds = input.germplasm;
|
|
42
|
+
const merged = mergeFilters(namedFilters, input.extraFilters, warnings);
|
|
43
|
+
// Apply dialect (plurals → singulars on SGN-family servers)
|
|
44
|
+
const adapted = dialect.adaptGetFilters('observations', merged);
|
|
45
|
+
warnings.push(...adapted.warnings);
|
|
46
|
+
// When the dialect drops ALL filters for /observations (known case: the
|
|
47
|
+
// brapi-test server doesn't honor studyDbId on /observations at all), skip
|
|
48
|
+
// the observations path entirely and go straight to the observationunits
|
|
49
|
+
// fallback rather than making an unscoped request.
|
|
50
|
+
const obsFiltersDropped = adapted.dropped.length > 0 && Object.keys(adapted.filters).length === 0;
|
|
51
|
+
const obsFilters = adapted.filters;
|
|
52
|
+
// ---- Path 1: /observations ----
|
|
53
|
+
const supportsObservations = supportsGet(args.profile, 'observations') && !obsFiltersDropped;
|
|
54
|
+
if (supportsObservations) {
|
|
55
|
+
const obs = await fetchObservationsPath(client, connection, dialect, config, obsFilters, loadLimit, ctx);
|
|
56
|
+
if (obs !== null && obs.length > 0) {
|
|
57
|
+
return obs;
|
|
58
|
+
}
|
|
59
|
+
if (obs !== null && obs.length === 0) {
|
|
60
|
+
// Server responded with empty for this study — note it and try fallback
|
|
61
|
+
warnings.push(`Study '${studyDbId}': /observations returned 0 rows — trying /observationunits fallback.`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else if (obsFiltersDropped) {
|
|
65
|
+
warnings.push(`Study '${studyDbId}': dialect '${dialect.id}' drops all study filters for /observations — using /observationunits fallback.`);
|
|
66
|
+
}
|
|
67
|
+
// ---- Path 2: /observationunits fallback ----
|
|
68
|
+
// Two sub-strategies:
|
|
69
|
+
// 2a. Units embed observations[] arrays — extract directly.
|
|
70
|
+
// 2b. Units carry germplasmDbIds but observations[] is null — pull
|
|
71
|
+
// /observations?germplasmDbId=X per germplasm found in the study.
|
|
72
|
+
const supportsObsUnits = supportsGet(args.profile, 'observationunits');
|
|
73
|
+
if (supportsObsUnits) {
|
|
74
|
+
const unitResult = await fetchObservationUnitsRaw(client, connection, dialect, config, studyDbId, loadLimit, ctx);
|
|
75
|
+
if (unitResult !== null) {
|
|
76
|
+
// 2a: check for embedded observations
|
|
77
|
+
const embeddedObs = extractEmbeddedObservations(unitResult, studyDbId);
|
|
78
|
+
if (embeddedObs.length > 0) {
|
|
79
|
+
warnings.push(`Study '${studyDbId}': Using /observationunits embedded observations[] fallback.`);
|
|
80
|
+
return embeddedObs;
|
|
81
|
+
}
|
|
82
|
+
// 2b: germplasm-anchored pull — units have germplasmDbIds, use them
|
|
83
|
+
let germplasmIds = [
|
|
84
|
+
...new Set(unitResult
|
|
85
|
+
.map((u) => u.germplasmDbId)
|
|
86
|
+
.filter((id) => typeof id === 'string' && id.length > 0)),
|
|
87
|
+
];
|
|
88
|
+
// When the caller scoped to specific germplasm, pull only those — avoids
|
|
89
|
+
// an O(all-germplasm-in-study) fan-out for single-germplasm callers (#9).
|
|
90
|
+
if (input.germplasm?.length) {
|
|
91
|
+
const want = new Set(input.germplasm);
|
|
92
|
+
germplasmIds = germplasmIds.filter((g) => want.has(g));
|
|
93
|
+
}
|
|
94
|
+
if (germplasmIds.length > 0) {
|
|
95
|
+
const germObs = await fetchObservationsByGermplasm(client, connection, dialect, config, germplasmIds, studyDbId, loadLimit, ctx);
|
|
96
|
+
if (germObs !== null && germObs.length > 0) {
|
|
97
|
+
warnings.push(`Study '${studyDbId}': Used /observationunits → /observations?germplasmDbId fallback because studyDbId filter is not honored on /observations.`);
|
|
98
|
+
return germObs;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Neither path yielded data. Distinguish "no path" from "empty".
|
|
104
|
+
if (!supportsObservations && !obsFiltersDropped && !supportsObsUnits) {
|
|
105
|
+
return null; // caller throws typed error
|
|
106
|
+
}
|
|
107
|
+
// Paths exist but all returned empty — treat as empty (not an error)
|
|
108
|
+
warnings.push(`Study '${studyDbId}': No observations found via /observations or /observationunits.`);
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
function supportsGet(profile, service) {
|
|
112
|
+
const descriptor = profile[service];
|
|
113
|
+
if (!descriptor)
|
|
114
|
+
return false;
|
|
115
|
+
if (!descriptor.methods || descriptor.methods.length === 0)
|
|
116
|
+
return true;
|
|
117
|
+
return descriptor.methods.includes('GET');
|
|
118
|
+
}
|
|
119
|
+
/** Fetch from /observations with study-anchored filters. Returns null on error. */
|
|
120
|
+
async function fetchObservationsPath(client, connection, dialect, config, filters, pageSize, ctx) {
|
|
121
|
+
try {
|
|
122
|
+
const opts = companionRequestOptions(connection, dialect, config, [], {
|
|
123
|
+
...filters,
|
|
124
|
+
pageSize,
|
|
125
|
+
});
|
|
126
|
+
const envelope = await client.get(connection.baseUrl, '/observations', ctx, opts);
|
|
127
|
+
const rows = extractRows(envelope.result);
|
|
128
|
+
return rows.flatMap(normalizeObsRow).filter(Boolean);
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
if (isDialectAllDropped(err))
|
|
132
|
+
throw err;
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/** Fetch raw observationunit records (without extracting observations). Returns null on error. */
|
|
137
|
+
async function fetchObservationUnitsRaw(client, connection, dialect, config, studyDbId, pageSize, ctx) {
|
|
138
|
+
try {
|
|
139
|
+
const rawFilters = { studyDbIds: [studyDbId] };
|
|
140
|
+
const adapted = dialect.adaptGetFilters('observationunits', rawFilters);
|
|
141
|
+
const obsUnitFilters = adapted.filters;
|
|
142
|
+
const opts = companionRequestOptions(connection, dialect, config, [], {
|
|
143
|
+
...obsUnitFilters,
|
|
144
|
+
pageSize,
|
|
145
|
+
});
|
|
146
|
+
const envelope = await client.get(connection.baseUrl, '/observationunits', ctx, opts);
|
|
147
|
+
return extractRows(envelope.result);
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
if (isDialectAllDropped(err))
|
|
151
|
+
throw err;
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/** Extract embedded observations[] from observationunit records (strategy 2a). */
|
|
156
|
+
function extractEmbeddedObservations(units, studyDbId) {
|
|
157
|
+
const obs = [];
|
|
158
|
+
for (const unit of units) {
|
|
159
|
+
const unitStudyDbId = unit.studyDbId ?? studyDbId;
|
|
160
|
+
const unitGermplasmDbId = unit.germplasmDbId ?? 'unknown';
|
|
161
|
+
const unitGermplasmName = typeof unit.germplasmName === 'string' && unit.germplasmName.length > 0
|
|
162
|
+
? unit.germplasmName
|
|
163
|
+
: unitGermplasmDbId;
|
|
164
|
+
const embedded = unit.observations;
|
|
165
|
+
if (!Array.isArray(embedded))
|
|
166
|
+
continue;
|
|
167
|
+
for (const raw of embedded) {
|
|
168
|
+
if (!raw || typeof raw !== 'object')
|
|
169
|
+
continue;
|
|
170
|
+
const r = raw;
|
|
171
|
+
const varId = r.observationVariableDbId ?? null;
|
|
172
|
+
const val = r.value ?? null;
|
|
173
|
+
if (!varId || val === null || val === undefined)
|
|
174
|
+
continue;
|
|
175
|
+
const season = seasonLabel(r);
|
|
176
|
+
obs.push({
|
|
177
|
+
germplasmDbId: unitGermplasmDbId,
|
|
178
|
+
germplasmName: unitGermplasmName,
|
|
179
|
+
observationVariableDbId: String(varId),
|
|
180
|
+
observationVariableName: typeof r.observationVariableName === 'string' && r.observationVariableName.length > 0
|
|
181
|
+
? r.observationVariableName
|
|
182
|
+
: String(varId),
|
|
183
|
+
studyDbId: unitStudyDbId,
|
|
184
|
+
value: String(val),
|
|
185
|
+
...(season ? { season } : {}),
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return obs;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Pull observations anchored by germplasmDbId (strategy 2b). Used when
|
|
193
|
+
* studyDbId filter is not honored on /observations but we know germplasmDbIds
|
|
194
|
+
* in the study from the observationunits response. Filters results to only
|
|
195
|
+
* observations for the target study.
|
|
196
|
+
*/
|
|
197
|
+
async function fetchObservationsByGermplasm(client, connection, dialect, config, germplasmIds, studyDbId, pageSize, ctx) {
|
|
198
|
+
try {
|
|
199
|
+
// Pull per germplasm to stay study-anchored. Bound by pageSize per call.
|
|
200
|
+
// For wide queries this is O(germplasmCount) requests but avoids an
|
|
201
|
+
// unbounded full-table scan on the observations endpoint.
|
|
202
|
+
const allObs = [];
|
|
203
|
+
for (const germId of germplasmIds) {
|
|
204
|
+
const rawFilters = { germplasmDbIds: [germId] };
|
|
205
|
+
const adapted = dialect.adaptGetFilters('observations', rawFilters);
|
|
206
|
+
// Skip if the germplasm filter is also dropped
|
|
207
|
+
if (adapted.dropped.length > 0 && Object.keys(adapted.filters).length === 0)
|
|
208
|
+
continue;
|
|
209
|
+
const opts = companionRequestOptions(connection, dialect, config, [], {
|
|
210
|
+
...adapted.filters,
|
|
211
|
+
pageSize,
|
|
212
|
+
});
|
|
213
|
+
try {
|
|
214
|
+
const envelope = await client.get(connection.baseUrl, '/observations', ctx, opts);
|
|
215
|
+
const rows = extractRows(envelope.result);
|
|
216
|
+
// Filter to only observations for the target study
|
|
217
|
+
for (const row of rows) {
|
|
218
|
+
if (row.studyDbId !== studyDbId)
|
|
219
|
+
continue;
|
|
220
|
+
const norm = normalizeObsRow(row);
|
|
221
|
+
if (norm)
|
|
222
|
+
allObs.push(norm);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
catch { }
|
|
226
|
+
}
|
|
227
|
+
return allObs;
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
if (isDialectAllDropped(err))
|
|
231
|
+
throw err;
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/** Normalise a raw /observations row; drops rows missing any required field. */
|
|
236
|
+
export function normalizeObsRow(row) {
|
|
237
|
+
const varId = row.observationVariableDbId ?? null;
|
|
238
|
+
const germId = row.germplasmDbId ?? null;
|
|
239
|
+
const studyId = row.studyDbId ?? null;
|
|
240
|
+
const val = row.value ?? null;
|
|
241
|
+
if (!varId || !germId || !studyId || val === null || val === undefined)
|
|
242
|
+
return null;
|
|
243
|
+
const norm = {
|
|
244
|
+
germplasmDbId: String(germId),
|
|
245
|
+
germplasmName: typeof row.germplasmName === 'string' && row.germplasmName.length > 0
|
|
246
|
+
? row.germplasmName
|
|
247
|
+
: String(germId),
|
|
248
|
+
observationVariableDbId: String(varId),
|
|
249
|
+
observationVariableName: typeof row.observationVariableName === 'string' && row.observationVariableName.length > 0
|
|
250
|
+
? row.observationVariableName
|
|
251
|
+
: String(varId),
|
|
252
|
+
studyDbId: String(studyId),
|
|
253
|
+
value: String(val),
|
|
254
|
+
};
|
|
255
|
+
const season = seasonLabel(row);
|
|
256
|
+
if (season)
|
|
257
|
+
norm.season = season;
|
|
258
|
+
return norm;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Derive a human season label from a BrAPI observation row. Servers carry
|
|
262
|
+
* season either as a nested object (`{ seasonName, year, seasonDbId }`) or a
|
|
263
|
+
* flat `seasonDbId` string. Returns undefined when neither is present.
|
|
264
|
+
*/
|
|
265
|
+
export function seasonLabel(row) {
|
|
266
|
+
const s = row.season;
|
|
267
|
+
if (s && typeof s === 'object') {
|
|
268
|
+
const so = s;
|
|
269
|
+
const name = typeof so.seasonName === 'string' && so.seasonName.length > 0 ? so.seasonName : undefined;
|
|
270
|
+
const year = typeof so.year === 'number' ? so.year : undefined;
|
|
271
|
+
if (name && year !== undefined)
|
|
272
|
+
return `${name} ${year}`;
|
|
273
|
+
if (name)
|
|
274
|
+
return name;
|
|
275
|
+
if (typeof so.seasonDbId === 'string' && so.seasonDbId.length > 0)
|
|
276
|
+
return so.seasonDbId;
|
|
277
|
+
}
|
|
278
|
+
else if (typeof s === 'string' && s.length > 0) {
|
|
279
|
+
return s;
|
|
280
|
+
}
|
|
281
|
+
if (typeof row.seasonDbId === 'string' && row.seasonDbId.length > 0)
|
|
282
|
+
return row.seasonDbId;
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
//# sourceMappingURL=observations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observations.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/shared/observations.ts"],"names":[],"mappings":"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"}
|
package/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyanheads/brapi-mcp-server",
|
|
3
3
|
"mcpName": "io.github.cyanheads/brapi-mcp-server",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.7.0",
|
|
5
5
|
"description": "A collaborative BrAPI v2.1 workspace for multi-agent research via MCP. Search studies, germplasm, genotypes, & more - across Breedbase, T3, Sweetpotatobase, & any BrAPI v2-compliant server.",
|
|
6
6
|
"author": "Casey Hand @cyanheads (https://github.com/cyanheads/brapi-mcp-server#readme)",
|
|
7
7
|
"type": "module",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
},
|
|
82
82
|
"dependencies": {
|
|
83
83
|
"@cyanheads/mcp-ts-core": "^0.9.16",
|
|
84
|
-
"@duckdb/node-api": "^1.5.3-r.
|
|
84
|
+
"@duckdb/node-api": "^1.5.3-r.3",
|
|
85
85
|
"pino-pretty": "^13.1.3",
|
|
86
86
|
"zod": "^4.4.3"
|
|
87
87
|
},
|
|
@@ -92,6 +92,6 @@
|
|
|
92
92
|
"ignore": "^7.0.5",
|
|
93
93
|
"tsc-alias": "^1.8.17",
|
|
94
94
|
"typescript": "^6.0.3",
|
|
95
|
-
"vitest": "^4.1.
|
|
95
|
+
"vitest": "^4.1.8"
|
|
96
96
|
}
|
|
97
97
|
}
|
package/server.json
CHANGED
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
"url": "https://github.com/cyanheads/brapi-mcp-server",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.7.0",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
14
14
|
"identifier": "@cyanheads/brapi-mcp-server",
|
|
15
15
|
"runtimeHint": "bun",
|
|
16
|
-
"version": "0.
|
|
16
|
+
"version": "0.7.0",
|
|
17
17
|
"packageArguments": [
|
|
18
18
|
{ "type": "positional", "value": "run" },
|
|
19
19
|
{ "type": "positional", "value": "start:stdio" }
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
50
50
|
"identifier": "@cyanheads/brapi-mcp-server",
|
|
51
51
|
"runtimeHint": "bun",
|
|
52
|
-
"version": "0.
|
|
52
|
+
"version": "0.7.0",
|
|
53
53
|
"packageArguments": [
|
|
54
54
|
{ "type": "positional", "value": "run" },
|
|
55
55
|
{ "type": "positional", "value": "start:http" }
|