Exa MCP server returns `title: null` for tools, breaking Dify's MCP integration

未关闭
#42,453 3 条评论 1 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
52/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
python
领域
api, backend

调研方向

Start at the MCP tool conversion path and provider registration flow described in the issue, then reproduce with https://mcp.exa.ai/mcp and Server ID exa-search. Trace how absent title, meta, and outputSchema fields become null and how registration persists rows; done means optional fields remain absent, title falls back to the tool name, failed validation leaves no broken row, and the MCP page can render and delete malformed entries.

由索引模型根据 Issue 内容生成。

描述

🐞 bug
Self Checks
  • I have read the Contributing Guide and Language Policy.
  • This is only for bug report, if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report, otherwise it will be closed.
  • 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
  • Please do not modify this template :) and fill in all the required fields.
Dify version

1.17.0 Plugin daemon: langgenius/dify-plugin-daemon:0.6

Cloud or Self Hosted

Self Hosted (Docker)

Steps to reproduce

In Dify, add a new HTTP MCP server with URL https://mcp.exa.ai/mcp and Server ID exa-search.
Save.
The MCP server returns this raw response (verified with curl directly against Exa's endpoint):

json
{
"result": {
"tools": [
{
"name": "web_search_exa",
"description": "Search the web for any topic...",
"inputSchema": { ... },
"annotations": { ... },
"execution": { ... }
}
]
},
"jsonrpc": "2.0",
"id": 1
}
Note: no title key at all.

✔️ Expected Behavior

Expected Behavior

Optional fields absent from the MCP server response should remain absent in Dify's internal representation, not be coerced to null.
If title is legitimately null or absent, fall back to the tool's name for display.
Provider registration should be transactional — a validation failure should not persist a broken row.
The Tools → MCP page should always render, even if a provider record is malformed, and allow deletion of the offending entry.
Suggested Fix

In the MCP tool conversion path, replace patterns like:

python
title = tool.get("title") # returns None if absent
with:

python
title = tool.get("title") or {"en_US": tool["name"]}
Or, if the code deliberately distinguishes absent from null, use:

python
title = tool["title"] if "title" in tool else None
and handle None at the point of I18nObject construction rather than serializing null into the intermediate representation.

❌ Actual Behavior

Observed Behavior

Dify's registration fails with:

text
[{"type":"missing","loc":["provider_id"],"msg":"Field required","input":{},"url":"https://errors.pydantic.dev/2.12/v/missing"}]
A row is persisted in tool_mcp_providers, but it contains Dify-injected null fields:

json
{
"name": "web_search_exa",
"title": null,
"meta": null,
"outputSchema": null,
...
}
Dify's client apparently calls tool.get("title"), tool.get("meta"), and tool.get("outputSchema") and serializes missing keys as JSON null — instead of omitting them. The title null then fails I18nObject validation during the provider registration step.

主要语言
TypeScript
星标
157k
派生
24.7k
平均合并
22 小时 32 分钟
30 天内合并 PR
611

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

langgenius/dify 的其他 Issue

查看 langgenius/dify 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。