Skip to main content
Glama

actors-mcp-server

Official
by apify
MIT License
7,198
465
  • Apple
actor.ts3.91 kB
import type { ApifyClient } from '../apify-client.js'; import { getActorMCPServerPath, getActorMCPServerURL } from '../mcp/actors.js'; import { mcpServerCache } from '../state.js'; import { getActorDefinition } from '../tools/build.js'; import type { ActorDefinitionStorage, DatasetItem } from '../types.js'; import { getValuesByDotKeys } from './generic.js'; /** * Resolve and cache the MCP server URL for the given Actor. * - Returns a string URL when the Actor exposes an MCP server * - Returns false when the Actor is not an MCP server * Uses a TTL LRU cache to avoid repeated API calls. */ export async function getActorMcpUrlCached( actorIdOrName: string, apifyClient: ApifyClient, ): Promise<string | false> { const cached = mcpServerCache.get(actorIdOrName); if (cached !== null && cached !== undefined) { return cached as string | false; } const actorDefinitionPruned = await getActorDefinition(actorIdOrName, apifyClient); const mcpPath = actorDefinitionPruned && getActorMCPServerPath(actorDefinitionPruned); if (actorDefinitionPruned && mcpPath) { const url = await getActorMCPServerURL(actorDefinitionPruned.id, mcpPath); mcpServerCache.set(actorIdOrName, url); return url; } mcpServerCache.set(actorIdOrName, false); return false; } /** * Returns an array of all field names mentioned in the display.properties * of all views in the given ActorDefinitionStorage object. */ export function getActorDefinitionStorageFieldNames(storage: ActorDefinitionStorage | object): string[] { const fieldSet = new Set<string>(); if ('views' in storage && typeof storage.views === 'object' && storage.views !== null) { for (const view of Object.values(storage.views)) { // Collect from display.properties if (view.display && view.display.properties) { Object.keys(view.display.properties).forEach((field) => fieldSet.add(field)); } // Collect from transformation.fields if (view.transformation && Array.isArray(view.transformation.fields)) { view.transformation.fields.forEach((field) => { if (typeof field === 'string') fieldSet.add(field); }); } } } return Array.from(fieldSet); } /** * Ensures the Actor output items are within the character limit. * * First checks if all items fit into the limit, then tries only the important fields and as a last resort * starts removing items until within the limit. In worst scenario return empty array. * * This is primarily used to ensure the tool output does not exceed the LLM context length or tool output limit. */ export function ensureOutputWithinCharLimit(items: DatasetItem[], importantFields: string[], charLimit: number): DatasetItem[] { // Check if all items fit into the limit const allItemsString = JSON.stringify(items); if (allItemsString.length <= charLimit) { return items; } /** * Items used for the final fallback - removing items until within the limit. * If important fields are defined, use only those fields for that fallback step. */ let sourceItems = items; // Try only the important fields if (importantFields.length > 0) { const importantItems = items.map((item) => getValuesByDotKeys(item, importantFields)); const importantItemsString = JSON.stringify(importantItems); if (importantItemsString.length <= charLimit) { return importantItems; } sourceItems = importantItems; } // Start removing items until within the limit const result: DatasetItem[] = []; for (const item of sourceItems) { if (JSON.stringify(result.concat(item)).length > charLimit) { break; } result.push(item); } return result; }

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