@cyanheads/brapi-mcp-server 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +391 -0
- package/Dockerfile +99 -0
- package/LICENSE +201 -0
- package/README.md +590 -0
- package/changelog/0.1.x/0.1.0.md +19 -0
- package/changelog/0.1.x/0.1.1.md +27 -0
- package/changelog/0.1.x/0.1.2.md +22 -0
- package/changelog/0.2.x/0.2.0.md +35 -0
- package/changelog/0.2.x/0.2.1.md +36 -0
- package/changelog/0.3.x/0.3.0.md +38 -0
- package/changelog/0.3.x/0.3.1.md +40 -0
- package/changelog/0.3.x/0.3.2.md +29 -0
- package/changelog/0.3.x/0.3.3.md +19 -0
- package/changelog/0.3.x/0.3.4.md +33 -0
- package/changelog/0.3.x/0.3.5.md +24 -0
- package/changelog/template.md +51 -0
- package/dist/config/alias-credentials.d.ts +82 -0
- package/dist/config/alias-credentials.d.ts.map +1 -0
- package/dist/config/alias-credentials.js +159 -0
- package/dist/config/alias-credentials.js.map +1 -0
- package/dist/config/server-config.d.ts +39 -0
- package/dist/config/server-config.d.ts.map +1 -0
- package/dist/config/server-config.js +128 -0
- package/dist/config/server-config.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +85 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/brapi-eda-study.prompt.d.ts +14 -0
- package/dist/mcp-server/prompts/definitions/brapi-eda-study.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/brapi-eda-study.prompt.js +75 -0
- package/dist/mcp-server/prompts/definitions/brapi-eda-study.prompt.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/brapi-meta-analysis.prompt.d.ts +16 -0
- package/dist/mcp-server/prompts/definitions/brapi-meta-analysis.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/brapi-meta-analysis.prompt.js +109 -0
- package/dist/mcp-server/prompts/definitions/brapi-meta-analysis.prompt.js.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-calls.resource.d.ts +11 -0
- package/dist/mcp-server/resources/definitions/brapi-calls.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-calls.resource.js +46 -0
- package/dist/mcp-server/resources/definitions/brapi-calls.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-dataset.resource.d.ts +13 -0
- package/dist/mcp-server/resources/definitions/brapi-dataset.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-dataset.resource.js +26 -0
- package/dist/mcp-server/resources/definitions/brapi-dataset.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-filters.resource.d.ts +19 -0
- package/dist/mcp-server/resources/definitions/brapi-filters.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-filters.resource.js +45 -0
- package/dist/mcp-server/resources/definitions/brapi-filters.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-germplasm.resource.d.ts +18 -0
- package/dist/mcp-server/resources/definitions/brapi-germplasm.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-germplasm.resource.js +34 -0
- package/dist/mcp-server/resources/definitions/brapi-germplasm.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-server-info.resource.d.ts +11 -0
- package/dist/mcp-server/resources/definitions/brapi-server-info.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-server-info.resource.js +28 -0
- package/dist/mcp-server/resources/definitions/brapi-server-info.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-study.resource.d.ts +18 -0
- package/dist/mcp-server/resources/definitions/brapi-study.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/brapi-study.resource.js +34 -0
- package/dist/mcp-server/resources/definitions/brapi-study.resource.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-connect.tool.d.ts +82 -0
- package/dist/mcp-server/tools/definitions/brapi-connect.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-connect.tool.js +106 -0
- package/dist/mcp-server/tools/definitions/brapi-connect.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-describe-filters.tool.d.ts +41 -0
- package/dist/mcp-server/tools/definitions/brapi-describe-filters.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-describe-filters.tool.js +88 -0
- package/dist/mcp-server/tools/definitions/brapi-describe-filters.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-genotype-calls.tool.d.ts +74 -0
- package/dist/mcp-server/tools/definitions/brapi-find-genotype-calls.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-genotype-calls.tool.js +386 -0
- package/dist/mcp-server/tools/definitions/brapi-find-genotype-calls.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-germplasm.tool.d.ts +72 -0
- package/dist/mcp-server/tools/definitions/brapi-find-germplasm.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-germplasm.tool.js +290 -0
- package/dist/mcp-server/tools/definitions/brapi-find-germplasm.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-images.tool.d.ts +65 -0
- package/dist/mcp-server/tools/definitions/brapi-find-images.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-images.tool.js +243 -0
- package/dist/mcp-server/tools/definitions/brapi-find-images.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-locations.tool.d.ts +63 -0
- package/dist/mcp-server/tools/definitions/brapi-find-locations.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-locations.tool.js +278 -0
- package/dist/mcp-server/tools/definitions/brapi-find-locations.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-observations.tool.d.ts +74 -0
- package/dist/mcp-server/tools/definitions/brapi-find-observations.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-observations.tool.js +288 -0
- package/dist/mcp-server/tools/definitions/brapi-find-observations.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-studies.tool.d.ts +69 -0
- package/dist/mcp-server/tools/definitions/brapi-find-studies.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-studies.tool.js +243 -0
- package/dist/mcp-server/tools/definitions/brapi-find-studies.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-variables.tool.d.ts +86 -0
- package/dist/mcp-server/tools/definitions/brapi-find-variables.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-variables.tool.js +337 -0
- package/dist/mcp-server/tools/definitions/brapi-find-variables.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-variants.tool.d.ts +59 -0
- package/dist/mcp-server/tools/definitions/brapi-find-variants.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-find-variants.tool.js +248 -0
- package/dist/mcp-server/tools/definitions/brapi-find-variants.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-get-germplasm.tool.d.ts +59 -0
- package/dist/mcp-server/tools/definitions/brapi-get-germplasm.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-get-germplasm.tool.js +306 -0
- package/dist/mcp-server/tools/definitions/brapi-get-germplasm.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-get-image.tool.d.ts +57 -0
- package/dist/mcp-server/tools/definitions/brapi-get-image.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-get-image.tool.js +291 -0
- package/dist/mcp-server/tools/definitions/brapi-get-image.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-get-study.tool.d.ts +75 -0
- package/dist/mcp-server/tools/definitions/brapi-get-study.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-get-study.tool.js +323 -0
- package/dist/mcp-server/tools/definitions/brapi-get-study.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-manage-dataset.tool.d.ts +87 -0
- package/dist/mcp-server/tools/definitions/brapi-manage-dataset.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-manage-dataset.tool.js +296 -0
- package/dist/mcp-server/tools/definitions/brapi-manage-dataset.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-raw-get.tool.d.ts +35 -0
- package/dist/mcp-server/tools/definitions/brapi-raw-get.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-raw-get.tool.js +148 -0
- package/dist/mcp-server/tools/definitions/brapi-raw-get.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-raw-search.tool.d.ts +33 -0
- package/dist/mcp-server/tools/definitions/brapi-raw-search.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-raw-search.tool.js +126 -0
- package/dist/mcp-server/tools/definitions/brapi-raw-search.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-server-info.tool.d.ts +51 -0
- package/dist/mcp-server/tools/definitions/brapi-server-info.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-server-info.tool.js +41 -0
- package/dist/mcp-server/tools/definitions/brapi-server-info.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-submit-observations.tool.d.ts +117 -0
- package/dist/mcp-server/tools/definitions/brapi-submit-observations.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-submit-observations.tool.js +574 -0
- package/dist/mcp-server/tools/definitions/brapi-submit-observations.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-walk-pedigree.tool.d.ts +52 -0
- package/dist/mcp-server/tools/definitions/brapi-walk-pedigree.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/brapi-walk-pedigree.tool.js +420 -0
- package/dist/mcp-server/tools/definitions/brapi-walk-pedigree.tool.js.map +1 -0
- package/dist/mcp-server/tools/shared/connect-auth-schema.d.ts +29 -0
- package/dist/mcp-server/tools/shared/connect-auth-schema.d.ts.map +1 -0
- package/dist/mcp-server/tools/shared/connect-auth-schema.js +55 -0
- package/dist/mcp-server/tools/shared/connect-auth-schema.js.map +1 -0
- package/dist/mcp-server/tools/shared/find-helpers.d.ts +143 -0
- package/dist/mcp-server/tools/shared/find-helpers.d.ts.map +1 -0
- package/dist/mcp-server/tools/shared/find-helpers.js +319 -0
- package/dist/mcp-server/tools/shared/find-helpers.js.map +1 -0
- package/dist/mcp-server/tools/shared/orientation-envelope.d.ts +97 -0
- package/dist/mcp-server/tools/shared/orientation-envelope.d.ts.map +1 -0
- package/dist/mcp-server/tools/shared/orientation-envelope.js +254 -0
- package/dist/mcp-server/tools/shared/orientation-envelope.js.map +1 -0
- package/dist/mcp-server/tools/shared/raw-routing-hints.d.ts +10 -0
- package/dist/mcp-server/tools/shared/raw-routing-hints.d.ts.map +1 -0
- package/dist/mcp-server/tools/shared/raw-routing-hints.js +46 -0
- package/dist/mcp-server/tools/shared/raw-routing-hints.js.map +1 -0
- package/dist/services/brapi-client/brapi-client.d.ts +76 -0
- package/dist/services/brapi-client/brapi-client.d.ts.map +1 -0
- package/dist/services/brapi-client/brapi-client.js +320 -0
- package/dist/services/brapi-client/brapi-client.js.map +1 -0
- package/dist/services/brapi-client/index.d.ts +9 -0
- package/dist/services/brapi-client/index.d.ts.map +1 -0
- package/dist/services/brapi-client/index.js +7 -0
- package/dist/services/brapi-client/index.js.map +1 -0
- package/dist/services/brapi-client/types.d.ts +82 -0
- package/dist/services/brapi-client/types.d.ts.map +1 -0
- package/dist/services/brapi-client/types.js +8 -0
- package/dist/services/brapi-client/types.js.map +1 -0
- package/dist/services/brapi-filters/catalog.d.ts +14 -0
- package/dist/services/brapi-filters/catalog.d.ts.map +1 -0
- package/dist/services/brapi-filters/catalog.js +490 -0
- package/dist/services/brapi-filters/catalog.js.map +1 -0
- package/dist/services/brapi-filters/index.d.ts +8 -0
- package/dist/services/brapi-filters/index.d.ts.map +1 -0
- package/dist/services/brapi-filters/index.js +7 -0
- package/dist/services/brapi-filters/index.js.map +1 -0
- package/dist/services/brapi-filters/types.d.ts +23 -0
- package/dist/services/brapi-filters/types.d.ts.map +1 -0
- package/dist/services/brapi-filters/types.js +9 -0
- package/dist/services/brapi-filters/types.js.map +1 -0
- package/dist/services/capability-registry/capability-registry.d.ts +51 -0
- package/dist/services/capability-registry/capability-registry.d.ts.map +1 -0
- package/dist/services/capability-registry/capability-registry.js +234 -0
- package/dist/services/capability-registry/capability-registry.js.map +1 -0
- package/dist/services/capability-registry/index.d.ts +9 -0
- package/dist/services/capability-registry/index.d.ts.map +1 -0
- package/dist/services/capability-registry/index.js +7 -0
- package/dist/services/capability-registry/index.js.map +1 -0
- package/dist/services/capability-registry/types.d.ts +67 -0
- package/dist/services/capability-registry/types.d.ts.map +1 -0
- package/dist/services/capability-registry/types.js +9 -0
- package/dist/services/capability-registry/types.js.map +1 -0
- package/dist/services/dataset-store/dataset-store.d.ts +35 -0
- package/dist/services/dataset-store/dataset-store.d.ts.map +1 -0
- package/dist/services/dataset-store/dataset-store.js +190 -0
- package/dist/services/dataset-store/dataset-store.js.map +1 -0
- package/dist/services/dataset-store/index.d.ts +8 -0
- package/dist/services/dataset-store/index.d.ts.map +1 -0
- package/dist/services/dataset-store/index.js +7 -0
- package/dist/services/dataset-store/index.js.map +1 -0
- package/dist/services/dataset-store/types.d.ts +65 -0
- package/dist/services/dataset-store/types.d.ts.map +1 -0
- package/dist/services/dataset-store/types.js +8 -0
- package/dist/services/dataset-store/types.js.map +1 -0
- package/dist/services/ontology-resolver/index.d.ts +8 -0
- package/dist/services/ontology-resolver/index.d.ts.map +1 -0
- package/dist/services/ontology-resolver/index.js +7 -0
- package/dist/services/ontology-resolver/index.js.map +1 -0
- package/dist/services/ontology-resolver/ontology-resolver.d.ts +49 -0
- package/dist/services/ontology-resolver/ontology-resolver.d.ts.map +1 -0
- package/dist/services/ontology-resolver/ontology-resolver.js +99 -0
- package/dist/services/ontology-resolver/ontology-resolver.js.map +1 -0
- package/dist/services/ontology-resolver/types.d.ts +38 -0
- package/dist/services/ontology-resolver/types.d.ts.map +1 -0
- package/dist/services/ontology-resolver/types.js +8 -0
- package/dist/services/ontology-resolver/types.js.map +1 -0
- package/dist/services/reference-data-cache/index.d.ts +9 -0
- package/dist/services/reference-data-cache/index.d.ts.map +1 -0
- package/dist/services/reference-data-cache/index.js +7 -0
- package/dist/services/reference-data-cache/index.js.map +1 -0
- package/dist/services/reference-data-cache/reference-data-cache.d.ts +31 -0
- package/dist/services/reference-data-cache/reference-data-cache.d.ts.map +1 -0
- package/dist/services/reference-data-cache/reference-data-cache.js +131 -0
- package/dist/services/reference-data-cache/reference-data-cache.js.map +1 -0
- package/dist/services/reference-data-cache/types.d.ts +42 -0
- package/dist/services/reference-data-cache/types.d.ts.map +1 -0
- package/dist/services/reference-data-cache/types.js +9 -0
- package/dist/services/reference-data-cache/types.js.map +1 -0
- package/dist/services/server-registry/index.d.ts +9 -0
- package/dist/services/server-registry/index.d.ts.map +1 -0
- package/dist/services/server-registry/index.js +7 -0
- package/dist/services/server-registry/index.js.map +1 -0
- package/dist/services/server-registry/server-registry.d.ts +57 -0
- package/dist/services/server-registry/server-registry.d.ts.map +1 -0
- package/dist/services/server-registry/server-registry.js +210 -0
- package/dist/services/server-registry/server-registry.js.map +1 -0
- package/dist/services/server-registry/types.d.ts +43 -0
- package/dist/services/server-registry/types.d.ts.map +1 -0
- package/dist/services/server-registry/types.js +10 -0
- package/dist/services/server-registry/types.js.map +1 -0
- package/package.json +86 -0
- package/server.json +99 -0
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `brapi_walk_pedigree` — walk germplasm ancestry or
|
|
3
|
+
* descendancy as a DAG. BrAPI only exposes direct parents / direct progeny
|
|
4
|
+
* per call, so we BFS outward from each root up to `maxDepth`, deduplicate
|
|
5
|
+
* nodes (cultivars may appear on multiple paths), and break cycles.
|
|
6
|
+
* Response includes traversal stats so the agent can see how the walk
|
|
7
|
+
* terminated without re-running the tool.
|
|
8
|
+
*
|
|
9
|
+
* @module mcp-server/tools/definitions/brapi-walk-pedigree.tool
|
|
10
|
+
*/
|
|
11
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
12
|
+
import { getBrapiClient } from '../../../services/brapi-client/index.js';
|
|
13
|
+
import { getCapabilityRegistry } from '../../../services/capability-registry/index.js';
|
|
14
|
+
import { DEFAULT_ALIAS, getServerRegistry } from '../../../services/server-registry/index.js';
|
|
15
|
+
import { AliasInput, buildRequestOptions, isUpstreamNotFound } from '../shared/find-helpers.js';
|
|
16
|
+
const DEFAULT_MAX_DEPTH = 3;
|
|
17
|
+
const MAX_NODES = 1_000;
|
|
18
|
+
const NodeSchema = z
|
|
19
|
+
.object({
|
|
20
|
+
germplasmDbId: z.string().describe('Server-side identifier for the germplasm.'),
|
|
21
|
+
germplasmName: z.string().optional().describe('Display name of the germplasm.'),
|
|
22
|
+
depth: z
|
|
23
|
+
.number()
|
|
24
|
+
.int()
|
|
25
|
+
.nonnegative()
|
|
26
|
+
.describe('Min distance from any root germplasm (0 for roots).'),
|
|
27
|
+
isRoot: z.boolean().describe('True when this node is one of the starting germplasm.'),
|
|
28
|
+
})
|
|
29
|
+
.describe('One germplasm reached during the walk.');
|
|
30
|
+
const EdgeSchema = z
|
|
31
|
+
.object({
|
|
32
|
+
from: z.string().describe('germplasmDbId of the source of the relationship.'),
|
|
33
|
+
to: z.string().describe('germplasmDbId of the target.'),
|
|
34
|
+
relationship: z
|
|
35
|
+
.enum(['parent', 'child'])
|
|
36
|
+
.describe('Direction: parent = from is a parent of to; child = from is a descendant of to.'),
|
|
37
|
+
parentType: z
|
|
38
|
+
.string()
|
|
39
|
+
.optional()
|
|
40
|
+
.describe('E.g. MALE, FEMALE, SELF, when the upstream response supplies it.'),
|
|
41
|
+
})
|
|
42
|
+
.describe('One deduplicated pedigree edge between two nodes.');
|
|
43
|
+
const OutputSchema = z.object({
|
|
44
|
+
alias: z.string().describe('Alias of the registered BrAPI connection the call used.'),
|
|
45
|
+
direction: z
|
|
46
|
+
.enum(['ancestors', 'descendants', 'both'])
|
|
47
|
+
.describe('The direction the walk expanded (echoed from the input).'),
|
|
48
|
+
maxDepth: z
|
|
49
|
+
.number()
|
|
50
|
+
.int()
|
|
51
|
+
.positive()
|
|
52
|
+
.describe('The maximum depth the walk was allowed to reach (echoed from the input).'),
|
|
53
|
+
nodes: z
|
|
54
|
+
.array(NodeSchema)
|
|
55
|
+
.describe('Deduplicated node list — every germplasm reached by the walk, sorted by depth then DbId.'),
|
|
56
|
+
edges: z
|
|
57
|
+
.array(EdgeSchema)
|
|
58
|
+
.describe('Deduplicated edge list. `relationship: "parent"` means `from` is a parent of `to`; `relationship: "child"` means `from` is a descendant of `to`.'),
|
|
59
|
+
depthReached: z
|
|
60
|
+
.number()
|
|
61
|
+
.int()
|
|
62
|
+
.nonnegative()
|
|
63
|
+
.describe('Deepest BFS level that produced at least one new edge (0 if only roots were walked).'),
|
|
64
|
+
rootCount: z.number().int().nonnegative().describe('Number of starting germplasm roots.'),
|
|
65
|
+
leafCount: z
|
|
66
|
+
.number()
|
|
67
|
+
.int()
|
|
68
|
+
.nonnegative()
|
|
69
|
+
.describe('Nodes that have no outgoing edges in the walked direction — terminal in the DAG.'),
|
|
70
|
+
cycleCount: z
|
|
71
|
+
.number()
|
|
72
|
+
.int()
|
|
73
|
+
.nonnegative()
|
|
74
|
+
.describe('Number of times the walk revisited an already-registered node (cycles broken).'),
|
|
75
|
+
deadEndCount: z
|
|
76
|
+
.number()
|
|
77
|
+
.int()
|
|
78
|
+
.nonnegative()
|
|
79
|
+
.describe('Nodes whose upstream pedigree/progeny lookup failed.'),
|
|
80
|
+
truncated: z
|
|
81
|
+
.boolean()
|
|
82
|
+
.describe(`True when the walk hit the ${MAX_NODES}-node safety cap before exhausting depth.`),
|
|
83
|
+
warnings: z
|
|
84
|
+
.array(z.string())
|
|
85
|
+
.describe('Advisory messages (capability gaps, per-node expansion failures).'),
|
|
86
|
+
});
|
|
87
|
+
export const brapiWalkPedigree = tool('brapi_walk_pedigree', {
|
|
88
|
+
description: 'Walk germplasm ancestry or descendancy as a deduplicated DAG, with multi-generation traversal, cycle detection, and depth limits. Returns nodes + edges plus traversal stats (depthReached, rootCount, leafCount, cycleCount, deadEndCount).',
|
|
89
|
+
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
90
|
+
input: z.object({
|
|
91
|
+
germplasmDbIds: z
|
|
92
|
+
.array(z.string().min(1))
|
|
93
|
+
.min(1)
|
|
94
|
+
.max(20)
|
|
95
|
+
.describe('Starting germplasm (1–20 roots). All roots are walked concurrently.'),
|
|
96
|
+
direction: z
|
|
97
|
+
.enum(['ancestors', 'descendants', 'both'])
|
|
98
|
+
.default('ancestors')
|
|
99
|
+
.describe('Which direction to walk: ancestors (parents), descendants (progeny), or both.'),
|
|
100
|
+
maxDepth: z
|
|
101
|
+
.number()
|
|
102
|
+
.int()
|
|
103
|
+
.positive()
|
|
104
|
+
.max(10)
|
|
105
|
+
.default(DEFAULT_MAX_DEPTH)
|
|
106
|
+
.describe(`Max generations to walk per direction (default ${DEFAULT_MAX_DEPTH}, cap 10).`),
|
|
107
|
+
alias: AliasInput,
|
|
108
|
+
}),
|
|
109
|
+
output: OutputSchema,
|
|
110
|
+
async handler(input, ctx) {
|
|
111
|
+
const registry = getServerRegistry();
|
|
112
|
+
const capabilities = getCapabilityRegistry();
|
|
113
|
+
const client = getBrapiClient();
|
|
114
|
+
const connection = await registry.get(ctx, input.alias ?? DEFAULT_ALIAS);
|
|
115
|
+
const capabilityLookup = {};
|
|
116
|
+
if (connection.resolvedAuth)
|
|
117
|
+
capabilityLookup.auth = connection.resolvedAuth;
|
|
118
|
+
await capabilities.ensure(connection.baseUrl, { service: 'germplasm', method: 'GET' }, ctx, capabilityLookup);
|
|
119
|
+
const profile = await capabilities.profile(connection.baseUrl, ctx, capabilityLookup);
|
|
120
|
+
const hasPedigree = Boolean(profile.supported['germplasm/{germplasmDbId}/pedigree']);
|
|
121
|
+
const hasProgeny = Boolean(profile.supported['germplasm/{germplasmDbId}/progeny']);
|
|
122
|
+
const warnings = [];
|
|
123
|
+
const wantsAncestors = input.direction === 'ancestors' || input.direction === 'both';
|
|
124
|
+
const wantsDescendants = input.direction === 'descendants' || input.direction === 'both';
|
|
125
|
+
if (wantsAncestors && !hasPedigree) {
|
|
126
|
+
warnings.push('Server does not expose /germplasm/{id}/pedigree — ancestor traversal is skipped.');
|
|
127
|
+
}
|
|
128
|
+
if (wantsDescendants && !hasProgeny) {
|
|
129
|
+
warnings.push('Server does not expose /germplasm/{id}/progeny — descendant traversal is skipped.');
|
|
130
|
+
}
|
|
131
|
+
if (hasPedigree) {
|
|
132
|
+
const missing = await Promise.all(input.germplasmDbIds.map(async (id) => (await rootExists(id, client, connection, ctx)) ? null : id));
|
|
133
|
+
for (const id of missing) {
|
|
134
|
+
if (id)
|
|
135
|
+
warnings.push(`Root germplasm '${id}' was not found in /germplasm/{id}/pedigree.`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const state = createWalkState(input.germplasmDbIds);
|
|
139
|
+
let truncated = false;
|
|
140
|
+
let cycleCount = 0;
|
|
141
|
+
let deadEndCount = 0;
|
|
142
|
+
let depthReached = 0;
|
|
143
|
+
for (let depth = 1; depth <= input.maxDepth; depth++) {
|
|
144
|
+
if (state.nodes.size >= MAX_NODES) {
|
|
145
|
+
truncated = true;
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
const previousFrontier = state.frontier;
|
|
149
|
+
state.frontier = new Set();
|
|
150
|
+
if (previousFrontier.size === 0)
|
|
151
|
+
break;
|
|
152
|
+
const exp = await Promise.all(Array.from(previousFrontier).map(async (id) => expandNode(id, {
|
|
153
|
+
client,
|
|
154
|
+
connection,
|
|
155
|
+
ctx,
|
|
156
|
+
walkAncestors: wantsAncestors && hasPedigree,
|
|
157
|
+
walkDescendants: wantsDescendants && hasProgeny,
|
|
158
|
+
})));
|
|
159
|
+
let producedEdge = false;
|
|
160
|
+
for (const result of exp) {
|
|
161
|
+
if (result.kind === 'deadEnd') {
|
|
162
|
+
deadEndCount++;
|
|
163
|
+
warnings.push(`Expansion failed for ${result.id}: ${result.error}`);
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
for (const parent of result.parents) {
|
|
167
|
+
const already = state.nodes.has(parent.germplasmDbId);
|
|
168
|
+
registerNode(state, parent.germplasmDbId, parent.germplasmName, depth);
|
|
169
|
+
const edge = {
|
|
170
|
+
from: parent.germplasmDbId,
|
|
171
|
+
to: result.id,
|
|
172
|
+
relationship: 'parent',
|
|
173
|
+
};
|
|
174
|
+
if (parent.parentType)
|
|
175
|
+
edge.parentType = parent.parentType;
|
|
176
|
+
const inverseKnown = isInverseEdgeKnown(state, edge);
|
|
177
|
+
if (addEdge(state, edge))
|
|
178
|
+
producedEdge = true;
|
|
179
|
+
if (already) {
|
|
180
|
+
// direction='both' walks BFS in two directions concurrently — we
|
|
181
|
+
// expect to re-encounter nodes via the inverse relationship as the
|
|
182
|
+
// expansions meet. That's a structural symmetry, not a cycle.
|
|
183
|
+
if (!inverseKnown)
|
|
184
|
+
cycleCount++;
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
state.frontier.add(parent.germplasmDbId);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
for (const child of result.children) {
|
|
191
|
+
const already = state.nodes.has(child.germplasmDbId);
|
|
192
|
+
registerNode(state, child.germplasmDbId, child.germplasmName, depth);
|
|
193
|
+
const edge = {
|
|
194
|
+
from: child.germplasmDbId,
|
|
195
|
+
to: result.id,
|
|
196
|
+
relationship: 'child',
|
|
197
|
+
};
|
|
198
|
+
const inverseKnown = isInverseEdgeKnown(state, edge);
|
|
199
|
+
if (addEdge(state, edge))
|
|
200
|
+
producedEdge = true;
|
|
201
|
+
if (already) {
|
|
202
|
+
if (!inverseKnown)
|
|
203
|
+
cycleCount++;
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
state.frontier.add(child.germplasmDbId);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (producedEdge)
|
|
211
|
+
depthReached = depth;
|
|
212
|
+
if (state.frontier.size === 0)
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
const nodes = Array.from(state.nodes.values()).sort((a, b) => a.depth - b.depth || a.germplasmDbId.localeCompare(b.germplasmDbId));
|
|
216
|
+
const edges = Array.from(state.edges.values());
|
|
217
|
+
const leafCount = computeLeafCount(nodes, edges);
|
|
218
|
+
const result = {
|
|
219
|
+
alias: connection.alias,
|
|
220
|
+
direction: input.direction,
|
|
221
|
+
maxDepth: input.maxDepth,
|
|
222
|
+
nodes,
|
|
223
|
+
edges,
|
|
224
|
+
depthReached,
|
|
225
|
+
rootCount: input.germplasmDbIds.length,
|
|
226
|
+
leafCount,
|
|
227
|
+
cycleCount,
|
|
228
|
+
deadEndCount,
|
|
229
|
+
truncated,
|
|
230
|
+
warnings,
|
|
231
|
+
};
|
|
232
|
+
return result;
|
|
233
|
+
},
|
|
234
|
+
format: (result) => {
|
|
235
|
+
const lines = [];
|
|
236
|
+
lines.push(`# Pedigree walk — ${result.direction}, depth ${result.depthReached}/${result.maxDepth} — \`${result.alias}\``);
|
|
237
|
+
lines.push('');
|
|
238
|
+
lines.push('## Stats');
|
|
239
|
+
lines.push(`- nodes: ${result.nodes.length}`);
|
|
240
|
+
lines.push(`- edges: ${result.edges.length}`);
|
|
241
|
+
lines.push(`- rootCount: ${result.rootCount}`);
|
|
242
|
+
lines.push(`- leafCount: ${result.leafCount}`);
|
|
243
|
+
lines.push(`- cycleCount: ${result.cycleCount}`);
|
|
244
|
+
lines.push(`- deadEndCount: ${result.deadEndCount}`);
|
|
245
|
+
lines.push(`- truncated: ${result.truncated}`);
|
|
246
|
+
if (result.nodes.length > 0) {
|
|
247
|
+
lines.push('');
|
|
248
|
+
lines.push('## Nodes');
|
|
249
|
+
for (const node of result.nodes) {
|
|
250
|
+
const parts = [`**${node.germplasmName ?? node.germplasmDbId}**`];
|
|
251
|
+
parts.push(`id=\`${node.germplasmDbId}\``);
|
|
252
|
+
parts.push(`depth=${node.depth}`);
|
|
253
|
+
if (node.isRoot)
|
|
254
|
+
parts.push('root');
|
|
255
|
+
lines.push(`- ${parts.join(' · ')}`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (result.edges.length > 0) {
|
|
259
|
+
lines.push('');
|
|
260
|
+
lines.push('## Edges');
|
|
261
|
+
for (const edge of result.edges) {
|
|
262
|
+
const suffix = edge.parentType ? ` (${edge.parentType})` : '';
|
|
263
|
+
const arrow = edge.relationship === 'parent' ? '→' : '←';
|
|
264
|
+
lines.push(`- \`${edge.from}\` ${arrow} \`${edge.to}\` · ${edge.relationship}${suffix}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (result.warnings.length > 0) {
|
|
268
|
+
lines.push('');
|
|
269
|
+
lines.push('## Warnings');
|
|
270
|
+
for (const w of result.warnings)
|
|
271
|
+
lines.push(`- ${w}`);
|
|
272
|
+
}
|
|
273
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
function createWalkState(rootIds) {
|
|
277
|
+
const nodes = new Map();
|
|
278
|
+
const frontier = new Set();
|
|
279
|
+
for (const id of rootIds) {
|
|
280
|
+
nodes.set(id, { germplasmDbId: id, depth: 0, isRoot: true });
|
|
281
|
+
frontier.add(id);
|
|
282
|
+
}
|
|
283
|
+
return { nodes, edges: new Map(), frontier };
|
|
284
|
+
}
|
|
285
|
+
function registerNode(state, id, name, depth) {
|
|
286
|
+
const existing = state.nodes.get(id);
|
|
287
|
+
if (existing) {
|
|
288
|
+
if (!existing.germplasmName && name)
|
|
289
|
+
existing.germplasmName = name;
|
|
290
|
+
if (depth < existing.depth)
|
|
291
|
+
existing.depth = depth;
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const node = { germplasmDbId: id, depth, isRoot: false };
|
|
295
|
+
if (name)
|
|
296
|
+
node.germplasmName = name;
|
|
297
|
+
state.nodes.set(id, node);
|
|
298
|
+
}
|
|
299
|
+
function addEdge(state, edge) {
|
|
300
|
+
const key = `${edge.relationship}:${edge.from}→${edge.to}`;
|
|
301
|
+
if (state.edges.has(key))
|
|
302
|
+
return false;
|
|
303
|
+
state.edges.set(key, edge);
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* `parent: A→B` and `child: B→A` describe the same biological relationship
|
|
308
|
+
* from opposite ends. When direction='both', BFS will discover both —
|
|
309
|
+
* detecting the inverse lets us avoid double-counting it as a cycle.
|
|
310
|
+
*/
|
|
311
|
+
function isInverseEdgeKnown(state, edge) {
|
|
312
|
+
const inverseRel = edge.relationship === 'parent' ? 'child' : 'parent';
|
|
313
|
+
return state.edges.has(`${inverseRel}:${edge.to}→${edge.from}`);
|
|
314
|
+
}
|
|
315
|
+
async function expandNode(id, input) {
|
|
316
|
+
try {
|
|
317
|
+
const encoded = encodeURIComponent(id);
|
|
318
|
+
const [pedigree, progeny] = await Promise.all([
|
|
319
|
+
input.walkAncestors
|
|
320
|
+
? fetchPedigree(input.client, input.connection, encoded, input.ctx)
|
|
321
|
+
: Promise.resolve([]),
|
|
322
|
+
input.walkDescendants
|
|
323
|
+
? fetchProgeny(input.client, input.connection, encoded, input.ctx)
|
|
324
|
+
: Promise.resolve([]),
|
|
325
|
+
]);
|
|
326
|
+
return { kind: 'ok', id, parents: pedigree, children: progeny };
|
|
327
|
+
}
|
|
328
|
+
catch (err) {
|
|
329
|
+
return {
|
|
330
|
+
kind: 'deadEnd',
|
|
331
|
+
id,
|
|
332
|
+
error: err instanceof Error ? err.message : String(err),
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
async function rootExists(id, client, connection, ctx) {
|
|
337
|
+
try {
|
|
338
|
+
const env = await client.get(connection.baseUrl, `/germplasm/${encodeURIComponent(id)}/pedigree`, ctx, buildRequestOptions(connection));
|
|
339
|
+
// Some servers (e.g. test-server.brapi.org) reply 200 with `result: null`
|
|
340
|
+
// for unknown germplasm instead of 404.
|
|
341
|
+
return env.result != null;
|
|
342
|
+
}
|
|
343
|
+
catch (err) {
|
|
344
|
+
if (isUpstreamNotFound(err))
|
|
345
|
+
return false;
|
|
346
|
+
// Non-404 errors get surfaced when the BFS later expands the node.
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
async function fetchPedigree(client, connection, encodedId, ctx) {
|
|
351
|
+
const env = await client.get(connection.baseUrl, `/germplasm/${encodedId}/pedigree`, ctx, buildRequestOptions(connection));
|
|
352
|
+
const rawParents = env.result?.parents;
|
|
353
|
+
if (!Array.isArray(rawParents))
|
|
354
|
+
return [];
|
|
355
|
+
const parents = [];
|
|
356
|
+
for (const entry of rawParents) {
|
|
357
|
+
if (typeof entry !== 'object' || entry === null)
|
|
358
|
+
continue;
|
|
359
|
+
const record = entry;
|
|
360
|
+
const dbId = record.germplasmDbId;
|
|
361
|
+
if (typeof dbId !== 'string' || dbId.length === 0)
|
|
362
|
+
continue;
|
|
363
|
+
const item = {
|
|
364
|
+
germplasmDbId: dbId,
|
|
365
|
+
};
|
|
366
|
+
if (typeof record.germplasmName === 'string')
|
|
367
|
+
item.germplasmName = record.germplasmName;
|
|
368
|
+
if (typeof record.parentType === 'string')
|
|
369
|
+
item.parentType = record.parentType;
|
|
370
|
+
parents.push(item);
|
|
371
|
+
}
|
|
372
|
+
return parents;
|
|
373
|
+
}
|
|
374
|
+
async function fetchProgeny(client, connection, encodedId, ctx) {
|
|
375
|
+
const env = await client.get(connection.baseUrl, `/germplasm/${encodedId}/progeny`, ctx, buildRequestOptions(connection));
|
|
376
|
+
const result = env.result;
|
|
377
|
+
const rawProgeny = result?.progeny;
|
|
378
|
+
const fallback = Array.isArray(rawProgeny)
|
|
379
|
+
? rawProgeny
|
|
380
|
+
: Array.isArray(result?.data)
|
|
381
|
+
? result.data
|
|
382
|
+
: [];
|
|
383
|
+
const children = [];
|
|
384
|
+
for (const entry of fallback) {
|
|
385
|
+
if (typeof entry !== 'object' || entry === null)
|
|
386
|
+
continue;
|
|
387
|
+
const record = entry;
|
|
388
|
+
const dbId = record.germplasmDbId;
|
|
389
|
+
if (typeof dbId !== 'string' || dbId.length === 0)
|
|
390
|
+
continue;
|
|
391
|
+
const item = { germplasmDbId: dbId };
|
|
392
|
+
if (typeof record.germplasmName === 'string')
|
|
393
|
+
item.germplasmName = record.germplasmName;
|
|
394
|
+
children.push(item);
|
|
395
|
+
}
|
|
396
|
+
return children;
|
|
397
|
+
}
|
|
398
|
+
function computeLeafCount(nodes, edges) {
|
|
399
|
+
// A leaf has no outgoing edge (in the walked direction). For 'parent'
|
|
400
|
+
// edges, `from` is the parent — so nodes that never appear as `from` in
|
|
401
|
+
// parent edges are ancestry-leaves. For 'child' edges, nodes that never
|
|
402
|
+
// appear as `from` in child edges are descendancy-leaves.
|
|
403
|
+
const parentSources = new Set();
|
|
404
|
+
const childSources = new Set();
|
|
405
|
+
for (const edge of edges) {
|
|
406
|
+
if (edge.relationship === 'parent')
|
|
407
|
+
parentSources.add(edge.from);
|
|
408
|
+
else
|
|
409
|
+
childSources.add(edge.from);
|
|
410
|
+
}
|
|
411
|
+
let leaves = 0;
|
|
412
|
+
for (const node of nodes) {
|
|
413
|
+
const hasParentOut = parentSources.has(node.germplasmDbId);
|
|
414
|
+
const hasChildOut = childSources.has(node.germplasmDbId);
|
|
415
|
+
if (!hasParentOut && !hasChildOut)
|
|
416
|
+
leaves++;
|
|
417
|
+
}
|
|
418
|
+
return leaves;
|
|
419
|
+
}
|
|
420
|
+
//# sourceMappingURL=brapi-walk-pedigree.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brapi-walk-pedigree.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/brapi-walk-pedigree.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared Zod discriminated union for BrAPI connection auth.
|
|
3
|
+
* Used by `brapi_connect` and, later, by any tool that needs to accept an
|
|
4
|
+
* inline auth payload.
|
|
5
|
+
*
|
|
6
|
+
* @module mcp-server/tools/shared/connect-auth-schema
|
|
7
|
+
*/
|
|
8
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
9
|
+
export declare const ConnectAuthSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
10
|
+
mode: z.ZodLiteral<"none">;
|
|
11
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
12
|
+
mode: z.ZodLiteral<"bearer">;
|
|
13
|
+
token: z.ZodString;
|
|
14
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
15
|
+
mode: z.ZodLiteral<"api_key">;
|
|
16
|
+
apiKey: z.ZodString;
|
|
17
|
+
headerName: z.ZodOptional<z.ZodString>;
|
|
18
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
19
|
+
mode: z.ZodLiteral<"sgn">;
|
|
20
|
+
username: z.ZodString;
|
|
21
|
+
password: z.ZodString;
|
|
22
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
23
|
+
mode: z.ZodLiteral<"oauth2">;
|
|
24
|
+
clientId: z.ZodString;
|
|
25
|
+
clientSecret: z.ZodString;
|
|
26
|
+
tokenUrl: z.ZodOptional<z.ZodString>;
|
|
27
|
+
}, z.core.$strip>], "mode">;
|
|
28
|
+
export type ConnectAuthInput = z.infer<typeof ConnectAuthSchema>;
|
|
29
|
+
//# sourceMappingURL=connect-auth-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect-auth-schema.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/shared/connect-auth-schema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAE3C,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;2BAiD3B,CAAC;AAEJ,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared Zod discriminated union for BrAPI connection auth.
|
|
3
|
+
* Used by `brapi_connect` and, later, by any tool that needs to accept an
|
|
4
|
+
* inline auth payload.
|
|
5
|
+
*
|
|
6
|
+
* @module mcp-server/tools/shared/connect-auth-schema
|
|
7
|
+
*/
|
|
8
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
9
|
+
export const ConnectAuthSchema = z
|
|
10
|
+
.discriminatedUnion('mode', [
|
|
11
|
+
z
|
|
12
|
+
.object({ mode: z.literal('none').describe('No authentication.') })
|
|
13
|
+
.describe('No-auth variant — public BrAPI endpoints.'),
|
|
14
|
+
z
|
|
15
|
+
.object({
|
|
16
|
+
mode: z.literal('bearer').describe('Pre-obtained bearer token.'),
|
|
17
|
+
token: z.string().min(1).describe('Raw token; sent as "Authorization: Bearer <token>".'),
|
|
18
|
+
})
|
|
19
|
+
.describe('Bearer-token variant — caller already has an access token.'),
|
|
20
|
+
z
|
|
21
|
+
.object({
|
|
22
|
+
mode: z.literal('api_key').describe('Static API key in a custom header.'),
|
|
23
|
+
apiKey: z.string().min(1).describe('API key value.'),
|
|
24
|
+
headerName: z
|
|
25
|
+
.string()
|
|
26
|
+
.optional()
|
|
27
|
+
.describe('Header name. Defaults to `Authorization` (or BRAPI_DEFAULT_API_KEY_HEADER).'),
|
|
28
|
+
})
|
|
29
|
+
.describe('API-key variant — static key sent in a configurable header.'),
|
|
30
|
+
z
|
|
31
|
+
.object({
|
|
32
|
+
mode: z
|
|
33
|
+
.literal('sgn')
|
|
34
|
+
.describe('Breedbase/SGN username+password; exchanged for a bearer token at /token.'),
|
|
35
|
+
username: z.string().min(1).describe('SGN account username.'),
|
|
36
|
+
password: z.string().min(1).describe('SGN account password.'),
|
|
37
|
+
})
|
|
38
|
+
.describe('SGN variant — username/password exchanged at /token for a session bearer.'),
|
|
39
|
+
z
|
|
40
|
+
.object({
|
|
41
|
+
mode: z
|
|
42
|
+
.literal('oauth2')
|
|
43
|
+
.describe('OAuth2 client-credentials flow. Not yet implemented — use mode="bearer".'),
|
|
44
|
+
clientId: z.string().min(1).describe('OAuth2 client ID.'),
|
|
45
|
+
clientSecret: z.string().min(1).describe('OAuth2 client secret.'),
|
|
46
|
+
tokenUrl: z
|
|
47
|
+
.string()
|
|
48
|
+
.url()
|
|
49
|
+
.optional()
|
|
50
|
+
.describe('OAuth2 token endpoint URL. Defaults derived from the base URL when omitted.'),
|
|
51
|
+
})
|
|
52
|
+
.describe('OAuth2 client-credentials variant (accepted at schema level, rejected at runtime).'),
|
|
53
|
+
])
|
|
54
|
+
.describe('Connection auth configuration. Discriminated by `mode`. Omit the entire `auth` field for no-auth servers.');
|
|
55
|
+
//# sourceMappingURL=connect-auth-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect-auth-schema.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/shared/connect-auth-schema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAE3C,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC;KAC/B,kBAAkB,CAAC,MAAM,EAAE;IAC1B,CAAC;SACE,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;SAClE,QAAQ,CAAC,2CAA2C,CAAC;IACxD,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,4BAA4B,CAAC;QAChE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,qDAAqD,CAAC;KACzF,CAAC;SACD,QAAQ,CAAC,4DAA4D,CAAC;IACzE,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,oCAAoC,CAAC;QACzE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QACpD,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,6EAA6E,CAAC;KAC3F,CAAC;SACD,QAAQ,CAAC,6DAA6D,CAAC;IAC1E,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC;aACJ,OAAO,CAAC,KAAK,CAAC;aACd,QAAQ,CAAC,0EAA0E,CAAC;QACvF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QAC7D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC;KAC9D,CAAC;SACD,QAAQ,CAAC,2EAA2E,CAAC;IACxF,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC;aACJ,OAAO,CAAC,QAAQ,CAAC;aACjB,QAAQ,CAAC,0EAA0E,CAAC;QACvF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QACzD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QACjE,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,GAAG,EAAE;aACL,QAAQ,EAAE;aACV,QAAQ,CAAC,6EAA6E,CAAC;KAC3F,CAAC;SACD,QAAQ,CACP,oFAAoF,CACrF;CACJ,CAAC;KACD,QAAQ,CACP,2GAA2G,CAC5G,CAAC"}
|