How McpToolProvider._validate_credentials Verifies MCP Server Connectivity in Dify

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

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

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.

mcp_clients.fetch_tools()

The fetch_tools method (lines 66–82 in 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:

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 (lines 11–18).
  • Client initialization: Creates transport-specific clients (McpSseClient or McpStreamableHttpClient) and opens connections via McpClients in 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 (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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →