Skip to content

HTTP Transport for MCP Servers

Shoal's MCP server (shoal-orchestrator) supports HTTP transport via FastMCP's streamable-http mode. The key mental model is simple: this is one orchestrator server with multiple client paths, not two different Shoal MCP servers.

Use this page to answer two questions: - How does a client connect? Either directly over HTTP or indirectly through shoal-mcp-proxy if the tool only speaks stdio MCP. - Which servers use HTTP? Only shoal-orchestrator defaults to HTTP; third-party MCP servers still use Shoal's socket pool.

flowchart LR
    CLI["shoal mcp start shoal-orchestrator"] --> Server["shoal-mcp-server<br/>name: shoal-orchestrator"]
    HttpClient["HTTP-capable MCP client"] --> Endpoint["http://localhost:8390/mcp/"]
    StdioClient["stdio-only MCP client"] --> Proxy["shoal-mcp-proxy shoal-orchestrator"]
    Proxy --> Endpoint
    Endpoint --> Server
    Other["memory / filesystem / github / fetch"] --> Pool["socket pool + per-connection spawn"]

Quick Start

Start the orchestrator (HTTP is the default)

shoal mcp start shoal-orchestrator

This automatically starts the server in HTTP mode on port 8390. No extra flags needed — Shoal's registry knows shoal-orchestrator defaults to HTTP.

Verify it's running

shoal mcp doctor

The doctor probes HTTP servers using FastMCP's StreamableHttpTransport and reports protocol, tool count, version, and latency:

┌────────────────────┬──────────┬──────┬─────────┬─────────┐
│ NAME               │ PROTOCOL │ TOOLS│ VERSION │ LATENCY │
├────────────────────┼──────────┼──────┼─────────┼─────────┤
│ shoal-orchestrator │ http     │ 34   │ 0.39.0  │ 12ms    │
└────────────────────┴──────────┴──────┴─────────┴─────────┘

How It Works

Server-side

The shoal-mcp-server binary supports two transport modes:

Mode Flag Default Port Protocol
stdio (none) JSON-RPC over stdin/stdout
HTTP --http 8390 FastMCP streamable-http
# Stdio mode (for direct MCP client connections)
shoal-mcp-server

# HTTP mode on default port
shoal-mcp-server --http

# HTTP mode on custom port
shoal-mcp-server --http 8391

In HTTP mode, the server listens at http://localhost:<port>/mcp/.

Transport auto-detection

When you run shoal mcp start <name>, Shoal checks the transport for that server:

  1. User registry (~/.config/shoal/mcp-servers.toml) — explicit transport field
  2. Built-in defaults — shoal-orchestrator defaults to "http"
  3. Fallback — all other servers default to "socket"

The shoal-orchestrator is the only built-in server that defaults to HTTP. All other servers (memory, filesystem, github, fetch) continue using Unix socket transport.


Registry Configuration

View the registry

shoal mcp registry

Shows all known servers with their transport mode:

┌────────────────────┬──────────┬───────────┬────────────────────────────────────────┐
│ NAME               │ SOURCE   │ TRANSPORT │ COMMAND                                │
├────────────────────┼──────────┼───────────┼────────────────────────────────────────┤
│ memory             │ built-in │ socket    │ npx -y @modelcontextprotocol/server-…  │
│ shoal-orchestrator │ built-in │ http      │ shoal-mcp-server                       │
└────────────────────┴──────────┴───────────┴────────────────────────────────────────┘

Override transport in user config

# ~/.config/shoal/mcp-servers.toml

# Force a server to use HTTP
[my-custom-server]
command = "my-mcp-server"
transport = "http"

# Or force socket for the orchestrator
[shoal-orchestrator]
command = "shoal-mcp-server"
transport = "socket"

Tool Integration

AI tools that support MCP over HTTP can connect directly to the orchestrator endpoint:

http://localhost:8390/mcp/

For tools that only support stdio MCP, use shoal-mcp-proxy to bridge:

shoal-mcp-proxy shoal-orchestrator

The proxy detects the server's transport mode and connects via HTTP or socket accordingly. It is a bridge, not a second Shoal MCP server.

Hermes Agent (experimental)

Hermes can connect directly to shoal-orchestrator over HTTP MCP. This path is experimental and still in development. The verified rollout today is local-only on 127.0.0.1, with a strict allow-list and read-first workflows.

approvals:
  mode: manual

mcp_servers:
  shoal:
    url: "http://127.0.0.1:8390/mcp/"
    tools:
      include:
        - list_sessions
        - session_info
        - session_snapshot
        - capture_pane
        - read_journal
        - session_summary
        - append_journal
        - create_session
        - spawn_team
        - wait_for_team
      prompts: false
      resources: false

Start with session_snapshot for fleet inspection. Treat kill_session, merge tools, and other destructive mutations as opt-in only after you have proven the whitelist and operator loop locally.

Tip

If shoal mcp start shoal-orchestrator fails because your environment cannot resolve the server command from the MCP pool, override it explicitly:

shoal mcp start shoal-orchestrator --http --port 8390 \
  --command "uv run shoal-mcp-server"

Application-level batching

The orchestrator now exposes two high-leverage surfaces for reducing round trips and token overhead:

  • batch_execute — one MCP call that executes mixed Shoal operations and returns ordered per-item results
  • session_snapshot — one MCP call that gathers selected fields across many sessions for supervisor-style inspection
  • POST /batch — HTTP equivalent of batch_execute
  • POST /sessions/snapshot — HTTP equivalent of session_snapshot

These are application-level batching surfaces. Shoal does not rely on protocol-level JSON-RPC batch arrays. Instead, one MCP tool call or one HTTP request carries multiple operations and returns structured per-item success or error envelopes.

session_snapshot is the read-optimized path when you need a fleet view. Callers can request only the fields they need — for example status, pane_tail, mcp_servers, or last_activity — instead of making separate session_info, capture_pane, and status calls for each session.

batch_execute supports mixed operations such as session_info, session_status, capture_pane, send_keys, kill_session, read_history, append_journal, and read_journal. Read-heavy batches can run with bounded parallelism; batches containing kill_session or aggregate session_status execute serially so later reads observe earlier writes safely.


Diagnostics

Health check

shoal mcp doctor

For HTTP servers, the doctor: 1. Reads the port from ~/.local/share/shoal/mcp-pool/ports/<name>.port 2. Connects via FastMCP Client with StreamableHttpTransport 3. Reports server name, version, tool count, and round-trip latency

Clean up stale servers

shoal mcp doctor --cleanup

Removes stale PID and port files for servers that are no longer running.

View server logs

shoal mcp logs shoal-orchestrator

Why HTTP?

The transport evaluation spike compared Unix socket byte bridging with FastMCP HTTP transport:

  • Compatibility: HTTP works with remote sessions via SSH tunnels — no Unix socket forwarding needed
  • Tooling: Standard HTTP endpoints are easier to debug (curl, browser, etc.)
  • FastMCP native: Uses FastMCP's built-in streamable-http transport with no custom bridging code

Socket transport remains the default for stateless MCP servers (memory, filesystem, etc.) where the byte bridge overhead is minimal and no remote access is needed.


Further Reading