Skip to content

fix: 修复了MCP工具对http/sse的兼容性问题#7712

Open
hjdhnx wants to merge 11 commits intoAstrBotDevs:masterfrom
hjdhnx:master
Open

fix: 修复了MCP工具对http/sse的兼容性问题#7712
hjdhnx wants to merge 11 commits intoAstrBotDevs:masterfrom
hjdhnx:master

Conversation

@hjdhnx
Copy link
Copy Markdown
Contributor

@hjdhnx hjdhnx commented Apr 21, 2026

Modifications / 改动点

修改了astrbot/core/agent/mcp_client.py,去除了SSL验证,防止http/sse 格式的MCP服务不可用

  • This is NOT a breaking change. / 这不是一个破坏性变更。

Screenshots or Test Results / 运行截图或测试结果

image

Checklist / 检查清单

  • 😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
    / 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。

  • 👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
    / 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”

  • 🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
    / 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到 requirements.txtpyproject.toml 文件相应位置。

  • 😮 My changes do not introduce malicious code.
    / 我的更改没有引入恶意代码。

Summary by Sourcery

Improve MCP HTTP/SSE client compatibility by customizing the underlying HTTP client configuration.

Bug Fixes:

  • Ensure MCP HTTP and SSE transports work with endpoints that fail standard SSL verification by using a non-verifying HTTP client when available.

Enhancements:

  • Unify HTTP client configuration for SSE and streamable HTTP transports via shared client factory options.

Taois and others added 10 commits April 20, 2026 13:44
1. 常见的openai和anthropic协议,如 智谱的codingpan
https://open.bigmodel.cn/api/coding/paas/v4
2. 新出的一些没有模型列表的自定义模型提供商,如科大讯飞
https://maas-coding-api.cn-huabei-1.xf-yun.com/v2
# Conflicts:
#	astrbot/core/utils/network_utils.py
已知:
  根因:系统有代理 127.0.0.1:7890,mcp 库底层用 httpx 会自动走代理,但代理的 SSL 证书不被 Python 信任,导致 SSL 验证失败 → 抛出 CancelledError(BaseException 子类) → 绕过
  except Exception → Quart 返回 HTTP 500。

  修复: 在 mcp_client.py 中新增了 _create_no_verify_httpx_client 工厂函数(verify=False),通过 httpx_client_factory 参数传给 sse_client 和 streamablehttp_client,跳过 SSL
  证书验证。
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. area:core The bug / feature is about astrbot's core, backend labels Apr 21, 2026
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • Disabling SSL verification globally via _create_no_verify_httpx_client is a significant security relaxation; consider making this opt-in via config (e.g., verify_ssl: false) or only using it for http:// endpoints while preserving verification for https://.
  • Instead of hardcoding verify=False, it may be better to expose verify (or a CA bundle path) as a parameter in cfg and pass it through to the HTTP client so users can choose between strict verification, custom certs, or no verification.
  • When _create_no_verify_httpx_client is unavailable, the behavior silently falls back to the default client; consider logging or surfacing this difference so users understand that SSL verification is still enforced in that case.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Disabling SSL verification globally via `_create_no_verify_httpx_client` is a significant security relaxation; consider making this opt-in via config (e.g., `verify_ssl: false`) or only using it for `http://` endpoints while preserving verification for `https://`.
- Instead of hardcoding `verify=False`, it may be better to expose `verify` (or a CA bundle path) as a parameter in `cfg` and pass it through to the HTTP client so users can choose between strict verification, custom certs, or no verification.
- When `_create_no_verify_httpx_client` is unavailable, the behavior silently falls back to the default client; consider logging or surfacing this difference so users understand that SSL verification is still enforced in that case.

## Individual Comments

### Comment 1
<location path="astrbot/core/agent/mcp_client.py" line_range="122" />
<code_context>
+    ) -> _httpx.AsyncClient:
+        kwargs: dict[str, Any] = {
+            "follow_redirects": True,
+            "verify": False,
+        }
+        if timeout is None:
</code_context>
<issue_to_address>
**🚨 issue (security):** Reconsider disabling TLS verification by default in the shared HTTPX client factory.

Setting `verify=False` here forces all callers to skip TLS certificate verification, which is unsafe as a default. If you need to support self‑signed certs, consider instead:

- Exposing `verify` as a parameter that defaults to `True`, so call sites explicitly opt into `False`, or
- Accepting a custom CA bundle while keeping verification enabled.

As written, this factory silently weakens TLS security for all consumers, which is risky for production use.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

) -> _httpx.AsyncClient:
kwargs: dict[str, Any] = {
"follow_redirects": True,
"verify": False,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 issue (security): Reconsider disabling TLS verification by default in the shared HTTPX client factory.

Setting verify=False here forces all callers to skip TLS certificate verification, which is unsafe as a default. If you need to support self‑signed certs, consider instead:

  • Exposing verify as a parameter that defaults to True, so call sites explicitly opt into False, or
  • Accepting a custom CA bundle while keeping verification enabled.

As written, this factory silently weakens TLS security for all consumers, which is risky for production use.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a helper function to create an httpx client with SSL verification disabled and refactors the MCP client to use this factory for SSE and streamable HTTP connections. Review feedback identifies a security vulnerability in hardcoding the disabled verification and suggests making it configurable. Additionally, it is recommended to refactor the SSL logic into a shared utility to ensure consistency with connection tests and to include unit tests for the new functionality.

) -> _httpx.AsyncClient:
kwargs: dict[str, Any] = {
"follow_redirects": True,
"verify": False,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

强制禁用 SSL 验证(verify=False)会使连接面临中间人攻击(MITM)的风险。建议通过配置项(例如从 cfg 中读取)来动态控制是否启用验证,而不是全局硬编码为 False

Comment on lines +471 to +474
if _create_no_verify_httpx_client is not None:
_http_client_kwargs["httpx_client_factory"] = (
_create_no_verify_httpx_client
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

此处的改动旨在通过自定义 httpx_client_factory 来跳过 SSL 验证,但 _quick_test_mcp_connection 仍然使用默认配置,这会导致连接测试失败。根据通用规则,建议将 SSL 配置逻辑重构为共享的辅助函数,以避免代码重复并确保逻辑一致性。

References
  1. When implementing similar functionality for different cases (e.g., direct vs. quoted attachments), refactor the logic into a shared helper function to avoid code duplication.

Comment on lines +115 to +132
def _create_no_verify_httpx_client(
headers: dict[str, str] | None = None,
timeout: _httpx.Timeout | None = None,
auth: _httpx.Auth | None = None,
) -> _httpx.AsyncClient:
kwargs: dict[str, Any] = {
"follow_redirects": True,
"verify": False,
}
if timeout is None:
kwargs["timeout"] = _httpx.Timeout(30, read=300)
else:
kwargs["timeout"] = timeout
if headers is not None:
kwargs["headers"] = headers
if auth is not None:
kwargs["auth"] = auth
return _httpx.AsyncClient(**kwargs)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

根据通用规则,新功能应包含单元测试。建议添加测试用例来验证 MCP 客户端在不同传输协议下对 SSL 验证配置的处理逻辑。

References
  1. New functionality, such as handling attachments, should be accompanied by corresponding unit tests.

@hjdhnx
Copy link
Copy Markdown
Contributor Author

hjdhnx commented Apr 21, 2026

@zouyonghe 大佬来合并一下这个关键修复

@hjdhnx
Copy link
Copy Markdown
Contributor Author

hjdhnx commented Apr 21, 2026

修改前配置 modelscope部署的 mcp服务必定报错如图所示:
image

@hjdhnx
Copy link
Copy Markdown
Contributor Author

hjdhnx commented Apr 21, 2026

#7603 本提交修复此问题

@hjdhnx
Copy link
Copy Markdown
Contributor Author

hjdhnx commented Apr 21, 2026

#5977 应该是同样问题

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core The bug / feature is about astrbot's core, backend size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants