@ontrails/mcp 1.0.0-beta.18 → 1.0.0-beta.19

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/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # @ontrails/mcp
2
2
 
3
+ ## 1.0.0-beta.19
4
+
5
+ ### Patch Changes
6
+
7
+ - e41c382: Document beta-channel install guidance in package and adapter README install snippets so consumers use explicit `@beta` (or pinned `1.0.0-beta.N`) tags instead of accidental `latest` resolution during the prerelease line. Adds the policy doc at `docs/releases/beta-channel-policy.md`, prints both `latest` and `beta` dist-tags in `bun run publish:registry-check`, and aligns plugin/skill install snippets.
8
+ - 1eb5bdc: Rename first-class trail composition from the `cross` API family to the `compose` family across core contracts, testing helpers, topo projections, Warden rules, CLI scaffolds, and docs. `composes`, `ctx.compose`, `composeInput`, and `Compose*` type names are now the public authoring vocabulary; topo persistence migrates legacy composition rows and graph keys forward.
9
+ - 8638dae: Add a public API example for MCP `deriveAnnotations` annotation derivation.
10
+ - 8638dae: Add public API examples for the MCP tool metadata keys.
11
+ - 8638dae: Add a public API example for the MCP progress callback bridge.
12
+ - 84f56a5: Project live trail-version metadata on CLI, HTTP, and MCP surfaces and thread explicit surface version selection into shared trail execution.
13
+ - 5d88104: Polish Trails blaze terminology across package docs and Warden guidance.
14
+ - Updated dependencies [e41c382]
15
+ - Updated dependencies [1eb5bdc]
16
+ - Updated dependencies [f8d80b9]
17
+ - Updated dependencies [846a597]
18
+ - Updated dependencies [223aaad]
19
+ - Updated dependencies [3125f4d]
20
+ - Updated dependencies [2494dc6]
21
+ - Updated dependencies [2d53717]
22
+ - Updated dependencies [16cb740]
23
+ - Updated dependencies [8894ecb]
24
+ - Updated dependencies [fdf7ec9]
25
+ - Updated dependencies [d76be13]
26
+ - Updated dependencies [84f56a5]
27
+ - Updated dependencies [431b04c]
28
+ - Updated dependencies [5d88104]
29
+ - Updated dependencies [f04a9ef]
30
+ - @ontrails/core@1.0.0-beta.19
31
+
3
32
  ## 1.0.0-beta.18
4
33
 
5
34
  ### Patch Changes
package/README.md CHANGED
@@ -85,11 +85,11 @@ Trail IDs become MCP tool names with the app prefix: `entity.show` in app `myapp
85
85
 
86
86
  ## Resource resolution
87
87
 
88
- Declared resources on each trail are resolved into the context before the implementation runs.
88
+ Declared resources on each trail are resolved into the context before the blaze receives input.
89
89
 
90
90
  ## Progress bridge
91
91
 
92
- Implementations report progress through `ctx.progress`. On MCP, these bridge to `notifications/progress` when the client sends a `progressToken`:
92
+ Blazes report progress through `ctx.progress`. On MCP, these bridge to `notifications/progress` when the client sends a `progressToken`:
93
93
 
94
94
  ```typescript
95
95
  const importTrail = trail('data.import', {
@@ -110,11 +110,10 @@ await surface(graph, { include: ['entity.**', 'search'] });
110
110
  await surface(graph, { exclude: ['internal.debug'] });
111
111
  ```
112
112
 
113
- `*` matches one dotted segment and `**` matches any depth. Trails declared with
114
- `visibility: 'internal'` stay hidden unless you include their exact trail ID.
113
+ `*` matches one dotted segment and `**` matches any depth. Trails declared with `visibility: 'internal'` stay hidden unless you include their exact trail ID.
115
114
 
116
115
  ## Installation
117
116
 
118
117
  ```bash
119
- bun add @ontrails/mcp
118
+ bun add @ontrails/mcp@beta
120
119
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ontrails/mcp",
3
- "version": "1.0.0-beta.18",
3
+ "version": "1.0.0-beta.19",
4
4
  "files": [
5
5
  "src/**/*.ts",
6
6
  "!src/**/__tests__/**",
@@ -22,7 +22,7 @@
22
22
  "clean": "rm -rf dist *.tsbuildinfo"
23
23
  },
24
24
  "dependencies": {
25
- "@ontrails/core": "^1.0.0-beta.17"
25
+ "@ontrails/core": "^1.0.0-beta.19"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "@modelcontextprotocol/sdk": "^1.28.0",
@@ -25,6 +25,26 @@ export interface McpAnnotations {
25
25
  *
26
26
  * Only sets hints that are explicitly declared on the trail.
27
27
  * Omitted hints let the MCP SDK use its defaults.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * import { deriveAnnotations } from '@ontrails/mcp';
32
+ *
33
+ * const annotations = deriveAnnotations({
34
+ * intent: 'read',
35
+ * idempotent: true,
36
+ * description: 'Show account',
37
+ * });
38
+ *
39
+ * // read intent -> readOnlyHint, idempotent -> idempotentHint, description -> title.
40
+ * annotations.readOnlyHint === true;
41
+ * annotations.idempotentHint === true;
42
+ * annotations.title === 'Show account';
43
+ *
44
+ * // destroy intent -> destructiveHint.
45
+ * const destroyAnnotations = deriveAnnotations({ intent: 'destroy' });
46
+ * destroyAnnotations.destructiveHint === true;
47
+ * ```
28
48
  */
29
49
  export const deriveAnnotations = (
30
50
  trail: Pick<
package/src/build.ts CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  Result,
12
12
  ValidationError,
13
13
  collectAttachedTypedLayers,
14
+ deriveSurfaceTrailVersionProjections,
14
15
  deriveStructuredTrailExamples,
15
16
  executeTrail,
16
17
  filterSurfaceTrails,
@@ -32,9 +33,11 @@ import type {
32
33
  Layer,
33
34
  ResourceOverrideMap,
34
35
  SurfaceErrorProjection,
36
+ SurfaceTrailVersionProjection,
35
37
  Topo,
36
38
  Trail,
37
39
  TrailContextInit,
40
+ TrailVersionReference,
38
41
  } from '@ontrails/core';
39
42
 
40
43
  import type { McpAnnotations } from './annotations.js';
@@ -42,8 +45,28 @@ import { deriveAnnotations } from './annotations.js';
42
45
  import { createMcpProgressCallback } from './progress.js';
43
46
  import { deriveToolName } from './tool-name.js';
44
47
 
48
+ /**
49
+ * Metadata key used for structured trail examples on derived MCP tools.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * import { MCP_TOOL_EXAMPLES_META_KEY } from '@ontrails/mcp';
54
+ *
55
+ * const examples = tool._meta?.[MCP_TOOL_EXAMPLES_META_KEY];
56
+ * ```
57
+ */
45
58
  export const MCP_TOOL_EXAMPLES_META_KEY = 'ontrails/examples';
46
59
 
60
+ /**
61
+ * Metadata key used for public Trails error projections on MCP tool errors.
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * import { MCP_TOOL_ERROR_META_KEY } from '@ontrails/mcp';
66
+ *
67
+ * const error = result._meta?.[MCP_TOOL_ERROR_META_KEY];
68
+ * ```
69
+ */
47
70
  export const MCP_TOOL_ERROR_META_KEY = 'ontrails/error';
48
71
 
49
72
  // ---------------------------------------------------------------------------
@@ -84,6 +107,7 @@ export interface McpToolDefinition {
84
107
  readonly outputSchema?: Record<string, unknown> | undefined;
85
108
  /** The trail ID this tool was derived from. */
86
109
  readonly trailId: string;
110
+ readonly versions?: readonly SurfaceTrailVersionProjection[] | undefined;
87
111
  }
88
112
 
89
113
  export interface McpExtra {
@@ -602,6 +626,48 @@ const projectMcpInputSchema = (
602
626
  return { projections, schema: mergedSchema };
603
627
  };
604
628
 
629
+ const TRAIL_VERSION_PARAM = 'trailVersion';
630
+
631
+ const addMcpVersionInputSchema = (
632
+ trail: Trail<unknown, unknown, unknown>,
633
+ schema: Record<string, unknown>
634
+ ): Record<string, unknown> => {
635
+ if (trail.version === undefined) {
636
+ return schema;
637
+ }
638
+ const properties =
639
+ isJsonObjectSchema(schema) && schema.properties !== undefined
640
+ ? schema.properties
641
+ : undefined;
642
+ return {
643
+ ...schema,
644
+ properties: {
645
+ ...properties,
646
+ [TRAIL_VERSION_PARAM]: {
647
+ description: 'Live trail version number or marker prefix',
648
+ type: 'string',
649
+ },
650
+ },
651
+ type: 'object',
652
+ };
653
+ };
654
+
655
+ const splitMcpSurfaceVersion = (
656
+ args: Record<string, unknown>
657
+ ): {
658
+ readonly args: Record<string, unknown>;
659
+ readonly version: TrailVersionReference | undefined;
660
+ } => {
661
+ const { [TRAIL_VERSION_PARAM]: rawVersion, ...rest } = args;
662
+ return {
663
+ args: rest,
664
+ version:
665
+ typeof rawVersion === 'string' || typeof rawVersion === 'number'
666
+ ? rawVersion
667
+ : undefined,
668
+ };
669
+ };
670
+
605
671
  /**
606
672
  * Partition a parsed MCP `args` record into the trail input plus per-layer
607
673
  * inputs, using each layer's routing table.
@@ -750,8 +816,12 @@ const createHandler =
750
816
  ) => Promise<McpToolResult>) =>
751
817
  async (args, extra): Promise<McpToolResult> => {
752
818
  const progressCb = createMcpProgressCallback(extra);
819
+ const versionedArgs =
820
+ t.version === undefined
821
+ ? { args, version: undefined }
822
+ : splitMcpSurfaceVersion(args);
753
823
  const { trailInput, layerInputs } = partitionMcpArgs(
754
- args,
824
+ versionedArgs.args,
755
825
  layerProjections
756
826
  );
757
827
  const permitResolution = await resolveMcpPermit(options, extra);
@@ -770,6 +840,9 @@ const createHandler =
770
840
  surfaceLayers: layers,
771
841
  topo: graph,
772
842
  topoLayers: graph.layers,
843
+ ...(versionedArgs.version === undefined
844
+ ? {}
845
+ : { version: versionedArgs.version }),
773
846
  });
774
847
  if (result.isOk()) {
775
848
  return {
@@ -867,6 +940,8 @@ const buildToolDefinition = (
867
940
  options.layers
868
941
  );
869
942
  const inputProjection = projectMcpInputSchema(trail, attachedLayers);
943
+ const inputSchema = addMcpVersionInputSchema(trail, inputProjection.schema);
944
+ const versions = deriveSurfaceTrailVersionProjections(trail);
870
945
  return {
871
946
  _meta: buildMeta(trail),
872
947
  annotations,
@@ -879,10 +954,11 @@ const buildToolDefinition = (
879
954
  projection?.wrapAsData ?? false,
880
955
  inputProjection.projections
881
956
  ),
882
- inputSchema: inputProjection.schema,
957
+ inputSchema,
883
958
  name: deriveToolName(graph.name, trail.id),
884
959
  outputSchema: projection?.schema,
885
960
  trailId: trail.id,
961
+ ...(versions === undefined ? {} : { versions }),
886
962
  };
887
963
  };
888
964
 
package/src/progress.ts CHANGED
@@ -54,6 +54,28 @@ const progressHandlers: Record<
54
54
  *
55
55
  * Returns `undefined` if the MCP client did not provide a progressToken
56
56
  * (meaning no progress reporting was requested).
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * import { createMcpProgressCallback, type McpExtra } from '@ontrails/mcp';
61
+ *
62
+ * const extra: McpExtra = {
63
+ * progressToken: 'token-123',
64
+ * sendProgress: async (current, total) => {
65
+ * console.log(`progress ${current}/${total}`);
66
+ * },
67
+ * };
68
+ *
69
+ * const progress = createMcpProgressCallback(extra);
70
+ * if (progress !== undefined) {
71
+ * progress({
72
+ * current: 0,
73
+ * ts: new Date().toISOString(),
74
+ * total: 1,
75
+ * type: 'start',
76
+ * });
77
+ * }
78
+ * ```
57
79
  */
58
80
  export const createMcpProgressCallback = (
59
81
  extra: McpExtra