# How the MCP Server Handles STDIO vs HTTP Transport and Security in code-review-graph

> Explore how the MCP server handles stdio vs HTTP transport and security in code-review-graph. Learn about runtime parameters, internal flags, and HTTP connection security.

- Repository: [Tirth Kanani/code-review-graph](https://github.com/tirth8205/code-review-graph)
- Tags: internals
- Published: 2026-07-29

---

**The code-review-graph MCP server uses FastMCP to toggle between stdio (default) and streamable-http transports via a runtime parameter, automatically setting an internal flag for stdio mode while enforcing strict Origin header validation and content-type checks for HTTP connections.**

The `code-review-graph` repository implements a Model Context Protocol (MCP) server built on **FastMCP**, designed to support both local stdio and network-based HTTP transports. Understanding how the MCP server handles transport selection and security is crucial for deploying the tool safely across different environments.

## Transport Architecture Overview

The server determines which transport mechanism to use based on the `transport` argument passed to the `run()` function in [`code_review_graph/main.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/main.py). This design allows operators to switch between local process communication and HTTP-based remote access without modifying core business logic.

### STDIO Transport (Default)

When the server starts without explicit transport configuration, it defaults to **stdio** (standard input/output) mode. In this configuration:

- The server uses a single-threaded, line-delimited protocol that operates over stdin/stdout streams
- An internal module-wide flag `_MCP_STDIO_ACTIVE` is set to `true` during initialization
- Long-running MCP tools are automatically offloaded to background threads to keep the stdio event loop responsive and prevent blocking

As implemented in [`code_review_graph/main.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/main.py) (lines 1086-1088), the stdio transport requires no network stack and exposes no attack surface to remote clients, making it ideal for local integrations with command-line tools.

### HTTP Transport (Streamable-HTTP)

When `transport="streamable-http"` is specified, the server initializes a lightweight ASGI HTTP server that exposes the MCP protocol over web standards:

- The endpoint `/mcp/` becomes available for JSON-RPC style communication
- The transport utilizes Server-Sent Events (SSE) for streaming responses
- FastMCP handles the ASGI lifecycle, converting HTTP requests into MCP tool calls

According to the source code (lines 1107-1110), this mode is activated by passing the transport string directly to `FastMCP.run()`, enabling browser-based clients and remote tooling to interact with the code review graph.

## Security Controls for HTTP Transport

When operating in HTTP mode, the server implements multiple security layers to prevent cross-origin attacks and content-type confusion. These protections are verified in the test suite, particularly in [`tests/test_http_origin_guard.py`](https://github.com/tirth8205/code-review-graph/blob/main/tests/test_http_origin_guard.py).

### Origin Header Validation

The server applies an **origin guard** middleware that inspects the `Origin` header of incoming HTTP requests:

- Requests without an `Origin` header (typical of non-browser clients like `curl` or Python scripts) are accepted automatically
- Browser-based requests must match a whitelisted origin set or be explicitly absent
- Mismatched origins receive a `406 Not Acceptable` response, mitigating Cross-Site Request Forgery (CSRF) attacks

This validation logic (lines 28-35) ensures that only intended origins can trigger MCP tool executions when the server is exposed over HTTP.

### Content-Type and Accept Header Enforcement

FastMCP enforces strict header requirements for HTTP transport compliance:

- Clients must include `Accept: application/json, text/event-stream` to indicate they can handle JSON responses or SSE streams
- Requests must specify `Content-Type: application/json` for POST bodies
- Missing or incorrect headers result in immediate `406` rejection (lines 28-30)

These checks prevent content-type confusion attacks and ensure clients are prepared to handle the binary or streaming responses generated by graph analysis tools.

### FastMCP Version Compatibility

The security model depends on specific FastMCP features for middleware injection. The test suite verifies that the installed FastMCP version supports:

- The `run_http_async` method signature
- A `middleware` parameter for origin validation (lines 126-130)

If these capabilities are absent, the server cannot guarantee origin protection, and the test suite will fail fast to prevent deployment of an insecure configuration.

## Practical Implementation Examples

**Starting the server in stdio mode (safe for local CLI integration):**

```python
import code_review_graph.main as crg

# Uses default stdio transport, sets _MCP_STDIO_ACTIVE flag

crg.run()

```

**Starting the server in HTTP mode (requires origin-aware client configuration):**

```python
import code_review_graph.main as crg

# Exposes /mcp/ endpoint with origin validation

crg.run(transport="streamable-http")

```

**Python client calling the HTTP MCP endpoint with required headers:**

```python
import httpx

resp = httpx.post(
    "http://localhost:8000/mcp/",
    json={"tool": "analyze_graph", "args": {"repo": "example/repo"}},
    headers={
        "Accept": "application/json, text/event-stream",
        "Content-Type": "application/json"
    }
)
print(resp.json())

```

**Verifying the stdio flag for thread management:**

```python

# Accessing the internal flag (defined in main.py lines 1139-1144)

from code_review_graph import main

if main._MCP_STDIO_ACTIVE:
    print("Running in stdio mode - tools will use background threads")

```

## Summary

- The transport mechanism is selected via the `transport` parameter in [`code_review_graph/main.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/main.py), supporting either `stdio` (default) or `streamable-http`
- STDIO mode sets `_MCP_STDIO_ACTIVE` to true and offloads long-running operations to background threads to maintain stream responsiveness
- HTTP mode exposes a `/mcp/` endpoint but requires strict `Accept` and `Content-Type` headers to prevent content negotiation attacks
- An origin validation middleware rejects cross-origin requests when `Origin` headers are present, mitigating CSRF risks
- The test suite enforces FastMCP version compatibility to ensure middleware capabilities exist before allowing HTTP transport deployment

## Frequently Asked Questions

### What is the default transport mode for the code-review-graph MCP server?

The default transport is **stdio** (standard input/output). When you invoke `crg.run()` without arguments, the server initializes stdio streams and sets the internal `_MCP_STDIO_ACTIVE` flag, making it suitable for local CLI tool integration without network exposure.

### How does the server protect against CSRF attacks when using HTTP transport?

The server implements an origin guard middleware that validates the `Origin` header on incoming HTTP requests. Requests from browser contexts with mismatched origins receive a `406 Not Acceptable` response, while non-browser clients (which typically omit the Origin header) are accepted. This pattern is tested in [`tests/test_http_origin_guard.py`](https://github.com/tirth8205/code-review-graph/blob/main/tests/test_http_origin_guard.py) (lines 69-78).

### Why does the stdio transport require background thread management?

In [`code_review_graph/main.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/main.py) (lines 1139-1144), the server detects when stdio mode is active and routes long-running MCP tool executions to background threads. This prevents the stdio event loop from blocking on graph analysis operations, ensuring the transport remains responsive for protocol handshake and heartbeat messages.

### Which HTTP headers are required when calling the MCP server over HTTP?

Clients must include `Accept: application/json, text/event-stream` and `Content-Type: application/json` headers. The FastMCP framework enforces these requirements (lines 28-30 in the origin guard tests) to ensure clients can properly handle JSON responses or Server-Sent Events streams returned by graph analysis tools.