Skip to main content
Glama

actors-mcp-server

Official
by apify
build.ts4.01 kB
import type { ApifyClient } from '../apify-client.js'; import { ACTOR_README_MAX_LENGTH } from '../const.js'; import type { ActorDefinitionPruned, ActorDefinitionWithDesc, SchemaProperties, } from '../types.js'; /** * Get Actor input schema by Actor name. * First, fetch the Actor details to get the default build tag and buildId. * Then, fetch the build details and return actorName, description, and input schema. * @param {string} actorIdOrName - Actor ID or Actor full name. * @param {ApifyClient} apifyClient - The Apify client instance. * @param {number} limit - Truncate the README to this limit. * @returns {Promise<ActorDefinitionWithDesc | null>} - The actor definition with description or null if not found. */ export async function getActorDefinition( actorIdOrName: string, apifyClient: ApifyClient, limit: number = ACTOR_README_MAX_LENGTH, ): Promise<ActorDefinitionPruned | null> { const actorClient = apifyClient.actor(actorIdOrName); try { // Fetch Actor details const actor = await actorClient.get(); if (!actor) { return null; } const defaultBuildClient = await actorClient.defaultBuild(); const buildDetails = await defaultBuildClient.get(); if (buildDetails?.actorDefinition) { const actorDefinitions = buildDetails?.actorDefinition as ActorDefinitionWithDesc; // We set actorDefinition ID to Actor ID actorDefinitions.id = actor.id; actorDefinitions.readme = truncateActorReadme(actorDefinitions.readme || '', limit); actorDefinitions.description = actor.description || ''; actorDefinitions.actorFullName = `${actor.username}/${actor.name}`; actorDefinitions.defaultRunOptions = actor.defaultRunOptions; return pruneActorDefinition(actorDefinitions); } return null; } catch (error) { // Check if it's a "not found" error (404 or 400 status codes) const isNotFound = typeof error === 'object' && error !== null && 'statusCode' in error && (error.statusCode === 404 || error.statusCode === 400); if (isNotFound) { // Return null for not found - caller will log appropriately return null; } // For server errors, throw the original error (preserve error type) // Caller should catch and log throw error; } } function pruneActorDefinition(response: ActorDefinitionWithDesc): ActorDefinitionPruned { return { id: response.id, actorFullName: response.actorFullName || '', buildTag: response?.buildTag || '', readme: response?.readme || '', input: response?.input && 'type' in response.input && 'properties' in response.input ? { ...response.input, type: response.input.type as string, properties: response.input.properties as Record<string, SchemaProperties>, } : undefined, description: response.description, defaultRunOptions: response.defaultRunOptions, webServerMcpPath: 'webServerMcpPath' in response ? response.webServerMcpPath as string : undefined, }; } /** Prune Actor README if it is too long * If the README is too long * - We keep the README as it is up to the limit. * - After the limit, we keep heading only * - We add a note that the README was truncated because it was too long. */ function truncateActorReadme(readme: string, limit = ACTOR_README_MAX_LENGTH): string { if (readme.length <= limit) { return readme; } const readmeFirst = readme.slice(0, limit); const readmeRest = readme.slice(limit); const lines = readmeRest.split('\n'); const prunedReadme = lines.filter((line) => line.startsWith('#')); return `${readmeFirst}\n\nREADME was truncated because it was too long. Remaining headers:\n${prunedReadme.join(', ')}`; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/apify/actors-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server