Skip to content

Commit 77138c9

Browse files
committed
feat: Add tool annotations (title, readOnlyHint, openWorldHint)
Add annotations to all internal and Actor tools: - title: Short display name (sentence case, Actor/Apify capitalized) - readOnlyHint: true for read-only tools - openWorldHint: true only for tools accessing open world (external web/Actors), not Apify platform Examples: call-actor and get-html-skeleton are openWorld; search-actors and fetch-apify-docs are not
1 parent 80aed10 commit 77138c9

17 files changed

+91
-3
lines changed

src/mcp/server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,8 @@ export class ActorsMcpServer {
297297
}
298298
} else {
299299
// No skyfire mode - store tools as-is
300-
for (const wrap of tools) {
301-
this.tools.set(wrap.name, wrap);
300+
for (const tool of tools) {
301+
this.tools.set(tool.name, tool);
302302
}
303303
}
304304
if (shouldNotifyToolsChangedHandler) this.notifyToolsChangedHandler();

src/tools/actor.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ Actor description: ${actorDefinitionPruned.description}`;
198198
inputSchema: inputSchema as ToolInputSchema,
199199
ajvValidate,
200200
memoryMbytes,
201+
annotations: {
202+
title: actorDefinitionPruned.actorFullName,
203+
openWorldHint: true,
204+
},
201205
});
202206
}
203207
return tools;
@@ -361,6 +365,10 @@ EXAMPLES:
361365
// Additional props true to allow skyfire-pay-id
362366
additionalProperties: true,
363367
}),
368+
annotations: {
369+
title: 'Call Actor',
370+
openWorldHint: true,
371+
},
364372
call: async (toolArgs: InternalToolArgs) => {
365373
const { args, apifyToken, progressTracker, extra, apifyMcpServer } = toolArgs;
366374
const { actor: actorName, step, input, callOptions } = callActorArgs.parse(args);

src/tools/build.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ export const actorDefinitionTool: ToolEntry = {
116116
+ `Limit the length of the README if needed.`,
117117
inputSchema: zodToJsonSchema(getActorDefinitionArgsSchema) as ToolInputSchema,
118118
ajvValidate: ajv.compile(zodToJsonSchema(getActorDefinitionArgsSchema)),
119+
annotations: {
120+
title: 'Get Actor definition',
121+
readOnlyHint: true,
122+
},
119123
call: async (toolArgs: InternalToolArgs) => {
120124
const { args, apifyToken } = toolArgs;
121125

src/tools/dataset.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ USAGE EXAMPLES:
5757
- user_input: What fields does username~my-dataset have?`,
5858
inputSchema: zodToJsonSchema(getDatasetArgs) as ToolInputSchema,
5959
ajvValidate: ajv.compile(zodToJsonSchema(getDatasetArgs)),
60+
annotations: {
61+
title: 'Get dataset',
62+
readOnlyHint: true,
63+
},
6064
call: async (toolArgs: InternalToolArgs) => {
6165
const { args, apifyToken } = toolArgs;
6266
const parsed = getDatasetArgs.parse(args);
@@ -89,6 +93,10 @@ USAGE EXAMPLES:
8993
- user_input: Get only metadata.url and title from dataset username~my-dataset (flatten metadata)`,
9094
inputSchema: zodToJsonSchema(getDatasetItemsArgs) as ToolInputSchema,
9195
ajvValidate: ajv.compile(zodToJsonSchema(getDatasetItemsArgs)),
96+
annotations: {
97+
title: 'Get dataset items',
98+
readOnlyHint: true,
99+
},
92100
call: async (toolArgs: InternalToolArgs) => {
93101
const { args, apifyToken } = toolArgs;
94102
const parsed = getDatasetItemsArgs.parse(args);
@@ -148,6 +156,10 @@ USAGE EXAMPLES:
148156
- user_input: Show schema of username~my-dataset (clean items only)`,
149157
inputSchema: zodToJsonSchema(getDatasetSchemaArgs) as ToolInputSchema,
150158
ajvValidate: ajv.compile(zodToJsonSchema(getDatasetSchemaArgs)),
159+
annotations: {
160+
title: 'Get dataset schema',
161+
readOnlyHint: true,
162+
},
151163
call: async (toolArgs: InternalToolArgs) => {
152164
const { args, apifyToken } = toolArgs;
153165
const parsed = getDatasetSchemaArgs.parse(args);

src/tools/dataset_collection.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ USAGE EXAMPLES:
4242
- user_input: List unnamed datasets`,
4343
inputSchema: zodToJsonSchema(getUserDatasetsListArgs) as ToolInputSchema,
4444
ajvValidate: ajv.compile(zodToJsonSchema(getUserDatasetsListArgs)),
45+
annotations: {
46+
title: 'Get user datasets list',
47+
readOnlyHint: true,
48+
},
4549
call: async (toolArgs: InternalToolArgs) => {
4650
const { args, apifyToken } = toolArgs;
4751
const parsed = getUserDatasetsListArgs.parse(args);

src/tools/fetch-actor-details.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ USAGE EXAMPLES:
2929
- user_input: What is the pricing for apify/instagram-scraper?`,
3030
inputSchema: zodToJsonSchema(fetchActorDetailsToolArgsSchema) as ToolInputSchema,
3131
ajvValidate: ajv.compile(zodToJsonSchema(fetchActorDetailsToolArgsSchema)),
32+
annotations: {
33+
title: 'Fetch Actor details',
34+
readOnlyHint: true,
35+
},
3236
call: async (toolArgs: InternalToolArgs) => {
3337
const { args, apifyToken } = toolArgs;
3438
const parsed = fetchActorDetailsToolArgsSchema.parse(args);

src/tools/fetch-apify-docs.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ USAGE EXAMPLES:
2929
- user_input: Fetch https://docs.apify.com/academy`,
3030
inputSchema: zodToJsonSchema(fetchApifyDocsToolArgsSchema) as ToolInputSchema,
3131
ajvValidate: ajv.compile(zodToJsonSchema(fetchApifyDocsToolArgsSchema)),
32+
annotations: {
33+
title: 'Fetch Apify docs',
34+
readOnlyHint: true,
35+
},
3236
call: async (toolArgs: InternalToolArgs) => {
3337
const { args } = toolArgs;
3438

src/tools/get-actor-output.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ Note: This tool is automatically included if the Apify MCP Server is configured
8888
* Allow additional properties for Skyfire mode to pass `skyfire-pay-id`.
8989
*/
9090
ajvValidate: ajv.compile({ ...zodToJsonSchema(getActorOutputArgs), additionalProperties: true }),
91+
annotations: {
92+
title: 'Get Actor output',
93+
readOnlyHint: true,
94+
},
9195
call: async (toolArgs: InternalToolArgs) => {
9296
const { args, apifyToken, apifyMcpServer } = toolArgs;
9397

src/tools/get-html-skeleton.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ USAGE EXAMPLES:
5252
- user_input: Get next chunk of HTML skeleton for https://example.com (chunk=2)`,
5353
inputSchema: zodToJsonSchema(getHtmlSkeletonArgs) as ToolInputSchema,
5454
ajvValidate: ajv.compile(zodToJsonSchema(getHtmlSkeletonArgs)),
55+
annotations: {
56+
title: 'Get HTML skeleton',
57+
readOnlyHint: true,
58+
openWorldHint: true,
59+
},
5560
call: async (toolArgs: InternalToolArgs) => {
5661
const { args, apifyToken } = toolArgs;
5762
const parsed = getHtmlSkeletonArgs.parse(args);

src/tools/helpers.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ USAGE EXAMPLES:
2727
- user_input: Add apify/instagram-scraper as a tool`,
2828
inputSchema: zodToJsonSchema(addToolArgsSchema) as ToolInputSchema,
2929
ajvValidate: ajv.compile(zodToJsonSchema(addToolArgsSchema)),
30+
annotations: {
31+
title: 'Add tool',
32+
},
3033
// TODO: I don't like that we are passing apifyMcpServer and mcpServer to the tool
3134
call: async (toolArgs: InternalToolArgs) => {
3235
const { apifyMcpServer, apifyToken, args, extra: { sendNotification } } = toolArgs;

0 commit comments

Comments
 (0)