Every call to some MCP servers may take 300s #16332

Closed
opened 2026-02-21 19:25:41 -05:00 by yindo · 5 comments
Owner

Originally created by @Graf2242 on GitHub (Aug 21, 2025).

Originally assigned to: @Nov1c444 on GitHub.

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.7.2

Cloud or Self Hosted

Self Hosted (Docker)

Steps to reproduce

  1. Set up Slack MCP server https://github.com/korotovsky/slack-mcp-server
    (probably any that use https://github.com/mark3labs/mcp-go)
  2. Try to add it in Dify

✔️ Expected Behavior

Server itself respond in a second, so Dify should too.

Actual Behavior

Every call to MCP (including Auth and "get tools") always takes about 300 seconds. The same applies to every individual tool call.

After investigating, I found that the issue occurs because ThreadPoolExecutor waits for all threads to finish, but the sse_reader thread is blocked inside event_source.iter_sse() until the read_timeout expires.

I compared the events inside event_source.iter_sse() between the Slack MCP tool and another tool that responds much faster:

def iter_sse(self) -> Iterator[ServerSentEvent]:
    self._check_content_type()
    decoder = SSEDecoder()
    for line in self._response.iter_lines():
        # Here I compare None and event counts
        line = line.rstrip("\n")
        sse = decoder.decode(line)
        if sse is not None:
            yield sse

Both tools produce the same number and order of None entries, so the differing performance does not appear to come from iter_sse directly.

The root cause may be in SlackMCP itself or in mcp-go. However, i think Dify should remain as failsafe as possible when integrating external MCP tools. I attempted a solution and submit it as a PR, but couldn’t get it to work properly myself.

Originally created by @Graf2242 on GitHub (Aug 21, 2025). Originally assigned to: @Nov1c444 on GitHub. ### Self Checks - [x] I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542). - [x] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general). - [x] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones. - [x] I confirm that I am using English to submit this report, otherwise it will be closed. - [x] 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :) - [x] Please do not modify this template :) and fill in all the required fields. ### Dify version 1.7.2 ### Cloud or Self Hosted Self Hosted (Docker) ### Steps to reproduce 1. Set up Slack MCP server https://github.com/korotovsky/slack-mcp-server (probably any that use https://github.com/mark3labs/mcp-go) 2. Try to add it in Dify ### ✔️ Expected Behavior Server itself respond in a second, so Dify should too. ### ❌ Actual Behavior Every call to MCP (including Auth and "get tools") always takes about 300 seconds. The same applies to every individual tool call. After investigating, I found that the issue occurs because [ThreadPoolExecutor](https://github.com/langgenius/dify/blob/main/api/core/mcp/client/sse_client.py#L279) waits for all threads to finish, but the [sse_reader](https://github.com/langgenius/dify/blob/main/api/core/mcp/client/sse_client.py#L129) thread is blocked inside event_source.iter_sse() until the read_timeout expires. I compared the events inside event_source.iter_sse() between the Slack MCP tool and another tool that responds much faster: ``` def iter_sse(self) -> Iterator[ServerSentEvent]: self._check_content_type() decoder = SSEDecoder() for line in self._response.iter_lines(): # Here I compare None and event counts line = line.rstrip("\n") sse = decoder.decode(line) if sse is not None: yield sse ``` Both tools produce the same number and order of None entries, so the differing performance does not appear to come from iter_sse directly. The root cause may be in SlackMCP itself or in mcp-go. However, i think Dify should remain as failsafe as possible when integrating external MCP tools. I attempted a solution and submit it as a PR, but couldn’t get it to work properly myself.
yindo added the 🤔 cant-reproduce label 2026-02-21 19:25:41 -05:00
yindo closed this issue 2026-02-21 19:25:41 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Aug 21, 2025):

Hi @Graf2242! I'm Dosu and I’m helping the dify team.

The 300s delay happens because Dify's MCP integration uses a ThreadPoolExecutor to run an sse_reader thread, which blocks inside event_source.iter_sse() until the SSE read timeout expires. By default, this timeout is set to 300 seconds, so if the MCP server doesn't close the connection or send events promptly, Dify waits the full duration before releasing the thread, even if the server itself responds quickly. This is a known architectural issue in Dify's MCP handling source.

Currently, Dify 1.7.2 does not support configuring MCP tool timeouts via the UI, API, or environment variables; recent PRs to add this were reverted, so only code-level changes are possible source. Timeout-related environment variables like SSRF_DEFAULT_TIME_OUT do not affect MCP tool invocation timeouts.

If you are comfortable patching the code, you can lower the sse_read_timeout value in api/core/mcp/client/sse_client.py (look for the SSETransport and sse_client context manager) and rebuild your Docker images. This will make Dify fail faster when MCP servers are slow or unresponsive.

As a workaround, consider redesigning your workflow to avoid using MCP tools for operations that may exceed the default timeout, or implement such logic as workflow tools instead, which are more robust for parallel and long-running tasks source.

Enabling debug logging can help confirm whether the delay is in the sse_reader/session layer and not the MCP server itself source.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Aug 21, 2025): <!-- Greeting --> Hi @Graf2242! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the dify team. <!-- Answer --> The 300s delay happens because Dify's MCP integration uses a ThreadPoolExecutor to run an `sse_reader` thread, which blocks inside `event_source.iter_sse()` until the SSE read timeout expires. By default, this timeout is set to 300 seconds, so if the MCP server doesn't close the connection or send events promptly, Dify waits the full duration before releasing the thread, even if the server itself responds quickly. This is a known architectural issue in Dify's MCP handling [source](https://github.com/langgenius/dify/blob/ad8e82ee1ded5e2965a57109ac606ad61b54d37e/api/core/mcp/client/sse_client.py). Currently, Dify 1.7.2 does not support configuring MCP tool timeouts via the UI, API, or environment variables; recent PRs to add this were reverted, so only code-level changes are possible [source](https://github.com/langgenius/dify/issues/24238#issuecomment-3205825167). Timeout-related environment variables like `SSRF_DEFAULT_TIME_OUT` do not affect MCP tool invocation timeouts. If you are comfortable patching the code, you can lower the `sse_read_timeout` value in `api/core/mcp/client/sse_client.py` (look for the `SSETransport` and `sse_client` context manager) and rebuild your Docker images. This will make Dify fail faster when MCP servers are slow or unresponsive. As a workaround, consider redesigning your workflow to avoid using MCP tools for operations that may exceed the default timeout, or implement such logic as workflow tools instead, which are more robust for parallel and long-running tasks [source](https://github.com/langgenius/dify/issues/23379#issuecomment-3152194864). Enabling debug logging can help confirm whether the delay is in the sse_reader/session layer and not the MCP server itself [source](https://github.com/langgenius/dify/issues/23327#issuecomment-3148317174). <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/ba0c6269-5b84-4aad-9a13-ad2d7ba241ae?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/ba0c6269-5b84-4aad-9a13-ad2d7ba241ae?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/ba0c6269-5b84-4aad-9a13-ad2d7ba241ae?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/ba0c6269-5b84-4aad-9a13-ad2d7ba241ae?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/ba0c6269-5b84-4aad-9a13-ad2d7ba241ae?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/ba0c6269-5b84-4aad-9a13-ad2d7ba241ae?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/ba0c6269-5b84-4aad-9a13-ad2d7ba241ae?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/6088a4f4-073a-43f3-b3d4-4f06fb0c05a0/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/langgenius/dify/issues/24297)
Author
Owner

@Graf2242 commented on GitHub (Aug 21, 2025):

Oh, also I added the pyinstrument profiler and collected a call trace for this issue.
From the results, we can see that Dify spends almost all of its time closing the ThreadPoolExecutor.

pyinstrument_GET__console_api_workspaces_current_tool-provider_mcp_update_6ecdde45-6173-40ec-88fe-f67c21ccde41_1755771525547_301.153s.html

@Graf2242 commented on GitHub (Aug 21, 2025): Oh, also I added the pyinstrument profiler and collected a call trace for this issue. From the results, we can see that Dify spends almost all of its time closing the ThreadPoolExecutor. [pyinstrument_GET__console_api_workspaces_current_tool-provider_mcp_update_6ecdde45-6173-40ec-88fe-f67c21ccde41_1755771525547_301.153s.html](https://github.com/user-attachments/files/21915757/pyinstrument_GET__console_api_workspaces_current_tool-provider_mcp_update_6ecdde45-6173-40ec-88fe-f67c21ccde41_1755771525547_301.153s.html)
Author
Owner

@tianlingchen commented on GitHub (Aug 27, 2025):

同样遇到这个问题,mcp工具里面加一个mcp server,授权要非常久,好几次才成功,调用里面某工具时,经常两百多秒,应该是哪里有问题,换一个其他的插件用的方式,就比较快

@tianlingchen commented on GitHub (Aug 27, 2025): 同样遇到这个问题,mcp工具里面加一个mcp server,授权要非常久,好几次才成功,调用里面某工具时,经常两百多秒,应该是哪里有问题,换一个其他的插件用的方式,就比较快
Author
Owner

@Nov1c444 commented on GitHub (Sep 9, 2025):

I tried to reproduce this issue using

  1. Server: the latest main branch of https://github.com/korotovsky/slack-mcp-server and started with SSE transport method (using npx mcp-server-slack sse)
  2. Client: the latest main branch of the Dify client.

but I wasn't able to reproduce it. Based on your description, it seems like the server might not be properly closing the SSE connection, causing iter_sse to remain blocked.
I can attempt to modify the SSE connection logic to add proactive disconnection, but I'd like to confirm if this approach is reasonable. If you could provide more information to help me reproduce this issue, I would be able to resolve it more quickly.
Could you please share:

  1. The specific version/commit of slack-mcp-server you're using
  2. Any specific configuration or setup details
  3. Whether this happens consistently or intermittently
  4. Any server logs that might help identify the issue
    Image
@Nov1c444 commented on GitHub (Sep 9, 2025): I tried to reproduce this issue using 1. Server: the latest main branch of https://github.com/korotovsky/slack-mcp-server and started with SSE transport method (using `npx mcp-server-slack sse`) 2. Client: the latest main branch of the Dify client. but I wasn't able to reproduce it. Based on your description, it seems like the server might not be properly closing the SSE connection, causing iter_sse to remain blocked. I can attempt to modify the SSE connection logic to add proactive disconnection, but I'd like to confirm if this approach is reasonable. If you could provide more information to help me reproduce this issue, I would be able to resolve it more quickly. Could you please share: 1. The specific version/commit of slack-mcp-server you're using 2. Any specific configuration or setup details 3. Whether this happens consistently or intermittently 4. Any server logs that might help identify the issue <img width="712" height="646" alt="Image" src="https://github.com/user-attachments/assets/08b136f1-ea80-4251-bba8-74cd2bfdd7b7" />
Author
Owner

@Graf2242 commented on GitHub (Sep 10, 2025):

  1. Right now tried to get latest ghcr.io/korotovsky/slack-mcp-server:latest which is v1.1.24
    My current Dify version is 1.8.0
  2. I use slack-mcp in docker. Connection Dify>slack-mcp is direct, with no proxy between with http (not https)
    args = ["mcp-server", "-t", "sse"]
    env = [
    SLACK_MCP_HOST="0.0.0.0"
    HTTP_PROXY = "MY_EX_PROXY_ADDR"
    HTTPS_PROXY = "MY_EX_PROXY_ADDR"
    NO_PROXY = "INTERNAL_RESOURCES_LIST"
    SLACK_MCP_PROXY = "MY_EX_PROXY_ADDR"
    SLACK_MCP_PORT = "24001"
    SLACK_MCP_SERVER_CA_INSECURE = true
    SLACK_MCP_XOXP_TOKEN = "MYTOKEN"
    ]
  3. It happens all the time for me starting from initial auth Dify > mcp_server
  4. Here is logs of mcp server itself
{"level":"info","timestamp":"2025-09-10T10:53:59Z","message":"Request received","app":"slack-mcp-server","tool":"channels_list","params":{"name":"channels_list","arguments":{"channel_types":"public_channel"}}}
{"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Auth middleware invoked","app":"slack-mcp-server","context":"http","transport":"sse","tool":"channels_list"}
{"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"No SSE API key configured, skipping authentication","app":"slack-mcp-server","context":"http"}
{"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Authentication successful","app":"slack-mcp-server","context":"http","transport":"sse","tool":"channels_list"}
{"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"ChannelsHandler called","app":"slack-mcp-server"}
{"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Request parameters","app":"slack-mcp-server","sort":"popularity","channel_types":"public_channel","cursor":"","limit":0}
{"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Validated channel types","app":"slack-mcp-server","types":["public_channel"]}
{"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Limit not provided, using default","app":"slack-mcp-server","limit":100}
{"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Total channels available","app":"slack-mcp-server","count":104}
{"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Channels after filtering by type","app":"slack-mcp-server","count":41}
{"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Pagination results","app":"slack-mcp-server","returned_count":41,"has_next_page":false}
{"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Sorting channels by popularity (member count)","app":"slack-mcp-server"}
{"level":"info","timestamp":"2025-09-10T10:53:59Z","message":"Request finished","app":"slack-mcp-server","tool":"channels_list","duration":571911}

DIfy-api logs here
dify-api.log

@Graf2242 commented on GitHub (Sep 10, 2025): 1. Right now tried to get latest ghcr.io/korotovsky/slack-mcp-server:latest which is [v1.1.24 ](https://github.com/korotovsky/slack-mcp-server/pkgs/container/slack-mcp-server/487828860?tag=v1.1.24) My current Dify version is 1.8.0 2. I use slack-mcp in docker. Connection Dify>slack-mcp is direct, with no proxy between with http (not https) args = ["mcp-server", "-t", "sse"] env = [ SLACK_MCP_HOST="0.0.0.0" HTTP_PROXY = "MY_EX_PROXY_ADDR" HTTPS_PROXY = "MY_EX_PROXY_ADDR" NO_PROXY = "INTERNAL_RESOURCES_LIST" SLACK_MCP_PROXY = "MY_EX_PROXY_ADDR" SLACK_MCP_PORT = "24001" SLACK_MCP_SERVER_CA_INSECURE = true SLACK_MCP_XOXP_TOKEN = "MYTOKEN" ] 3. It happens all the time for me starting from initial auth Dify > mcp_server 4. Here is logs of mcp server itself ``` {"level":"info","timestamp":"2025-09-10T10:53:59Z","message":"Request received","app":"slack-mcp-server","tool":"channels_list","params":{"name":"channels_list","arguments":{"channel_types":"public_channel"}}} {"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Auth middleware invoked","app":"slack-mcp-server","context":"http","transport":"sse","tool":"channels_list"} {"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"No SSE API key configured, skipping authentication","app":"slack-mcp-server","context":"http"} {"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Authentication successful","app":"slack-mcp-server","context":"http","transport":"sse","tool":"channels_list"} {"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"ChannelsHandler called","app":"slack-mcp-server"} {"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Request parameters","app":"slack-mcp-server","sort":"popularity","channel_types":"public_channel","cursor":"","limit":0} {"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Validated channel types","app":"slack-mcp-server","types":["public_channel"]} {"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Limit not provided, using default","app":"slack-mcp-server","limit":100} {"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Total channels available","app":"slack-mcp-server","count":104} {"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Channels after filtering by type","app":"slack-mcp-server","count":41} {"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Pagination results","app":"slack-mcp-server","returned_count":41,"has_next_page":false} {"level":"debug","timestamp":"2025-09-10T10:53:59Z","message":"Sorting channels by popularity (member count)","app":"slack-mcp-server"} {"level":"info","timestamp":"2025-09-10T10:53:59Z","message":"Request finished","app":"slack-mcp-server","tool":"channels_list","duration":571911} ``` DIfy-api logs here [dify-api.log](https://github.com/user-attachments/files/22253490/dify-api.log)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#16332