# `ConduitMcp.Subscriptions.Filter`
[🔗](https://github.com/nyo16/conduit_mcp/blob/v0.11.0/lib/conduit_mcp/subscriptions/filter.ex#L1)

The `notifications` filter of a `subscriptions/listen` request
(`SubscriptionFilter`), reduced to the subset this server honours.

`parse/3` turns the request's `params` into a `t:t/0`:

  * `:ack` — the `notifications` object of
    `notifications/subscriptions/acknowledged`: only the fields honoured,
    each with the value honoured;
  * `:topics` — the `ConduitMcp.Subscriptions` topics the stream registers
    under;
  * `:kinds` — the honoured fields as atoms, for telemetry (never URIs).

## Fields

  * `toolsListChanged`, `promptsListChanged`, `resourcesListChanged` — a
    boolean. `true` is honoured when the server advertises the matching
    capability (`ConduitMcp.Capabilities.build/2`): an Endpoint without
    prompts omits `promptsListChanged` from the acknowledgment, as the
    specification asks. `false` subscribes to nothing.
  * `resourceSubscriptions` — a list of at most
    1000 URI strings. Each is authorized like `resources/read` (the
    resource's `scope`) and, when the server defines
    `c:ConduitMcp.Server.handle_subscribe_resource/2`, must also be
    accepted by it (`{:ok, _}`) — the same hook legacy `resources/subscribe`
    runs. A URI the caller may not read, or the hook refuses, is dropped
    from the acknowledgment silently, exactly as if it had not been requested, so
    the acknowledgment reveals nothing beyond what the caller may read.
    Duplicates are collapsed; an empty result omits the field.
  * `taskIds` — only while `ConduitMcp.Ext.Tasks` is enabled (otherwise an
    unknown field): a list of at most 1000 task ids for
    `notifications/tasks`. The request must declare the
    `io.modelcontextprotocol/tasks` extension in its client capabilities
    (`-32021` with `data.requiredCapabilities` otherwise, as the extension
    requires). Each id is kept only if the task exists and is owned by the
    caller (`ConduitMcp.Principal.id/1`, the owner check of `tasks/get`);
    any other id is dropped silently, so a foreign id and an unknown one
    look the same. The stream then receives a task's changes only while
    its principal is the task's owner (SV-1): the topic is keyed by owner.
    Duplicates are collapsed; an empty result omits the field.

A field of the wrong type, a `notifications` that is not an object, or
more than 1000 URIs or task ids is `-32602`. Unknown fields (a newer
revision's, or an extension's this server does not enable) are not
honoured and are omitted from the acknowledgment.

# `t`

```elixir
@type t() :: %ConduitMcp.Subscriptions.Filter{
  ack: %{optional(String.t()) =&gt; boolean() | [String.t()]},
  kinds: [atom()],
  topics: [ConduitMcp.Subscriptions.topic()]
}
```

An honoured filter; see the moduledoc.

# `max_resource_subscriptions`

```elixir
@spec max_resource_subscriptions() :: pos_integer()
```

The most URIs one `resourceSubscriptions` may name (1000).

# `parse`

```elixir
@spec parse(map(), module(), Plug.Conn.t() | map()) ::
  {:ok, t()} | {:error, integer(), String.t(), map() | nil}
```

Parses the `params` of a `subscriptions/listen` request for
`server_module`, authorizing resource URIs against `conn`.

---

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