@apify/actors-mcp-server 0.11.7-beta.10 → 0.11.7-beta.11
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/mcp/server.d.ts +0 -16
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +4 -295
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/task_execution.d.ts +42 -0
- package/dist/mcp/task_execution.d.ts.map +1 -0
- package/dist/mcp/task_execution.js +310 -0
- package/dist/mcp/task_execution.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import log from '@apify/log';
|
|
2
|
+
import { FAILURE_CATEGORY, TOOL_STATUS } from '../const.js';
|
|
3
|
+
import { withReportProblemNudge } from '../tools/dev/report_problem.js';
|
|
4
|
+
import { TOOL_TYPE } from '../types.js';
|
|
5
|
+
import { logHttpError, sanitizeMezmoMessage } from '../utils/logging.js';
|
|
6
|
+
import { createProgressTracker } from '../utils/progress.js';
|
|
7
|
+
import { buildActorFields, getToolFullName } from '../utils/tools.js';
|
|
8
|
+
import { buildToolCallErrorResult, TOOL_CALL_ERROR_KIND } from './tool_call_error_mapper.js';
|
|
9
|
+
import { logToolCallAndTelemetry, prepareTelemetryData } from './tool_call_telemetry.js';
|
|
10
|
+
import { dispatchToolCall } from './tool_dispatch.js';
|
|
11
|
+
import { createTaskCancellationWatcher, isTaskCancelled, isTaskNotFoundError, storeTaskResultOrSkipIfExpired, } from './utils.js';
|
|
12
|
+
/** Send notifications/tasks/status for taskId. Routes via session transport (no relatedRequestId).
|
|
13
|
+
* Swallows errors — notifications are advisory. */
|
|
14
|
+
export async function emitTaskStatusNotification(taskId, mcpSessionId, taskStore, server) {
|
|
15
|
+
try {
|
|
16
|
+
const task = await taskStore.getTask(taskId, mcpSessionId);
|
|
17
|
+
if (!task)
|
|
18
|
+
return;
|
|
19
|
+
// Per spec: notifications/tasks/status MUST NOT carry _meta.related-task (task ID is in params).
|
|
20
|
+
// Called without options so the notification routes through the session transport,
|
|
21
|
+
// not the request-scoped stream (which closes once the initial { task } response is flushed).
|
|
22
|
+
await server.notification({
|
|
23
|
+
method: 'notifications/tasks/status',
|
|
24
|
+
params: {
|
|
25
|
+
taskId: task.taskId,
|
|
26
|
+
status: task.status,
|
|
27
|
+
createdAt: task.createdAt,
|
|
28
|
+
lastUpdatedAt: task.lastUpdatedAt,
|
|
29
|
+
ttl: task.ttl,
|
|
30
|
+
...(task.statusMessage != null && { statusMessage: task.statusMessage }),
|
|
31
|
+
...(task.pollInterval != null && { pollInterval: task.pollInterval }),
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// Silent fail — notifications are advisory
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// TODO: outer orchestration here (pre-flight, telemetry bookkeeping, task-store handling) still duplicates the CallToolRequestSchema handler's logic; the dispatch ladder is now shared. Refactor.
|
|
40
|
+
/**
|
|
41
|
+
* Executes a tool asynchronously for a long-running task and updates task status.
|
|
42
|
+
*
|
|
43
|
+
* @param params - Tool execution parameters
|
|
44
|
+
* @param params.taskId - The task identifier
|
|
45
|
+
* @param params.tool - The tool to execute
|
|
46
|
+
* @param params.toolArgs - Tool arguments
|
|
47
|
+
* @param params.logSafeArgs - Tool arguments with sensitive fields redacted, safe for logging
|
|
48
|
+
* @param params.apifyClient - ApifyClient configured with payment headers or the standard token
|
|
49
|
+
* @param params.apifyToken - Apify API token
|
|
50
|
+
* @param params.progressToken - Progress token for notifications
|
|
51
|
+
* @param params.extra - Extra request handler context
|
|
52
|
+
* @param params.mcpSessionId - MCP session ID for telemetry
|
|
53
|
+
* @param params.actorName - Actor name, used for telemetry and error diagnostics
|
|
54
|
+
* @param params.actorId - Actor ID, used for telemetry and error diagnostics
|
|
55
|
+
* @param params.apifyMcpServer - The ActorsMcpServer instance (task store, server, tools, telemetry config)
|
|
56
|
+
*/
|
|
57
|
+
export async function executeToolAndUpdateTask(params) {
|
|
58
|
+
const { taskId, tool, toolArgs, logSafeArgs, apifyClient, apifyToken, progressToken, extra, mcpSessionId, actorName, actorId, apifyMcpServer, } = params;
|
|
59
|
+
let toolStatus = TOOL_STATUS.SUCCEEDED;
|
|
60
|
+
// Always populate actor fields so they're tracked on both success and failure paths.
|
|
61
|
+
let callDiagnostics = { ...buildActorFields(actorName, actorId) };
|
|
62
|
+
const startTime = Date.now();
|
|
63
|
+
log.debug('[executeToolAndUpdateTask] Starting task execution', {
|
|
64
|
+
taskId,
|
|
65
|
+
toolName: tool.name,
|
|
66
|
+
mcpSessionId,
|
|
67
|
+
});
|
|
68
|
+
// Prepare telemetry before try-catch so it's accessible to both paths.
|
|
69
|
+
// This avoids re-fetching user data in the error handler.
|
|
70
|
+
const { telemetryData, userId } = await prepareTelemetryData({
|
|
71
|
+
toolName: getToolFullName(tool),
|
|
72
|
+
mcpSessionId,
|
|
73
|
+
apifyToken,
|
|
74
|
+
apifyMcpServer,
|
|
75
|
+
});
|
|
76
|
+
const finishTaskTracking = (status, diagnostics, result) => {
|
|
77
|
+
logToolCallAndTelemetry({
|
|
78
|
+
toolName: tool.name,
|
|
79
|
+
mcpSessionId,
|
|
80
|
+
toolStatus: status,
|
|
81
|
+
startTime,
|
|
82
|
+
taskId,
|
|
83
|
+
telemetryData,
|
|
84
|
+
userId,
|
|
85
|
+
callDiagnostics: diagnostics,
|
|
86
|
+
args: toolArgs,
|
|
87
|
+
result,
|
|
88
|
+
apifyMcpServer,
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
// Terminal step shared by every task outcome: store the result (expiry-tolerant),
|
|
92
|
+
// emit the status notification, record telemetry.
|
|
93
|
+
const completeTask = async (storeStatus, taskResult, status, diagnostics) => {
|
|
94
|
+
await storeTaskResultOrSkipIfExpired(apifyMcpServer.taskStore, tool.name, taskId, storeStatus, taskResult, mcpSessionId);
|
|
95
|
+
await emitTaskStatusNotification(taskId, mcpSessionId, apifyMcpServer.taskStore, apifyMcpServer.server);
|
|
96
|
+
finishTaskTracking(status, diagnostics, taskResult);
|
|
97
|
+
};
|
|
98
|
+
// Once a task is cancelled the spec forbids writing a result; every storage path
|
|
99
|
+
// must short-circuit here. `logSuffix` is concatenated after "Task was cancelled"
|
|
100
|
+
// so we keep the existing log format and the existing telemetry status per path.
|
|
101
|
+
const skipIfTaskCancelled = async (logSuffix, status, diagnostics) => {
|
|
102
|
+
if (!(await isTaskCancelled(taskId, mcpSessionId, apifyMcpServer.taskStore)))
|
|
103
|
+
return false;
|
|
104
|
+
log.debug(`[executeToolAndUpdateTask] Task was cancelled${logSuffix}`, { taskId, mcpSessionId });
|
|
105
|
+
finishTaskTracking(status, diagnostics);
|
|
106
|
+
return true;
|
|
107
|
+
};
|
|
108
|
+
// Bridges MCP `tasks/cancel` to the running handler: when the client
|
|
109
|
+
// explicitly cancels the task, this signal aborts so the underlying
|
|
110
|
+
// Actor run stops instead of consuming compute until natural completion.
|
|
111
|
+
// Per MCP tasks spec, request-level aborts (client disconnect,
|
|
112
|
+
// notifications/cancelled for the original request ID) MUST NOT cancel
|
|
113
|
+
// the task — `extra.signal` is intentionally not chained here.
|
|
114
|
+
const cancelWatcher = createTaskCancellationWatcher({
|
|
115
|
+
taskId,
|
|
116
|
+
mcpSessionId,
|
|
117
|
+
taskStore: apifyMcpServer.taskStore,
|
|
118
|
+
});
|
|
119
|
+
const taskExtra = { ...extra, signal: cancelWatcher.signal };
|
|
120
|
+
try {
|
|
121
|
+
log.debug('[executeToolAndUpdateTask] Updating task status to working', {
|
|
122
|
+
taskId,
|
|
123
|
+
mcpSessionId,
|
|
124
|
+
});
|
|
125
|
+
// The store rejects terminal → 'working' transitions. If `tasks/cancel` raced
|
|
126
|
+
// with us (between handler dispatch and the first watcher tick at ~500 ms),
|
|
127
|
+
// updateTaskStatus throws — re-check the store to tell a clean cancel-race
|
|
128
|
+
// apart from a genuine store error.
|
|
129
|
+
// noinspection ExceptionCaughtLocallyJS
|
|
130
|
+
try {
|
|
131
|
+
await apifyMcpServer.taskStore.updateTaskStatus(taskId, 'working', undefined, mcpSessionId);
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
if (await skipIfTaskCancelled(' before execution started, skipping', TOOL_STATUS.ABORTED, {
|
|
135
|
+
...buildActorFields(actorName, actorId),
|
|
136
|
+
}))
|
|
137
|
+
return;
|
|
138
|
+
throw err;
|
|
139
|
+
}
|
|
140
|
+
await emitTaskStatusNotification(taskId, mcpSessionId, apifyMcpServer.taskStore, apifyMcpServer.server);
|
|
141
|
+
// Execute the tool and get the result
|
|
142
|
+
let result = {};
|
|
143
|
+
// Callback to propagate Actor run statusMessage into the task store and emit a push notification.
|
|
144
|
+
// TODO(TC-3): cancel arriving while this is scheduled throws cancelled → working;
|
|
145
|
+
// currently swallowed by progress.ts's tick catch — guard or catch explicitly.
|
|
146
|
+
const onStatusMessage = async (message) => {
|
|
147
|
+
await apifyMcpServer.taskStore.updateTaskStatus(taskId, 'working', message, mcpSessionId);
|
|
148
|
+
await emitTaskStatusNotification(taskId, mcpSessionId, apifyMcpServer.taskStore, apifyMcpServer.server);
|
|
149
|
+
};
|
|
150
|
+
// ACTOR_MCP never reads the tracker (matching the sync path, which passes null for it);
|
|
151
|
+
// INTERNAL/ACTOR get one built from taskId + onStatusMessage, which dispatch consumes
|
|
152
|
+
// and stops.
|
|
153
|
+
const progressTracker = tool.type === TOOL_TYPE.ACTOR_MCP
|
|
154
|
+
? null
|
|
155
|
+
: createProgressTracker(progressToken, extra.sendNotification, taskId, onStatusMessage);
|
|
156
|
+
const dispatchResult = await dispatchToolCall({
|
|
157
|
+
tool,
|
|
158
|
+
toolArgs,
|
|
159
|
+
logSafeArgs,
|
|
160
|
+
apifyToken,
|
|
161
|
+
apifyClient,
|
|
162
|
+
apifyMcpServer,
|
|
163
|
+
mcpSessionId,
|
|
164
|
+
progressToken,
|
|
165
|
+
progressTracker,
|
|
166
|
+
shouldForwardNotifications: false,
|
|
167
|
+
extra: taskExtra,
|
|
168
|
+
actorName,
|
|
169
|
+
actorId,
|
|
170
|
+
taskMode: true,
|
|
171
|
+
logContext: { messageSuffix: ' for task', fields: { taskId } },
|
|
172
|
+
});
|
|
173
|
+
result = dispatchResult.result;
|
|
174
|
+
toolStatus = dispatchResult.toolStatus;
|
|
175
|
+
callDiagnostics = dispatchResult.callDiagnostics;
|
|
176
|
+
// Check if task was cancelled before storing result
|
|
177
|
+
if (await skipIfTaskCancelled(', skipping result storage', toolStatus))
|
|
178
|
+
return;
|
|
179
|
+
// On a failed result, nudge the agent to report the blocker via report-problem (mirrors the
|
|
180
|
+
// synchronous CallTool path, which task-mode calls like call-actor bypass).
|
|
181
|
+
result = withReportProblemNudge({
|
|
182
|
+
result,
|
|
183
|
+
tools: apifyMcpServer.tools,
|
|
184
|
+
failingToolName: tool.name,
|
|
185
|
+
failureCategory: callDiagnostics.failure_category,
|
|
186
|
+
failureHttpStatus: callDiagnostics.failure_http_status,
|
|
187
|
+
});
|
|
188
|
+
// Store the result in the task store
|
|
189
|
+
log.debug('[executeToolAndUpdateTask] Storing completed result', {
|
|
190
|
+
taskId,
|
|
191
|
+
mcpSessionId,
|
|
192
|
+
});
|
|
193
|
+
await completeTask('completed', result, toolStatus, callDiagnostics);
|
|
194
|
+
log.debug('Task completed successfully', { taskId, toolName: tool.name, mcpSessionId });
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
// Reached only when the task expired before the `working` transition (updateTaskStatus
|
|
198
|
+
// above rethrows the store's unknown-taskId error). The tool never ran and the task is
|
|
199
|
+
// gone, so soft-fail, record telemetry, and stop. Every result store (success and error
|
|
200
|
+
// paths) tolerates expiry via storeTaskResultOrSkipIfExpired, so they don't reach here.
|
|
201
|
+
if (isTaskNotFoundError(error)) {
|
|
202
|
+
log.softFail('Task expired before execution started', {
|
|
203
|
+
taskId,
|
|
204
|
+
toolName: tool.name,
|
|
205
|
+
mcpSessionId,
|
|
206
|
+
});
|
|
207
|
+
finishTaskTracking(TOOL_STATUS.SOFT_FAIL, {
|
|
208
|
+
failure_category: FAILURE_CATEGORY.INTERNAL_ERROR,
|
|
209
|
+
...buildActorFields(actorName, actorId),
|
|
210
|
+
});
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const errorResult = buildToolCallErrorResult(error, {
|
|
214
|
+
toolName: tool.name,
|
|
215
|
+
actorName,
|
|
216
|
+
actorId,
|
|
217
|
+
isAborted: Boolean(cancelWatcher.signal.aborted),
|
|
218
|
+
});
|
|
219
|
+
// Handle 402 Payment Required — return structured x402 result so clients can auto-pay
|
|
220
|
+
if (errorResult.kind === TOOL_CALL_ERROR_KIND.PAYMENT) {
|
|
221
|
+
logHttpError(error, 'Payment required while calling tool (task mode)', { toolName: tool.name });
|
|
222
|
+
// Per MCP tasks spec: once a task is cancelled it MUST remain cancelled,
|
|
223
|
+
// so guard storeTaskResult against a cancel that raced with this 402.
|
|
224
|
+
if (await skipIfTaskCancelled(', skipping 402 result storage', TOOL_STATUS.ABORTED, {
|
|
225
|
+
...buildActorFields(actorName, actorId),
|
|
226
|
+
}))
|
|
227
|
+
return;
|
|
228
|
+
await completeTask('completed', errorResult.response, errorResult.toolStatus, errorResult.callDiagnostics);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (errorResult.kind === TOOL_CALL_ERROR_KIND.APPROVAL) {
|
|
232
|
+
logHttpError(error, 'Permission approval required while calling tool (task mode)', {
|
|
233
|
+
toolName: tool.name,
|
|
234
|
+
});
|
|
235
|
+
// Per MCP tasks spec: once a task is cancelled it MUST remain cancelled,
|
|
236
|
+
// so guard storeTaskResult against a cancel that raced with this approval error.
|
|
237
|
+
if (await skipIfTaskCancelled(', skipping permission-approval result storage', TOOL_STATUS.ABORTED, {
|
|
238
|
+
...buildActorFields(actorName, actorId),
|
|
239
|
+
}))
|
|
240
|
+
return;
|
|
241
|
+
await completeTask('completed', errorResult.response, errorResult.toolStatus, errorResult.callDiagnostics);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
toolStatus = errorResult.toolStatus;
|
|
245
|
+
callDiagnostics = errorResult.callDiagnostics;
|
|
246
|
+
// Log level follows the already-classified toolStatus:
|
|
247
|
+
// SOFT_FAIL (e.g. 402/403 user quota, client-side issues) → softFail
|
|
248
|
+
// FAILED/ABORTED/other → error
|
|
249
|
+
if (toolStatus === TOOL_STATUS.SOFT_FAIL) {
|
|
250
|
+
// Mezmo promotes on "error" in message/keys — use errMessage key, sanitized.
|
|
251
|
+
const errMessage = sanitizeMezmoMessage(error instanceof Error ? error.message : String(error));
|
|
252
|
+
log.softFail('Tool execution soft-failed for task', {
|
|
253
|
+
taskId,
|
|
254
|
+
toolName: tool.name,
|
|
255
|
+
toolStatus,
|
|
256
|
+
mcpSessionId,
|
|
257
|
+
failureCategory: callDiagnostics.failure_category,
|
|
258
|
+
failureHttpStatus: callDiagnostics.failure_http_status,
|
|
259
|
+
actorName: callDiagnostics.actor_name,
|
|
260
|
+
errMessage,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
log.error('Error executing tool for task', {
|
|
265
|
+
taskId,
|
|
266
|
+
toolName: tool.name,
|
|
267
|
+
toolStatus,
|
|
268
|
+
mcpSessionId,
|
|
269
|
+
failureCategory: callDiagnostics.failure_category,
|
|
270
|
+
failureHttpStatus: callDiagnostics.failure_http_status,
|
|
271
|
+
actorName: callDiagnostics.actor_name,
|
|
272
|
+
error,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
const { userText } = errorResult;
|
|
276
|
+
// Check if task was cancelled before storing result
|
|
277
|
+
if (await skipIfTaskCancelled(', skipping result storage', toolStatus, callDiagnostics))
|
|
278
|
+
return;
|
|
279
|
+
log.debug('[executeToolAndUpdateTask] Storing failed result', {
|
|
280
|
+
taskId,
|
|
281
|
+
mcpSessionId,
|
|
282
|
+
});
|
|
283
|
+
// Nudge on a genuinely-failed task result (mirrors the completed path and the sync
|
|
284
|
+
// captureResult). INTERNAL_ERROR and an unknown category get the full nudge; a genuine
|
|
285
|
+
// INVALID_INPUT gets the softer nudge; payment (402) is suppressed via the HTTP status and
|
|
286
|
+
// AUTH / PERMISSION_APPROVAL_REQUIRED via NON_NUDGE_FAILURE_CATEGORIES. The 402 branch above
|
|
287
|
+
// returns before reaching here, so this only sees non-payment failures.
|
|
288
|
+
const failedResult = withReportProblemNudge({
|
|
289
|
+
result: {
|
|
290
|
+
content: [
|
|
291
|
+
{
|
|
292
|
+
type: 'text',
|
|
293
|
+
text: userText,
|
|
294
|
+
},
|
|
295
|
+
],
|
|
296
|
+
isError: true,
|
|
297
|
+
internalToolStatus: toolStatus,
|
|
298
|
+
},
|
|
299
|
+
tools: apifyMcpServer.tools,
|
|
300
|
+
failingToolName: tool.name,
|
|
301
|
+
failureCategory: callDiagnostics.failure_category,
|
|
302
|
+
failureHttpStatus: callDiagnostics.failure_http_status,
|
|
303
|
+
});
|
|
304
|
+
await completeTask('failed', failedResult, toolStatus, callDiagnostics);
|
|
305
|
+
}
|
|
306
|
+
finally {
|
|
307
|
+
cancelWatcher.dispose();
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
//# sourceMappingURL=task_execution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task_execution.js","sourceRoot":"","sources":["../../src/mcp/task_execution.ts"],"names":[],"mappings":"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"}
|