@@ -6,6 +6,8 @@ import { HelperTools } from '../const.js';
66import type { InternalTool , ToolEntry } from '../types' ;
77import { getActorsAsTools } from './actor.js' ;
88import { actorNameToToolName } from './utils.js' ;
9+ import { ApifyApiError } from 'apify-client' ;
10+ import log from '@apify/log' ;
911
1012const ajv = new Ajv ( { coerceTypes : 'array' , strict : false } ) ;
1113
@@ -79,7 +81,32 @@ export const addTool: ToolEntry = {
7981 call : async ( toolArgs ) => {
8082 const { apifyMcpServer, mcpServer, apifyToken, args } = toolArgs ;
8183 const parsed = addToolArgsSchema . parse ( args ) ;
82- const tools = await getActorsAsTools ( [ parsed . actorName ] , apifyToken ) ;
84+ if ( ! parsed . actorName || typeof parsed . actorName !== 'string' || parsed . actorName . trim ( ) === '' ) {
85+ return { content : [ { type : 'text' , text : 'Actor name is required.' } ] } ;
86+ }
87+ if ( apifyMcpServer . listAllToolNames ( ) . includes ( parsed . actorName ) ) {
88+ return {
89+ content : [ {
90+ type : 'text' ,
91+ text : `Actor ${ parsed . actorName } is already available. No new tools were added.` ,
92+ } ] ,
93+ } ;
94+ }
95+ let tools ;
96+ try {
97+ tools = await getActorsAsTools ( [ parsed . actorName ] , apifyToken ) ;
98+ } catch ( error ) {
99+ if ( error instanceof ApifyApiError ) {
100+ log . error ( `[addTool] Failed to add Actor ${ parsed . actorName } : ${ error . message } ` ) ;
101+ return {
102+ content : [ {
103+ type : 'text' ,
104+ text : `Failed to add Actor ${ parsed . actorName } . Error: ${ error . message } ` ,
105+ } ] ,
106+ } ;
107+ }
108+ throw error ;
109+ }
83110 const toolsAdded = apifyMcpServer . upsertTools ( tools , true ) ;
84111 await mcpServer . notification ( { method : 'notifications/tools/list_changed' } ) ;
85112
@@ -112,8 +139,19 @@ export const removeTool: ToolEntry = {
112139 // TODO: I don't like that we are passing apifyMcpServer and mcpServer to the tool
113140 call : async ( toolArgs ) => {
114141 const { apifyMcpServer, mcpServer, args } = toolArgs ;
115-
116142 const parsed = removeToolArgsSchema . parse ( args ) ;
143+ // Check if tool exists before attempting removal
144+ if ( ! apifyMcpServer . tools . has ( parsed . toolName ) ) {
145+ // Send notification so client can update its tool list
146+ // just in case the client tool list is out of sync
147+ await mcpServer . notification ( { method : 'notifications/tools/list_changed' } ) ;
148+ return {
149+ content : [ {
150+ type : 'text' ,
151+ text : `Tool '${ args . toolName } ' not found. No tools were removed.` ,
152+ } ] ,
153+ } ;
154+ }
117155 const removedTools = apifyMcpServer . removeToolsByName ( [ parsed . toolName ] , true ) ;
118156 await mcpServer . notification ( { method : 'notifications/tools/list_changed' } ) ;
119157 return { content : [ { type : 'text' , text : `Tools removed: ${ removedTools . join ( ', ' ) } ` } ] } ;
0 commit comments