{# MCP install widget: server-rendered client x method x scope x cooldown matrix. widget_name, clients, methods, cooldowns, panels, default_cooldown_mode, default_cooldown_days, variant are provided by MCPInstallWidget.context() / the directive's option merge. The scope row is rendered as one __scopes-group per client that has more than one scope. Single-scope clients (Claude Desktop) get no group — the prehydrate CSS in _ext/widgets/_prehydrate.py hides every group and shows only the active client's group via ``html[data-mcp-install-client="X"] .rp-mcp-install__scopes-group [data-scope-client="X"]``. Switching clients in widget.js updates ```` and the matching group becomes visible without any JS-driven DOM mutation. Each code block runs through the `highlight` filter (defined in docs._ext.widgets._base.make_highlight_filter) which wraps Sphinx's PygmentsBridge — so the output is byte-identical to a native ``.. code-block::`` block, meaning sphinx-copybutton + its prompt-strip regex work automatically. The output is then run through ``cooldown_days_slot`` (defined in docs._ext.widgets._base.make_cooldown_days_slot_filter) which swaps two post-Pygments sentinels: * ``<COOLDOWN_DURATION>`` becomes ``P7D`` — used by uvx and pip days bodies, where uv + pip 26.1+ re-evaluate the duration on every invocation. * ``<COOLDOWN_DATE>`` becomes ``YYYY-MM-DD`` — used by pipx days bodies because pipx 1.8.0's bundled pip rejects the duration form. ``widget.js`` updates both slot kinds' textContent on every cooldown-days input change. #}
{% for client in clients %} {% endfor %}
{% for method in methods %} {% endfor %}
{% for client in clients if client.scopes|length > 1 %}
{% for scope in client.scopes %} {% endfor %}
{% endfor %}
{% for panel in panels %}
{% if panel.method.doc_url %}

With {{ panel.method.label }} installed:

{% elif panel.method.id == 'pip' %}

Install the packages first:

{{ (("$ " ~ panel.pip_prereq) | highlight("console")) | cooldown_days_slot }}

Then {{ 'register' if panel.client.kind == 'cli' else 'use this config' }}:

{% endif %} {% if panel.scope.note %}

{{ panel.scope.note }}

{% endif %} {{ (panel.body | highlight(panel.language)) | cooldown_days_slot }} {% if panel.note %}

{{ panel.note }}

{% endif %} {# JSON-only clients (Cursor, Claude Desktop) carry the config file in the body itself — without showing the destination path the reader has no way to know where to paste it. CLI clients embed the destination in the command (the CLI binary + ``--scope`` flag both encode it), so the compact variant can safely omit the label for them. #} {% if variant != 'compact' or panel.client.kind == 'json' %}

Config file: {{ panel.scope.config_file }}

{% endif %}
{% endfor %}