CertSafari
    CLAUDE-CERTIFIED-DEVELOPER-FOUNDATIONS-CCDV-F · Lessons

    Domain 8 · Lesson 24/25

    MCP Transports and Connecting Servers to Claude Code

    MCP Server Development

    10 min read
    3.53% of exam
    3 sources
    Published 29 Sep 2026
    Docs as of 26 Sep 2026

    What you will be able to do

    • Build a stdio server that keeps stdout for protocol messages and sends logs to stderr
    • Describe how Streamable HTTP carries requests, notifications and responses over one POST endpoint
    • Secure a locally or remotely deployed HTTP server with Origin checks, localhost binding and authentication
    • Add stdio, HTTP, SSE and WebSocket servers to Claude Code and diagnose their status

    1.stdio: the server as a child process

    The simplest transport runs the server as a child process of the client. The server reads JSON-RPC messages from stdin and writes JSON-RPC messages to stdout. Each message is a single request, notification or response, messages are separated by newlines, and a message must not contain embedded newlines. On stdout the server may send responses to client requests (matched by JSON-RPC id), notifications about an in-flight request such as notifications/progress, and notifications for an active subscriptions/listen request.

    The key rule is that stdout belongs to the protocol. The server must not write anything to stdout that is not a valid MCP message, and the client must not write anything else to the server's stdin. Diagnostics go to stderr. The server may write UTF-8 logging there, including informational, debug and error messages. The client may capture, forward or ignore stderr, and should not treat output there as a sign of an error. Shutdown is also client-driven: the client closes the child process's input stream, waits for it to exit, and forcibly terminates it if it does not exit within a reasonable time.

    The stdio page also describes how a client works out which protocol generation a server speaks. If the server returns a DiscoverResult, it is modern, and the client picks a version from supportedVersions. If it returns a recognised error such as UnsupportedProtocolVersionError, it is still modern, and the client must choose one of the versions the server advertises rather than falling back. Any other error, or no response within a reasonable timeout, marks the server as legacy, and the client falls back to the initialize handshake.

    Sources1

    2.Streamable HTTP: one endpoint, one POST per message

    For remote servers, the protocol uses Streamable HTTP. The server exposes a single HTTP endpoint, the MCP endpoint, which accepts POST. The client sends every JSON-RPC request or notification as its own POST, and the body is always a single request or notification, never a response. The client's Accept header must list both application/json and text/event-stream. If the body is a notification, the server returns 202 Accepted with no body, or an HTTP error status if it rejects it. If the body is a request, the server replies either with one JSON object or with a Server-Sent Events stream for that request. The stream may carry related notifications such as notifications/progress before the final response, which should end the stream.

    The 2026-07-28 revision removes the GET stream endpoint and protocol-level sessions. The server must not send independent JSON-RPC requests on a response stream. Server-to-client interactions such as sampling, elicitation and list-roots are embedded as input requests inside an InputRequiredResult. This changes the 2025-03-26 through 2025-11-25 versions, where servers could send such requests on SSE streams. Long-lived change notifications arrive on the response stream of a subscriptions/listen request.

    Request metadata headers on a tools/call POSThttp
    POST /mcp HTTP/1.1
    Content-Type: application/json
    MCP-Protocol-Version: 2026-07-28
    Mcp-Method: tools/call
    Mcp-Name: get_weather

    Mcp-Method is required on every request. Mcp-Name, taken from params.name or params.uri, is required on tools/call, resources/read and prompts/get. A tool author can also mirror a parameter into a header by adding an x-mcp-header annotation to it in the inputSchema. For example, a region property annotated "Region" is sent as Mcp-Param-Region: us-west1. The annotation is allowed only on string, integer and boolean parameters (not number) that are reachable from the schema root through properties keys alone.

    A team wants to connect their agent to a third-party analytics MCP server. The provider's documentation gives a hosted endpoint URL, `https://analytics.example.com/mcp`, rather than a local command to run. Which configuration best matches this integration pattern?

    Sources2

    3.Deploying a server locally or remotely

    A server can run as a local process or a remote service, and the transport follows from that choice. A stdio server is launched on the user's machine. An HTTP server listens on a network interface, which is where most deployment risk comes from. The Streamable HTTP rules cover three points. Servers must validate the Origin header on all incoming connections to prevent DNS rebinding attacks, and must respond with HTTP 403 Forbidden if the header is present and invalid. When running locally, servers should bind only to 127.0.0.1 rather than 0.0.0.0. And servers should implement proper authentication for every connection.

    On the client side, Claude Code sends credentials to an authenticated remote server as HTTP headers that you set when you add the server:

    Adding a remote HTTP server that expects a bearer tokenbash
    # Example with Bearer token
    claude mcp add --transport http secure-api https://api.example.com/mcp \
      --header "Authorization: Bearer your-token"

    Sources2

    4.Connecting a server to Claude Code

    Claude Code is an MCP host. Once it is connected to your server, Claude can use it for tasks such as querying a database or implementing an issue from a tracker, and a server can even act as a channel that pushes messages into the session. The documentation shows how to identify what you have been given. A URL such as https://mcp.example.com/mcp means the server is remote. A launch command such as npx -y @example/mcp-server means it runs on your machine. An mcpServers JSON block is configuration written for another client's settings file.

    Adding a local stdio server: everything after -- is the launch commandbash
    # Basic syntax
    claude mcp add [options] <name> -- <command> [args...]
    
    # Real example: Add Airtable server
    claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport stdio airtable \
      -- npx -y airtable-mcp-server
    Matching a server's shape to the way Claude Code connects to it
    Server shapeHow to add itConfig type
    Local launch commandclaude mcp add --transport stdio <name> -- <command> [args...]No type field; an entry without a type is read as stdio
    Remote HTTP endpointclaude mcp add --transport http <name> <url>"type": "http"
    Remote SSE endpointclaude mcp add --transport sse <name> <url>"type": "sse"
    WebSocket endpointclaude mcp add-json with a wss:// url"type": "ws"

    When you paste an mcpServers block through claude mcp add-json, give every url entry an explicit type. Server names may contain only letters, numbers, hyphens and underscores. After adding servers, claude mcp list shows all configured servers, claude mcp get <name> shows details, claude mcp remove <name> removes one, and /mcp inside Claude Code shows status. Common states include: a project-scoped server from .mcp.json that is pending your approval, a server rejected by a disabledMcpjsonServers entry (shown only in claude mcp get), and a server disabled for the project through disabledMcpServers, which you can turn back on from /mcp. Claude Code also warns about hidden leading or trailing whitespace in config values, which often comes from a pasted token, and about the same server name defined in more than one scope with different endpoints.

    For authoring, Claude Code offers a helper: install the mcp-server-dev plugin with /plugin install mcp-server-dev@claude-plugins-official, then run /mcp-server-dev:build-mcp-server. These sources cover connecting servers to Claude Code only. They do not describe how the Agent SDK loads or authenticates MCP servers, so that is outside this lesson.

    A developer configures an MCP server named `github` that exposes a `list_issues` tool. To auto-approve only this specific tool, without granting access to any other tool on the server, which entry should be added to `allowedTools`?

    Sources3

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.Writing debug output to stdout from a stdio server is harmless, because the client ignores lines it does not recognise.Why is that wrong?

      stdout is reserved for protocol messages. Logs belong on stderr, which the client may capture, forward or ignore.

      Covered in stdio: the server as a child process

    2. 2.A locally run HTTP MCP server should listen on 0.0.0.0 so every client on the machine can reach it.Why is that wrong?

      Local servers should bind only to 127.0.0.1, validate the Origin header against DNS rebinding, and authenticate every connection.

      Covered in Deploying a server locally or remotely

    3. 3.An mcpServers entry that has only a url field will be connected to Claude Code as a remote HTTP server.Why is that wrong?

      Claude Code treats an entry with no type as stdio, so a url-only entry fails. Add "type": "http", "sse" or "ws" to match the endpoint.

      Covered in Connecting a server to Claude Code

    Practise it for real

    Connect a remote MCP server to Claude Code, inspect it with the management commands, then remove it.

    1. 1.Run: claude mcp add --transport http notion https://mcp.notion.com/mcp

      Why: The server is given as a URL, so it is remote and needs the http transport rather than a stdio launch command.

      You should see: Claude Code records a server named notion.

    2. 2.Run: claude mcp list

      Why: This lists every configured server along with any warnings, such as hidden whitespace or the same name defined in more than one scope.

      You should see: notion appears among the configured servers.

    3. 3.Run: claude mcp get notion

      Why: This shows details for one server, including states that claude mcp list does not show, such as a rejected .mcp.json server.

      You should see: The notion entry is shown with its details.

    4. 4.Start claude and run /mcp

      Why: The /mcp panel is where you check server status from inside Claude Code and re-enable disabled servers.

      You should see: notion is listed in the panel with its current status.

    5. 5.Run: claude mcp remove notion

      Why: Removing test servers keeps you from having the same name defined in several scopes with different endpoints later.

      You should see: notion no longer appears in claude mcp list.

    Stuck? Get a nudge

    If the URL-based entry you paste through claude mcp add-json fails to connect, check whether it has a type field.

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “The server reads JSON-RPC messages from stdin and writes JSON-RPC messages to stdout.”
      ↩︎ stdio: the server as a child process
      “Messages are delimited by newlines, and MUST NOT contain embedded newlines.”
      ↩︎ stdio: the server as a child process
      “SHOULD NOT assume stderr output indicates error conditions”
      ↩︎ stdio: the server as a child process
      “The server returns any other error, or does not respond within a reasonable timeout: the server is legacy.”
      ↩︎ stdio: the server as a child process
      “The server MUST NOT write anything to its stdout that is not a valid MCP message.”
      ↩︎ Exam trap 1
    2. 2.
      “The server exposes a single HTTP endpoint (the MCP endpoint) that accepts POST.”
      ↩︎ Streamable HTTP: one endpoint, one POST per message
      “The server MUST NOT send independent JSON-RPC requests on this stream.”
      ↩︎ Streamable HTTP: one endpoint, one POST per message
      “Removal of protocol-level sessions.”
      ↩︎ Streamable HTTP: one endpoint, one POST per message
      “Servers MUST validate the Origin header on all incoming connections to prevent DNS rebinding attacks.”
      ↩︎ Deploying a server locally or remotely
      “Servers SHOULD implement proper authentication for all connections.”
      ↩︎ Deploying a server locally or remotely
      “When running locally, servers SHOULD bind only to localhost (127.0.0.1) rather than all network interfaces (0.0.0.0).”
      ↩︎ Exam trap 2
    3. 3.
      “A launch command such as npx -y @example/mcp-server: the server runs on your machine.”
      ↩︎ Connecting a server to Claude Code
      “an MCP server can also act as a channel that pushes messages into your session”
      ↩︎ Connecting a server to Claude Code
      “Pending approval (run `claude` to approve): a project-scoped server from .mcp.json”
      ↩︎ Connecting a server to Claude Code
      “Claude Code reads an entry with no type as a stdio server, so a url entry without a type fails.”
      ↩︎ Exam trap 3

    Ready to test yourself?

    Practise the 20 questions on this subdomain.