> ## Documentation Index
> Fetch the complete documentation index at: https://docs.domesystems.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Gateways

> Group tools and models behind Gateways, grant agent access, and configure scoped runtime endpoints

export const gateway = "A Gateway is a named access surface that lists which tools and models an agent may reach and exposes one stable URL for that set. Dome checks membership and access grants before Rules run on each call.";

<p>
  {gateway}
</p>

## Overview

A Gateway carries two related controls:

* **Resource membership** makes a tool, pool, or model addressable through the Gateway's runtime endpoint.
* **Agent access** admits the agent at the edge and generates rules that permit all current and future resource members.

Other workspace and custom rules still apply. Those rules can deny a resource member after the agent passes Gateway admission.

The typical workflow is:

1. [Create a Gateway](#create-gateway) or reuse the [Default gateway](#default-gateway).
2. [Add the resource as a member](#manage-resource-memberships).
3. [Grant the agent access](#manage-agent-access) to the Gateway.
4. Point the client at the [Gateway's endpoint](#build-the-runtime-endpoint).
5. [Verify reachability](#verify-reachability) with that agent's API key.

### Resource membership

Membership determines which resources a Gateway exposes:

| Kind            | What it exposes                                                   |
| --------------- | ----------------------------------------------------------------- |
| Individual tool | One selected tool from a connection                               |
| Tool source     | Every tool on an MCP connection, including tools discovered later |
| Pool            | A pool behind its stable name                                     |
| Direct model    | One model connection by name                                      |

A resource with no Gateway membership stays valid. The resource shows as **Unreachable** because no runtime endpoint addresses it. Removing a membership leaves the underlying resource intact. Gateway membership is available in Rules through `resource.gateways.contains("<id>")`. Refer to the [Rules reference](/reference/controls/rules#resource-attributes).

You can change what a Gateway exposes when you [add or remove members](#manage-resource-memberships).

### Agent access

A **per-agent** grant adds the Gateway to that agent's allowed resources (`agent.register` and `rules.deploy`). A **workspace-wide** grant covers every current and future agent in the workspace (`rules.deploy` and `gateway.manage`). `gateway.manage` alone cannot grant runtime access. Revoking a workspace-wide grant leaves per-agent grants in place.

Without either grant, invocation fails at edge admission (`access.denied` / `permission_denied` with `DENY_DETAIL_CODE_GATEWAY_ADMISSION`). Discovery such as `tools/list` and `GET /v1/models` is exempt from admission and stays membership- and Cedar-filtered. With a grant, other rules can still deny individual resource members. Generated permit rules are shown read-only in the dashboard.

You can change who reaches a Gateway when you [grant or revoke access](#manage-agent-access).

### Default gateway

Every new workspace starts with an active **Default** Gateway that has no resource memberships or agent grants. Migrated workspaces may already have resources attached, but callers still need an explicit per-agent or all-agents grant.

The default marker only pre-selects a Gateway in dashboard dialogs that create tools, pools, and models. The marker adds no resources, grants no access, and overrides no rules.

Free and Pro workspaces support one Gateway, and the auto-created Default counts toward that limit. Team, Enterprise, and self-managed workspaces support additional Gateways. Exceeding the plan cap returns HTTP `429` / `RESOURCE_EXHAUSTED`.

You can move the marker when you [set the Default gateway](#set-default-gateway).

### Runtime endpoints

Each Gateway has its own path under the workspace gateway host. Callers select a Gateway in the request URL. The base URL depends on the client protocol. A disabled Gateway rejects requests but keeps its memberships and grants.

Refer to [Build the runtime endpoint](#build-the-runtime-endpoint) for client-specific URL paths.

### Cost quotas

A Gateway cost quota caps aggregate LLM spend for member pools and direct model connections. Exceeding the cap blocks further LLM calls through that Gateway until the active window resets. Filter audit by `producer_gateway_id`. Metrics dashboards do not break down by Gateway.

You can cap spend when you [set a cost quota](#set-a-cost-quota). Window and scope semantics are on the [Quotas](/reference/controls/quotas) reference.

## Requirements

Before you begin:

* Authenticate to Dome and select a workspace
* Collect the resource and agent identifiers the operation needs
* Have an active agent key with access to the selected Gateway when you verify runtime reachability

### Permissions

Gateway membership, grants, and related operations require platform permissions. Each operation states its required permission inline.

| Default roles                    | Permission       | Grants                                             |
| -------------------------------- | ---------------- | -------------------------------------------------- |
| All workspace roles              | `gateway.view`   | List Gateways and inspect membership               |
| `admin`, `operator`              | `gateway.manage` | Create, update, and delete Gateways and membership |
| All workspace roles              | `agent.view`     | List agents when managing grants                   |
| `admin`, `operator`, `developer` | `agent.register` | Per-agent Gateway grants (with `rules.deploy`)     |
| `admin`, `operator`, `security`  | `rules.deploy`   | Required for Gateway access-grant changes          |

## Create Gateway

Create a separate Gateway when callers need a resource set or endpoint boundary that the Default gateway should not share. A new Gateway starts active with empty membership and no grants.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway create prod-resources --description "Production tools and models"
    ```

    <Callout icon="terminal">Reference: [`dome gateway create`](/cli/connect/gateway#create)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_create`

    ```json theme={"system"}
    {
      "name": "prod-resources",
      "description": "Production tools and models"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_create`](/reference/mcp/gateway#dome_gateway_create)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/CreateGateway
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "name": "prod-resources",
      "description": "Production tools and models"
    }
    ```

    <Callout icon="code">Reference: [`CreateGateway`](/api/gateway/create-gateway)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Create a Gateway" theme={"system"}
    Create a Gateway named "prod-resources" for production tools and models.
    ```
  </Tab>
</Tabs>

<Info>
  Free and Pro workspaces support only one Gateway. Reuse, rename, or delete the Default gateway before creating another one.
</Info>

After creation, [retrieve the Gateway](#get-gateway) to confirm its ID, active state, empty membership, and grant settings.

## Update Gateway

Update a Gateway to change its name or description.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway update prod-resources --description "Production tools, pools, and models"
    ```

    Omitted values remain unchanged.

    <Callout icon="terminal">Reference: [`dome gateway update`](/cli/connect/gateway#update)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_update`

    ```json theme={"system"}
    {
      "name": "prod-resources",
      "new_name": "production-resources",
      "description": "Production tools, pools, and models"
    }
    ```

    Omitted values remain unchanged.

    <Callout icon="cpu">Reference: [`dome_gateway_update`](/reference/mcp/gateway#dome_gateway_update)</Callout>
  </Tab>

  <Tab title="API">
    An empty `name` keeps the current name. The API always writes `description`, so include the current description when it must remain unchanged.

    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/UpdateGateway
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "gateway_id": "{{GATEWAY_ID}}",
      "name": "production-resources",
      "description": "Production tools, pools, and models"
    }
    ```

    <Callout icon="code">Reference: [`UpdateGateway`](/api/gateway/update-gateway)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Update a Gateway" theme={"system"}
    Rename "prod-resources" to "production-resources" and update its description to "Production tools, pools, and models".
    ```
  </Tab>
</Tabs>

After the update, [retrieve the Gateway](#get-gateway) to confirm its name and description.

## Get Gateway

Retrieve one Gateway to inspect its state, default marker, workspace-wide grant, and resource memberships.

<Callout icon="key">Requires `gateway.view`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway get prod-resources
    ```

    <Callout icon="terminal">Reference: [`dome gateway get`](/cli/connect/gateway#get)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_get`

    ```json theme={"system"}
    {
      "name": "prod-resources"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_get`](/reference/mcp/gateway#dome_gateway_get)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/GetGateway
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "gateway_id": "{{GATEWAY_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`GetGateway`](/api/gateway/get-gateway)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Get a Gateway" theme={"system"}
    Get "prod-resources" and show its state, grants, and resource memberships.
    ```
  </Tab>
</Tabs>

## List Gateways

List Gateways to retrieve their names, IDs, states, default markers, and canonical endpoint paths.

<Callout icon="key">Requires `gateway.view`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway list
    ```

    <Callout icon="terminal">Reference: [`dome gateway list`](/cli/connect/gateway#list)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_list`

    ```json theme={"system"}
    {}
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_list`](/reference/mcp/gateway#dome_gateway_list)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/ListGateways
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`ListGateways`](/api/gateway/list-gateways)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="List Gateways" theme={"system"}
    List the Gateways in the active workspace with their IDs, states, and endpoint paths.
    ```
  </Tab>
</Tabs>

## Set Default gateway

Set a Gateway as the workspace default to pre-select it in dashboard dialogs that create tools, pools, and models. Setting a new default clears the previous marker. A disabled default is not pre-selected.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway set-default prod-resources
    ```

    <Callout icon="terminal">Reference: [`dome gateway set-default`](/cli/connect/gateway#set-default)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_set_default`

    ```json theme={"system"}
    {
      "name": "prod-resources"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_set_default`](/reference/mcp/gateway#dome_gateway_set_default)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/SetGatewayDefault
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "gateway_id": "{{GATEWAY_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`SetGatewayDefault`](/api/gateway/set-gateway-default)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Set the default Gateway" theme={"system"}
    Set "prod-resources" as the workspace's Default gateway.
    ```
  </Tab>
</Tabs>

After setting the default, [retrieve the Gateway](#get-gateway) and confirm that it is marked as the workspace default.

## Manage lifecycle

Manage a Gateway's availability without changing resource memberships or agent grants. Delete a Gateway only when callers no longer need that endpoint.

### Enable Gateway

Enable a disabled Gateway to restore its endpoint. Disabling a Gateway preserves existing memberships and grants.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway enable prod-resources
    ```

    <Callout icon="terminal">Reference: [`dome gateway enable`](/cli/connect/gateway#enable)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_set_state`

    ```json theme={"system"}
    {
      "name": "prod-resources",
      "state": "active"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_set_state`](/reference/mcp/gateway#dome_gateway_set_state)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/SetGatewayState
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "gateway_id": "{{GATEWAY_ID}}",
      "state": "active"
    }
    ```

    <Callout icon="code">Reference: [`SetGatewayState`](/api/gateway/set-gateway-state)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Enable a Gateway" theme={"system"}
    Enable the "prod-resources" Gateway.
    ```
  </Tab>
</Tabs>

### Disable Gateway

Disable a Gateway to block its endpoint without removing memberships or grants. Requests stay rejected until you enable the Gateway again.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway disable prod-resources
    ```

    <Callout icon="terminal">Reference: [`dome gateway disable`](/cli/connect/gateway#disable)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_set_state`

    ```json theme={"system"}
    {
      "name": "prod-resources",
      "state": "disabled"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_set_state`](/reference/mcp/gateway#dome_gateway_set_state)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/SetGatewayState
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "gateway_id": "{{GATEWAY_ID}}",
      "state": "disabled"
    }
    ```

    <Callout icon="code">Reference: [`SetGatewayState`](/api/gateway/set-gateway-state)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Disable a Gateway" theme={"system"}
    Disable "prod-resources" while preserving its memberships and grants.
    ```
  </Tab>
</Tabs>

After enabling or disabling a Gateway, [retrieve the Gateway](#get-gateway) to confirm the resulting state.

### Delete Gateway

Delete a Gateway only after moving callers to another endpoint. Deletion removes the Gateway and its resource memberships. The `/gateways/{{GATEWAY_ID}}/...` endpoint starts rejecting requests. Deletion does not remove the underlying tools, connections, pools, or models.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Warning>
  Deletion is permanent. Per-agent grants for the deleted ID no longer admit callers. Callers must use another Gateway ID.
</Warning>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway delete prod-resources
    ```

    <Callout icon="terminal">Reference: [`dome gateway delete`](/cli/connect/gateway#delete)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_delete`

    ```json theme={"system"}
    {
      "name": "prod-resources"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_delete`](/reference/mcp/gateway#dome_gateway_delete)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/DeleteGateway
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "gateway_id": "{{GATEWAY_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`DeleteGateway`](/api/gateway/delete-gateway)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Delete a Gateway" theme={"system"}
    Delete "prod-resources" without deleting its underlying resources.
    ```
  </Tab>
</Tabs>

After deletion, [list the Gateways](#list-gateways) to confirm the deleted Gateway no longer appears.

## Manage resource memberships

Add or remove members so resources are addressable through a Gateway. Membership kinds are in [Overview](#resource-membership). Membership changes do not modify or delete the underlying resources.

### Individual tools

Add or remove one tool without exposing the rest of its connection.

##### Add individual tool

Add one tool without exposing the other tools from its connection.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway tools add prod-resources {{TOOL_ID}}
    ```

    <Callout icon="terminal">Reference: [`dome gateway tools add`](/cli/connect/gateway#tools-add)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_tool_add`

    ```json theme={"system"}
    {
      "gateway": "prod-resources",
      "connection": "notion",
      "tool": "create_page"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_tool_add`](/reference/mcp/gateway#dome_gateway_tool_add)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/AddGatewayTool
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "gateway_id": "{{GATEWAY_ID}}",
      "tool_id": "{{TOOL_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`AddGatewayTool`](/api/gateway/add-gateway-tool)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Add an individual tool" theme={"system"}
    Add the "create_page" tool from the "notion" connection to "prod-resources".
    ```
  </Tab>
</Tabs>

##### Remove individual tool

Remove an individual membership to stop exposing the tool on its own. The tool stays addressable when a tool-source membership also covers that tool.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway tools remove prod-resources {{TOOL_ID}}
    ```

    <Callout icon="terminal">Reference: [`dome gateway tools remove`](/cli/connect/gateway#tools-remove)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_tool_remove`

    ```json theme={"system"}
    {
      "gateway": "prod-resources",
      "connection": "notion",
      "tool": "create_page"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_tool_remove`](/reference/mcp/gateway#dome_gateway_tool_remove)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/RemoveGatewayTool
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "gateway_id": "{{GATEWAY_ID}}",
      "tool_id": "{{TOOL_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`RemoveGatewayTool`](/api/gateway/remove-gateway-tool)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Remove an individual tool" theme={"system"}
    Remove the "create_page" tool from "prod-resources" without deleting the tool.
    ```
  </Tab>
</Tabs>

### Tool source

Add or remove an entire MCP connection. Newly discovered tools on that connection join the Gateway automatically.

##### Add tool source

Add a tool source to include every tool currently on that connection.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway tool-sources add prod-resources notion
    ```

    <Callout icon="terminal">Reference: [`dome gateway tool-sources add`](/cli/connect/gateway#tool-sources-add)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_tool_source_add`

    ```json theme={"system"}
    {
      "gateway": "prod-resources",
      "connection": "notion"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_tool_source_add`](/reference/mcp/gateway#dome_gateway_tool_source_add)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/AddGatewayToolSource
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "gateway_id": "{{GATEWAY_ID}}",
      "connection_id": "{{CONNECTION_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`AddGatewayToolSource`](/api/gateway/add-gateway-tool-source)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Add a tool source" theme={"system"}
    Add the entire "notion" tool source to "prod-resources", including newly discovered tools.
    ```
  </Tab>
</Tabs>

##### Remove tool source

Remove a tool-source membership to stop automatically including tools from that connection. Individually added tools remain in the Gateway.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway tool-sources remove prod-resources notion
    ```

    <Callout icon="terminal">Reference: [`dome gateway tool-sources remove`](/cli/connect/gateway#tool-sources-remove)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_tool_source_remove`

    ```json theme={"system"}
    {
      "gateway": "prod-resources",
      "connection": "notion"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_tool_source_remove`](/reference/mcp/gateway#dome_gateway_tool_source_remove)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/RemoveGatewayToolSource
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "gateway_id": "{{GATEWAY_ID}}",
      "connection_id": "{{CONNECTION_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`RemoveGatewayToolSource`](/api/gateway/remove-gateway-tool-source)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Remove a tool source" theme={"system"}
    Remove the "notion" tool source from "prod-resources" without deleting the connection.
    ```
  </Tab>
</Tabs>

### Pool

Add or remove a pool so agents can call it by its stable name through the Gateway. Changes to the pool's members do not require a membership update.

##### Add pool

Add a pool to expose its routed models through the Gateway.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway model-pools add prod-resources production
    ```

    <Callout icon="terminal">Reference: [`dome gateway model-pools add`](/cli/connect/gateway#model-pools-add)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_model_pool_add`

    ```json theme={"system"}
    {
      "gateway": "prod-resources",
      "pool": "production"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_model_pool_add`](/reference/mcp/gateway#dome_gateway_model_pool_add)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/AddGatewayLLMPool
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "gateway_id": "{{GATEWAY_ID}}",
      "llm_pool_id": "{{POOL_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`AddGatewayLLMPool`](/api/gateway/add-gateway-llm-pool)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Add a model pool" theme={"system"}
    Add the "production" model pool to "prod-resources".
    ```
  </Tab>
</Tabs>

##### Remove pool

Remove a pool to stop exposing that pool through the Gateway. The pool and its members remain configured.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway model-pools remove prod-resources production
    ```

    <Callout icon="terminal">Reference: [`dome gateway model-pools remove`](/cli/connect/gateway#model-pools-remove)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_model_pool_remove`

    ```json theme={"system"}
    {
      "gateway": "prod-resources",
      "pool": "production"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_model_pool_remove`](/reference/mcp/gateway#dome_gateway_model_pool_remove)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/RemoveGatewayLLMPool
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "gateway_id": "{{GATEWAY_ID}}",
      "llm_pool_id": "{{POOL_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`RemoveGatewayLLMPool`](/api/gateway/remove-gateway-llm-pool)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Remove a model pool" theme={"system"}
    Remove the "production" model pool from "prod-resources" without deleting the pool.
    ```
  </Tab>
</Tabs>

### Direct model

Add or remove one model connection without routing through a pool.

##### Add direct model

Add a direct model connection to make that model name addressable through the Gateway.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway models add prod-resources claude-prod
    ```

    <Callout icon="terminal">Reference: [`dome gateway models add`](/cli/connect/gateway#models-add)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_model_add`

    ```json theme={"system"}
    {
      "gateway": "prod-resources",
      "model": "claude-prod"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_model_add`](/reference/mcp/gateway#dome_gateway_model_add)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/AddGatewayLLMModel
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "gateway_id": "{{GATEWAY_ID}}",
      "llm_model_connection_id": "{{MODEL_CONNECTION_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`AddGatewayLLMModel`](/api/gateway/add-gateway-llm-model)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Add a direct model" theme={"system"}
    Add "claude-prod" directly to "prod-resources".
    ```
  </Tab>
</Tabs>

##### Remove direct model

Remove a direct model connection to stop exposing it through the Gateway without deleting the connection.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway models remove prod-resources claude-prod
    ```

    <Callout icon="terminal">Reference: [`dome gateway models remove`](/cli/connect/gateway#models-remove)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_model_remove`

    ```json theme={"system"}
    {
      "gateway": "prod-resources",
      "model": "claude-prod"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_model_remove`](/reference/mcp/gateway#dome_gateway_model_remove)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/RemoveGatewayLLMModel
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "gateway_id": "{{GATEWAY_ID}}",
      "llm_model_connection_id": "{{MODEL_CONNECTION_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`RemoveGatewayLLMModel`](/api/gateway/remove-gateway-llm-model)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Remove a direct model" theme={"system"}
    Remove "claude-prod" from "prod-resources" without deleting the model connection.
    ```
  </Tab>
</Tabs>

After any membership change, [retrieve the Gateway](#get-gateway) to confirm its individual tool, tool source, model pool, and direct model memberships.

## Manage agent access

Grant or revoke who is admitted at the Gateway edge. Per-agent and workspace-wide grants are in [Overview](#agent-access). Other Rules can still deny individual members after admission.

### List agent access

List agents and show whether each agent has a per-agent grant to the Gateway. Revoked agents are excluded. Suspended agents remain listed so you can inspect their grants before reactivation.

<Callout icon="key">Requires `agent.view`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway access list prod-resources
    ```

    <Callout icon="terminal">Reference: [`dome gateway access list`](/cli/connect/gateway#access-list)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_access_list`

    ```json theme={"system"}
    {
      "gateway": "prod-resources"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_access_list`](/reference/mcp/gateway#dome_gateway_access_list)</Callout>
  </Tab>

  <Tab title="API">
    The API returns every agent in the workspace. Exclude revoked agents, then check whether each remaining agent's `allowed_gateway_ids` contains the target Gateway ID.

    ```http theme={"system"}
    POST /dome.agent.v1.AgentRegistry/ListAgents
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`ListAgents`](/api/agents/list-agents)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="List agent access" theme={"system"}
    List agents and show whether each one has a per-agent grant to "prod-resources".
    ```
  </Tab>
</Tabs>

### Grant one agent

Grant one agent access while preserving its existing Gateway grants. Dome generates and manages the permit rules. You cannot edit those rules directly.

<Callout icon="key">Requires `agent.register` and `rules.deploy`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway access grant prod-resources data-pipeline-agent
    ```

    <Callout icon="terminal">Reference: [`dome gateway access grant`](/cli/connect/gateway#access-grant)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_agent_grant`

    ```json theme={"system"}
    {
      "gateway": "prod-resources",
      "agent_id": "{{AGENT_ID}}"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_agent_grant`](/reference/mcp/gateway#dome_gateway_agent_grant)</Callout>
  </Tab>

  <Tab title="API">
    The `allowed_gateway_ids` field replaces the agent's full list. Include every existing Gateway ID that the agent should keep, plus the new ID.

    ```http theme={"system"}
    POST /dome.agent.v1.AgentRegistry/UpdateAgent
    Content-Type: application/json

    {
      "agent_id": "{{AGENT_ID}}",
      "workspace_id": "{{WORKSPACE_ID}}",
      "allowed_gateway_ids": [
        "{{EXISTING_GATEWAY_ID}}",
        "{{GATEWAY_ID}}"
      ],
      "update_mask": "allowed_gateway_ids"
    }
    ```

    <Callout icon="code">Reference: [`UpdateAgent`](/api/agents/update-agent)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Grant one agent" theme={"system"}
    Grant "data-pipeline-agent" access to "prod-resources" and preserve its existing Gateway grants.
    ```
  </Tab>
</Tabs>

### Revoke one agent

Revoke one agent's access to the Gateway while preserving its other Gateway grants. Requests from that agent to the Gateway endpoint fail at edge admission unless a workspace-wide grant also applies.

<Callout icon="key">Requires `agent.register` and `rules.deploy`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway access revoke prod-resources data-pipeline-agent
    ```

    <Callout icon="terminal">Reference: [`dome gateway access revoke`](/cli/connect/gateway#access-revoke)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_agent_revoke`

    ```json theme={"system"}
    {
      "gateway": "prod-resources",
      "agent_id": "{{AGENT_ID}}"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_agent_revoke`](/reference/mcp/gateway#dome_gateway_agent_revoke)</Callout>
  </Tab>

  <Tab title="API">
    The `allowed_gateway_ids` field replaces the agent's full list. Omit the revoked ID and preserve every other ID the agent should keep.

    ```http theme={"system"}
    POST /dome.agent.v1.AgentRegistry/UpdateAgent
    Content-Type: application/json

    {
      "agent_id": "{{AGENT_ID}}",
      "workspace_id": "{{WORKSPACE_ID}}",
      "allowed_gateway_ids": [
        "{{OTHER_GATEWAY_ID}}"
      ],
      "update_mask": "allowed_gateway_ids"
    }
    ```

    <Callout icon="code">Reference: [`UpdateAgent`](/api/agents/update-agent)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Revoke one agent" theme={"system"}
    Revoke "data-pipeline-agent" access to "prod-resources" and preserve its other Gateway grants.
    ```
  </Tab>
</Tabs>

### Grant every workspace agent

Grant every current and future workspace agent access when all agents need the same endpoint. Other rules can still deny individual resources after admission.

<Callout icon="key">Requires `gateway.manage` and `rules.deploy`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway access grant-all prod-resources
    ```

    <Callout icon="terminal">Reference: [`dome gateway access grant-all`](/cli/connect/gateway#access-grant-all)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_all_agents_grant`

    ```json theme={"system"}
    {
      "gateway": "prod-resources"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_all_agents_grant`](/reference/mcp/gateway#dome_gateway_all_agents_grant)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/SetGatewayAllAgentsGrant
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "gateway_id": "{{GATEWAY_ID}}",
      "granted": true
    }
    ```

    <Callout icon="code">Reference: [`SetGatewayAllAgentsGrant`](/api/gateway/set-gateway-all-agents-grant)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Grant every workspace agent" theme={"system"}
    Grant every current and future workspace agent access to "prod-resources".
    ```
  </Tab>
</Tabs>

### Revoke every workspace agent

Revoke the workspace-wide grant to stop automatically admitting every agent. Existing per-agent grants remain in place.

<Callout icon="key">Requires `gateway.manage` and `rules.deploy`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway access revoke-all prod-resources
    ```

    <Callout icon="terminal">Reference: [`dome gateway access revoke-all`](/cli/connect/gateway#access-revoke-all)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_all_agents_revoke`

    ```json theme={"system"}
    {
      "gateway": "prod-resources"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_all_agents_revoke`](/reference/mcp/gateway#dome_gateway_all_agents_revoke)</Callout>
  </Tab>

  <Tab title="API">
    ```http theme={"system"}
    POST /dome.gateway.v1.GatewayService/SetGatewayAllAgentsGrant
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "gateway_id": "{{GATEWAY_ID}}",
      "granted": false
    }
    ```

    <Callout icon="code">Reference: [`SetGatewayAllAgentsGrant`](/api/gateway/set-gateway-all-agents-grant)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Revoke every workspace agent" theme={"system"}
    Revoke the workspace-wide grant from "prod-resources" without changing per-agent grants.
    ```
  </Tab>
</Tabs>

After any access change, [list agent access](#list-agent-access) to confirm the resulting per-agent grants. For a workspace-wide grant, [retrieve the Gateway](#get-gateway) and check its workspace-wide grant setting.

## Manage cost quotas

Cap aggregate LLM spend for member pools and direct model connections on this Gateway. Refer to [Overview](#cost-quotas). Window and scope semantics are on the [Quotas](/reference/controls/quotas) reference.

### List cost quotas

List Gateway cost quotas in the workspace or filter the result to one Gateway.

<Callout icon="key">Requires `gateway.view`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway quota list prod-resources
    ```

    <Callout icon="terminal">Reference: [`dome gateway quota list`](/cli/connect/gateway#quota-list)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_quota_list`

    ```json theme={"system"}
    {
      "gateway": "prod-resources"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_quota_list`](/reference/mcp/gateway#dome_gateway_quota_list)</Callout>
  </Tab>

  <Tab title="API">
    The API returns every LLM quota in the workspace. Filter the response to records with `subject_type` equal to `gateway` and the desired `subject_id`.

    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/ListLLMQuotas
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`ListLLMQuotas`](/api/management/list-llm-quotas)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="List cost quotas" theme={"system"}
    List the cost quotas for the "prod-resources" Gateway.
    ```
  </Tab>
</Tabs>

### Set a cost quota

Set a daily or monthly USD spend cap for LLM calls through a Gateway. Once spend exceeds the cap, LLM calls addressed to that Gateway return HTTP `429`.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway quota set prod-resources --limit 500 --window monthly --name "prod-monthly"
    ```

    <Callout icon="terminal">Reference: [`dome gateway quota set`](/cli/connect/gateway#quota-set)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_quota_set`

    ```json theme={"system"}
    {
      "gateway": "prod-resources",
      "limit_usd": 500,
      "window": "monthly",
      "name": "prod-monthly"
    }
    ```

    <Callout icon="cpu">Reference: [`dome_gateway_quota_set`](/reference/mcp/gateway#dome_gateway_quota_set)</Callout>
  </Tab>

  <Tab title="API">
    The API expresses the limit in millionths of a US dollar. For example, `$500` is `500000000`.

    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/CreateLLMQuota
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "subject_type": "gateway",
      "subject_id": "{{GATEWAY_ID}}",
      "limit_micros": "500000000",
      "window": "monthly",
      "name": "prod-monthly",
      "enabled": true
    }
    ```

    <Callout icon="code">Reference: [`CreateLLMQuota`](/api/management/create-llm-quota)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Set a cost quota" theme={"system"}
    Create a monthly $500 cost quota named "prod-monthly" for "prod-resources".
    ```
  </Tab>
</Tabs>

### Remove a cost quota

Remove a Gateway cost quota to stop enforcing that cap.

<Callout icon="key">Requires `gateway.manage`.</Callout>

<Warning>
  Removing a quota takes away an active spending control. Confirm the quota ID with the list operation first.
</Warning>

<Tabs>
  <Tab title="CLI">
    ```bash theme={"system"}
    dome gateway quota rm {{QUOTA_ID}}
    ```

    The command rejects quota IDs that belong to another subject type.

    <Callout icon="terminal">Reference: [`dome gateway quota rm`](/cli/connect/gateway#quota-remove)</Callout>
  </Tab>

  <Tab title="MCP">
    Tool: `dome_gateway_quota_remove`

    ```json theme={"system"}
    {
      "quota_id": "{{QUOTA_ID}}"
    }
    ```

    The tool rejects quota IDs that belong to another subject type.

    <Callout icon="cpu">Reference: [`dome_gateway_quota_remove`](/reference/mcp/gateway#dome_gateway_quota_remove)</Callout>
  </Tab>

  <Tab title="API">
    Confirm that the quota has `subject_type: gateway` before deleting it. The generic API endpoint does not add the CLI and MCP subject-type guard.

    ```http theme={"system"}
    POST /dome.mgmt.v1.Management/DeleteLLMQuota
    Content-Type: application/json

    {
      "workspace_id": "{{WORKSPACE_ID}}",
      "quota_id": "{{QUOTA_ID}}"
    }
    ```

    <Callout icon="code">Reference: [`DeleteLLMQuota`](/api/management/delete-llm-quota)</Callout>
  </Tab>

  <Tab title="Agent">
    ```text title="Remove a cost quota" theme={"system"}
    Confirm that "{{QUOTA_ID}}" is a Gateway quota, then remove it.
    ```
  </Tab>
</Tabs>

After any quota change, [list cost quotas](#list-cost-quotas) to confirm the active caps and reset windows.

## Build the runtime endpoint

Build the runtime endpoint from the workspace gateway host and the Gateway ID. Retrieve the ID with [List Gateways](#list-gateways).

<Callout icon="key">Requires `gateway.view` to retrieve the ID. Runtime calls require an active agent key and a grant to the Gateway.</Callout>

Use the ID in the canonical prefix:

```text theme={"system"}
https://{{GATEWAY_HOST}}/gateways/{{GATEWAY_ID}}
```

Choose the base URL that matches the client.

| Client                | Base URL                                               | Client appends                        |
| --------------------- | ------------------------------------------------------ | ------------------------------------- |
| Dome SDK              | `https://{{GATEWAY_HOST}}/gateways/{{GATEWAY_ID}}`     | nothing, used as-is                   |
| Anthropic SDK         | `https://{{GATEWAY_HOST}}/gateways/{{GATEWAY_ID}}`     | `/v1/messages` (SDK-managed)          |
| OpenAI-compatible SDK | `https://{{GATEWAY_HOST}}/gateways/{{GATEWAY_ID}}/v1`  | `/chat/completions`, `/embeddings`, … |
| MCP client            | `https://{{GATEWAY_HOST}}/gateways/{{GATEWAY_ID}}/mcp` | protocol frames                       |

Do not add `/v1` to the Anthropic base URL because the Anthropic SDK appends `/v1/messages`. Bare `/mcp` and `/v1` requests return HTTP `400`. Every caller must select a Gateway in the URL.

Run `dome gateway get <name-or-id> --json` to retrieve the complete `gateway_url`, `mcp_url`, `openai_base_url`, and `anthropic_base_url`. SDK agent-key creation and token exchange return the same authoritative endpoint set. Refer to [Python SDK Gateways](/sdks/python/reference#gateways).

## Verify reachability

Verify discovery before invoking a tool or model. Discovery returns only members of the selected Gateway that the agent's grant and applicable rules permit.

<Callout icon="key">Requires an active agent key, access to the Gateway, and rules that allow discovery.</Callout>

List MCP tools through the scoped endpoint:

```bash theme={"system"}
curl -X POST "https://{{GATEWAY_HOST}}/gateways/{{GATEWAY_ID}}/mcp" \
  -H "Authorization: Bearer {{DOME_AGENT_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

List model pools and direct model connections through the OpenAI-compatible endpoint:

```bash theme={"system"}
curl "https://{{GATEWAY_HOST}}/gateways/{{GATEWAY_ID}}/v1/models" \
  -H "Authorization: Bearer {{DOME_AGENT_KEY}}"
```

Configure runtime credentials and SDK clients in [Develop](/develop).

## Troubleshoot reachability

Use the observed response to locate the failed layer.

| Symptom                                        | Likely cause                                                                         | Resolution                                                                          |
| ---------------------------------------------- | ------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
| HTTP `400` asks for a Gateway                  | The client used bare `/mcp` or `/v1`                                                 | Add `/gateways/{{GATEWAY_ID}}` before the protocol path                             |
| Gateway is unavailable                         | The ID is unknown, disabled, or not yet synchronized                                 | Verify the ID, enable the Gateway, and wait for gateway synchronization to complete |
| Invocation is denied before rules evaluate     | The agent lacks access to the Gateway                                                | Add a per-agent or workspace-wide grant                                             |
| Discovery returns no resources                 | The agent lacks access, the Gateway has no matching members, or rules deny discovery | Check agent access, membership, and rules                                           |
| Tool is missing from `tools/list`              | The tool lacks membership, is blocked, or rules deny discovery                       | Check individual and tool-source membership, tool status, and rules                 |
| Pool or model is missing from `/v1/models`     | The resource lacks membership or rules deny discovery                                | Check pool or direct-model membership and model rules                               |
| Resource shows **Unreachable**                 | The resource belongs to no Gateway                                                   | Add the resource or its containing tool source or pool                              |
| LLM call returns HTTP `429`                    | A Gateway or other LLM cost quota is exhausted                                       | List active quotas and check their reset windows                                    |
| Gateway creation is rejected at the plan limit | The workspace already has the maximum number of Gateways                             | Reuse, rename, or delete the Default gateway, or change plans                       |
| Anthropic request returns HTTP `404`           | The client base URL includes an extra `/v1`                                          | Use `https://{{GATEWAY_HOST}}/gateways/{{GATEWAY_ID}}`                              |

After changing memberships or grants, wait for gateway synchronization before testing again. If discovery succeeds but invocation fails, inspect the resource rules and the agent's lifecycle state.

## Next steps

* [Gateways](/concepts/gateways) concept for how membership and grants work
* [Register agents](/connect/agents) to create agent identities and keys
* [Tools](/connect/resources/tools) to configure tool connections and catalog state
* [Pools](/connect/resources/models/pools) to configure pools and routing
