# What Happens When an MCP Server Returns an Error During Tool Execution

> Learn what happens when an MCP server returns an error during tool execution. Dify MCP plugin detects, raises, and propagates errors for seamless debugging and issue resolution.

- Repository: [Junjie.M/dify-plugin-agent-mcp_sse](https://github.com/junjiem/dify-plugin-agent-mcp_sse)
- Tags: how-to-guide
- Published: 2026-03-05

---

**When an MCP server returns an error during tool execution, the Dify MCP plugin detects the error in the `call_tool` method, raises a Python exception containing the server name and raw error payload, and re-wraps it in `execute_tool` before propagating the failure to the Dify runtime.**

The `junjiem/dify-plugin-agent-mcp_sse` repository implements a Model Context Protocol (MCP) client that enables Dify agents to invoke tools hosted on remote MCP servers. Understanding what happens when an MCP server returns an error during tool execution is critical for building resilient agent workflows and debugging integration failures.

## Error Detection in the MCP Client Layer

When a Dify agent invokes an MCP tool, the request flows through the `McpClient` class defined in [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-agent-mcp_sse/blob/main/utils/mcp_client.py). The `call_tool` method constructs a JSON‑RPC `tools/call` request and transmits it via the configured transport (SSE or streamable HTTP).

### The `call_tool` Method Implementation

Inside `call_tool`, the client awaits the server response and inspects the payload for an `error` field. If present, the method immediately raises a Python exception that includes the server name and the complete error object.

```python

# utils/mcp_client.py (lines 71-84)

response = self.send_message(data)
if "error" in response:                       # Line 82

    error = response["error"]
    raise Exception(f"{self.name} - MCP Server tools/call error: {error}")

```

This early detection ensures that protocol‑level errors—such as *method not found* (`-32601`) or custom MCP application errors—are captured before any result processing occurs.

## Error Propagation to the Dify Runtime

The `McpClients` class (plural) orchestrates multiple server connections and provides the `execute_tool` entry point that Dify agents actually invoke. This method wraps the lower‑level `call_tool` logic and standardizes exception handling across all configured servers.

### Exception Handling in `execute_tool`

When `execute_tool` delegates to `call_tool`, it wraps the invocation in a try‑except block. Any exception—whether from network failures, JSON‑RPC errors, or the explicit error raise in `call_tool`—is caught and re‑wrapped with a descriptive prefix.

```python

# utils/mcp_client.py (lines 12-74)

try:
    if action_type == ActionType.TOOL:
        tool_contents = client.call_tool(tool_name, tool_args)   # Line 26-28

except Exception as e:
    raise Exception(f"Error executing tool: {str(e)}")             # Line 73-74

```

This two‑layer wrapping preserves the original error details while providing context about which tool execution failed, making debugging easier for Dify developers.

### Impact on Dify Workflow Execution

Once the re‑wrapped exception bubbles up to the Dify orchestration layer, the platform treats it as a hard tool failure. Dify surfaces the error message to the end user—typically displaying *“Tool execution failed: …”*—and may trigger configured fallback behaviors such as retry loops, alternative tool selection, or graceful degradation based on the agent’s error‑handling policy.

## Practical Example: Handling MCP Server Errors in Python

The following example demonstrates how to invoke an MCP tool through the plugin and catch the specific error chain described above.

```python
from utils.mcp_client import McpClients

# Initialize client with server configuration

clients = McpClients(
    servers_config={
        "my_server": {
            "url": "https://example.com/mcp",
            "transport": "sse"
        }
    }
)

try:
    # Attempt to execute a tool that may fail on the server

    result = clients.execute_tool("risky_operation", {"param": "value"})
    print("Success:", result)
except Exception as exc:
    # Output: Error executing tool: my_server - MCP Server tools/call error: {...}

    print("Captured error:", exc)

```

When the remote MCP server returns a JSON‑RPC error object—such as `{"code": -32601, "message": "Method not found"}`—the exception message will contain the full error payload, allowing precise diagnosis of whether the failure is due to a missing tool, invalid parameters, or server‑side logic errors.

## Summary

When an MCP server returns an error during tool execution, the Dify MCP plugin handles it through a strict two‑phase process:

- **Immediate detection** in `McpClient.call_tool` ([`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-agent-mcp_sse/blob/main/utils/mcp_client.py)), which inspects JSON‑RPC responses and raises an exception containing the server name and raw error payload.
- **Standardized propagation** in `McpClients.execute_tool`, which catches all lower‑level exceptions, wraps them with execution context, and propagates the failure to the Dify runtime.
- **No partial results** are returned; the entire tool invocation is treated as a hard failure that Dify surfaces to users and handles according to agent‑level retry or fallback policies.

## Frequently Asked Questions

### Does the Dify MCP plugin automatically retry failed tool calls?

No, the plugin itself does not implement automatic retry logic. When `McpClient.call_tool` detects a server error or when `McpClients.execute_tool` catches an exception, it immediately raises a wrapped exception. Any retry behavior must be configured at the Dify agent or workflow level, where the orchestration layer can catch the failure and decide whether to retry, switch tools, or degrade gracefully.

### What specific error information is included in the exception message?

The exception message includes the **server name** (e.g., `my_server`), the **MCP method** that failed (`tools/call`), and the **complete JSON‑RPC error object** returned by the server. For example: `my_server - MCP Server tools/call error: {'code': -32601, 'message': 'Method not found'}`. This structure allows developers to distinguish between protocol errors (like invalid method names) and application‑specific errors defined by the MCP server.

### Can partial tool results be returned when an MCP server error occurs?

No. The error handling logic in [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-agent-mcp_sse/blob/main/utils/mcp_client.py) treats any presence of an `error` field in the JSON‑RPC response as a complete failure. The `call_tool` method raises an exception immediately upon detecting the error, preventing any partial content from being processed or returned to the Dify agent. This all‑or‑nothing approach ensures data consistency but requires that MCP servers return valid results only when execution is fully successful.

### How can I customize error handling for specific MCP servers?

Currently, the plugin uses a uniform error handling strategy across all configured servers through the `McpClients` class. To implement server‑specific logic (such as custom retry policies or error translation), you would need to extend the `McpClient` class in [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-agent-mcp_sse/blob/main/utils/mcp_client.py) and override the `call_tool` method, or wrap the `execute_tool` call in your Dify agent code with custom exception handling that inspects the server name embedded in the error message.