# How MCP Transports Align With Core Socket Behavior in OpenHuman

> Discover how MCP transports in OpenHuman align with core socket behavior by reusing the HTTP client, WebSocket channels, TLS, and authentication for consistent network operations and security.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: internals
- Published: 2026-08-30

---

**MCP transports in OpenHuman reuse the core socket layer's HTTP client, WebSocket channels, TLS configuration, and authentication store, ensuring identical network behavior and security policies across native RPC and external service calls.**

The OpenHuman framework implements a unified communication architecture where Multiplexed Channel Protocol (MCP) transports directly leverage the core socket infrastructure instead of maintaining a separate network stack. This design, implemented in the `tinyhumansai/openhuman` repository, guarantees consistent request signing, error classification, and observability across both internal RPC endpoints and external service integrations.

## Core Socket Architecture

The foundation resides in [`src/core/socket.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/socket.rs), which exposes a JSON-RPC endpoint over a local HTTP server and an optional WebSocket (Socket.IO) channel for push events. This layer handles live agent updates, thread notifications, and audit logs through a single, centralized network stack that powers both the desktop UI via Tauri and headless embeds.

## MCP Transport Integration Points

The MCP package located in `src/openhuman/mcp/` provides a generic transport abstraction for external services including cloud-hosted AI backends and third-party channel providers. Rather than implementing isolated networking logic, MCP reuses the core socket primitives through six critical alignment strategies.

### Shared HTTP Client and Request Signing

**`McpHttpClient`** performs all MCP calls over the same HTTP client that the core uses for its own RPC traffic. Located in [`src/openhuman/mcp/client/http.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/mcp/client/http.rs), this client automatically injects the `x-sdk-name` header and authentication credentials that the core expects, ensuring identical request signing and timeout handling across both layers.

MCP clients pull the current bearer token from the global `CoreContext` using the core-wide **`BearerToken`** store. This integration means that token rotations performed by the core during session refreshes are instantly visible to MCP callers without additional configuration or re-authentication steps.

### WebSocket Namespace Sharing

When the core socket enables WebSocket listeners, **`McpWebSocketTransport`** registers its own namespaces (`/mcp/*`) on the same channel. This implementation in [`src/openhuman/mcp/client/websocket.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/mcp/client/websocket.rs) allows MCP-based tools to receive real-time events—including tool progress updates, server status notifications, and completion signals—without opening separate socket connections or consuming additional ports.

### Unified TLS and Proxy Policies

Both layers share the **`transport::http_client`** module located in [`src/openhuman/mcp/http_client.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/mcp/http_client.rs). MCP inherits the core's TLS strategy—using Rustls on non-Windows platforms and Schannel on Windows—along with proxy resolution from `config::proxy`. This guarantees that MCP traffic respects the same corporate proxy policies as core RPC traffic, eliminating network configuration drift between internal and external service calls.

### Common Error Classification Layer

MCP request errors funnel through **`rest::classify_sdk_error`**, the same error-mapping layer used by the core's SDK wrapper. This yields uniform error codes—such as `Unauthorized` for authentication failures, `Transient` for retryable network issues, and `NotFound` for missing resources—across both native RPC and MCP external service calls.

### Consolidated Observability Pipeline

All MCP requests emit tracing spans through **`observability::tracing`** hooks, using identical span identifiers (`[rpc]`, `[mcp]`) to native core RPC calls. This allows a single observability pipeline to capture latency metrics, retry attempts, and success rates across the entire stack without separate instrumentation configurations.

## Practical Implementation Examples

Because MCP adopts the core socket's configuration, no additional network ports or credentials are required when enabling MCP tooling. The following examples demonstrate how to initialize MCP clients that automatically inherit core socket behavior.

### Initializing an MCP HTTP Client

```rust
use openhuman::mcp::client::McpHttpClient;
use openhuman::core::builder::HarnessBuilder;

// Build a core harness with socket listener for live updates
let harness = HarnessBuilder::new()
    .provider(openhuman::provider::openai_compatible(
        "https://api.openai.com/v1",
        "sk-....",
    ))
    .access(openhuman::access::full())
    .socket(openhuman::socket::SocketConfig::enabled())
    .build()
    .await?;

// MCP client automatically re-uses the same HTTP client & bearer token
let mcp = McpHttpClient::new(&harness);
let servers = mcp.list_servers().await?;
println!("MCP servers: {:?}", servers);

```

### Subscribing to MCP WebSocket Events

```rust
use openhuman::mcp::client::McpWebSocketTransport;
use futures_util::StreamExt;

let ws = McpWebSocketTransport::connect(&harness).await?;
let mut events = ws.subscribe("mcp.events");

// Process real-time MCP events (progress, completion, errors)
while let Some(event) = events.next().await {
    println!("MCP event: {:?}", event);
}

```

### Streaming Tool Execution via Core Socket

```rust
let tool = mcp.tool("my_custom_tool");
let mut stream = tool.run_streaming(vec!["arg1", "arg2"]).await?;

// Process streamed chunks as they arrive through the core socket
while let Some(chunk) = stream.next().await {
    println!("Chunk: {}", String::from_utf8_lossy(&chunk));
}

```

## Summary

- **HTTP client reuse**: `McpHttpClient` in [`src/openhuman/mcp/client/http.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/mcp/client/http.rs) automatically inherits the core's HTTP configuration, authentication headers, and timeout settings.
- **WebSocket channel sharing**: `McpWebSocketTransport` registers on the core socket's existing WebSocket listener, enabling real-time events without additional connections.
- **Unified security posture**: The shared `transport::http_client` module ensures both layers use identical TLS certificates and proxy resolutions from `config::proxy`.
- **Consistent error handling**: MCP leverages `rest::classify_sdk_error` to produce uniform error codes across native RPC and external service calls.
- **Simplified testing architecture**: Unit and integration tests can spin up a single in-process core instance using `Harness::builder()` to exercise both core RPC and MCP calls against the same mock server.

## Frequently Asked Questions

### How does MCP authentication align with core socket sessions?

MCP clients automatically pull the current bearer token from the global `CoreContext` store using the core-wide `BearerToken` implementation. When the core performs token rotation during session refreshes, MCP callers immediately receive the updated credentials without manual intervention, ensuring continuous authorization across both transport layers.

### Can MCP operate without the core socket WebSocket enabled?

While MCP can function over HTTP without WebSocket support, disabling the core socket limits real-time event capabilities. The `McpWebSocketTransport` requires the core socket's WebSocket listener to be active in order to register its `/mcp/*` namespaces and receive push notifications for tool progress and server status updates.

### What error codes does MCP share with the core socket layer?

MCP requests funnel through `rest::classify_sdk_error`, producing uniform error classifications including `Unauthorized` for authentication failures, `Transient` for retryable network issues, and `NotFound` for missing resources. This ensures consistent error handling logic across native RPC and MCP external service calls.

### How does MCP handle corporate proxy configurations?

MCP inherits the core's proxy resolution from `config::proxy` through the shared `transport::http_client` module. This guarantees that all MCP traffic respects the same corporate proxy policies as core RPC traffic, using Rustls on non-Windows platforms and Schannel on Windows for TLS handling.