# `WardrikMCP.Server`

An MCP server and how to reach it.

    github: [
      transport: {:stdio, command: "github-mcp-server", args: ["stdio"], env: %{}},
      only: ["search_issues", "create_issue"],
      gated: ["create_*"]
    ]

    linear: [
      transport: {:streamable_http, url: "https://mcp.linear.app/mcp", headers: %{}},
      credential_name: "linear"
    ]

## Options

  * `:transport` - required. `{:stdio, command: ..., args: ..., env: ...}` or
    `{:streamable_http, url: ..., headers: ...}`. The `url` is the server's endpoint, as it
    publishes it, as `"https://mcp.linear.app/mcp"`. A command gets its `env` and only these
    of the app's own variables: `HOME`, `LANG`, `LC_ALL`, `LOGNAME`, `PATH`, `SHELL`, `TERM`,
    `TMPDIR` and `USER`. It's started through `env`, which unsets the rest.
  * `:only` - the server's tool names to offer, as `["search_issues"]`. Every tool unless set.
  * `:except` - the server's tool names to leave out.
  * `:prefix` - the prefix for tool names, as `"linear"` for `linear__search_issues`. The
    server's name unless set.
  * `:credential_name` - the credential each principal reaches the server with. See
    `WardrikCore.Credentials`.
  * `:credential_header` - the HTTP header the credential goes in. `"authorization"` unless set.
  * `:credential_scheme` - the scheme before the credential. `"Bearer"` unless set.
  * `:credential_env` - the environment variable the credential goes in, for a command.
  * `:timeout` - milliseconds a call may take. `60_000` unless set.
  * `:max_result_bytes` - bytes of a result the model gets. `131_072` unless set.
  * `:cost` - each call's cost, as `[usd: 0.001]`, or a function of the server's result.
  * `:gated` - which tools need a person's approval: `true`, `false`, or tool name globs, as
    `["create_*"]`. Tools not marked read-only unless set.
  * `:trusted` - `true` to treat answers as the deployment's own, not labelled `"outside"`.
    `false` unless set.

# `cost`

```elixir
@type cost() :: keyword(number()) | (map() -&gt; %{optional(atom()) =&gt; number()})
```

# `t`

```elixir
@type t() :: %WardrikMCP.Server{
  check: (String.t() -&gt; :ok | {:error, String.t()}) | nil,
  cost: cost() | nil,
  credential_env: String.t() | nil,
  credential_header: String.t(),
  credential_name: String.t() | nil,
  credential_scheme: String.t(),
  except: [String.t()] | nil,
  gated: boolean() | [String.t()] | nil,
  max_result_bytes: pos_integer(),
  mcp: atom() | nil,
  name: String.t(),
  only: [String.t()] | nil,
  prefix: String.t() | nil,
  timeout: pos_integer(),
  transport: {:stdio | :streamable_http, keyword()},
  trusted: boolean()
}
```

# `gated?`

```elixir
@spec gated?(t(), String.t(), boolean()) :: boolean()
```

Returns whether calls to the tool `name` need a person's approval.

# `labels`

```elixir
@spec labels(t()) :: [String.t()]
```

Returns the labels on the server's answers: `["outside"]`, or `[]` if it's trusted.

# `new!`

```elixir
@spec new!(atom() | String.t(), keyword()) :: t()
```

Builds a server named `name`. Raises `ArgumentError` on an unknown option.

# `offers?`

```elixir
@spec offers?(t(), String.t()) :: boolean()
```

Returns whether the server offers its tool `name`, given `only` and `except`.

# `prefix`

```elixir
@spec prefix(t()) :: String.t()
```

Returns the prefix for the server's tool names.

# `reachable`

```elixir
@spec reachable(t()) :: :ok | {:error, String.t()}
```

Returns `:ok` if the server may be reached now, or `{:error, reason}`.

Always `:ok` without a `check`. With one, a command is refused and the URL must pass it.

# `transport`

```elixir
@spec transport(t(), String.t() | nil) :: {:stdio | :streamable_http, keyword()}
```

Returns the transport options for reaching the server with the caller's `token`.

---

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