Skip to main content
Glama

relay_run

Execute a single AI model call to test prompts before building full workflows. Returns output, token usage, estimated provider cost, and trace URL.

Instructions

Execute a single AI model call. Useful for testing prompts before building full workflows. Returns output, token usage, estimated provider cost, and trace URL. Note: Cost tracks your provider bill (OpenAI/Anthropic), not RelayPlane fees - we're BYOK.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
modelYesModel in provider:model format (e.g., 'openai:gpt-4o', 'anthropic:claude-3-5-sonnet-20241022')
promptYesThe user prompt to send
systemPromptNoOptional system prompt
schemaNoOptional JSON schema for structured output

Implementation Reference

  • Main tool handler that orchestrates model execution: parses model, checks budget and config, calls provider-specific execute functions, calculates costs, stores run data, handles errors.
    export async function relayRun(input: RelayRunInput): Promise<RelayRunResponse> {
      const startTime = Date.now();
      const runId = generateRunId();
      const config = getConfig();
    
      try {
        // Parse model
        const { provider, modelId } = parseModel(input.model);
    
        // Check provider is configured
        if (!isProviderConfigured(provider)) {
          throw new Error(
            `Provider "${provider}" is not configured. Set ${provider.toUpperCase()}_API_KEY environment variable.`
          );
        }
    
        // Estimate cost and check budget
        const estimatedCost = estimateProviderCost(input.model, input.prompt, input.systemPrompt);
        const budgetCheck = checkBudget(estimatedCost);
    
        if (!budgetCheck.allowed) {
          throw new Error(budgetCheck.error);
        }
    
        // Get API key
        const apiKey = getProviderKey(provider)!;
    
        // Execute based on provider
        let result: { output: any; promptTokens: number; completionTokens: number };
    
        switch (provider) {
          case 'openai':
            result = await executeOpenAI(apiKey, modelId, input.prompt, input.systemPrompt, input.schema);
            break;
          case 'anthropic':
            result = await executeAnthropic(apiKey, modelId, input.prompt, input.systemPrompt, input.schema);
            break;
          case 'google':
            result = await executeGoogle(apiKey, modelId, input.prompt, input.systemPrompt);
            break;
          case 'xai':
            result = await executeXAI(apiKey, modelId, input.prompt, input.systemPrompt);
            break;
          default:
            throw new Error(`Unsupported provider: ${provider}`);
        }
    
        const durationMs = Date.now() - startTime;
        const actualCost = calculateActualCost(input.model, result.promptTokens, result.completionTokens);
    
        // Record actual cost
        recordCost(actualCost);
    
        const response: RelayRunResponse = {
          success: true,
          output: result.output,
          model: input.model,
          usage: {
            promptTokens: result.promptTokens,
            completionTokens: result.completionTokens,
            totalTokens: result.promptTokens + result.completionTokens,
            estimatedProviderCostUsd: actualCost,
          },
          durationMs,
          runId,
          traceUrl: `${config.traceUrlBase}/${runId}`,
        };
    
        // Store run
        addRun({
          runId,
          type: 'single',
          model: input.model,
          success: true,
          startTime: new Date(startTime),
          endTime: new Date(),
          durationMs,
          usage: response.usage,
          input: { prompt: input.prompt, systemPrompt: input.systemPrompt },
          output: result.output,
        });
    
        return response;
      } catch (error) {
        const durationMs = Date.now() - startTime;
        const errorMessage = error instanceof Error ? error.message : String(error);
    
        const response: RelayRunResponse = {
          success: false,
          output: '',
          model: input.model,
          usage: {
            promptTokens: 0,
            completionTokens: 0,
            totalTokens: 0,
            estimatedProviderCostUsd: 0,
          },
          durationMs,
          runId,
          traceUrl: `${config.traceUrlBase}/${runId}`,
          error: {
            code: 'EXECUTION_ERROR',
            message: errorMessage,
          },
        };
    
        // Store failed run
        addRun({
          runId,
          type: 'single',
          model: input.model,
          success: false,
          startTime: new Date(startTime),
          endTime: new Date(),
          durationMs,
          usage: response.usage,
          input: { prompt: input.prompt, systemPrompt: input.systemPrompt },
          error: errorMessage,
        });
    
        return response;
      }
  • Zod schema for validating input to the relay_run tool.
    export const relayRunSchema = z.object({
      model: z
        .string()
        .describe("Model in provider:model format (e.g., 'openai:gpt-4o', 'anthropic:claude-3-5-sonnet-20241022')"),
      prompt: z.string().describe('The user prompt to send'),
      systemPrompt: z.string().optional().describe('Optional system prompt'),
      schema: z.object({}).passthrough().optional().describe('Optional JSON schema for structured output'),
    });
  • Tool definition object used for MCP registration, including name, description, and input schema.
    export const relayRunDefinition = {
      name: 'relay_run',
      description:
        "Execute a single AI model call. Useful for testing prompts before building full workflows. Returns output, token usage, estimated provider cost, and trace URL. Note: Cost tracks your provider bill (OpenAI/Anthropic), not RelayPlane fees - we're BYOK.",
      inputSchema: {
        type: 'object' as const,
        properties: {
          model: {
            type: 'string',
            description: "Model in provider:model format (e.g., 'openai:gpt-4o', 'anthropic:claude-3-5-sonnet-20241022')",
          },
          prompt: {
            type: 'string',
            description: 'The user prompt to send',
          },
          systemPrompt: {
            type: 'string',
            description: 'Optional system prompt',
          },
          schema: {
            type: 'object',
            description: 'Optional JSON schema for structured output',
          },
        },
        required: ['model', 'prompt'],
      },
    };
  • src/server.ts:59-67 (registration)
    Array of all tool definitions registered with the MCP server for the listTools request.
    const TOOLS = [
      relayModelsListDefinition,
      relayRunDefinition,
      relayWorkflowRunDefinition,
      relayWorkflowValidateDefinition,
      relaySkillsListDefinition,
      relayRunsListDefinition,
      relayRunGetDefinition,
    ];
  • src/server.ts:114-118 (registration)
    Dispatch case in MCP callTool handler that validates input with schema and invokes the relayRun handler function.
    case 'relay_run': {
      const parsed = relayRunSchema.parse(args);
      result = await relayRun(parsed);
      break;
    }

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/RelayPlane/mcp-server'

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