@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 CHANGED
@@ -1,7 +1,7 @@
1
1
  # Agent Protocol
2
2
 
3
3
  **Server:** brapi-mcp-server
4
- **Version:** 0.4.11
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
- [![npm](https://img.shields.io/npm/v/@cyanheads/brapi-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/@cyanheads/brapi-mcp-server) [![Version](https://img.shields.io/badge/Version-0.4.12-blue.svg?style=flat-square)](./CHANGELOG.md) [![Framework](https://img.shields.io/badge/Built%20on-@cyanheads/mcp--ts--core-259?style=flat-square)](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.29.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/)
10
+ [![npm](https://img.shields.io/npm/v/@cyanheads/brapi-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/@cyanheads/brapi-mcp-server) [![Version](https://img.shields.io/badge/Version-0.4.13-blue.svg?style=flat-square)](./CHANGELOG.md) [![Framework](https://img.shields.io/badge/Built%20on-@cyanheads/mcp--ts--core-259?style=flat-square)](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.29.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/)
11
11
 
12
12
  [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![TypeScript](https://img.shields.io/badge/TypeScript-^6.0.3-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-v1.3.11-blueviolet.svg?style=flat-square)](https://bun.sh/) [![Status](https://img.shields.io/badge/Status-Beta-yellow.svg?style=flat-square)](./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/analytical workspace over spilled rows, an additive write surface for observations, and raw passthrough escape hatches.
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 Name | Description |
25
- |:----------|:------------|
26
- | `brapi_connect` | Connect to a BrAPI v2 server, authenticate, cache the capability profile, and return the full orientation envelope inline. |
27
- | `brapi_server_info` | Return the full orientation envelope for a registered BrAPI connection — identity, capabilities, content counts, notes. |
28
- | `brapi_describe_filters` | List valid filter names for a BrAPI endpoint — powers dynamic discovery for `extraFilters` on any `find_*` tool. |
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 Name | Description |
33
- |:----------|:------------|
34
- | `brapi_find_studies` | Locate studies matching crop / trial type / season / location / program filters, with per-field distributions and dataset spillover. |
35
- | `brapi_get_study` | Fetch a single study with program / trial / location FKs resolved and companion counts for observations, units, and variables. |
36
- | `brapi_find_germplasm` | Find germplasm by name, synonym, accession, crop, or free-text query, with distributions and dataset spillover. |
37
- | `brapi_get_germplasm` | Fetch a single germplasm with attributes, direct parents, and companion counts (studies, parents, direct descendants). |
38
- | `brapi_walk_pedigree` | Walk germplasm ancestry or descendancy as a deduplicated DAG (BFS) with cycle detection, depth limits, and traversal stats. |
39
- | `brapi_find_variables` | Find observation variables (traits) by name, class, ontology, or free-text; ranked client-side via `OntologyResolver` when `text` is supplied. |
40
- | `brapi_find_observations` | Pull observation records filtered by study, germplasm, variable, season, or observation unit. Dataset spillover. |
41
- | `brapi_find_images` | Filter images by observation unit / study / ontology term / MIME type metadata only, bytes via `brapi_get_image`. |
42
- | `brapi_get_image` | Fetch image bytes for up to 5 imageDbIds inline as `type: image` content blocks. Prefers `/images/{id}/imagecontent`, falls back to `imageURL`. |
43
- | `brapi_find_locations` | Find research stations / field sites by country / type / abbreviation, with optional client-side bounding-box filter. |
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 across a germplasm × variant set via async-search polling. Upstream pull bounded by deployment policy (`BRAPI_GENOTYPE_CALLS_MAX_PULL`, default 100k, max 500k); rows beyond `loadLimit` spill to DatasetStore. |
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 Name | Description |
50
- |:----------|:------------|
51
- | `brapi_manage_dataset` | Lifecycle for `find_*` spillover datasets — list, summary, load (paged rows with column projection), delete. |
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 Name | Description |
56
- |:----------|:------------|
57
- | `brapi_dataframe_query` | Run SELECT SQL across in-memory dataframes (DuckDB-backed). Spilled `find_*` datasets auto-register as `ds_<datasetId>` dataframes. Use `registerAs` to chain. Read-only — multi-statement, non-SELECT, file-reads, and exports are rejected. **Opt-in via `CANVAS_PROVIDER_TYPE=duckdb` + `BRAPI_CANVAS_ENABLED=true`** — omitted from `tools/list` otherwise. |
58
- | `brapi_dataframe_describe` | List dataframes with column schema, row counts, and originating-dataset provenance for `ds_*` entries. |
59
- | `brapi_dataframe_drop` | Drop a dataframe by name. Idempotent — `dropped: false` for unknown names. Underlying DatasetStore dataset is unaffected. |
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 Name | Description |
64
- |:----------|:------------|
65
- | `brapi_submit_observations` | Submit new (POST) or updated (PUT) observation rows for a study. Default `mode: preview` validates only; `mode: apply` elicits confirmation, fans POST + PUT in parallel, and reports the post-write count. Additive — no observation is destroyed. **Opt-in via `BRAPI_ENABLE_WRITES=true`** — omitted from `tools/list` otherwise. |
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 Name | Description |
70
- |:----------|:------------|
71
- | `brapi_raw_get` | Passthrough to any BrAPI `GET /{path}` the curated tools don't cover. Emits a routing nudge when a goal-shaped tool exists for the target. |
72
- | `brapi_raw_search` | Passthrough to any BrAPI `POST /search/{noun}` with async polling handled transparently. Same routing nudge pattern. |
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
- Six MCP resources mirror the curated tool surface for clients that prefer URI-addressable access. Tool-only clients lose nothing every resource has a corresponding tool path.
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
- All resources use the default connection. Multi-server workflows route through the tool surface where alias is an explicit input.
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
- Two prompt templates package multi-step BrAPI workflows so the agent can pick them off the shelf.
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?` | Exploratory-data-analysis playbook for a single study — orient, variables, coverage, missing data, outliers, pedigree side-quest, structured report. |
334
- | `brapi_meta_analysis` | `germplasmDbIds` (CSV), `traitName`, `alias?` | Cross-study meta-analysis playbook — trait resolution, study discovery, harmonization, per-germplasm × per-study summary, across-study summary, pedigree context. |
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
- ## Features
341
-
342
- Built on [`@cyanheads/mcp-ts-core`](https://www.npmjs.com/package/@cyanheads/mcp-ts-core):
343
-
344
- - Declarative tool, resource, and prompt definitions single file per primitive, framework handles registration and validation
345
- - Unified error handling handlers throw, framework catches, classifies, and formats
346
- - Pluggable auth: `none`, `jwt`, `oauth`
347
- - Swappable storage backends: `in-memory`, `filesystem`, `Supabase`, `Cloudflare KV/R2/D1`
348
- - Structured logging with optional OpenTelemetry tracing
349
- - STDIO and Streamable HTTP transports
350
-
351
- BrAPI-specific:
352
-
353
- - **Multi-server session** — `ServerRegistry` maps aliases to live BrAPI connections, so one agent session can span Breedbase, T3, and Sweetpotatobase in parallel
354
- - **Capability-aware calls** — `CapabilityRegistry` caches the `/serverinfo` profile per connection and guards every tool call against unsupported endpoints before they hit the wire
355
- - **Tolerant capability discovery** if `/serverinfo` is unavailable or sparse, discovery falls back to `/calls` and returns a partial orientation envelope with explicit notes
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 the following to your MCP client configuration file.
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
- Or with npx (no Bun required):
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
- ```json
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 environment variables are required for the public BrAPI test server agents can open connections at runtime via `brapi_connect`. **For credentialed servers, prefer env vars over agent input**: set `BRAPI_DEFAULT_*` for a default connection, or `BRAPI_<ALIAS>_*` per registered alias, so passwords / tokens / API keys stay out of the LLM context. See [Per-alias credentials](#per-alias-credentials).
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
- 4. **Configure environment:**
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 — agents can configure connections entirely at runtime via `brapi_connect`. Set the `BRAPI_DEFAULT_*` variables if you want a default connection without an explicit `brapi_connect` call.
157
+ Every variable is optional.
474
158
 
475
159
  | Variable | Description | Default |
476
160
  |:---------|:------------|:--------|
477
- | `BRAPI_DEFAULT_BASE_URL` | Default BrAPI v2 base URL including path prefix (e.g. `https://test-server.brapi.org/brapi/v2`). | — |
478
- | `BRAPI_DEFAULT_USERNAME` | Default SGN-family username for session-token auth. | — |
479
- | `BRAPI_DEFAULT_PASSWORD` | Default SGN-family password. | — |
480
- | `BRAPI_DEFAULT_OAUTH_CLIENT_ID` | Default OAuth2 client ID (e.g. CGIAR-family servers). | |
481
- | `BRAPI_DEFAULT_OAUTH_CLIENT_SECRET` | Default OAuth2 client secret. | — |
482
- | `BRAPI_DEFAULT_API_KEY` | Default static API key. | |
483
- | `BRAPI_DEFAULT_API_KEY_HEADER` | Header name carrying the static API key. | `Authorization` |
484
- | `BRAPI_LOAD_LIMIT` | In-context row cap before `find_*` tools spill to `DatasetStore`. | `200` |
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` | Total budget for async `/search/{noun}/{id}` polling. | `60000` |
490
- | `BRAPI_SEARCH_POLL_INTERVAL_MS` | Interval between async-search status checks. | `1000` |
491
- | `BRAPI_DATASET_TTL_SECONDS` | TTL for spilled datasets. | `86400` |
492
- | `BRAPI_DATASET_STORE_DIR` | Filesystem path for `DatasetStore` payloads when filesystem storage is active. | |
493
- | `BRAPI_REFERENCE_CACHE_TTL_SECONDS` | TTL for reference-data cache entries (programs, trials, locations, crops). | `3600` |
494
- | `BRAPI_ALLOW_PRIVATE_IPS` | Allow connecting to RFC 1918 / loopback targets. Dev-only. | `false` |
495
- | `BRAPI_ENABLE_WRITES` | Opt-in flag for the write surface (`brapi_submit_observations`). Off by default the tool is omitted from `tools/list` unless the operator opts in for this deployment. | `false` |
496
- | `BRAPI_GENOTYPE_CALLS_MAX_PULL` | Hard ceiling on rows pulled from the upstream BrAPI server in a single `brapi_find_genotype_calls` invocation. Bounds total page count per query — protects upstream from unbounded pagination loops. Maximum 500,000. | `100000` |
497
- | `CANVAS_PROVIDER_TYPE` | Framework-side switch for the `DataCanvas` primitive. Set to `duckdb` to enable the dataframe surface. Fails closed on Cloudflare Workers. | `none` |
498
- | `BRAPI_CANVAS_ENABLED` | Server-side gate for `brapi_dataframe_*` tools. Effective only when `CANVAS_PROVIDER_TYPE=duckdb`. | `true` |
499
- | `BRAPI_CANVAS_MAX_ROWS` | Hard cap on rows materialized into a `brapi_dataframe_query` response. Use `registerAs` to keep larger result sets in the workspace. | `10000` |
500
- | `BRAPI_CANVAS_QUERY_TIMEOUT_MS` | Per-query wall-clock timeout for `brapi_dataframe_query`. | `30000` |
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` switchset 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, so credentials never enter the LLM context. Four layers of precedence:
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>_*` where the alias name is uppercased and hyphens become underscores (`my-server` → `BRAPI_MY_SERVER_*`).
518
- 3. **Built-in known-server registry** — see [Built-in aliases](#built-in-aliases) below.
519
- 4. **Default env vars** — `BRAPI_DEFAULT_*`, only consulted when the alias differs from `default`.
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 a single alias raises a `ValidationError` naming the conflict.
202
+ Mixing families within an alias raises a `ValidationError`.
534
203
 
535
204
  ```sh
536
- # .env — register Cassavabase as alias 'cassava'
537
- BRAPI_CASSAVA_BASE_URL=https://cassavabase.org/brapi/v2
538
- BRAPI_CASSAVA_USERNAME=alice
539
- BRAPI_CASSAVA_PASSWORD=...
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
- # Register a static-API-key server as alias 'prod'
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 alias resolves out-of-the-box without any env vars call `brapi_connect({ alias: 'cassava' })` and the resolver fills in the URL. Each entry is published under [Creative Commons Attribution](https://creativecommons.org/licenses/by/4.0/); the orientation envelope surfaces license, citation, and homepage in its `attribution` block so agents can satisfy reuse terms automatically.
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 project |
562
- | `sweetpotato` | [sweetpotatobase.org](https://sweetpotatobase.org/) | Boyce Thompson Institute | Sweet potato | |
563
- | `wheat` | [wheat.triticeaetoolbox.org](https://wheat.triticeaetoolbox.org/) | Triticeae Toolbox (T3) | Wheat | |
564
- | `breedbase` | [breedbase.org](https://breedbase.org/) | Boyce Thompson Institute | _Demo_ | Sample data only — not production records. Useful for onboarding and tests. |
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
- **Override:** set `BRAPI_<ALIAS>_BASE_URL=...` to repoint an alias at a staging mirror or a fork env always wins over the builtin URL. Set `BRAPI_<ALIAS>_USERNAME=...` etc. to attach credentials on top of the builtin URL when you need write access (each Breedbase instance has its own user table separate registration on each upstream).
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
- **Opt-out:** `BRAPI_BUILTIN_ALIASES_DISABLED=cassava,wheat` (comma-separated, case-insensitive) removes specific aliases from resolution and discovery for deployments that prefer a stripped surface.
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
- ### Local development
577
-
578
- - **Hot-reload dev mode** (Bun runs TypeScript directly):
579
-
580
- ```sh
581
- MCP_TRANSPORT_TYPE=stdio bun --watch src/index.ts
582
- MCP_TRANSPORT_TYPE=http bun --watch src/index.ts
583
- ```
584
-
585
- - **Build and run the production version:**
586
-
587
- ```sh
588
- bun run rebuild
589
- bun run start # transport selected via MCP_TRANSPORT_TYPE (stdio default)
590
- # or pin the transport explicitly:
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
- The Dockerfile defaults to HTTP transport, stateless session mode, and logs to `/var/log/brapi-mcp-server`. OpenTelemetry peer dependencies are installed by default — build with `--build-arg OTEL_ENABLED=false` to omit them.
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` where `ServerRegistry` (connection aliases + resolved bearer tokens), `DatasetStore` (spilled `find_*` rows), and `CapabilityRegistry` (cached `/serverinfo` profiles) live — is **scoped by `tenantId`, not by MCP session id**. Tenant resolution:
266
+ `ctx.state` (where `ServerRegistry`, `DatasetStore`, and `CapabilityRegistry` live) is **scoped by `tenantId`, not session id**:
615
267
 
616
- | Mode | Resolved `tenantId` |
617
- |:-----|:--------------------|
268
+ | Mode | `tenantId` |
269
+ |:-----|:-----------|
618
270
  | `MCP_TRANSPORT_TYPE=stdio` (any auth) | `default` |
619
- | `MCP_TRANSPORT_TYPE=http` + `MCP_AUTH_MODE=none` (default) | `default` for every connected client |
620
- | `MCP_TRANSPORT_TYPE=http` + `MCP_AUTH_MODE=jwt` or `oauth` | JWT `tid` claim, fail-closed if absent |
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
- ## Project structure
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 guide
278
+ ## Development
649
279
 
650
- See [`CLAUDE.md`](./CLAUDE.md) for development guidelines and architectural rules. The short version:
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 request-scoped logging, `ctx.state` for tenant-scoped storage
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 to domain type → return output schema; never fabricate missing fields
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
- bun run devcheck
665
- bun run test
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) for details.
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,CAoCjG;AAaD;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAmB9E"}
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 alias = captured.toLowerCase();
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 listBuiltinAliases(env)) {
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":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAmBnF,MAAM,cAAc,GAA6D;IAC/E,CAAC,SAAS,EAAE,UAAU,CAAC;IACvB,CAAC,UAAU,EAAE,UAAU,CAAC;IACxB,CAAC,UAAU,EAAE,UAAU,CAAC;IACxB,CAAC,QAAQ,EAAE,SAAS,CAAC;IACrB,CAAC,cAAc,EAAE,gBAAgB,CAAC;IAClC,CAAC,aAAa,EAAE,cAAc,CAAC;IAC/B,CAAC,eAAe,EAAE,iBAAiB,CAAC;IACpC,CAAC,mBAAmB,EAAE,qBAAqB,CAAC;IAC5C,CAAC,eAAe,EAAE,iBAAiB,CAAC;CACrC,CAAC;AAEF,MAAM,aAAa,GAAG,SAAS,CAAC;AAChC,MAAM,SAAS,GAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAEhD,iFAAiF;AACjF,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,SAAS,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC;AAC5D,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,oBAAoB,CAClC,KAAa,EACb,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;QACxC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;YAAE,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;IACjE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,KAAuB,EACvB,KAAa;IAEb,MAAM,QAAQ,GAA8C;QAC1D,EAAE,IAAI,EAAE,yBAAyB,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE;QAClF,EAAE,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE;QAC9D,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE;QACrD;YACE,IAAI,EAAE,0CAA0C;YAChD,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,iBAAiB,CAAC;SAC5D;KACF,CAAC;IACF,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACrE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACjC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,eAAe,CACnB,oCAAoC,KAAK,wCAAwC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,kDAAkD,EACrJ,EAAE,KAAK,EAAE,OAAO,EAAE,CACnB,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC7E,CAAC;IACD,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACtB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC;IACtD,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO,KAAK,CAAC,YAAY;YACvB,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,YAAY,EAAE;YAC3E,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;IAChD,CAAC;IACD,IAAI,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;QACnD,OAAO,KAAK,CAAC,aAAa;YACxB,CAAC,CAAC;gBACE,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK,CAAC,aAAa;gBAC7B,YAAY,EAAE,KAAK,CAAC,iBAAiB;gBACrC,QAAQ,EAAE,KAAK,CAAC,aAAa;aAC9B;YACH,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,aAAa,EAAE,YAAY,EAAE,KAAK,CAAC,iBAAiB,EAAE,CAAC;IAC/F,CAAC;IACD,OAAO;AACT,CAAC;AAOD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,KAAuE,EACvE,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,UAAU,GAAG,oBAAoB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,YAAY,GAChB,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,oBAAoB,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;IAElF,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACjG,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,UAAU,CAAC,OAAO,IAAI,OAAO,EAAE,OAAO,IAAI,YAAY,CAAC,OAAO,CAAC;IAChG,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,eAAe,CACnB,4DAA4D,cAAc,CAAC,KAAK,CAAC,WAAW,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,cAAc,CAAC,aAAa,CAAC,UAAU,GAAG,EAC5K,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAED,MAAM,wBAAwB,GAAG,CAAC,OAAO,IAAI,KAAK,KAAK,aAAa,CAAC;IACrE,MAAM,IAAI,GACR,KAAK,CAAC,IAAI;QACV,yBAAyB,CAAC,UAAU,EAAE,KAAK,CAAC;QAC5C,CAAC,wBAAwB;YACvB,CAAC,CAAC,yBAAyB,CAAC,YAAY,EAAE,aAAa,CAAC;YACxD,CAAC,CAAC,SAAS,CAAC;QACd,SAAS,CAAC;IAEZ,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC;AAgBD,MAAM,sBAAsB,GAAG,+BAA+B,CAAC;AAE/D;;;;;;;;;GASG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC5E,MAAM,MAAM,GAAsB,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACzC,2EAA2E;IAC3E,2EAA2E;IAC3E,oEAAoE;IACpE,0EAA0E;IAC1E,MAAM,wBAAwB,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAE/F,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK;YAAE,SAAS;QAClC,MAAM,aAAa,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,wBAAwB,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,KAAK,IAAI,aAAa,CAAC;QAClF,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC;YACV,KAAK;YACL,QAAQ,EAAE,sBAAsB,CAAC,KAAK,EAAE,KAAK,CAAC;YAC9C,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,SAAS;QACtC,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACvD,MAAM,CAAC,IAAI,CAAC;YACV,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,QAAQ,EAAE,sBAAsB,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC;YACtD,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM,EAAE,SAAS;SAClB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACnB,IAAI,CAAC,CAAC,KAAK,KAAK,aAAa;YAAE,OAAO,CAAC,CAAC,CAAC;QACzC,IAAI,CAAC,CAAC,KAAK,KAAK,aAAa;YAAE,OAAO,CAAC,CAAC;QACxC,OAAO,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAuB,EAAE,KAAa;IACpE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,yBAAyB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACrD,OAAO,IAAI,EAAE,IAAI,IAAI,MAAM,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;QACzE,uEAAuE;QACvE,OAAO,MAAM,CAAC;IAChB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CAAC,OAA0B;IACpE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IAC3F,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IACnF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CACR,kGAAkG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACxH,CAAC;IACJ,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CACR,0GAA0G,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC5H,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CACR,mGAAmG,CACpG,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC"}
@@ -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,CAsCtD,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"}
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: 'breedbase',
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,SAAS;QAChB,OAAO,EAAE,kCAAkC;QAC3C,QAAQ,EAAE,0BAA0B;QACpC,gBAAgB,EAAE,0BAA0B;QAC5C,SAAS,EAAE,SAAS;QACpB,OAAO,EAAE,OAAO;QAChB,QAAQ,EAAE,kBAAkB;KAC7B,CAAC;IACF,MAAM,CAAC,MAAM,CAAC;QACZ,KAAK,EAAE,aAAa;QACpB,OAAO,EAAE,sCAAsC;QAC/C,QAAQ,EAAE,8BAA8B;QACxC,gBAAgB,EAAE,0BAA0B;QAC5C,SAAS,EAAE,aAAa;QACxB,OAAO,EAAE,OAAO;QAChB,QAAQ,EAAE,kBAAkB;KAC7B,CAAC;IACF,MAAM,CAAC,MAAM,CAAC;QACZ,KAAK,EAAE,OAAO;QACd,OAAO,EAAE,6CAA6C;QACtD,QAAQ,EAAE,qCAAqC;QAC/C,gBAAgB,EAAE,wBAAwB;QAC1C,SAAS,EAAE,OAAO;QAClB,OAAO,EAAE,OAAO;QAChB,QAAQ,EAAE,kBAAkB;KAC7B,CAAC;IACF,MAAM,CAAC,MAAM,CAAC;QACZ,KAAK,EAAE,WAAW;QAClB,OAAO,EAAE,gCAAgC;QACzC,QAAQ,EAAE,wBAAwB;QAClC,gBAAgB,EAAE,0BAA0B;QAC5C,SAAS,EAAE,oBAAoB;QAC/B,OAAO,EAAE,OAAO;QAChB,QAAQ,EAAE,kBAAkB;QAC5B,MAAM,EAAE,IAAI;KACb,CAAC;CACH,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,gCAAgC,CAAC;AAE1D;;;GAGG;AACH,SAAS,eAAe,CAAC,GAAsB;IAC7C,MAAM,GAAG,GAAG,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAClC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,GAAG,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC1C,IAAI,OAAO;YAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAa,EACb,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAChC,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO;IAC9B,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,eAAe,CAAC;IAChD,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AACvE,CAAC"}
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.12",
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.12",
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.12",
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.12",
52
+ "version": "0.4.13",
53
53
  "packageArguments": [
54
54
  { "type": "positional", "value": "run" },
55
55
  { "type": "positional", "value": "start:http" }