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

オープン
#42,453 コメント 3 件 リアクション 1 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
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分
マージ済み PR(30日)
611

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

langgenius/dify のほかの issue

langgenius/dify の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。