@forestadmin/mcp-server 1.22.1 → 1.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/http-client/index.d.ts +1 -1
- package/dist/http-client/index.js +6 -2
- package/dist/http-client/mcp-http-client.d.ts +9 -4
- package/dist/http-client/mcp-http-client.js +17 -4
- package/dist/http-client/types.d.ts +18 -2
- package/dist/server.d.ts +1 -1
- package/dist/server.js +13 -1
- package/dist/tools/get-workflow-run.d.ts +4 -0
- package/dist/tools/get-workflow-run.js +64 -0
- package/dist/tools/list-workflows.d.ts +4 -0
- package/dist/tools/list-workflows.js +73 -0
- package/dist/tools/trigger-workflow.d.ts +4 -0
- package/dist/tools/trigger-workflow.js +166 -0
- package/dist/utils/activity-logs-creator.d.ts +8 -0
- package/dist/utils/activity-logs-creator.js +88 -26
- package/dist/utils/auth-context.d.ts +11 -0
- package/dist/utils/auth-context.js +20 -0
- package/dist/utils/with-activity-log.js +31 -16
- package/dist/utils/workflow-error.d.ts +29 -0
- package/dist/utils/workflow-error.js +57 -0
- package/package.json +3 -3
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
|
-
|
|
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,
|
|
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
|
|
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
|
|
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,
|
|
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3NlcnZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxzREFBc0Q7QUFDdEQsc0VBQXNFO0FBQ3RFLHVCQUFxQjtBQVNyQiw4RkFBbUc7QUFDbkcsNEZBQTZGO0FBQzdGLHNGQUF1RjtBQUN2RiwwR0FBb0c7QUFDcEcsa0dBQW1HO0FBQ25HLCtFQUd5RDtBQUN6RCxvRUFBb0U7QUFDcEUsMEZBQW1HO0FBQ25HLGdEQUF3QjtBQUN4QixzREFBOEI7QUFDOUIsMkNBQTZCO0FBRTdCLHlGQUFnRTtBQUNoRSxnREFBMEQ7QUFDMUQsb0ZBQTBEO0FBQzFELCtDQUF5RDtBQUN6RCwyQ0FBaUU7QUFDakUsa0VBQXFEO0FBQ3JELDREQUErQztBQUMvQyw0REFBK0M7QUFDL0Msc0ZBQXdFO0FBQ3hFLG9FQUF1RDtBQUN2RCw0RUFBOEQ7QUFDOUQsOEVBQStEO0FBQy9ELGdGQUFpRTtBQUNqRSx3REFBMkM7QUFDM0Msd0VBQTBEO0FBQzFELDRFQUE4RDtBQUM5RCxvR0FBb0Y7QUFDcEYsZ0ZBQWtFO0FBQ2xFLDREQUErQztBQUMvQyxzRkFBNEQ7QUFDNUQsMEZBQWdFO0FBQ2hFLDJEQUErRTtBQUMvRSxnRkFBd0U7QUFDeEUsa0VBQWtEO0FBQ2xELHVDQUEwQztBQUU3QixRQUFBLFFBQVEsR0FBRyxpRUFBaUUsQ0FBQztBQVcxRixTQUFTLGVBQWUsQ0FBQyxLQUFlO0lBQ3RDLElBQUksS0FBSyxLQUFLLE9BQU87UUFBRSxPQUFPLENBQUMsR0FBVyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2xFLElBQUksS0FBSyxLQUFLLE1BQU07UUFBRSxPQUFPLENBQUMsR0FBVyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRWhFLE9BQU8sQ0FBQyxHQUFXLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDNUMsQ0FBQztBQUVELE1BQU0sYUFBYSxHQUFXLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO0lBQy9DLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUNsQyxDQUFDLENBQUM7QUFFRixTQUFTLGlCQUFpQixDQUFDLFVBQWtCO0lBQzNDLElBQUksVUFBVSxJQUFJLEdBQUc7UUFBRSxPQUFPLE9BQU8sQ0FBQztJQUN0QyxJQUFJLFVBQVUsSUFBSSxHQUFHO1FBQUUsT0FBTyxNQUFNLENBQUM7SUFFckMsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELFNBQVMsaUJBQWlCLENBQUMsTUFBYyxFQUFFLE9BQWUsRUFBRSxHQUFVO0lBQ3BFLE1BQU0sQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFFekIsSUFBSSxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDZCxNQUFNLENBQUMsT0FBTyxFQUFFLFVBQVUsR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDekMsQ0FBQztBQUNILENBQUM7QUFFRCxxRUFBcUU7QUFDckUsTUFBTSwwQkFBMEIsR0FBNkI7SUFDM0QsSUFBSSxFQUFFLENBQUMsZ0JBQWdCLENBQUM7SUFDeEIsV0FBVyxFQUFFLENBQUMsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixDQUFDO0lBQ2pFLE1BQU0sRUFBRSxDQUFDLGdCQUFnQixDQUFDO0lBQzFCLE1BQU0sRUFBRSxDQUFDLGdCQUFnQixFQUFFLFVBQVUsQ0FBQztJQUN0QyxNQUFNLEVBQUUsQ0FBQyxnQkFBZ0IsRUFBRSxXQUFXLENBQUM7SUFDdkMsa0JBQWtCLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQztJQUN0QyxhQUFhLEVBQUUsQ0FBQyxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsV0FBVyxDQUFDO0lBQzVELGFBQWEsRUFBRSxDQUFDLGdCQUFnQixFQUFFLFlBQVksRUFBRSxXQUFXLENBQUM7SUFDNUQsdUJBQXVCLEVBQUUsQ0FBQyxVQUFVLENBQUM7SUFDckMsU0FBUyxFQUFFLENBQUMsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLGdCQUFnQixDQUFDO0lBQ2pGLFVBQVUsRUFBRSxDQUFDLGdCQUFnQixFQUFFLGNBQWMsRUFBRSxnQkFBZ0IsRUFBRSxpQkFBaUIsQ0FBQztJQUNuRixhQUFhLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQztJQUNqQyxlQUFlLEVBQUUsQ0FBQyxZQUFZLEVBQUUsVUFBVSxDQUFDO0lBQzNDLGNBQWMsRUFBRSxDQUFDLE9BQU8sQ0FBQztDQUMxQixDQUFDO0FBOEVGOzs7OztHQUtHO0FBRUgsTUFBcUIsZUFBZTtJQXFCbEMsWUFBWSxPQUFnQztRQVhwQyxvQkFBZSxHQUFhLEVBQUUsQ0FBQztRQVlyQyxJQUFJLENBQUMsZUFBZSxHQUFHLE9BQU8sRUFBRSxlQUFlLElBQUksNkJBQTZCLENBQUM7UUFDakYsSUFBSSxDQUFDLFlBQVksR0FBRyxPQUFPLEVBQUUsWUFBWSxJQUFJLDZCQUE2QixDQUFDO1FBQzNFLElBQUksQ0FBQyxTQUFTLEdBQUcsT0FBTyxFQUFFLFNBQVMsQ0FBQztRQUNwQyxJQUFJLENBQUMsVUFBVSxHQUFHLE9BQU8sRUFBRSxVQUFVLENBQUM7UUFDdEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLEVBQUUsTUFBTSxJQUFJLGFBQWEsQ0FBQztRQUMvQyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN0RCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUEsOEJBQWtCLEVBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBQSw2QkFBaUIsRUFBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLEVBQUUsZUFBZSxDQUFDO1FBQ2hELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBQSxtQkFBaUIsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVsRSxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBQSwrQkFBbUIsRUFBQyxPQUFPLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztRQUM3RSx5RUFBeUU7UUFDekUsSUFBSSxDQUFDLGtCQUFrQixHQUFHLE9BQU8sRUFBRSxXQUFXLElBQUksU0FBUyxDQUFDO1FBRTVELDZGQUE2RjtRQUM3Riw2RkFBNkY7UUFDN0YsNkZBQTZGO1FBQzdGLGdFQUFnRTtRQUNoRSxJQUFJLE9BQU8sRUFBRSxXQUFXLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDbkMsd0ZBQXdGO1lBQ3hGLHlGQUF5RjtZQUN6RixzREFBc0Q7WUFDdEQsSUFBSSxPQUFPLENBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQyxFQUFFLENBQUM7Z0JBQzlELElBQUksQ0FBQyxNQUFNLENBQ1QsTUFBTSxFQUNOLHVGQUF1RixDQUN4RixDQUFDO1lBQ0osQ0FBQztZQUVELElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUVELG9EQUFvRDtRQUNwRCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsT0FBTyxFQUFFLGtCQUFrQixJQUFJLElBQUksQ0FBQywrQkFBK0IsRUFBRSxDQUFDO0lBQ2xHLENBQUM7SUFFTywrQkFBK0I7UUFDckMsT0FBTyxJQUFBLHNDQUF3QixFQUFDO1lBQzlCLGVBQWUsRUFBRSxJQUFJLENBQUMsZUFBZTtZQUNyQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7U0FDMUIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLEtBQUssQ0FBQyxvQkFBb0I7UUFDaEMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFBLGtDQUFpQixFQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1lBQ2hFLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBQSxtQ0FBa0IsRUFBQyxNQUFNLENBQUMsQ0FBQztRQUNwRCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksQ0FBQyxNQUFNLENBQ1QsTUFBTSxFQUNOLGtDQUFrQyxLQUFLLGdGQUFnRixDQUN4SCxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFTyxlQUFlO1FBQ3JCLE1BQU0sU0FBUyxHQUFHLElBQUksa0JBQVMsQ0FBQztZQUM5QixJQUFJLEVBQUUsY0FBSTtZQUNWLE9BQU8sRUFBRSxpQkFBTztZQUNoQixLQUFLLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxnQkFBUSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsQ0FBQztTQUNsRCxDQUFDLENBQUM7UUFFSCxNQUFNLEdBQUcsR0FBZ0I7WUFDdkIsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLGtCQUFrQjtZQUMzQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFDbkIsZUFBZSxFQUFFLElBQUksQ0FBQyxlQUFlO1lBQ3JDLGVBQWUsRUFBRSxJQUFJLENBQUMsZUFBZTtZQUNyQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVc7U0FDOUIsQ0FBQztRQUVGLE1BQU0sUUFBUSxHQUFzRDtZQUNsRSxFQUFFLElBQUksRUFBRSxvQkFBb0IsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBQSw2QkFBNkIsRUFBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLEVBQUU7WUFDN0YsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFBLGNBQWUsRUFBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLEVBQUU7WUFDakUsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFBLHNCQUFzQixFQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsRUFBRTtZQUMvRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUEsZ0JBQWlCLEVBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxFQUFFO1lBQ3JFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBQSxnQkFBaUIsRUFBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLEVBQUU7WUFDckUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFBLGdCQUFpQixFQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsRUFBRTtZQUNyRSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUEsbUJBQW9CLEVBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxFQUFFO1lBQzNFLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBQSxvQkFBcUIsRUFBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLEVBQUU7WUFDN0UsRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFBLHlCQUF3QixFQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsRUFBRTtZQUNuRixFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUEsd0JBQXdCLEVBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxFQUFFO1lBQ25GLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBQSx3QkFBd0IsRUFBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLEVBQUU7WUFDbkYsRUFBRSxJQUFJLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUEsMEJBQTBCLEVBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxFQUFFO1lBQ3ZGLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFBLDBCQUF5QixFQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsRUFBRTtZQUNyRixHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVc7Z0JBQ2xCLENBQUMsQ0FBQztvQkFDRTt3QkFDRSxJQUFJLEVBQUUseUJBQWtDO3dCQUN4QyxRQUFRLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBQSxvQ0FBa0MsRUFBQyxTQUFTLEVBQUUsR0FBRyxDQUFDO3FCQUNuRTtpQkFDRjtnQkFDSCxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQ1IsQ0FBQztRQUVGLE1BQU0sa0JBQWtCLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3JGLE1BQU0saUJBQWlCLEdBQUcsUUFBUTthQUMvQixNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUNqRCxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFMUIsTUFBTSxTQUFTLEdBQUcsa0JBQWtCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFFbEUsSUFBSSxDQUFDLE1BQU0sQ0FDVCxNQUFNLEVBQ04sa0JBQWtCLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssU0FBUyxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUMsTUFBTSxHQUFHLENBQ2xGLENBQUM7UUFFRixJQUFJLGlCQUFpQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNqQyxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDO1lBQzlCLElBQUksQ0FBQyxNQUFNLENBQ1QsTUFBTSxFQUNOLG1CQUFtQixpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssaUJBQWlCLENBQUMsTUFBTSxJQUFJLEtBQUssR0FBRyxDQUN6RixDQUFDO1FBQ0osQ0FBQztRQUVELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFTyxtQkFBbUIsQ0FBQyxPQUFnQztRQUMxRCxNQUFNLFlBQVksR0FBZTtZQUMvQixvQkFBb0I7WUFDcEIsTUFBTTtZQUNOLGFBQWE7WUFDYixRQUFRO1lBQ1IsUUFBUTtZQUNSLFFBQVE7WUFDUixXQUFXO1lBQ1gsWUFBWTtZQUNaLGVBQWU7WUFDZixlQUFlO1lBQ2YsZUFBZTtZQUNmLGlCQUFpQjtZQUNqQixnQkFBZ0I7WUFDaEIseUJBQXlCO1NBQzFCLENBQUM7UUFFRixNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsQ0FBQyxPQUFPLEVBQUUsWUFBWSxJQUFJLFlBQVksQ0FBQyxDQUFDO1FBRS9ELElBQUksT0FBTyxFQUFFLFlBQVksRUFBRSxDQUFDO1lBQzFCLE1BQU0sZUFBZSxHQUFHLElBQUksR0FBRyxDQUFTLFlBQVksQ0FBQyxDQUFDO1lBQ3RELE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7WUFFckYsSUFBSSxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUM1QixJQUFJLENBQUMsTUFBTSxDQUNULE1BQU0sRUFDTix1Q0FBdUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQ3pGLENBQUM7WUFDSixDQUFDO1lBRUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLEVBQUUsQ0FBQztnQkFDekQsSUFBSSxDQUFDLE1BQU0sQ0FDVCxNQUFNLEVBQ04sd0dBQXdHLENBQ3pHLENBQUM7WUFDSixDQUFDO1lBRUQsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FDcEMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEtBQUssb0JBQW9CLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUM1RCxDQUFDO1lBRUYsSUFBSSxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUMxQixNQUFNLFFBQVEsR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUN2QyxJQUFJLENBQUMsTUFBTSxDQUNULE1BQU0sRUFDTixnQ0FBZ0MsUUFBUSx5Q0FBeUMsQ0FDbEYsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDO1FBRUQsd0NBQXdDO1FBQ3hDLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUVsQyxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRU8sbUJBQW1CO1FBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLEtBQUssQ0FDYiwyR0FBMkcsQ0FDNUcsQ0FBQztRQUNKLENBQUM7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3JCLE1BQU0sSUFBSSxLQUFLLENBQ2IsOEdBQThHLENBQy9HLENBQUM7UUFDSixDQUFDO1FBRUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDcEUsQ0FBQztJQUVEOzs7T0FHRztJQUNLLG9CQUFvQixDQUMxQixRQUFnQixFQUNoQixJQUE2QjtRQUU3QixNQUFNLGFBQWEsR0FBRywwQkFBMEIsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFakUsT0FBTyxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakcsQ0FBQztJQUVEOztPQUVHO0lBQ0ssb0JBQW9CLENBQUMsR0FBb0I7UUFTL0MsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLElBQXVCLENBQUM7UUFFekMsSUFBSSxJQUFJLEVBQUUsTUFBTSxLQUFLLFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUM7WUFDeEQsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztRQUNsQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUM7UUFDekMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUUzRCxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxjQUFjLFFBQVEsY0FBYyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN0RixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssS0FBSyxDQUFDLGdCQUFnQixDQUFDLEdBQW9CLEVBQUUsR0FBcUI7UUFDeEUsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLElBQUksRUFBRSxNQUFNLElBQUksU0FBUyxDQUFDO1FBQ2hELElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLFlBQVksR0FBRyxDQUFDLE1BQU0sSUFBSSxHQUFHLENBQUMsSUFBSSxLQUFLLFNBQVMsR0FBRyxDQUFDLENBQUM7UUFFekUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQy9CLElBQUEsMEJBQWdDLEVBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVuRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdEMsTUFBTSxTQUFTLEdBQUcsSUFBSSxpREFBNkIsQ0FBQyxFQUFFLGtCQUFrQixFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFFdkYsTUFBTSxPQUFPLEdBQUcsS0FBSyxJQUFJLEVBQUU7WUFDekIsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDMUIsQ0FBQyxDQUFDO1FBRUYsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ2hDLE1BQU0sU0FBUyxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUVsRCw4RUFBOEU7WUFDOUUsaUZBQWlGO1lBQ2pGLElBQUksR0FBRyxDQUFDLFVBQVUsSUFBSSxHQUFHLEVBQUUsQ0FBQztnQkFDMUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsMkJBQTJCLEdBQUcsQ0FBQyxVQUFVLFNBQVMsU0FBUyxHQUFHLENBQUMsQ0FBQztZQUN2RixDQUFDO1FBQ0gsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsSUFBSSxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQ3RCLE1BQU0sT0FBTyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFO29CQUMxQixJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSw2QkFBNkIsR0FBRyxFQUFFLENBQUMsQ0FBQztnQkFDMUQsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sR0FBRyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFO29CQUNuQixPQUFPLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUU7d0JBQ3BCLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLDZCQUE2QixHQUFHLEVBQUUsQ0FBQyxDQUFDO29CQUMxRCxDQUFDLENBQUMsQ0FBQztnQkFDTCxDQUFDLENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxLQUFLLENBQUMsZUFBZSxDQUFDLE9BQWE7UUFDakMsTUFBTSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUU3RCwrRkFBK0Y7UUFDL0YsMkZBQTJGO1FBQzNGLHdGQUF3RjtRQUN4RiwyRkFBMkY7UUFDM0YsNEZBQTRGO1FBQzVGLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMseUJBQXlCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUMxRSxnRkFBZ0Y7WUFDaEYsd0ZBQXdGO1lBQ3hGLG9GQUFvRjtZQUNwRixJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxDQUFDO2dCQUN0QyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSwyQkFBZ0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDNUQsQ0FBQztZQUVELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBQSwwQkFBa0IsRUFDbkM7Z0JBQ0UsR0FBRyxJQUFJLENBQUMsa0JBQWtCO2dCQUMxQixHQUFHLENBQUMsSUFBSSxDQUFDLGdCQUFnQixJQUFJLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO2FBQ2pFLEVBQ0QsVUFBVSxFQUNWLElBQUksQ0FBQyxNQUFNLENBQ1osQ0FBQztZQUVGLDRGQUE0RjtZQUM1RiwyRkFBMkY7WUFDM0YsMEZBQTBGO1lBQzFGLDRCQUE0QjtZQUM1QixJQUNFLElBQUksQ0FBQyxnQkFBZ0I7Z0JBQ3JCLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsc0JBQXNCLEVBQ25FLENBQUM7Z0JBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FDVCxNQUFNLEVBQ04sd0JBQXdCLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxvQ0FBb0M7b0JBQ25GLG1CQUFtQixJQUFJLENBQUMsV0FBVyxDQUFDLHNCQUFzQixVQUFVO29CQUNwRSw0RUFBNEU7b0JBQzVFLDZEQUE2RCxDQUNoRSxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFFRCxNQUFNLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBRWxDLE1BQU0sR0FBRyxHQUFHLElBQUEsaUJBQU8sR0FBRSxDQUFDO1FBRXRCLCtFQUErRTtRQUMvRSx3RUFBd0U7UUFDeEUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFMUIsR0FBRyxDQUFDLEdBQUcsQ0FDTCxJQUFBLGNBQUksRUFBQztZQUNILE1BQU0sRUFBRSxHQUFHO1NBQ1osQ0FBQyxDQUNILENBQUM7UUFFRiw0QkFBNEI7UUFDNUIsTUFBTSxhQUFhLEdBQUcsSUFBSSwrQkFBbUIsQ0FBQztZQUM1QyxlQUFlLEVBQUUsSUFBSSxDQUFDLGVBQWU7WUFDckMsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO1lBQy9CLFNBQVM7WUFDVCxVQUFVO1lBQ1YsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtZQUN2QixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7WUFDdkIsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLG1CQUFtQjtTQUM5QyxDQUFDLENBQUM7UUFDSCxNQUFNLGFBQWEsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUVqQyxrRkFBa0Y7UUFDbEYsTUFBTSxnQkFBZ0IsR0FBRyxPQUFPLElBQUksYUFBYSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBRS9ELElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3RCLE1BQU0sSUFBSSxLQUFLLENBQ2IsK0NBQStDO2dCQUM3QywyR0FBMkcsQ0FDOUcsQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQztRQUVsQywyRkFBMkY7UUFDM0YsNkZBQTZGO1FBQzdGLElBQUksTUFBTSxJQUFJLGdCQUFnQixDQUFDLFFBQVEsS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUNoRCxNQUFNLElBQUksS0FBSyxDQUNiLGlCQUFpQixNQUFNLGdFQUFnRTtnQkFDckYseUJBQXlCLGdCQUFnQixDQUFDLFFBQVEsbUNBQW1DO2dCQUNyRix3QkFBd0IsQ0FDM0IsQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDO1FBQy9GLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQztRQUV6RixNQUFNLGVBQWUsR0FBRyxDQUFDLFVBQVUsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBRTdFLG1GQUFtRjtRQUNuRixNQUFNLGFBQWEsR0FBRyxJQUFBLCtCQUFtQixFQUFDO1lBQ3hDLFFBQVEsRUFBRSxhQUFhO1lBQ3ZCLFNBQVM7WUFDVCxPQUFPLEVBQUUsU0FBUztZQUNsQixlQUFlO1NBQ2hCLENBQUMsQ0FBQztRQUVILGFBQWEsQ0FBQyxxQ0FBcUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9ELGFBQWEsQ0FBQyx3QkFBd0IsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2xELGFBQWEsQ0FBQyxnQ0FBZ0MsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRTFELGFBQWEsQ0FBQyxjQUFjLEdBQUcsR0FBRyxTQUFTLENBQUMsSUFBSSxhQUFhLENBQUM7UUFDOUQsYUFBYSxDQUFDLHNCQUFzQixHQUFHLEdBQUcsU0FBUyxDQUFDLElBQUksaUJBQWlCLENBQUM7UUFDMUUsaUVBQWlFO1FBQ2pFLGFBQWEsQ0FBQyxxQkFBcUIsR0FBRyxHQUFHLElBQUksQ0FBQyxlQUFlLGlCQUFpQixDQUFDO1FBQy9FLDJEQUEyRDtRQUMzRCxPQUFPLGFBQWEsQ0FBQyxtQkFBbUIsQ0FBQztRQUV6Qyx5RUFBeUU7UUFDekUsNEVBQTRFO1FBQzVFLGtEQUFrRDtRQUNsRCxxRkFBcUY7UUFDckYsdUZBQXVGO1FBQ3ZGLElBQUksSUFBSSxDQUFDLGdCQUFnQixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUM5QyxNQUFNLFdBQVcsR0FBRyxHQUFHLE1BQU0sY0FBYyxDQUFDO1lBRTVDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUM7Z0JBQzlCLFFBQVEsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVE7Z0JBQ25DLGFBQWEsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLHNCQUFzQjtnQkFDdEQsVUFBVSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCO2dCQUM3QyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLG1CQUFtQjtnQkFDdEQsYUFBYSxFQUFFLElBQUksR0FBRyxDQUFDLFdBQVcsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDLElBQUk7YUFDM0QsQ0FBQyxDQUFDO1lBRUgsR0FBRyxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7UUFDN0QsQ0FBQztRQUVELEdBQUcsQ0FBQyxHQUFHLENBQUMsaUJBQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3hCLEdBQUcsQ0FBQyxHQUFHLENBQUMsaUJBQU8sQ0FBQyxVQUFVLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRWhELHVFQUF1RTtRQUN2RSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsRUFBRTtZQUN6QixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFFN0IsR0FBRyxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFO2dCQUNwQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUyxDQUFDO2dCQUN4QyxNQUFNLEtBQUssR0FBRyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQ2hELElBQUksQ0FBQyxNQUFNLENBQ1QsS0FBSyxFQUNMLElBQUksR0FBRyxDQUFDLFVBQVUsS0FBSyxHQUFHLENBQUMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxPQUFPLElBQUksR0FBRyxDQUFDLElBQUksTUFBTSxRQUFRLElBQUksQ0FDL0UsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1lBRUgsSUFBSSxFQUFFLENBQUM7UUFDVCxDQUFDLENBQUMsQ0FBQztRQUVILEdBQUcsQ0FBQyxHQUFHLENBQ0wsR0FBRyxNQUFNLGtCQUFrQixFQUMzQixJQUFBLG1DQUFvQixFQUFDO1lBQ25CLFFBQVEsRUFBRSxhQUFhO1NBQ3hCLENBQUMsQ0FDSCxDQUFDO1FBQ0YsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE1BQU0sY0FBYyxFQUFFLElBQUEsdUJBQVksRUFBQyxFQUFFLFFBQVEsRUFBRSxhQUFhLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFNUUsK0VBQStFO1FBQy9FLE1BQU0sY0FBYyxHQUFHLElBQUksR0FBRyxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQztRQUVqRCxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsdUZBQXVGO1lBQ3ZGLDBGQUEwRjtZQUMxRix3RUFBd0U7WUFDeEUsR0FBRyxDQUFDLEdBQUcsQ0FDTCx3Q0FBd0MsY0FBYyxDQUFDLFFBQVEsRUFBRSxFQUNqRSxJQUFBLDZCQUFlLEVBQUM7Z0JBQ2QsUUFBUSxFQUFFLGNBQWMsQ0FBQyxJQUFJO2dCQUM3QixxQkFBcUIsRUFBRSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUM7Z0JBQzdDLGdCQUFnQixFQUFFLGVBQWU7YUFDbEMsQ0FBQyxDQUNILENBQUM7WUFDRixHQUFHLENBQUMsR0FBRyxDQUFDLDBDQUEwQyxNQUFNLEVBQUUsRUFBRSxJQUFBLDZCQUFlLEVBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztRQUM5RixDQUFDO2FBQU0sQ0FBQztZQUNOLEdBQUcsQ0FBQyxHQUFHLENBQ0wsSUFBQSxpQ0FBcUIsRUFBQztnQkFDcEIsYUFBYTtnQkFDYixpQkFBaUIsRUFBRSxjQUFjO2dCQUNqQyxlQUFlO2FBQ2hCLENBQUMsQ0FDSCxDQUFDO1FBQ0osQ0FBQztRQUVELEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBQSxrQ0FBYyxFQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWxDLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxHQUFHLENBQ2pDLHdDQUF3QyxjQUFjLENBQUMsUUFBUSxFQUFFLEVBQ2pFLGdCQUFnQixDQUNqQixDQUFDLElBQUksQ0FBQztRQUVQLEdBQUcsQ0FBQyxJQUFJLENBQ04sR0FBRyxNQUFNLE1BQU0sRUFDZixJQUFBLGlDQUFpQixFQUFDO1lBQ2hCLFFBQVEsRUFBRSxhQUFhO1lBQ3ZCLGNBQWMsRUFBRSxDQUFDLFVBQVUsQ0FBQztZQUM1QixtQkFBbUI7U0FDcEIsQ0FBQyxFQUNGLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFO1lBQ1gsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUU7Z0JBQzVDLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxJQUFJLEVBQUUsTUFBTSxJQUFJLFNBQVMsQ0FBQztnQkFDaEQsTUFBTSxHQUFHLEdBQUcsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFDdEUsaUJBQWlCLENBQ2YsSUFBSSxDQUFDLE1BQU0sRUFDWCx3QkFBd0IsU0FBUyxNQUFNLEdBQUcsQ0FBQyxPQUFPLElBQUksS0FBSyxFQUFFLEVBQzdELEdBQUcsQ0FDSixDQUFDO2dCQUVGLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7b0JBQ3JCLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO3dCQUNuQixPQUFPLEVBQUUsS0FBSzt3QkFDZCxLQUFLLEVBQUU7NEJBQ0wsSUFBSSxFQUFFLENBQUMsS0FBSzs0QkFDWixPQUFPLEVBQUUsR0FBRyxDQUFDLE9BQU8sSUFBSSx1QkFBdUI7eUJBQ2hEO3dCQUNELEVBQUUsRUFBRSxJQUFJO3FCQUNULENBQUMsQ0FBQztnQkFDTCxDQUFDO3FCQUFNLENBQUM7b0JBQ04sSUFBSSxDQUFDLE1BQU0sQ0FDVCxNQUFNLEVBQ04saUVBQWlFLFNBQVMsR0FBRyxDQUM5RSxDQUFDO2dCQUNKLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FDRixDQUFDO1FBRUYscURBQXFEO1FBQ3JELDBFQUEwRTtRQUMxRSxrRkFBa0Y7UUFDbEYsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQztRQUN4QixHQUFHLENBQUMsR0FBRztRQUNMLDZEQUE2RDtRQUM3RCxDQUFDLEdBQVUsRUFBRSxHQUFvQixFQUFFLEdBQXFCLEVBQUUsS0FBMkIsRUFBRSxFQUFFO1lBQ3ZGLGlCQUFpQixDQUNmLE1BQU0sRUFDTixzQkFBc0IsR0FBRyxDQUFDLE1BQU0sSUFBSSxHQUFHLENBQUMsSUFBSSxLQUFLLEdBQUcsQ0FBQyxPQUFPLEVBQUUsRUFDOUQsR0FBRyxDQUNKLENBQUM7WUFFRixJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNyQixHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQztvQkFDbkIsS0FBSyxFQUFFLHVCQUF1QjtvQkFDOUIsaUJBQWlCLEVBQUUsR0FBRyxDQUFDLE9BQU87aUJBQy9CLENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDLENBQ0YsQ0FBQztRQUVGLElBQUksQ0FBQyxVQUFVLEdBQUcsR0FBRyxDQUFDO1FBRXRCLE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLGVBQWUsQ0FBQyxPQUFhO1FBQ2pDLE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNoRCxNQUFNLFVBQVUsR0FBRyxJQUFBLDBCQUFjLEVBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRWpELE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFO1lBQ3hCLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDO1lBRTNCLElBQUksVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3BCLDBFQUEwRTtnQkFDMUUsb0ZBQW9GO2dCQUNwRixtRkFBbUY7Z0JBQ25GLDZFQUE2RTtnQkFDN0UsTUFBTSxNQUFNLEdBQUcsR0FBVSxDQUFDO2dCQUUxQixxREFBcUQ7Z0JBQ3JELElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7b0JBQzNCLE1BQU0sQ0FBQyxjQUFjLEdBQUc7d0JBQ3RCLEtBQUssRUFBRSxFQUFFO3dCQUNULFVBQVUsRUFBRSxDQUFDO3dCQUNiLE9BQU8sRUFBRSxJQUFJO3dCQUNiLEtBQUssRUFBRSxJQUFJO3dCQUNYLFVBQVUsRUFBRSxJQUFJO3dCQUNoQixPQUFPLEVBQUUsS0FBSztxQkFDZixDQUFDO2dCQUNKLENBQUM7cUJBQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO29CQUN2RCxzREFBc0Q7b0JBQ3RELE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztnQkFDbkMsQ0FBQztnQkFDRCw0RUFBNEU7Z0JBRTVFLG9DQUFvQztnQkFDcEMsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNoQixDQUFDO2lCQUFNLElBQUksSUFBSSxFQUFFLENBQUM7Z0JBQ2hCLHlDQUF5QztnQkFDekMsSUFBSSxFQUFFLENBQUM7WUFDVCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sZ0ZBQWdGO2dCQUNoRixHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxFQUFFLGNBQWMsRUFBRSxrQkFBa0IsRUFBRSxDQUFDLENBQUM7Z0JBQzNELEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDbEQsQ0FBQztRQUNILENBQUMsQ0FBQztJQUNKLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxHQUFHO1FBQ1AsMkZBQTJGO1FBQzNGLCtGQUErRjtRQUMvRiwwQkFBMEI7UUFDMUIsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUM7UUFDNUMsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUM5QyxNQUFNLGFBQWEsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDO1FBRXhELElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksR0FBRyxDQUFDLElBQUksSUFBSSxHQUFHLEtBQUssRUFBRSxDQUFDO1lBQ3hELE1BQU0sSUFBSSxLQUFLLENBQ2IsNEJBQTRCLE9BQU8sNkNBQTZDLENBQ2pGLENBQUM7UUFDSixDQUFDO1FBRUQsbUZBQW1GO1FBQ25GLElBQUksSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ2pDLE1BQU0sSUFBSSxLQUFLLENBQ2IseUZBQXlGO2dCQUN2RiwwRUFBMEUsQ0FDN0UsQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLFNBQVMsR0FBRyxhQUFhLElBQUksb0JBQW9CLElBQUksRUFBRSxDQUFDO1FBQzlELE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFFekUsOEZBQThGO1FBQzlGLGNBQWM7UUFDZCxJQUNFLENBQUMsT0FBTztZQUNSLENBQUMsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUM7WUFDL0MsT0FBTyxDQUFDLElBQUksS0FBSyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsRUFDckMsQ0FBQztZQUNELDBGQUEwRjtZQUMxRiw4Q0FBOEM7WUFDOUMsTUFBTSxLQUFLLEdBQ1QsT0FBTyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssTUFBTTtnQkFDbEMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNO2dCQUNoQixDQUFDLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBRXRELE1BQU0sSUFBSSxLQUFLLENBQ2Isa0NBQWtDLEtBQUssOENBQThDO2dCQUNuRiw4REFBOEQsQ0FDakUsQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFaEQsc0NBQXNDO1FBQ3RDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUV6QyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFO1lBQ2hDLElBQUksQ0FBQyxNQUFNLENBQ1QsTUFBTSxFQUNOLDJDQUEyQyxJQUFJLGlCQUFpQixPQUFPLENBQUMsSUFBSSxFQUFFLENBQy9FLENBQUM7WUFFRixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQ25CLElBQUksQ0FBQyxNQUFNLENBQ1QsTUFBTSxFQUNOLGdDQUFnQyxJQUFJLGlEQUFpRDtvQkFDbkYsa0ZBQWtGLENBQ3JGLENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0Y7QUF2cUJELGtDQXVxQkMifQ==
|
|
@@ -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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
//
|
|
49
|
-
//
|
|
50
|
-
|
|
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,
|
|
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
|
-
//
|
|
49
|
-
//
|
|
50
|
-
|
|
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
|
-
(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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,
|
|
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.
|
|
3
|
+
"version": "1.23.1",
|
|
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.
|
|
20
|
-
"@forestadmin/forestadmin-client": "1.
|
|
19
|
+
"@forestadmin/agent-client": "1.14.2",
|
|
20
|
+
"@forestadmin/forestadmin-client": "1.43.1",
|
|
21
21
|
"@modelcontextprotocol/sdk": "^1.28.0",
|
|
22
22
|
"cors": "^2.8.5",
|
|
23
23
|
"express": "^5.2.1",
|