# `AttestoMCP.Server.Plug`
[🔗](https://github.com/XukuLLC/attesto_mcp_server/blob/v2.8.0/lib/attesto_mcp_server/plug.ex#L1)

Plug-compatible Streamable HTTP boundary for modern and legacy MCP.

Every protected MCP leg authenticates through `AttestoMCP.Plug.ProtectResource`
before package-owned request decoding or registry dispatch. A host parser
placed earlier in the endpoint runs before this Plug and must apply its own
input limit. Metadata discovery is the one intentionally public route
defined by RFC 9728. Hosts may select
request-scoped tool streams with `stream_tools` or `stream_all_tools`; both
options are validated during `init/1`.

`:auth` accepts either a keyword list or a zero-arity remote callback/MFA
returning one. Resolver-backed authentication is evaluated for every
applicable MCP or metadata request, so runtime authorization configuration
is not captured by router compilation. The trusted resolver may supply the
canonical resource or origin at runtime; it is checked against the configured
Plug path and reused for metadata and audience verification. A resolver may
not replace the boundary's canonical assign keys, and failures fail the
request closed.

A host may keep that canonical resource pinned for RFC 9728 metadata while
accepting tokens for an explicit set of alternate gateway identifiers by
supplying Attesto core's `:trusted_audiences` inside `:auth`. The list
replaces the single-resource audience policy, so it must include the
canonical resource when direct clients should remain accepted.

`:principal_binding` may derive a bounded stable identity from the complete
authenticated principal without replacing the value handlers receive.
`:client_ip` may derive the canonical IPv4 or IPv6 tuple used by both
authenticated and failed-authentication rate-limit buckets. It accepts a
one-argument function or MFA receiving the `Plug.Conn`; when omitted,
`conn.remote_ip` is used verbatim. Explicit callback failures and non-IP
returns fail closed and emit neutral `client_ip/exception` telemetry.
`:authorize` is a separate mount-level business-policy callback. It receives
the authenticated base context once per protected HTTP leg; only literal
`true` permits the request, and denial is a neutral 403 before POST body
reading or protocol dispatch.

# `auth_options_resolver`

```elixir
@type auth_options_resolver() ::
  (-&gt; keyword()) | {module(), atom()} | {module(), atom(), [term()]}
```

Supported Plug boundary options.

# `plug_option`

```elixir
@type plug_option() ::
  {:server, pid() | atom()}
  | {:path, String.t()}
  | {:auth, keyword() | auth_options_resolver()}
  | {:scope_map, map()}
  | {:scope_policy, scope_policy()}
  | {:default_scopes, [String.t()]}
  | {:scopes_supported, [String.t()]}
  | {:context_builder,
     (Plug.Conn.t() -&gt; map())
     | {module(), atom()}
     | {module(), atom(), [term()]}}
  | {:principal_binding,
     (term() -&gt; term()) | {module(), atom()} | {module(), atom(), [term()]}}
  | {:client_ip,
     (Plug.Conn.t() -&gt; :inet.ip_address())
     | {module(), atom()}
     | {module(), atom(), [term()]}}
  | {:authorize,
     (map() -&gt; boolean()) | {module(), atom()} | {module(), atom(), [term()]}}
  | {:subscription_scopes, [String.t()]}
  | {:max_body_bytes, pos_integer()}
  | {:max_message_bytes, pos_integer()}
  | {:allow_http, boolean()}
  | {:allow_dynamic_origin, boolean()}
  | {:origin, String.t()}
  | {:base_url, String.t()}
  | {:resource, String.t()}
  | {:resource_audience, String.t()}
  | {:stream_keepalive_ms, pos_integer()}
  | {:legacy_keepalive_ms, pos_integer()}
  | {:subscription_timeout, pos_integer()}
  | {:stream_queue_size, pos_integer()}
  | {:subscription_queue_size, pos_integer()}
  | {:max_queue, pos_integer()}
  | {:stream_all_tools, boolean()}
  | {:stream_tools, [String.t()]}
```

# `scope_policy`

```elixir
@type scope_policy() :: %{optional(String.t()) =&gt; scope_policy_mode()}
```

Per-method opt-ins to definition-based HTTP authorization.

# `scope_policy_mode`

```elixir
@type scope_policy_mode() :: :visible_definitions | :selected_definition
```

An explicit definition-based authorization mode for one MCP method.

# `call`

```elixir
@spec call(Plug.Conn.t(), map()) :: Plug.Conn.t()
```

Authenticates and serves one HTTP request through the MCP boundary.

# `init`

```elixir
@spec init([plug_option()]) :: map()
```

Initializes a Plug state for an already-supervised server and pinned auth boundary.

---

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