55import type { Client } from '@modelcontextprotocol/sdk/client/index.js' ;
66import { Server } from '@modelcontextprotocol/sdk/server/index.js' ;
77import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js' ;
8- import { CallToolRequestSchema , ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js' ;
8+ import { CallToolRequestSchema , ErrorCode , ListToolsRequestSchema , McpError } from '@modelcontextprotocol/sdk/types.js' ;
99import type { ActorCallOptions } from 'apify-client' ;
1010
1111import log from '@apify/log' ;
@@ -116,15 +116,14 @@ export class ActorsMcpServer {
116116 * @returns {object } - The response object containing the tools.
117117 */
118118 this . server . setRequestHandler ( ListToolsRequestSchema , async ( ) => {
119- // TODO if there is actor-mcp as a tool, also list the tools from that Actor
120119 const tools = Array . from ( this . tools . values ( ) ) . map ( ( tool ) => ( tool . tool ) ) ;
121120 return { tools } ;
122121 } ) ;
123122
124123 /**
125124 * Handles the request to call a tool.
126125 * @param {object } request - The request object containing tool name and arguments.
127- * @throws {Error } - Throws an error if the tool is unknown or arguments are invalid.
126+ * @throws {McpError } - based on the McpServer class code from the typescript MCP SDK
128127 */
129128 this . server . setRequestHandler ( CallToolRequestSchema , async ( request ) => {
130129 const { name, arguments : args } = request . params ;
@@ -135,27 +134,47 @@ export class ActorsMcpServer {
135134
136135 // Validate token
137136 if ( ! apifyToken ) {
138- throw new Error ( 'APIFY_TOKEN is required but not set in the environment variables or passed as a parameter.' ) ;
137+ const msg = 'APIFY_TOKEN is required. It must be set in the environment variables or passed as a parameter in the body.' ;
138+ log . error ( msg ) ;
139+ await this . server . sendLoggingMessage ( { level : 'error' , data : msg } ) ;
140+ throw new McpError (
141+ ErrorCode . InvalidParams ,
142+ msg ,
143+ ) ;
139144 }
140145
141- // TODO - log errors
142- // TODO: handle errors better, server.sendLoggingMessage ( )
143- // TODO - do not raise but return mcp errors
144146 // TODO - if connection is /mcp client will not receive notification on tool change
145147
146148 // Find tool by name or actor full name
147149 const tool = Array . from ( this . tools . values ( ) )
148150 . find ( ( t ) => t . tool . name === name || ( t . type === 'actor' && ( t . tool as ActorTool ) . actorFullName === name ) ) ;
149151 if ( ! tool ) {
150- await this . server . sendLoggingMessage ( { level : 'info' , data : `Unknown tool $\{name}, available tools ${ this . getToolNames ( ) } ` } ) ;
151- throw new Error ( `Unknown tool: ${ name } ` ) ;
152+ const msg = `Tool ${ name } not found. Available tools: ${ this . getToolNames ( ) . join ( ', ' ) } ` ;
153+ log . error ( msg ) ;
154+ await this . server . sendLoggingMessage ( { level : 'error' , data : msg } ) ;
155+ throw new McpError (
156+ ErrorCode . InvalidParams ,
157+ msg ,
158+ ) ;
152159 }
153160 if ( ! args ) {
154- throw new Error ( `Missing arguments for tool: ${ name } ` ) ;
161+ const msg = `Missing arguments for tool ${ name } ` ;
162+ log . error ( msg ) ;
163+ await this . server . sendLoggingMessage ( { level : 'error' , data : msg } ) ;
164+ throw new McpError (
165+ ErrorCode . InvalidParams ,
166+ msg ,
167+ ) ;
155168 }
156169 log . info ( `Validate arguments for tool: ${ tool . tool . name } with arguments: ${ JSON . stringify ( args ) } ` ) ;
157170 if ( ! tool . tool . ajvValidate ( args ) ) {
158- throw new Error ( `Invalid arguments for tool ${ tool . tool . name } : args: ${ JSON . stringify ( args ) } error: ${ JSON . stringify ( tool ?. tool . ajvValidate . errors ) } ` ) ;
171+ const msg = `Invalid arguments for tool ${ tool . tool . name } : args: ${ JSON . stringify ( args ) } error: ${ JSON . stringify ( tool ?. tool . ajvValidate . errors ) } ` ;
172+ log . error ( msg ) ;
173+ await this . server . sendLoggingMessage ( { level : 'error' , data : msg } ) ;
174+ throw new McpError (
175+ ErrorCode . InvalidParams ,
176+ msg ,
177+ ) ;
159178 }
160179
161180 try {
@@ -207,11 +226,23 @@ export class ActorsMcpServer {
207226 return { content } ;
208227 }
209228 } catch ( error ) {
210- log . error ( `Error calling tool: ${ error } ` ) ;
211- throw new Error ( `Error calling tool: ${ error } ` ) ;
229+ log . error ( `Error calling tool ${ name } : ${ error } ` ) ;
230+ throw new McpError (
231+ ErrorCode . InternalError ,
232+ `An error occurred while calling the tool.` ,
233+ ) ;
212234 }
213235
214- throw new Error ( `Tool ${ name } is not implemented` ) ;
236+ const msg = `Unknown tool: ${ name } ` ;
237+ log . error ( msg ) ;
238+ await this . server . sendLoggingMessage ( {
239+ level : 'error' ,
240+ data : msg ,
241+ } ) ;
242+ throw new McpError (
243+ ErrorCode . InvalidParams ,
244+ msg ,
245+ ) ;
215246 } ) ;
216247 }
217248
0 commit comments