@cyanheads/brapi-mcp-server 0.7.13 → 0.8.1

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.
Files changed (94) hide show
  1. package/AGENTS.md +39 -29
  2. package/CLAUDE.md +39 -29
  3. package/Dockerfile +93 -54
  4. package/README.md +210 -241
  5. package/changelog/0.8.x/0.8.0.md +48 -0
  6. package/changelog/0.8.x/0.8.1.md +38 -0
  7. package/dist/config/alias-credentials.d.ts +28 -7
  8. package/dist/config/alias-credentials.d.ts.map +1 -1
  9. package/dist/config/alias-credentials.js +91 -24
  10. package/dist/config/alias-credentials.js.map +1 -1
  11. package/dist/config/builtin-aliases.d.ts +11 -6
  12. package/dist/config/builtin-aliases.d.ts.map +1 -1
  13. package/dist/config/builtin-aliases.js +23 -37
  14. package/dist/config/builtin-aliases.js.map +1 -1
  15. package/dist/index.js +7 -6
  16. package/dist/index.js.map +1 -1
  17. package/dist/mcp-server/resources/definitions/brapi-server-info.resource.js +1 -1
  18. package/dist/mcp-server/resources/definitions/brapi-server-info.resource.js.map +1 -1
  19. package/dist/mcp-server/resources/definitions/brapi-variable.resource.d.ts.map +1 -1
  20. package/dist/mcp-server/resources/definitions/brapi-variable.resource.js +2 -10
  21. package/dist/mcp-server/resources/definitions/brapi-variable.resource.js.map +1 -1
  22. package/dist/mcp-server/tools/definitions/brapi-build-phenotype-matrix.tool.js +1 -1
  23. package/dist/mcp-server/tools/definitions/brapi-build-phenotype-matrix.tool.js.map +1 -1
  24. package/dist/mcp-server/tools/definitions/brapi-connect.tool.d.ts +46 -0
  25. package/dist/mcp-server/tools/definitions/brapi-connect.tool.d.ts.map +1 -1
  26. package/dist/mcp-server/tools/definitions/brapi-connect.tool.js +65 -15
  27. package/dist/mcp-server/tools/definitions/brapi-connect.tool.js.map +1 -1
  28. package/dist/mcp-server/tools/definitions/brapi-dataframe-describe.tool.d.ts.map +1 -1
  29. package/dist/mcp-server/tools/definitions/brapi-dataframe-describe.tool.js +1 -3
  30. package/dist/mcp-server/tools/definitions/brapi-dataframe-describe.tool.js.map +1 -1
  31. package/dist/mcp-server/tools/definitions/brapi-dataframe-export.tool.d.ts.map +1 -1
  32. package/dist/mcp-server/tools/definitions/brapi-dataframe-export.tool.js +4 -10
  33. package/dist/mcp-server/tools/definitions/brapi-dataframe-export.tool.js.map +1 -1
  34. package/dist/mcp-server/tools/definitions/brapi-dataframe-query.tool.js +1 -1
  35. package/dist/mcp-server/tools/definitions/brapi-dataframe-query.tool.js.map +1 -1
  36. package/dist/mcp-server/tools/definitions/brapi-describe-filters.tool.d.ts.map +1 -1
  37. package/dist/mcp-server/tools/definitions/brapi-describe-filters.tool.js +8 -7
  38. package/dist/mcp-server/tools/definitions/brapi-describe-filters.tool.js.map +1 -1
  39. package/dist/mcp-server/tools/definitions/brapi-export-genotype-matrix.tool.d.ts.map +1 -1
  40. package/dist/mcp-server/tools/definitions/brapi-export-genotype-matrix.tool.js +2 -2
  41. package/dist/mcp-server/tools/definitions/brapi-export-genotype-matrix.tool.js.map +1 -1
  42. package/dist/mcp-server/tools/definitions/brapi-find-genotype-calls.tool.js +2 -2
  43. package/dist/mcp-server/tools/definitions/brapi-find-genotype-calls.tool.js.map +1 -1
  44. package/dist/mcp-server/tools/definitions/brapi-germplasm-performance.tool.js +1 -5
  45. package/dist/mcp-server/tools/definitions/brapi-germplasm-performance.tool.js.map +1 -1
  46. package/dist/mcp-server/tools/definitions/brapi-get-germplasm.tool.d.ts.map +1 -1
  47. package/dist/mcp-server/tools/definitions/brapi-get-germplasm.tool.js +2 -10
  48. package/dist/mcp-server/tools/definitions/brapi-get-germplasm.tool.js.map +1 -1
  49. package/dist/mcp-server/tools/definitions/brapi-get-image.tool.js +1 -1
  50. package/dist/mcp-server/tools/definitions/brapi-get-image.tool.js.map +1 -1
  51. package/dist/mcp-server/tools/definitions/brapi-get-study.tool.d.ts.map +1 -1
  52. package/dist/mcp-server/tools/definitions/brapi-get-study.tool.js +2 -10
  53. package/dist/mcp-server/tools/definitions/brapi-get-study.tool.js.map +1 -1
  54. package/dist/mcp-server/tools/definitions/brapi-raw-get.tool.d.ts.map +1 -1
  55. package/dist/mcp-server/tools/definitions/brapi-raw-get.tool.js +0 -1
  56. package/dist/mcp-server/tools/definitions/brapi-raw-get.tool.js.map +1 -1
  57. package/dist/mcp-server/tools/definitions/brapi-raw-search.tool.d.ts.map +1 -1
  58. package/dist/mcp-server/tools/definitions/brapi-raw-search.tool.js +1 -5
  59. package/dist/mcp-server/tools/definitions/brapi-raw-search.tool.js.map +1 -1
  60. package/dist/mcp-server/tools/definitions/brapi-server-info.tool.d.ts +12 -0
  61. package/dist/mcp-server/tools/definitions/brapi-server-info.tool.d.ts.map +1 -1
  62. package/dist/mcp-server/tools/definitions/brapi-server-info.tool.js +1 -1
  63. package/dist/mcp-server/tools/definitions/brapi-server-info.tool.js.map +1 -1
  64. package/dist/mcp-server/tools/definitions/brapi-submit-observations.tool.d.ts +5 -0
  65. package/dist/mcp-server/tools/definitions/brapi-submit-observations.tool.d.ts.map +1 -1
  66. package/dist/mcp-server/tools/definitions/brapi-submit-observations.tool.js +55 -10
  67. package/dist/mcp-server/tools/definitions/brapi-submit-observations.tool.js.map +1 -1
  68. package/dist/mcp-server/tools/definitions/index.d.ts +123 -65
  69. package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
  70. package/dist/mcp-server/tools/shared/find-helpers.d.ts +11 -5
  71. package/dist/mcp-server/tools/shared/find-helpers.d.ts.map +1 -1
  72. package/dist/mcp-server/tools/shared/find-helpers.js +24 -16
  73. package/dist/mcp-server/tools/shared/find-helpers.js.map +1 -1
  74. package/dist/mcp-server/tools/shared/orientation-envelope.d.ts +26 -0
  75. package/dist/mcp-server/tools/shared/orientation-envelope.d.ts.map +1 -1
  76. package/dist/mcp-server/tools/shared/orientation-envelope.js +75 -6
  77. package/dist/mcp-server/tools/shared/orientation-envelope.js.map +1 -1
  78. package/dist/services/brapi-client/brapi-client.d.ts.map +1 -1
  79. package/dist/services/brapi-client/brapi-client.js +29 -26
  80. package/dist/services/brapi-client/brapi-client.js.map +1 -1
  81. package/dist/services/capability-registry/capability-registry.d.ts +8 -1
  82. package/dist/services/capability-registry/capability-registry.d.ts.map +1 -1
  83. package/dist/services/capability-registry/capability-registry.js +37 -6
  84. package/dist/services/capability-registry/capability-registry.js.map +1 -1
  85. package/dist/services/reference-data-cache/reference-data-cache.d.ts.map +1 -1
  86. package/dist/services/reference-data-cache/reference-data-cache.js +9 -4
  87. package/dist/services/reference-data-cache/reference-data-cache.js.map +1 -1
  88. package/dist/services/server-registry/server-registry.d.ts +17 -3
  89. package/dist/services/server-registry/server-registry.d.ts.map +1 -1
  90. package/dist/services/server-registry/server-registry.js +30 -7
  91. package/dist/services/server-registry/server-registry.js.map +1 -1
  92. package/manifest.json +1 -1
  93. package/package.json +11 -10
  94. package/server.json +11 -13
package/Dockerfile CHANGED
@@ -4,15 +4,17 @@
4
4
  # This stage installs all dependencies (including dev), builds the TypeScript
5
5
  # source code into JavaScript, and prepares the production assets.
6
6
  #
7
- # Pinned to BUILDPLATFORM, not the target platform. `bun run build` emits
8
- # platform-independent JavaScript and only `dist/` is copied forward, so this
9
- # stage has no reason to run under emulation — and under QEMU it does not run
10
- # at all: Bun's JavaScriptCore aborts with a spurious MemoryExhaustion
11
- # assertion (~21 MB peak), so a cross-arch build of this stage fails outright
12
- # on an arm64 host. Building natively also removes emulation from the slowest
13
- # stage of a multi-arch build.
7
+ # Pinned to $BUILDPLATFORM rather than the target platform: `bun run build` emits
8
+ # JavaScript, and only `dist/` crosses into the production stage. Built for the
9
+ # target instead, the non-native leg of a `--platform linux/amd64,linux/arm64`
10
+ # build runs under QEMU, where bun >= 1.4 aborts with a JavaScriptCore allocator
11
+ # assertion and fails the multi-arch push.
12
+ #
13
+ # The constraint this assumes: the build stage produces platform-independent
14
+ # output. A stage that compiles a native addon needs the target-arch toolchain
15
+ # and cannot cross-compile this way — drop the flag there.
14
16
  # ==============================================================================
15
- FROM --platform=$BUILDPLATFORM oven/bun:1.4.0 AS build
17
+ FROM --platform=$BUILDPLATFORM oven/bun:1.4.2 AS build
16
18
 
17
19
  WORKDIR /usr/src/app
18
20
 
@@ -35,69 +37,105 @@ RUN bun run build
35
37
 
36
38
 
37
39
  # ==============================================================================
38
- # Production Stage
40
+ # Production Dependencies Stage
39
41
  #
40
- # This stage creates a minimal, optimized, and secure image for running the
41
- # application. It uses a slim base image and only includes production
42
- # dependencies and build artifacts.
42
+ # Installs the production dependency tree for the target platform. Every step
43
+ # here can run JavaScript — bunfig.toml's security scanner runs as a Bun
44
+ # program, and so do the OTel and musl-prune scripts — so the stage runs on
45
+ # $BUILDPLATFORM and cross-installs with `--os`/`--cpu`, which pick each
46
+ # platform-specific optional dependency (DuckDB's native bindings among them)
47
+ # for the target. Only `node_modules` leaves this stage.
48
+ #
49
+ # A clean image rather than `FROM build`: the build stage's node_modules holds
50
+ # devDependencies.
43
51
  # ==============================================================================
44
- FROM oven/bun:1.4.0-slim AS production
52
+ FROM --platform=$BUILDPLATFORM oven/bun:1.4.2 AS deps
45
53
 
46
54
  WORKDIR /usr/src/app
47
55
 
48
- # Set the environment to production for performance and to ensure only
49
- # production dependencies are installed.
50
- ENV NODE_ENV=production
51
-
52
- # OCI image metadata (https://github.com/opencontainers/image-spec/blob/main/annotations.md)
53
- ARG APP_VERSION=dev
54
- LABEL org.opencontainers.image.title="@cyanheads/brapi-mcp-server"
55
- LABEL org.opencontainers.image.description="BrAPI v2.1 MCP server — studies, germplasm, observations, genotypes, images, and pedigrees across Breedbase, T3, Sweetpotatobase, and any BrAPI-compliant server."
56
- LABEL org.opencontainers.image.source="https://github.com/cyanheads/brapi-mcp-server"
57
- LABEL org.opencontainers.image.licenses="Apache-2.0"
58
- LABEL org.opencontainers.image.version="${APP_VERSION}"
59
-
60
- # Copy dependency manifests
61
- COPY package.json bun.lock ./
56
+ # Copy dependency manifests. `bunfig.toml` rides along so every install below
57
+ # passes its release-age gate and security scanner, as a local install does.
58
+ COPY package.json bun.lock bunfig.toml ./
59
+
60
+ # The scanner bunfig.toml names is a devDependency, and Bun installs a missing
61
+ # scanner through the same production-filtered install, which omits it and
62
+ # aborts. Seed it from the build stage's full install instead. Remove this line,
63
+ # and the `rm` at the end of this stage, if bunfig.toml stops naming a scanner.
64
+ COPY --from=build /usr/src/app/node_modules/@socketsecurity/bun-security-scanner ./node_modules/@socketsecurity/bun-security-scanner
65
+
66
+ # Docker names the target architecture `amd64`/`arm64`; Bun's `--cpu` takes
67
+ # `x64`/`arm64`. Mapped once here, read by both installs below. `oven/bun`
68
+ # publishes only these two architectures, so any other target fails here.
69
+ ARG TARGETOS
70
+ ARG TARGETARCH
71
+ RUN case "$TARGETARCH" in \
72
+ amd64) echo x64 ;; \
73
+ arm64) echo arm64 ;; \
74
+ *) echo "Unsupported TARGETARCH '$TARGETARCH': expected amd64 or arm64" >&2; exit 1 ;; \
75
+ esac > .bun-cpu
62
76
 
63
77
  # Install only production dependencies, ignoring any lifecycle scripts (like 'prepare')
64
78
  # that are not needed in the final production image.
65
79
  # `--omit=peer` drops the framework's optional peer tiers (test runner, service
66
80
  # SDKs, parsers) that Bun would otherwise auto-install. Anything this server
67
- # actually imports belongs in its own `dependencies` — @duckdb/node-api among
68
- # them — so nothing needed at runtime is lost. The two `bun add` steps below
69
- # carry the same flag; without it, they re-resolve the graph and pull every
70
- # optional peer back in.
81
+ # actually imports belongs in its own `dependencies` — @duckdb/node-api, which
82
+ # backs the mandatory dataframe (canvas) surface, among them — so nothing needed
83
+ # at runtime is lost.
71
84
  RUN --mount=type=cache,target=/root/.bun/install/cache \
72
- bun install --production --omit=peer --frozen-lockfile --ignore-scripts
85
+ bun install --production --omit=peer --frozen-lockfile --ignore-scripts \
86
+ --os="$TARGETOS" --cpu="$(cat .bun-cpu)"
73
87
 
74
88
  # Conditionally install OpenTelemetry optional peer dependencies (Tier 3).
75
- # These are not bundled by default to keep the base image lean. Enable at build time
76
- # with: docker build --build-arg OTEL_ENABLED=true
89
+ # Installed by default. Omit them for a leaner image at build time
90
+ # with: docker build --build-arg OTEL_ENABLED=false
91
+ # The script reads the list and each range from the installed framework's
92
+ # `peerDependencies` and passes the target flags on to its `bun install`.
93
+ COPY scripts/install-otel.ts ./scripts/
77
94
  ARG OTEL_ENABLED=true
78
95
  RUN --mount=type=cache,target=/root/.bun/install/cache \
79
96
  if [ "$OTEL_ENABLED" = "true" ]; then \
80
- bun add --omit=dev --omit=peer --ignore-scripts @hono/otel \
81
- @opentelemetry/instrumentation-http \
82
- @opentelemetry/exporter-metrics-otlp-http \
83
- @opentelemetry/exporter-trace-otlp-http \
84
- @opentelemetry/instrumentation-pino \
85
- @opentelemetry/resources \
86
- @opentelemetry/sdk-metrics \
87
- @opentelemetry/sdk-node \
88
- @opentelemetry/sdk-trace-node \
89
- @opentelemetry/semantic-conventions; \
97
+ bun scripts/install-otel.ts --os="$TARGETOS" --cpu="$(cat .bun-cpu)"; \
90
98
  fi
91
99
 
92
- # Conditionally install the DuckDB optional peer dependency for the dataframe
93
- # (canvas) surface. Default-on so the published image works out of the box with
94
- # CANVAS_PROVIDER_TYPE=duckdb. Disable for size-sensitive self-builds with:
95
- # docker build --build-arg CANVAS_ENABLED=false
96
- ARG CANVAS_ENABLED=true
97
- RUN --mount=type=cache,target=/root/.bun/install/cache \
98
- if [ "$CANVAS_ENABLED" = "true" ]; then \
99
- bun add --omit=dev --omit=peer @duckdb/node-api; \
100
- fi
100
+ # `--os`/`--cpu` have no libc counterpart, so a native dependency published in
101
+ # glibc and musl variants (DuckDB's bindings, for one) installs both. The
102
+ # runtime image is Debian (glibc) and never loads the musl copy; the script
103
+ # deletes every package whose own `libc` admits only musl. It follows every
104
+ # install, since a later `bun install` restores what it removes.
105
+ COPY scripts/prune-musl-packages.ts ./scripts/
106
+ RUN bun scripts/prune-musl-packages.ts
107
+
108
+ # The seeded scanner served only the installs above; keep it out of the image.
109
+ RUN rm -rf node_modules/@socketsecurity/bun-security-scanner
110
+
111
+
112
+ # ==============================================================================
113
+ # Production Stage
114
+ #
115
+ # This stage creates a minimal, optimized, and secure image for running the
116
+ # application. It uses a slim base image and only includes production
117
+ # dependencies and build artifacts. Its only Bun invocations are HEALTHCHECK
118
+ # and CMD, which run on the real target at container start.
119
+ # ==============================================================================
120
+ FROM oven/bun:1.4.2-slim AS production
121
+
122
+ WORKDIR /usr/src/app
123
+
124
+ # Set the environment to production for performance.
125
+ ENV NODE_ENV=production
126
+
127
+ # OCI image metadata (https://github.com/opencontainers/image-spec/blob/main/annotations.md)
128
+ ARG APP_VERSION=dev
129
+ LABEL org.opencontainers.image.title="@cyanheads/brapi-mcp-server"
130
+ LABEL org.opencontainers.image.description="BrAPI v2.1 MCP server — studies, germplasm, observations, genotypes, images, and pedigrees across Breedbase, T3, Sweetpotatobase, and any BrAPI-compliant server."
131
+ LABEL org.opencontainers.image.source="https://github.com/cyanheads/brapi-mcp-server"
132
+ LABEL org.opencontainers.image.licenses="Apache-2.0"
133
+ LABEL org.opencontainers.image.version="${APP_VERSION}"
134
+
135
+ # The manifest comes from the build context: the deps stage's copy was rewritten
136
+ # by the OTel install, and the runtime reads only its name, version, and type.
137
+ COPY package.json ./
138
+ COPY --from=deps /usr/src/app/node_modules ./node_modules
101
139
 
102
140
  # Copy the compiled application code from the build stage
103
141
  COPY --from=build /usr/src/app/dist ./dist
@@ -117,13 +155,14 @@ ARG PORT
117
155
 
118
156
  # Set runtime environment variables
119
157
  # Note: PORT is an automatic variable in many cloud environments (e.g., Cloud Run)
158
+ # MCP_SESSION_MODE stays stateful: the server declares `sessionMode.require:
159
+ # 'stateful'` and refuses to start over HTTP in stateless mode.
120
160
  ENV MCP_HTTP_PORT=${PORT:-3010}
121
161
  ENV MCP_HTTP_HOST="0.0.0.0"
122
162
  ENV MCP_TRANSPORT_TYPE="http"
123
163
  ENV MCP_SESSION_MODE="stateful"
124
164
  ENV MCP_LOG_LEVEL="info"
125
165
  ENV LOGS_DIR="/var/log/brapi-mcp-server"
126
- ENV MCP_FORCE_CONSOLE_LOGGING="true"
127
166
 
128
167
  # Expose the port the server listens on
129
168
  EXPOSE ${MCP_HTTP_PORT}