# `Sake.Stdio`
[🔗](https://github.com/hattoriai/sake/blob/v0.4.3/lib/sake/stdio.ex#L1)

Serves a `Sake.Server` over standard input and output, for a client that
launches the server as a subprocess:

    Sake.Stdio.run(MyApp.MCP)

`run/2` blocks until standard input closes. In a supervision tree, start
it as a child instead, after `Sake`:

    {Sake.Stdio, server: MyApp.MCP}

From a Mix project, `mix sake.stdio MyApp.MCP` does the same.

Options: `server:` (the child's, required), `scope:` (the host's
principal: a value, or a function of no arguments called for every
request; default `nil`), `secret:` (binary or `{m, f, a}`; default the
`Sake` configuration, else a random secret for the life of the process),
`reraise:` (re-raise tool exceptions, for tests), `grace:` (ms that
requests still running when standard input closes get to finish,
default 2 000), `halt:` (the child's only: stop the VM once standard
input closes, default `true`), `input:` and `output:` (IO devices,
default standard input and output).

The server speaks both eras on the one connection. A request whose
`_meta` names the modern revision is served statelessly; an `initialize`
request opens the connection's legacy session, and requests without a
protocol version in `_meta` then belong to it. Each request runs in its
own process, so responses can arrive out of order;
`notifications/cancelled` stops a request and suppresses its response.

There is no authorization on stdio: the client that launched the server
already holds its credentials, and the server takes its own from its
environment. Pass the principal as `scope:`.

Standard output carries MCP messages only. While serving it, Sake moves
the default `Logger` handler to standard error and runs every request
with standard error as its group leader, so `IO.puts/1` in a tool cannot
break the stream.

# `log_to_stderr`

```elixir
@spec log_to_stderr() :: :ok
```

Moves the default `Logger` handler from standard output to standard
error. `run/2` and the child do this when they serve standard output; a
release that logs while it boots should also configure it:

    config :logger, :default_handler, config: [type: :standard_error]

# `run`

```elixir
@spec run(module(), keyword()) :: :ok
```

Serves `server` until standard input (or `input:`) closes.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
