Skip to content

Async Jobs

github-actions[bot] edited this page Mar 22, 2026 · 11 revisions

Async Jobs

Long-running MATLAB code is automatically handled through the async job system.

How It Works

  1. You call execute_code with your MATLAB code
  2. The server starts executing synchronously in the background
  3. If execution exceeds sync_timeout (default 30 seconds), the job is promoted to async
  4. You get back a job_id immediately
  5. Poll get_job_status for progress updates
  6. Call get_job_result when the job completes

Job Lifecycle

PENDING → RUNNING → COMPLETED
                  → FAILED
                  → CANCELLED

Terminal states: COMPLETED, FAILED, CANCELLED

Active states: PENDING, RUNNING

Sync Execution

Short-running code (under sync_timeout) executes synchronously:

  1. A job is created and marked PENDING
  2. An engine is acquired from the pool
  3. Job context is injected into the MATLAB workspace (__mcp_job_id__, __mcp_temp_dir__)
  4. Code executes with stdout/stderr captured
  5. Result is returned inline with status: "completed"
{
  "status": "completed",
  "job_id": "j-abc123...",
  "text": "0.5023",
  "variables": {...}
}

Async Promotion

When a job exceeds sync_timeout:

  1. The job transitions to RUNNING state
  2. A background task is created to monitor the execution
  3. The engine is held by the background task (not released)
  4. An immediate response is returned with status: "pending"
  5. The client polls for status updates
{
  "status": "pending",
  "job_id": "j-abc123..."
}

The background task continues executing and will eventually mark the job as COMPLETED, FAILED, or CANCELLED.

Job Status Polling

Use get_job_status to check job progress:

{
  "job_id": "j-abc123...",
  "status": "running",
  "progress": 45,
  "message": "Processed 450000/1000000 items",
  "elapsed_seconds": 12.5
}

Poll periodically until status is terminal (COMPLETED, FAILED, or CANCELLED).

Progress Reporting

Use the mcp_progress() helper function in your MATLAB code to report progress back to the agent:

mcp_progress(__mcp_job_id__, percentage, message)
  • __mcp_job_id__ — automatically injected into the workspace by the server
  • percentage — number from 0 to 100
  • message — optional status message

Example

n = 1e6;
results = zeros(n, 1);
for i = 1:n
    results(i) = process_item(i);
    if mod(i, 1e5) == 0
        mcp_progress(__mcp_job_id__, i/n*100, ...
            sprintf('Processed %d/%d items', i, n));
    end
end
disp(mean(results));

The agent sees:

get_job_status → {status: "running", progress: 10, message: "Processed 100000/1000000 items"}
get_job_status → {status: "running", progress: 50, message: "Processed 500000/1000000 items"}
get_job_status → {status: "running", progress: 100, message: "Processed 1000000/1000000 items"}
get_job_result → {status: "completed", text: "0.5023", ...}

How Progress Works Internally

  1. mcp_progress.m writes a JSON file to __mcp_temp_dir__/<job_id>.progress
  2. get_job_status reads this file and includes progress in the response
  3. The file is cleaned up when the job completes

Job Result Retrieval

Use get_job_result to retrieve the full result of a completed job:

{
  "status": "completed",
  "job_id": "j-abc123...",
  "text": "0.5023",
  "variables": {
    "results": [...],
    "n": 1000000
  },
  "elapsed_seconds": 45.2
}

For failed jobs:

{
  "status": "failed",
  "job_id": "j-abc123...",
  "error": {
    "type": "MATLAB:UndefinedVariable",
    "message": "Undefined variable 'results'",
    "matlab_id": "MATLAB:UndefinedVariable",
    "stack_trace": "Error in mycode (line 5)..."
  },
  "elapsed_seconds": 2.1
}

Job Cancellation

Use cancel_job to stop a job that is PENDING or RUNNING:

{
  "status": "cancelled",
  "job_id": "j-abc123...",
  "message": "Job cancelled by user"
}

Once a job reaches a terminal state (COMPLETED, FAILED, or CANCELLED), it cannot be cancelled.

Job Management Tools

Tool Description
execute_code Execute MATLAB code (sync or async)
get_job_status Current status + progress percentage + elapsed time
get_job_result Full result of a completed job
cancel_job Cancel a pending or running job
list_jobs List all jobs in the session

Retention and Cleanup

Completed, failed, and cancelled jobs are retained in the tracker for a configurable period:

sessions:
  job_retention_seconds: 86400  # Keep job metadata for 24 hours (default)

After this period, jobs are automatically pruned. The pruning process removes:

  • Job metadata (status, result, error, timings)
  • Progress files from the temporary directory

Active jobs (PENDING, RUNNING) are never pruned.

Configuration

execution:
  sync_timeout: 30           # Seconds before async promotion (default)
  max_execution_time: 86400  # Hard limit (24 hours)

sessions:
  job_retention_seconds: 86400  # Keep job metadata for 24h after completion

Tips

  • Short code (< 30s): Results return inline, no polling needed
  • Medium code (30s - minutes): Auto-promoted to async, poll with get_job_status
  • Long code (hours): Add mcp_progress() calls so the agent can monitor status
  • Cancel: Call cancel_job if you need to stop a running job before it completes
  • Increase timeout: Set sync_timeout: 60 if most of your code runs 30-60 seconds
  • Check active jobs: Use list_jobs to see all jobs in the current session
  • Monitor performance: Check elapsed_seconds in status and result responses

Clone this wiki locally