@apify/actors-mcp-server 0.12.0 → 0.12.1-beta.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/dist/apify_client.js +1 -4
- package/dist/apify_client.js.map +1 -1
- package/dist/const.js +1 -4
- package/dist/const.js.map +1 -1
- package/dist/dev_server.d.ts +19 -0
- package/dist/dev_server.d.ts.map +1 -1
- package/dist/dev_server.js +28 -15
- package/dist/dev_server.js.map +1 -1
- package/dist/errors.js +1 -4
- package/dist/errors.js.map +1 -1
- package/dist/index.js +1 -4
- package/dist/index.js.map +1 -1
- package/dist/index_internals.js +1 -4
- package/dist/index_internals.js.map +1 -1
- package/dist/input.js +1 -4
- package/dist/input.js.map +1 -1
- package/dist/instrument.js +1 -4
- package/dist/instrument.js.map +1 -1
- package/dist/mcp/actors.js +1 -4
- package/dist/mcp/actors.js.map +1 -1
- package/dist/mcp/client.js +1 -4
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/client_context.d.ts +11 -0
- package/dist/mcp/client_context.d.ts.map +1 -0
- package/dist/mcp/client_context.js +24 -0
- package/dist/mcp/client_context.js.map +1 -0
- package/dist/mcp/const.js +1 -4
- package/dist/mcp/const.js.map +1 -1
- package/dist/mcp/proxy.js +1 -4
- package/dist/mcp/proxy.js.map +1 -1
- package/dist/mcp/server.d.ts +11 -2
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +135 -333
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/task_execution.d.ts +2 -0
- package/dist/mcp/task_execution.d.ts.map +1 -1
- package/dist/mcp/task_execution.js +3 -5
- package/dist/mcp/task_execution.js.map +1 -1
- package/dist/mcp/tool_call_engine.d.ts +84 -0
- package/dist/mcp/tool_call_engine.d.ts.map +1 -0
- package/dist/mcp/tool_call_engine.js +301 -0
- package/dist/mcp/tool_call_engine.js.map +1 -0
- package/dist/mcp/tool_call_error_mapper.js +1 -4
- package/dist/mcp/tool_call_error_mapper.js.map +1 -1
- package/dist/mcp/tool_call_telemetry.d.ts +2 -0
- package/dist/mcp/tool_call_telemetry.d.ts.map +1 -1
- package/dist/mcp/tool_call_telemetry.js +8 -13
- package/dist/mcp/tool_call_telemetry.js.map +1 -1
- package/dist/mcp/tool_dispatch.d.ts +4 -0
- package/dist/mcp/tool_dispatch.d.ts.map +1 -1
- package/dist/mcp/tool_dispatch.js +3 -6
- package/dist/mcp/tool_dispatch.js.map +1 -1
- package/dist/mcp/utils.js +1 -4
- package/dist/mcp/utils.js.map +1 -1
- package/dist/payments/const.js +1 -4
- package/dist/payments/const.js.map +1 -1
- package/dist/payments/helpers.js +1 -4
- package/dist/payments/helpers.js.map +1 -1
- package/dist/payments/index.js +1 -4
- package/dist/payments/index.js.map +1 -1
- package/dist/payments/resolve.js +1 -4
- package/dist/payments/resolve.js.map +1 -1
- package/dist/payments/skyfire.js +1 -4
- package/dist/payments/skyfire.js.map +1 -1
- package/dist/payments/types.js +1 -4
- package/dist/payments/types.js.map +1 -1
- package/dist/payments/x402.js +1 -4
- package/dist/payments/x402.js.map +1 -1
- package/dist/prompts/index.js +1 -4
- package/dist/prompts/index.js.map +1 -1
- package/dist/resources/api_resources.js +1 -4
- package/dist/resources/api_resources.js.map +1 -1
- package/dist/resources/resource_service.js +1 -4
- package/dist/resources/resource_service.js.map +1 -1
- package/dist/resources/widgets.js +1 -4
- package/dist/resources/widgets.js.map +1 -1
- package/dist/server_card.js +1 -4
- package/dist/server_card.js.map +1 -1
- package/dist/state.js +1 -4
- package/dist/state.js.map +1 -1
- package/dist/stdio.js +1 -4
- package/dist/stdio.js.map +1 -1
- package/dist/telemetry.js +1 -4
- package/dist/telemetry.js.map +1 -1
- package/dist/tools/actor_input_schema.js +1 -4
- package/dist/tools/actor_input_schema.js.map +1 -1
- package/dist/tools/actor_tool_naming.js +1 -4
- package/dist/tools/actor_tool_naming.js.map +1 -1
- package/dist/tools/actors/actor_definition.js +1 -4
- package/dist/tools/actors/actor_definition.js.map +1 -1
- package/dist/tools/actors/actor_executor.js +1 -4
- package/dist/tools/actors/actor_executor.js.map +1 -1
- package/dist/tools/actors/actor_run_response.js +1 -4
- package/dist/tools/actors/actor_run_response.js.map +1 -1
- package/dist/tools/actors/actor_tools_factory.js +1 -4
- package/dist/tools/actors/actor_tools_factory.js.map +1 -1
- package/dist/tools/actors/add_actor.js +1 -4
- package/dist/tools/actors/add_actor.js.map +1 -1
- package/dist/tools/actors/call_actor.js +1 -4
- package/dist/tools/actors/call_actor.js.map +1 -1
- package/dist/tools/actors/fetch_actor_details.js +1 -4
- package/dist/tools/actors/fetch_actor_details.js.map +1 -1
- package/dist/tools/actors/search_actors.js +1 -4
- package/dist/tools/actors/search_actors.js.map +1 -1
- package/dist/tools/dev/report_problem.js +1 -4
- package/dist/tools/dev/report_problem.js.map +1 -1
- package/dist/tools/docs/fetch_apify_docs.js +1 -4
- package/dist/tools/docs/fetch_apify_docs.js.map +1 -1
- package/dist/tools/docs/search_apify_docs.js +1 -4
- package/dist/tools/docs/search_apify_docs.js.map +1 -1
- package/dist/tools/index.js +1 -4
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/registry.js +1 -4
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/runs/abort_actor_run.js +1 -4
- package/dist/tools/runs/abort_actor_run.js.map +1 -1
- package/dist/tools/runs/get_actor_run.js +1 -4
- package/dist/tools/runs/get_actor_run.js.map +1 -1
- package/dist/tools/runs/get_actor_run_list.js +1 -4
- package/dist/tools/runs/get_actor_run_list.js.map +1 -1
- package/dist/tools/runs/get_actor_run_log.js +1 -4
- package/dist/tools/runs/get_actor_run_log.js.map +1 -1
- package/dist/tools/storage/get_dataset.js +1 -4
- package/dist/tools/storage/get_dataset.js.map +1 -1
- package/dist/tools/storage/get_dataset_items.js +1 -4
- package/dist/tools/storage/get_dataset_items.js.map +1 -1
- package/dist/tools/storage/get_dataset_list.js +1 -4
- package/dist/tools/storage/get_dataset_list.js.map +1 -1
- package/dist/tools/storage/get_dataset_schema.js +1 -4
- package/dist/tools/storage/get_dataset_schema.js.map +1 -1
- package/dist/tools/storage/get_key_value_store.js +1 -4
- package/dist/tools/storage/get_key_value_store.js.map +1 -1
- package/dist/tools/storage/get_key_value_store_keys.js +1 -4
- package/dist/tools/storage/get_key_value_store_keys.js.map +1 -1
- package/dist/tools/storage/get_key_value_store_list.js +1 -4
- package/dist/tools/storage/get_key_value_store_list.js.map +1 -1
- package/dist/tools/storage/get_key_value_store_record.js +1 -4
- package/dist/tools/storage/get_key_value_store_record.js.map +1 -1
- package/dist/tools/storage/storage_helpers.js +1 -4
- package/dist/tools/storage/storage_helpers.js.map +1 -1
- package/dist/tools/structured_output_schemas.js +1 -4
- package/dist/tools/structured_output_schemas.js.map +1 -1
- package/dist/tools/widgets/call_actor_widget.js +1 -4
- package/dist/tools/widgets/call_actor_widget.js.map +1 -1
- package/dist/tools/widgets/fetch_actor_details_widget.js +1 -4
- package/dist/tools/widgets/fetch_actor_details_widget.js.map +1 -1
- package/dist/tools/widgets/get_actor_run_widget.js +1 -4
- package/dist/tools/widgets/get_actor_run_widget.js.map +1 -1
- package/dist/tools/widgets/search_actors_widget.js +1 -4
- package/dist/tools/widgets/search_actors_widget.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.js +1 -4
- package/dist/types.js.map +1 -1
- package/dist/utils/actor.js +1 -4
- package/dist/utils/actor.js.map +1 -1
- package/dist/utils/actor_card.js +1 -4
- package/dist/utils/actor_card.js.map +1 -1
- package/dist/utils/actor_details.js +1 -4
- package/dist/utils/actor_details.js.map +1 -1
- package/dist/utils/actor_search.js +1 -4
- package/dist/utils/actor_search.js.map +1 -1
- package/dist/utils/ajv.js +1 -4
- package/dist/utils/ajv.js.map +1 -1
- package/dist/utils/apify_docs.js +1 -4
- package/dist/utils/apify_docs.js.map +1 -1
- package/dist/utils/apify_errors.js +1 -4
- package/dist/utils/apify_errors.js.map +1 -1
- package/dist/utils/apify_properties.js +1 -4
- package/dist/utils/apify_properties.js.map +1 -1
- package/dist/utils/auth.js +1 -4
- package/dist/utils/auth.js.map +1 -1
- package/dist/utils/console_link.js +1 -4
- package/dist/utils/console_link.js.map +1 -1
- package/dist/utils/encode_text.js +1 -4
- package/dist/utils/encode_text.js.map +1 -1
- package/dist/utils/generic.js +1 -4
- package/dist/utils/generic.js.map +1 -1
- package/dist/utils/logging.js +1 -4
- package/dist/utils/logging.js.map +1 -1
- package/dist/utils/mcp.js +1 -4
- package/dist/utils/mcp.js.map +1 -1
- package/dist/utils/mcp_clients.d.ts +3 -3
- package/dist/utils/mcp_clients.d.ts.map +1 -1
- package/dist/utils/mcp_clients.js +7 -10
- package/dist/utils/mcp_clients.js.map +1 -1
- package/dist/utils/payment_errors.js +1 -4
- package/dist/utils/payment_errors.js.map +1 -1
- package/dist/utils/pricing_info.js +1 -4
- package/dist/utils/pricing_info.js.map +1 -1
- package/dist/utils/progress.js +1 -4
- package/dist/utils/progress.js.map +1 -1
- package/dist/utils/schema_generation.js +1 -4
- package/dist/utils/schema_generation.js.map +1 -1
- package/dist/utils/server-instructions/index.js +1 -4
- package/dist/utils/server-instructions/index.js.map +1 -1
- package/dist/utils/server_mode.js +1 -4
- package/dist/utils/server_mode.js.map +1 -1
- package/dist/utils/tool_categories_helpers.js +1 -4
- package/dist/utils/tool_categories_helpers.js.map +1 -1
- package/dist/utils/tool_status.js +1 -4
- package/dist/utils/tool_status.js.map +1 -1
- package/dist/utils/tools.js +1 -4
- package/dist/utils/tools.js.map +1 -1
- package/dist/utils/tools_loader.js +1 -4
- package/dist/utils/tools_loader.js.map +1 -1
- package/dist/utils/ttl_lru.js +1 -4
- package/dist/utils/ttl_lru.js.map +1 -1
- package/dist/utils/userid_cache.js +1 -4
- package/dist/utils/userid_cache.js.map +1 -1
- package/dist/utils/version.js +1 -4
- package/dist/utils/version.js.map +1 -1
- package/dist/web/dist/actor-run-widget.js +0 -2
- package/dist/web/dist/search-actors-widget.js +0 -2
- package/manifest.json +1 -1
- package/package.json +1 -1
- package/server.json +1 -1
package/dist/mcp/server.js
CHANGED
|
@@ -1,84 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Model Context Protocol (MCP) server for Apify Actors
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="b2bdac72-d12f-5751-9e08-72a36e12d99e")}catch(e){}}();
|
|
6
4
|
import { randomUUID } from 'node:crypto';
|
|
7
|
-
// The ext-apps package exposes `./server` via conditional exports only (no `./server/index.js`
|
|
8
|
-
// wildcard), so we can't satisfy the `import/extensions` rule on this subpath.
|
|
9
|
-
// eslint-disable-next-line import/extensions
|
|
10
|
-
import { getUiCapability, RESOURCE_MIME_TYPE } from '@modelcontextprotocol/ext-apps/server';
|
|
11
5
|
import { InMemoryTaskStore } from '@modelcontextprotocol/sdk/experimental/tasks/stores/in-memory.js';
|
|
12
6
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
13
7
|
import { CallToolRequestSchema, CancelTaskRequestSchema, ErrorCode, GetPromptRequestSchema, GetTaskPayloadRequestSchema, GetTaskRequestSchema, InitializeRequestSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListResourceTemplatesRequestSchema, ListTasksRequestSchema, ListToolsRequestSchema, McpError, ReadResourceRequestSchema, RELATED_TASK_META_KEY, SetLevelRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
14
|
-
import dedent from 'dedent';
|
|
15
8
|
import log from '@apify/log';
|
|
16
9
|
import { parseBooleanOrNull } from '@apify/utilities';
|
|
17
10
|
import { ApifyClient } from '../apify_client.js';
|
|
18
|
-
import {
|
|
19
|
-
import { prepareToolCallContext } from '../payments/helpers.js';
|
|
11
|
+
import { DEFAULT_TELEMETRY_ENABLED, DEFAULT_TELEMETRY_ENV, FAILURE_CATEGORY, HELPER_TOOLS, TOOL_STATUS, } from '../const.js';
|
|
20
12
|
import { prompts } from '../prompts/index.js';
|
|
21
13
|
import { createResourceService } from '../resources/resource_service.js';
|
|
22
14
|
import { resolveAvailableWidgets } from '../resources/widgets.js';
|
|
23
15
|
import { getServerInfo } from '../server_card.js';
|
|
24
16
|
import { getTelemetryEnv } from '../telemetry.js';
|
|
25
|
-
import { decodeDotPropertyNames } from '../tools/actor_input_schema.js';
|
|
26
|
-
import { legacyToolNameToNew } from '../tools/actor_tool_naming.js';
|
|
27
|
-
import { checkPaymentProviderStandbyConflict } from '../tools/actors/call_actor.js';
|
|
28
17
|
import { withReportProblemNudge } from '../tools/dev/report_problem.js';
|
|
29
18
|
import { getActorsAsTools } from '../tools/index.js';
|
|
30
19
|
import { SERVER_MODE, TOOL_TYPE } from '../types.js';
|
|
31
|
-
import { isMcpClientFaultMessage,
|
|
32
|
-
import { respondOk } from '../utils/mcp.js';
|
|
20
|
+
import { isMcpClientFaultMessage, sanitizeMezmoMessage } from '../utils/logging.js';
|
|
33
21
|
import { getRequestOriginForClient, isReportProblemBlockedForClient } from '../utils/mcp_clients.js';
|
|
34
|
-
import { createProgressTracker } from '../utils/progress.js';
|
|
35
22
|
import { getServerInstructions } from '../utils/server-instructions/index.js';
|
|
36
23
|
import { parseServerMode, resolveServerMode } from '../utils/server_mode.js';
|
|
37
|
-
import {
|
|
38
|
-
import { buildActorFields, extractActorId, extractActorName, getToolFullName, getToolPublicFieldOnly, } from '../utils/tools.js';
|
|
24
|
+
import { buildActorFields, getToolFullName, getToolPublicFieldOnly } from '../utils/tools.js';
|
|
39
25
|
import { getActors, getToolsForServerMode, toolNamesToInput } from '../utils/tools_loader.js';
|
|
26
|
+
import { buildMcpClientContext, isUiSupportedByClient } from './client_context.js';
|
|
40
27
|
import { LOG_LEVEL_MAP } from './const.js';
|
|
41
28
|
import { emitTaskStatusNotification, executeToolAndUpdateTask } from './task_execution.js';
|
|
42
|
-
import {
|
|
29
|
+
import { buildPreflightFailureOutcome, classifyToolCallError, executeSyncToolCall, prepareToolCall, } from './tool_call_engine.js';
|
|
43
30
|
import { logToolCallAndTelemetry, prepareTelemetryData } from './tool_call_telemetry.js';
|
|
44
|
-
import { dispatchToolCall } from './tool_dispatch.js';
|
|
45
31
|
import { parseInputParamsFromUrl, storeTaskResultOrSkipIfExpired } from './utils.js';
|
|
46
|
-
/**
|
|
47
|
-
* Returns true when the initialize request advertises the MCP Apps UI extension
|
|
48
|
-
* with the widget MIME type. Used to resolve `'auto'` server mode.
|
|
49
|
-
*
|
|
50
|
-
* Uses {@link getUiCapability} from `@modelcontextprotocol/ext-apps/server` to
|
|
51
|
-
* read the `io.modelcontextprotocol/ui` extension from client capabilities — the
|
|
52
|
-
* canonical way per the MCP Apps spec.
|
|
53
|
-
*/
|
|
54
|
-
function isUiSupportedByClient(request) {
|
|
55
|
-
var _a, _b, _c;
|
|
56
|
-
const uiCap = getUiCapability((_a = request === null || request === void 0 ? void 0 : request.params) === null || _a === void 0 ? void 0 : _a.capabilities);
|
|
57
|
-
return (_c = (_b = uiCap === null || uiCap === void 0 ? void 0 : uiCap.mimeTypes) === null || _b === void 0 ? void 0 : _b.includes(RESOURCE_MIME_TYPE)) !== null && _c !== void 0 ? _c : false;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Shared diagnostics for a pre-flight failure (standby-provider conflict or missing/invalid payment
|
|
61
|
-
* signature) — a call outcome already known before any Actor runs. Standby rejection wins over the
|
|
62
|
-
* generic payment-required failure so the agent gets the precise reason instead of a generic 402.
|
|
63
|
-
* Pure: callers own their own post-handling (return the result directly, or store + notify + synthesize
|
|
64
|
-
* a terminal task) — call this only once `standbyRejection ?? paymentRequiredResult` is already truthy.
|
|
65
|
-
*/
|
|
66
|
-
function buildPreflightFailureOutcome(standbyRejection, paymentRequiredResult, actorName, actorId) {
|
|
67
|
-
return {
|
|
68
|
-
toolStatus: TOOL_STATUS.SOFT_FAIL,
|
|
69
|
-
callDiagnostics: {
|
|
70
|
-
failure_category: FAILURE_CATEGORY.INVALID_INPUT,
|
|
71
|
-
...(standbyRejection ? {} : { failure_http_status: 402 }),
|
|
72
|
-
...buildActorFields(actorName, actorId),
|
|
73
|
-
},
|
|
74
|
-
result: (standbyRejection !== null && standbyRejection !== void 0 ? standbyRejection : paymentRequiredResult),
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
32
|
/**
|
|
78
33
|
* Create Apify MCP server
|
|
79
34
|
*/
|
|
80
35
|
export class ActorsMcpServer {
|
|
81
36
|
constructor(options = {}) {
|
|
37
|
+
var _a;
|
|
82
38
|
Object.defineProperty(this, "server", {
|
|
83
39
|
enumerable: true,
|
|
84
40
|
configurable: true,
|
|
@@ -127,6 +83,12 @@ export class ActorsMcpServer {
|
|
|
127
83
|
writable: true,
|
|
128
84
|
value: void 0
|
|
129
85
|
});
|
|
86
|
+
Object.defineProperty(this, "clientContext", {
|
|
87
|
+
enumerable: true,
|
|
88
|
+
configurable: true,
|
|
89
|
+
writable: true,
|
|
90
|
+
value: void 0
|
|
91
|
+
});
|
|
130
92
|
/**
|
|
131
93
|
* Resolved server mode. Preliminary value at construction (`'auto'` → `DEFAULT`).
|
|
132
94
|
* Finalized inside the `initialize` request handler (see constructor) once the
|
|
@@ -200,6 +162,7 @@ export class ActorsMcpServer {
|
|
|
200
162
|
value: false
|
|
201
163
|
});
|
|
202
164
|
this.options = options;
|
|
165
|
+
this.clientContext = buildMcpClientContext((_a = options.initializeRequestData) === null || _a === void 0 ? void 0 : _a.params);
|
|
203
166
|
// for stdio use in memory task store if not provided, otherwise use provided task store
|
|
204
167
|
if (this.options.transportType === 'stdio' && !this.options.taskStore) {
|
|
205
168
|
this.taskStore = new InMemoryTaskStore();
|
|
@@ -303,7 +266,9 @@ export class ActorsMcpServer {
|
|
|
303
266
|
const sdkInitHandler = this.server._oninitialize.bind(this.server);
|
|
304
267
|
this.server.setRequestHandler(InitializeRequestSchema, async (request) => {
|
|
305
268
|
var _a;
|
|
306
|
-
this.
|
|
269
|
+
this.clientContext = buildMcpClientContext(request.params);
|
|
270
|
+
this.options.initializeRequestData = request;
|
|
271
|
+
this.clientSupportsUi = isUiSupportedByClient(this.clientContext);
|
|
307
272
|
if (this.serverModeOption === 'auto') {
|
|
308
273
|
const resolved = resolveServerMode('auto', this.clientSupportsUi);
|
|
309
274
|
if (resolved !== this.serverMode) {
|
|
@@ -311,9 +276,6 @@ export class ActorsMcpServer {
|
|
|
311
276
|
}
|
|
312
277
|
this.serverModeResolved = true;
|
|
313
278
|
}
|
|
314
|
-
// Setting this makes `clientKnown` true, so the queued compose below (and any later
|
|
315
|
-
// load) resolves the tool set for this client and applies the per-client blocklist.
|
|
316
|
-
this.options.initializeRequestData = request;
|
|
317
279
|
log.info('Resolved server mode for client capabilities', {
|
|
318
280
|
serverMode: this.serverMode,
|
|
319
281
|
serverModeOption: this.serverModeOption,
|
|
@@ -334,7 +296,7 @@ export class ActorsMcpServer {
|
|
|
334
296
|
* recovery path). Only client-gated tools wait for this so the per-client blocklist can be
|
|
335
297
|
* applied; client-agnostic tools compose regardless. */
|
|
336
298
|
get clientKnown() {
|
|
337
|
-
return this.
|
|
299
|
+
return this.clientContext != null;
|
|
338
300
|
}
|
|
339
301
|
/**
|
|
340
302
|
* Compose the tool list for the current connection: resolve mode-specific tools, then drop
|
|
@@ -362,9 +324,7 @@ export class ActorsMcpServer {
|
|
|
362
324
|
* survive a load that never sees an initialize.
|
|
363
325
|
*/
|
|
364
326
|
isReportProblemServable() {
|
|
365
|
-
return
|
|
366
|
-
this.clientKnown &&
|
|
367
|
-
!isReportProblemBlockedForClient(this.options.initializeRequestData));
|
|
327
|
+
return this.telemetryEnabled && this.clientKnown && !isReportProblemBlockedForClient(this.clientContext);
|
|
368
328
|
}
|
|
369
329
|
composePendingToolsForClient() {
|
|
370
330
|
if (this.pendingToolsUntilClientKnown.length === 0)
|
|
@@ -468,7 +428,6 @@ export class ActorsMcpServer {
|
|
|
468
428
|
/**
|
|
469
429
|
* Loads missing toolNames from a provided list of tool names.
|
|
470
430
|
* Skips toolNames that are already loaded and loads only the missing ones.
|
|
471
|
-
* @param toolNames - Array of tool names to ensure are loaded
|
|
472
431
|
*/
|
|
473
432
|
async loadToolsByName(toolNames, apifyClient) {
|
|
474
433
|
const loadedTools = new Set(this.listAllToolNames());
|
|
@@ -637,12 +596,12 @@ export class ActorsMcpServer {
|
|
|
637
596
|
* Token-scoped client for resources/read (the API proxy needs auth). Deliberately token-only:
|
|
638
597
|
* unlike the CallTool path it does NOT forward provider/payment headers, so a payment-only
|
|
639
598
|
* session (x402/Skyfire, no Apify token) has no client and every read fails by design.
|
|
640
|
-
* Still carries the request-origin tag
|
|
599
|
+
* Still carries the request-origin tag from the client context captured by this point.
|
|
641
600
|
*/
|
|
642
601
|
resolveApifyClient(params) {
|
|
643
602
|
const token = this.resolveApifyToken(params._meta);
|
|
644
603
|
return token
|
|
645
|
-
? new ApifyClient({ token, requestOrigin: getRequestOriginForClient(this.
|
|
604
|
+
? new ApifyClient({ token, requestOrigin: getRequestOriginForClient(this.clientContext) })
|
|
646
605
|
: undefined;
|
|
647
606
|
}
|
|
648
607
|
setupResourceHandlers() {
|
|
@@ -661,41 +620,43 @@ export class ActorsMcpServer {
|
|
|
661
620
|
return await resourceService.listResourceTemplates();
|
|
662
621
|
});
|
|
663
622
|
}
|
|
623
|
+
/**
|
|
624
|
+
* Returns the prompts/list result.
|
|
625
|
+
*/
|
|
626
|
+
listPrompts() {
|
|
627
|
+
return { prompts };
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Builds the prompts/get result: find → not-found → validate → render.
|
|
631
|
+
* Throws {@link McpError} for an unknown prompt name or invalid arguments (v1 behavior).
|
|
632
|
+
*/
|
|
633
|
+
getPrompt(name, args) {
|
|
634
|
+
const prompt = prompts.find((p) => p.name === name);
|
|
635
|
+
if (!prompt) {
|
|
636
|
+
throw new McpError(ErrorCode.InvalidParams, `Prompt ${name} not found. Available prompts: ${prompts.map((p) => p.name).join(', ')}`);
|
|
637
|
+
}
|
|
638
|
+
if (!prompt.ajvValidate(args)) {
|
|
639
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid arguments for prompt ${name}: args: ${JSON.stringify(args)} error: ${JSON.stringify(prompt.ajvValidate.errors)}`);
|
|
640
|
+
}
|
|
641
|
+
return {
|
|
642
|
+
description: prompt.description,
|
|
643
|
+
messages: [
|
|
644
|
+
{
|
|
645
|
+
role: 'user',
|
|
646
|
+
content: {
|
|
647
|
+
type: 'text',
|
|
648
|
+
text: prompt.render(args || {}),
|
|
649
|
+
},
|
|
650
|
+
},
|
|
651
|
+
],
|
|
652
|
+
};
|
|
653
|
+
}
|
|
664
654
|
/**
|
|
665
655
|
* Sets up MCP request handlers for prompts.
|
|
666
656
|
*/
|
|
667
657
|
setupPromptHandlers() {
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
*/
|
|
671
|
-
this.server.setRequestHandler(ListPromptsRequestSchema, () => {
|
|
672
|
-
return { prompts };
|
|
673
|
-
});
|
|
674
|
-
/**
|
|
675
|
-
* Handles the prompts/get request.
|
|
676
|
-
*/
|
|
677
|
-
this.server.setRequestHandler(GetPromptRequestSchema, (request) => {
|
|
678
|
-
const { name, arguments: args } = request.params;
|
|
679
|
-
const prompt = prompts.find((p) => p.name === name);
|
|
680
|
-
if (!prompt) {
|
|
681
|
-
throw new McpError(ErrorCode.InvalidParams, `Prompt ${name} not found. Available prompts: ${prompts.map((p) => p.name).join(', ')}`);
|
|
682
|
-
}
|
|
683
|
-
if (!prompt.ajvValidate(args)) {
|
|
684
|
-
throw new McpError(ErrorCode.InvalidParams, `Invalid arguments for prompt ${name}: args: ${JSON.stringify(args)} error: ${JSON.stringify(prompt.ajvValidate.errors)}`);
|
|
685
|
-
}
|
|
686
|
-
return {
|
|
687
|
-
description: prompt.description,
|
|
688
|
-
messages: [
|
|
689
|
-
{
|
|
690
|
-
role: 'user',
|
|
691
|
-
content: {
|
|
692
|
-
type: 'text',
|
|
693
|
-
text: prompt.render(args || {}),
|
|
694
|
-
},
|
|
695
|
-
},
|
|
696
|
-
],
|
|
697
|
-
};
|
|
698
|
-
});
|
|
658
|
+
this.server.setRequestHandler(ListPromptsRequestSchema, () => this.listPrompts());
|
|
659
|
+
this.server.setRequestHandler(GetPromptRequestSchema, (request) => this.getPrompt(request.params.name, request.params.arguments));
|
|
699
660
|
}
|
|
700
661
|
/**
|
|
701
662
|
* Fetches a task by ID, softFail-logging and throwing a client-facing McpError if it doesn't exist.
|
|
@@ -794,8 +755,9 @@ export class ActorsMcpServer {
|
|
|
794
755
|
* `sendNotification`. Throws {@link McpError} to mirror the MCP SDK's McpServer error codes.
|
|
795
756
|
*/
|
|
796
757
|
this.server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
|
|
797
|
-
var _a, _b, _c
|
|
758
|
+
var _a, _b, _c;
|
|
798
759
|
const params = request.params;
|
|
760
|
+
// Keep telemetry on the decoded arguments.
|
|
799
761
|
// eslint-disable-next-line prefer-const
|
|
800
762
|
let { name, arguments: args, _meta: meta } = params;
|
|
801
763
|
const progressToken = meta === null || meta === void 0 ? void 0 : meta.progressToken;
|
|
@@ -816,157 +778,69 @@ export class ActorsMcpServer {
|
|
|
816
778
|
// this handler's `finally` — so its `Tool call completed` log line keeps the taskId the
|
|
817
779
|
// async path logs via finishTaskTracking.
|
|
818
780
|
let preflightTaskId;
|
|
819
|
-
//
|
|
781
|
+
// The nudge must be included in the measured result.
|
|
820
782
|
let toolResult = null;
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
result: r,
|
|
827
|
-
tools: this.tools,
|
|
828
|
-
failingToolName: resolvedToolName,
|
|
829
|
-
failureCategory: callDiagnostics.failure_category,
|
|
830
|
-
failureHttpStatus: callDiagnostics.failure_http_status,
|
|
831
|
-
});
|
|
832
|
-
toolResult = augmented;
|
|
833
|
-
return augmented;
|
|
834
|
-
};
|
|
835
|
-
const failInvalidParams = async (message, details, logFields) => {
|
|
836
|
-
toolStatus = TOOL_STATUS.SOFT_FAIL;
|
|
837
|
-
callDiagnostics = details;
|
|
838
|
-
log.softFail(message, {
|
|
839
|
-
mcpSessionId,
|
|
840
|
-
failureCategory: details.failure_category,
|
|
841
|
-
actorName: details.actor_name,
|
|
842
|
-
validationKeyword: details.validation_keyword,
|
|
843
|
-
validationPath: details.validation_path,
|
|
844
|
-
validationMissingProperty: details.validation_missing_property,
|
|
845
|
-
validationAdditionalProperty: details.validation_additional_property,
|
|
846
|
-
...logFields,
|
|
847
|
-
});
|
|
848
|
-
await this.server.sendLoggingMessage({ level: 'error', data: message });
|
|
849
|
-
throw new McpError(ErrorCode.InvalidParams, message);
|
|
850
|
-
};
|
|
851
|
-
// Initialize telemetry with raw tool name — updated below once the tool is resolved.
|
|
852
|
-
// This ensures telemetry is available even for early failures (missing token, tool not found).
|
|
783
|
+
// Keep actor context available to the outer catch.
|
|
784
|
+
let actorName;
|
|
785
|
+
let actorId;
|
|
786
|
+
const { clientContext } = this;
|
|
787
|
+
// Start with the raw name so early failures still have telemetry.
|
|
853
788
|
const { telemetryData, userId } = await prepareTelemetryData({
|
|
854
789
|
toolName: name,
|
|
855
790
|
mcpSessionId,
|
|
856
791
|
apifyToken,
|
|
857
792
|
apifyMcpServer: this,
|
|
793
|
+
clientContext,
|
|
858
794
|
});
|
|
859
|
-
// actorName/actorId are declared here so they're available in the catch block for telemetry.
|
|
860
|
-
// Set after tool resolution (inside the try block).
|
|
861
|
-
let actorName;
|
|
862
|
-
let actorId;
|
|
863
795
|
try {
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
!((_a = this.options.paymentProvider) === null || _a === void 0 ? void 0 : _a.allowsUnauthenticated) &&
|
|
867
|
-
!this.options.allowUnauthMode) {
|
|
868
|
-
await failInvalidParams(dedent `
|
|
869
|
-
Apify API token is required but was not provided.
|
|
870
|
-
Please set the APIFY_TOKEN environment variable or pass it as a parameter in the request header as Authorization Bearer <token>.
|
|
871
|
-
You can get your Apify token from https://console.apify.com/account/integrations.
|
|
872
|
-
`, {
|
|
873
|
-
failure_category: FAILURE_CATEGORY.AUTH,
|
|
874
|
-
});
|
|
875
|
-
}
|
|
876
|
-
// TODO - if connection is /mcp client will not receive notification on tool change
|
|
877
|
-
// Find tool by name, actor full name, or legacy tool name (e.g. apify-slash-rag-web-browser → apify--rag-web-browser)
|
|
878
|
-
const newName = (_b = legacyToolNameToNew(name)) !== null && _b !== void 0 ? _b : name;
|
|
879
|
-
const toolEntry = Array.from(this.tools.values()).find((t) => t.name === newName || getToolFullName(t) === newName);
|
|
880
|
-
if (!toolEntry) {
|
|
881
|
-
const availableTools = this.listToolNames();
|
|
882
|
-
await failInvalidParams(dedent `
|
|
883
|
-
Tool "${name}" was not found.
|
|
884
|
-
Available tools: ${availableTools.length > 0 ? availableTools.join(', ') : 'none'}.
|
|
885
|
-
Please verify the tool name is correct. You can list all available tools using the tools/list request.
|
|
886
|
-
`, {
|
|
887
|
-
failure_category: FAILURE_CATEGORY.INVALID_INPUT,
|
|
888
|
-
});
|
|
889
|
-
}
|
|
890
|
-
const tool = toolEntry;
|
|
891
|
-
resolvedToolName = getToolFullName(tool);
|
|
892
|
-
// Update telemetry tool name now that we resolved the tool (uses actorFullName for actor tools).
|
|
893
|
-
if (telemetryData) {
|
|
894
|
-
telemetryData.tool_name = resolvedToolName;
|
|
895
|
-
}
|
|
896
|
-
// Extract actor name/id for telemetry — available even when validation fails later.
|
|
897
|
-
actorName = extractActorName(tool, args);
|
|
898
|
-
actorId = extractActorId(tool);
|
|
899
|
-
// Always populate actor fields so they're tracked on both success and failure paths.
|
|
900
|
-
callDiagnostics = { ...callDiagnostics, ...buildActorFields(actorName, actorId) };
|
|
901
|
-
if (!args) {
|
|
902
|
-
await failInvalidParams(dedent `
|
|
903
|
-
Missing arguments for tool "${name}".
|
|
904
|
-
Please provide the required arguments for this tool. Check the tool's input schema using ${HELPER_TOOLS.ACTOR_GET_DETAILS} tool to see what parameters are required.
|
|
905
|
-
`, {
|
|
906
|
-
failure_category: FAILURE_CATEGORY.INVALID_INPUT,
|
|
907
|
-
...buildActorFields(actorName, actorId),
|
|
908
|
-
});
|
|
909
|
-
}
|
|
910
|
-
// Decode dot property names in arguments before validation,
|
|
911
|
-
// since validation expects the original, non-encoded property names.
|
|
912
|
-
args = decodeDotPropertyNames(args);
|
|
913
|
-
// Centralize all payment processing: validate, strip payment fields, create client.
|
|
914
|
-
// Must run before AJV validation so toolArgsWithoutPayment doesn't contain provider-specific fields.
|
|
915
|
-
const { toolArgsWithoutPayment: toolArgs, toolArgsRedacted: logSafeArgs, apifyClient, paymentRequiredResult, } = prepareToolCallContext({
|
|
916
|
-
provider: this.options.paymentProvider,
|
|
917
|
-
tool,
|
|
918
|
-
args: args,
|
|
796
|
+
const prepared = await prepareToolCall({
|
|
797
|
+
apifyMcpServer: this,
|
|
919
798
|
apifyToken,
|
|
799
|
+
name,
|
|
800
|
+
args,
|
|
920
801
|
meta,
|
|
921
|
-
requestHeaders: (
|
|
922
|
-
|
|
802
|
+
requestHeaders: (_a = extra.requestInfo) === null || _a === void 0 ? void 0 : _a.headers,
|
|
803
|
+
isTaskRequest: Boolean(request.params.task),
|
|
804
|
+
mcpSessionId,
|
|
805
|
+
telemetryData,
|
|
806
|
+
clientContext,
|
|
807
|
+
extra,
|
|
923
808
|
});
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
Invalid arguments for tool "${tool.name}".
|
|
933
|
-
Validation errors: ${errorMessages}.
|
|
934
|
-
Please check the tool's input schema using ${HELPER_TOOLS.ACTOR_GET_DETAILS} tool and ensure all required parameters are provided with correct types and values.
|
|
935
|
-
`, {
|
|
936
|
-
failure_category: FAILURE_CATEGORY.INVALID_INPUT,
|
|
937
|
-
...ajvErrorDetails,
|
|
938
|
-
...buildActorFields(actorName, actorId),
|
|
939
|
-
});
|
|
809
|
+
if ('result' in prepared) {
|
|
810
|
+
// The engine already classified this post-resolution failure.
|
|
811
|
+
resolvedToolName = prepared.resolvedToolName;
|
|
812
|
+
args = prepared.decodedArgs;
|
|
813
|
+
toolStatus = prepared.toolStatus;
|
|
814
|
+
callDiagnostics = prepared.callDiagnostics;
|
|
815
|
+
toolResult = prepared.result;
|
|
816
|
+
return prepared.result;
|
|
940
817
|
}
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
818
|
+
if ('message' in prepared) {
|
|
819
|
+
// Reproduce v1's invalid-params tail and preserve telemetry fields.
|
|
820
|
+
resolvedToolName = (_b = prepared.resolvedToolName) !== null && _b !== void 0 ? _b : resolvedToolName;
|
|
821
|
+
if (prepared.decodedArgs)
|
|
822
|
+
args = prepared.decodedArgs;
|
|
823
|
+
toolStatus = prepared.toolStatus;
|
|
824
|
+
callDiagnostics = prepared.callDiagnostics;
|
|
825
|
+
log.softFail(prepared.message, {
|
|
826
|
+
mcpSessionId,
|
|
827
|
+
failureCategory: prepared.callDiagnostics.failure_category,
|
|
828
|
+
actorName: prepared.callDiagnostics.actor_name,
|
|
829
|
+
validationKeyword: prepared.callDiagnostics.validation_keyword,
|
|
830
|
+
validationPath: prepared.callDiagnostics.validation_path,
|
|
831
|
+
validationMissingProperty: prepared.callDiagnostics.validation_missing_property,
|
|
832
|
+
validationAdditionalProperty: prepared.callDiagnostics.validation_additional_property,
|
|
833
|
+
...prepared.logFields,
|
|
951
834
|
});
|
|
835
|
+
await this.server.sendLoggingMessage({ level: 'error', data: prepared.message });
|
|
836
|
+
throw new McpError(ErrorCode.InvalidParams, prepared.message);
|
|
952
837
|
}
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
//
|
|
958
|
-
|
|
959
|
-
const { paymentProvider } = this.options;
|
|
960
|
-
const isCallActorTool = tool.name === HELPER_TOOLS.ACTOR_CALL || tool.name === HELPER_TOOLS.ACTOR_CALL_WIDGET;
|
|
961
|
-
const actorArg = toolArgs === null || toolArgs === void 0 ? void 0 : toolArgs.actor;
|
|
962
|
-
const standbyRejection = paymentProvider && isCallActorTool && typeof actorArg === 'string' && actorArg.length > 0
|
|
963
|
-
? await checkPaymentProviderStandbyConflict({
|
|
964
|
-
actorName: actorArg,
|
|
965
|
-
paymentProvider,
|
|
966
|
-
apifyToken,
|
|
967
|
-
mcpSessionId,
|
|
968
|
-
})
|
|
969
|
-
: null;
|
|
838
|
+
const { tool, toolArgs, logSafeArgs, apifyClient, standbyRejection, paymentRequiredResult } = prepared;
|
|
839
|
+
actorName = prepared.actorName;
|
|
840
|
+
actorId = prepared.actorId;
|
|
841
|
+
resolvedToolName = getToolFullName(tool);
|
|
842
|
+
// Telemetry uses the decoded arguments.
|
|
843
|
+
args = prepared.decodedArgs;
|
|
970
844
|
// TODO: we should split this huge method into smaller parts as it is slowly getting out of hand
|
|
971
845
|
// Handle long-running task request
|
|
972
846
|
if (request.params.task) {
|
|
@@ -1000,8 +874,7 @@ export class ActorsMcpServer {
|
|
|
1000
874
|
// CreateTaskResult parse error; surface it as a protocol error instead.
|
|
1001
875
|
// The pre-flight outcome left toolStatus=SOFT_FAIL, but a genuine store
|
|
1002
876
|
// outage is a hard failure — correct it before throwing so the handler
|
|
1003
|
-
// `finally` logs FAILED/INTERNAL_ERROR
|
|
1004
|
-
// these), not the stale pre-flight SOFT_FAIL.
|
|
877
|
+
// `finally` logs FAILED/INTERNAL_ERROR, not the stale pre-flight SOFT_FAIL.
|
|
1005
878
|
toolStatus = TOOL_STATUS.FAILED;
|
|
1006
879
|
callDiagnostics = {
|
|
1007
880
|
failure_category: FAILURE_CATEGORY.INTERNAL_ERROR,
|
|
@@ -1015,7 +888,14 @@ export class ActorsMcpServer {
|
|
|
1015
888
|
setImmediate(() => {
|
|
1016
889
|
void emitTaskStatusNotification(task.taskId, mcpSessionId, this.taskStore, this.server);
|
|
1017
890
|
});
|
|
1018
|
-
|
|
891
|
+
// Measure the nudged result without changing the stored result.
|
|
892
|
+
toolResult = withReportProblemNudge({
|
|
893
|
+
result: outcome.result,
|
|
894
|
+
tools: this.tools,
|
|
895
|
+
failingToolName: resolvedToolName,
|
|
896
|
+
failureCategory: callDiagnostics.failure_category,
|
|
897
|
+
failureHttpStatus: callDiagnostics.failure_http_status,
|
|
898
|
+
});
|
|
1019
899
|
// createTask returned status `working`; synthesize the terminal status instead of
|
|
1020
900
|
// re-fetching — if the task expired before the result store (the one case
|
|
1021
901
|
// storeTaskResultOrSkipIfExpired tolerates), a re-fetch would come back empty and a
|
|
@@ -1027,9 +907,9 @@ export class ActorsMcpServer {
|
|
|
1027
907
|
executeToolAndUpdateTask({
|
|
1028
908
|
taskId: task.taskId,
|
|
1029
909
|
tool,
|
|
1030
|
-
toolArgs
|
|
910
|
+
toolArgs,
|
|
1031
911
|
logSafeArgs,
|
|
1032
|
-
apifyClient
|
|
912
|
+
apifyClient,
|
|
1033
913
|
apifyToken,
|
|
1034
914
|
progressToken,
|
|
1035
915
|
extra,
|
|
@@ -1037,6 +917,7 @@ export class ActorsMcpServer {
|
|
|
1037
917
|
actorName,
|
|
1038
918
|
actorId,
|
|
1039
919
|
apifyMcpServer: this,
|
|
920
|
+
clientContext,
|
|
1040
921
|
}).catch((error) =>
|
|
1041
922
|
// Benign task-expiry is handled in-method (see the catch block and
|
|
1042
923
|
// storeTaskResultOrSkipIfExpired); anything reaching here is genuinely unexpected.
|
|
@@ -1046,116 +927,38 @@ export class ActorsMcpServer {
|
|
|
1046
927
|
shouldTrackTelemetry = false;
|
|
1047
928
|
return { task };
|
|
1048
929
|
}
|
|
1049
|
-
// Sync path:
|
|
1050
|
-
|
|
1051
|
-
// 402, so the agent gets the precise reason.
|
|
1052
|
-
if (standbyRejection || paymentRequiredResult) {
|
|
1053
|
-
const outcome = buildPreflightFailureOutcome(standbyRejection, paymentRequiredResult, actorName, actorId);
|
|
1054
|
-
toolStatus = outcome.toolStatus;
|
|
1055
|
-
callDiagnostics = outcome.callDiagnostics;
|
|
1056
|
-
return captureResult(outcome.result);
|
|
1057
|
-
}
|
|
1058
|
-
// Progress tracker: opt in for the two INTERNAL tools that emit during a sync wait
|
|
1059
|
-
// (call-actor start+waitForFinish, get-actor-run when waitSecs > 0), and unconditionally
|
|
1060
|
-
// for ACTOR tools. ACTOR_MCP forwards notifications directly, not via a tracker.
|
|
1061
|
-
const progressTrackerOptIn = tool.type === TOOL_TYPE.ACTOR ||
|
|
1062
|
-
(tool.type === TOOL_TYPE.INTERNAL &&
|
|
1063
|
-
(tool.name === HELPER_TOOLS.ACTOR_CALL || tool.name === HELPER_TOOLS.ACTOR_RUNS_GET));
|
|
1064
|
-
const progressTracker = progressTrackerOptIn
|
|
1065
|
-
? createProgressTracker(progressToken, extra.sendNotification)
|
|
1066
|
-
: null;
|
|
1067
|
-
const dispatchResult = await dispatchToolCall({
|
|
1068
|
-
tool,
|
|
1069
|
-
toolArgs: toolArgs,
|
|
1070
|
-
logSafeArgs,
|
|
1071
|
-
apifyToken,
|
|
1072
|
-
apifyClient: apifyClient,
|
|
930
|
+
// Sync path: run the shared dispatch tail and project its neutral outcome by identity.
|
|
931
|
+
const outcome = await executeSyncToolCall(prepared, {
|
|
1073
932
|
apifyMcpServer: this,
|
|
933
|
+
apifyToken,
|
|
934
|
+
toolName: name,
|
|
1074
935
|
mcpSessionId,
|
|
1075
936
|
progressToken,
|
|
1076
|
-
progressTracker,
|
|
1077
|
-
shouldForwardNotifications: true,
|
|
1078
937
|
extra,
|
|
1079
|
-
actorName,
|
|
1080
|
-
actorId,
|
|
1081
|
-
taskMode: false,
|
|
1082
938
|
});
|
|
1083
|
-
toolStatus =
|
|
1084
|
-
callDiagnostics =
|
|
1085
|
-
|
|
939
|
+
toolStatus = outcome.toolStatus;
|
|
940
|
+
callDiagnostics = outcome.callDiagnostics;
|
|
941
|
+
toolResult = outcome.result;
|
|
942
|
+
return outcome.result;
|
|
1086
943
|
}
|
|
1087
944
|
catch (error) {
|
|
1088
|
-
//
|
|
1089
|
-
// returns them as JSON-RPC errors. failInvalidParams already set callDiagnostics
|
|
1090
|
-
// with the correct semantic category (e.g. AUTH), so we must not overwrite it.
|
|
1091
|
-
// Re-throwing first is order-equivalent only because no McpError with an HTTP-range
|
|
1092
|
-
// code reaches this catch: an McpError(402) WOULD satisfy the x402 predicate
|
|
1093
|
-
// (getHttpStatusCode falls through to `.code`), but every remote-McpError route is
|
|
1094
|
-
// sealed by an inner catch (ACTOR_MCP branch, call-actor MCP passthrough) and all
|
|
1095
|
-
// in-repo McpErrors use negative ErrorCode.* values.
|
|
945
|
+
// Match v1: classify task-creation failures, but re-throw protocol errors as JSON-RPC.
|
|
1096
946
|
if (error instanceof McpError) {
|
|
1097
947
|
throw error;
|
|
1098
948
|
}
|
|
1099
|
-
const
|
|
949
|
+
const outcome = classifyToolCallError(error, {
|
|
950
|
+
apifyMcpServer: this,
|
|
1100
951
|
toolName: name,
|
|
952
|
+
failingToolName: resolvedToolName,
|
|
1101
953
|
actorName,
|
|
1102
954
|
actorId,
|
|
1103
|
-
isAborted: Boolean((
|
|
955
|
+
isAborted: Boolean((_c = extra.signal) === null || _c === void 0 ? void 0 : _c.aborted),
|
|
956
|
+
mcpSessionId,
|
|
1104
957
|
});
|
|
1105
|
-
toolStatus =
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
// content[0].text (JSON) + isError: true. No log here (unlike the task path). The
|
|
1110
|
-
// concurrent-run limit also surfaces as 402 but is excluded by the predicate and
|
|
1111
|
-
// falls through to the generic run-limit handling below.
|
|
1112
|
-
callDiagnostics = errorResult.callDiagnostics;
|
|
1113
|
-
return captureResult(errorResult.response);
|
|
1114
|
-
}
|
|
1115
|
-
case TOOL_CALL_ERROR_KIND.APPROVAL: {
|
|
1116
|
-
callDiagnostics = errorResult.callDiagnostics;
|
|
1117
|
-
logHttpError(error, 'Permission approval required while calling tool', {
|
|
1118
|
-
toolName: name,
|
|
1119
|
-
mcpSessionId,
|
|
1120
|
-
});
|
|
1121
|
-
return captureResult(errorResult.response);
|
|
1122
|
-
}
|
|
1123
|
-
case TOOL_CALL_ERROR_KIND.EXECUTION: {
|
|
1124
|
-
callDiagnostics = {
|
|
1125
|
-
// Spread existing diagnostics first (e.g. validation_keyword from
|
|
1126
|
-
// failInvalidParams), then overwrite with the mapper's freshly computed fields
|
|
1127
|
-
// so they take precedence.
|
|
1128
|
-
...callDiagnostics,
|
|
1129
|
-
...errorResult.callDiagnostics,
|
|
1130
|
-
};
|
|
1131
|
-
logHttpError(error, 'Error occurred while calling tool', {
|
|
1132
|
-
toolName: name,
|
|
1133
|
-
toolStatus,
|
|
1134
|
-
mcpSessionId,
|
|
1135
|
-
failureCategory: callDiagnostics.failure_category,
|
|
1136
|
-
failureHttpStatus: callDiagnostics.failure_http_status,
|
|
1137
|
-
actorName: callDiagnostics.actor_name,
|
|
1138
|
-
validationKeyword: callDiagnostics.validation_keyword,
|
|
1139
|
-
validationPath: callDiagnostics.validation_path,
|
|
1140
|
-
validationMissingProperty: callDiagnostics.validation_missing_property,
|
|
1141
|
-
validationAdditionalProperty: callDiagnostics.validation_additional_property,
|
|
1142
|
-
});
|
|
1143
|
-
// This framework outer-catch path bypasses extractToolTelemetry (returned via
|
|
1144
|
-
// captureResult), so preserve the pre-existing wire shape { toolStatus } exactly:
|
|
1145
|
-
// reuse the local ABORTED-aware toolStatus, do NOT re-derive from the error (which
|
|
1146
|
-
// would drop ABORTED and leak failureCategory/failureHttpStatus onto the wire).
|
|
1147
|
-
return captureResult({
|
|
1148
|
-
...respondOk(errorResult.userText),
|
|
1149
|
-
isError: true,
|
|
1150
|
-
toolTelemetry: { toolStatus },
|
|
1151
|
-
});
|
|
1152
|
-
}
|
|
1153
|
-
default:
|
|
1154
|
-
// Compile-time exhaustiveness guard (same `satisfies never` idiom as
|
|
1155
|
-
// dispatchToolCall's default arm): a new TOOL_CALL_ERROR_KIND makes `errorResult`
|
|
1156
|
-
// non-`never` here and fails to compile. Unreachable at runtime.
|
|
1157
|
-
throw new McpError(ErrorCode.InvalidParams, `Unknown tool-call error kind "${errorResult.kind}"`);
|
|
1158
|
-
}
|
|
958
|
+
toolStatus = outcome.toolStatus;
|
|
959
|
+
callDiagnostics = outcome.callDiagnostics;
|
|
960
|
+
toolResult = outcome.result;
|
|
961
|
+
return outcome.result;
|
|
1159
962
|
}
|
|
1160
963
|
finally {
|
|
1161
964
|
if (shouldTrackTelemetry) {
|
|
@@ -1240,5 +1043,4 @@ export class ActorsMcpServer {
|
|
|
1240
1043
|
await this.server.close();
|
|
1241
1044
|
}
|
|
1242
1045
|
}
|
|
1243
|
-
//# sourceMappingURL=server.js.map
|
|
1244
|
-
//# debugId=b2bdac72-d12f-5751-9e08-72a36e12d99e
|
|
1046
|
+
//# sourceMappingURL=server.js.map
|