# `ConduitMcp.Capabilities`
[🔗](https://github.com/nyo16/conduit_mcp/blob/v0.11.0/lib/conduit_mcp/capabilities.ex#L1)

Builds the `capabilities` object a server advertises to MCP clients.

The base set comes from the server module's `__capabilities__/0` when it
defines one (typically generated by `ConduitMcp.Endpoint`); otherwise it is
the plain `tools`/`resources`/`prompts` set with `listChanged: false`.

Flags for optional features are then overlaid according to which callbacks
the server module exports:

  * `resources.subscribe: true` (legacy) — `handle_subscribe_resource/2`,
    and only when the base set advertises `resources` at all.
  * `completions: %{}` — `handle_complete/3`.
  * `logging: %{}` — `handle_set_log_level/2` (legacy); always on the modern
    era, where any tool can emit `notifications/message` through
    `ConduitMcp.Log` on a request that sets a `logLevel`, and the
    2026-07-28 spec requires a server that emits them to declare `logging`.
  * `extensions: %{"io.modelcontextprotocol/tasks" => %{}}` — modern era
    only, while `ConduitMcp.Ext.Tasks` is enabled.

Used for both the legacy `initialize` reply and the modern
`server/discover` result (`ConduitMcp.Discover`). The two eras differ in
change notifications:

  * **legacy** advertises the base set as is: this library has no
    legacy delivery path for list-changed notifications, and
    `resources.subscribe` means the server implements
    `resources/subscribe`.
  * **modern** sets `listChanged: true` on each of `tools`, `prompts` and
    `resources` it advertises, and `subscribe: true` on `resources`:
    every modern server answers `subscriptions/listen`
    (`ConduitMcp.Subscriptions`, always running), whose
    `toolsListChanged`/`promptsListChanged`/`resourcesListChanged`/
    `resourceSubscriptions` filters deliver whatever the server pushes
    with `ConduitMcp.notify_tools_changed/0` and friends.

The tasks extension is advertised on the modern era only.

# `build`

```elixir
@spec build(module(), keyword()) :: map()
```

Returns the capabilities map advertised for `server_module`.

Options:

  * `:era` — `:legacy` (default) or `:modern`; see the moduledoc. Modern
    may add the tasks extension.

## Examples

    ConduitMcp.Capabilities.build(MyServer)
    #=> %{
    #     "tools" => %{"listChanged" => false},
    #     "resources" => %{"listChanged" => false},
    #     "prompts" => %{"listChanged" => false}
    #   }

    ConduitMcp.Capabilities.build(MyServer, era: :modern)
    #=> %{
    #     "tools" => %{"listChanged" => true},
    #     "resources" => %{"listChanged" => true, "subscribe" => true},
    #     "prompts" => %{"listChanged" => true}
    #   }

---

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