Skip to content

Commit 59a9e0a

Browse files
committed
remove toolkits (move to tools index), pass apify token as arg, clean up old tools.ts, separate Actor readme
1 parent 9241f03 commit 59a9e0a

File tree

14 files changed

+465
-78
lines changed

14 files changed

+465
-78
lines changed

.actor/ACTOR.md

Lines changed: 389 additions & 0 deletions
Large diffs are not rendered by default.

.actor/actor.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
"description": "Implementation of a Model Context Protocol (MCP) Server for Apify Actors that enables AI applications (and AI agents) to interact with Apify Actors",
66
"version": "0.1",
77
"input": "./input_schema.json",
8+
"readme": "./ACTOR.md",
89
"dockerfile": "./Dockerfile"
910
}

src/actors.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { Ajv } from 'ajv';
2+
import type { ActorStoreList } from 'apify-client';
23
import { ApifyClient } from 'apify-client';
34

45
import { ACTOR_ADDITIONAL_INSTRUCTIONS, defaults, MAX_DESCRIPTION_LENGTH, ACTOR_README_MAX_LENGTH, ACTOR_ENUM_MAX_LENGTH } from './const.js';
56
import { log } from './logger.js';
6-
import type { ActorDefinitionPruned, ActorDefinitionWithDesc, IActorInputSchema, ISchemaProperties, ToolWrap } from './types.js';
7+
import type { ActorStorePruned, PricingInfo, ActorDefinitionPruned, ActorDefinitionWithDesc, IActorInputSchema, ISchemaProperties, ToolWrap } from './types.js';
78

89
export function actorNameToToolName(actorName: string): string {
910
return actorName
@@ -349,3 +350,39 @@ export async function getActorsAsTools(actors: string[]): Promise<ToolWrap[]> {
349350
}
350351
return tools;
351352
}
353+
354+
function pruneActorStoreInfo(response: ActorStoreList): ActorStorePruned {
355+
const stats = response.stats || {};
356+
const pricingInfo = (response.currentPricingInfo || {}) as PricingInfo;
357+
return {
358+
id: response.id,
359+
name: response.name?.toString() || '',
360+
username: response.username?.toString() || '',
361+
actorFullName: `${response.username}/${response.name}`,
362+
title: response.title?.toString() || '',
363+
description: response.description?.toString() || '',
364+
stats: {
365+
totalRuns: stats.totalRuns,
366+
totalUsers30Days: stats.totalUsers30Days,
367+
publicActorRunStats30Days: 'publicActorRunStats30Days' in stats
368+
? stats.publicActorRunStats30Days : {},
369+
},
370+
currentPricingInfo: {
371+
pricingModel: pricingInfo.pricingModel?.toString() || '',
372+
pricePerUnitUsd: pricingInfo?.pricePerUnitUsd ?? 0,
373+
trialMinutes: pricingInfo?.trialMinutes ?? 0,
374+
},
375+
url: response.url?.toString() || '',
376+
totalStars: 'totalStars' in response ? (response.totalStars as number) : null,
377+
};
378+
}
379+
380+
export async function searchActorsByKeywords(
381+
search: string,
382+
limit: number | undefined = undefined,
383+
offset: number | undefined = undefined,
384+
): Promise<ActorStorePruned[] | null> {
385+
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
386+
const results = await client.store().list({ search, limit, offset });
387+
return results.items.map((x) => pruneActorStoreInfo(x));
388+
}

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44

55
export { createExpressApp } from './server.js';
66
export { ApifyMcpServer } from './mcp-server.js';
7-
export { getActorAutoLoadingTools, getActorDiscoveryTools } from './toolkits/index.js';
7+
export { getActorAutoLoadingTools, getActorDiscoveryTools } from './tools/index.js';
88
export { addActorToTools, discoverActorsTool, getActorsDetailsTool, removeActorFromTools } from './tools/index.js';

src/main.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ import { processInput } from './input.js';
99
import { log } from './logger.js';
1010
import { ApifyMcpServer } from './mcp-server.js';
1111
import { createExpressApp } from './server.js';
12-
import { getActorAutoLoadingTools } from './toolkits/actor-auto-loading-tools.js';
13-
import { getActorDiscoveryTools } from './toolkits/discovery-tools.js';
12+
import { getActorAutoLoadingTools, getActorDiscoveryTools } from './tools/index.js';
1413
import type { Input } from './types.js';
1514
import { isActorStandby } from './utils.js';
1615

@@ -70,6 +69,6 @@ if (isActorStandby()) {
7069
await Actor.fail('If you need to debug a specific actor, please provide the debugActor and debugActorInput fields in the input');
7170
}
7271
const options = { memory: input.maxActorMemoryBytes } as ActorCallOptions;
73-
await mcpServer.callActorGetDataset(input.debugActor!, input.debugActorInput!, options);
72+
await mcpServer.callActorGetDataset(input.debugActor!, input.debugActorInput!, process.env.APIFY_TOKEN, options);
7473
await Actor.exit();
7574
}

src/mcp-server.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
} from './const.js';
2727
import { processInput } from './input.js';
2828
import { log } from './logger.js';
29-
import { getActorAutoLoadingTools } from './toolkits/actor-auto-loading-tools.js';
29+
import { getActorAutoLoadingTools } from './tools/index.js';
3030
import type { Input, ActorTool, ToolWrap, InternalTool } from './types.js';
3131

3232
/**
@@ -80,14 +80,15 @@ export class ApifyMcpServer {
8080
public async callActorGetDataset(
8181
actorName: string,
8282
input: unknown,
83+
apifyToken: string,
8384
callOptions: ActorCallOptions | undefined = undefined,
8485
): Promise<object[]> {
8586
const name = actorName;
8687
try {
8788
log.info(`Calling actor ${name} with input: ${JSON.stringify(input)}`);
8889

8990
const options: ApifyClientOptions = { requestInterceptors: [this.addUserAgent] };
90-
const client = new ApifyClient({ ...options, token: process.env.APIFY_TOKEN });
91+
const client = new ApifyClient({ ...options, token: apifyToken });
9192
const actorClient = client.actor(name);
9293

9394
const results = await actorClient.call(input, callOptions);
@@ -172,7 +173,7 @@ export class ApifyMcpServer {
172173
* @throws {Error} - Throws an error if the tool is unknown or arguments are invalid.
173174
*/
174175
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
175-
const { name, arguments: args } = request.params;
176+
const { name, arguments: args, apifyToken } = request.params;
176177

177178
const tool = Array.from(this.tools.values())
178179
.find((t) => t.tool.name === name || (t.type === 'actor' && (t.tool as ActorTool).actorFullName === name));
@@ -203,7 +204,9 @@ export class ApifyMcpServer {
203204
if (tool.type === 'actor') {
204205
const actorTool = tool.tool as ActorTool;
205206

206-
const items = await this.callActorGetDataset(actorTool.actorFullName, args, { memory: actorTool.memoryMbytes } as ActorCallOptions);
207+
const items = await this.callActorGetDataset(actorTool.actorFullName, args, apifyToken as string, {
208+
memory: actorTool.memoryMbytes,
209+
} as ActorCallOptions);
207210
const content = items.map((item) => {
208211
const text = JSON.stringify(item).slice(0, ACTOR_OUTPUT_MAX_CHARS_PER_ITEM);
209212
return text.length === ACTOR_OUTPUT_MAX_CHARS_PER_ITEM

src/server.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/*
2+
* This file contains the express server implementation used for standby Actor mode.
3+
*/
4+
15
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
26
import type { Request, Response } from 'express';
37
import express from 'express';

src/stdio.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ import minimist from 'minimist';
1717

1818
import { log } from './logger.js';
1919
import { ApifyMcpServer } from './mcp-server.js';
20-
import { getActorAutoLoadingTools } from './toolkits/actor-auto-loading-tools.js';
21-
import { getActorDiscoveryTools } from './toolkits/discovery-tools.js';
20+
import { getActorAutoLoadingTools, getActorDiscoveryTools } from './tools/index.js';
2221

2322
log.setLevel(log.LEVELS.ERROR);
2423

src/toolkits/actor-auto-loading-tools.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/toolkits/discovery-tools.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)