-
Notifications
You must be signed in to change notification settings - Fork 0
Async Jobs
Long-running MATLAB code is automatically handled through the async job system.
- You call
execute_codewith your MATLAB code - The server starts executing synchronously
- If execution exceeds
sync_timeout(default 30 seconds), the job is promoted to async - You get back a
job_idimmediately - Poll
get_job_statusfor progress updates and job status - Call
get_job_resultwhen the job completes
PENDING → RUNNING → COMPLETED
→ FAILED
→ CANCELLED
- PENDING: Job created, waiting to acquire an engine
- RUNNING: Engine acquired, code is executing (either sync or async background)
- COMPLETED: Code finished successfully with a result
- FAILED: Code execution raised an error
-
CANCELLED: Job was explicitly cancelled via
cancel_job
- Job is created and marked RUNNING
- An engine is acquired from the pool
- Job context is injected into the MATLAB workspace
- Code executes in the foreground via
engine.execute(code, background=True) - Server waits up to
sync_timeoutseconds (default 30s) - If code completes within the timeout:
- Result is captured immediately
- Job is marked COMPLETED
- Engine is released back to the pool
- Response includes full result:
{"status": "completed", "job_id": "...", ...result}
- If foreground execution exceeds
sync_timeout, the job is promoted to async - A background task is spawned to continue monitoring the execution
- Server releases the engine back to the pool (other requests can use it)
- Response returns immediately:
{"status": "pending", "job_id": "..."} - Client polls
get_job_statusto monitor progress - When execution completes (or fails), the background task:
- Captures the final result
- Marks job COMPLETED or FAILED
- Releases the engine
Use the mcp_progress() helper function in your MATLAB code to report execution 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 (string)
-
mcp_progress.mwrites a JSON file to__mcp_temp_dir__/<job_id>.progress -
get_job_statusreads this file and includesprogressandmessagein the response - The progress file is automatically cleaned up when the job completes
- Progress updates are useful for long-running jobs to keep the agent informed
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", output: "0.5023", ...}
Call get_job_status to check the current status of a job:
{
"status": "running",
"job_id": "j-abc123...",
"progress": 45,
"message": "Processing batch 5 of 10"
}Fields:
-
status— Current job status (pending, running, completed, failed, cancelled) -
job_id— The job identifier -
progress— Percentage 0-100 (ifmcp_progress()was called) -
message— Status message (ifmcp_progress()was called) -
error— Error details if status is "failed"
Call get_job_result to retrieve the complete result of a completed job:
{
"status": "completed",
"job_id": "j-abc123...",
"text": "ans =\n 0.5023",
"workspace": {
"results": [[...array data...]],
"n": 1000000
}
}Fields:
-
status— Terminal status (completed, failed, or cancelled) -
job_id— The job identifier -
text— Captured stdout from execution -
workspace— Variables that were assigned during execution -
error— Error details if status is "failed" (includes type, message, matlab_id, stack_trace)
Note: Results are retained for job_retention_seconds (default 86400 / 24 hours) after completion. Older job results are automatically pruned.
Call cancel_job to cancel a PENDING or RUNNING job:
{
"status": "cancelled",
"job_id": "j-abc123..."
}- Only jobs in PENDING or RUNNING status can be cancelled
- Cancelling a RUNNING job stops the MATLAB code execution
- The job transitions to CANCELLED status
- The result cannot be retrieved after cancellation
Call list_jobs to retrieve all jobs in the current session:
{
"jobs": [
{
"job_id": "j-abc123...",
"status": "completed",
"created_at": 1699564800.5,
"started_at": 1699564801.2,
"completed_at": 1699564810.8,
"elapsed_seconds": 9.6
},
{
"job_id": "j-def456...",
"status": "running",
"created_at": 1699564815.1,
"started_at": 1699564815.9,
"elapsed_seconds": 120.3
}
]
}Each job entry includes timing information and current status.
The job tracker maintains both active and historical job metadata:
- Active jobs: PENDING and RUNNING jobs are kept indefinitely while active
-
Terminal jobs: COMPLETED, FAILED, and CANCELLED jobs are retained for
job_retention_seconds(default 86400 / 24 hours) - Automatic pruning: The tracker periodically removes expired terminal jobs to prevent unbounded memory growth
- Session isolation: Each session maintains its own job history
To adjust retention, configure:
sessions:
job_retention_seconds: 86400 # 24 hours (default)| Tool | Description |
|---|---|
execute_code |
Submit code for execution (returns immediately with job_id) |
get_job_status |
Current status, progress %, and message for a job |
get_job_result |
Full result of a completed/failed/cancelled job |
cancel_job |
Cancel a pending or running job |
list_jobs |
List all jobs in the session with timing info |
execution:
sync_timeout: 30 # Seconds before async promotion (default)
max_execution_time: 86400 # Hard limit on total execution time (24h default)
sessions:
job_retention_seconds: 86400 # Keep terminal job metadata for 24h (default)- Short code (< 30s): Results return inline in the execute response, no polling needed
-
Medium code (30s - minutes): Auto-promoted to async, poll with
get_job_statusfor progress -
Long code (hours): Add
mcp_progress()calls so the agent can monitor execution and estimate completion time -
Cancel long jobs: Call
cancel_jobif you need to stop a running job and free the engine -
Increase timeout: Set
sync_timeout: 60(or higher) if most of your code takes 30-60 seconds, to avoid unnecessary promotion -
Check retention: Monitor
list_jobsto see how much history is retained; adjustjob_retention_secondsif needed