# How McpToolProvider._validate_credentials Verifies MCP Server Connectivity in Dify

> Discover how McpToolProvider._validate_credentials verifies MCP server connectivity by parsing config, creating clients, and performing a live tools list JSON-RPC call. Learn more.

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

---

**The `_validate_credentials` method validates MCP server connectivity by parsing the JSON configuration, instantiating transport-specific clients for each configured server, and executing a live `tools/list` JSON-RPC call to confirm the server responds correctly.**

The `junjiem/dify-plugin-tools-mcp_sse` repository implements an MCP (Model Context Protocol) tool provider for the Dify AI platform. When administrators configure MCP servers through the Dify UI, the `McpToolProvider` class in [`provider/mcp_tool.py`](https://github.com/junjiem/dify-plugin-tools-mcp_sse/blob/main/provider/mcp_tool.py) runs the `_validate_credentials` method to ensure every listed server is syntactically valid, reachable, and operational before accepting the credentials.

## The Three-Step Validation Process

The `_validate_credentials` method implements a rigorous connectivity verification pipeline that moves from configuration parsing to active RPC testing. Each step must succeed for validation to pass.

### Step 1: Parse the JSON Server Configuration

First, the method extracts and validates the `servers_config` credential field. This JSON string must contain valid MCP server definitions under the `mcpServers` key.

```python
servers_config_json = credentials.get("servers_config", "")
if not servers_config_json:
    raise ToolProviderCredentialValidationError("Please fill in the servers_config")
servers_config = json.loads(servers_config_json)

```

If the field is empty or contains malformed JSON, the method immediately raises a `ToolProviderCredentialValidationError`, surfacing the issue to the Dify UI before attempting any network connections. This check appears in [`provider/mcp_tool.py`](https://github.com/junjiem/dify-plugin-tools-mcp_sse/blob/main/provider/mcp_tool.py) at lines 11–18.

### Step 2: Instantiate MCP Clients with Transport Initialization

After parsing, the method creates client instances for each configured server through the `McpClients` wrapper class defined in [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-tools-mcp_sse/blob/main/utils/mcp_client.py).

```python
mcp_clients = McpClients(servers_config)

```

The `McpClients.__init__` method (lines 27–39) iterates over each server entry in the configuration and:
- Determines the transport type (`sse` or `streamable_http`)
- Instantiates the appropriate concrete client (`McpSseClient` or `McpStreamableHttpClient`)
- Immediately calls `client.initialize()` to open the HTTP connection

This initialization process (lines 44–61) establishes the underlying network session and prepares the client for JSON-RPC communication. If a server URL is unreachable or the transport connection fails, the exception propagates upward and fails validation.

### Step 3: Execute the Tools/List RPC Probe

Finally, the method performs an active connectivity test by requesting the list of available tools from every configured server.

```python
mcp_clients.fetch_tools()

```

The `fetch_tools` method (lines 66–82 in [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-tools-mcp_sse/blob/main/utils/mcp_client.py)) iterates through all initialized clients and calls `client.list_tools()`. This method constructs and sends a JSON-RPC **`tools/list`** request through the active transport. If the server responds with a valid list of tools, connectivity is confirmed. If the server returns an RPC error, HTTP error, or network timeout, the method raises an exception that `_validate_credentials` catches and converts into a validation error.

## Complete Validation Flow Example

The following code demonstrates the exact validation sequence used by the provider when processing credentials:

```python
import json
from provider.mcp_tool import McpToolProvider
from dify_plugin.errors.tool import ToolProviderCredentialValidationError

# Simulated credentials dict as provided by Dify UI

credentials = {
    "servers_config": json.dumps({
        "mcpServers": {
            "filesystem": {
                "url": "http://localhost:3001/sse",
                "transport": "sse"
            },
            "fetch": {
                "url": "https://api.example.com/mcp",
                "transport": "streamable_http",
                "headers": {"Authorization": "Bearer token123"}
            }
        }
    })
}

provider = McpToolProvider()
try:
    # This triggers _validate_credentials internally

    provider._validate_credentials(credentials)
    print("All MCP servers validated successfully")
except ToolProviderCredentialValidationError as e:
    print(f"Validation failed: {e}")

```

Running this example executes the full three-step process: JSON parsing, client initialization for both SSE and HTTP transports, and live `tools/list` RPC calls to both servers.

## Error Handling and Failure Modes

Any exception raised during the three-step process—whether from `json.loads`, `McpClients` initialization, or `fetch_tools`—is caught by the `_validate_credentials` method and re-raised as a `ToolProviderCredentialValidationError`. This ensures Dify receives a standardized error message suitable for UI display, whether the failure stems from:
- Missing or invalid JSON syntax in `servers_config`
- Network timeouts during client initialization
- HTTP 4xx/5xx responses from the MCP server
- JSON-RPC error responses to the `tools/list` method

## Summary

- **Configuration parsing**: Validates JSON syntax and required `servers_config` field in [`provider/mcp_tool.py`](https://github.com/junjiem/dify-plugin-tools-mcp_sse/blob/main/provider/mcp_tool.py) (lines 11–18).
- **Client initialization**: Creates transport-specific clients (`McpSseClient` or `McpStreamableHttpClient`) and opens connections via `McpClients` in [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-tools-mcp_sse/blob/main/utils/mcp_client.py) (lines 27–39, 44–61).
- **Live RPC testing**: Confirms connectivity by executing `tools/list` JSON-RPC calls through `fetch_tools()` in [`utils/mcp_client.py`](https://github.com/junjiem/dify-plugin-tools-mcp_sse/blob/main/utils/mcp_client.py) (lines 66–82).
- **Error propagation**: Converts all exceptions to `ToolProviderCredentialValidationError` for consistent error reporting in the Dify interface.

## Frequently Asked Questions

### What happens if one MCP server is down but others are healthy?

The `_validate_credentials` method fails the entire validation. Because `McpClients.fetch_tools()` iterates over all configured servers and raises an exception if any individual `list_tools()` call fails, a single unreachable server will prevent credential validation from succeeding. You must either fix the connectivity issue or remove the offending server from the `servers_config` JSON.

### Does the method check server authentication credentials?

Yes, indirectly. The `client.initialize()` and `client.list_tools()` methods include any configured headers (such as `Authorization` tokens) in their HTTP requests. If the MCP server rejects the authentication credentials, it returns an HTTP 401/403 error or a JSON-RPC authentication error, which propagates up as a `ToolProviderCredentialValidationError`.

### What is the difference between `McpSseClient` and `McpStreamableHttpClient`?

`McpSseClient` uses Server-Sent Events (SSE) for bidirectional communication with the MCP server, maintaining a persistent HTTP connection for streaming responses. `McpStreamableHttpClient` uses standard HTTP POST requests with streaming JSON responses. The `_validate_credentials` method automatically instantiates the correct client based on the `transport` field in each server's configuration.

### Can I call `_validate_credentials` directly for testing?

Yes. While the method is prefixed with an underscore indicating it is intended for internal use, you can invoke it directly on an instance of `McpToolProvider` for debugging or automated testing purposes, as shown in the code example above. Ensure you handle `ToolProviderCredentialValidationError` to catch validation failures gracefully.