Skip to content

Commit 8add54c

Browse files
authored
fix: deprecate enableActorAutoLoading in favor of enable-adding-actors, and load tools only if not provided in query parameter (#63)
* fix: replace minimist with yargs-parser, deprecate enableActorAutoLoading in favor of enable-adding-actors, and load tools only if not provided in query parameter
1 parent 6c488dd commit 8add54c

File tree

9 files changed

+170
-79
lines changed

9 files changed

+170
-79
lines changed

.actor/input_schema.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,14 @@
1515
]
1616
},
1717
"enableActorAutoLoading": {
18-
"title": "Enable automatic loading of Actors based on context and use-case (experimental, check if it supported by your client)",
18+
"title": "Enable automatic loading of Actors based on context and use-case (experimental, check if it supported by your client) (deprecated, use enableAddingActors instead)",
19+
"type": "boolean",
20+
"description": "When enabled, the server can dynamically add Actors as tools based on user requests and context. \n\nNote: MCP client must support notification on tool updates. To try it, you can use the [Tester MCP Client](https://apify.com/jiri.spilka/tester-mcp-client). This is an experimental feature and may require client-specific support.",
21+
"default": false,
22+
"editor": "hidden"
23+
},
24+
"enableAddingActors": {
25+
"title": "Enable adding Actors based on context and use-case (experimental, check if it supported by your client)",
1926
"type": "boolean",
2027
"description": "When enabled, the server can dynamically add Actors as tools based on user requests and context. \n\nNote: MCP client must support notification on tool updates. To try it, you can use the [Tester MCP Client](https://apify.com/jiri.spilka/tester-mcp-client). This is an experimental feature and may require client-specific support.",
2128
"default": false

README.md

Lines changed: 61 additions & 63 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 18 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"apify": "^3.2.6",
3636
"apify-client": "^2.11.2",
3737
"express": "^4.21.2",
38-
"minimist": "^1.2.8",
38+
"yargs-parser": "^21.1.1",
3939
"zod": "^3.24.1",
4040
"zod-to-json-schema": "^3.24.1"
4141
},
@@ -46,6 +46,7 @@
4646
"@apify/tsconfig": "^0.1.0",
4747
"@types/express": "^4.0.0",
4848
"@types/minimist": "^1.2.5",
49+
"@types/yargs-parser": "^21.0.3",
4950
"dotenv": "^16.4.7",
5051
"eslint": "^9.17.0",
5152
"eventsource": "^3.0.2",

src/index.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,27 @@
1313
*/
1414

1515
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
16-
import minimist from 'minimist';
16+
import parser from 'yargs-parser';
1717

1818
import { log } from './logger.js';
1919
import { ApifyMcpServer } from './server.js';
2020
import { getActorDiscoveryTools, getActorAutoLoadingTools } from './tools.js';
2121

2222
log.setLevel(log.LEVELS.ERROR);
2323

24-
const argv = minimist(process.argv.slice(2));
24+
const argv = parser(process.argv.slice(2), {
25+
boolean: [
26+
'enable-adding-actors',
27+
'enableActorAutoLoading', // deprecated
28+
],
29+
string: ['actors'],
30+
default: {
31+
'enable-adding-actors': false,
32+
},
33+
});
34+
35+
const argEnableAddingActors = argv['enable-adding-actors'] || argv.enableActorAutoLoading || false;
2536
const argActors = argv.actors?.split(',').map((actor: string) => actor.trim()) || [];
26-
const argEnableActorAutoLoading = argv.enableActorAutoLoading || false;
2737

2838
if (!process.env.APIFY_TOKEN) {
2939
log.error('APIFY_TOKEN is required but not set in the environment variables.');
@@ -36,7 +46,7 @@ async function main() {
3646
? server.addToolsFromActors(argActors)
3747
: server.addToolsFromDefaultActors());
3848
server.updateTools(getActorDiscoveryTools());
39-
if (argEnableActorAutoLoading) {
49+
if (argEnableAddingActors) {
4050
server.updateTools(getActorAutoLoadingTools());
4151
}
4252
const transport = new StdioServerTransport();

src/input.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { log } from './logger.js';
12
import type { Input } from './types.js';
23

34
/**
@@ -12,8 +13,16 @@ export async function processInput(originalInput: Partial<Input>): Promise<Input
1213
if (input.actors && typeof input.actors === 'string') {
1314
input.actors = input.actors.split(',').map((format: string) => format.trim()) as string[];
1415
}
15-
if (!input.enableActorAutoLoading) {
16-
input.enableActorAutoLoading = false;
16+
17+
// enableAddingActors is deprecated, use enableActorAutoLoading instead
18+
if (input.enableActorAutoLoading !== undefined && input.enableAddingActors === undefined) {
19+
log.warning('enableActorAutoLoading is deprecated, use enableAddingActors instead');
20+
input.enableAddingActors = input.enableActorAutoLoading;
21+
}
22+
23+
if (!input.enableAddingActors) {
24+
input.enableAddingActors = false;
1725
}
26+
1827
return input;
1928
}

src/main.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ const actorRun = Actor.isAtHome() ? {
5757
} : {};
5858

5959
/**
60-
* Process input parameters and update tools
61-
* If URL contains query parameter actors, add tools from actors, otherwise add tools from default actors
60+
* Process input parameters and update tools.
61+
* If URL contains query parameter `actors`, add Actors as tools.
62+
* Otherwise, add default Actors but only if there are no tools added yet.
6263
* @param url
6364
*/
6465
async function processParamsAndUpdateTools(url: string) {
@@ -68,9 +69,8 @@ async function processParamsAndUpdateTools(url: string) {
6869
const input = await processInput(params as unknown as Input);
6970
if (input.actors) {
7071
await mcpServer.addToolsFromActors(input.actors as string[]);
71-
}
72-
if (input.enableActorAutoLoading) {
73-
mcpServer.updateTools(getActorAutoLoadingTools());
72+
} else if (mcpServer.getToolNames().length === 0) {
73+
await mcpServer.addToolsFromDefaultActors();
7474
}
7575
log.debug(`Server is running in STANDBY mode with the following Actors (tools): ${mcpServer.getToolNames()}.
7676
To use different Actors, provide them in query parameter "actors" or include them in the Actor Task input.`);
@@ -137,9 +137,8 @@ log.info(`Loaded input: ${JSON.stringify(input)} `);
137137

138138
if (STANDBY_MODE) {
139139
log.info('Actor is running in the STANDBY mode.');
140-
await mcpServer.addToolsFromDefaultActors();
141140
mcpServer.updateTools(getActorDiscoveryTools());
142-
if (input.enableActorAutoLoading) {
141+
if (input.enableAddingActors) {
143142
mcpServer.updateTools(getActorAutoLoadingTools());
144143
}
145144
app.listen(PORT, () => {

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { ActorDefaultRunOptions, ActorDefinition } from 'apify-client';
33

44
export type Input = {
55
actors: string[] | string;
6+
enableAddingActors?: boolean;
67
enableActorAutoLoading?: boolean;
78
maxActorMemoryBytes?: number;
89
debugActor?: string;

tests/input.test.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { describe, it, expect } from 'vitest';
2+
3+
import { processInput } from '../src/input.js';
4+
import type { Input } from '../src/types.js';
5+
6+
describe('processInput', () => {
7+
it('should handle string actors input and convert to array', async () => {
8+
const input: Partial<Input> = {
9+
actors: 'actor1, actor2,actor3',
10+
};
11+
const processed = await processInput(input);
12+
expect(processed.actors).toEqual(['actor1', 'actor2', 'actor3']);
13+
});
14+
15+
it('should keep array actors input unchanged', async () => {
16+
const input: Partial<Input> = {
17+
actors: ['actor1', 'actor2', 'actor3'],
18+
};
19+
const processed = await processInput(input);
20+
expect(processed.actors).toEqual(['actor1', 'actor2', 'actor3']);
21+
});
22+
23+
it('should handle enableActorAutoLoading to set enableAddingActors', async () => {
24+
const input: Partial<Input> = {
25+
actors: ['actor1'],
26+
enableActorAutoLoading: true,
27+
};
28+
const processed = await processInput(input);
29+
expect(processed.enableAddingActors).toBe(true);
30+
});
31+
32+
it('should not override existing enableAddingActors with enableActorAutoLoading', async () => {
33+
const input: Partial<Input> = {
34+
actors: ['actor1'],
35+
enableActorAutoLoading: true,
36+
enableAddingActors: false,
37+
};
38+
const processed = await processInput(input);
39+
expect(processed.enableAddingActors).toBe(false);
40+
});
41+
42+
it('should default enableAddingActors to false when not provided', async () => {
43+
const input: Partial<Input> = {
44+
actors: ['actor1'],
45+
};
46+
const processed = await processInput(input);
47+
expect(processed.enableAddingActors).toBe(false);
48+
});
49+
});

0 commit comments

Comments
 (0)