Skip to content

Commit 68c4475

Browse files
committed
fix(prompts): await awaitable result returned by sync prompt callback (#3709)
Closes #3709.
1 parent 2af9e30 commit 68c4475

2 files changed

Lines changed: 22 additions & 0 deletions

File tree

‎src/mcp/server/mcpserver/prompts/base.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from __future__ import annotations
44

55
import functools
6+
import inspect
67
from collections.abc import Awaitable, Callable, Sequence
78
from typing import TYPE_CHECKING, Annotated, Any, Literal
89

@@ -188,6 +189,9 @@ async def render(
188189
else:
189190
result = await anyio.to_thread.run_sync(functools.partial(self.fn, **call_args))
190191

192+
if inspect.isawaitable(result):
193+
result = await result
194+
191195
if isinstance(result, InputRequiredResult):
192196
return result
193197

‎tests/server/mcpserver/prompts/test_base.py‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import threading
2+
from collections.abc import Awaitable
23
from pathlib import Path
34
from typing import Any
45

@@ -332,3 +333,20 @@ def fn() -> Image:
332333

333334
with pytest.raises(ValueError):
334335
await Prompt.from_function(fn).render(None, Context())
336+
337+
338+
@pytest.mark.anyio
339+
async def test_prompt_render_awaits_awaitable_returned_by_sync_callback():
340+
async def resolve() -> list[str]:
341+
return []
342+
343+
coroutine = resolve()
344+
345+
def prompt() -> Awaitable[list[str]]:
346+
return coroutine
347+
348+
try:
349+
messages = await Prompt.from_function(prompt).render(None, Context())
350+
finally:
351+
coroutine.close()
352+
assert messages == []

0 commit comments

Comments
 (0)