Skip to content

Commit b43361a

Browse files
authored
fix: code improvements (#91)
* cache Actor definition and real Actor ID API calls * better error handling and logging * Revert "cache Actor definition and real Actor ID API calls" This reverts commit aadbfa3.
1 parent 521cc8e commit b43361a

File tree

1 file changed

+45
-14
lines changed

1 file changed

+45
-14
lines changed

src/mcp/server.ts

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import type { Client } from '@modelcontextprotocol/sdk/client/index.js';
66
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
77
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
8-
import { CallToolRequestSchema, CallToolResultSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
8+
import { CallToolRequestSchema, CallToolResultSchema, ErrorCode, ListToolsRequestSchema, McpError } from '@modelcontextprotocol/sdk/types.js';
99
import type { ActorCallOptions } from 'apify-client';
1010

1111
import log from '@apify/log';
@@ -160,15 +160,14 @@ export class ActorsMcpServer {
160160
* @returns {object} - The response object containing the tools.
161161
*/
162162
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
163-
// TODO if there is actor-mcp as a tool, also list the tools from that Actor
164163
const tools = Array.from(this.tools.values()).map((tool) => (tool.tool));
165164
return { tools };
166165
});
167166

168167
/**
169168
* Handles the request to call a tool.
170169
* @param {object} request - The request object containing tool name and arguments.
171-
* @throws {Error} - Throws an error if the tool is unknown or arguments are invalid.
170+
* @throws {McpError} - based on the McpServer class code from the typescript MCP SDK
172171
*/
173172
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
174173
const { name, arguments: args } = request.params;
@@ -179,27 +178,47 @@ export class ActorsMcpServer {
179178

180179
// Validate token
181180
if (!apifyToken) {
182-
throw new Error('APIFY_TOKEN is required but not set in the environment variables or passed as a parameter.');
181+
const msg = 'APIFY_TOKEN is required. It must be set in the environment variables or passed as a parameter in the body.';
182+
log.error(msg);
183+
await this.server.sendLoggingMessage({ level: 'error', data: msg });
184+
throw new McpError(
185+
ErrorCode.InvalidParams,
186+
msg,
187+
);
183188
}
184189

185-
// TODO - log errors
186-
// TODO: handle errors better, server.sendLoggingMessage ( )
187-
// TODO - do not raise but return mcp errors
188190
// TODO - if connection is /mcp client will not receive notification on tool change
189191

190192
// Find tool by name or actor full name
191193
const tool = Array.from(this.tools.values())
192194
.find((t) => t.tool.name === name || (t.type === 'actor' && (t.tool as ActorTool).actorFullName === name));
193195
if (!tool) {
194-
await this.server.sendLoggingMessage({ level: 'info', data: `Unknown tool $\{name}, available tools ${this.getToolNames()}` });
195-
throw new Error(`Unknown tool: ${name}`);
196+
const msg = `Tool ${name} not found. Available tools: ${this.getToolNames().join(', ')}`;
197+
log.error(msg);
198+
await this.server.sendLoggingMessage({ level: 'error', data: msg });
199+
throw new McpError(
200+
ErrorCode.InvalidParams,
201+
msg,
202+
);
196203
}
197204
if (!args) {
198-
throw new Error(`Missing arguments for tool: ${name}`);
205+
const msg = `Missing arguments for tool ${name}`;
206+
log.error(msg);
207+
await this.server.sendLoggingMessage({ level: 'error', data: msg });
208+
throw new McpError(
209+
ErrorCode.InvalidParams,
210+
msg,
211+
);
199212
}
200213
log.info(`Validate arguments for tool: ${tool.tool.name} with arguments: ${JSON.stringify(args)}`);
201214
if (!tool.tool.ajvValidate(args)) {
202-
throw new Error(`Invalid arguments for tool ${tool.tool.name}: args: ${JSON.stringify(args)} error: ${JSON.stringify(tool?.tool.ajvValidate.errors)}`);
215+
const msg = `Invalid arguments for tool ${tool.tool.name}: args: ${JSON.stringify(args)} error: ${JSON.stringify(tool?.tool.ajvValidate.errors)}`;
216+
log.error(msg);
217+
await this.server.sendLoggingMessage({ level: 'error', data: msg });
218+
throw new McpError(
219+
ErrorCode.InvalidParams,
220+
msg,
221+
);
203222
}
204223

205224
try {
@@ -253,11 +272,23 @@ export class ActorsMcpServer {
253272
return { content };
254273
}
255274
} catch (error) {
256-
log.error(`Error calling tool: ${error}`);
257-
throw new Error(`Error calling tool: ${error}`);
275+
log.error(`Error calling tool ${name}: ${error}`);
276+
throw new McpError(
277+
ErrorCode.InternalError,
278+
`An error occurred while calling the tool.`,
279+
);
258280
}
259281

260-
throw new Error(`Tool ${name} is not implemented`);
282+
const msg = `Unknown tool: ${name}`;
283+
log.error(msg);
284+
await this.server.sendLoggingMessage({
285+
level: 'error',
286+
data: msg,
287+
});
288+
throw new McpError(
289+
ErrorCode.InvalidParams,
290+
msg,
291+
);
261292
});
262293
}
263294

0 commit comments

Comments
 (0)