Summary
fit_predict_async_tool and load_data_source_async_tool return a job_id
saying the job started. But the job never runs — it stays "pending" forever.
The problem is that both tools submit coroutines to an event loop that is never
started in a background thread.
Steps to Reproduce
import sys, time
sys.path.insert(0, "src")
from sktime_mcp.runtime.executor import get_executor
executor = get_executor()
result = executor.fit_predict_async({
"dataset": "airline",
"estimator": "NaiveForecaster",
"horizon": 12
})
job_id = result["job_id"]
time.sleep(0.5)
print(executor.get_job_status({"job_id": job_id})["status"]) # pending
time.sleep(2.0)
print(executor.get_job_status({"job_id": job_id})["status"]) # still pending
What's Happening
In fit_predict.py and data_tools.py:
loop = asyncio.get_event_loop() # gets a loop — but never runs it
asyncio.run_coroutine_threadsafe(coro, loop) # submits to a stopped loop
# coroutine sits in queue forever
run_coroutine_threadsafe only works if the loop is actively running
in another thread. There is no such thread started anywhere, so jobs never execute.
Expected vs Actual
|
Expected |
Actual |
| Job status after 2 seconds |
running / completed |
pending |
| Coroutine executes |
Yes |
Never |
| Async workflows usable by LLM |
Yes |
Completely broken |
Suggested Fix
Add a shared background event loop thread at server startup:
# src/sktime_mcp/runtime/_background_loop.py
import asyncio, threading
class _BackgroundLoop:
def __init__(self):
self._loop = asyncio.new_event_loop()
self._thread = threading.Thread(
target=self._loop.run_forever, daemon=True
)
self._thread.start()
def submit(self, coro):
return asyncio.run_coroutine_threadsafe(coro, self._loop)
BG_LOOP = _BackgroundLoop()
Then in fit_predict.py and data_tools.py replace:
# Old broken code:
loop = asyncio.get_event_loop()
asyncio.run_coroutine_threadsafe(coro, loop)
# New working code:
from sktime_mcp.runtime._background_loop import BG_LOOP
BG_LOOP.submit(coro)
Related Issues
Environment
- sktime-mcp: 0.1.0
- Python: 3.12.9
- sktime: 0.40.1
- mcp: 1.27.0
- OS: Windows
Summary
fit_predict_async_toolandload_data_source_async_toolreturn ajob_idsaying the job started. But the job never runs — it stays "pending" forever.
The problem is that both tools submit coroutines to an event loop that is never
started in a background thread.
Steps to Reproduce
What's Happening
In
fit_predict.pyanddata_tools.py:run_coroutine_threadsafeonly works if the loop is actively runningin another thread. There is no such thread started anywhere, so jobs never execute.
Expected vs Actual
Suggested Fix
Add a shared background event loop thread at server startup:
Then in
fit_predict.pyanddata_tools.pyreplace:Related Issues
asyncio.get_event_loop) in sync entrypoints #65 — asyncio deprecation warning (different: that PR fixes warning but not root cause)Environment