# `Snodo.Subscription`
[🔗](https://github.com/joshrotenberg/snodo/blob/v0.1.0/lib/snodo/subscription.ex#L1)

An opened, request-scoped MCP subscription.

Applications implement `Snodo.Subscription.Source`; this module owns filter
narrowing, lifecycle safety, bounded pulling, and protocol wire shaping.

# `id`

```elixir
@type id() :: integer() | String.t()
```

# `t`

```elixir
@type t() :: %Snodo.Subscription{
  accepted_filter: map(),
  context: Snodo.Context.t(),
  extension_filters: %{optional(String.t()) =&gt; map()},
  extension_registry: Snodo.Extension.Registry.t(),
  handle: term(),
  id: id(),
  protocol: module(),
  source: Snodo.Subscription.Source.Config.t()
}
```

# `acknowledgement`

```elixir
@spec acknowledgement(t()) :: {:ok, map()} | {:error, Snodo.Error.t()}
```

Returns the first required acknowledgement notification.

# `close`

```elixir
@spec close(t(), Snodo.Subscription.Source.close_reason()) :: :ok
```

Closes the application-owned source handle with an explicit reason.

# `completion`

```elixir
@spec completion(t()) :: {:ok, map()} | {:error, Snodo.Error.t()}
```

Returns the final successful JSON-RPC response for graceful completion.

# `failure`

```elixir
@spec failure(t(), term()) :: map()
```

Returns a terminal JSON-RPC error response for a failed open stream.

# `notification`

```elixir
@spec notification(t(), Snodo.Subscription.Event.t()) ::
  {:ok, map()} | :drop | {:error, Snodo.Error.t()}
```

Shapes one requested source event or drops an event outside the accepted filter.

# `open`

```elixir
@spec open(Snodo.Subscription.Source.Config.t(), map(), Snodo.Context.t()) ::
  {:ok, t()} | {:error, Snodo.Error.t()}
```

Starts a monitored, demand-driven source worker owned by the caller.

After each `continue/1`, the owner receives
`{:mcp_subscription, worker, outcome}` where the outcome is `{:ok, event}`,
`:closed`, or `{:error, reason}`.

# `start_worker`

```elixir
@spec start_worker(t(), pid()) :: {pid(), reference()}
```

Allows a subscription worker to pull exactly one more source outcome.

# `stop_worker`

```elixir
@spec stop_worker(pid(), reference()) :: :ok
```

Stops a worker and removes its process monitor.

---

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