mcpclaudearchitecture

How Claude MCP Connectors Actually Work Under the Hood

Deep dive into how Claude MCP connectors work -- HTTP transport, tool registration, authentication, and request lifecycle.

10 min read

MCP connectors have become the standard way to give Claude access to external tools. But most developers treat them as black boxes -- paste a config, hope it works, move on. Understanding what happens under the hood helps you debug connection failures, build custom servers, and reason about security.

This post breaks down the three core mechanics of MCP connectors: HTTP transport, tool registration, and authentication.

HTTP Transport: How Messages Flow

MCP uses a simple HTTP-based protocol. The client (Claude, Cursor, VS Code) sends JSON-RPC requests to a server URL over standard HTTPS. There is no WebSocket upgrade, no custom binary format -- just POST requests with JSON bodies.

When Claude needs to call a tool, the runtime sends a request to the MCP server's endpoint. The server processes the request, calls the underlying API, and returns the result as a JSON-RPC response. The entire round trip is a single HTTP request-response cycle.

Bash
# What happens under the hood when Claude calls an MCP tool
POST https://mcp.example.com/mcp HTTP/1.1
Content-Type: application/json
x-api-key: sk-xxx

{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "search_google",
    "arguments": { "query": "best noise cancelling headphones 2026" }
  },
  "id": 1
}

This simplicity is intentional. HTTP transport means MCP servers work behind corporate proxies, load balancers, and CDNs without special configuration.

Tool Registration: The Discovery Phase

Before Claude can call any tool, the client must discover what tools the server offers. This happens during initialization. The client sends atools/list request, and the server responds with a manifest of available tools, each described by a name, description, and JSON Schema for its parameters.

JSON
{
  "tools": [
    {
      "name": "search_google",
      "description": "Search Google and return structured results",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": { "type": "string" },
          "num_results": { "type": "integer", "default": 10 }
        },
        "required": ["query"]
      }
    }
  ]
}

Claude uses these schemas to decide when and how to call each tool. A vague description leads to poor tool selection. A missing required field causes silent failures. Getting the schema right matters more than most developers realize.

Authentication: Headers and API Keys

MCP servers authenticate requests using HTTP headers. The most common pattern is a static API key passed in a custom header. The client includes this header on every request to the server, including the initial discovery call.

JSON
{
  "mcpServers": {
    "scavio": {
      "type": "http",
      "url": "https://mcp.scavio.dev/mcp",
      "headers": {
        "x-api-key": "YOUR_SCAVIO_API_KEY"
      }
    }
  }
}

Some servers use OAuth 2.0 flows for user-level authentication, but for most API-backed tools, a static key is sufficient. The key never leaves the client config -- it is sent directly to the MCP server over TLS, not to the LLM provider.

Error Handling and Timeouts

When a tool call fails, the MCP server returns a JSON-RPC error with a code and message. Common failure modes include:

  • Authentication errors (invalid or expired API key)
  • Rate limiting (too many requests in a short window)
  • Timeout (the upstream API took too long to respond)
  • Schema validation errors (the LLM sent malformed arguments)

Most MCP clients set a default timeout of 30-60 seconds per tool call. If your upstream API is slow, consider adding a caching layer to your MCP server or increasing the timeout in the client config.

Building Your Own MCP Server

The MCP specification is open, and building a server is straightforward. The official TypeScript and Python SDKs handle the JSON-RPC plumbing. Your job is to define tools and implement their handlers.

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";

const server = new McpServer({ name: "my-tools", version: "1.0.0" });

server.tool(
  "lookup_price",
  { ticker: z.string() },
  async ({ ticker }) => {
    const price = await fetchStockPrice(ticker);
    return { content: [{ type: "text", text: JSON.stringify(price) }] };
  }
);

Once deployed, any MCP-compatible client can connect to your server with just a URL and optional headers. No client-side code changes needed.

Key Takeaways

MCP connectors are not magic. They are HTTP endpoints that follow a simple JSON-RPC protocol. Understanding the three layers -- transport, tool registration, and authentication -- lets you debug issues faster, write better tool descriptions, and build servers that work reliably across every MCP client.

If you want to try a production MCP server without building one, Scavio offers a hosted MCP endpoint at https://mcp.scavio.dev/mcp with tools for Google, Amazon, YouTube, Walmart, and Reddit search.