@ontrails/mcp 1.0.0-beta.11 → 1.0.0-beta.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/src/build.ts CHANGED
@@ -2,12 +2,13 @@
2
2
  * Build MCP tool definitions from a Trails App.
3
3
  *
4
4
  * Iterates the topo, generates McpToolDefinition[] with handlers that
5
- * validate input, compose layers, execute the implementation, and map
5
+ * validate input, compose gates, execute the implementation, and map
6
6
  * Results to MCP responses.
7
7
  */
8
8
 
9
9
  import {
10
10
  Result,
11
+ TRAILHEAD_KEY,
11
12
  ValidationError,
12
13
  executeTrail,
13
14
  isBlobRef,
@@ -15,8 +16,8 @@ import {
15
16
  } from '@ontrails/core';
16
17
  import type {
17
18
  BlobRef,
18
- Layer,
19
- ServiceOverrideMap,
19
+ Gate,
20
+ ProvisionOverrideMap,
20
21
  Topo,
21
22
  Trail,
22
23
  TrailContextInit,
@@ -32,13 +33,17 @@ import { deriveToolName } from './tool-name.js';
32
33
  // ---------------------------------------------------------------------------
33
34
 
34
35
  export interface BuildMcpToolsOptions {
36
+ /** Config values for provisions that declare a `config` schema, keyed by provision ID. */
37
+ readonly configValues?:
38
+ | Readonly<Record<string, Record<string, unknown>>>
39
+ | undefined;
35
40
  readonly createContext?:
36
41
  | (() => TrailContextInit | Promise<TrailContextInit>)
37
42
  | undefined;
38
43
  readonly excludeTrails?: readonly string[] | undefined;
39
44
  readonly includeTrails?: readonly string[] | undefined;
40
- readonly layers?: readonly Layer[] | undefined;
41
- readonly services?: ServiceOverrideMap | undefined;
45
+ readonly gates?: readonly Gate[] | undefined;
46
+ readonly provisions?: ProvisionOverrideMap | undefined;
42
47
  }
43
48
 
44
49
  export interface McpToolDefinition {
@@ -59,7 +64,7 @@ export interface McpExtra {
59
64
  readonly sendProgress?:
60
65
  | ((current: number, total: number) => Promise<void>)
61
66
  | undefined;
62
- readonly signal?: AbortSignal | undefined;
67
+ readonly abortSignal?: AbortSignal | undefined;
63
68
  }
64
69
 
65
70
  export interface McpToolResult {
@@ -207,10 +212,20 @@ const mcpError = (message: string): McpToolResult => ({
207
212
  isError: true,
208
213
  });
209
214
 
215
+ /** Add the MCP trailhead marker while preserving any existing context extras. */
216
+ const withMcpTrailhead = (
217
+ progressCb: TrailContextInit['progress']
218
+ ): Partial<TrailContextInit> => ({
219
+ ...(progressCb === undefined ? {} : { progress: progressCb }),
220
+ extensions: {
221
+ [TRAILHEAD_KEY]: 'mcp' as const,
222
+ },
223
+ });
224
+
210
225
  const createHandler =
211
226
  (
212
227
  t: Trail<unknown, unknown>,
213
- layers: readonly Layer[],
228
+ gates: readonly Gate[],
214
229
  options: BuildMcpToolsOptions
215
230
  ): ((
216
231
  args: Record<string, unknown>,
@@ -219,11 +234,12 @@ const createHandler =
219
234
  async (args, extra): Promise<McpToolResult> => {
220
235
  const progressCb = createMcpProgressCallback(extra);
221
236
  const result = await executeTrail(t, args, {
237
+ abortSignal: extra.abortSignal,
238
+ configValues: options.configValues,
222
239
  createContext: options.createContext,
223
- ctx: progressCb === undefined ? undefined : { progress: progressCb },
224
- layers,
225
- services: options.services,
226
- signal: extra.signal,
240
+ ctx: withMcpTrailhead(progressCb),
241
+ gates,
242
+ provisions: options.provisions,
227
243
  });
228
244
  if (result.isOk()) {
229
245
  return { content: await serializeOutput(result.value) };
@@ -241,15 +257,15 @@ const createHandler =
241
257
  * Each trail in the topo becomes an McpToolDefinition with:
242
258
  * - A derived tool name (app-prefixed, underscore-delimited)
243
259
  * - JSON Schema input from zodToJsonSchema
244
- * - MCP annotations from trail metadata
245
- * - A handler that validates, composes layers, executes, and maps results
260
+ * - MCP annotations from trail meta
261
+ * - A handler that validates, composes gates, executes, and maps results
246
262
  */
247
- /** Check if a trail should be included based on metadata and filters. */
263
+ /** Check if a trail should be included based on meta and filters. */
248
264
  const shouldInclude = (
249
265
  trail: Trail<unknown, unknown>,
250
266
  options: BuildMcpToolsOptions
251
267
  ): boolean => {
252
- if (trail.metadata?.['internal'] === true) {
268
+ if (trail.meta?.['internal'] === true) {
253
269
  return false;
254
270
  }
255
271
  if (options.includeTrails !== undefined && options.includeTrails.length > 0) {
@@ -286,7 +302,7 @@ const buildDescription = (
286
302
  const buildToolDefinition = (
287
303
  app: Topo,
288
304
  trail: Trail<unknown, unknown>,
289
- layers: readonly Layer[],
305
+ gates: readonly Gate[],
290
306
  options: BuildMcpToolsOptions
291
307
  ): McpToolDefinition => {
292
308
  const rawAnnotations = deriveAnnotations(trail);
@@ -295,7 +311,7 @@ const buildToolDefinition = (
295
311
  return {
296
312
  annotations,
297
313
  description: buildDescription(trail),
298
- handler: createHandler(trail, layers, options),
314
+ handler: createHandler(trail, gates, options),
299
315
  inputSchema: zodToJsonSchema(trail.input),
300
316
  name: deriveToolName(app.name, trail.id),
301
317
  trailId: trail.id,
@@ -306,7 +322,7 @@ const buildToolDefinition = (
306
322
  const registerTool = (
307
323
  app: Topo,
308
324
  trailItem: Trail<unknown, unknown>,
309
- layers: readonly Layer[],
325
+ gates: readonly Gate[],
310
326
  options: BuildMcpToolsOptions,
311
327
  nameToTrailId: Map<string, string>,
312
328
  tools: McpToolDefinition[]
@@ -321,7 +337,7 @@ const registerTool = (
321
337
  );
322
338
  }
323
339
  nameToTrailId.set(toolName, trailItem.id);
324
- tools.push(buildToolDefinition(app, trailItem, layers, options));
340
+ tools.push(buildToolDefinition(app, trailItem, gates, options));
325
341
  return Result.ok();
326
342
  };
327
343
 
@@ -336,7 +352,7 @@ export const buildMcpTools = (
336
352
  app: Topo,
337
353
  options: BuildMcpToolsOptions = {}
338
354
  ): Result<McpToolDefinition[], Error> => {
339
- const layers = options.layers ?? [];
355
+ const gates = options.gates ?? [];
340
356
  const tools: McpToolDefinition[] = [];
341
357
  const nameToTrailId = new Map<string, string>();
342
358
 
@@ -344,7 +360,7 @@ export const buildMcpTools = (
344
360
  const registered = registerTool(
345
361
  app,
346
362
  trailItem,
347
- layers,
363
+ gates,
348
364
  options,
349
365
  nameToTrailId,
350
366
  tools
package/src/index.ts CHANGED
@@ -17,8 +17,8 @@ export { deriveAnnotations, type McpAnnotations } from './annotations.js';
17
17
  // Progress
18
18
  export { createMcpProgressCallback } from './progress.js';
19
19
 
20
- // Blaze
21
- export { blaze, type BlazeMcpOptions } from './blaze.js';
20
+ // Trailhead
21
+ export { trailhead, type TrailheadMcpOptions } from './trailhead.js';
22
22
 
23
23
  // Transport
24
24
  export { connectStdio } from './stdio.js';
package/src/stdio.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Thin wrapper around MCP SDK's StdioServerTransport.
3
3
  *
4
4
  * Exists as a separate function so it can be swapped for other transports
5
- * (SSE, streamable HTTP) without changing blaze().
5
+ * (SSE, streamable HTTP) without changing trailhead().
6
6
  */
7
7
 
8
8
  import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
@@ -1,11 +1,11 @@
1
1
  /**
2
- * blaze() -- the one-liner MCP server launcher.
2
+ * trailhead() -- the one-liner MCP server launcher.
3
3
  *
4
4
  * Three lines to expose trails as MCP tools:
5
5
  *
6
6
  * ```ts
7
7
  * const app = topo("myapp", entity);
8
- * await blaze(app);
8
+ * await trailhead(app);
9
9
  * ```
10
10
  */
11
11
 
@@ -15,8 +15,8 @@ import {
15
15
  ListToolsRequestSchema,
16
16
  } from '@modelcontextprotocol/sdk/types.js';
17
17
  import type {
18
- Layer,
19
- ServiceOverrideMap,
18
+ Gate,
19
+ ProvisionOverrideMap,
20
20
  Topo,
21
21
  TrailContextInit,
22
22
  } from '@ontrails/core';
@@ -30,13 +30,18 @@ import { connectStdio } from './stdio.js';
30
30
  // Options
31
31
  // ---------------------------------------------------------------------------
32
32
 
33
- export interface BlazeMcpOptions {
33
+ export interface TrailheadMcpOptions {
34
+ /** Config values for provisions that declare a `config` schema, keyed by provision ID. */
35
+ readonly configValues?:
36
+ | Readonly<Record<string, Record<string, unknown>>>
37
+ | undefined;
34
38
  readonly createContext?:
35
39
  | (() => TrailContextInit | Promise<TrailContextInit>)
36
40
  | undefined;
37
41
  readonly excludeTrails?: readonly string[] | undefined;
38
42
  readonly includeTrails?: readonly string[] | undefined;
39
- readonly layers?: readonly Layer[] | undefined;
43
+ readonly gates?: readonly Gate[] | undefined;
44
+ readonly provisions?: ProvisionOverrideMap | undefined;
40
45
  readonly serverInfo?:
41
46
  | {
42
47
  readonly name?: string | undefined;
@@ -44,7 +49,6 @@ export interface BlazeMcpOptions {
44
49
  }
45
50
  | undefined;
46
51
  readonly transport?: 'stdio' | undefined;
47
- readonly services?: ServiceOverrideMap | undefined;
48
52
  /** Set to `false` to skip topo validation at startup. Defaults to `true`. */
49
53
  readonly validate?: boolean | undefined;
50
54
  }
@@ -115,9 +119,9 @@ export const createMcpServer = (
115
119
  };
116
120
 
117
121
  const extra = {
122
+ abortSignal: undefined as AbortSignal | undefined,
118
123
  progressToken,
119
124
  sendProgress,
120
- signal: undefined as AbortSignal | undefined,
121
125
  };
122
126
 
123
127
  const result = await tool.handler(args, extra);
@@ -129,15 +133,15 @@ export const createMcpServer = (
129
133
  };
130
134
 
131
135
  // ---------------------------------------------------------------------------
132
- // blaze
136
+ // trailhead
133
137
  // ---------------------------------------------------------------------------
134
138
 
135
139
  /**
136
140
  * Build MCP tools from an App, create a server, and connect via stdio.
137
141
  */
138
- export const blaze = async (
142
+ export const trailhead = async (
139
143
  app: Topo,
140
- options: BlazeMcpOptions = {}
144
+ options: TrailheadMcpOptions = {}
141
145
  ): Promise<void> => {
142
146
  if (options.validate !== false) {
143
147
  const validated = validateTopo(app);
@@ -147,11 +151,12 @@ export const blaze = async (
147
151
  }
148
152
 
149
153
  const toolsResult = buildMcpTools(app, {
154
+ configValues: options.configValues,
150
155
  createContext: options.createContext,
151
156
  excludeTrails: options.excludeTrails,
157
+ gates: options.gates,
152
158
  includeTrails: options.includeTrails,
153
- layers: options.layers,
154
- services: options.services,
159
+ provisions: options.provisions,
155
160
  });
156
161
 
157
162
  if (toolsResult.isErr()) {
@@ -1 +1 @@
1
- {"root":["./src/annotations.ts","./src/blaze.ts","./src/build.ts","./src/index.ts","./src/progress.ts","./src/stdio.ts","./src/tool-name.ts"],"version":"5.9.3"}
1
+ {"root":["./src/annotations.ts","./src/build.ts","./src/index.ts","./src/progress.ts","./src/stdio.ts","./src/tool-name.ts","./src/trailhead.ts"],"version":"5.9.3"}