Skip to main content
Glama

quality.getJobStatus

Check status and retrieve results for async quality evaluation jobs submitted via batch processing. Monitor progress percentage, item counts, and access result summaries or error details.

Instructions

Check the status of an async batch quality evaluation job.

Use this tool to poll for the status and results of a job that was submitted with quality.batch_evaluate.

Returns:

  • Job state (waiting, active, completed, failed)

  • Progress percentage (0-100)

  • Item counts (total, processed, success, failed)

  • Result summary when completed

  • Error details when failed

Note: When Redis is unavailable, falls back to LRU store (in-memory). Jobs in LRU store are not persisted across server restarts.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
job_idYesThe job ID returned by quality.batch_evaluate

Implementation Reference

  • The handler function 'qualityGetJobStatusHandler' implements the logic for 'quality.getJobStatus'. It attempts to retrieve job status from BullMQ (Redis) and falls back to an in-memory LRU store if the job is not found or Redis is unavailable.
    export async function qualityGetJobStatusHandler(
      input: unknown
    ): Promise<QualityGetJobStatusOutput> {
      // router.tsから注入された_request_idを使用、フォールバックとして自動生成
      const requestId =
        ((input as Record<string, unknown> | null)?._request_id as string | undefined) ??
        generateRequestId();
    
      if (isDevelopment()) {
        logger.info("[MCP Tool] quality.getJobStatus called", {
          hasInput: input !== null && input !== undefined,
          requestId,
        });
      }
    
      // Validate input
      let validated: QualityGetJobStatusInput;
      try {
        validated = qualityGetJobStatusInputSchema.parse(input);
      } catch (error) {
        logger.warn("[MCP Tool] quality.getJobStatus validation error", {
          error: error instanceof Error ? error.message : String(error),
          requestId,
        });
        return createErrorResponseWithRequestId(
          GET_QUALITY_JOB_STATUS_ERROR_CODES.VALIDATION_ERROR,
          error instanceof Error ? error.message : "Invalid input",
          requestId
        );
      }
    
      const jobId = validated.job_id;
    
      // Check Redis availability
      const redisAvailable = await isRedisAvailable();
    
      if (redisAvailable) {
        // Try BullMQ queue first
        const queue = createBatchQualityQueue();
    
        try {
          const status = await getBatchQualityJobStatus(queue, jobId);
    
          if (status) {
            // Job found in BullMQ
            if (isDevelopment()) {
              logger.debug("[MCP Tool] quality.getJobStatus job found in BullMQ", {
                jobId,
                state: status.state,
                progress: status.progress,
                requestId,
              });
            }
    
            const data: QualityGetJobStatusData = {
              jobId: status.jobId,
              status: mapBullMQStateToQualityState(status.state),
              progress: status.progress,
              totalItems: status.totalItems,
              processedItems: status.processedItems,
              successItems: status.successItems,
              failedItems: status.failedItems,
              timestamps: status.timestamps,
            };
    
            // Add result if completed
            if (status.state === "completed" && status.result) {
              data.result = {
                jobId: status.result.jobId,
                success: status.result.success,
                totalItems: status.result.totalItems,
                processedItems: status.result.processedItems,
                successItems: status.result.successItems,
                failedItems: status.result.failedItems,
                results: status.result.results.map((r) => ({
                  index: r.index,
                  success: r.success,
                  data: r.data,
                  error: r.error,
                })),
                processingTimeMs: status.result.processingTimeMs,
                completedAt: status.result.completedAt,
                error: status.result.error,
              };
            }
    
            // Add error if failed
            if (status.state === "failed" && status.error) {
              data.failedReason = status.error;
            }
    
            return {
              success: true,
              data,
              metadata: {
                request_id: requestId,
                redis_used: true,
                lru_fallback: false,
              },
            };
          }
    
          // Job not found in BullMQ, try LRU store as fallback
          if (isDevelopment()) {
            logger.debug("[MCP Tool] quality.getJobStatus job not found in BullMQ, trying LRU store", {
              jobId,
              requestId,
            });
          }
        } finally {
          // Close queue connection
          await closeBatchQualityQueue(queue);
        }
      }
    
      // Try LRU store (either Redis unavailable or job not found in BullMQ)
      const lruJob = getBatchJob(jobId);
    
      if (lruJob) {
        // Job found in LRU store
        if (isDevelopment()) {
          logger.debug("[MCP Tool] quality.getJobStatus job found in LRU store", {
            jobId,
            status: lruJob.status,
            progress: lruJob.progress_percent,
            requestId,
          });
        }
    
        const data: QualityGetJobStatusData = {
          jobId: lruJob.job_id,
          status: mapLRUStatusToQualityState(lruJob.status),
          progress: lruJob.progress_percent,
          totalItems: lruJob.total_items,
          processedItems: lruJob.processed_items,
          successItems: lruJob.success_items,
          failedItems: lruJob.failed_items,
          timestamps: {
            created: new Date(lruJob.created_at).getTime(),
            completed: lruJob.completed_at ? new Date(lruJob.completed_at).getTime() : undefined,
          },
        };
    
        // Add result if completed
        if (lruJob.status === "completed" && lruJob.results) {
          data.result = {
            jobId: lruJob.job_id,
            success: lruJob.failed_items === 0,
            totalItems: lruJob.total_items,
            processedItems: lruJob.processed_items,
            successItems: lruJob.success_items,
            failedItems: lruJob.failed_items,
            results: lruJob.results.map((r, index) => ({
              index,
              success: true,
              data: r,
            })),
            completedAt: lruJob.completed_at,
          };
    
          // Add errors if any
          if (lruJob.errors && lruJob.errors.length > 0) {
            data.result.results = [
              ...(data.result.results ?? []),
              ...lruJob.errors.map((e) => ({
                index: e.index,
                success: false,
                error: e.error,
              })),
            ].sort((a, b) => a.index - b.index);
          }
        }
    
        // Add error if failed
        if (lruJob.status === "failed" && lruJob.errors && lruJob.errors.length > 0) {
          data.failedReason = lruJob.errors[0]?.error?.message ?? "Unknown error";
        }
    
        return {
          success: true,
          data,
          metadata: {
            request_id: requestId,
            redis_used: false,
            lru_fallback: true,
          },
        };
      }
    
      // Job not found in either BullMQ or LRU store
      if (isDevelopment()) {
        logger.debug("[MCP Tool] quality.getJobStatus job not found", { jobId, requestId });
      }
    
      return createErrorResponseWithRequestId(
        GET_QUALITY_JOB_STATUS_ERROR_CODES.JOB_NOT_FOUND,
        `Job with ID ${jobId} not found. It may have expired (jobs are retained for 24 hours) or never existed.`,
        requestId
      );
    }
  • Tool definition and input schema for 'quality.getJobStatus'.
    export const qualityGetJobStatusToolDefinition = {
      name: "quality.getJobStatus",
      description: `Check the status of an async batch quality evaluation job.
    
    Use this tool to poll for the status and results of a job that was submitted
    with quality.batch_evaluate.
    
    Returns:
    - Job state (waiting, active, completed, failed)
    - Progress percentage (0-100)
    - Item counts (total, processed, success, failed)
    - Result summary when completed
    - Error details when failed
    
    Note: When Redis is unavailable, falls back to LRU store (in-memory).
    Jobs in LRU store are not persisted across server restarts.`,
      inputSchema: {
        type: "object" as const,
        properties: {
          job_id: {
            type: "string",
            format: "uuid",
            description: "The job ID returned by quality.batch_evaluate",
          },
        },
        required: ["job_id"],
        additionalProperties: false,
      },
      annotations: {
        title: "Quality Get Job Status",
        readOnlyHint: true,
        idempotentHint: true,
        openWorldHint: false,
      },
    };
  • Registration of the 'quality.getJobStatus' tool within the MCP server's tool registry.
    // quality.getJobStatus(Phase 3-5 一括評価ジョブステータス確認)
    "quality.getJobStatus": qualityGetJobStatusHandler,

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/TKMD/reftrix-mcp'

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