@cyanheads/brapi-mcp-server 0.4.12 → 0.4.13
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 +1 -1
- package/README.md +147 -518
- package/changelog/0.4.x/0.4.13.md +42 -0
- package/dist/config/alias-credentials.d.ts.map +1 -1
- package/dist/config/alias-credentials.js +9 -2
- package/dist/config/alias-credentials.js.map +1 -1
- package/dist/config/builtin-aliases.d.ts.map +1 -1
- package/dist/config/builtin-aliases.js +22 -4
- package/dist/config/builtin-aliases.js.map +1 -1
- package/package.json +1 -1
- package/server.json +3 -3
package/CLAUDE.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** brapi-mcp-server
|
|
4
|
-
**Version:** 0.4.
|
|
4
|
+
**Version:** 0.4.13
|
|
5
5
|
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
|
|
6
6
|
|
|
7
7
|
> **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<div align="center">
|
|
9
9
|
|
|
10
|
-
[](https://www.npmjs.com/package/@cyanheads/brapi-mcp-server) [](https://www.npmjs.com/package/@cyanheads/brapi-mcp-server) [](./CHANGELOG.md) [](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) [](https://modelcontextprotocol.io/)
|
|
11
11
|
|
|
12
12
|
[](./LICENSE) [](https://www.typescriptlang.org/) [](https://bun.sh/) [](./CHANGELOG.md)
|
|
13
13
|
|
|
@@ -17,360 +17,112 @@
|
|
|
17
17
|
|
|
18
18
|
## Tools
|
|
19
19
|
|
|
20
|
-
Twenty-two tools grouped by shape — connection tools bootstrap a session, `find_*` tools return a summarized page plus distributions and spill overflow rows into the DatasetStore, `get_*` tools fetch a single record with companion counts, plus pedigree walking, dataset lifecycle, an opt-in SQL
|
|
20
|
+
Twenty-two tools grouped by shape — connection tools bootstrap a session, `find_*` tools return a summarized page plus distributions and spill overflow rows into the DatasetStore, `get_*` tools fetch a single record with companion counts, plus pedigree walking, dataset lifecycle, an opt-in SQL workspace over spilled rows, an additive write surface for observations, and raw passthrough escape hatches.
|
|
21
21
|
|
|
22
22
|
### Orient
|
|
23
23
|
|
|
24
|
-
| Tool
|
|
25
|
-
|
|
26
|
-
| `brapi_connect` |
|
|
27
|
-
| `brapi_server_info` |
|
|
28
|
-
| `brapi_describe_filters` |
|
|
24
|
+
| Tool | Description |
|
|
25
|
+
|:-----|:------------|
|
|
26
|
+
| `brapi_connect` | Authenticate, register the connection under an alias, cache the capability profile, and return the orientation envelope inline. One call fully orients the agent. |
|
|
27
|
+
| `brapi_server_info` | Re-fetch the orientation envelope for a registered alias — identity, auth, capabilities, content counts, attribution, notes. |
|
|
28
|
+
| `brapi_describe_filters` | Static BrAPI v2.1 filter catalog for any endpoint — powers `extraFilters` discovery on every `find_*` tool. |
|
|
29
29
|
|
|
30
30
|
### Retrieve
|
|
31
31
|
|
|
32
|
-
| Tool
|
|
33
|
-
|
|
34
|
-
| `brapi_find_studies` |
|
|
35
|
-
| `brapi_get_study` | Fetch a
|
|
36
|
-
| `brapi_find_germplasm` | Find germplasm by name, synonym, accession, crop, or free-text
|
|
37
|
-
| `brapi_get_germplasm` | Fetch a
|
|
38
|
-
| `brapi_walk_pedigree` |
|
|
39
|
-
| `brapi_find_variables` | Find observation variables
|
|
40
|
-
| `brapi_find_observations` | Pull observation records
|
|
41
|
-
| `brapi_find_images` | Filter
|
|
42
|
-
| `brapi_get_image` | Fetch image bytes for up to 5 imageDbIds inline as `type: image`
|
|
43
|
-
| `brapi_find_locations` | Find research stations
|
|
32
|
+
| Tool | Description |
|
|
33
|
+
|:-----|:------------|
|
|
34
|
+
| `brapi_find_studies` | Find studies by crop / trial type / season / location / program. Distributions + dataset spillover. |
|
|
35
|
+
| `brapi_get_study` | Fetch a study with program / trial / location FKs resolved and companion counts (observations, units, variables). |
|
|
36
|
+
| `brapi_find_germplasm` | Find germplasm by name, synonym, accession, PUI, crop, or free-text. Distributions + dataset spillover. |
|
|
37
|
+
| `brapi_get_germplasm` | Fetch a germplasm with attributes, direct parents, and companion counts (studies, parents, descendants). |
|
|
38
|
+
| `brapi_walk_pedigree` | BFS-walk ancestry / descendancy as a deduplicated DAG with cycle detection, depth limits, and traversal stats. |
|
|
39
|
+
| `brapi_find_variables` | Find observation variables by name / class / ontology / free-text; ranked client-side via `OntologyResolver` when `text` is supplied. |
|
|
40
|
+
| `brapi_find_observations` | Pull observation records by study / germplasm / variable / season / unit / timestamp. Dataset spillover. |
|
|
41
|
+
| `brapi_find_images` | Filter image metadata by unit / study / ontology / MIME type. Bytes via `brapi_get_image`. |
|
|
42
|
+
| `brapi_get_image` | Fetch image bytes for up to 5 imageDbIds inline as `type: image` blocks. Prefers `/imagecontent`, falls back to `imageURL`. |
|
|
43
|
+
| `brapi_find_locations` | Find research stations by country / type / abbreviation, with optional client-side bbox filter. |
|
|
44
44
|
| `brapi_find_variants` | Find variant records by variant set, reference, or genomic region (1-based inclusive / exclusive). |
|
|
45
|
-
| `brapi_find_genotype_calls` | Pull genotype calls
|
|
45
|
+
| `brapi_find_genotype_calls` | Pull genotype calls via async-search polling. Upstream pull bounded by `BRAPI_GENOTYPE_CALLS_MAX_PULL` (default 100k, max 500k). |
|
|
46
46
|
|
|
47
47
|
### Orchestrate
|
|
48
48
|
|
|
49
|
-
| Tool
|
|
50
|
-
|
|
51
|
-
| `brapi_manage_dataset` | Lifecycle for `find_*` spillover datasets — list
|
|
49
|
+
| Tool | Description |
|
|
50
|
+
|:-----|:------------|
|
|
51
|
+
| `brapi_manage_dataset` | Lifecycle for `find_*` spillover datasets — list / summary / load (paged + projected) / delete. |
|
|
52
52
|
|
|
53
|
-
### Analyze
|
|
53
|
+
### Analyze (opt-in: `CANVAS_PROVIDER_TYPE=duckdb` + `BRAPI_CANVAS_ENABLED=true`)
|
|
54
54
|
|
|
55
|
-
| Tool
|
|
56
|
-
|
|
57
|
-
| `brapi_dataframe_query` |
|
|
58
|
-
| `brapi_dataframe_describe` | List dataframes with column schema, row counts, and
|
|
59
|
-
| `brapi_dataframe_drop` | Drop a dataframe by name. Idempotent
|
|
55
|
+
| Tool | Description |
|
|
56
|
+
|:-----|:------------|
|
|
57
|
+
| `brapi_dataframe_query` | SELECT SQL across in-memory dataframes (DuckDB-backed). Spilled `find_*` datasets auto-register as `ds_<datasetId>`. Read-only — multi-statement, non-SELECT, file-reads, and exports rejected. |
|
|
58
|
+
| `brapi_dataframe_describe` | List dataframes with column schema, row counts, and dataset provenance. |
|
|
59
|
+
| `brapi_dataframe_drop` | Drop a dataframe by name. Idempotent. Underlying dataset is unaffected. |
|
|
60
60
|
|
|
61
|
-
### Write
|
|
61
|
+
### Write (opt-in: `BRAPI_ENABLE_WRITES=true`)
|
|
62
62
|
|
|
63
|
-
| Tool
|
|
64
|
-
|
|
65
|
-
| `brapi_submit_observations` |
|
|
63
|
+
| Tool | Description |
|
|
64
|
+
|:-----|:------------|
|
|
65
|
+
| `brapi_submit_observations` | Two-phase observation write — `mode: preview` validates; `mode: apply` elicits confirmation, then fans POST + PUT in parallel. Additive only — no destructive deletion. |
|
|
66
66
|
|
|
67
67
|
### Escape hatches
|
|
68
68
|
|
|
69
|
-
| Tool
|
|
70
|
-
|
|
71
|
-
| `brapi_raw_get` | Passthrough to any BrAPI `GET /{path}`
|
|
72
|
-
| `brapi_raw_search` | Passthrough to any
|
|
69
|
+
| Tool | Description |
|
|
70
|
+
|:-----|:------------|
|
|
71
|
+
| `brapi_raw_get` | Passthrough to any BrAPI `GET /{path}` not covered by curated tools. Emits a routing nudge when one applies. |
|
|
72
|
+
| `brapi_raw_search` | Passthrough to any `POST /search/{noun}` with async polling handled transparently. Same nudge pattern. |
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
### `brapi_connect`
|
|
77
|
-
|
|
78
|
-
Session bootstrap. Authenticates to a BrAPI v2 server, registers the connection under a named alias, loads the capability profile via `CapabilityRegistry`, and inlines the full orientation envelope in the response. One call fully orients the agent.
|
|
79
|
-
|
|
80
|
-
- `baseUrl` and `auth` are optional — when omitted they fall back to `BRAPI_<ALIAS>_*`, then a built-in registry of public BrAPI servers (`cassava`, `sweetpotato`, `wheat`, `breedbase`), then `BRAPI_DEFAULT_*` (see [Per-alias credentials](#per-alias-credentials) and [Built-in aliases](#built-in-aliases)). Agents can call `brapi_connect({ alias: 'cassava' })` with nothing else and credentials never enter the LLM context
|
|
81
|
-
- Tagged-union auth input: `none`, `sgn` (session-token exchange), `oauth2` (client-credentials exchange), `bearer`, `api_key`
|
|
82
|
-
- Multiple concurrent connections per session via distinct aliases
|
|
83
|
-
- Forces a fresh capability load on every connect — the agent expects current state
|
|
84
|
-
- Returns the same envelope as `brapi_server_info` — server identity, auth status, capability profile (supported/missing calls), content summary, server-specific notes
|
|
85
|
-
|
|
86
|
-
> **Alias discovery.** Configured aliases are appended to this tool's description at server startup, so agents see the inventory on `tools/list` without anyone having to spell them out in the prompt. Restart the server after changing `BRAPI_<ALIAS>_*` env vars to refresh. Pre-configured aliases are shortcuts only — any other BrAPI v2 server is reachable by passing `baseUrl` directly.
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
### `brapi_server_info`
|
|
91
|
-
|
|
92
|
-
On-demand orientation envelope for any registered alias. Useful for refreshing capability data after a long session or switching between aliases.
|
|
93
|
-
|
|
94
|
-
- Defaults to the most recent `brapi_connect` alias when `alias` is omitted
|
|
95
|
-
- `forceRefresh: true` bypasses the cached capability profile
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
### `brapi_describe_filters`
|
|
100
|
-
|
|
101
|
-
Static filter catalog drawn from the BrAPI v2.1 spec — name, type, description, and example per filter. Use it before constructing `extraFilters` on any `find_*` tool.
|
|
102
|
-
|
|
103
|
-
- Covers `studies`, `germplasm`, `variables`, `observations`, `images`, `variants`, `locations`
|
|
104
|
-
- Catalog entries reflect the v2.1 spec; individual servers may implement subsets (the capability profile from `brapi_connect` tells you which)
|
|
105
|
-
- Response includes `specReference` link and the full list of available endpoints for discovery
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
|
|
109
|
-
### `brapi_find_studies`
|
|
110
|
-
|
|
111
|
-
Locate studies with filters on crop, trial type, season, location, program, free text. Pulls an initial page (capped at `loadLimit`) and, when the upstream total exceeds `loadLimit`, spills the full union into `DatasetStore` and returns a dataset handle.
|
|
112
|
-
|
|
113
|
-
- Distributions computed across the full row set (`programName`, `studyType`, `seasons`, `locationName`, `commonCropName`)
|
|
114
|
-
- Refinement hint suggests which field to narrow when results exceed `loadLimit`
|
|
115
|
-
- `extraFilters` escape hatch for server-specific filter keys (discover via `brapi_describe_filters`)
|
|
116
|
-
- Warnings surface when `extraFilters` collides with named inputs
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
### `brapi_get_study`
|
|
121
|
-
|
|
122
|
-
Fetch a single study by `studyDbId` with FKs resolved via `ReferenceDataCache` and cheap `pageSize=0` probes for observation / observation-unit / variable counts.
|
|
123
|
-
|
|
124
|
-
- Resolves `programDbId`, `trialDbId`, `locationDbId` into full records in one call
|
|
125
|
-
- Companion counts signal where to drill next without a full page pull
|
|
126
|
-
- Warnings when the upstream server doesn't support count probes
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
### `brapi_find_germplasm`
|
|
131
|
-
|
|
132
|
-
Find germplasm by name, synonym, accession number, PUI, crop, or free-text. Matches across registered synonyms per BrAPI semantics.
|
|
133
|
-
|
|
134
|
-
- Distributions across `commonCropName`, `genus`, `species`, `collection`, `countryOfOriginCode`
|
|
135
|
-
- Dataset spillover identical to `brapi_find_studies`
|
|
136
|
-
- Refinement hint identifies the highest-cardinality dimension for narrowing
|
|
137
|
-
|
|
138
|
-
---
|
|
139
|
-
|
|
140
|
-
### `brapi_get_germplasm`
|
|
141
|
-
|
|
142
|
-
Fetch a single germplasm with attributes, direct parents, and three companion counts (studies the germplasm appeared in, direct parents, direct descendants) — the counts signal where pedigree traversal could go next.
|
|
143
|
-
|
|
144
|
-
- Pulls `/germplasm/{id}`, `/germplasm/{id}/attributes`, `/germplasm/{id}/pedigree`, and `/germplasm/{id}/progeny` in one call
|
|
145
|
-
- Warnings when the upstream server omits any of those sub-endpoints
|
|
146
|
-
|
|
147
|
-
---
|
|
148
|
-
|
|
149
|
-
### `brapi_walk_pedigree`
|
|
150
|
-
|
|
151
|
-
Walk germplasm ancestry or descendancy as a deduplicated DAG. BrAPI only exposes one generation per call, so this tool BFS-expands from each root, breaks cycles, and enforces a 1000-node safety cap.
|
|
152
|
-
|
|
153
|
-
- `direction`: `ancestors` (parents), `descendants` (progeny), or `both`
|
|
154
|
-
- Up to 20 roots per call, depth capped at 10 (default 3)
|
|
155
|
-
- Returns nodes + edges plus traversal stats (`depthReached`, `leafCount`, `cycleCount`, `deadEndCount`, `truncated`)
|
|
156
|
-
- Warnings when the server doesn't expose `/germplasm/{id}/pedigree` or `/progeny`
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
### `brapi_find_variables`
|
|
161
|
-
|
|
162
|
-
Find observation variables (traits) by name, trait class, ontology term, or free-text. When `text` is supplied, results are re-ranked client-side via `OntologyResolver`; otherwise falls back to upstream order.
|
|
163
|
-
|
|
164
|
-
- Distributions across `ontologyDbId`, `traitClass`, `scaleName`
|
|
165
|
-
- Ontology candidates (top 10) surfaced separately when `text` is supplied, with source attribution (`puiMatch` / `nameMatch` / `synonymMatch` / `traitClassMatch`)
|
|
166
|
-
- Dataset spillover and `extraFilters` passthrough identical to other `find_*` tools
|
|
167
|
-
|
|
168
|
-
---
|
|
169
|
-
|
|
170
|
-
### `brapi_find_observations`
|
|
171
|
-
|
|
172
|
-
Pull observation records filtered by study, germplasm, variable, season, observation unit, observation level, or timestamp range.
|
|
173
|
-
|
|
174
|
-
- Distributions across `observationVariableName`, `studyName`, `germplasmName`, `observationLevel`, `season`
|
|
175
|
-
- Dataset spillover when the upstream total exceeds `loadLimit` — handle passes to `brapi_manage_dataset`
|
|
176
|
-
|
|
177
|
-
---
|
|
178
|
-
|
|
179
|
-
### `brapi_find_images`
|
|
180
|
-
|
|
181
|
-
Filter images by observation unit, observation, study, descriptive ontology term, file name, or MIME type. Returns metadata only — use `brapi_get_image` for bytes.
|
|
182
|
-
|
|
183
|
-
- Distributions across `mimeType`, `studyName`, `observationUnitName`, `descriptiveOntologyTerms`
|
|
184
|
-
- Dataset spillover for large result sets
|
|
185
|
-
|
|
186
|
-
---
|
|
187
|
-
|
|
188
|
-
### `brapi_get_image`
|
|
189
|
-
|
|
190
|
-
Fetch image bytes for up to 5 `imageDbIds` and return them inline as `type: image` content blocks. Hard cap of 20 MB per image.
|
|
191
|
-
|
|
192
|
-
- Prefers BrAPI `/images/{id}/imagecontent`; falls back to the `imageURL` field when the server doesn't implement imagecontent
|
|
193
|
-
- Relative `imageURL`s resolve against the registered base URL; absolute URLs pass through (no auth attached to the fallback)
|
|
194
|
-
- Per-image error reporting — partial success is surfaced cleanly
|
|
195
|
-
|
|
196
|
-
---
|
|
197
|
-
|
|
198
|
-
### `brapi_find_locations`
|
|
199
|
-
|
|
200
|
-
Find research stations / field sites by country, abbreviation, type, or location ID.
|
|
201
|
-
|
|
202
|
-
- Optional client-side bounding-box filter (`bbox: {minLat, maxLat, minLon, maxLon}`) applied after the upstream fetch (BrAPI has no spec-level bbox filter)
|
|
203
|
-
- Distributions across `countryCode` and `locationType`
|
|
204
|
-
- All four corners required to activate `bbox`; mismatched values produce a warning and the filter is skipped
|
|
205
|
-
|
|
206
|
-
---
|
|
207
|
-
|
|
208
|
-
### `brapi_find_variants`
|
|
209
|
-
|
|
210
|
-
Find variant records by variant set, reference sequence, or genomic region.
|
|
211
|
-
|
|
212
|
-
- Genomic region uses 1-based inclusive `start` / exclusive `end` per the BrAPI spec
|
|
213
|
-
- Distributions across `variantType`, `referenceName`, `variantSetDbId`
|
|
214
|
-
- Warns when `start >= end`
|
|
215
|
-
|
|
216
|
-
---
|
|
217
|
-
|
|
218
|
-
### `brapi_find_genotype_calls`
|
|
219
|
-
|
|
220
|
-
Pull genotype calls for a germplasm × variant set. Handles BrAPI's async-search pattern (`POST /search/calls` → `GET /search/calls/{id}`) transparently.
|
|
221
|
-
|
|
222
|
-
- Requires at least one filter (`variantSetDbId`, `germplasmDbIds`, `callSetDbIds`, `variantDbIds`) — unfiltered pulls are rejected
|
|
223
|
-
- Upstream pull bounded by deployment policy (`BRAPI_GENOTYPE_CALLS_MAX_PULL`, default 100,000, hard ceiling 500,000) — protects upstream from unbounded sequential paginated GETs. `truncated: true` flags when the cap was hit; agents narrow the filters and re-pull, or query the spilled dataframe
|
|
224
|
-
- Rows beyond `loadLimit` (default 200) spill to `DatasetStore` for paged follow-up via `brapi_manage_dataset`, or SQL-queryable access via `brapi_dataframe_query`
|
|
225
|
-
- Echoes server-reported genotype-encoding (`expandHomozygotes`, `unknownString`, `sepPhased`, `sepUnphased`) so the agent can interpret the values
|
|
226
|
-
|
|
227
|
-
---
|
|
228
|
-
|
|
229
|
-
### `brapi_manage_dataset`
|
|
230
|
-
|
|
231
|
-
Consolidated lifecycle tool for datasets produced by `find_*` spillovers.
|
|
232
|
-
|
|
233
|
-
- `mode: list` — enumerate datasets with source / query / rowCount / expiration
|
|
234
|
-
- `mode: summary` — per-dataset metadata and provenance
|
|
235
|
-
- `mode: load` — paged rows (up to 1000 per page) with optional column projection
|
|
236
|
-
- `mode: delete` — drop metadata and payload
|
|
237
|
-
- Export (CSV / Parquet) is deferred until the write surface lands
|
|
238
|
-
|
|
239
|
-
---
|
|
240
|
-
|
|
241
|
-
### `brapi_dataframe_query`
|
|
242
|
-
|
|
243
|
-
Run SQL across in-memory dataframes — a SQL/analytical workspace backed by the framework's DuckDB-powered DataCanvas. Spilled `find_*` datasets auto-register as `ds_<datasetId>` dataframes; describe them via `brapi_dataframe_describe` before composing a query.
|
|
244
|
-
|
|
245
|
-
> **Off by default.** Both gates must be on: `CANVAS_PROVIDER_TYPE=duckdb` (framework-side) and `BRAPI_CANVAS_ENABLED=true` (server-side, default true). Requires the optional `@duckdb/node-api` peer dep. Not available on Cloudflare Workers — DuckDB has no V8-isolate build.
|
|
246
|
-
|
|
247
|
-
- Read-only enforcement via the framework's three-layer SQL gate (single statement → SELECT only → plan-walk allowlist), plus a server-side deny-list for `read_json*` / `read_parquet*` / `iceberg_scan` / `delta_scan` that bypass the canvas
|
|
248
|
-
- `registerAs` materializes the result as a new dataframe — full result lives in the workspace, response carries a bounded `preview` slice plus the full `rowCount`
|
|
249
|
-
- `BRAPI_CANVAS_MAX_ROWS` (default 10,000) caps response materialization; raising `rowLimit` past this is silently capped — use `registerAs` instead
|
|
250
|
-
- `BRAPI_CANVAS_QUERY_TIMEOUT_MS` (default 30,000) wraps the query in a wall-clock cap on top of `ctx.signal`
|
|
251
|
-
- Per-tenant default workspace cached in `ctx.state` — agents never see the underlying canvasId
|
|
252
|
-
- SQL-gate rejections translate to a typed `sql_rejected` reason, preserving the granular gate code on `data.gateReason`
|
|
253
|
-
|
|
254
|
-
---
|
|
255
|
-
|
|
256
|
-
### `brapi_dataframe_describe`
|
|
257
|
-
|
|
258
|
-
List the dataframes available in the current workspace (or describe one by name) with column schema, row counts, and originating-dataset provenance.
|
|
259
|
-
|
|
260
|
-
- `ds_*`-prefixed dataframes carry full provenance: originating tool (`source`), `baseUrl`, original `query`, `createdAt`, `expiresAt`
|
|
261
|
-
- User-derived dataframes (created via `brapi_dataframe_query({ registerAs })`) show structural info only
|
|
262
|
-
- Pass `tableName` to scope to one entry; omit to list all
|
|
263
|
-
|
|
264
|
-
---
|
|
265
|
-
|
|
266
|
-
### `brapi_dataframe_drop`
|
|
267
|
-
|
|
268
|
-
Release a dataframe by name. Idempotent — returns `dropped: false` rather than failing when the name is unknown.
|
|
269
|
-
|
|
270
|
-
- Drops the dataframe and its provenance metadata; the underlying DatasetStore dataset is untouched
|
|
271
|
-
- Use `brapi_manage_dataset mode=delete` to drop both the dataset and its dataframe in one call
|
|
272
|
-
|
|
273
|
-
---
|
|
274
|
-
|
|
275
|
-
### `brapi_raw_get`
|
|
276
|
-
|
|
277
|
-
Last-resort passthrough to any BrAPI `GET /{path}` the curated tools don't cover (e.g. `/samples`, `/methods`, `/scales`, `/crosses`). Returns the raw upstream envelope plus pagination metadata.
|
|
278
|
-
|
|
279
|
-
- Rejects absolute URLs in `path` — cross-origin smuggling via the registered base URL is blocked
|
|
280
|
-
- Emits a `suggestion` field when a goal-shaped tool covers the target endpoint (e.g. calling `raw_get /studies` nudges you to `brapi_find_studies`)
|
|
281
|
-
- Does not enrich results, resolve foreign keys, or compute distributions — prefer curated tools when they apply
|
|
282
|
-
|
|
283
|
-
---
|
|
284
|
-
|
|
285
|
-
### `brapi_raw_search`
|
|
286
|
-
|
|
287
|
-
Last-resort passthrough to any BrAPI `POST /search/{noun}`. Handles the 202 / async-poll pattern transparently.
|
|
288
|
-
|
|
289
|
-
- Same routing-nudge behavior as `brapi_raw_get`
|
|
290
|
-
- Returns `kind: sync | async` and the `searchResultsDbId` when the server took the async path
|
|
291
|
-
|
|
292
|
-
---
|
|
293
|
-
|
|
294
|
-
### `brapi_submit_observations`
|
|
295
|
-
|
|
296
|
-
Two-phase write for observation rows. Default `mode: preview` validates rows against the study's variables and returns a routing breakdown; `mode: apply` elicits user confirmation when the client supports it, then POSTs new rows and PUTs rows carrying `observationDbId` in parallel.
|
|
297
|
-
|
|
298
|
-
> **Off by default.** Registered only when the operator sets `BRAPI_ENABLE_WRITES=true`; omitted from the surface otherwise. Operator-level deploy-time consent for the only mutation tool — the in-tool preview default, `ctx.elicit` confirmation, `force: true` bypass, and `brapi:write:observations` auth scope all continue to apply when registration is on.
|
|
299
|
-
|
|
300
|
-
- POST/PUT routing keyed on per-row `observationDbId` presence — mixed batches in one call
|
|
301
|
-
- Pre-flight pulls `/studies/{id}/observationvariables` to flag rows whose variable isn't exposed by the study (warning, not rejection — the upstream is the source of truth)
|
|
302
|
-
- Apply mode requires `ctx.elicit` confirmation OR an explicit `force: true` flag (rejected with `Forbidden` otherwise)
|
|
303
|
-
- Post-write probe re-fetches `/studies/{id}/observations?pageSize=0` to surface the new total in the response
|
|
304
|
-
- `latestObservationTimestamp` echoes the most recent `observationTimeStamp` across the accepted rows
|
|
305
|
-
- Additive only — destructive deletion is not exposed; corrections route through PUT
|
|
306
|
-
- Auth scope: `brapi:write:observations` (HTTP deployments only)
|
|
74
|
+
> **Alias discovery.** Built-in and operator-configured aliases are appended to the `brapi_connect` description at server startup, so agents see the inventory on `tools/list`. Restart after env-var changes to refresh.
|
|
307
75
|
|
|
308
76
|
---
|
|
309
77
|
|
|
310
78
|
## Resources
|
|
311
79
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
| URI template | Description |
|
|
315
|
-
|:-------------|:------------|
|
|
316
|
-
| `brapi://server/info` | Orientation envelope for the default connection (mirror of `brapi_server_info`). |
|
|
317
|
-
| `brapi://calls` | Raw capability profile — supported services, their methods/versions, declared crops. |
|
|
318
|
-
| `brapi://study/{studyDbId}` | Single study with FKs resolved (mirror of `brapi_get_study`). |
|
|
319
|
-
| `brapi://germplasm/{germplasmDbId}` | Single germplasm with attributes and parents (mirror of `brapi_get_germplasm`). |
|
|
320
|
-
| `brapi://dataset/{datasetId}` | Metadata + provenance for a persisted dataset (paged rows via `brapi_manage_dataset` mode `load`). |
|
|
321
|
-
| `brapi://filters/{endpoint}` | Filter catalog for a BrAPI endpoint (mirror of `brapi_describe_filters`). |
|
|
80
|
+
URI-addressable mirrors of the curated tool surface for clients that prefer resources. All resources use the default connection — multi-server workflows route through tools.
|
|
322
81
|
|
|
323
|
-
|
|
82
|
+
| URI template | Mirrors |
|
|
83
|
+
|:-------------|:--------|
|
|
84
|
+
| `brapi://server/info` | `brapi_server_info` (default connection) |
|
|
85
|
+
| `brapi://calls` | Raw capability profile |
|
|
86
|
+
| `brapi://study/{studyDbId}` | `brapi_get_study` |
|
|
87
|
+
| `brapi://germplasm/{germplasmDbId}` | `brapi_get_germplasm` |
|
|
88
|
+
| `brapi://dataset/{datasetId}` | Dataset metadata + provenance |
|
|
89
|
+
| `brapi://filters/{endpoint}` | `brapi_describe_filters` |
|
|
324
90
|
|
|
325
91
|
---
|
|
326
92
|
|
|
327
93
|
## Prompts
|
|
328
94
|
|
|
329
|
-
|
|
95
|
+
Multi-step BrAPI workflow templates — pure user-message generators, no side effects.
|
|
330
96
|
|
|
331
97
|
| Name | Args | Purpose |
|
|
332
98
|
|:-----|:-----|:--------|
|
|
333
|
-
| `brapi_eda_study` | `studyDbId`, `alias?` |
|
|
334
|
-
| `brapi_meta_analysis` | `germplasmDbIds` (CSV), `traitName`, `alias?` | Cross-study meta-analysis
|
|
335
|
-
|
|
336
|
-
Pure templates — they generate the user message a downstream LLM consumes. No side effects.
|
|
99
|
+
| `brapi_eda_study` | `studyDbId`, `alias?` | EDA playbook for one study — orient, variables, coverage, missing data, outliers, pedigree, structured report. |
|
|
100
|
+
| `brapi_meta_analysis` | `germplasmDbIds` (CSV), `traitName`, `alias?` | Cross-study meta-analysis — trait resolution, study discovery, harmonization, per-germplasm × per-study and across-study summaries. |
|
|
337
101
|
|
|
338
102
|
---
|
|
339
103
|
|
|
340
|
-
##
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
-
|
|
345
|
-
-
|
|
346
|
-
-
|
|
347
|
-
-
|
|
348
|
-
-
|
|
349
|
-
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
- **
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
- **Find-route planning** — curated `find_*` tools prefer GET list endpoints, then fall back to POST `/search/{noun}` when only search is advertised
|
|
357
|
-
- **Dataset spillover** — `find_*` tools cap in-context rows at `loadLimit` and transparently persist larger unions (up to 50k rows / 50 pages) as handles in `DatasetStore`; `brapi_manage_dataset` pages / projects / deletes them
|
|
358
|
-
- **Dataframes (Tier 3, opt-in)** — spilled `find_*` rows auto-register as DuckDB-backed dataframes named `ds_<datasetId>`; agents run SELECT SQL across them via `brapi_dataframe_query`, with read-only enforcement and a per-tenant workspace. Gated by `CANVAS_PROVIDER_TYPE=duckdb` + `BRAPI_CANVAS_ENABLED=true`; requires the optional `@duckdb/node-api` peer dep. Not available on Cloudflare Workers.
|
|
359
|
-
- **Async-search transparency** — `brapi_find_genotype_calls` and `brapi_raw_search` handle the `POST /search/{noun}` → `GET /search/{noun}/{id}` 202-retry pattern without the agent needing to know
|
|
360
|
-
- **Pedigree DAG walks** — `brapi_walk_pedigree` BFS-traverses ancestry or descendancy with cycle detection, depth limits, and traversal stats — BrAPI only exposes one generation per call
|
|
361
|
-
- **Image content** — `brapi_get_image` fetches image bytes inline as MCP `type: image` blocks, preferring `/images/{id}/imagecontent` and falling back to the metadata `imageURL` field
|
|
362
|
-
- **Free-text variable ranking** — `OntologyResolver` scores variable records against a query (PUI / name / synonym / trait-class) so `find_variables text:"..."` returns ranked candidates even when the server has no `/ontologies` endpoint
|
|
363
|
-
- **Dynamic filter discovery** — static v2.1 filter catalog plus an `extraFilters` passthrough lets agents drive any server-specific filter without schema churn
|
|
364
|
-
- **Auth variants in one schema** — tagged-union connection auth covers none / bearer / api-key / SGN session-token exchange / OAuth2 client-credentials exchange in a single input shape
|
|
365
|
-
- **Compatibility matrix** — live server probes are tracked in [docs/compatibility.md](./docs/compatibility.md)
|
|
366
|
-
- **Typed error contracts** — every declared failure mode carries a stable `data.reason`, an HTTP-style `code`, and a `recovery.hint` mirrored onto the wire, so agent clients can route errors deterministically (e.g. `unknown_alias` → re-run `brapi_connect`, `dataset_not_found` → drop the stale handle)
|
|
367
|
-
- **Last-resort escape hatches** — `brapi_raw_get` and `brapi_raw_search` pass through to any endpoint with routing nudges pointing at the curated tool when one exists
|
|
104
|
+
## BrAPI-specific features
|
|
105
|
+
|
|
106
|
+
- **Multi-server session** — `ServerRegistry` maps aliases to live BrAPI connections; one session can span Breedbase, T3, and Sweetpotatobase in parallel.
|
|
107
|
+
- **Capability-aware calls** — `CapabilityRegistry` caches `/serverinfo` per connection and guards every tool call against unsupported endpoints. Falls back to `/calls` when `/serverinfo` is sparse.
|
|
108
|
+
- **Built-in known-server registry** — `bti-cassava`, `bti-sweetpotato`, `bti-breedbase-demo`, `t3-wheat`, `t3-oat`, `t3-barley` resolve out-of-the-box without env vars; orientation envelope carries CC-BY attribution.
|
|
109
|
+
- **Dataset spillover** — `find_*` tools cap in-context rows at `loadLimit` and persist larger unions (up to 50k rows / 50 pages) as handles in `DatasetStore`. `brapi_manage_dataset` pages / projects / deletes them.
|
|
110
|
+
- **Dataframes (Tier 3, opt-in)** — spilled rows auto-register as DuckDB-backed `ds_<datasetId>` dataframes; agents run SELECT SQL via `brapi_dataframe_query` with read-only enforcement and a per-tenant workspace. Requires the optional `@duckdb/node-api` peer dep. Not on Cloudflare Workers.
|
|
111
|
+
- **Async-search transparency** — `brapi_find_genotype_calls` and `brapi_raw_search` handle the `POST /search/{noun}` → `GET /search/{noun}/{id}` 202-retry pattern automatically.
|
|
112
|
+
- **Pedigree DAG walks** — `brapi_walk_pedigree` BFS-traverses ancestry / descendancy with cycle detection (BrAPI only exposes one generation per call).
|
|
113
|
+
- **Image content** — `brapi_get_image` fetches bytes inline as MCP `type: image` blocks, preferring `/images/{id}/imagecontent` with `imageURL` fallback.
|
|
114
|
+
- **Free-text variable ranking** — `OntologyResolver` scores variables against a query (PUI / name / synonym / trait-class) so `find_variables text:"..."` returns ranked candidates even without `/ontologies`.
|
|
115
|
+
- **Auth variants in one schema** — tagged-union covers `none` / `bearer` / `api_key` / `sgn` (session-token exchange) / `oauth2` (client-credentials).
|
|
116
|
+
- **Typed error contracts** — every declared failure mode carries a stable `data.reason`, an HTTP-style `code`, and a `recovery.hint` so clients can route deterministically.
|
|
117
|
+
- **Compatibility matrix** — live server probes tracked in [docs/compatibility.md](./docs/compatibility.md).
|
|
118
|
+
|
|
119
|
+
Built on [`@cyanheads/mcp-ts-core`](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) — declarative definitions, unified error handling, pluggable auth (`none` / `jwt` / `oauth`), swappable storage, structured logging with optional OTel, STDIO + Streamable HTTP transports.
|
|
368
120
|
|
|
369
121
|
---
|
|
370
122
|
|
|
371
123
|
## Getting started
|
|
372
124
|
|
|
373
|
-
Add
|
|
125
|
+
Add to your MCP client config — pick one runner:
|
|
374
126
|
|
|
375
127
|
```json
|
|
376
128
|
{
|
|
@@ -379,146 +131,63 @@ Add the following to your MCP client configuration file.
|
|
|
379
131
|
"type": "stdio",
|
|
380
132
|
"command": "bunx",
|
|
381
133
|
"args": ["@cyanheads/brapi-mcp-server@latest"],
|
|
382
|
-
"env": {
|
|
383
|
-
"MCP_TRANSPORT_TYPE": "stdio",
|
|
384
|
-
"MCP_LOG_LEVEL": "info"
|
|
385
|
-
}
|
|
134
|
+
"env": { "MCP_TRANSPORT_TYPE": "stdio", "MCP_LOG_LEVEL": "info" }
|
|
386
135
|
}
|
|
387
136
|
}
|
|
388
137
|
}
|
|
389
138
|
```
|
|
390
139
|
|
|
391
|
-
|
|
140
|
+
Swap `command`/`args` for `npx -y @cyanheads/brapi-mcp-server@latest` (no Bun) or `docker run -i --rm -e MCP_TRANSPORT_TYPE=stdio ghcr.io/cyanheads/brapi-mcp-server:latest`.
|
|
392
141
|
|
|
393
|
-
|
|
394
|
-
{
|
|
395
|
-
"mcpServers": {
|
|
396
|
-
"brapi": {
|
|
397
|
-
"type": "stdio",
|
|
398
|
-
"command": "npx",
|
|
399
|
-
"args": ["-y", "@cyanheads/brapi-mcp-server@latest"],
|
|
400
|
-
"env": {
|
|
401
|
-
"MCP_TRANSPORT_TYPE": "stdio",
|
|
402
|
-
"MCP_LOG_LEVEL": "info"
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
Or with Docker:
|
|
410
|
-
|
|
411
|
-
```json
|
|
412
|
-
{
|
|
413
|
-
"mcpServers": {
|
|
414
|
-
"brapi": {
|
|
415
|
-
"type": "stdio",
|
|
416
|
-
"command": "docker",
|
|
417
|
-
"args": [
|
|
418
|
-
"run", "-i", "--rm",
|
|
419
|
-
"-e", "MCP_TRANSPORT_TYPE=stdio",
|
|
420
|
-
"ghcr.io/cyanheads/brapi-mcp-server:latest"
|
|
421
|
-
]
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
For Streamable HTTP, set the transport and start the server:
|
|
142
|
+
For Streamable HTTP:
|
|
428
143
|
|
|
429
144
|
```sh
|
|
430
145
|
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
|
|
431
146
|
# Server listens at http://localhost:3010/mcp
|
|
432
147
|
```
|
|
433
148
|
|
|
434
|
-
No
|
|
435
|
-
|
|
436
|
-
### Prerequisites
|
|
437
|
-
|
|
438
|
-
- [Bun v1.3.11](https://bun.sh/) or higher (or Node.js v22+).
|
|
439
|
-
- A BrAPI v2 endpoint to point at — the public [test server](https://test-server.brapi.org/brapi/v2) works out of the box; production servers typically need credentials.
|
|
440
|
-
- *(Optional)* [`@duckdb/node-api`](https://www.npmjs.com/package/@duckdb/node-api) — required only to enable the dataframe surface (`CANVAS_PROVIDER_TYPE=duckdb`). Listed as an optional peer dep so the bare install stays light. Linux/macOS/Windows × x64 plus Linux/macOS arm64 supported (Windows arm64 is unsupported by DuckDB upstream). Not available on Cloudflare Workers.
|
|
441
|
-
|
|
442
|
-
### Installation
|
|
443
|
-
|
|
444
|
-
1. **Clone the repository:**
|
|
445
|
-
|
|
446
|
-
```sh
|
|
447
|
-
git clone https://github.com/cyanheads/brapi-mcp-server.git
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
2. **Navigate into the directory:**
|
|
451
|
-
|
|
452
|
-
```sh
|
|
453
|
-
cd brapi-mcp-server
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
3. **Install dependencies:**
|
|
457
|
-
|
|
458
|
-
```sh
|
|
459
|
-
bun install
|
|
460
|
-
```
|
|
149
|
+
No env vars are required — the six built-in aliases (`bti-cassava`, `bti-sweetpotato`, `bti-breedbase-demo`, `t3-wheat`, `t3-oat`, `t3-barley`) resolve out-of-the-box, and agents can connect to any other BrAPI v2 URL at runtime via `brapi_connect`. **For credentialed servers, prefer env vars over agent input** so passwords / tokens / API keys stay out of the LLM context — see [Per-alias credentials](#per-alias-credentials).
|
|
461
150
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
```sh
|
|
465
|
-
cp .env.example .env
|
|
466
|
-
# edit .env and set required vars
|
|
467
|
-
```
|
|
151
|
+
**Prerequisites:** [Bun v1.3.11+](https://bun.sh/) or Node.js v22+. *(Optional)* [`@duckdb/node-api`](https://www.npmjs.com/package/@duckdb/node-api) for the dataframe surface — Linux/macOS/Windows × x64 plus Linux/macOS arm64 (no Windows arm64; no Cloudflare Workers).
|
|
468
152
|
|
|
469
153
|
---
|
|
470
154
|
|
|
471
155
|
## Configuration
|
|
472
156
|
|
|
473
|
-
Every variable is optional
|
|
157
|
+
Every variable is optional.
|
|
474
158
|
|
|
475
159
|
| Variable | Description | Default |
|
|
476
160
|
|:---------|:------------|:--------|
|
|
477
|
-
| `BRAPI_DEFAULT_BASE_URL` | Default BrAPI v2 base URL
|
|
478
|
-
| `BRAPI_DEFAULT_USERNAME` |
|
|
479
|
-
| `
|
|
480
|
-
| `
|
|
481
|
-
| `
|
|
482
|
-
| `
|
|
483
|
-
| `
|
|
484
|
-
| `
|
|
485
|
-
| `BRAPI_MAX_CONCURRENT_REQUESTS` | Per-connection concurrency cap for parallel upstream fan-out. | `4` |
|
|
486
|
-
| `BRAPI_RETRY_MAX_ATTEMPTS` | Max retries on 429/5xx before surfacing the error. | `3` |
|
|
487
|
-
| `BRAPI_RETRY_BASE_DELAY_MS` | Base delay for exponential backoff between retries. | `500` |
|
|
161
|
+
| `BRAPI_DEFAULT_BASE_URL` | Default BrAPI v2 base URL (e.g. `https://test-server.brapi.org/brapi/v2`). | — |
|
|
162
|
+
| `BRAPI_DEFAULT_USERNAME` / `_PASSWORD` | SGN session-token auth for the default connection. | — |
|
|
163
|
+
| `BRAPI_DEFAULT_OAUTH_CLIENT_ID` / `_OAUTH_CLIENT_SECRET` | OAuth2 client-credentials for the default connection. | — |
|
|
164
|
+
| `BRAPI_DEFAULT_API_KEY` / `_API_KEY_HEADER` | Static API key for the default connection. | header `Authorization` |
|
|
165
|
+
| `BRAPI_BUILTIN_ALIASES_DISABLED` | Comma-separated alias names (case-insensitive) to remove from the built-in registry. | — |
|
|
166
|
+
| `BRAPI_LOAD_LIMIT` | In-context row cap before `find_*` spills to `DatasetStore`. | `200` |
|
|
167
|
+
| `BRAPI_MAX_CONCURRENT_REQUESTS` | Per-connection concurrency cap. | `4` |
|
|
168
|
+
| `BRAPI_RETRY_MAX_ATTEMPTS` / `BRAPI_RETRY_BASE_DELAY_MS` | Retry policy for 429/5xx with exponential backoff. | `3` / `500` |
|
|
488
169
|
| `BRAPI_REQUEST_TIMEOUT_MS` | Per-request HTTP timeout. | `30000` |
|
|
489
|
-
| `BRAPI_SEARCH_POLL_TIMEOUT_MS`
|
|
490
|
-
| `
|
|
491
|
-
| `
|
|
492
|
-
| `
|
|
493
|
-
| `
|
|
494
|
-
| `
|
|
495
|
-
| `
|
|
496
|
-
| `
|
|
497
|
-
| `
|
|
498
|
-
| `
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
| `MCP_TRANSPORT_TYPE` | Transport: `stdio` or `http`. | `stdio` |
|
|
502
|
-
| `MCP_HTTP_PORT` | Port for HTTP server. | `3010` |
|
|
503
|
-
| `MCP_AUTH_MODE` | Auth mode: `none`, `jwt`, or `oauth`. | `none` |
|
|
504
|
-
| `MCP_LOG_LEVEL` | Log level (RFC 5424). | `info` |
|
|
505
|
-
| `STORAGE_PROVIDER_TYPE` | Storage backend. | `in-memory` |
|
|
506
|
-
| `OTEL_ENABLED` | Enable OpenTelemetry. | `false` |
|
|
507
|
-
|
|
508
|
-
Per-alias overrides follow the `BRAPI_<ALIAS>_*` pattern — see [Per-alias credentials](#per-alias-credentials).
|
|
509
|
-
|
|
510
|
-
See [`.env.example`](./.env.example) for the full list of optional overrides.
|
|
170
|
+
| `BRAPI_SEARCH_POLL_TIMEOUT_MS` / `_INTERVAL_MS` | Async `/search` polling budget + interval. | `60000` / `1000` |
|
|
171
|
+
| `BRAPI_DATASET_TTL_SECONDS` / `BRAPI_DATASET_STORE_DIR` | TTL for spilled datasets + filesystem path when filesystem storage is active. | `86400` / — |
|
|
172
|
+
| `BRAPI_REFERENCE_CACHE_TTL_SECONDS` | TTL for programs / trials / locations / crops cache. | `3600` |
|
|
173
|
+
| `BRAPI_ALLOW_PRIVATE_IPS` | Allow RFC 1918 / loopback targets. Dev-only. | `false` |
|
|
174
|
+
| `BRAPI_ENABLE_WRITES` | Opt-in for `brapi_submit_observations` registration. | `false` |
|
|
175
|
+
| `BRAPI_GENOTYPE_CALLS_MAX_PULL` | Upstream row ceiling per `brapi_find_genotype_calls` invocation. Max 500,000. | `100000` |
|
|
176
|
+
| `CANVAS_PROVIDER_TYPE` | Framework `DataCanvas` switch — set to `duckdb` to enable the dataframe surface. | `none` |
|
|
177
|
+
| `BRAPI_CANVAS_ENABLED` / `BRAPI_CANVAS_MAX_ROWS` / `BRAPI_CANVAS_QUERY_TIMEOUT_MS` | Dataframe surface gate, response row cap, per-query timeout. | `true` / `10000` / `30000` |
|
|
178
|
+
| `MCP_TRANSPORT_TYPE` / `MCP_HTTP_PORT` | Transport (`stdio` \| `http`) + HTTP port. | `stdio` / `3010` |
|
|
179
|
+
| `MCP_AUTH_MODE` / `MCP_LOG_LEVEL` / `STORAGE_PROVIDER_TYPE` / `OTEL_ENABLED` | Auth mode (`none` \| `jwt` \| `oauth`), log level, storage backend, OpenTelemetry. | `none` / `info` / `in-memory` / `false` |
|
|
180
|
+
|
|
181
|
+
Per-alias overrides follow the `BRAPI_<ALIAS>_*` pattern — see [`.env.example`](./.env.example) for every override and inline comments.
|
|
511
182
|
|
|
512
183
|
### Per-alias credentials
|
|
513
184
|
|
|
514
|
-
`brapi_connect` resolves `baseUrl` and `auth` from env vars when the agent omits them
|
|
185
|
+
`brapi_connect` resolves `baseUrl` and `auth` from env vars when the agent omits them — credentials never enter the LLM context. Four layers of precedence:
|
|
515
186
|
|
|
516
187
|
1. **Explicit agent input** — always wins.
|
|
517
|
-
2. **Per-alias env vars** — `BRAPI_<ALIAS>_*`
|
|
518
|
-
3. **Built-in known-server registry** — see [Built-in aliases](#built-in-aliases)
|
|
519
|
-
4. **Default env vars** — `BRAPI_DEFAULT_*`, only
|
|
520
|
-
|
|
521
|
-
When the baseUrl is satisfied by a builtin, `BRAPI_DEFAULT_*` credentials are **not** layered on top — those belong to the default server, not whatever upstream the builtin happens to point at. Per-alias credentials still apply, since those were explicitly set for this alias.
|
|
188
|
+
2. **Per-alias env vars** — `BRAPI_<ALIAS>_*` (uppercased, hyphens → underscores: `my-server` → `BRAPI_MY_SERVER_*`).
|
|
189
|
+
3. **Built-in known-server registry** — see [Built-in aliases](#built-in-aliases).
|
|
190
|
+
4. **Default env vars** — `BRAPI_DEFAULT_*`, only when the alias differs from `default`. Not layered on top of a built-in URL — defaults belong to the default server.
|
|
522
191
|
|
|
523
192
|
Each alias carries **one** credential family — auth mode is derived from which fields are set:
|
|
524
193
|
|
|
@@ -530,75 +199,58 @@ Each alias carries **one** credential family — auth mode is derived from which
|
|
|
530
199
|
| `_OAUTH_CLIENT_ID` + `_OAUTH_CLIENT_SECRET` (+ optional `_OAUTH_TOKEN_URL`) | `oauth2` |
|
|
531
200
|
| _(none set)_ | `none` |
|
|
532
201
|
|
|
533
|
-
Mixing families within
|
|
202
|
+
Mixing families within an alias raises a `ValidationError`.
|
|
534
203
|
|
|
535
204
|
```sh
|
|
536
|
-
# .env —
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
205
|
+
# .env — attach write credentials to the built-in 'bti-cassava' alias
|
|
206
|
+
BRAPI_BTI_CASSAVA_USERNAME=alice
|
|
207
|
+
BRAPI_BTI_CASSAVA_PASSWORD=...
|
|
208
|
+
# (BASE_URL omitted — built-in registry covers it)
|
|
540
209
|
|
|
541
|
-
#
|
|
210
|
+
# Static API key as alias 'prod'
|
|
542
211
|
BRAPI_PROD_BASE_URL=https://my-brapi.example.com/brapi/v2
|
|
543
212
|
BRAPI_PROD_API_KEY=...
|
|
544
213
|
BRAPI_PROD_API_KEY_HEADER=X-API-Key
|
|
545
|
-
|
|
546
|
-
# Register an OAuth2 client-credentials server as alias 'secure'
|
|
547
|
-
BRAPI_SECURE_BASE_URL=https://my-oauth-brapi.example.com/brapi/v2
|
|
548
|
-
BRAPI_SECURE_OAUTH_CLIENT_ID=...
|
|
549
|
-
BRAPI_SECURE_OAUTH_CLIENT_SECRET=...
|
|
550
|
-
BRAPI_SECURE_OAUTH_TOKEN_URL=https://auth.example.com/oauth/token
|
|
551
214
|
```
|
|
552
215
|
|
|
553
|
-
Then the agent calls `brapi_connect({ alias: 'cassava' })` — no `baseUrl`, no `auth`, no secrets in the prompt.
|
|
216
|
+
Then the agent calls `brapi_connect({ alias: 'bti-cassava' })` — no `baseUrl`, no `auth`, no secrets in the prompt.
|
|
554
217
|
|
|
555
218
|
### Built-in aliases
|
|
556
219
|
|
|
557
|
-
The server ships with a curated registry of public BrAPI v2 endpoints. Each
|
|
220
|
+
The server ships with a curated registry of public BrAPI v2 endpoints. Each resolves out-of-the-box; the orientation envelope surfaces license, citation, and homepage in its `attribution` block under [Creative Commons Attribution](https://creativecommons.org/licenses/by/4.0/).
|
|
558
221
|
|
|
559
222
|
| Alias | Upstream | Hosted by | Crop | Notes |
|
|
560
223
|
|:------|:---------|:----------|:-----|:------|
|
|
561
|
-
| `cassava` | [cassavabase.org](https://cassavabase.org/) | Boyce Thompson Institute | Cassava | NextGen Cassava
|
|
562
|
-
| `sweetpotato` | [sweetpotatobase.org](https://sweetpotatobase.org/) | Boyce Thompson Institute | Sweet potato | |
|
|
563
|
-
| `
|
|
564
|
-
| `
|
|
224
|
+
| `bti-cassava` | [cassavabase.org](https://cassavabase.org/) | Boyce Thompson Institute | Cassava | NextGen Cassava |
|
|
225
|
+
| `bti-sweetpotato` | [sweetpotatobase.org](https://sweetpotatobase.org/) | Boyce Thompson Institute | Sweet potato | |
|
|
226
|
+
| `bti-breedbase-demo` | [breedbase.org](https://breedbase.org/) | Boyce Thompson Institute | _Demo_ | Sample data only — onboarding + tests. |
|
|
227
|
+
| `t3-wheat` | [wheat.triticeaetoolbox.org](https://wheat.triticeaetoolbox.org/) | Triticeae Toolbox (T3) | Wheat | Wheat CAP / IWYP. |
|
|
228
|
+
| `t3-oat` | [oat.triticeaetoolbox.org](https://oat.triticeaetoolbox.org/) | Triticeae Toolbox (T3) | Oat | Global Oat Genetics Database. |
|
|
229
|
+
| `t3-barley` | [barley.triticeaetoolbox.org](https://barley.triticeaetoolbox.org/) | Triticeae Toolbox (T3) | Barley | T-CAP / US Wheat & Barley Scab Initiative. |
|
|
565
230
|
|
|
566
|
-
|
|
231
|
+
Set `BRAPI_<ALIAS>_BASE_URL` to repoint at a staging mirror or fork (env wins over the built-in URL — hyphens in the alias become underscores in the env var, so `t3-wheat` → `BRAPI_T3_WHEAT_BASE_URL`). Set `BRAPI_<ALIAS>_USERNAME` etc. to attach credentials on top of the built-in URL — each Breedbase instance has its own user table, so write access requires separate registration on each upstream. Use `BRAPI_BUILTIN_ALIASES_DISABLED=bti-cassava,t3-wheat` to strip specific entries.
|
|
567
232
|
|
|
568
|
-
**
|
|
569
|
-
|
|
570
|
-
**Citation:** all four shipped builtins reference the same foundational paper — Morales et al. 2022, _"Breedbase: a digital ecosystem for modern plant breeding."_ G3 12(7): jkac078. [doi:10.1093/g3journal/jkac078](https://doi.org/10.1093/g3journal/jkac078).
|
|
233
|
+
**Citation:** all six built-ins reference Morales et al. 2022, _"Breedbase: a digital ecosystem for modern plant breeding."_ G3 12(7): jkac078. [doi:10.1093/g3journal/jkac078](https://doi.org/10.1093/g3journal/jkac078).
|
|
571
234
|
|
|
572
235
|
---
|
|
573
236
|
|
|
574
237
|
## Running the server
|
|
575
238
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
bun run start:stdio
|
|
592
|
-
bun run start:http
|
|
593
|
-
```
|
|
594
|
-
|
|
595
|
-
- **Run checks and tests:**
|
|
596
|
-
|
|
597
|
-
```sh
|
|
598
|
-
bun run devcheck # Lint, format, typecheck, security, changelog sync
|
|
599
|
-
bun run test # Vitest suite
|
|
600
|
-
bun run lint:mcp # Validate MCP definitions against spec
|
|
601
|
-
```
|
|
239
|
+
```sh
|
|
240
|
+
# Hot-reload dev (Bun runs TS directly)
|
|
241
|
+
bun --watch src/index.ts
|
|
242
|
+
|
|
243
|
+
# Production
|
|
244
|
+
bun run rebuild
|
|
245
|
+
bun run start # transport via MCP_TRANSPORT_TYPE (stdio default)
|
|
246
|
+
bun run start:stdio # or pin explicitly
|
|
247
|
+
bun run start:http
|
|
248
|
+
|
|
249
|
+
# Checks
|
|
250
|
+
bun run devcheck # lint + format + typecheck + security + changelog sync
|
|
251
|
+
bun run test # Vitest
|
|
252
|
+
bun run lint:mcp # validate MCP definitions
|
|
253
|
+
```
|
|
602
254
|
|
|
603
255
|
### Docker
|
|
604
256
|
|
|
@@ -607,66 +259,43 @@ docker build -t brapi-mcp-server .
|
|
|
607
259
|
docker run --rm -p 3010:3010 brapi-mcp-server
|
|
608
260
|
```
|
|
609
261
|
|
|
610
|
-
|
|
262
|
+
Defaults to HTTP transport, stateless session mode, logs to `/var/log/brapi-mcp-server`. OTel peer deps are installed by default — `--build-arg OTEL_ENABLED=false` to omit.
|
|
611
263
|
|
|
612
264
|
### Multi-user HTTP deployments
|
|
613
265
|
|
|
614
|
-
`ctx.state`
|
|
266
|
+
`ctx.state` (where `ServerRegistry`, `DatasetStore`, and `CapabilityRegistry` live) is **scoped by `tenantId`, not session id**:
|
|
615
267
|
|
|
616
|
-
| Mode |
|
|
617
|
-
|
|
268
|
+
| Mode | `tenantId` |
|
|
269
|
+
|:-----|:-----------|
|
|
618
270
|
| `MCP_TRANSPORT_TYPE=stdio` (any auth) | `default` |
|
|
619
|
-
| `
|
|
620
|
-
| `
|
|
621
|
-
|
|
622
|
-
In HTTP + `none`, every client shares one bucket: connection aliases registered by one user (including the access token resolved from an SGN `/token` exchange) are reachable to any other connected user. For shared HTTP deployments, set `MCP_AUTH_MODE=jwt` (HS256, `MCP_AUTH_SECRET_KEY`) or `oauth` (JWKS, `OAUTH_ISSUER_URL` + `OAUTH_AUDIENCE`) so each caller's `tid` carves its own state.
|
|
623
|
-
|
|
624
|
-
---
|
|
271
|
+
| `http` + `MCP_AUTH_MODE=none` | `default` for every client — **shared bucket** |
|
|
272
|
+
| `http` + `jwt` or `oauth` | JWT `tid` claim, fail-closed if absent |
|
|
625
273
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
| Directory | Purpose |
|
|
629
|
-
|:----------|:--------|
|
|
630
|
-
| `src/index.ts` | `createApp()` entry point — registers 22 tools, 6 resources, 2 prompts, and inits the eight services. |
|
|
631
|
-
| `src/config` | Server-specific environment variable parsing with Zod. |
|
|
632
|
-
| `src/mcp-server/tools` | Tool definitions (`*.tool.ts`) and shared helpers (`orientation-envelope`, `find-helpers`, `connect-auth-schema`, `raw-routing-hints`). |
|
|
633
|
-
| `src/mcp-server/resources` | Resource definitions (`*.resource.ts`) — URI-addressable mirrors of curated tool data. |
|
|
634
|
-
| `src/mcp-server/prompts` | Prompt definitions (`*.prompt.ts`) — multi-step BrAPI workflow templates. |
|
|
635
|
-
| `src/services/brapi-client` | HTTP client with retry, concurrency capping, async-search polling, private-IP guard, and binary fetch. |
|
|
636
|
-
| `src/services/brapi-filters` | Static BrAPI v2.1 filter catalog. |
|
|
637
|
-
| `src/services/canvas-bridge` | Bridge over the framework's `DataCanvas` primitive — per-tenant default-workspace resolution, dataframe naming, provenance tracking. |
|
|
638
|
-
| `src/services/capability-registry` | Per-connection capability profile cache. |
|
|
639
|
-
| `src/services/dataset-store` | Tenant-scoped dataset handles for spilled `find_*` results. Auto-registers rows as dataframes when the canvas-bridge is enabled. |
|
|
640
|
-
| `src/services/ontology-resolver` | Free-text → ontology-candidate matcher powering `brapi_find_variables` ranking. |
|
|
641
|
-
| `src/services/reference-data-cache` | Cache for programs, trials, locations, crops. |
|
|
642
|
-
| `src/services/server-registry` | Alias → live BrAPI connection map with auth resolution. |
|
|
643
|
-
| `tests/` | Unit and integration tests mirroring `src/`. |
|
|
644
|
-
| `docs/design.md` | End-to-end surface design (current + planned tools). |
|
|
274
|
+
For shared HTTP deployments, set `MCP_AUTH_MODE=jwt` (HS256, `MCP_AUTH_SECRET_KEY`) or `oauth` (JWKS, `OAUTH_ISSUER_URL` + `OAUTH_AUDIENCE`) so each caller's `tid` carves its own state. Otherwise registered aliases — including SGN-exchanged bearer tokens — leak across users.
|
|
645
275
|
|
|
646
276
|
---
|
|
647
277
|
|
|
648
|
-
## Development
|
|
278
|
+
## Development
|
|
649
279
|
|
|
650
|
-
See [`CLAUDE.md`](./CLAUDE.md) for
|
|
280
|
+
See [`CLAUDE.md`](./CLAUDE.md) for full architectural rules. Short version:
|
|
651
281
|
|
|
652
282
|
- Handlers throw, framework catches — no `try/catch` in tool logic
|
|
653
|
-
- Use `ctx.log` for
|
|
283
|
+
- Use `ctx.log` for logging, `ctx.state` for storage — no `console`, no direct persistence
|
|
654
284
|
- Register new tools in the `tools` array of `createApp()` in `src/index.ts`
|
|
655
|
-
- Wrap upstream calls: validate raw → normalize
|
|
656
|
-
|
|
657
|
-
---
|
|
658
|
-
|
|
659
|
-
## Contributing
|
|
660
|
-
|
|
661
|
-
Issues and pull requests are welcome. Run checks and tests before submitting:
|
|
285
|
+
- Wrap upstream calls: validate raw → normalize → return output schema; never fabricate missing fields
|
|
662
286
|
|
|
663
287
|
```sh
|
|
664
|
-
|
|
665
|
-
|
|
288
|
+
git clone https://github.com/cyanheads/brapi-mcp-server.git
|
|
289
|
+
cd brapi-mcp-server
|
|
290
|
+
bun install
|
|
291
|
+
cp .env.example .env # edit if you need credentials
|
|
292
|
+
bun run devcheck && bun run test
|
|
666
293
|
```
|
|
667
294
|
|
|
295
|
+
PRs welcome.
|
|
296
|
+
|
|
668
297
|
---
|
|
669
298
|
|
|
670
299
|
## License
|
|
671
300
|
|
|
672
|
-
Apache-2.0 — see [LICENSE](LICENSE)
|
|
301
|
+
Apache-2.0 — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Built-in alias rename — source-prefixed handles (`bti-*`, `t3-*`); adds T3/Oat and T3/Barley; fixes hyphenated-builtin env shadow."
|
|
3
|
+
breaking: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.4.13 — 2026-05-04
|
|
7
|
+
|
|
8
|
+
Source-prefixed alias rename across the built-in registry, plus two new T3 small-grains servers. Tool schemas refresh on next connect, so agents reading the current connect tool description pick up the new handles automatically. Operators with per-alias credential env vars (e.g. `BRAPI_CASSAVA_USERNAME`) need to rename to the new prefix (`BRAPI_BTI_CASSAVA_USERNAME`) — see Migration below.
|
|
9
|
+
|
|
10
|
+
## Added
|
|
11
|
+
|
|
12
|
+
- **`t3-oat` and `t3-barley` built-ins** — Triticeae Toolbox (T3) hosts three sibling Breedbase instances at `*.triticeaetoolbox.org`; only wheat shipped before. Live probes confirm anonymous reads return real data: T3/Oat advertises 2,564 studies / 59,780 germplasm / 288 variables, T3/Barley 1,574 / 63,859 / 208. Same Breedbase platform underneath, same CC-BY posture, same Morales et al. 2022 citation as the existing entries.
|
|
13
|
+
|
|
14
|
+
## Changed
|
|
15
|
+
|
|
16
|
+
- **Built-in aliases renamed to source-prefixed handles** so the hosting source is visible at the call site:
|
|
17
|
+
|
|
18
|
+
| Before | After |
|
|
19
|
+
|:-------|:------|
|
|
20
|
+
| `cassava` | `bti-cassava` |
|
|
21
|
+
| `sweetpotato` | `bti-sweetpotato` |
|
|
22
|
+
| `wheat` | `t3-wheat` |
|
|
23
|
+
| `breedbase` | `bti-breedbase-demo` |
|
|
24
|
+
|
|
25
|
+
Tool input schema is unchanged (alias is still a free-form `z.string().regex(...)`), and the connect tool description lists current builtins dynamically — fresh agent sessions read the new handles and use them. Custom env-only aliases under the old short names (`cassava`, `sweetpotato`, `wheat`, `breedbase`) are now valid free-form names that resolve via `BRAPI_<ALIAS>_*` env vars only — they no longer shadow a built-in.
|
|
26
|
+
|
|
27
|
+
## Fixed
|
|
28
|
+
|
|
29
|
+
- **`discoverConfiguredAliases` reverse-maps env var keys against hyphenated builtins.** The regex extracted alias names from `BRAPI_<X>_BASE_URL` keys but couldn't tell whether an underscore in the captured group should map back to a hyphen, so an env var like `BRAPI_BTI_CASSAVA_BASE_URL` was reported as a separate `bti_cassava` alias instead of shadowing the built-in `bti-cassava`. Discovery now consults the registry's underscored-name map and uses the canonical hyphenated alias when one matches. `resolveConnectInput` was unaffected — it derives the env prefix from the alias the agent passed.
|
|
30
|
+
|
|
31
|
+
## Migration
|
|
32
|
+
|
|
33
|
+
Operators who attached per-alias credentials to a built-in via env vars need to rename:
|
|
34
|
+
|
|
35
|
+
| Old env var | New env var |
|
|
36
|
+
|:------------|:------------|
|
|
37
|
+
| `BRAPI_CASSAVA_*` | `BRAPI_BTI_CASSAVA_*` |
|
|
38
|
+
| `BRAPI_SWEETPOTATO_*` | `BRAPI_BTI_SWEETPOTATO_*` |
|
|
39
|
+
| `BRAPI_WHEAT_*` | `BRAPI_T3_WHEAT_*` |
|
|
40
|
+
| `BRAPI_BREEDBASE_*` | `BRAPI_BTI_BREEDBASE_DEMO_*` |
|
|
41
|
+
|
|
42
|
+
`BRAPI_BUILTIN_ALIASES_DISABLED` values follow the same rename. Hardcoded `alias: 'cassava'` (etc.) in agent system prompts or saved scripts also need updating to the new handles.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alias-credentials.d.ts","sourceRoot":"","sources":["../../src/config/alias-credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAEjF;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAiBD,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,oFAAoF;AACpF,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,gBAAgB,CAQlB;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,MAAM,GACZ,WAAW,GAAG,SAAS,CAwCzB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;CAAE,EACvE,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,oBAAoB,CAwBtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,KAAK,GAAG,SAAS,CAAC;CAC3B;AAID;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"alias-credentials.d.ts","sourceRoot":"","sources":["../../src/config/alias-credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAEjF;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAiBD,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,oFAAoF;AACpF,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,gBAAgB,CAQlB;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,MAAM,GACZ,WAAW,GAAG,SAAS,CAwCzB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;CAAE,EACvE,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,oBAAoB,CAwBtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,KAAK,GAAG,SAAS,CAAC;CAC3B;AAID;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,eAAe,EAAE,CA2CjG;AAaD;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAmB9E"}
|
|
@@ -130,12 +130,19 @@ const ALIAS_BASE_URL_PATTERN = /^BRAPI_([A-Z0-9_]+)_BASE_URL$/;
|
|
|
130
130
|
export function discoverConfiguredAliases(env = process.env) {
|
|
131
131
|
const result = [];
|
|
132
132
|
const seen = new Set();
|
|
133
|
+
const builtins = listBuiltinAliases(env);
|
|
134
|
+
// Reverse-map for hyphen → underscore env-var translation: a builtin named
|
|
135
|
+
// `bti-cassava` exposes BRAPI_BTI_CASSAVA_*, but the regex below only sees
|
|
136
|
+
// the underscored form. Without this map, an env var that shadows a
|
|
137
|
+
// hyphenated builtin would be reported as a separate `bti_cassava` alias.
|
|
138
|
+
const builtinByUnderscoredName = new Map(builtins.map((b) => [b.alias.replace(/-/g, '_'), b]));
|
|
133
139
|
for (const [key, value] of Object.entries(env)) {
|
|
134
140
|
const match = key.match(ALIAS_BASE_URL_PATTERN);
|
|
135
141
|
const captured = match?.[1];
|
|
136
142
|
if (!captured || !value)
|
|
137
143
|
continue;
|
|
138
|
-
const
|
|
144
|
+
const lowerCaptured = captured.toLowerCase();
|
|
145
|
+
const alias = builtinByUnderscoredName.get(lowerCaptured)?.alias ?? lowerCaptured;
|
|
139
146
|
const creds = readAliasCredentials(alias, env);
|
|
140
147
|
result.push({
|
|
141
148
|
alias,
|
|
@@ -145,7 +152,7 @@ export function discoverConfiguredAliases(env = process.env) {
|
|
|
145
152
|
});
|
|
146
153
|
seen.add(alias);
|
|
147
154
|
}
|
|
148
|
-
for (const builtin of
|
|
155
|
+
for (const builtin of builtins) {
|
|
149
156
|
if (seen.has(builtin.alias))
|
|
150
157
|
continue;
|
|
151
158
|
const creds = readAliasCredentials(builtin.alias, env);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alias-credentials.js","sourceRoot":"","sources":["../../src/config/alias-credentials.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"alias-credentials.js","sourceRoot":"","sources":["../../src/config/alias-credentials.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtin-aliases.d.ts","sourceRoot":"","sources":["../../src/config/builtin-aliases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"builtin-aliases.d.ts","sourceRoot":"","sources":["../../src/config/builtin-aliases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,YAAY,CAwDtD,CAAC;AAmBH;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,YAAY,GAAG,SAAS,CAK1B;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,aAAa,CAAC,YAAY,CAAC,CAI7B"}
|
|
@@ -27,7 +27,7 @@ const BREEDBASE_CITATION = 'Morales et al. 2022. "Breedbase: a digital ecosystem
|
|
|
27
27
|
*/
|
|
28
28
|
export const BUILTIN_ALIASES = Object.freeze([
|
|
29
29
|
Object.freeze({
|
|
30
|
-
alias: 'cassava',
|
|
30
|
+
alias: 'bti-cassava',
|
|
31
31
|
baseUrl: 'https://cassavabase.org/brapi/v2',
|
|
32
32
|
homepage: 'https://cassavabase.org/',
|
|
33
33
|
organizationName: 'Boyce Thompson Institute',
|
|
@@ -36,7 +36,7 @@ export const BUILTIN_ALIASES = Object.freeze([
|
|
|
36
36
|
citation: BREEDBASE_CITATION,
|
|
37
37
|
}),
|
|
38
38
|
Object.freeze({
|
|
39
|
-
alias: 'sweetpotato',
|
|
39
|
+
alias: 'bti-sweetpotato',
|
|
40
40
|
baseUrl: 'https://sweetpotatobase.org/brapi/v2',
|
|
41
41
|
homepage: 'https://sweetpotatobase.org/',
|
|
42
42
|
organizationName: 'Boyce Thompson Institute',
|
|
@@ -45,7 +45,7 @@ export const BUILTIN_ALIASES = Object.freeze([
|
|
|
45
45
|
citation: BREEDBASE_CITATION,
|
|
46
46
|
}),
|
|
47
47
|
Object.freeze({
|
|
48
|
-
alias: 'wheat',
|
|
48
|
+
alias: 't3-wheat',
|
|
49
49
|
baseUrl: 'https://wheat.triticeaetoolbox.org/brapi/v2',
|
|
50
50
|
homepage: 'https://wheat.triticeaetoolbox.org/',
|
|
51
51
|
organizationName: 'Triticeae Toolbox (T3)',
|
|
@@ -54,7 +54,25 @@ export const BUILTIN_ALIASES = Object.freeze([
|
|
|
54
54
|
citation: BREEDBASE_CITATION,
|
|
55
55
|
}),
|
|
56
56
|
Object.freeze({
|
|
57
|
-
alias: '
|
|
57
|
+
alias: 't3-oat',
|
|
58
|
+
baseUrl: 'https://oat.triticeaetoolbox.org/brapi/v2',
|
|
59
|
+
homepage: 'https://oat.triticeaetoolbox.org/',
|
|
60
|
+
organizationName: 'Triticeae Toolbox (T3)',
|
|
61
|
+
cropFocus: 'Oat',
|
|
62
|
+
license: 'CC-BY',
|
|
63
|
+
citation: BREEDBASE_CITATION,
|
|
64
|
+
}),
|
|
65
|
+
Object.freeze({
|
|
66
|
+
alias: 't3-barley',
|
|
67
|
+
baseUrl: 'https://barley.triticeaetoolbox.org/brapi/v2',
|
|
68
|
+
homepage: 'https://barley.triticeaetoolbox.org/',
|
|
69
|
+
organizationName: 'Triticeae Toolbox (T3)',
|
|
70
|
+
cropFocus: 'Barley',
|
|
71
|
+
license: 'CC-BY',
|
|
72
|
+
citation: BREEDBASE_CITATION,
|
|
73
|
+
}),
|
|
74
|
+
Object.freeze({
|
|
75
|
+
alias: 'bti-breedbase-demo',
|
|
58
76
|
baseUrl: 'https://breedbase.org/brapi/v2',
|
|
59
77
|
homepage: 'https://breedbase.org/',
|
|
60
78
|
organizationName: 'Boyce Thompson Institute',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtin-aliases.js","sourceRoot":"","sources":["../../src/config/builtin-aliases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,kBAAkB,GACtB,+IAA+I,CAAC;AAalJ;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAgC,MAAM,CAAC,MAAM,CAAC;IACxE,MAAM,CAAC,MAAM,CAAC;QACZ,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"builtin-aliases.js","sourceRoot":"","sources":["../../src/config/builtin-aliases.ts"],"names":[],"mappings":"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"}
|
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.
|
|
4
|
+
"version": "0.4.13",
|
|
5
5
|
"description": "BrAPI v2.1 MCP server — studies, germplasm, observations, genotypes, images, and pedigrees.",
|
|
6
6
|
"author": "Casey Hand @cyanheads (https://github.com/cyanheads/brapi-mcp-server#readme)",
|
|
7
7
|
"type": "module",
|
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.4.
|
|
9
|
+
"version": "0.4.13",
|
|
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.4.
|
|
16
|
+
"version": "0.4.13",
|
|
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.4.
|
|
52
|
+
"version": "0.4.13",
|
|
53
53
|
"packageArguments": [
|
|
54
54
|
{ "type": "positional", "value": "run" },
|
|
55
55
|
{ "type": "positional", "value": "start:http" }
|