@apify/actors-mcp-server 0.11.7-beta.7 → 0.11.7-beta.8
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 -19
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +9 -203
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool_dispatch.d.ts +49 -0
- package/dist/mcp/tool_dispatch.d.ts.map +1 -0
- package/dist/mcp/tool_dispatch.js +208 -0
- package/dist/mcp/tool_dispatch.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { CallToolResultSchema, ErrorCode, McpError, ServerNotificationSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import dedent from 'dedent';
|
|
3
|
+
import log from '@apify/log';
|
|
4
|
+
import { FAILURE_CATEGORY, TOOL_STATUS } from '../const.js';
|
|
5
|
+
import { actorExecutor } from '../tools/actors/actor_executor.js';
|
|
6
|
+
import { TOOL_TYPE } from '../types.js';
|
|
7
|
+
import { remoteMcpFailureDetail } from '../utils/apify_errors.js';
|
|
8
|
+
import { logHttpError } from '../utils/logging.js';
|
|
9
|
+
import { respondErrorNoTelemetry } from '../utils/mcp.js';
|
|
10
|
+
import { applyToolTelemetry, classifyFailureCategory, getToolStatusFromError } from '../utils/tool_status.js';
|
|
11
|
+
import { buildActorFields } from '../utils/tools.js';
|
|
12
|
+
import { connectMCPClient } from './client.js';
|
|
13
|
+
import { EXTERNAL_TOOL_CALL_TIMEOUT_MSEC } from './const.js';
|
|
14
|
+
/**
|
|
15
|
+
* Runs a validated tool call through the single tool-type dispatch switch and returns the raw
|
|
16
|
+
* result plus derived telemetry. The exhaustive switch turns a future 4th TOOL_TYPE into a compile
|
|
17
|
+
* error (same `satisfies never` idiom as getToolFullName) instead of a silent runtime fall-through.
|
|
18
|
+
* Both the sync `CallToolRequestSchema` handler and `executeToolAndUpdateTask` call this after their
|
|
19
|
+
* own pre-dispatch validation and keep their own try/catch + buildToolCallErrorResult around it.
|
|
20
|
+
* INTERNAL and ACTOR execution errors propagate to the caller's catch; the ACTOR_MCP case keeps its
|
|
21
|
+
* own inner catch and returns a soft-fail result instead of throwing.
|
|
22
|
+
*
|
|
23
|
+
* `extractToolTelemetry` (via `applyToolTelemetry`) runs once here, in the INTERNAL and ACTOR
|
|
24
|
+
* cases, and strips `toolTelemetry` in place, so callers must not re-strip. ACTOR_MCP sets
|
|
25
|
+
* telemetry manually instead. The caller constructs `progressTracker`; dispatch consumes it and stops
|
|
26
|
+
* it in the branch `finally`. The abort source is `extra.signal`: the request signal for sync; the
|
|
27
|
+
* task caller passes a `taskExtra` whose `signal` is the cancel watcher's, so a client disconnect
|
|
28
|
+
* never cancels a task. `shouldForwardNotifications` gates only the ACTOR_MCP raw-notification
|
|
29
|
+
* forwarder (true for sync, false for task, whose originating request is already answered).
|
|
30
|
+
* `taskMode` is a passthrough to `tool.call` / `executeActorTool`, never a dispatch selector.
|
|
31
|
+
*/
|
|
32
|
+
export async function dispatchToolCall(params) {
|
|
33
|
+
var _a, _b, _c, _d;
|
|
34
|
+
const { tool, toolArgs, logSafeArgs, apifyToken, apifyClient, apifyMcpServer, mcpSessionId, progressToken, progressTracker, shouldForwardNotifications, extra, actorName, actorId, taskMode, logContext, } = params;
|
|
35
|
+
let result = {};
|
|
36
|
+
let toolStatus = TOOL_STATUS.SUCCEEDED;
|
|
37
|
+
// Always populate actor fields so they're tracked on both success and failure paths.
|
|
38
|
+
let callDiagnostics = { ...buildActorFields(actorName, actorId) };
|
|
39
|
+
switch (tool.type) {
|
|
40
|
+
case TOOL_TYPE.INTERNAL: {
|
|
41
|
+
try {
|
|
42
|
+
log.info(`Calling internal tool${(_a = logContext === null || logContext === void 0 ? void 0 : logContext.messageSuffix) !== null && _a !== void 0 ? _a : ''}`, {
|
|
43
|
+
...logContext === null || logContext === void 0 ? void 0 : logContext.fields,
|
|
44
|
+
toolName: tool.name,
|
|
45
|
+
mcpSessionId,
|
|
46
|
+
input: logSafeArgs,
|
|
47
|
+
});
|
|
48
|
+
const res = (await tool.call({
|
|
49
|
+
args: toolArgs,
|
|
50
|
+
extra,
|
|
51
|
+
apifyMcpServer,
|
|
52
|
+
mcpServer: apifyMcpServer.server,
|
|
53
|
+
apifyToken,
|
|
54
|
+
apifyClient,
|
|
55
|
+
progressTracker,
|
|
56
|
+
mcpSessionId,
|
|
57
|
+
taskMode,
|
|
58
|
+
}));
|
|
59
|
+
// Extract diagnostics and strip internal fields from res before returning to client.
|
|
60
|
+
({ toolStatus, callDiagnostics } = applyToolTelemetry(res, actorName, actorId, callDiagnostics));
|
|
61
|
+
result = res;
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
progressTracker === null || progressTracker === void 0 ? void 0 : progressTracker.stop();
|
|
65
|
+
}
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
case TOOL_TYPE.ACTOR_MCP: {
|
|
69
|
+
// This case never throws: connect/exec failures resolve to a soft-fail `result`
|
|
70
|
+
// (isError body) below instead. As a task, that means the outer completeTask
|
|
71
|
+
// stores it via the 'completed' path (isError body) — deliberately matching sync's
|
|
72
|
+
// own soft-fail semantics, unlike ACTOR/INTERNAL, whose thrown errors land in the
|
|
73
|
+
// task caller's 'failed' path.
|
|
74
|
+
let client = null;
|
|
75
|
+
try {
|
|
76
|
+
client = await connectMCPClient(tool.serverUrl, apifyToken, mcpSessionId);
|
|
77
|
+
if (!client) {
|
|
78
|
+
const msg = dedent `
|
|
79
|
+
Failed to connect to MCP server at "${tool.serverUrl}".
|
|
80
|
+
Please verify the server URL is correct and accessible, and ensure you have a valid Apify token with appropriate permissions.
|
|
81
|
+
`;
|
|
82
|
+
log.softFail(msg, { mcpSessionId, failureCategory: FAILURE_CATEGORY.INTERNAL_ERROR });
|
|
83
|
+
await apifyMcpServer.server.sendLoggingMessage({ level: 'error', data: msg });
|
|
84
|
+
toolStatus = TOOL_STATUS.SOFT_FAIL;
|
|
85
|
+
callDiagnostics = { ...callDiagnostics, failure_category: FAILURE_CATEGORY.INTERNAL_ERROR };
|
|
86
|
+
result = respondErrorNoTelemetry(msg);
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
// Only set up notification handlers if progressToken is provided by the client.
|
|
90
|
+
// Gated off for tasks (shouldForwardNotifications=false): the originating request is
|
|
91
|
+
// already answered, so forwarding against its progressToken would misroute.
|
|
92
|
+
if (shouldForwardNotifications && progressToken !== undefined && progressToken !== null) {
|
|
93
|
+
// Set up notification handlers for the client
|
|
94
|
+
for (const schema of ServerNotificationSchema.options) {
|
|
95
|
+
const method = schema.shape.method.value;
|
|
96
|
+
// Forward notifications from the proxy client to the server
|
|
97
|
+
client.setNotificationHandler(schema, async (notification) => {
|
|
98
|
+
log.debug('Sending MCP notification', {
|
|
99
|
+
method,
|
|
100
|
+
mcpSessionId,
|
|
101
|
+
notification,
|
|
102
|
+
});
|
|
103
|
+
await extra.sendNotification(notification);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
log.info(`Calling Actor-MCP${(_b = logContext === null || logContext === void 0 ? void 0 : logContext.messageSuffix) !== null && _b !== void 0 ? _b : ''}`, {
|
|
108
|
+
...logContext === null || logContext === void 0 ? void 0 : logContext.fields,
|
|
109
|
+
toolName: tool.name,
|
|
110
|
+
actorMcpToolName: tool.originToolName,
|
|
111
|
+
actorId: tool.actorId,
|
|
112
|
+
mcpSessionId,
|
|
113
|
+
input: logSafeArgs,
|
|
114
|
+
});
|
|
115
|
+
const res = await client.callTool({
|
|
116
|
+
name: tool.originToolName,
|
|
117
|
+
arguments: toolArgs,
|
|
118
|
+
// Without forwarding there is no route back for remote progress — don't
|
|
119
|
+
// hand the remote a token nobody listens to.
|
|
120
|
+
...(shouldForwardNotifications ? { _meta: { progressToken } } : {}),
|
|
121
|
+
}, CallToolResultSchema, {
|
|
122
|
+
timeout: EXTERNAL_TOOL_CALL_TIMEOUT_MSEC,
|
|
123
|
+
});
|
|
124
|
+
// TODO: actor-mcp responses are opaque — isError could be a user input problem
|
|
125
|
+
// (e.g. invalid query) or a genuine server failure. We can't distinguish without
|
|
126
|
+
// parsing the error text. Defaulting to INTERNAL_ERROR for now; revisit when
|
|
127
|
+
// actor-mcp gets deeper telemetry treatment.
|
|
128
|
+
if ('isError' in res && res.isError) {
|
|
129
|
+
toolStatus = TOOL_STATUS.SOFT_FAIL;
|
|
130
|
+
callDiagnostics = {
|
|
131
|
+
failure_category: FAILURE_CATEGORY.INTERNAL_ERROR,
|
|
132
|
+
...buildActorFields(actorName, actorId),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
result = { ...res };
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
toolStatus = getToolStatusFromError(error, Boolean((_c = extra.signal) === null || _c === void 0 ? void 0 : _c.aborted));
|
|
139
|
+
const failureDetail = error instanceof Error ? error.message.slice(0, 200) : String(error).slice(0, 200);
|
|
140
|
+
callDiagnostics = {
|
|
141
|
+
failure_category: classifyFailureCategory(error),
|
|
142
|
+
failure_detail: failureDetail,
|
|
143
|
+
...buildActorFields(actorName, actorId),
|
|
144
|
+
};
|
|
145
|
+
logHttpError(error, `Failed to call MCP tool '${tool.originToolName}' on Actor '${tool.actorId}'`, {
|
|
146
|
+
actorId: tool.actorId,
|
|
147
|
+
toolName: tool.originToolName,
|
|
148
|
+
failureCategory: callDiagnostics.failure_category,
|
|
149
|
+
});
|
|
150
|
+
result = respondErrorNoTelemetry(`Failed to call MCP tool '${tool.originToolName}' on Actor '${tool.actorId}': ${remoteMcpFailureDetail(error)}`);
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
if (client)
|
|
154
|
+
await client.close();
|
|
155
|
+
}
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
case TOOL_TYPE.ACTOR: {
|
|
159
|
+
try {
|
|
160
|
+
log.info(`Calling Actor${(_d = logContext === null || logContext === void 0 ? void 0 : logContext.messageSuffix) !== null && _d !== void 0 ? _d : ''}`, {
|
|
161
|
+
...logContext === null || logContext === void 0 ? void 0 : logContext.fields,
|
|
162
|
+
toolName: tool.name,
|
|
163
|
+
actorName: tool.actorFullName,
|
|
164
|
+
mcpSessionId,
|
|
165
|
+
input: logSafeArgs,
|
|
166
|
+
});
|
|
167
|
+
const executorResult = await actorExecutor.executeActorTool({
|
|
168
|
+
actorFullName: tool.actorFullName,
|
|
169
|
+
input: toolArgs,
|
|
170
|
+
apifyClient,
|
|
171
|
+
callOptions: { memory: tool.memoryMbytes },
|
|
172
|
+
progressTracker,
|
|
173
|
+
abortSignal: extra.signal,
|
|
174
|
+
mcpSessionId,
|
|
175
|
+
datasetItemsSchema: tool.datasetItemsSchema,
|
|
176
|
+
taskMode,
|
|
177
|
+
});
|
|
178
|
+
if (!executorResult) {
|
|
179
|
+
toolStatus = TOOL_STATUS.ABORTED;
|
|
180
|
+
// Receivers of cancellation notifications SHOULD NOT send a response for the cancelled request
|
|
181
|
+
// https://modelcontextprotocol.io/specification/2025-06-18/basic/utilities/cancellation#behavior-requirements
|
|
182
|
+
result = {};
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
// Mirror the INTERNAL branch: read the telemetry the executor embedded on error
|
|
186
|
+
// results (e.g. respondUserError → SOFT_FAIL/INVALID_INPUT), strip it from the wire,
|
|
187
|
+
// and set failure_category so the report-problem nudge picks the softer variant.
|
|
188
|
+
({ toolStatus, callDiagnostics } = applyToolTelemetry(executorResult, actorName, actorId, callDiagnostics));
|
|
189
|
+
result = executorResult;
|
|
190
|
+
}
|
|
191
|
+
finally {
|
|
192
|
+
if (progressTracker) {
|
|
193
|
+
progressTracker.stop();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
default:
|
|
199
|
+
// Exhaustiveness guard mirroring getToolFullName: a new TOOL_TYPE member makes `tool`
|
|
200
|
+
// non-`never` here and fails `satisfies never` at compile time. Unreachable at runtime —
|
|
201
|
+
// ToolEntry is a closed 3-way union. Unlike the pre-extraction fall-through (which also
|
|
202
|
+
// listed available tools, called log.softFail, and sent a logging message before
|
|
203
|
+
// throwing), this just throws InvalidParams with no side effects.
|
|
204
|
+
throw new McpError(ErrorCode.InvalidParams, `Unknown tool type "${tool.type}"`);
|
|
205
|
+
}
|
|
206
|
+
return { result, toolStatus, callDiagnostics };
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=tool_dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool_dispatch.js","sourceRoot":"","sources":["../../src/mcp/tool_dispatch.ts"],"names":[],"mappings":"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"}
|