diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c6c05d0..ee1cfe89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -205,4 +205,4 @@ All notable changes to this project will be documented in this file. ### 🐛 Bug Fixes - Update express routes to correctly handle GET and HEAD requests, fix CI ([#5](https://github.com/apify/actors-mcp-server/pull/5)) ([ec6e9b0](https://github.com/apify/actors-mcp-server/commit/ec6e9b0a4657f673b3650a5906fe00e66411d7f1)) by [@jirispilka](https://github.com/jirispilka) -- Correct publishing of npm module ([#6](https://github.com/apify/actors-mcp-server/pull/6)) ([4c953e9](https://github.com/apify/actors-mcp-server/commit/4c953e9fe0c735f1690c8356884dd78d8608979f)) by [@jirispilka](https://github.com/jirispilka) \ No newline at end of file +- Correct publishing of npm module ([#6](https://github.com/apify/actors-mcp-server/pull/6)) ([4c953e9](https://github.com/apify/actors-mcp-server/commit/4c953e9fe0c735f1690c8356884dd78d8608979f)) by [@jirispilka](https://github.com/jirispilka) diff --git a/src/main.ts b/src/main.ts index d98fe312..e314b873 100644 --- a/src/main.ts +++ b/src/main.ts @@ -11,14 +11,7 @@ import log from '@apify/log'; import { createExpressApp } from './actor/server.js'; import { processInput } from './input.js'; import { ActorsMcpServer } from './mcp/server.js'; -import { - actorDefinitionTool, - addTool, - callActorGetDataset, - getActorsAsTools, - removeTool, - searchTool, -} from './tools/index.js'; +import { callActorGetDataset, getActorsAsTools } from './tools/index.js'; import type { Input } from './types.js'; const STANDBY_MODE = Actor.getEnv().metaOrigin === 'STANDBY'; @@ -33,25 +26,26 @@ if (!process.env.APIFY_TOKEN) { process.exit(1); } -const mcpServer = new ActorsMcpServer(); - const input = processInput((await Actor.getInput>()) ?? ({} as Input)); log.info(`Loaded input: ${JSON.stringify(input)} `); if (STANDBY_MODE) { + const mcpServer = new ActorsMcpServer({ + enableAddingActors: Boolean(input.enableAddingActors), + enableDefaultActors: false, + }); + const app = createExpressApp(HOST, mcpServer); log.info('Actor is running in the STANDBY mode.'); - // Do not load default Actors here, for mastra.ai template we need to start without default Actors - const tools = [searchTool, actorDefinitionTool]; - if (input.enableAddingActors) { - tools.push(addTool, removeTool); - } + + // Load only Actors specified in the input + // If you wish to start without any Actor, create a task and leave the input empty if (input.actors && input.actors.length > 0) { const { actors } = input; const actorsToLoad = Array.isArray(actors) ? actors : actors.split(','); - tools.push(...await getActorsAsTools(actorsToLoad, process.env.APIFY_TOKEN as string)); + const tools = await getActorsAsTools(actorsToLoad, process.env.APIFY_TOKEN as string); + mcpServer.updateTools(tools); } - mcpServer.updateTools(tools); app.listen(PORT, () => { log.info(`The Actor web server is listening for user requests at ${HOST}`); }); diff --git a/src/mcp/server.ts b/src/mcp/server.ts index c0ed87d2..8e1e6633 100644 --- a/src/mcp/server.ts +++ b/src/mcp/server.ts @@ -17,20 +17,37 @@ import { SERVER_NAME, SERVER_VERSION, } from '../const.js'; -import { actorDefinitionTool, callActorGetDataset, getActorsAsTools, searchTool } from '../tools/index.js'; +import { + actorDefinitionTool, + addTool, + callActorGetDataset, + getActorsAsTools, + removeTool, + searchTool, +} from '../tools/index.js'; import { actorNameToToolName } from '../tools/utils.js'; import type { ActorMCPTool, ActorTool, HelperTool, ToolWrap } from '../types.js'; import { createMCPClient } from './client.js'; import { processParamsGetTools } from './utils.js'; +type ActorsMcpServerOptions = { + enableAddingActors?: boolean; + enableDefaultActors?: boolean; +}; + /** * Create Apify MCP server */ export class ActorsMcpServer { public readonly server: Server; public readonly tools: Map; + private readonly options: ActorsMcpServerOptions; - constructor() { + constructor(options: ActorsMcpServerOptions = {}) { + this.options = { + enableAddingActors: options.enableAddingActors ?? false, + enableDefaultActors: options.enableDefaultActors ?? true, // Default to true for backward compatibility + }; this.server = new Server( { name: SERVER_NAME, @@ -49,10 +66,29 @@ export class ActorsMcpServer { // Add default tools this.updateTools([searchTool, actorDefinitionTool]); + + // Add tools to dynamically load Actors + if (this.options.enableAddingActors) { + this.loadToolsToAddActors(); + } + + // Initialize automatically for backward compatibility + this.initialize().catch((error) => { + log.error('Failed to initialize server:', error); + }); + } + + /** + * Initialize the server with default tools if enabled + */ + public async initialize(): Promise { + if (this.options.enableDefaultActors) { + await this.loadDefaultTools(process.env.APIFY_TOKEN as string); + } } /** - * Loads missing default tools. + * Loads default tools if not already loaded. */ public async loadDefaultTools(apifyToken: string) { const missingDefaultTools = defaults.actors.filter((name) => !this.tools.has(actorNameToToolName(name))); @@ -78,6 +114,13 @@ export class ActorsMcpServer { } } + /** + * Add Actors to server dynamically + */ + public loadToolsToAddActors() { + this.updateTools([addTool, removeTool]); + } + /** * Upsert new tools. * @param tools - Array of tool wrappers. diff --git a/src/stdio.ts b/src/stdio.ts index 587a919a..40c5a58e 100644 --- a/src/stdio.ts +++ b/src/stdio.ts @@ -19,7 +19,7 @@ import log from '@apify/log'; import { defaults } from './const.js'; import { ActorsMcpServer } from './mcp/server.js'; -import { addTool, getActorsAsTools, removeTool } from './tools/index.js'; +import { getActorsAsTools } from './tools/index.js'; // Configure logging, set to ERROR log.setLevel(log.LEVELS.ERROR); @@ -36,7 +36,8 @@ const argv = parser(process.argv.slice(2), { 'enable-adding-actors': false, }, }); -const { actors = '', enableActorAutoLoading = false } = argv; +const enableAddingActors = argv['enable-adding-actors'] || argv.enableActorAutoLoading || false; +const { actors = '' } = argv; const actorList = actors ? actors.split(',').map((a: string) => a.trim()) : []; // Validate environment @@ -46,12 +47,8 @@ if (!process.env.APIFY_TOKEN) { } async function main() { - const mcpServer = new ActorsMcpServer(); - // Initialize tools + const mcpServer = new ActorsMcpServer({ enableAddingActors, enableDefaultActors: false }); const tools = await getActorsAsTools(actorList.length ? actorList : defaults.actors, process.env.APIFY_TOKEN as string); - if (enableActorAutoLoading) { - tools.push(addTool, removeTool); - } mcpServer.updateTools(tools); // Start server