Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ The server provides a set of helper tools to discover available Actors and retri

There are also tools to manage the available tools list. However, dynamically adding and removing tools requires the MCP client to have the capability to manage the tools list, which is typically not supported.

You can try this functionality using the [Apify Tester MCP Client](https://apify.com/jiri.spilka/tester-mcp-client) Actor. To enable it, set the `enableActorAutoLoading` parameter.
You can try this functionality using the [Apify Tester MCP Client](https://apify.com/jiri.spilka/tester-mcp-client) Actor.
To enable it, set the `enableActorAutoLoading` parameter.

- `add-actor-as-tool`: Adds an Actor by name to the available tools list without executing it, requiring user consent to run later.
- `remove-actor-from-tool`: Removes an Actor by name from the available tools list when it's no longer needed.
Expand Down Expand Up @@ -206,7 +207,6 @@ Alternatively, you can use simple python [client_see.py](https://github.com/apif

### Install

Follow the steps below to set up and run the server on your local machine:
First, clone the repository using the following command:

```bash
Expand Down
9 changes: 2 additions & 7 deletions src/actors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@ import { ApifyClient } from 'apify-client';

import { ACTOR_ADDITIONAL_INSTRUCTIONS, defaults, MAX_DESCRIPTION_LENGTH } from './const.js';
import { log } from './logger.js';
import type {
ActorDefinitionPruned,
ActorDefinitionWithDesc,
SchemaProperties,
Tool,
} from './types.js';
import type { ActorDefinitionPruned, ActorDefinitionWithDesc, SchemaProperties, Tool } from './types.js';

export function actorNameToToolName(actorName: string): string {
return actorName.replace('/', '--');
Expand Down Expand Up @@ -59,7 +54,7 @@ export async function getActorDefinition(actorFullName: string): Promise<ActorDe
return null;
} catch (error) {
log.error(`Failed to fetch input schema for actor: ${actorFullName} with error ${error}.`);
return null;
throw new Error(`Failed to fetch input schema for actor: ${actorFullName} with error ${error}.`);
}
}

Expand Down
8 changes: 5 additions & 3 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ async function processParamsAndUpdateTools(url: string) {
const input = await processInput(params as unknown as Input);
if (input.actors) {
await mcpServer.addToolsFromActors(input.actors as string[]);
} else {
log.debug(`Server is running in STANDBY mode with the following Actors (tools): ${mcpServer.getToolNames()}.
To use different Actors, provide them in query parameter "actors" or include them in the Actor Task input.`);
}
if (input.enableActorAutoLoading) {
mcpServer.updateTools(getActorAutoLoadingTools());
}
log.debug(`Server is running in STANDBY mode with the following Actors (tools): ${mcpServer.getToolNames()}.
To use different Actors, provide them in query parameter "actors" or include them in the Actor Task input.`);
}

app.route(Routes.ROOT)
Expand Down
4 changes: 2 additions & 2 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,12 @@ export class ApifyMcpServer {
case InternalTools.ADD_ACTOR_TO_TOOLS: {
const parsed = AddActorToToolsArgsSchema.parse(args);
await this.addToolsFromActors([parsed.actorFullName]);
return { content: [{ type: 'text', text: `Actor ${args.name} was added to tools` }] };
return { content: [{ type: 'text', text: `Actor ${parsed.actorFullName} was added to tools` }] };
}
case InternalTools.REMOVE_ACTOR_FROM_TOOLS: {
const parsed = RemoveActorToolArgsSchema.parse(args);
this.tools.delete(parsed.toolName);
return { content: [{ type: 'text', text: `Actor ${args.name} was removed from tools` }] };
return { content: [{ type: 'text', text: `Tool ${parsed.toolName} was removed` }] };
}
case InternalTools.DISCOVER_ACTORS: {
const parsed = DiscoverActorsArgsSchema.parse(args);
Expand Down
6 changes: 3 additions & 3 deletions src/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ApifyClient } from 'apify-client';
import { z } from 'zod';
import { zodToJsonSchema } from 'zod-to-json-schema';

import { actorNameToToolName, toolNameToActorName } from './actors.js';
import { toolNameToActorName } from './actors.js';
import { InternalTools } from './const.js';
import type { ActorStorePruned, PricingInfo, Tool } from './types.js';

Expand Down Expand Up @@ -35,14 +35,14 @@ export const RemoveActorToolArgsSchema = z.object({
toolName: z.string()
.describe('Full name of the Actor to remove. Actor full name is always composed from `username--name`'
+ 'Never use name or username only')
.transform((val) => actorNameToToolName(val)),
.transform((val) => toolNameToActorName(val)),
});

export const AddActorToToolsArgsSchema = z.object({
actorFullName: z.string()
.describe('Full name of the Actor to add as tool. Tool name is always composed from `username--name`'
+ 'Never use name or username only')
.transform((val) => actorNameToToolName(val)),
.transform((val) => toolNameToActorName(val)),
});

export const GetActorDefinition = z.object({
Expand Down
Loading