# How to Troubleshoot MCP Server Connection Issues: Complete Diagnostic Guide

> Troubleshoot MCP server connection issues with this diagnostic guide. Learn to fix transport misconfigurations, environment variables, network restrictions, and timeout handling.

- Repository: [Composio/awesome-codex-skills](https://github.com/composiohq/awesome-codex-skills)
- Tags: how-to-guide
- Published: 2026-04-26

---

**MCP server connection issues typically stem from transport misconfiguration, missing environment variables, network restrictions, or improper timeout handling in the server implementation.**

Model Context Protocol (MCP) servers expose tools that LLM agents invoke over transport layers like STDIO, HTTP, or SSE. When clients cannot reach the server, systematic troubleshooting of the transport stack, credentials, and error handling logic will resolve most failures. This guide uses implementation details from the ComposioHQ/awesome-codex-skills reference repositories to diagnose and fix connection problems.

## Common Connection Failure Points

Connection failures in MCP architectures usually originate in one of five layers. Examine each systematically to isolate the root cause.

### Transport Configuration

Verify the server and client use matching transport protocols. The Python MCP server supports `stdio`, `streamable_http`, and `sse` modes, configured during initialization. If you launched the server with `mcp.run()` for STDIO, ensure evaluation scripts use the `-t stdio` flag. For HTTP transports, confirm the URL (`http://localhost:8000`) and port binding match between the server startup command and client connection parameters. Reference implementations in [`mcp-builder/reference/python_mcp_server.md`](https://github.com/ComposioHQ/awesome-codex-skills/blob/main/mcp-builder/reference/python_mcp_server.md) demonstrate how transport flags must align across the connection lifecycle.

### Environment and Credentials

Missing API keys or tokens are a frequent cause of silent connection failures. Ensure required secrets like `OPENAI_API_KEY` or `GITHUB_TOKEN` are exported in the shell environment and properly read by the server using `os.getenv` or Pydantic settings. The evaluation documentation in [`mcp-builder/reference/evaluation.md`](https://github.com/ComposioHQ/awesome-codex-skills/blob/main/mcp-builder/reference/evaluation.md) specifically notes that connection errors often indicate the server cannot access credentials needed for underlying API calls.

### Network Reachability

Test basic connectivity before debugging application logic. From the client machine, run `nc -zv <host> <port>` or `curl -I <url>` to verify the server endpoint is accessible. Check for firewall rules, VPC restrictions, or container networking issues that might block the port. DNS resolution failures will also manifest as connection timeouts.

### Server-Side Error Handling

Robust servers must wrap all outbound network calls with timeout handling and convert exceptions into user-friendly error messages. According to [`mcp-builder/reference/python_mcp_server.md`](https://github.com/ComposioHQ/awesome-codex-skills/blob/main/mcp-builder/reference/python_mcp_server.md), tools should return strings starting with `"Error:"` rather than raising raw exceptions, which preserves the MCP protocol connection and allows the LLM to react gracefully. The `_handle_api_error` helper function demonstrates this pattern by catching `httpx.TimeoutException` and `httpx.HTTPStatusError` before they bubble up.

### Logging and Diagnostics

Enable detailed logging to capture request/response cycles. In Python FastMCP implementations, use `ctx.log_info()` or `ctx.log_error()` methods. For STDIO transports, examine server stdout and stderr directly, as protocol messages stream through these channels. The Node.js reference in [`mcp-builder/reference/node_mcp_server.md`](https://github.com/ComposioHQ/awesome-codex-skills/blob/main/mcp-builder/reference/node_mcp_server.md) (line 907) emphasizes logging all network operations to diagnose timeout and connection errors.

## Step-by-Step Troubleshooting Checklist

Follow this sequence to isolate MCP connection failures:

1. **Confirm transport alignment** — Verify the server transport flag matches the client evaluation script. If running HTTP mode, ensure the server listens on `0.0.0.0` rather than `localhost` when accessed remotely.

2. **Validate environment variables** — Export all required secrets (`export GITHUB_TOKEN=...`) and verify the server process can access them. Missing keys often trigger connection failures during the initial tool listing phase.

3. **Test network connectivity** — Use `telnet` or `curl` to verify the host and port are reachable from the client machine. Timeouts here indicate infrastructure issues outside the MCP implementation.

4. **Inspect server logs** — Look for `httpx.TimeoutException` or `httpx.HTTPStatusError` entries. The `_handle_api_error` implementation logs exact status codes that triggered failures.

5. **Check timeout settings** — The default `httpx.AsyncClient` timeout is 30 seconds. Increase this to 60 seconds or higher for slow external APIs, or implement retry logic as shown in the reference implementations.

6. **Verify tool error handling** — Ensure all tools return formatted error strings rather than raising unhandled exceptions. This keeps the protocol connection intact.

7. **Run the evaluation harness** — Execute [`scripts/evaluation.py`](https://github.com/ComposioHQ/awesome-codex-skills/blob/main/scripts/evaluation.py) with the `-t` flag matching your transport mode. This automated check will surface misconfigured transports or missing credentials.

## Code Solutions for Connection Resilience

Implement these patterns from the ComposioHQ reference code to prevent and handle connection issues gracefully.

### Adding Timeout and Retry Logic

Wrap external API calls with configurable timeouts and exponential backoff. This pattern mirrors the error handling in [`mcp-builder/reference/python_mcp_server.md`](https://github.com/ComposioHQ/awesome-codex-skills/blob/main/mcp-builder/reference/python_mcp_server.md):

```python
import httpx
from typing import Any

MAX_RETRIES = 3
TIMEOUT_SEC = 60.0  # Increased from default 30s

async def _make_api_request(endpoint: str, method: str = "GET", **kwargs) -> Any:
    """Reusable HTTP client with timeout and retry logic."""
    for attempt in range(1, MAX_RETRIES + 1):
        try:
            async with httpx.AsyncClient() as client:
                resp = await client.request(
                    method,
                    f"{API_BASE_URL}/{endpoint}",
                    timeout=TIMEOUT_SEC,
                    **kwargs,
                )
                resp.raise_for_status()
                return resp.json()
        except (httpx.TimeoutException, httpx.HTTPStatusError) as e:
            print(f"[Attempt {attempt}] Request failed: {e}")
            if attempt == MAX_RETRIES:
                raise

```

### Formatting Errors for LLM Consumption

Structure tool outputs to maintain protocol stability when connections fail:

```python
@mcp.tool(
    name="example_fetch_resource",
    annotations={
        "title": "Fetch Example Resource",
        "readOnlyHint": True,
        "idempotentHint": True,
    },
)
async def example_fetch_resource(params: ResourceInput) -> str:
    """Retrieve remote resource with graceful error handling."""
    try:
        data = await _make_api_request(f"resources/{params.id}")
        return json.dumps(data, indent=2)
    except Exception as exc:
        # Returns "Error: ..." to keep MCP connection alive

        return _handle_api_error(exc)

```

### Testing with the Evaluation Harness

Verify connectivity using the built-in evaluation script:

```bash

# Terminal 1: Start HTTP server

python my_mcp_server.py &

# Terminal 2: Run evaluation

python scripts/evaluation.py \
  -t http \
  -c python \
  -a my_mcp_server.py \
  -e GITHUB_TOKEN=$GITHUB_TOKEN \
  -o eval_report.md \
  my_evaluation.xml

```

If this produces "connection error," verify the server is listening on the expected interface and that no firewall blocks the port.

## Key Reference Files

These files in the `ComposioHQ/awesome-codex-skills` repository contain authoritative implementation details:

- **[`mcp-builder/reference/python_mcp_server.md`](https://github.com/ComposioHQ/awesome-codex-skills/blob/main/mcp-builder/reference/python_mcp_server.md)** — Transport configuration options, `_handle_api_error` helper implementation, and FastMCP context logging methods.
- **[`mcp-builder/reference/node_mcp_server.md`](https://github.com/ComposioHQ/awesome-codex-skills/blob/main/mcp-builder/reference/node_mcp_server.md)** — Node.js equivalent of timeout handling and connection error management (see line 907).
- **[`mcp-builder/reference/mcp_best_practices.md`](https://github.com/ComposioHQ/awesome-codex-skills/blob/main/mcp-builder/reference/mcp_best_practices.md)** — Architectural guidance for connection lifecycle management and proper error handling strategies.
- **[`mcp-builder/reference/evaluation.md`](https://github.com/ComposioHQ/awesome-codex-skills/blob/main/mcp-builder/reference/evaluation.md)** — Automated troubleshooting via the evaluation harness, including the Connection Errors diagnostic section (lines 78-86).
- **[`scripts/evaluation.py`](https://github.com/ComposioHQ/awesome-codex-skills/blob/main/scripts/evaluation.py)** — Executable harness for testing transport modes and credential configurations.

## Summary

- **Transport mismatch** between server and client is the most common connection failure—always verify flags like `-t stdio` or `-t http` align with the server's startup mode.
- **Missing environment variables** cause cryptic connection errors during tool execution—validate all API keys are exported before starting the server.
- **Network timeouts** default to 30 seconds in `httpx.AsyncClient`—increase this value or add retry logic for unreliable external APIs.
- **Protocol stability** requires converting exceptions to `"Error:"` strings rather than raising them, preserving the MCP connection for LLM retry logic.
- **Diagnostic logging** via `ctx.log_*` or stdout examination provides visibility into STDIO transport failures.

## Frequently Asked Questions

### How do I fix "connection refused" when connecting to an MCP server?

"Connection refused" typically indicates the server is not listening on the expected port or interface. Verify the server started successfully and binds to `0.0.0.0` rather than `127.0.0.1` for remote connections. Check that no firewall or Docker network isolation blocks the port, and confirm the client URL includes the correct port number (e.g., `http://localhost:8000`).

### Why does my MCP server work with STDIO but fail on HTTP transport?

HTTP mode requires explicit transport configuration and network accessibility. Ensure you started the server with the HTTP transport flag (e.g., `transport="streamable_http"`) and that the evaluation script uses `-t http`. Additionally, HTTP servers must handle CORS headers and binding interfaces correctly, whereas STDIO simply uses process pipes.

### How can I debug timeout errors in MCP tool calls?

Enable verbose logging to identify whether the timeout occurs during the MCP handshake or the underlying API call. Increase the `httpx.AsyncClient` timeout from the default 30 seconds, or implement the retry pattern shown in `_make_api_request`. Check [`mcp-builder/reference/node_mcp_server.md`](https://github.com/ComposioHQ/awesome-codex-skills/blob/main/mcp-builder/reference/node_mcp_server.md) line 907 for the Node.js equivalent timeout configuration.

### What should I do if the evaluation script reports connection errors immediately?

Run the checklist steps: first verify required environment variables (`-e` flags) are passed correctly, then test network reachability with `curl`. If using HTTP mode, ensure the server process is actually running and listening (check with `netstat -tlnp` or `lsof -i :8000`). Finally, examine the server logs for startup errors that prevent the transport from initializing.