[Bug][Fixed] mcp服务异常mcp.shared.exceptions.McpError: Session terminated

Open Beginner friendly
#9,859 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
72/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
docker, python
Domain
backend

Research direction

Start with astrbot/core/agent/mcp_client.py, especially call_tool_with_reconnect and the retry and exception-handling points identified in the report. Reproduce with the listed streamable_http configuration and review the Session terminated logs. Done means the MCP service reconnects and the tool call succeeds after the container is restarted.

Written by the indexing model from the issue text.

Description

area:core bug
问题描述

docker使用镜像源部署,添加https://mcpmarket.cn的mcp服务的时候发现mcp.shared.exceptions.McpError: Session terminated。
临时修复:容器内运行

cd /tmp && cat > fix_mcp.py << 'PYEOF'
import io

path = "/AstrBot/astrbot/core/agent/mcp_client.py"
src = io.open(path, encoding="utf-8").read()

# 1. 顶部加 import
if "from mcp.shared.exceptions import McpError" not in src:
    assert "import httpx\n" in src, "import anchor not found"
    src = src.replace(
        "import httpx\n",
        "import httpx\nfrom mcp.shared.exceptions import McpError\n",
        1,
    )

# 2. 扩大重试条件
old_retry = "retry=retry_if_exception_type(anyio.ClosedResourceError),"
new_retry = "retry=retry_if_exception_type((anyio.ClosedResourceError, TimeoutError, McpError)),"
assert src.count(old_retry) == 1, "retry anchor not found"
src = src.replace(old_retry, new_retry)

# 3. 扩大异常捕获并加重连保护
old_exc = """            except anyio.ClosedResourceError:
                logger.warning(
                    f"MCP tool {tool_name} call failed (ClosedResourceError), attempting to reconnect..."
                )
                # Attempt to reconnect
                await self._reconnect()
                # Reraise the exception to trigger tenacity retry
                raise"""
new_exc = """            except (anyio.ClosedResourceError, TimeoutError, McpError) as e:
                logger.warning(
                    f"MCP tool {tool_name} call failed ({type(e).__name__}: {e}), attempting to reconnect..."
                )
                # Attempt to reconnect (best effort, don't mask the original error)
                try:
                    await self._reconnect()
                except Exception as re:
                    logger.error(f"Reconnect failed: {re}")
                # Reraise the exception to trigger tenacity retry
                raise"""
assert src.count(old_exc) == 1, "except anchor not found"
src = src.replace(old_exc, new_exc)

io.open(path, "w", encoding="utf-8").write(src)
print("OK: 三处修改全部完成")
PYEOF
python fix_mcp.py

重启容器后得到解决

如何复现?

正常docker部署,用镜像源m.daocloud.io/docker.io/soulter/astrbot:latest+m.daocloud.io/docker.io/mlikiowa/napcat-docker:latest(版本对应为4.27.4),添加配置:
root@663fab43182d:/AstrBot/data# cat mcp_server.json
{
"mcpServers": {
"高德地图": {
"active": true,
"transport": "streamable_http",
"url": "https://mcpmarket.cn/mcp/688537b7d00f731bbe02e03e",
"headers": {},
"timeout": 5,
"sse_read_timeout": 300
},
"天气查询": {
"active": true,
"transport": "streamable_http",
"url": "https://mcpmarket.cn/mcp/5b3f77de1dac10ca4f373352",
"headers": {},
"timeout": 5,
"sse_read_timeout": 300
},
"12306服务": {
"active": true,
"transport": "streamable_http",
"url": "https://mcpmarket.cn/mcp/6e628a618abaac31b04789e4",
"headers": {},
"timeout": 5,
"sse_read_timeout": 300
},
"MarkitDown": {
"active": true,
"transport": "streamable_http",
"url": "https://mcpmarket.cn/mcp/bfd0296c9522e068abfc6178",
"headers": {},
"timeout": 5,
"sse_read_timeout": 300
},
"百度搜索": {
"active": true,
"transport": "streamable_http",
"url": "https://mcpmarket.cn/mcp/559f4b2ecdd8d3b2efd477fa",
"headers": {},
"timeout": 5,
"sse_read_timeout": 300
}
}
}
在对话中服务不可用。

AstrBot 版本

v4.27.4

操作系统

Linux

部署方式

docker

使用的消息平台适配器

Onebot v11

错误日志
[2026-08-27 07:00:07.922] [Core]
[INFO]
[runners.tool_loop_agent_runner:1152]: 使用工具:get_weather_forecast,参数:{'latitude': 31.4914, 'longitude': 120.3119, 'days': 1, 'hourly_vars': 'temperature_2m,precipitation,windspeed_10m,weathercode,relative_humidity_2m'}
[2026-08-27 07:00:08.078] [Core]
[WARN]
[v4.27.4] [runners.tool_loop_agent_runner:1324]: Traceback (most recent call last):
  File "/AstrBot/astrbot/core/agent/runners/tool_loop_agent_runner.py", line 1206, in _handle_function_tools
    async for resp in self._iter_tool_executor_results(executor):  # type: ignore
  File "/AstrBot/astrbot/core/agent/runners/tool_loop_agent_runner.py", line 1561, in _iter_tool_executor_results
    yield next_result_task.result()
          ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/AstrBot/astrbot/core/agent/runners/tool_loop_agent_runner.py", line 1531, in _next_executor_result
    return await anext(executor)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/AstrBot/astrbot/core/astr_agent_tool_exec.py", line 185, in execute
    async for r in cls._execute_local(tool, run_context, **tool_args):
  File "/AstrBot/astrbot/core/astr_agent_tool_exec.py", line 666, in _execute_local
    resp = await asyncio.wait_for(
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/asyncio/tasks.py", line 520, in wait_for
    return await fut
           ^^^^^^^^^
  File "/AstrBot/astrbot/core/astr_agent_tool_exec.py", line 807, in call_local_llm_tool
    ret = await ready_to_call
          ^^^^^^^^^^^^^^^^^^^
  File "/AstrBot/astrbot/core/provider/func_tool_manager.py", line 269, in call
    return await self._wrapped.call(context, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/AstrBot/astrbot/core/agent/mcp_client.py", line 817, in call
    return await self.mcp_client.call_tool_with_reconnect(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/AstrBot/astrbot/core/agent/mcp_client.py", line 774, in call_tool_with_reconnect
    return await _call_with_retry()
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/tenacity/asyncio/__init__.py", line 193, in async_wrapped
    return await copy(fn, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/tenacity/asyncio/__init__.py", line 112, in __call__
    do = await self.iter(retry_state=retry_state)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/tenacity/asyncio/__init__.py", line 157, in iter
    result = await action(retry_state)
             ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/tenacity/_utils.py", line 111, in inner
    return call(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/tenacity/__init__.py", line 393, in <lambda>
    self._add_action_func(lambda rs: rs.outcome.result())
                                     ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/concurrent/futures/_base.py", line 449, in result
    return self.__get_result()
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/usr/local/lib/python3.12/site-packages/tenacity/asyncio/__init__.py", line 116, in __call__
    result = await fn(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/AstrBot/astrbot/core/agent/mcp_client.py", line 760, in _call_with_retry
    return await self.session.call_tool(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/mcp/client/session.py", line 401, in call_tool
    result = await self.send_request(
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/mcp/shared/session.py", line 306, in send_request
    raise McpError(response_or_error.error)
mcp.shared.exceptions.McpError: Session terminated
[2026-08-27 07:00:08.079] [Core]
[INFO]
[runners.tool_loop_agent_runner:1349]: Tool `get_weather_forecast` Result: error: Session terminated
[2026-08-28 07:00:05.933] [Core]
[INFO]
[runners.tool_loop_agent_runner:1096]: Agent 使用工具: ['get-current-date', 'get_weather_forecast']
[2026-08-28 07:00:05.933] [Core]
[INFO]
[runners.tool_loop_agent_runner:1152]: 使用工具:get-current-date,参数:{}
[2026-08-28 07:02:05.975] [Core]
[WARN]
[v4.27.4] [runners.tool_loop_agent_runner:1324]: Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/anyio/streams/memory.py", line 118, in receive
    return self.receive_nowait()
           ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/anyio/streams/memory.py", line 113, in receive_nowait
    raise WouldBlock
anyio.WouldBlock

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.12/asyncio/tasks.py", line 520, in wait_for
    return await fut
           ^^^^^^^^^
  File "/AstrBot/astrbot/core/astr_agent_tool_exec.py", line 807, in call_local_llm_tool
    ret = await ready_to_call
          ^^^^^^^^^^^^^^^^^^^
  File "/AstrBot/astrbot/core/provider/func_tool_manager.py", line 269, in call
    return await self._wrapped.call(context, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/AstrBot/astrbot/core/agent/mcp_client.py", line 817, in call
    return await self.mcp_client.call_tool_with_reconnect(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/AstrBot/astrbot/core/agent/mcp_client.py", line 774, in call_tool_with_reconnect
    return await _call_with_retry()
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/tenacity/asyncio/__init__.py", line 193, in async_wrapped
    return await copy(fn, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/tenacity/asyncio/__init__.py", line 112, in __call__
    do = await self.iter(retry_state=retry_state)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/tenacity/asyncio/__init__.py", line 157, in iter
    result = await action(retry_state)
             ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/tenacity/_utils.py", line 111, in inner
    return call(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/tenacity/__init__.py", line 393, in <lambda>
    self._add_action_func(lambda rs: rs.outcome.result())
                                     ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/concurrent/futures/_base.py", line 449, in result
    return self.__get_result()
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/usr/local/lib/python3.12/site-packages/tenacity/asyncio/__init__.py", line 116, in __call__
    result = await fn(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/AstrBot/astrbot/core/agent/mcp_client.py", line 760, in _call_with_retry
    return await self.session.call_tool(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/mcp/client/session.py", line 401, in call_tool
    result = await self.send_request(
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/mcp/shared/session.py", line 292, in send_request
    response_or_error = await response_stream_reader.receive()
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/anyio/streams/memory.py", line 126, in receive
    await receive_event.wait()
  File "/usr/local/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 1866, in wait
    await self._event.wait()
  File "/usr/local/lib/python3.12/asyncio/locks.py", line 212, in wait
    await fut
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/AstrBot/astrbot/core/astr_agent_tool_exec.py", line 666, in _execute_local
    resp = await asyncio.wait_for(
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/asyncio/tasks.py", line 519, in wait_for
    async with timeouts.timeout(timeout):
               ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/asyncio/timeouts.py", line 115, in __aexit__
    raise TimeoutError from exc_val
TimeoutError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/AstrBot/astrbot/core/agent/runners/tool_loop_agent_runner.py", line 1206, in _handle_function_tools
    async for resp in self._iter_tool_executor_results(executor):  # type: ignore
  File "/AstrBot/astrbot/core/agent/runners/tool_loop_agent_runner.py", line 1561, in _iter_tool_executor_results
    yield next_result_task.result()
          ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/AstrBot/astrbot/core/agent/runners/tool_loop_agent_runner.py", line 1531, in _next_executor_result
    return await anext(executor)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/AstrBot/astrbot/core/astr_agent_tool_exec.py", line 185, in execute
    async for r in cls._execute_local(tool, run_context, **tool_args):
  File "/AstrBot/astrbot/core/astr_agent_tool_exec.py", line 699, in _execute_local
    raise Exception(
Exception: tool get-current-date execution timeout after 120 seconds.
[2026-08-28 07:02:05.976] [Core]
[INFO]
[runners.tool_loop_agent_runner:1349]: Tool `get-current-date` Result: error: tool get-current-date execution timeout after 120 seconds.
[2026-08-28 07:02:05.992] [Core]
[INFO]
辅助信息

No response

检查清单
  • 我已在 Issue 列表中搜索过相关问题仍无法解决,或该问题从未被报告过。
  • 我已尝试过禁用所有插件,排除了可能是因插件导致的问题。
  • 我报告的问题与 AstrBot 本体相关,而非在报告某一插件的问题。
  • 我已阅读并同意本项目的贡献者行为准则
  • (可选)我愿意提交 PR 以帮助修复该问题。
Dominant language
Python
Stars
40.7k
Forks
2.9k
Avg merge
1d 5h
Merged PRs (30d)
112

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from AstrBotDevs/AstrBot

All issues in AstrBotDevs/AstrBot

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.