@forestadmin/mcp-server 1.22.1 → 1.23.0

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/README.md CHANGED
@@ -21,6 +21,14 @@ This MCP server provides HTTP REST API access to Forest Admin operations, enabli
21
21
  | `getActionForm` | Get the form fields for a custom action |
22
22
  | `executeAction` | Execute a custom action |
23
23
  | `requestActionFileUpload` | Get a destination to upload a file to, for an action `File` field (only with `fileUploads`) |
24
+ | `listWorkflows` | List the MCP-enabled workflows in the caller's rendering, optionally filtered by collection |
25
+ | `triggerWorkflow` | Start a workflow run on a record, and return its `runId` |
26
+ | `getWorkflowRun` | Read a run started through MCP: its state and step-by-step history |
27
+
28
+ `triggerWorkflow` starts a process with side effects, so it is annotated `destructiveHint: true` and
29
+ MCP clients are expected to ask the user before each call. Like every other tool it is **enabled by
30
+ default**, but it stays inert until someone turns the MCP trigger on for a given workflow in Forest
31
+ — the server refuses a trigger on any workflow that has not opted in.
24
32
 
25
33
  ## Usage
26
34
 
@@ -6,5 +6,5 @@ export interface CreateForestServerClientOptions {
6
6
  }
7
7
  export declare function createForestServerClient(options: CreateForestServerClientOptions): ForestServerClient;
8
8
  export { ForestServerClientImpl };
9
- export type { ActivityLogAction, ActivityLogResponse, ActivityLogsServiceInterface, ActivityLogType, CreateActivityLogParams, ForestServerClient, UpdateActivityLogStatusParams, ForestSchemaCollection, ForestSchemaField, ForestSchemaAction, SchemaServiceInterface, } from './types';
9
+ export type { ActivityLogAction, ActivityLogResponse, ActivityLogsServiceInterface, ActivityLogType, CreateActivityLogParams, ForestServerClient, GetMcpWorkflowByIdParams, GetMcpWorkflowRunParams, ListMcpWorkflowsParams, McpWorkflow, McpWorkflowLookup, TriggerMcpWorkflowParams, HydratedWorkflowRun, WorkflowRunTriggerResult, UpdateActivityLogStatusParams, ForestSchemaCollection, ForestSchemaField, ForestSchemaAction, SchemaServiceInterface, WorkflowsServiceInterface, } from './types';
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -22,6 +22,10 @@ function createForestServerClient(options) {
22
22
  ...serviceOptions,
23
23
  headers: { 'Forest-Application-Source': 'MCP' },
24
24
  });
25
- return new mcp_http_client_1.default(schemaService, activityLogsService, options.forestServerUrl);
25
+ const workflowsService = new forestadmin_client_1.WorkflowsService(forestHttpApi, {
26
+ forestServerUrl: options.forestServerUrl,
27
+ headers: { 'Forest-Application-Source': 'MCP' },
28
+ });
29
+ return new mcp_http_client_1.default(schemaService, activityLogsService, workflowsService, options.forestServerUrl);
26
30
  }
27
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaHR0cC1jbGllbnQvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBV0EsNERBb0JDO0FBN0JELHdFQUFvRztBQUVwRyx3RUFBdUQ7QUE2QjlDLGlDQTdCRix5QkFBc0IsQ0E2QkU7QUF0Qi9CLFNBQWdCLHdCQUF3QixDQUN0QyxPQUF3QztJQUV4QyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBRUQsTUFBTSxhQUFhLEdBQUcsSUFBSSxrQ0FBYSxFQUFFLENBQUM7SUFDMUMsTUFBTSxjQUFjLEdBQUc7UUFDckIsZUFBZSxFQUFFLE9BQU8sQ0FBQyxlQUFlO1FBQ3hDLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUztLQUM3QixDQUFDO0lBRUYsTUFBTSxhQUFhLEdBQUcsSUFBSSxrQ0FBYSxDQUFDLGFBQWEsRUFBRSxjQUFjLENBQUMsQ0FBQztJQUN2RSxNQUFNLG1CQUFtQixHQUFHLElBQUksd0NBQW1CLENBQUMsYUFBYSxFQUFFO1FBQ2pFLEdBQUcsY0FBYztRQUNqQixPQUFPLEVBQUUsRUFBRSwyQkFBMkIsRUFBRSxLQUFLLEVBQUU7S0FDaEQsQ0FBQyxDQUFDO0lBRUgsT0FBTyxJQUFJLHlCQUFzQixDQUFDLGFBQWEsRUFBRSxtQkFBbUIsRUFBRSxPQUFPLENBQUMsZUFBZSxDQUFDLENBQUM7QUFDakcsQ0FBQyJ9
31
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaHR0cC1jbGllbnQvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBZ0JBLDREQTZCQztBQTNDRCx3RUFLeUM7QUFFekMsd0VBQXVEO0FBc0M5QyxpQ0F0Q0YseUJBQXNCLENBc0NFO0FBL0IvQixTQUFnQix3QkFBd0IsQ0FDdEMsT0FBd0M7SUFFeEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUM7SUFDeEUsQ0FBQztJQUVELE1BQU0sYUFBYSxHQUFHLElBQUksa0NBQWEsRUFBRSxDQUFDO0lBQzFDLE1BQU0sY0FBYyxHQUFHO1FBQ3JCLGVBQWUsRUFBRSxPQUFPLENBQUMsZUFBZTtRQUN4QyxTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVM7S0FDN0IsQ0FBQztJQUVGLE1BQU0sYUFBYSxHQUFHLElBQUksa0NBQWEsQ0FBQyxhQUFhLEVBQUUsY0FBYyxDQUFDLENBQUM7SUFDdkUsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLHdDQUFtQixDQUFDLGFBQWEsRUFBRTtRQUNqRSxHQUFHLGNBQWM7UUFDakIsT0FBTyxFQUFFLEVBQUUsMkJBQTJCLEVBQUUsS0FBSyxFQUFFO0tBQ2hELENBQUMsQ0FBQztJQUNILE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxxQ0FBZ0IsQ0FBQyxhQUFhLEVBQUU7UUFDM0QsZUFBZSxFQUFFLE9BQU8sQ0FBQyxlQUFlO1FBQ3hDLE9BQU8sRUFBRSxFQUFFLDJCQUEyQixFQUFFLEtBQUssRUFBRTtLQUNoRCxDQUFDLENBQUM7SUFFSCxPQUFPLElBQUkseUJBQXNCLENBQy9CLGFBQWEsRUFDYixtQkFBbUIsRUFDbkIsZ0JBQWdCLEVBQ2hCLE9BQU8sQ0FBQyxlQUFlLENBQ3hCLENBQUM7QUFDSixDQUFDIn0=
@@ -1,16 +1,21 @@
1
- import type { ActivityLogResponse, ActivityLogsServiceInterface, CreateActivityLogParams, ForestSchemaCollection, ForestServerClient, SchemaServiceInterface, UpdateActivityLogStatusParams } from './types';
1
+ import type { ActivityLogResponse, ActivityLogsServiceInterface, CreateActivityLogParams, ForestSchemaCollection, ForestServerClient, GetMcpWorkflowByIdParams, GetMcpWorkflowRunParams, HydratedWorkflowRun, ListMcpWorkflowsParams, McpWorkflow, McpWorkflowLookup, SchemaServiceInterface, TriggerMcpWorkflowParams, UpdateActivityLogStatusParams, WorkflowRunTriggerResult, WorkflowsServiceInterface } from './types';
2
2
  /**
3
- * Default implementation of ForestServerClient that uses SchemaService and ActivityLogsService.
4
- * This provides a convenient API for MCP server operations.
3
+ * Default implementation of ForestServerClient that uses SchemaService, ActivityLogsService
4
+ * and WorkflowsService. This provides a convenient API for MCP server operations.
5
5
  */
6
6
  export default class ForestServerClientImpl implements ForestServerClient {
7
7
  private readonly schemaService;
8
8
  private readonly activityLogsService;
9
+ private readonly workflowsService;
9
10
  readonly forestServerUrl: string;
10
- constructor(schemaService: SchemaServiceInterface, activityLogsService: ActivityLogsServiceInterface, forestServerUrl: string);
11
+ constructor(schemaService: SchemaServiceInterface, activityLogsService: ActivityLogsServiceInterface, workflowsService: WorkflowsServiceInterface, forestServerUrl: string);
11
12
  fetchSchema(): Promise<ForestSchemaCollection[]>;
12
13
  createActivityLog(params: CreateActivityLogParams): Promise<ActivityLogResponse>;
13
14
  createMcpActivityLog(params: CreateActivityLogParams): Promise<ActivityLogResponse>;
14
15
  updateActivityLogStatus(params: UpdateActivityLogStatusParams): Promise<void>;
16
+ listMcpEnabledWorkflows(params: ListMcpWorkflowsParams): Promise<McpWorkflow[]>;
17
+ getMcpWorkflowById(params: GetMcpWorkflowByIdParams): Promise<McpWorkflowLookup>;
18
+ triggerMcpWorkflow(params: TriggerMcpWorkflowParams): Promise<WorkflowRunTriggerResult>;
19
+ getMcpWorkflowRun(params: GetMcpWorkflowRunParams): Promise<HydratedWorkflowRun>;
15
20
  }
16
21
  //# sourceMappingURL=mcp-http-client.d.ts.map
@@ -1,13 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  /**
4
- * Default implementation of ForestServerClient that uses SchemaService and ActivityLogsService.
5
- * This provides a convenient API for MCP server operations.
4
+ * Default implementation of ForestServerClient that uses SchemaService, ActivityLogsService
5
+ * and WorkflowsService. This provides a convenient API for MCP server operations.
6
6
  */
7
7
  class ForestServerClientImpl {
8
- constructor(schemaService, activityLogsService, forestServerUrl) {
8
+ constructor(schemaService, activityLogsService, workflowsService, forestServerUrl) {
9
9
  this.schemaService = schemaService;
10
10
  this.activityLogsService = activityLogsService;
11
+ this.workflowsService = workflowsService;
11
12
  this.forestServerUrl = forestServerUrl;
12
13
  }
13
14
  async fetchSchema() {
@@ -22,6 +23,18 @@ class ForestServerClientImpl {
22
23
  async updateActivityLogStatus(params) {
23
24
  return this.activityLogsService.updateActivityLogStatus(params);
24
25
  }
26
+ async listMcpEnabledWorkflows(params) {
27
+ return this.workflowsService.listMcpEnabledWorkflows(params);
28
+ }
29
+ async getMcpWorkflowById(params) {
30
+ return this.workflowsService.getMcpWorkflowById(params);
31
+ }
32
+ async triggerMcpWorkflow(params) {
33
+ return this.workflowsService.triggerMcpWorkflow(params);
34
+ }
35
+ async getMcpWorkflowRun(params) {
36
+ return this.workflowsService.getMcpWorkflowRun(params);
37
+ }
25
38
  }
26
39
  exports.default = ForestServerClientImpl;
27
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLWh0dHAtY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2h0dHAtY2xpZW50L21jcC1odHRwLWNsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVVBOzs7R0FHRztBQUNILE1BQXFCLHNCQUFzQjtJQUN6QyxZQUNtQixhQUFxQyxFQUNyQyxtQkFBaUQsRUFDbEQsZUFBdUI7UUFGdEIsa0JBQWEsR0FBYixhQUFhLENBQXdCO1FBQ3JDLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBOEI7UUFDbEQsb0JBQWUsR0FBZixlQUFlLENBQVE7SUFDdEMsQ0FBQztJQUVKLEtBQUssQ0FBQyxXQUFXO1FBQ2YsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ3hDLENBQUM7SUFFRCxLQUFLLENBQUMsaUJBQWlCLENBQUMsTUFBK0I7UUFDckQsT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVELEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxNQUErQjtRQUN4RCxPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBRUQsS0FBSyxDQUFDLHVCQUF1QixDQUFDLE1BQXFDO1FBQ2pFLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLHVCQUF1QixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2xFLENBQUM7Q0FDRjtBQXRCRCx5Q0FzQkMifQ==
40
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLWh0dHAtY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2h0dHAtY2xpZW50L21jcC1odHRwLWNsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQW1CQTs7O0dBR0c7QUFDSCxNQUFxQixzQkFBc0I7SUFDekMsWUFDbUIsYUFBcUMsRUFDckMsbUJBQWlELEVBQ2pELGdCQUEyQyxFQUM1QyxlQUF1QjtRQUh0QixrQkFBYSxHQUFiLGFBQWEsQ0FBd0I7UUFDckMsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUE4QjtRQUNqRCxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQTJCO1FBQzVDLG9CQUFlLEdBQWYsZUFBZSxDQUFRO0lBQ3RDLENBQUM7SUFFSixLQUFLLENBQUMsV0FBVztRQUNmLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUN4QyxDQUFDO0lBRUQsS0FBSyxDQUFDLGlCQUFpQixDQUFDLE1BQStCO1FBQ3JELE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFRCxLQUFLLENBQUMsb0JBQW9CLENBQUMsTUFBK0I7UUFDeEQsT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDL0QsQ0FBQztJQUVELEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxNQUFxQztRQUNqRSxPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyx1QkFBdUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRUQsS0FBSyxDQUFDLHVCQUF1QixDQUFDLE1BQThCO1FBQzFELE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLHVCQUF1QixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQy9ELENBQUM7SUFFRCxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBZ0M7UUFDdkQsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVELEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFnQztRQUN2RCxPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRUQsS0FBSyxDQUFDLGlCQUFpQixDQUFDLE1BQStCO1FBQ3JELE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3pELENBQUM7Q0FDRjtBQXZDRCx5Q0F1Q0MifQ==
@@ -1,5 +1,5 @@
1
- import type { ActivityLogAction, ActivityLogResponse, ActivityLogType, ActivityLogsServiceInterface, CreateActivityLogParams, ForestSchemaAction, ForestSchemaCollection, ForestSchemaField, SchemaServiceInterface, UpdateActivityLogStatusParams } from '@forestadmin/forestadmin-client';
2
- export type { ActivityLogAction, ActivityLogResponse, ActivityLogsServiceInterface, ActivityLogType, CreateActivityLogParams, ForestSchemaAction, ForestSchemaCollection, ForestSchemaField, SchemaServiceInterface, UpdateActivityLogStatusParams, };
1
+ import type { ActivityLogAction, ActivityLogResponse, ActivityLogType, ActivityLogsServiceInterface, CreateActivityLogParams, ForestSchemaAction, ForestSchemaCollection, ForestSchemaField, GetMcpWorkflowByIdParams, GetMcpWorkflowRunParams, HydratedWorkflowRun, ListMcpWorkflowsParams, McpWorkflow, McpWorkflowLookup, SchemaServiceInterface, TriggerMcpWorkflowParams, UpdateActivityLogStatusParams, WorkflowRunTriggerResult, WorkflowsServiceInterface } from '@forestadmin/forestadmin-client';
2
+ export type { ActivityLogAction, ActivityLogResponse, ActivityLogsServiceInterface, ActivityLogType, CreateActivityLogParams, ForestSchemaAction, ForestSchemaCollection, ForestSchemaField, GetMcpWorkflowByIdParams, GetMcpWorkflowRunParams, HydratedWorkflowRun, ListMcpWorkflowsParams, McpWorkflow, McpWorkflowLookup, SchemaServiceInterface, TriggerMcpWorkflowParams, UpdateActivityLogStatusParams, WorkflowRunTriggerResult, WorkflowsServiceInterface, };
3
3
  /**
4
4
  * Interface for communicating with Forest Admin server.
5
5
  * This abstraction allows for easy mocking in tests.
@@ -25,5 +25,21 @@ export interface ForestServerClient {
25
25
  * Updates an activity log status.
26
26
  */
27
27
  updateActivityLogStatus(params: UpdateActivityLogStatusParams): Promise<void>;
28
+ /**
29
+ * Lists the MCP-enabled workflows the caller can access in a rendering.
30
+ */
31
+ listMcpEnabledWorkflows(params: ListMcpWorkflowsParams): Promise<McpWorkflow[]>;
32
+ /**
33
+ * Resolves a single workflow by id (name, collection, mcpEnabled), scoped to the caller.
34
+ */
35
+ getMcpWorkflowById(params: GetMcpWorkflowByIdParams): Promise<McpWorkflowLookup>;
36
+ /**
37
+ * Starts a run of an MCP-enabled workflow on a record and returns its runId (async).
38
+ */
39
+ triggerMcpWorkflow(params: TriggerMcpWorkflowParams): Promise<WorkflowRunTriggerResult>;
40
+ /**
41
+ * Reads the full hydrated workflow run, scoped to the caller.
42
+ */
43
+ getMcpWorkflowRun(params: GetMcpWorkflowRunParams): Promise<HydratedWorkflowRun>;
28
44
  }
29
45
  //# sourceMappingURL=types.d.ts.map
package/dist/server.d.ts CHANGED
@@ -9,7 +9,7 @@ export declare const LOGO_URL = "https://forest-assets.s3.us-east-1.amazonaws.co
9
9
  export type LogLevel = 'Debug' | 'Info' | 'Warn' | 'Error';
10
10
  export type Logger = (level: LogLevel, message: string) => void;
11
11
  export type HttpCallback = (req: http.IncomingMessage, res: http.ServerResponse, next?: () => void) => void;
12
- export type ToolName = 'describeCollection' | 'list' | 'listRelated' | 'create' | 'update' | 'delete' | 'associate' | 'dissociate' | 'getActionForm' | 'executeAction' | 'requestActionFileUpload';
12
+ export type ToolName = 'describeCollection' | 'list' | 'listRelated' | 'create' | 'update' | 'delete' | 'associate' | 'dissociate' | 'getActionForm' | 'executeAction' | 'listWorkflows' | 'triggerWorkflow' | 'getWorkflowRun' | 'requestActionFileUpload';
13
13
  /**
14
14
  * Options for configuring the Forest Admin MCP Server
15
15
  */
package/dist/server.js CHANGED
@@ -63,9 +63,12 @@ const describe_collection_1 = __importDefault(require("./tools/describe-collecti
63
63
  const dissociate_1 = __importDefault(require("./tools/dissociate"));
64
64
  const execute_action_1 = __importDefault(require("./tools/execute-action"));
65
65
  const get_action_form_1 = __importDefault(require("./tools/get-action-form"));
66
+ const get_workflow_run_1 = __importDefault(require("./tools/get-workflow-run"));
66
67
  const list_1 = __importDefault(require("./tools/list"));
67
68
  const list_related_1 = __importDefault(require("./tools/list-related"));
69
+ const list_workflows_1 = __importDefault(require("./tools/list-workflows"));
68
70
  const request_action_file_upload_1 = __importDefault(require("./tools/request-action-file-upload"));
71
+ const trigger_workflow_1 = __importDefault(require("./tools/trigger-workflow"));
69
72
  const update_1 = __importDefault(require("./tools/update"));
70
73
  const normalize_agent_url_1 = __importDefault(require("./utils/normalize-agent-url"));
71
74
  const normalize_domain_list_1 = __importDefault(require("./utils/normalize-domain-list"));
@@ -110,6 +113,9 @@ const SAFE_ARGUMENTS_FOR_LOGGING = {
110
113
  requestActionFileUpload: ['mimeType'],
111
114
  associate: ['collectionName', 'relationName', 'parentRecordId', 'targetRecordId'],
112
115
  dissociate: ['collectionName', 'relationName', 'parentRecordId', 'targetRecordIds'],
116
+ listWorkflows: ['collectionName'],
117
+ triggerWorkflow: ['workflowId', 'recordId'],
118
+ getWorkflowRun: ['runId'],
113
119
  };
114
120
  /**
115
121
  * Forest Admin MCP Server
@@ -188,6 +194,9 @@ class ForestMCPServer {
188
194
  { name: 'dissociate', register: () => (0, dissociate_1.default)(mcpServer, ctx) },
189
195
  { name: 'getActionForm', register: () => (0, get_action_form_1.default)(mcpServer, ctx) },
190
196
  { name: 'executeAction', register: () => (0, execute_action_1.default)(mcpServer, ctx) },
197
+ { name: 'listWorkflows', register: () => (0, list_workflows_1.default)(mcpServer, ctx) },
198
+ { name: 'triggerWorkflow', register: () => (0, trigger_workflow_1.default)(mcpServer, ctx) },
199
+ { name: 'getWorkflowRun', register: () => (0, get_workflow_run_1.default)(mcpServer, ctx) },
191
200
  ...(this.fileUploads
192
201
  ? [
193
202
  {
@@ -221,6 +230,9 @@ class ForestMCPServer {
221
230
  'dissociate',
222
231
  'getActionForm',
223
232
  'executeAction',
233
+ 'listWorkflows',
234
+ 'triggerWorkflow',
235
+ 'getWorkflowRun',
224
236
  'requestActionFileUpload',
225
237
  ];
226
238
  const enabled = new Set(options?.enabledTools ?? allToolNames);
@@ -594,4 +606,4 @@ class ForestMCPServer {
594
606
  }
595
607
  }
596
608
  exports.default = ForestMCPServer;
597
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3NlcnZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxzREFBc0Q7QUFDdEQsc0VBQXNFO0FBQ3RFLHVCQUFxQjtBQVNyQiw4RkFBbUc7QUFDbkcsNEZBQTZGO0FBQzdGLHNGQUF1RjtBQUN2RiwwR0FBb0c7QUFDcEcsa0dBQW1HO0FBQ25HLCtFQUd5RDtBQUN6RCxvRUFBb0U7QUFDcEUsMEZBQW1HO0FBQ25HLGdEQUF3QjtBQUN4QixzREFBOEI7QUFDOUIsMkNBQTZCO0FBRTdCLHlGQUFnRTtBQUNoRSxnREFBMEQ7QUFDMUQsb0ZBQTBEO0FBQzFELCtDQUF5RDtBQUN6RCwyQ0FBaUU7QUFDakUsa0VBQXFEO0FBQ3JELDREQUErQztBQUMvQyw0REFBK0M7QUFDL0Msc0ZBQXdFO0FBQ3hFLG9FQUF1RDtBQUN2RCw0RUFBOEQ7QUFDOUQsOEVBQStEO0FBQy9ELHdEQUEyQztBQUMzQyx3RUFBMEQ7QUFDMUQsb0dBQW9GO0FBQ3BGLDREQUErQztBQUMvQyxzRkFBNEQ7QUFDNUQsMEZBQWdFO0FBQ2hFLDJEQUErRTtBQUMvRSxnRkFBd0U7QUFDeEUsa0VBQWtEO0FBQ2xELHVDQUEwQztBQUU3QixRQUFBLFFBQVEsR0FBRyxpRUFBaUUsQ0FBQztBQVcxRixTQUFTLGVBQWUsQ0FBQyxLQUFlO0lBQ3RDLElBQUksS0FBSyxLQUFLLE9BQU87UUFBRSxPQUFPLENBQUMsR0FBVyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2xFLElBQUksS0FBSyxLQUFLLE1BQU07UUFBRSxPQUFPLENBQUMsR0FBVyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRWhFLE9BQU8sQ0FBQyxHQUFXLEVBQUUsRUFBRSxDQUFDLE9BQU8s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
609
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3NlcnZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxzREFBc0Q7QUFDdEQsc0VBQXNFO0FBQ3RFLHVCQUFxQjtBQVNyQiw4RkFBbUc7QUFDbkcsNEZBQTZGO0FBQzdGLHNGQUF1RjtBQUN2RiwwR0FBb0c7QUFDcEcsa0dBQW1HO0FBQ25HLCtFQUd5RDtBQUN6RCxvRUFBb0U7QUFDcEUsMEZBQW1HO0FBQ25HLGdEQUF3QjtBQUN4QixzREFBOEI7QUFDOUIsMkNBQTZCO0FBRTdCLHlGQUFnRTtBQUNoRSxnREFBMEQ7QUFDMUQsb0ZBQTBEO0FBQzFELCtDQUF5RDtBQUN6RCwyQ0FBaUU7QUFDakUsa0VBQXFEO0FBQ3JELDREQUErQztBQUMvQyw0REFBK0M7QUFDL0Msc0ZBQXdFO0FBQ3hFLG9FQUF1RDtBQUN2RCw0RUFBOEQ7QUFDOUQsOEVBQStEO0FBQy9ELGdGQUFpRTtBQUNqRSx3REFBMkM7QUFDM0Msd0VBQTBEO0FBQzFELDRFQUE4RDtBQUM5RCxvR0FBb0Y7QUFDcEYsZ0ZBQWtFO0FBQ2xFLDREQUErQztBQUMvQyxzRkFBNEQ7QUFDNUQsMEZBQWdFO0FBQ2hFLDJEQUErRTtBQUMvRSxnRkFBd0U7QUFDeEUsa0VBQWtEO0FBQ2xELHVDQUEwQztBQUU3QixRQUFBLFFBQVEsR0FBRyxpRUFBaUUsQ0FBQztBQVcxRixTQUFTLGVBQWUsQ0FBQyxLQUFlO0lBQ3RDLElBQUksS0FBSyxLQUFLLE9BQU87UUFBRSxPQUFPLENBQUMsR0FBVyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2xFLElBQUksS0FBSyxLQUFLLE1BQU07UUFBRSxPQUFPLENBQUMsR0FBVyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lB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
@@ -0,0 +1,4 @@
1
+ import type { ToolContext } from '../tool-context';
2
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ export default function declareGetWorkflowRunTool(mcpServer: McpServer, ctx: ToolContext): string;
4
+ //# sourceMappingURL=get-workflow-run.d.ts.map
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = declareGetWorkflowRunTool;
7
+ const zod_1 = require("zod");
8
+ const auth_context_1 = __importDefault(require("../utils/auth-context"));
9
+ const tool_with_logging_1 = __importDefault(require("../utils/tool-with-logging"));
10
+ const workflow_error_1 = __importDefault(require("../utils/workflow-error"));
11
+ const RUN_ID_DESCRIPTION = 'The id of the workflow run to observe, as returned by triggerWorkflow.';
12
+ function runUnavailableMessage(runId) {
13
+ return (`Run "${runId}" could not be read because Forest could not be reached. This is a temporary ` +
14
+ 'server-side failure, not a problem with the run id — retry later, and report it to your ' +
15
+ 'Forest administrator if it persists.');
16
+ }
17
+ function declareGetWorkflowRunTool(mcpServer, ctx) {
18
+ const { forestServerClient, logger } = ctx;
19
+ return (0, tool_with_logging_1.default)(mcpServer, 'getWorkflowRun', {
20
+ // Spelled out rather than relying on defaults: the MCP spec defaults an omitted
21
+ // destructiveHint to true, so a client reading that field alone would treat these
22
+ // reads as destructive.
23
+ annotations: {
24
+ readOnlyHint: true,
25
+ destructiveHint: false,
26
+ idempotentHint: true,
27
+ openWorldHint: false,
28
+ },
29
+ title: 'Get a workflow run status',
30
+ description: 'Poll a workflow run started with triggerWorkflow. Returns the full hydrated run: its ' +
31
+ 'runState (started, pending, loading, aborted or finished) plus the complete ' +
32
+ 'workflowHistory — every step with its resolved definition (type, title, prompt, task ' +
33
+ 'type, outgoing branches) and its per-step context (completion, selected option, error, ' +
34
+ 'escalation state, awaiting-input reason). Use it to see exactly where the run is and ' +
35
+ 'what each step does. A run parked on a human-gated step cannot be resumed via MCP in ' +
36
+ 'v1 and must be finished from the Forest UI. Poll at a reasonable interval: wait at ' +
37
+ 'least a few seconds between calls, and do not busy-loop on a long-running or ' +
38
+ 'human-gated run (which never resolves via MCP in v1).',
39
+ inputSchema: {
40
+ runId: zod_1.z.string().min(1).describe(RUN_ID_DESCRIPTION),
41
+ },
42
+ }, async (args, extra) => {
43
+ const { forestServerToken, renderingId } = (0, auth_context_1.default)(extra);
44
+ let runStatus;
45
+ try {
46
+ runStatus = await forestServerClient.getMcpWorkflowRun({
47
+ forestServerToken,
48
+ renderingId,
49
+ runId: args.runId,
50
+ });
51
+ }
52
+ catch (error) {
53
+ // Same rule as the two sibling workflow tools: Forest's own refusal is worth reading, a
54
+ // raw transport failure is transport detail the model must never receive.
55
+ throw (0, workflow_error_1.default)(error, {
56
+ logger,
57
+ context: `Failed to read workflow run "${args.runId}"`,
58
+ unavailableMessage: runUnavailableMessage(args.runId),
59
+ });
60
+ }
61
+ return { content: [{ type: 'text', text: JSON.stringify(runStatus) }] };
62
+ }, logger);
63
+ }
64
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0LXdvcmtmbG93LXJ1bi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90b29scy9nZXQtd29ya2Zsb3ctcnVuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBdUJBLDRDQXdEQztBQTVFRCw2QkFBd0I7QUFFeEIseUVBQW1EO0FBQ25ELG1GQUFpRTtBQUNqRSw2RUFBdUQ7QUFFdkQsTUFBTSxrQkFBa0IsR0FBRyx3RUFBd0UsQ0FBQztBQUVwRyxTQUFTLHFCQUFxQixDQUFDLEtBQWE7SUFDMUMsT0FBTyxDQUNMLFFBQVEsS0FBSywrRUFBK0U7UUFDNUYsMEZBQTBGO1FBQzFGLHNDQUFzQyxDQUN2QyxDQUFDO0FBQ0osQ0FBQztBQU1ELFNBQXdCLHlCQUF5QixDQUFDLFNBQW9CLEVBQUUsR0FBZ0I7SUFDdEYsTUFBTSxFQUFFLGtCQUFrQixFQUFFLE1BQU0sRUFBRSxHQUFHLEdBQUcsQ0FBQztJQUUzQyxPQUFPLElBQUEsMkJBQXVCLEVBQzVCLFNBQVMsRUFDVCxnQkFBZ0IsRUFDaEI7UUFDRSxnRkFBZ0Y7UUFDaEYsa0ZBQWtGO1FBQ2xGLHdCQUF3QjtRQUN4QixXQUFXLEVBQUU7WUFDWCxZQUFZLEVBQUUsSUFBSTtZQUNsQixlQUFlLEVBQUUsS0FBSztZQUN0QixjQUFjLEVBQUUsSUFBSTtZQUNwQixhQUFhLEVBQUUsS0FBSztTQUNyQjtRQUNELEtBQUssRUFBRSwyQkFBMkI7UUFDbEMsV0FBVyxFQUNULHVGQUF1RjtZQUN2Riw4RUFBOEU7WUFDOUUsdUZBQXVGO1lBQ3ZGLHlGQUF5RjtZQUN6Rix1RkFBdUY7WUFDdkYsdUZBQXVGO1lBQ3ZGLHFGQUFxRjtZQUNyRiwrRUFBK0U7WUFDL0UsdURBQXVEO1FBQ3pELFdBQVcsRUFBRTtZQUNYLEtBQUssRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQztTQUN0RDtLQUNGLEVBQ0QsS0FBSyxFQUFFLElBQTRCLEVBQUUsS0FBSyxFQUFFLEVBQUU7UUFDNUMsTUFBTSxFQUFFLGlCQUFpQixFQUFFLFdBQVcsRUFBRSxHQUFHLElBQUEsc0JBQWMsRUFBQyxLQUFLLENBQUMsQ0FBQztRQUVqRSxJQUFJLFNBQVMsQ0FBQztRQUVkLElBQUksQ0FBQztZQUNILFNBQVMsR0FBRyxNQUFNLGtCQUFrQixDQUFDLGlCQUFpQixDQUFDO2dCQUNyRCxpQkFBaUI7Z0JBQ2pCLFdBQVc7Z0JBQ1gsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO2FBQ2xCLENBQUMsQ0FBQztRQUNMLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2Ysd0ZBQXdGO1lBQ3hGLDBFQUEwRTtZQUMxRSxNQUFNLElBQUEsd0JBQWdCLEVBQUMsS0FBSyxFQUFFO2dCQUM1QixNQUFNO2dCQUNOLE9BQU8sRUFBRSxnQ0FBZ0MsSUFBSSxDQUFDLEtBQUssR0FBRztnQkFDdEQsa0JBQWtCLEVBQUUscUJBQXFCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQzthQUN0RCxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUMxRSxDQUFDLEVBQ0QsTUFBTSxDQUNQLENBQUM7QUFDSixDQUFDIn0=
@@ -0,0 +1,4 @@
1
+ import type { ToolContext } from '../tool-context';
2
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ export default function declareListWorkflowsTool(mcpServer: McpServer, ctx: ToolContext): string;
4
+ //# sourceMappingURL=list-workflows.d.ts.map
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = declareListWorkflowsTool;
7
+ const zod_1 = require("zod");
8
+ const auth_context_1 = __importDefault(require("../utils/auth-context"));
9
+ const tool_with_logging_1 = __importDefault(require("../utils/tool-with-logging"));
10
+ const workflow_error_1 = __importDefault(require("../utils/workflow-error"));
11
+ const LISTING_UNAVAILABLE_MESSAGE = 'The MCP-enabled workflows could not be listed because Forest could not be reached. This is a ' +
12
+ 'temporary server-side failure — retry later, and report it to your Forest administrator if it ' +
13
+ 'persists.';
14
+ const COLLECTION_NAME_DESCRIPTION = 'Optional. Narrow the results to workflows operating on this collection — typically the ' +
15
+ 'collection of the record currently in context.';
16
+ function createListWorkflowsArgumentShape(collectionNames) {
17
+ const collectionName = collectionNames.length > 0 ? zod_1.z.enum(collectionNames) : zod_1.z.string();
18
+ return {
19
+ collectionName: collectionName.optional().describe(COLLECTION_NAME_DESCRIPTION),
20
+ };
21
+ }
22
+ function declareListWorkflowsTool(mcpServer, ctx) {
23
+ const { forestServerClient, logger, collectionNames } = ctx;
24
+ return (0, tool_with_logging_1.default)(mcpServer, 'listWorkflows', {
25
+ // Spelled out rather than relying on defaults: the MCP spec defaults an omitted
26
+ // destructiveHint to true, so a client reading that field alone would treat these
27
+ // reads as destructive.
28
+ annotations: {
29
+ readOnlyHint: true,
30
+ destructiveHint: false,
31
+ idempotentHint: true,
32
+ openWorldHint: false,
33
+ },
34
+ title: 'List MCP-enabled workflows',
35
+ description: 'Discover Forest workflows enabled for MCP triggering that you can access. Returns each ' +
36
+ "workflow's id, name and the collection it operates on. Optionally filter by collectionName " +
37
+ 'to match the record currently in context, then start one with triggerWorkflow.',
38
+ inputSchema: createListWorkflowsArgumentShape(collectionNames),
39
+ }, async (args, extra) => {
40
+ const { forestServerToken, renderingId } = (0, auth_context_1.default)(extra);
41
+ let workflows;
42
+ try {
43
+ workflows = await forestServerClient.listMcpEnabledWorkflows({
44
+ forestServerToken,
45
+ renderingId,
46
+ collectionName: args.collectionName,
47
+ });
48
+ }
49
+ catch (error) {
50
+ // Forest's own refusals still reach the model — they say something actionable. What must
51
+ // not is a raw transport failure: its message carries the Forest server URL and an internal
52
+ // host and port, and this result is stringified straight into a model's context.
53
+ throw (0, workflow_error_1.default)(error, {
54
+ logger,
55
+ context: 'Failed to list MCP-enabled workflows',
56
+ unavailableMessage: LISTING_UNAVAILABLE_MESSAGE,
57
+ });
58
+ }
59
+ // A workflow whose collection was renamed or removed cannot be triggered - triggerWorkflow
60
+ // rejects a null collectionName up front - so listing it would only send the model round the
61
+ // discover, trigger, rejected, discover loop. Surface the drop to the operator instead.
62
+ // `!= null` on purpose, to match triggerWorkflow's own guard: an absent key and an explicit
63
+ // null must be dropped by the same rule, or the discover/trigger loop reopens.
64
+ const triggerable = workflows.filter(workflow => workflow.collectionName != null);
65
+ const droppedCount = workflows.length - triggerable.length;
66
+ if (droppedCount > 0) {
67
+ logger('Warn', `listWorkflows hid ${droppedCount} MCP-enabled workflow(s) whose collection is no longer ` +
68
+ 'available in this rendering; they cannot be triggered until their configuration is fixed.');
69
+ }
70
+ return { content: [{ type: 'text', text: JSON.stringify(triggerable) }] };
71
+ }, logger);
72
+ }
73
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC13b3JrZmxvd3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdG9vbHMvbGlzdC13b3JrZmxvd3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUErQkEsMkNBaUVDO0FBN0ZELDZCQUF3QjtBQUV4Qix5RUFBbUQ7QUFDbkQsbUZBQWlFO0FBQ2pFLDZFQUF1RDtBQUV2RCxNQUFNLDJCQUEyQixHQUMvQiwrRkFBK0Y7SUFDL0YsZ0dBQWdHO0lBQ2hHLFdBQVcsQ0FBQztBQUVkLE1BQU0sMkJBQTJCLEdBQy9CLHlGQUF5RjtJQUN6RixnREFBZ0QsQ0FBQztBQUVuRCxTQUFTLGdDQUFnQyxDQUFDLGVBQXlCO0lBQ2pFLE1BQU0sY0FBYyxHQUNsQixlQUFlLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBQyxDQUFDLElBQUksQ0FBQyxlQUF3QyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUU3RixPQUFPO1FBQ0wsY0FBYyxFQUFFLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLENBQUMsMkJBQTJCLENBQUM7S0FDaEYsQ0FBQztBQUNKLENBQUM7QUFNRCxTQUF3Qix3QkFBd0IsQ0FBQyxTQUFvQixFQUFFLEdBQWdCO0lBQ3JGLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLEVBQUUsZUFBZSxFQUFFLEdBQUcsR0FBRyxDQUFDO0lBRTVELE9BQU8sSUFBQSwyQkFBdUIsRUFDNUIsU0FBUyxFQUNULGVBQWUsRUFDZjtRQUNFLGdGQUFnRjtRQUNoRixrRkFBa0Y7UUFDbEYsd0JBQXdCO1FBQ3hCLFdBQVcsRUFBRTtZQUNYLFlBQVksRUFBRSxJQUFJO1lBQ2xCLGVBQWUsRUFBRSxLQUFLO1lBQ3RCLGNBQWMsRUFBRSxJQUFJO1lBQ3BCLGFBQWEsRUFBRSxLQUFLO1NBQ3JCO1FBQ0QsS0FBSyxFQUFFLDRCQUE0QjtRQUNuQyxXQUFXLEVBQ1QseUZBQXlGO1lBQ3pGLDZGQUE2RjtZQUM3RixnRkFBZ0Y7UUFDbEYsV0FBVyxFQUFFLGdDQUFnQyxDQUFDLGVBQWUsQ0FBQztLQUMvRCxFQUNELEtBQUssRUFBRSxJQUEyQixFQUFFLEtBQUssRUFBRSxFQUFFO1FBQzNDLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsR0FBRyxJQUFBLHNCQUFjLEVBQUMsS0FBSyxDQUFDLENBQUM7UUFFakUsSUFBSSxTQUFTLENBQUM7UUFFZCxJQUFJLENBQUM7WUFDSCxTQUFTLEdBQUcsTUFBTSxrQkFBa0IsQ0FBQyx1QkFBdUIsQ0FBQztnQkFDM0QsaUJBQWlCO2dCQUNqQixXQUFXO2dCQUNYLGNBQWMsRUFBRSxJQUFJLENBQUMsY0FBYzthQUNwQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLHlGQUF5RjtZQUN6Riw0RkFBNEY7WUFDNUYsaUZBQWlGO1lBQ2pGLE1BQU0sSUFBQSx3QkFBZ0IsRUFBQyxLQUFLLEVBQUU7Z0JBQzVCLE1BQU07Z0JBQ04sT0FBTyxFQUFFLHNDQUFzQztnQkFDL0Msa0JBQWtCLEVBQUUsMkJBQTJCO2FBQ2hELENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCwyRkFBMkY7UUFDM0YsNkZBQTZGO1FBQzdGLHdGQUF3RjtRQUN4Riw0RkFBNEY7UUFDNUYsK0VBQStFO1FBQy9FLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsY0FBYyxJQUFJLElBQUksQ0FBQyxDQUFDO1FBQ2xGLE1BQU0sWUFBWSxHQUFHLFNBQVMsQ0FBQyxNQUFNLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQztRQUUzRCxJQUFJLFlBQVksR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNyQixNQUFNLENBQ0osTUFBTSxFQUNOLHFCQUFxQixZQUFZLHlEQUF5RDtnQkFDeEYsMkZBQTJGLENBQzlGLENBQUM7UUFDSixDQUFDO1FBRUQsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM1RSxDQUFDLEVBQ0QsTUFBTSxDQUNQLENBQUM7QUFDSixDQUFDIn0=
@@ -0,0 +1,4 @@
1
+ import type { ToolContext } from '../tool-context';
2
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ export default function declareTriggerWorkflowTool(mcpServer: McpServer, ctx: ToolContext): string;
4
+ //# sourceMappingURL=trigger-workflow.d.ts.map
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = declareTriggerWorkflowTool;
7
+ const forestadmin_client_1 = require("@forestadmin/forestadmin-client");
8
+ const zod_1 = require("zod");
9
+ const auth_context_1 = __importDefault(require("../utils/auth-context"));
10
+ const tool_with_logging_1 = __importDefault(require("../utils/tool-with-logging"));
11
+ const with_activity_log_1 = __importDefault(require("../utils/with-activity-log"));
12
+ const workflow_error_1 = require("../utils/workflow-error");
13
+ const WORKFLOW_ID_DESCRIPTION = 'The id of the workflow to start, as returned by listWorkflows. The workflow must have the MCP ' +
14
+ 'trigger enabled.';
15
+ const RECORD_ID_DESCRIPTION = 'The id of the record to run the workflow on. For collections with a composite primary key, ' +
16
+ 'use the packed id form (values joined by "|").';
17
+ // One message for the unknown, MCP-disabled and trigger-time-404 cases, so the LLM-facing
18
+ // contract stays uniform and never leaks whether a given workflow exists. The last sentence exists
19
+ // so a model cannot loop: an orchestrator that predates (or was rolled back before) the by-id
20
+ // endpoint 404s every lookup while listWorkflows keeps returning the same ids.
21
+ function notMcpEnabledMessage(workflowId) {
22
+ return (`Workflow "${workflowId}" is not an MCP-enabled workflow you can access. ` +
23
+ 'Use listWorkflows to discover triggerable workflows. If listWorkflows just returned this id, ' +
24
+ 'do not retry — report it to your Forest administrator instead.');
25
+ }
26
+ // Distinct from the uniform 404 message: the workflow may well exist and be triggerable, Forest
27
+ // just could not be reached. Retrying later is the right advice, and the transport detail stays in
28
+ // the operator log rather than in the model's context. Reserved for genuinely retryable failures —
29
+ // see isRetryable: a 4xx handed this message would make the model retry an id that can never work.
30
+ function lookupUnavailableMessage(workflowId) {
31
+ return (`Workflow "${workflowId}" could not be resolved because Forest could not be reached. ` +
32
+ 'This is a temporary server-side failure, not a problem with the workflow id — retry later, ' +
33
+ 'and report it to your Forest administrator if it persists.');
34
+ }
35
+ // Forest refused the lookup for a reason that will not change on retry, and said why. Reached only
36
+ // for an HttpError — isRetryable treats everything else as retryable — so `detail` is either the
37
+ // server's own JSON:API message or a fixed string, never transport detail. Keeping it distinguishes
38
+ // a malformed id, a refused identity and a browser-engine environment from one another, instead of
39
+ // having all three claim the workflow is not MCP-enabled.
40
+ function terminalLookupMessage(workflowId, detail) {
41
+ const reason = detail.replace(/\.$/, '');
42
+ return `Workflow "${workflowId}" could not be resolved — ${reason}. ${workflow_error_1.RETRY_WILL_NOT_HELP}`;
43
+ }
44
+ // The trigger is not idempotent and the write may have landed before the transport failed, so this
45
+ // deliberately does not tell the model to retry: a blind retry either duplicates intent or hits the
46
+ // active-run conflict, and neither is something a model should decide on its own.
47
+ function triggerUnavailableMessage(workflowId) {
48
+ return (`Workflow "${workflowId}" could not be triggered because Forest could not be reached. The run ` +
49
+ 'may or may not have started — do not retry blindly; report it to your Forest administrator.');
50
+ }
51
+ function unavailableCollectionMessage(workflowId) {
52
+ return (`Workflow "${workflowId}" cannot be triggered via MCP because its collection is unavailable. ` +
53
+ "Check the workflow's configuration in Forest.");
54
+ }
55
+ function declareTriggerWorkflowTool(mcpServer, ctx) {
56
+ const { forestServerClient, logger } = ctx;
57
+ return (0, tool_with_logging_1.default)(mcpServer, 'triggerWorkflow', {
58
+ annotations: {
59
+ readOnlyHint: false,
60
+ destructiveHint: true,
61
+ idempotentHint: false,
62
+ openWorldHint: true,
63
+ },
64
+ title: 'Trigger a workflow',
65
+ description: 'Start an MCP-enabled Forest workflow on a specific record. Returns a runId immediately; ' +
66
+ 'the run continues asynchronously — poll getWorkflowRun to observe its status. The record ' +
67
+ 'is not validated at trigger time: an invalid record surfaces later via getWorkflowRun. ' +
68
+ 'Discover triggerable workflows with listWorkflows first.',
69
+ inputSchema: {
70
+ workflowId: zod_1.z.string().min(1).describe(WORKFLOW_ID_DESCRIPTION),
71
+ // 255 matches the server's selectedRecordId column, so an over-long id is rejected here
72
+ // rather than after the pending audit row has been written.
73
+ recordId: zod_1.z.string().min(1).max(255).describe(RECORD_ID_DESCRIPTION),
74
+ },
75
+ }, async (args, extra) => {
76
+ const { forestServerToken, renderingId } = (0, auth_context_1.default)(extra);
77
+ // Resolve the workflow by id up front so the audit log can be labelled BEFORE the trigger
78
+ // (fail-closed). Reject unknown or MCP-disabled workflows here — no run, no log.
79
+ let workflow;
80
+ try {
81
+ workflow = await forestServerClient.getMcpWorkflowById({
82
+ forestServerToken,
83
+ renderingId,
84
+ workflowId: args.workflowId,
85
+ });
86
+ }
87
+ catch (error) {
88
+ // Always log: a 404 here is indistinguishable from a missing route, so without this an
89
+ // orchestrator too old to serve the lookup is visible only to the model.
90
+ logger('Error', `Failed to resolve workflow "${args.workflowId}" via getMcpWorkflowById: ${error instanceof Error ? error.message : String(error)}`);
91
+ // A 404 keeps the uniform wording on purpose: unknown, MCP-disabled and out-of-rendering
92
+ // must stay indistinguishable, or the contract leaks whether a given workflow exists.
93
+ if (error instanceof forestadmin_client_1.NotFoundError) {
94
+ throw new Error(notMcpEnabledMessage(args.workflowId));
95
+ }
96
+ // Any other non-retryable refusal (a 400 on a malformed id, a 401/403 on the identity, a
97
+ // 409 on a browser-engine environment) fails identically on every attempt. Sending those
98
+ // down the "retry later" path is what made a model loop forever on a request that can
99
+ // never succeed — typically a workflow *name* it guessed instead of the id.
100
+ if (!(0, workflow_error_1.isRetryable)(error)) {
101
+ throw new Error(terminalLookupMessage(args.workflowId, error instanceof Error ? error.message : String(error)));
102
+ }
103
+ // Retryable (5xx, timeout, ECONNREFUSED). Its message carries transport detail — the Forest
104
+ // server URL, an internal host and port — that has no business in a model's context, so
105
+ // only the fixed sentence travels. The full error is in the operator log above.
106
+ throw new Error(lookupUnavailableMessage(args.workflowId));
107
+ }
108
+ if (!workflow.mcpEnabled) {
109
+ throw new Error(notMcpEnabledMessage(args.workflowId));
110
+ }
111
+ // A renamed/deleted collection leaves collectionName null, which the audit route rejects
112
+ // (collectionModelName is required). Fail-closed would then block with a misleading message,
113
+ // so reject up front with one that names the actual problem.
114
+ if (workflow.collectionName == null) {
115
+ throw new Error(unavailableCollectionMessage(args.workflowId));
116
+ }
117
+ const result = await (0, with_activity_log_1.default)({
118
+ forestServerClient,
119
+ request: extra,
120
+ action: 'triggerWorkflow',
121
+ context: {
122
+ collectionName: workflow.collectionName,
123
+ recordId: args.recordId,
124
+ // One trigger writes two Activity Logs rows, and this is the first: it records the
125
+ // request, before the run exists. The orchestrator writes the second once the run is
126
+ // committed, labelled "triggered ... via MCP". The two deliberately do not share a
127
+ // wording — this one cannot carry a runId (that is what makes it fail-closed), and the
128
+ // second is best-effort, so a successful trigger can leave only this one. Identical
129
+ // labels made a single trigger read as two indistinguishable events, and made "how many
130
+ // workflows did assistants start?" answerable only by deduplicating on the runId.
131
+ label: `requested the workflow "${workflow.name}" via MCP`,
132
+ },
133
+ logger,
134
+ operation: () => forestServerClient.triggerMcpWorkflow({
135
+ forestServerToken,
136
+ renderingId,
137
+ workflowId: args.workflowId,
138
+ recordId: args.recordId,
139
+ }),
140
+ errorEnhancer: async (parsedMessage, originalError) => {
141
+ // Guard the race where the workflow is disabled/deleted between the lookup and the
142
+ // trigger.
143
+ if (originalError instanceof forestadmin_client_1.NotFoundError) {
144
+ return notMcpEnabledMessage(args.workflowId);
145
+ }
146
+ // withActivityLog rethrows the parsed message as-is, so without this the raw transport
147
+ // failure of the start call itself reaches the model — the same leak the lookup above
148
+ // guards, one call later.
149
+ if ((0, workflow_error_1.carriesTransportDetail)(originalError)) {
150
+ logger('Error', `Failed to trigger workflow "${args.workflowId}": ${originalError instanceof Error ? originalError.message : String(originalError)}`);
151
+ return triggerUnavailableMessage(args.workflowId);
152
+ }
153
+ return parsedMessage;
154
+ },
155
+ });
156
+ return {
157
+ content: [
158
+ {
159
+ type: 'text',
160
+ text: JSON.stringify({ runId: result.runId, runState: result.runState }),
161
+ },
162
+ ],
163
+ };
164
+ }, logger);
165
+ }
166
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJpZ2dlci13b3JrZmxvdy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90b29scy90cmlnZ2VyLXdvcmtmbG93LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBNkVBLDZDQWlKQztBQTFORCx3RUFBZ0U7QUFDaEUsNkJBQXdCO0FBRXhCLHlFQUFtRDtBQUNuRCxtRkFBaUU7QUFDakUsbUZBQXlEO0FBQ3pELDREQUFtRztBQUVuRyxNQUFNLHVCQUF1QixHQUMzQixnR0FBZ0c7SUFDaEcsa0JBQWtCLENBQUM7QUFFckIsTUFBTSxxQkFBcUIsR0FDekIsNkZBQTZGO0lBQzdGLGdEQUFnRCxDQUFDO0FBT25ELDBGQUEwRjtBQUMxRixtR0FBbUc7QUFDbkcsOEZBQThGO0FBQzlGLCtFQUErRTtBQUMvRSxTQUFTLG9CQUFvQixDQUFDLFVBQWtCO0lBQzlDLE9BQU8sQ0FDTCxhQUFhLFVBQVUsbURBQW1EO1FBQzFFLCtGQUErRjtRQUMvRixnRUFBZ0UsQ0FDakUsQ0FBQztBQUNKLENBQUM7QUFFRCxnR0FBZ0c7QUFDaEcsbUdBQW1HO0FBQ25HLG1HQUFtRztBQUNuRyxtR0FBbUc7QUFDbkcsU0FBUyx3QkFBd0IsQ0FBQyxVQUFrQjtJQUNsRCxPQUFPLENBQ0wsYUFBYSxVQUFVLCtEQUErRDtRQUN0Riw2RkFBNkY7UUFDN0YsNERBQTRELENBQzdELENBQUM7QUFDSixDQUFDO0FBRUQsbUdBQW1HO0FBQ25HLGlHQUFpRztBQUNqRyxvR0FBb0c7QUFDcEcsbUdBQW1HO0FBQ25HLDBEQUEwRDtBQUMxRCxTQUFTLHFCQUFxQixDQUFDLFVBQWtCLEVBQUUsTUFBYztJQUMvRCxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztJQUV6QyxPQUFPLGFBQWEsVUFBVSw2QkFBNkIsTUFBTSxLQUFLLG9DQUFtQixFQUFFLENBQUM7QUFDOUYsQ0FBQztBQUVELG1HQUFtRztBQUNuRyxv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
@@ -3,11 +3,19 @@ import type { Logger } from '../server';
3
3
  import type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';
4
4
  import type { ServerNotification, ServerRequest } from '@modelcontextprotocol/sdk/types.js';
5
5
  export type { ActivityLogAction, ActivityLogResponse };
6
+ /**
7
+ * Sent instead of the cause when a write is blocked by an audit failure whose message carries
8
+ * transport detail. Retrying is safe advice here, unlike a failure of the operation itself: this
9
+ * throws before the operation runs, so nothing has happened yet.
10
+ */
11
+ export declare const AUDIT_UNAVAILABLE_MESSAGE: string;
6
12
  export default function createPendingActivityLog(forestServerClient: ForestServerClient, request: RequestHandlerExtra<ServerRequest, ServerNotification>, action: ActivityLogAction, extra?: {
7
13
  collectionName?: string;
8
14
  recordId?: string | number;
9
15
  recordIds?: string[] | number[];
10
16
  label?: string;
17
+ /** Used only to report why a read proceeded unaudited; never sent to the server. */
18
+ logger?: Logger;
11
19
  }): Promise<ActivityLogResponse>;
12
20
  interface MarkActivityLogAsFailedOptions {
13
21
  forestServerClient: ForestServerClient;
@@ -1,9 +1,24 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AUDIT_UNAVAILABLE_MESSAGE = void 0;
3
7
  exports.default = createPendingActivityLog;
4
8
  exports.markActivityLogAsFailed = markActivityLogAsFailed;
5
9
  exports.markActivityLogAsSucceeded = markActivityLogAsSucceeded;
6
10
  const forestadmin_client_1 = require("@forestadmin/forestadmin-client");
11
+ const auth_context_1 = __importDefault(require("./auth-context"));
12
+ const workflow_error_1 = require("./workflow-error");
13
+ /**
14
+ * Fail policy for the audit trail, keyed by action type: a write whose activity log cannot be
15
+ * created is blocked (no unaudited side effect), while a read proceeds with a warning (an audit
16
+ * store outage must not take down the read surface). Both the refusal/outage path and the
17
+ * 200-with-no-id path in `createPendingActivityLog` are arbitrated by this map.
18
+ *
19
+ * One case is arbitrated by the cause instead of the action type: an authorization refusal
20
+ * (401/403) propagates for reads too — see `isAuthorizationRefusal`.
21
+ */
7
22
  const ACTION_TO_TYPE = {
8
23
  index: 'read',
9
24
  search: 'read',
@@ -14,40 +29,87 @@ const ACTION_TO_TYPE = {
14
29
  delete: 'write',
15
30
  listRelatedData: 'read',
16
31
  describeCollection: 'read',
32
+ triggerWorkflow: 'write',
17
33
  };
18
- function getAuthContext(request) {
19
- const forestServerToken = request.authInfo?.extra?.forestServerToken;
20
- const renderingId = request.authInfo?.extra?.renderingId;
21
- if (!forestServerToken || typeof forestServerToken !== 'string') {
22
- throw new Error('Invalid or missing forestServerToken in authentication context');
23
- }
24
- // renderingId can be number (from JWT) or string - convert to string for API calls
25
- if (renderingId === undefined || renderingId === null) {
26
- throw new Error('Invalid or missing renderingId in authentication context');
27
- }
28
- return { forestServerToken, renderingId: String(renderingId) };
34
+ /**
35
+ * The caller's identity was rejected (401/403), which is not an audit outage: the read the caller
36
+ * is about to perform is not authorized either. Fail-open exists so a broken audit store cannot
37
+ * take down the read surface — it must not turn an authorization refusal into a silent warning.
38
+ */
39
+ function isAuthorizationRefusal(error) {
40
+ return error instanceof forestadmin_client_1.HttpError && (error.status === 401 || error.status === 403);
29
41
  }
42
+ /**
43
+ * Sent instead of the cause when a write is blocked by an audit failure whose message carries
44
+ * transport detail. Retrying is safe advice here, unlike a failure of the operation itself: this
45
+ * throws before the operation runs, so nothing has happened yet.
46
+ */
47
+ exports.AUDIT_UNAVAILABLE_MESSAGE = 'Forest could not be reached to write the audit trail, so the operation was not performed. ' +
48
+ 'This is a temporary server-side failure — retry later, and report it to your Forest ' +
49
+ 'administrator if it persists.';
30
50
  async function createPendingActivityLog(forestServerClient, request, action, extra) {
31
51
  const type = ACTION_TO_TYPE[action];
32
- const { forestServerToken, renderingId } = getAuthContext(request);
33
- return forestServerClient.createMcpActivityLog({
34
- forestServerToken,
35
- renderingId,
36
- action,
37
- type,
38
- collectionName: extra?.collectionName,
39
- recordId: extra?.recordId,
40
- recordIds: extra?.recordIds,
41
- label: extra?.label,
42
- });
52
+ // Outside the fail policy below: a missing auth context is a caller bug, not an audit outage.
53
+ const { forestServerToken, renderingId } = (0, auth_context_1.default)(request);
54
+ let activityLog;
55
+ try {
56
+ activityLog = await forestServerClient.createMcpActivityLog({
57
+ forestServerToken,
58
+ renderingId,
59
+ action,
60
+ type,
61
+ collectionName: extra?.collectionName,
62
+ recordId: extra?.recordId,
63
+ recordIds: extra?.recordIds,
64
+ label: extra?.label,
65
+ });
66
+ }
67
+ catch (error) {
68
+ // The audit log was refused (400/404 — e.g. an unresolvable collection) or the store is
69
+ // unreachable (5xx, timeout, connection error). Both land here, and both are far more likely
70
+ // than the 200-with-null-id case below.
71
+ if (type === 'write' || isAuthorizationRefusal(error)) {
72
+ // A blocked write is reported to the caller, and for an MCP tool the caller is a model. An
73
+ // HttpError message is the server's own detail or a fixed string, both meant to be read; a
74
+ // timeout or a raw Node/superagent error instead carries the Forest server URL, an internal
75
+ // host:port or a TLS chain. Only the sanitized sentence may travel — the same split the
76
+ // workflow tools apply to their own calls, and what the 200-with-no-id branch below has
77
+ // always done. Without this the cause reaches the model verbatim.
78
+ if ((0, workflow_error_1.carriesTransportDetail)(error)) {
79
+ extra?.logger?.('Error', `Activity log for '${action}' could not be created: ${error instanceof Error ? error.message : String(error)}`);
80
+ throw new Error(exports.AUDIT_UNAVAILABLE_MESSAGE);
81
+ }
82
+ throw error;
83
+ }
84
+ // Report the cause: without it every fail-open read logs the same sentence, and an operator
85
+ // cannot tell a validation refusal (act now) from a transient outage (wait).
86
+ extra?.logger?.('Error', `Activity log for '${action}' could not be created: ${error instanceof Error ? error.message : String(error)}`);
87
+ return null;
88
+ }
89
+ // 200 with no id: the route answered but the audit store dropped the write.
90
+ if (activityLog?.id === null || activityLog?.id === undefined) {
91
+ if (type === 'write') {
92
+ throw new Error('Failed to create activity log: the server returned no activity log id. ' +
93
+ 'Blocking the operation to preserve the audit trail.');
94
+ }
95
+ extra?.logger?.('Error', `Activity log for '${action}' could not be created: the server answered 200 with no ` +
96
+ 'activity log id, so the audit store dropped the write.');
97
+ return null;
98
+ }
99
+ return activityLog;
43
100
  }
44
101
  const MAX_RETRIES = 5;
45
102
  const RETRY_DELAY_MS = 500;
46
103
  async function updateActivityLogStatus(options, attempt = 1) {
47
104
  const { forestServerClient, request, activityLog, status, logger } = options;
48
- // Use optional chaining with fallback since we're in error handling context
49
- // and don't want to throw a different error if auth context is missing
50
- const forestServerToken = request.authInfo?.extra?.forestServerToken ?? '';
105
+ // Read directly rather than through getAuthContext: this runs in a fire-and-forget path and must
106
+ // not throw a second, unrelated error. A missing token means the request cannot be authenticated,
107
+ // so skip the call rather than spend a round trip on a request that can only be refused.
108
+ const forestServerToken = request.authInfo?.extra?.forestServerToken;
109
+ if (typeof forestServerToken !== 'string' || !forestServerToken) {
110
+ logger('Error', `Cannot update activity log status to '${status}': no forestServerToken in the auth context.`);
111
+ return;
112
+ }
51
113
  try {
52
114
  await forestServerClient.updateActivityLogStatus({
53
115
  forestServerToken,
@@ -96,4 +158,4 @@ function markActivityLogAsSucceeded(options) {
96
158
  logger('Error', `Unexpected error updating activity log to 'succeeded': ${error}`);
97
159
  });
98
160
  }
99
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aXZpdHktbG9ncy1jcmVhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL2FjdGl2aXR5LWxvZ3MtY3JlYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQTZDQSwyQ0F3QkM7QUF1REQsMERBWUM7QUFTRCxnRUFZQztBQW5KRCx3RUFBZ0U7QUFJaEUsTUFBTSxjQUFjLEdBQStDO0lBQ2pFLEtBQUssRUFBRSxNQUFNO0lBQ2IsTUFBTSxFQUFFLE1BQU07SUFDZCxNQUFNLEVBQUUsTUFBTTtJQUNkLE1BQU0sRUFBRSxPQUFPO0lBQ2YsTUFBTSxFQUFFLE9BQU87SUFDZixNQUFNLEVBQUUsT0FBTztJQUNmLE1BQU0sRUFBRSxPQUFPO0lBQ2YsZUFBZSxFQUFFLE1BQU07SUFDdkIsa0JBQWtCLEVBQUUsTUFBTTtDQUMzQixDQUFDO0FBRUYsU0FBUyxjQUFjLENBQUMsT0FBK0Q7SUFJckYsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxpQkFBaUIsQ0FBQztJQUNyRSxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxXQUFXLENBQUM7SUFFekQsSUFBSSxDQUFDLGlCQUFpQixJQUFJLE9BQU8saUJBQWlCLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDaEUsTUFBTSxJQUFJLEtBQUssQ0FBQyxnRUFBZ0UsQ0FBQyxDQUFDO0lBQ3BGLENBQUM7SUFFRCxtRkFBbUY7SUFDbkYsSUFBSSxXQUFXLEtBQUssU0FBUyxJQUFJLFdBQVcsS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUN0RCxNQUFNLElBQUksS0FBSyxDQUFDLDBEQUEwRCxDQUFDLENBQUM7SUFDOUUsQ0FBQztJQUVELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7QUFDakUsQ0FBQztBQUVjLEtBQUssVUFBVSx3QkFBd0IsQ0FD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
161
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aXZpdHktbG9ncy1jcmVhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL2FjdGl2aXR5LWxvZ3MtY3JlYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUEwREEsMkNBc0ZDO0FBaUVELDBEQVlDO0FBU0QsZ0VBWUM7QUF4T0Qsd0VBQTJFO0FBRTNFLGtFQUE0QztBQUM1QyxxREFBMEQ7QUFJMUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLGNBQWMsR0FBK0M7SUFDakUsS0FBSyxFQUFFLE1BQU07SUFDYixNQUFNLEVBQUUsTUFBTTtJQUNkLE1BQU0sRUFBRSxNQUFNO0lBQ2QsTUFBTSxFQUFFLE9BQU87SUFDZixNQUFNLEVBQUUsT0FBTztJQUNmLE1BQU0sRUFBRSxPQUFPO0lBQ2YsTUFBTSxFQUFFLE9BQU87SUFDZixlQUFlLEVBQUUsTUFBTTtJQUN2QixrQkFBa0IsRUFBRSxNQUFNO0lBQzFCLGVBQWUsRUFBRSxPQUFPO0NBQ3pCLENBQUM7QUFFRjs7OztHQUlHO0FBQ0gsU0FBUyxzQkFBc0IsQ0FBQyxLQUFjO0lBQzVDLE9BQU8sS0FBSyxZQUFZLDhCQUFTLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0FBQ3RGLENBQUM7QUFFRDs7OztHQUlHO0FBQ1UsUUFBQSx5QkFBeUIsR0FDcEMsNEZBQTRGO0lBQzVGLHNGQUFzRjtJQUN0RiwrQkFBK0IsQ0FBQztBQUVuQixLQUFLLFVBQVUsd0JBQXdCLENBQ3BELGtCQUFzQyxFQUN0QyxPQUErRCxFQUMvRCxNQUF5QixFQUN6QixLQU9DO0lBRUQsTUFBTSxJQUFJLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3BDLDhGQUE4RjtJQUM5RixNQUFNLEVBQUUsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLEdBQUcsSUFBQSxzQkFBYyxFQUFDLE9BQU8sQ0FB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
@@ -0,0 +1,11 @@
1
+ import type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';
2
+ import type { ServerNotification, ServerRequest } from '@modelcontextprotocol/sdk/types.js';
3
+ /**
4
+ * Extracts the caller's Forest identity from the MCP request auth context.
5
+ * Populated by the OAuth provider's `verifyAccessToken` (see `forest-oauth-provider.ts`).
6
+ */
7
+ export default function getAuthContext(request: RequestHandlerExtra<ServerRequest, ServerNotification>): {
8
+ forestServerToken: string;
9
+ renderingId: string;
10
+ };
11
+ //# sourceMappingURL=auth-context.d.ts.map
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = getAuthContext;
4
+ /**
5
+ * Extracts the caller's Forest identity from the MCP request auth context.
6
+ * Populated by the OAuth provider's `verifyAccessToken` (see `forest-oauth-provider.ts`).
7
+ */
8
+ function getAuthContext(request) {
9
+ const forestServerToken = request.authInfo?.extra?.forestServerToken;
10
+ const renderingId = request.authInfo?.extra?.renderingId;
11
+ if (!forestServerToken || typeof forestServerToken !== 'string') {
12
+ throw new Error('Invalid or missing forestServerToken in authentication context');
13
+ }
14
+ // renderingId can be number (from JWT) or string - convert to string for API calls
15
+ if (renderingId === undefined || renderingId === null) {
16
+ throw new Error('Invalid or missing renderingId in authentication context');
17
+ }
18
+ return { forestServerToken, renderingId: String(renderingId) };
19
+ }
20
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC1jb250ZXh0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL2F1dGgtY29udGV4dC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQU9BLGlDQWdCQztBQXBCRDs7O0dBR0c7QUFDSCxTQUF3QixjQUFjLENBQ3BDLE9BQStEO0lBRS9ELE1BQU0saUJBQWlCLEdBQUcsT0FBTyxDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsaUJBQWlCLENBQUM7SUFDckUsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsV0FBVyxDQUFDO0lBRXpELElBQUksQ0FBQyxpQkFBaUIsSUFBSSxPQUFPLGlCQUFpQixLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ2hFLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0VBQWdFLENBQUMsQ0FBQztJQUNwRixDQUFDO0lBRUQsbUZBQW1GO0lBQ25GLElBQUksV0FBVyxLQUFLLFNBQVMsSUFBSSxXQUFXLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDdEQsTUFBTSxJQUFJLEtBQUssQ0FBQywwREFBMEQsQ0FBQyxDQUFDO0lBQzlFLENBQUM7SUFFRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO0FBQ2pFLENBQUMifQ==
@@ -45,17 +45,30 @@ const error_parser_1 = __importDefault(require("./error-parser"));
45
45
  */
46
46
  async function withActivityLog(options) {
47
47
  const { forestServerClient, request, action, context, logger, operation, errorEnhancer } = options;
48
- // We want to create the activity log before executing the operation
49
- // If activity log creation fails, we must prevent the execution of the operation
50
- const activityLog = await (0, activity_logs_creator_1.default)(forestServerClient, request, action, context);
48
+ // The activity log is created before the operation runs, so intent is captured even when the
49
+ // operation itself fails. `createPendingActivityLog` owns the fail policy: it throws for a write
50
+ // whose log could not be created (blocking the operation) and for an authorization refusal on
51
+ // any action, and resolves to null for a read whose audit write was lost.
52
+ const activityLog = await (0, activity_logs_creator_1.default)(forestServerClient, request, action, {
53
+ ...context,
54
+ logger,
55
+ });
56
+ // Read whose audit log could not be created (fail-open): proceed without status tracking. The
57
+ // cause was already logged by `createPendingActivityLog`.
58
+ if (!activityLog) {
59
+ logger('Warn', `Activity log for '${action}' was not persisted by the server; ` +
60
+ 'proceeding without audit trail for this read operation.');
61
+ }
51
62
  try {
52
63
  const result = await operation();
53
- (0, activity_logs_creator_1.markActivityLogAsSucceeded)({
54
- forestServerClient,
55
- request,
56
- activityLog,
57
- logger,
58
- });
64
+ if (activityLog) {
65
+ (0, activity_logs_creator_1.markActivityLogAsSucceeded)({
66
+ forestServerClient,
67
+ request,
68
+ activityLog,
69
+ logger,
70
+ });
71
+ }
59
72
  return result;
60
73
  }
61
74
  catch (error) {
@@ -70,13 +83,15 @@ async function withActivityLog(options) {
70
83
  logger('Warn', `Error enhancement failed (using original error message): ${enhancerError instanceof Error ? enhancerError.message : String(enhancerError)}`);
71
84
  }
72
85
  }
73
- (0, activity_logs_creator_1.markActivityLogAsFailed)({
74
- forestServerClient,
75
- request,
76
- activityLog,
77
- logger,
78
- });
86
+ if (activityLog) {
87
+ (0, activity_logs_creator_1.markActivityLogAsFailed)({
88
+ forestServerClient,
89
+ request,
90
+ activityLog,
91
+ logger,
92
+ });
93
+ }
79
94
  throw new Error(errorMessage);
80
95
  }
81
96
  }
82
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2l0aC1hY3Rpdml0eS1sb2cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvd2l0aC1hY3Rpdml0eS1sb2cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFzQ0Esa0NBK0NDO0FBL0VELGlGQUdpQztBQUNqQyxrRUFBNkM7QUF3QjdDOzs7R0FHRztBQUNZLEtBQUssVUFBVSxlQUFlLENBQUksT0FBa0M7SUFDakYsTUFBTSxFQUFFLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLEdBQ3RGLE9BQU8sQ0FBQztJQUVWLG9FQUFvRTtJQUNwRSxpRkFBaUY7SUFFakYsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFBLCtCQUF3QixFQUFDLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFFakcsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxTQUFTLEVBQUUsQ0FBQztRQUVqQyxJQUFBLGtEQUEwQixFQUFDO1lBQ3pCLGtCQUFrQjtZQUNsQixPQUFPO1lBQ1AsV0FBVztZQUNYLE1BQU07U0FDUCxDQUFDLENBQUM7UUFFSCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE1BQU0sV0FBVyxHQUFHLElBQUEsc0JBQWUsRUFBQyxLQUFLLENBQUMsQ0FBQztRQUMzQyxJQUFJLFlBQVksR0FBRyxXQUFXLElBQUksQ0FBQyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUUzRix5RkFBeUY7UUFDekYsSUFBSSxhQUFhLEVBQUUsQ0FBQztZQUNsQixJQUFJLENBQUM7Z0JBQ0gsWUFBWSxHQUFHLE1BQU0sYUFBYSxDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMxRCxDQUFDO1lBQUMsT0FBTyxhQUFhLEVBQUUsQ0FBQztnQkFDdkIsTUFBTSxDQUNKLE1BQU0sRUFDTiw0REFDRSxhQUFhLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUMvRSxFQUFFLENBQ0gsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBQSwrQ0FBdUIsRUFBQztZQUN0QixrQkFBa0I7WUFDbEIsT0FBTztZQUNQLFdBQVc7WUFDWCxNQUFNO1NBQ1AsQ0FBQyxDQUFDO1FBRUgsTUFBTSxJQUFJLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNoQyxDQUFDO0FBQ0gsQ0FBQyJ9
97
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2l0aC1hY3Rpdml0eS1sb2cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvd2l0aC1hY3Rpdml0eS1sb2cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFzQ0Esa0NBaUVDO0FBakdELGlGQUdpQztBQUNqQyxrRUFBNkM7QUF3QjdDOzs7R0FHRztBQUNZLEtBQUssVUFBVSxlQUFlLENBQUksT0FBa0M7SUFDakYsTUFBTSxFQUFFLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLEdBQ3RGLE9BQU8sQ0FBQztJQUVWLDZGQUE2RjtJQUM3RixpR0FBaUc7SUFDakcsOEZBQThGO0lBQzlGLDBFQUEwRTtJQUMxRSxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUEsK0JBQXdCLEVBQUMsa0JBQWtCLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRTtRQUN0RixHQUFHLE9BQU87UUFDVixNQUFNO0tBQ1AsQ0FBQyxDQUFDO0lBRUgsOEZBQThGO0lBQzlGLDBEQUEwRDtJQUMxRCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDakIsTUFBTSxDQUNKLE1BQU0sRUFDTixxQkFBcUIsTUFBTSxxQ0FBcUM7WUFDOUQseURBQXlELENBQzVELENBQUM7SUFDSixDQUFDO0lBRUQsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxTQUFTLEVBQUUsQ0FBQztRQUVqQyxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQ2hCLElBQUEsa0RBQTBCLEVBQUM7Z0JBQ3pCLGtCQUFrQjtnQkFDbEIsT0FBTztnQkFDUCxXQUFXO2dCQUNYLE1BQU07YUFDUCxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixNQUFNLFdBQVcsR0FBRyxJQUFBLHNCQUFlLEVBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0MsSUFBSSxZQUFZLEdBQUcsV0FBVyxJQUFJLENBQUMsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFFM0YseUZBQXlGO1FBQ3pGLElBQUksYUFBYSxFQUFFLENBQUM7WUFDbEIsSUFBSSxDQUFDO2dCQUNILFlBQVksR0FBRyxNQUFNLGFBQWEsQ0FBQyxZQUFZLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDMUQsQ0FBQztZQUFDLE9BQU8sYUFBYSxFQUFFLENBQUM7Z0JBQ3ZCLE1BQU0sQ0FDSixNQUFNLEVBQ04sNERBQ0UsYUFBYSxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FDL0UsRUFBRSxDQUNILENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksV0FBVyxFQUFFLENBQUM7WUFDaEIsSUFBQSwrQ0FBdUIsRUFBQztnQkFDdEIsa0JBQWtCO2dCQUNsQixPQUFPO2dCQUNQLFdBQVc7Z0JBQ1gsTUFBTTthQUNQLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCxNQUFNLElBQUksS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ2hDLENBQUM7QUFDSCxDQUFDIn0=
@@ -0,0 +1,29 @@
1
+ import type { Logger } from '../server';
2
+ /**
3
+ * True when the error's message carries transport detail — the Forest server URL, an internal
4
+ * host:port, a TLS chain. Anything that is not an `HttpError` reached us as a raw Node/superagent
5
+ * error, so its message is unfit for a model's context.
6
+ */
7
+ export declare function carriesTransportDetail(error: unknown): boolean;
8
+ /**
9
+ * True when retrying the same call could plausibly succeed. A 4xx that is neither a timeout nor a
10
+ * rate-limit is the caller's own fault and will fail identically forever — telling a model to
11
+ * retry one of those is what turns a bad argument into an endless loop.
12
+ */
13
+ export declare function isRetryable(error: unknown): boolean;
14
+ /**
15
+ * Closing advice for a refusal that will repeat. Shared so the three workflow tools tell a model
16
+ * the same thing — the wording is the only signal it has that retrying is pointless.
17
+ */
18
+ export declare const RETRY_WILL_NOT_HELP = "Retrying will not help: fix the request, or report it to your Forest administrator.";
19
+ /**
20
+ * Turns a workflow transport failure into an error the model may see: the full cause always goes
21
+ * to the operator log, a message carrying transport detail is replaced by `unavailableMessage`,
22
+ * and a refusal that will repeat is told to stop.
23
+ */
24
+ export default function toModelSafeError(error: unknown, { logger, context, unavailableMessage, }: {
25
+ logger: Logger;
26
+ context: string;
27
+ unavailableMessage: string;
28
+ }): Error;
29
+ //# sourceMappingURL=workflow-error.d.ts.map
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RETRY_WILL_NOT_HELP = void 0;
4
+ exports.carriesTransportDetail = carriesTransportDetail;
5
+ exports.isRetryable = isRetryable;
6
+ exports.default = toModelSafeError;
7
+ const forestadmin_client_1 = require("@forestadmin/forestadmin-client");
8
+ // A timeout is the one HttpError whose message is built client-side: ServerUtils interpolates the
9
+ // full Forest server URL into it. Every other HttpError message is either a fixed string or the
10
+ // server's own JSON:API detail, both of which are meant to be read.
11
+ const TIMEOUT_STATUS = 408;
12
+ const RATE_LIMITED_STATUS = 429;
13
+ /**
14
+ * True when the error's message carries transport detail — the Forest server URL, an internal
15
+ * host:port, a TLS chain. Anything that is not an `HttpError` reached us as a raw Node/superagent
16
+ * error, so its message is unfit for a model's context.
17
+ */
18
+ function carriesTransportDetail(error) {
19
+ return !(error instanceof forestadmin_client_1.HttpError) || error.status === TIMEOUT_STATUS;
20
+ }
21
+ /**
22
+ * True when retrying the same call could plausibly succeed. A 4xx that is neither a timeout nor a
23
+ * rate-limit is the caller's own fault and will fail identically forever — telling a model to
24
+ * retry one of those is what turns a bad argument into an endless loop.
25
+ */
26
+ function isRetryable(error) {
27
+ if (!(error instanceof forestadmin_client_1.HttpError))
28
+ return true;
29
+ return (error.status < 400 ||
30
+ error.status >= 500 ||
31
+ error.status === TIMEOUT_STATUS ||
32
+ error.status === RATE_LIMITED_STATUS);
33
+ }
34
+ /**
35
+ * Closing advice for a refusal that will repeat. Shared so the three workflow tools tell a model
36
+ * the same thing — the wording is the only signal it has that retrying is pointless.
37
+ */
38
+ exports.RETRY_WILL_NOT_HELP = 'Retrying will not help: fix the request, or report it to your Forest administrator.';
39
+ /**
40
+ * Turns a workflow transport failure into an error the model may see: the full cause always goes
41
+ * to the operator log, a message carrying transport detail is replaced by `unavailableMessage`,
42
+ * and a refusal that will repeat is told to stop.
43
+ */
44
+ function toModelSafeError(error, { logger, context, unavailableMessage, }) {
45
+ const detail = error instanceof Error ? error.message : String(error);
46
+ logger('Error', `${context}: ${detail}`);
47
+ if (carriesTransportDetail(error))
48
+ return new Error(unavailableMessage);
49
+ // A 4xx that is neither a timeout nor a rate limit fails identically on every attempt. Handing a
50
+ // model the bare reason leaves nothing saying so — and these are the tools it is told to poll, so
51
+ // the loop it produces is the documented usage rather than a mistake.
52
+ if (!isRetryable(error)) {
53
+ return new Error(`${detail.replace(/\.$/, '')}. ${exports.RETRY_WILL_NOT_HELP}`);
54
+ }
55
+ return new Error(detail);
56
+ }
57
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2Zsb3ctZXJyb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvd29ya2Zsb3ctZXJyb3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBZUEsd0RBRUM7QUFPRCxrQ0FTQztBQWNELG1DQXNCQztBQW5FRCx3RUFBNEQ7QUFFNUQsa0dBQWtHO0FBQ2xHLGdHQUFnRztBQUNoRyxvRUFBb0U7QUFDcEUsTUFBTSxjQUFjLEdBQUcsR0FBRyxDQUFDO0FBQzNCLE1BQU0sbUJBQW1CLEdBQUcsR0FBRyxDQUFDO0FBRWhDOzs7O0dBSUc7QUFDSCxTQUFnQixzQkFBc0IsQ0FBQyxLQUFjO0lBQ25ELE9BQU8sQ0FBQyxDQUFDLEtBQUssWUFBWSw4QkFBUyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxjQUFjLENBQUM7QUFDMUUsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFnQixXQUFXLENBQUMsS0FBYztJQUN4QyxJQUFJLENBQUMsQ0FBQyxLQUFLLFlBQVksOEJBQVMsQ0FBQztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBRS9DLE9BQU8sQ0FDTCxLQUFLLENBQUMsTUFBTSxHQUFHLEdBQUc7UUFDbEIsS0FBSyxDQUFDLE1BQU0sSUFBSSxHQUFHO1FBQ25CLEtBQUssQ0FBQyxNQUFNLEtBQUssY0FBYztRQUMvQixLQUFLLENBQUMsTUFBTSxLQUFLLG1CQUFtQixDQUNyQyxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7R0FHRztBQUNVLFFBQUEsbUJBQW1CLEdBQzlCLHFGQUFxRixDQUFDO0FBRXhGOzs7O0dBSUc7QUFDSCxTQUF3QixnQkFBZ0IsQ0FDdEMsS0FBYyxFQUNkLEVBQ0UsTUFBTSxFQUNOLE9BQU8sRUFDUCxrQkFBa0IsR0FDOEM7SUFFbEUsTUFBTSxNQUFNLEdBQUcsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRXRFLE1BQU0sQ0FBQyxPQUFPLEVBQUUsR0FBRyxPQUFPLEtBQUssTUFBTSxFQUFFLENBQUMsQ0FBQztJQUV6QyxJQUFJLHNCQUFzQixDQUFDLEtBQUssQ0FBQztRQUFFLE9BQU8sSUFBSSxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUV4RSxpR0FBaUc7SUFDakcsa0dBQWtHO0lBQ2xHLHNFQUFzRTtJQUN0RSxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDeEIsT0FBTyxJQUFJLEtBQUssQ0FBQyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLDJCQUFtQixFQUFFLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBRUQsT0FBTyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUMzQixDQUFDIn0=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forestadmin/mcp-server",
3
- "version": "1.22.1",
3
+ "version": "1.23.0",
4
4
  "description": "Model Context Protocol server for Forest Admin with OAuth authentication",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -16,8 +16,8 @@
16
16
  "directory": "packages/mcp-server"
17
17
  },
18
18
  "dependencies": {
19
- "@forestadmin/agent-client": "1.14.0",
20
- "@forestadmin/forestadmin-client": "1.42.1",
19
+ "@forestadmin/agent-client": "1.14.1",
20
+ "@forestadmin/forestadmin-client": "1.43.0",
21
21
  "@modelcontextprotocol/sdk": "^1.28.0",
22
22
  "cors": "^2.8.5",
23
23
  "express": "^5.2.1",