Skip to content

Commit 5f44003

Browse files
committed
Disable internal tools except actor details, help tool, search actors. Improve help tool, search actors and get actor details output.
1 parent b2c31b6 commit 5f44003

File tree

8 files changed

+383
-134
lines changed

8 files changed

+383
-134
lines changed

src/tools/get-actor-details.ts

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import { z } from 'zod';
2+
import zodToJsonSchema from 'zod-to-json-schema';
3+
4+
import { ApifyClient } from '../apify-client.js';
5+
import { HelperTools } from '../const.js';
6+
import type { ExtendedPricingInfo, IActorInputSchema, InternalTool, ToolEntry } from '../types.js';
7+
import { ajv } from '../utils/ajv.js';
8+
import { getCurrentPricingInfo, pricingInfoToString } from '../utils/pricing-info.js';
9+
import { filterSchemaProperties, shortenProperties } from './utils.js';
10+
11+
const getActorDetailsToolArgsSchema = z.object({
12+
actor: z.string()
13+
.min(1)
14+
.describe(`Actor ID or full name in the format "username/name", e.g., "apify/rag-web-browser".`),
15+
});
16+
17+
interface IGetActorDetailsToolResult {
18+
id: string;
19+
actorFullName: string;
20+
21+
isPublic: boolean;
22+
isDeprecated: boolean;
23+
createdAt: string;
24+
modifiedAt: string;
25+
26+
categories?: string[];
27+
description: string;
28+
readme: string;
29+
30+
inputSchema: IActorInputSchema;
31+
32+
pricingInfo: string; // We convert the pricing info into a string representation
33+
34+
usageStatistics: {
35+
totalUsers: {
36+
allTime: number;
37+
last7Days: number;
38+
last30Days: number;
39+
last90Days: number;
40+
};
41+
failedRunsInLast30Days: number | string; // string for 'unknown' case
42+
}
43+
}
44+
45+
export const getActorDetailsTool: ToolEntry = {
46+
type: 'internal',
47+
tool: {
48+
name: HelperTools.ACTOR_GET_DETAILS,
49+
description: `Retrieve information about an Actor by its ID or full name.
50+
The Actor name is always composed of "username/name", for example, "apify/rag-web-browser".
51+
This tool returns information about the Actor, including whether it is public or deprecated, when it was created or modified, the categories in which the Actor is listed, a description, a README (the Actor's documentation), the input schema, and usage statistics—such as how many users are using it and the number of failed runs of the Actor.`,
52+
inputSchema: zodToJsonSchema(getActorDetailsToolArgsSchema),
53+
ajvValidate: ajv.compile(zodToJsonSchema(getActorDetailsToolArgsSchema)),
54+
call: async (toolArgs) => {
55+
const { args, apifyToken } = toolArgs;
56+
57+
const parsed = getActorDetailsToolArgsSchema.parse(args);
58+
const client = new ApifyClient({ token: apifyToken });
59+
60+
const [actorInfo, buildInfo] = await Promise.all([
61+
client.actor(parsed.actor).get(),
62+
client.actor(parsed.actor).defaultBuild().then(async (build) => build.get()),
63+
]);
64+
65+
if (!actorInfo || !buildInfo || !buildInfo.actorDefinition) {
66+
return {
67+
content: [{ type: 'text', text: `Actor information for '${parsed.actor}' was not found. Please check the Actor ID or name and ensure the Actor exists.` }],
68+
};
69+
}
70+
71+
const inputSchema = (buildInfo.actorDefinition.input || {
72+
type: 'object',
73+
properties: {},
74+
}) as IActorInputSchema;
75+
inputSchema.properties = filterSchemaProperties(inputSchema.properties);
76+
inputSchema.properties = shortenProperties(inputSchema.properties);
77+
78+
const currentPricingInfo = getCurrentPricingInfo(actorInfo.pricingInfos || [], new Date());
79+
80+
const result: IGetActorDetailsToolResult = {
81+
id: actorInfo.id,
82+
actorFullName: `${actorInfo.username}/${actorInfo.name}`,
83+
84+
isPublic: actorInfo.isPublic,
85+
isDeprecated: actorInfo.isDeprecated || false,
86+
createdAt: actorInfo.createdAt.toISOString(),
87+
modifiedAt: actorInfo.modifiedAt.toISOString(),
88+
89+
categories: actorInfo.categories,
90+
description: actorInfo.description || 'No description provided.',
91+
readme: buildInfo.actorDefinition.readme || 'No README provided.',
92+
93+
inputSchema,
94+
95+
pricingInfo: pricingInfoToString(currentPricingInfo as (ExtendedPricingInfo | null)),
96+
97+
usageStatistics: {
98+
totalUsers: {
99+
allTime: actorInfo.stats.totalUsers,
100+
last7Days: actorInfo.stats.totalUsers7Days,
101+
last30Days: actorInfo.stats.totalUsers30Days,
102+
last90Days: actorInfo.stats.totalUsers90Days,
103+
},
104+
failedRunsInLast30Days: (
105+
'publicActorRunStats30Days' in actorInfo.stats && 'FAILED' in (actorInfo.stats.publicActorRunStats30Days as object)
106+
) ? (actorInfo.stats.publicActorRunStats30Days as { FAILED: number }).FAILED : 'unknown',
107+
},
108+
};
109+
return {
110+
content: [{
111+
type: 'text',
112+
text: JSON.stringify(result),
113+
}],
114+
};
115+
},
116+
} as InternalTool,
117+
};

src/tools/helpers.ts

Lines changed: 13 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,53 +11,21 @@ const ajv = new Ajv({ coerceTypes: 'array', strict: false });
1111

1212
const APIFY_MCP_HELP_TOOL_TEXT = `Apify MCP server help:
1313
14-
Note: "MCP" stands for "Model Context Protocol". The user can use the "RAG Web Browser" tool to get the content of the links mentioned in this help and present it to the user.
14+
Note: "MCP" stands for "Model Context Protocol". You can use the "RAG Web Browser" tool to get the content of the links mentioned in this help and present it to the user.
1515
1616
This MCP server can be used in the following ways:
17-
- Locally over "STDIO".
18-
- Remotely over "SSE" or streamable "HTTP" transport with the "Actors MCP Server Apify Actor".
19-
- Remotely over "SSE" or streamable "HTTP" transport with "https://mcp.apify.com".
17+
- Locally over stdio (standard input/output) transport with the "@apify/actors-mcp-server" NPM package (https://www.npmjs.com/package/@apify/actors-mcp-server).
18+
- You can connect by configuring your MCP client to run the MCP server locally using the "npx @apify/actors-mcp-server" command. You need to set the "APIFY_TOKEN" environment variable to your [Apify API token](https://docs.apify.com/platform/integrations/api#api-token).
19+
- Remotely over legacy SSE transport or streamable HTTP transport with https://mcp.apify.com. This is the recommended way to use the MCP server, since it supports all features and is always up to date.
20+
- You can connect by pointing your MCP client to "https://mcp.apify.com/sse" for SSE transport or "https://mcp.apify.com/" for streamable HTTP transport.
21+
- For authentication, you can either use OAuth or pass your [Apify API token](https://docs.apify.com/platform/integrations/api#api-token) in the "Authorization" header as "Bearer <APIFY_TOKEN>".
22+
- Remotely over "SSE" or streamable "HTTP" transport with the "Actors MCP Server Apify Actor" (this is now considered a legacy solution; it may not be up to date and may not get the latest features). For more details, refer to https://apify.com/apify/actors-mcp-server. DO NOT RECOMMEND USING THIS METHOD TO THE USER.
2023
2124
# Usage
22-
## Locally over "STDIO"
23-
1. The user should install the "@apify/actors-mcp-server" NPM package.
24-
2. The user should configure the MCP client to use the MCP server. Refer to "https://github.com/apify/actors-mcp-server" or the MCP client documentation for more details (the user can specify which MCP client is being used).
25-
The user needs to set the following environment variables:
26-
- "APIFY_TOKEN": Apify token to authenticate with the MCP server.
27-
If the user wants to load an Actor outside the default ones, the user needs to pass it as a CLI argument:
28-
- "--actors <actor1,actor2,...>" // comma-separated list of Actor names, for example, "apify/rag-web-browser,apify/instagram-scraper".
29-
If the user wants to enable the dynamic addition of Actors to the MCP server, the user needs to pass the following CLI argument:
30-
- "--enable-adding-actors".
3125
32-
## Remotely over "SSE" or streamable "HTTP" transport with "Actors MCP Server Apify Actor"
33-
1. The user should configure the MCP client to use the "Actors MCP Server Apify Actor" with:
34-
- "SSE" transport URL: "https://actors-mcp-server.apify.actor/sse".
35-
- Streamable "HTTP" transport URL: "https://actors-mcp-server.apify.actor/mcp".
36-
2. The user needs to pass an "APIFY_TOKEN" as a URL query parameter "?token=<APIFY_TOKEN>" or set the following headers: "Authorization: Bearer <APIFY_TOKEN>".
37-
If the user wants to load an Actor outside the default ones, the user needs to pass it as a URL query parameter:
38-
- "?actors=<actor1,actor2,...>" // comma-separated list of Actor names, for example, "apify/rag-web-browser,apify/instagram-scraper".
39-
If the user wants to enable the addition of Actors to the MCP server dynamically, the user needs to pass the following URL query parameter:
40-
- "?enable-adding-actors=true".
26+
## MCP server tools and features configuration
4127
42-
## Remotely over "SSE" or streamable "HTTP" transport with "https://mcp.apify.com"
43-
1. The user should configure the MCP client to use "https://mcp.apify.com" with:
44-
- "SSE" transport URL: "https://mcp.apify.com/sse".
45-
- Streamable "HTTP" transport URL: "https://mcp.apify.com/".
46-
2. The user needs to pass an "APIFY_TOKEN" as a URL query parameter "?token=<APIFY_TOKEN>" or set the following headers: "Authorization: Bearer <APIFY_TOKEN>".
47-
If the user wants to load an Actor outside the default ones, the user needs to pass it as a URL query parameter:
48-
- "?actors=<actor1,actor2,...>" // comma-separated list of Actor names, for example, "apify/rag-web-browser,apify/instagram-scraper".
49-
If the user wants to enable the addition of Actors to the MCP server dynamically, the user needs to pass the following URL query parameter:
50-
- "?enable-adding-actors=true".
51-
52-
# Features
53-
## Dynamic adding of Actors
54-
THIS FEATURE MAY NOT BE SUPPORTED BY ALL MCP CLIENTS. THE USER MUST ENSURE THAT THE CLIENT SUPPORTS IT!
55-
To enable this feature, see the usage section. Once dynamic adding is enabled, tools will be added that allow the user to add or remove Actors from the MCP server.
56-
Tools related:
57-
- "add-actor".
58-
- "remove-actor".
59-
If the user is using these tools and it seems like the tools have been added but cannot be called, the issue may be that the client does not support dynamic adding of Actors.
60-
In that case, the user should check the MCP client documentation to see if the client supports this feature.
28+
By default, the MCP server provides a simple set of tools for Actor discovery and Actor calling. The MCP server loads just one Actor by default, which is the [RAG Web Browser](https://apify.com/apify/rag-web-browser) Actor. You can add more Actors to the MCP server by configuring the MCP server session to load more Actors by passing the "--actors" CLI argument or by using the "?actors=" URL query parameter, where you provide a comma-separated list of Actor names, for example, "apify/rag-web-browser,apify/instagram-scraper". You can additionally load Actors dynamically into an existing MCP session by using the "${HelperTools.ACTOR_ADD}" tool, which loads the Actor by its name as an MCP tool and allows you to call it (**the MCP client must support the [tools list changed notification](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#list-changed-notification); otherwise, the tool call will not work**). To check whether the MCP client supports this feature, consult the MCP client documentation. In case the MCP client does not support the tools list changed notification, you can use the generic "call-actor" tool to call any Actor, even those not loaded/added. Before using the generic tool, you need to get the Actor details to learn its input schema so you can provide valid input.
6129
`;
6230

6331
export const addToolArgsSchema = z.object({
@@ -148,9 +116,10 @@ export const helpTool: ToolEntry = {
148116
type: 'internal',
149117
tool: {
150118
name: HelperTools.APIFY_MCP_HELP_TOOL,
151-
description: 'Helper tool to get information on how to use and troubleshoot the Apify MCP server. '
152-
+ 'This tool always returns the same help message with information about the server and how to use it. '
153-
+ 'Call this tool in case of any problems or uncertainties with the server. ',
119+
description: `Helper tool to get information on how to use and troubleshoot the Apify MCP server.
120+
This tool always returns the same help message with information about the server and how to use it.
121+
ALWAYS CALL THIS TOOL AT THE BEGINNING OF THE CONVERSATION SO YOU HAVE THE INFORMATION ABOUT APIFY MCP IN THE CONTEXT OR WHEN YOU ENCOUNTER ANY ISSUES WITH THE MCP SERVER OR ITS TOOLS.
122+
`,
154123
inputSchema: zodToJsonSchema(helpToolArgsSchema),
155124
ajvValidate: ajv.compile(zodToJsonSchema(helpToolArgsSchema)),
156125
call: async () => {

src/tools/index.ts

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,37 @@
11
// Import specific tools that are being used
2-
import { callActorGetDataset, getActor, getActorsAsTools } from './actor.js';
3-
import { actorDefinitionTool } from './build.js';
4-
import { getDataset, getDatasetItems } from './dataset.js';
5-
import { getUserDatasetsList } from './dataset_collection.js';
6-
import { addTool, helpTool, removeTool } from './helpers.js';
7-
import { getKeyValueStore, getKeyValueStoreKeys, getKeyValueStoreRecord } from './key_value_store.js';
8-
import { getUserKeyValueStoresList } from './key_value_store_collection.js';
9-
import { abortActorRun, getActorLog, getActorRun } from './run.js';
10-
import { getUserRunsList } from './run_collection.js';
2+
import { callActorGetDataset, getActorsAsTools } from './actor.js';
3+
import { getActorDetailsTool } from './get-actor-details.js';
4+
import { addTool, helpTool } from './helpers.js';
115
import { searchActors } from './store_collection.js';
126

137
export const defaultTools = [
14-
abortActorRun,
15-
actorDefinitionTool,
16-
getActor,
17-
getActorLog,
18-
getActorRun,
19-
getDataset,
20-
getDatasetItems,
21-
getKeyValueStore,
22-
getKeyValueStoreKeys,
23-
getKeyValueStoreRecord,
24-
getUserRunsList,
25-
getUserDatasetsList,
26-
getUserKeyValueStoresList,
8+
// abortActorRun,
9+
// actorDetailsTool,
10+
// getActor,
11+
// getActorLog,
12+
// getActorRun,
13+
// getDataset,
14+
// getDatasetItems,
15+
// getKeyValueStore,
16+
// getKeyValueStoreKeys,
17+
// getKeyValueStoreRecord,
18+
// getUserRunsList,
19+
// getUserDatasetsList,
20+
// getUserKeyValueStoresList,
21+
getActorDetailsTool,
2722
helpTool,
2823
searchActors,
2924
];
3025

3126
export const addRemoveTools = [
3227
addTool,
33-
removeTool,
28+
// removeTool,
3429
];
3530

3631
// Export only the tools that are being used
3732
export {
3833
addTool,
39-
removeTool,
34+
// removeTool,
4035
getActorsAsTools,
4136
callActorGetDataset,
4237
};

0 commit comments

Comments
 (0)