ExMCP.Server.StdioServer (ex_mcp v1.0.0-rc.0)

View Source

STDIO transport server for MCP protocol.

This server reads from stdin and writes to stdout, making it suitable for command-line tools and scripting environments.

Important: STDIO Transport Requirements

The MCP STDIO transport requires that ONLY JSON-RPC messages appear on stdout. All other output (logs, debug messages, etc.) MUST go to stderr to avoid contaminating the protocol stream.

Handling Startup Output

This module implements several strategies to handle startup output from Mix.install and other sources:

  1. Automatic logging suppression - Configures all loggers to emergency level
  2. Startup delay - Waits before reading stdin (configurable via :stdio_startup_delay)
  3. Graceful non-JSON handling - Ignores non-JSON lines instead of sending errors

Configuration

For scripts using Mix.install, add this before calling Mix.install:

# Configure STDIO mode and startup delay
Application.put_env(:ex_mcp, :stdio_mode, true)
Application.put_env(:ex_mcp, :stdio_startup_delay, 500)  # ms

# Suppress all logging for clean STDIO JSON-RPC
System.put_env("ELIXIR_LOG_LEVEL", "emergency")

Usage

defmodule MyStdioServer do
  use ExMCP.Server.Handler
  use ExMCP.Server.DSL, name: "my-stdio-server", version: "1.0.0"

  tool "hello", "Says hello" do
    param :name, :string, required: true
    run fn %{name: name}, state -> {:ok, "Hello, #{name}!", state} end
  end
end

# Start with STDIO transport
MyStdioServer.start_link(transport: :stdio)

Summary

Functions

Returns a specification to start this module under a supervisor.

Starts the STDIO server.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

start_link(opts)

Starts the STDIO server.

Options

  • :module - The handler module implementing server callbacks
  • Other options are passed to GenServer.start_link