{
  "schema_version": 2,
  "id": "develop/ai/context-engine/context-gateway/manage-gateways",
  "title": "Manage Gateways and Upstreams",
  "url": "https://redis.io/docs/latest/develop/ai/context-engine/context-gateway/manage-gateways/",
  "summary": "Create and change Gateways, register MCP servers with their credentials, set tool policies, and remove Upstreams.",
  "tags": [
    "docs",
    "develop",
    "ai"
  ],
  "last_updated": "2026-11-02T17:45:57-08:00",
  "page_type": "content",
  "content_hash": "a925a9a73033a2cd6211d33a53e9c08be77502eed588a034c4b98a11f9daf718",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "Create a Gateway, connect Model Context Protocol (MCP) servers, and configure how agents discover tools and receive results.\n\nThis guide covers administration on a self-managed deployment using the Iris command-line interface (CLI). For Redis Cloud, see [Create a Gateway](https://redis.io/docs/latest/operate/iris/context-gateway/create-gateway) and [Manage a Gateway](https://redis.io/docs/latest/operate/iris/context-gateway/manage-gateway).\n\nTo generate tools for records stored in Redis, see [Manage Context Surfaces](https://redis.io/docs/latest/develop/ai/context-engine/context-gateway/manage-context-surfaces)."
    },
    {
      "id": "before-you-begin",
      "title": "Before you begin",
      "role": "content",
      "text": "You need:\n\n- A running Context Gateway deployment.\n- Its administration URL and admin token.\n- Python 3.11 or later.\n- An MCP server that the Gateway can reach over Streamable HTTP.\n\nAdministrative requests configure the Gateway. Agents use a separate credential to discover and call tools through its MCP endpoint.\n\n[code example]\n\nInstall the unified Python SDK and CLI:\n\n[code example]\n\nSet the administration connection values:\n\n[code example]\n\nUse the administration base URL, including its scheme and host. The CLI adds the application programming interface (API) path.\n\nThe admin token manages every Gateway in the deployment. Keep it out of agent and application configuration. See [Authentication and authorization](https://redis.io/docs/latest/operate/iris/context-gateway/self-managed/authentication)."
    },
    {
      "id": "use-the-http-api",
      "title": "Use the HTTP API",
      "role": "content",
      "text": "You can perform the same tasks through the Control Plane API. The HTTP examples use Bash, cURL, and jq. Define this helper in your shell:\n\n[code example]\n\nAPI values are case-sensitive. Use `FULL` or `SEARCH`, and `ENABLED` or `DISABLED`, in JSON. CLI options accept the lowercase forms shown in this guide. For Python and TypeScript SDK choices, see [Choose a client](https://redis.io/docs/latest/develop/ai/context-engine/context-gateway/mcp#choose-a-client)."
    },
    {
      "id": "create-a-gateway",
      "title": "Create a Gateway",
      "role": "content",
      "text": "Create a Gateway named Support in search mode. Start with caching and compression disabled so you can connect and verify its tools before configuring result handling.\n\n**CLI:**\n\n[code example]\n\nCopy the returned Gateway ID:\n\n[code example]\n\nThe `--no-key` option creates the Gateway without minting an agent key.\n\n**HTTP:**\n\n[code example]\n\n\n\nSave the returned `mcpEndpoint` for agent connections. Gateway IDs begin with `gw_`, and Upstream IDs begin with `up_`. Copy returned IDs rather than constructing them."
    },
    {
      "id": "database-and-feature-defaults",
      "title": "Database and feature defaults",
      "role": "content",
      "text": "A Gateway database stores cached results and handles. You can select one during creation with `--database-id` in the CLI or `databaseId` in the API.\n\n| Creation setting | Behavior |\n| --- | --- |\n| No database specified | Uses the deployment’s default Gateway database, if configured. |\n| No explicit or default database available | Caching and compression are disabled. |\n| Database available and feature settings omitted | Caching and compression default to enabled, subject to compression capability checks. |\n| Features explicitly disabled | They remain disabled, as in this example. |\n\nFor HTTP creation requests, an empty or `null` `databaseId` returns `400`. Responses expose the resolved database through `databaseBinding`, including its name when available.\n\nSee [Default databases](https://redis.io/docs/latest/operate/iris/context-gateway/self-managed/configuration#default-databases) for deployment configuration."
    },
    {
      "id": "register-an-mcp-server",
      "title": "Connect an MCP server",
      "role": "content",
      "text": "Register the server as an Upstream. Its endpoint must be reachable from the Gateway and permitted by the deployment’s outbound policy.\n\nThis example connects a server that accepts a bearer token:\n\n[code example]\n\n**CLI:**\n\n[code example]\n\nCopy the returned Upstream ID for recovery if deletion later stops partway:\n\n[code example]\n\n**HTTP:**\n\n[code example]\n\n\n\nRemove the token from your shell when finished:\n\n[code example]\n\nCredentials are write-only: inspecting an Upstream does not return their values. Do not print or retain request files containing credentials.\n\n| Server authentication | CLI | HTTP configuration |\n| --- | --- | --- |\n| None | Omit authentication options | `\"authentication\": {\"methods\": []}` |\n| Bearer token | `--bearer-secret env:UPSTREAM_TOKEN` | `{\"bearer\": {\"value\": \"<upstream-key>\"}}` in `authentication.methods` |\n| Custom header | `--header X-Api-Key --header-secret env:UPSTREAM_TOKEN` | `{\"header\": {\"name\": \"X-Api-Key\", \"value\": \"<upstream-key>\"}}` in `authentication.methods` |\n\nThe namespace distinguishes this source’s tools from other Upstreams. Namespaces have at most 32 characters. A tool named `get_ticket` in the `support` namespace is exposed as `support__get_ticket`. Use names returned by discovery rather than recreating naming rules."
    },
    {
      "id": "inspect-the-tool-catalog",
      "title": "Verify the available tools",
      "role": "content",
      "text": "Inspect the Upstream and its catalog:\n\n**CLI:**\n\n[code example]\n\n**HTTP:**\n\n[code example]\n\n\n\nConfirm that the catalog contains the tools you expect from the server.\n\nRegistration can succeed even when initial tool discovery fails. If the response includes `initialCatalogFailure`, correct the reported connection, authentication, or discovery problem, then [refresh the catalog](#refresh-or-disable-an-upstream):\n\n[code example]\n\nInspect the catalog again before connecting an agent. A catalog listing confirms discovery. To verify execution, mint an agent key for this Gateway. Get the Identity Service administration URL and token from your administrator, then run:\n\n[code example]\n\nThe file contains the agent connection values. Keep it out of source control. See [Gateway authorization and grants](https://redis.io/docs/latest/operate/iris/context-gateway/self-managed/authentication#gateway-authorization-and-grants) for access requirements.\n\nLoad the connection values and discover tools on the search-mode Gateway created in this guide:\n\n[code example]\n\nChoose a tool you intend to execute, inspect its input schema, and save matching arguments as a JSON object in `tool-input.json`. Call it by the name returned by discovery:\n\n[code example]\n\nCheck that the result is successful and matches the source. For a separate walkthrough with prepared clinic data, see the [quickstart](https://redis.io/docs/latest/develop/ai/context-engine/context-gateway/quickstart)."
    },
    {
      "id": "list-and-inspect-gateways-and-upstreams",
      "title": "Find existing Gateways and Upstreams",
      "role": "content",
      "text": "| Task | Command |\n| --- | --- |\n| List Gateways | `iris context-gateway service list` |\n| Inspect the selected Gateway | `iris context-gateway service show \"$IRIS_CONTEXT_GATEWAY_ID\"` |\n| List its Upstreams | `iris context-gateway upstream list` |\n| Inspect an Upstream | `iris context-gateway upstream show support` |\n\nAn Upstream argument can be its namespace or returned ID.\n\nPlace `--json` immediately after `iris` when saving or processing output:\n\n[code example]"
    },
    {
      "id": "list-resources-through-http",
      "title": "List resources through HTTP",
      "role": "content",
      "text": "HTTP list operations return a page containing `items` and an optional `nextCursor`:\n\n[code example]\n\nPass the returned cursor unchanged and URL-encoded to retrieve another page:\n\n[code example]\n\nUse `/gateways/$IRIS_CONTEXT_GATEWAY_ID/upstreams` to list an Upstream page."
    },
    {
      "id": "change-a-gateway",
      "title": "Change a Gateway",
      "role": "content",
      "text": "Update a Gateway’s name or discovery mode:\n\n[code example]\n\nUse `--tool-exposure-mode full` to expose all tool definitions directly. See [Tool exposure modes](https://redis.io/docs/latest/develop/ai/context-engine/context-gateway/concepts#tool-exposure-modes).\n\nClients receive the updated tool list when they next request it. Clients that cache definitions may need to refresh their local list."
    },
    {
      "id": "handle-concurrent-changes",
      "title": "Handle concurrent changes",
      "role": "content",
      "text": "The CLI reads the current revision before changing or deleting a resource. If another administrator changes it first, the operation can fail with a revision conflict.\n\nInspect the resource again and reconcile your intended change before repeating the command.\n\nFor HTTP updates, read the resource and send its current revision as `expectedRevision`:\n\n[code example]\n\nTreat revisions as opaque values, not counters. A stale revision returns `412` with problem type `/errors/revision-conflict`."
    },
    {
      "id": "turn-the-cache-and-compression-on-or-off",
      "title": "Configure caching and compression",
      "role": "configuration",
      "text": "Both features require a Gateway database and must be enabled in the deployment and on the Gateway.\n\nCaching additionally requires a policy for each tool whose results you want to cache. Compression applies to eligible large results while enabled, unless a tool policy changes that behavior."
    },
    {
      "id": "enable-the-gateway-features",
      "title": "Enable the Gateway features",
      "role": "content",
      "text": "Get the registered Gateway database ID from your administrator:\n\n[code example]\n\n**CLI:**\n\n[code example]\n\n**HTTP:**\n\n[code example]\n\n\n\nThe Gateway database stores cached results and handles. It is separate from a Context Surface’s source database.\n\n| Change | What to configure | Result |\n| --- | --- | --- |\n| Add a database | Select the database and explicitly enable the features you want | Adding a database alone preserves existing feature settings. |\n| Disable caching | `--cache disabled` | Cached entries remain subject to their time to live (TTL). |\n| Disable compression | `--compression disabled` | Handle tools disappear from discovery. Stored handles remain subject to expiry. |\n| Detach the database | Clear the binding and disable both features in the same update | The Gateway no longer uses that database for caching or compression. |\n\nTo detach the database:\n\n[code example]\n\nFor HTTP updates, send `databaseId: null`, `cache: \"DISABLED\"`, and `compression: \"DISABLED\"` with `expectedRevision`."
    },
    {
      "id": "compression-database-requirements",
      "title": "Compression database requirements",
      "role": "content",
      "text": "Compression requires a reachable database with Redis JSON support and `maxmemory-policy noeviction`.\n\n| Situation | Behavior |\n| --- | --- |\n| You explicitly enable compression with an unsuitable database | The request fails with `400`. An entry in `errors[]` has a `pointer` identifying `/compression`. |\n| The database cannot be reached during an explicit enablement check | The request fails with `503`. |\n| Gateway creation leaves compression unspecified and the capability check fails | The Gateway is created with compression disabled. |\n\nSee [Cache and compression](https://redis.io/docs/latest/operate/iris/context-gateway/self-managed/configuration#cache-and-compression) for deployment settings and memory limits."
    },
    {
      "id": "set-tool-policies",
      "title": "Set tool policies",
      "role": "content",
      "text": "Policies configure one tool within one Upstream. Use the tool’s exact original name from the Upstream catalog, such as `get_ticket`, rather than its exposed name `support__get_ticket`.\n\n| Policy | CLI option | API field | Effect |\n| --- | --- | --- | --- |\n| Cache lifetime | `--cache-ttl` | `cache.ttlSeconds` | Reuse eligible results for 1 to 86400 seconds (24 hours). |\n| Handle lifetime | `--compression-ttl` | `compression.ttlSeconds` | Retain captured results for 1 to 86400 seconds (24 hours). |\n| Disable capture | `--compression-capture never` | `compression.capture: \"NEVER\"` | Ordinary calls return results inline. Explicit handle requests return a tool error. |\n\nA tool’s compression policy can specify a lifetime or disable capture, but cannot do both. Its cache policy is independent."
    },
    {
      "id": "cache-a-tools-results",
      "title": "Cache a tool’s results",
      "role": "content",
      "text": "List tools eligible for caching:\n\n[code example]\n\nA tool declaring `readOnlyHint: false` or `destructiveHint: true` is not cacheable.\n\nEnable caching on the Gateway, then set a policy:\n\n[code example]\n\nChoose a lifetime that reflects how quickly the source data changes. All callers with access to the Gateway share its cache entries.\n\nNew or changed cache policies return `400` while Gateway caching is disabled. Existing unchanged policies can remain stored."
    },
    {
      "id": "customize-compression",
      "title": "Customize compression",
      "role": "content",
      "text": "Set a five-minute handle lifetime:\n\n[code example]\n\nAlternatively, prevent capture for the tool:\n\n[code example]\n\nInspect the policies:\n\n[code example]\n\nRemove only the setting you want to clear. To remove the cache policy:\n\n[code example]\n\nTo remove the compression override instead:\n\n[code example]\n\nRemoving a compression override restores the Gateway’s default behavior for that tool."
    },
    {
      "id": "preserve-other-policies-in-http-updates",
      "title": "Preserve other policies in HTTP updates",
      "role": "content",
      "text": "The CLI preserves unrelated policies when updating a tool. With HTTP, preserve the existing policy map and the selected tool’s other settings yourself.\n\nFor example, this request changes only a tool’s cache lifetime:\n\n[code example]\n\nIf you change an Upstream’s endpoint, inspect the response’s `droppedToolPolicies`. Policies incompatible with the new catalog can be removed."
    },
    {
      "id": "refresh-or-disable-an-upstream",
      "title": "Refresh or disable an Upstream",
      "role": "content",
      "text": "Refresh after adding, removing, or changing tools on the MCP server:\n\n**CLI:**\n\n[code example]\n\n**HTTP:**\n\n[code example]\n\n\n\nA refresh publishes a new catalog revision. Cached results associated with the previous revision are no longer served."
    },
    {
      "id": "enable-or-disable-an-upstream",
      "title": "Disable or enable the tools",
      "role": "content",
      "text": "Temporarily remove the Upstream’s tools from discovery:\n\n**CLI:**\n\n[code example]\n\nRestore them with:\n\n[code example]\n\n**HTTP:**\n\n[code example]\n\nTo restore the tools, read the current revision again and send `enabled: true`.\n\n\n\nDisabling preserves the registration."
    },
    {
      "id": "rotate-an-upstream-credential",
      "title": "Update an Upstream’s credentials",
      "role": "content",
      "text": "When the source’s bearer token changes, update the registered credential:\n\n[code example]\n\n**CLI:**\n\n[code example]\n\nThe CLI preserves authentication methods that the command does not change.\n\n**HTTP:**\n\nFor the bearer-only server registered in this guide, send the replacement authentication configuration at the current revision:\n\n[code example]\n\nKeep request files containing credentials private and remove them after use.\n\n\n\n[code example]\n\nIf a credential is managed and rotated directly in an external secrets backend, refresh the catalog after rotation so previously cached results stop being served."
    },
    {
      "id": "delete-an-upstream-or-a-gateway",
      "title": "Delete an Upstream or Gateway",
      "role": "content",
      "text": "Remove all Upstreams before deleting their Gateway. The CLI has no `--cascade` flag.\n\n**CLI:**\n\nDelete the Upstream when you no longer want the Gateway to expose its tools:\n\n[code example]\n\nThe command asks for confirmation. If deletion stops partway, repeat it using the saved Upstream ID. A partially deleted Upstream may no longer appear in listings.\n\nAfter removing all Upstreams, preview the Gateway deletion:\n\n[code example]\n\nThen delete it:\n\n[code example]\n\n**HTTP:**\n\nRead each resource’s latest revision and pass it URL-encoded as `expectedRevision`. Delete the Upstream first:\n\n[code example]\n\nAfter removing all Upstreams, delete the Gateway:\n\n[code example]\n\n\n\nA delete marks the Upstream before cleanup. If cleanup stops, repeat deletion by ID to finish. See [Retry uncertain operations](https://redis.io/docs/latest/develop/ai/context-engine/context-gateway/limits#retry-uncertain-operations) for recovery when a read reports a partially deleted Upstream as not found.\n\nRevoke agent keys that are no longer needed. See [Rotate credentials](https://redis.io/docs/latest/operate/iris/context-gateway/self-managed/operations#rotate-credentials)."
    },
    {
      "id": "related-guides",
      "title": "Related guides",
      "role": "related",
      "text": "- [Manage Context Surfaces](https://redis.io/docs/latest/develop/ai/context-engine/context-gateway/manage-context-surfaces): Generate tools for querying Redis data.\n- [Integrate with an agent](https://redis.io/docs/latest/develop/ai/context-engine/context-gateway/agent-integration): Connect an agent framework.\n- [Control Plane API Reference](https://redis.io/docs/latest/operate/iris/context-gateway/self-managed/control-plane-api-reference): Look up request and response schemas.\n- [Limits and errors](https://redis.io/docs/latest/develop/ai/context-engine/context-gateway/limits): Diagnose failures and recover from conflicts."
    }
  ],
  "examples": [
    {
      "id": "before-you-begin-ex0",
      "language": "mermaid {background=\"transparent\"}",
      "code": "---\nconfig:\n  look: neo\n---\nflowchart LR\n    Admin[\"Administrator\"] -->|\"Admin token\"| Config[\"Gateway configuration\"]\n    Agent[\"Agent\"] -->|\"Agent credential\"| Gateway[\"Gateway MCP endpoint\"]\n    Config -.->|\"Configures\"| Gateway\n    Gateway -->|\"Upstream credential\"| Server[\"Connected MCP server\"]",
      "section_id": "before-you-begin"
    },
    {
      "id": "before-you-begin-ex1",
      "language": "bash",
      "code": "pip install redis-iris",
      "section_id": "before-you-begin"
    },
    {
      "id": "before-you-begin-ex2",
      "language": "bash",
      "code": "export IRIS_CONTEXT_GATEWAY_SERVICE_URL='<administration-url>'\nexport IRIS_CONTEXT_GATEWAY_SERVICE_TOKEN='<admin-token>'",
      "section_id": "before-you-begin"
    },
    {
      "id": "use-the-http-api-ex0",
      "language": "bash",
      "code": "export GATEWAY_API=\"$IRIS_CONTEXT_GATEWAY_SERVICE_URL/iris/v1/context-gateway\"\numask 077\n\ngateway_api() {\n  local method=\"$1\" path=\"$2\"\n  shift 2\n  curl --fail-with-body --silent --show-error \\\n    -X \"$method\" \"$GATEWAY_API$path\" \\\n    -H \"Authorization: Bearer $IRIS_CONTEXT_GATEWAY_SERVICE_TOKEN\" \\\n    -H 'Content-Type: application/json' \"$@\"\n}",
      "section_id": "use-the-http-api"
    },
    {
      "id": "create-a-gateway-ex0",
      "language": "bash",
      "code": "iris context-gateway service create \\\n  --name Support \\\n  --tool-exposure-mode search \\\n  --cache disabled \\\n  --compression disabled \\\n  --no-key",
      "section_id": "create-a-gateway"
    },
    {
      "id": "create-a-gateway-ex1",
      "language": "bash",
      "code": "export IRIS_CONTEXT_GATEWAY_ID='<gateway-id>'",
      "section_id": "create-a-gateway"
    },
    {
      "id": "create-a-gateway-ex2",
      "language": "bash",
      "code": "gateway_api POST /gateways \\\n  --data '{\n    \"name\": \"Support\",\n    \"toolExposureMode\": \"SEARCH\",\n    \"cache\": \"DISABLED\",\n    \"compression\": \"DISABLED\"\n  }' > gateway.json\n\nexport IRIS_CONTEXT_GATEWAY_ID=\"$(jq -er '.gatewayId' gateway.json)\"\njq '{gatewayId, mcpEndpoint, revision}' gateway.json",
      "section_id": "create-a-gateway"
    },
    {
      "id": "register-an-mcp-server-ex0",
      "language": "bash",
      "code": "export UPSTREAM_URL='<upstream-mcp-url>'\nexport UPSTREAM_TOKEN='<upstream-bearer-token>'",
      "section_id": "register-an-mcp-server"
    },
    {
      "id": "register-an-mcp-server-ex1",
      "language": "bash",
      "code": "iris context-gateway upstream add \\\n  --name 'Support tools' \\\n  --namespace support \\\n  --endpoint \"$UPSTREAM_URL\" \\\n  --bearer-secret env:UPSTREAM_TOKEN",
      "section_id": "register-an-mcp-server"
    },
    {
      "id": "register-an-mcp-server-ex2",
      "language": "bash",
      "code": "export UPSTREAM_ID='<upstream-id>'",
      "section_id": "register-an-mcp-server"
    },
    {
      "id": "register-an-mcp-server-ex3",
      "language": "bash",
      "code": "jq -n \\\n  --arg endpoint \"$UPSTREAM_URL\" \\\n  --arg token \"$UPSTREAM_TOKEN\" '{\n    name: \"Support tools\",\n    namespace: \"support\",\n    kind: \"MCP\",\n    mcp: {\n      endpoint: $endpoint,\n      transport: \"streamable-http\",\n      authentication: {methods: [{bearer: {value: $token}}]}\n    }\n  }' > upstream-create.json\n\ngateway_api POST \"/gateways/$IRIS_CONTEXT_GATEWAY_ID/upstreams\" \\\n  --data-binary @upstream-create.json > upstream.json\n\nrm upstream-create.json\nexport UPSTREAM_ID=\"$(jq -er '.upstreamId' upstream.json)\"\njq '{upstreamId, revision, initialCatalogFailure}' upstream.json",
      "section_id": "register-an-mcp-server"
    },
    {
      "id": "register-an-mcp-server-ex4",
      "language": "bash",
      "code": "unset UPSTREAM_TOKEN",
      "section_id": "register-an-mcp-server"
    },
    {
      "id": "inspect-the-tool-catalog-ex0",
      "language": "bash",
      "code": "iris context-gateway upstream show support\niris context-gateway upstream tools support",
      "section_id": "inspect-the-tool-catalog"
    },
    {
      "id": "inspect-the-tool-catalog-ex1",
      "language": "bash",
      "code": "gateway_api GET \"/gateways/$IRIS_CONTEXT_GATEWAY_ID/upstreams/$UPSTREAM_ID\" > upstream.json\ngateway_api GET \"/gateways/$IRIS_CONTEXT_GATEWAY_ID/upstreams/$UPSTREAM_ID/tools\" > tools.json\njq . tools.json",
      "section_id": "inspect-the-tool-catalog"
    },
    {
      "id": "inspect-the-tool-catalog-ex2",
      "language": "bash",
      "code": "iris context-gateway upstream refresh support",
      "section_id": "inspect-the-tool-catalog"
    },
    {
      "id": "inspect-the-tool-catalog-ex3",
      "language": "bash",
      "code": "export IRIS_IDENTITY_URL='<identity-service-url>'\nexport IRIS_IDENTITY_TOKEN='<identity-service-admin-token>'\niris context-gateway service key \"$IRIS_CONTEXT_GATEWAY_ID\" --write .env.gateway",
      "section_id": "inspect-the-tool-catalog"
    },
    {
      "id": "inspect-the-tool-catalog-ex4",
      "language": "bash",
      "code": "set -a\nsource .env.gateway\nset +a\niris --json context-gateway tools search '*'",
      "section_id": "inspect-the-tool-catalog"
    },
    {
      "id": "inspect-the-tool-catalog-ex5",
      "language": "bash",
      "code": "iris --json context-gateway tools call '<discovered-tool-name>' --input tool-input.json",
      "section_id": "inspect-the-tool-catalog"
    },
    {
      "id": "list-and-inspect-gateways-and-upstreams-ex0",
      "language": "bash",
      "code": "iris --json context-gateway upstream list",
      "section_id": "list-and-inspect-gateways-and-upstreams"
    },
    {
      "id": "list-resources-through-http-ex0",
      "language": "bash",
      "code": "gateway_api GET '/gateways?limit=50' > gateways.json\njq '.items[] | {gatewayId, name}' gateways.json",
      "section_id": "list-resources-through-http"
    },
    {
      "id": "list-resources-through-http-ex1",
      "language": "bash",
      "code": "cursor=\"$(jq -r '.nextCursor // empty' gateways.json)\"\nif [ -n \"$cursor\" ]; then\n  gateway_api GET /gateways --get \\\n    --data-urlencode 'limit=50' \\\n    --data-urlencode \"cursor=$cursor\" > gateways-next.json\nfi",
      "section_id": "list-resources-through-http"
    },
    {
      "id": "change-a-gateway-ex0",
      "language": "bash",
      "code": "iris context-gateway service update \"$IRIS_CONTEXT_GATEWAY_ID\" \\\n  --name 'Customer support' \\\n  --tool-exposure-mode search",
      "section_id": "change-a-gateway"
    },
    {
      "id": "handle-concurrent-changes-ex0",
      "language": "bash",
      "code": "gateway_api GET \"/gateways/$IRIS_CONTEXT_GATEWAY_ID\" > gateway.json\njq '{expectedRevision: .revision, toolExposureMode: \"SEARCH\"}' gateway.json > update.json\ngateway_api PATCH \"/gateways/$IRIS_CONTEXT_GATEWAY_ID\" \\\n  --data-binary @update.json > gateway.json",
      "section_id": "handle-concurrent-changes"
    },
    {
      "id": "enable-the-gateway-features-ex0",
      "language": "bash",
      "code": "export GATEWAY_DATABASE_ID='<gateway-database-id>'",
      "section_id": "enable-the-gateway-features"
    },
    {
      "id": "enable-the-gateway-features-ex1",
      "language": "bash",
      "code": "iris context-gateway service update \"$IRIS_CONTEXT_GATEWAY_ID\" \\\n  --database-id \"$GATEWAY_DATABASE_ID\" \\\n  --cache enabled \\\n  --compression enabled",
      "section_id": "enable-the-gateway-features"
    },
    {
      "id": "enable-the-gateway-features-ex2",
      "language": "bash",
      "code": "gateway_api GET \"/gateways/$IRIS_CONTEXT_GATEWAY_ID\" > gateway.json\njq --arg database \"$GATEWAY_DATABASE_ID\" \\\n  '{expectedRevision: .revision, databaseId: $database, cache: \"ENABLED\", compression: \"ENABLED\"}' \\\n  gateway.json > update.json\ngateway_api PATCH \"/gateways/$IRIS_CONTEXT_GATEWAY_ID\" --data-binary @update.json > gateway.json",
      "section_id": "enable-the-gateway-features"
    },
    {
      "id": "enable-the-gateway-features-ex3",
      "language": "bash",
      "code": "iris context-gateway service update \"$IRIS_CONTEXT_GATEWAY_ID\" \\\n  --clear-database \\\n  --cache disabled \\\n  --compression disabled",
      "section_id": "enable-the-gateway-features"
    },
    {
      "id": "cache-a-tools-results-ex0",
      "language": "bash",
      "code": "iris context-gateway upstream tools support --cacheable-only",
      "section_id": "cache-a-tools-results"
    },
    {
      "id": "cache-a-tools-results-ex1",
      "language": "bash",
      "code": "iris context-gateway policy set support '<original-tool-name>' --cache-ttl 60s",
      "section_id": "cache-a-tools-results"
    },
    {
      "id": "customize-compression-ex0",
      "language": "bash",
      "code": "iris context-gateway policy set support '<original-tool-name>' --compression-ttl 5m",
      "section_id": "customize-compression"
    },
    {
      "id": "customize-compression-ex1",
      "language": "bash",
      "code": "iris context-gateway policy set support '<original-tool-name>' --compression-capture never",
      "section_id": "customize-compression"
    },
    {
      "id": "customize-compression-ex2",
      "language": "bash",
      "code": "iris context-gateway policy list support",
      "section_id": "customize-compression"
    },
    {
      "id": "customize-compression-ex3",
      "language": "bash",
      "code": "iris context-gateway policy clear support '<original-tool-name>' --cache",
      "section_id": "customize-compression"
    },
    {
      "id": "customize-compression-ex4",
      "language": "bash",
      "code": "iris context-gateway policy clear support '<original-tool-name>' --compression",
      "section_id": "customize-compression"
    },
    {
      "id": "preserve-other-policies-in-http-updates-ex0",
      "language": "bash",
      "code": "export ORIGINAL_TOOL_NAME='<original-tool-name>'\ngateway_api GET \"/gateways/$IRIS_CONTEXT_GATEWAY_ID/upstreams/$UPSTREAM_ID\" > upstream.json\n\njq --arg tool \"$ORIGINAL_TOOL_NAME\" '\n  (.toolPolicies // {}) as $policies |\n  {\n    expectedRevision: .revision,\n    toolPolicies: (\n      $policies + {\n        ($tool): (\n          ($policies[$tool] // {}) + {\n            cache: (($policies[$tool].cache // {}) + {ttlSeconds: 60})\n          }\n        )\n      }\n    )\n  }\n' upstream.json > update.json\n\ngateway_api PATCH \"/gateways/$IRIS_CONTEXT_GATEWAY_ID/upstreams/$UPSTREAM_ID\" \\\n  --data-binary @update.json > upstream.json",
      "section_id": "preserve-other-policies-in-http-updates"
    },
    {
      "id": "refresh-or-disable-an-upstream-ex0",
      "language": "bash",
      "code": "iris context-gateway upstream refresh support",
      "section_id": "refresh-or-disable-an-upstream"
    },
    {
      "id": "refresh-or-disable-an-upstream-ex1",
      "language": "bash",
      "code": "gateway_api POST \"/gateways/$IRIS_CONTEXT_GATEWAY_ID/upstreams/$UPSTREAM_ID/refresh\" > upstream.json",
      "section_id": "refresh-or-disable-an-upstream"
    },
    {
      "id": "enable-or-disable-an-upstream-ex0",
      "language": "bash",
      "code": "iris context-gateway upstream disable support",
      "section_id": "enable-or-disable-an-upstream"
    },
    {
      "id": "enable-or-disable-an-upstream-ex1",
      "language": "bash",
      "code": "iris context-gateway upstream enable support",
      "section_id": "enable-or-disable-an-upstream"
    },
    {
      "id": "enable-or-disable-an-upstream-ex2",
      "language": "bash",
      "code": "gateway_api GET \"/gateways/$IRIS_CONTEXT_GATEWAY_ID/upstreams/$UPSTREAM_ID\" > upstream.json\njq '{expectedRevision: .revision, enabled: false}' upstream.json > update.json\ngateway_api PATCH \"/gateways/$IRIS_CONTEXT_GATEWAY_ID/upstreams/$UPSTREAM_ID\" \\\n  --data-binary @update.json > upstream.json",
      "section_id": "enable-or-disable-an-upstream"
    },
    {
      "id": "rotate-an-upstream-credential-ex0",
      "language": "bash",
      "code": "export UPSTREAM_TOKEN='<replacement-upstream-token>'",
      "section_id": "rotate-an-upstream-credential"
    },
    {
      "id": "rotate-an-upstream-credential-ex1",
      "language": "bash",
      "code": "iris context-gateway upstream update support --bearer-secret env:UPSTREAM_TOKEN",
      "section_id": "rotate-an-upstream-credential"
    },
    {
      "id": "rotate-an-upstream-credential-ex2",
      "language": "bash",
      "code": "gateway_api GET \"/gateways/$IRIS_CONTEXT_GATEWAY_ID/upstreams/$UPSTREAM_ID\" > upstream.json\njq --arg token \"$UPSTREAM_TOKEN\" '{\n  expectedRevision: .revision,\n  mcp: {authentication: {methods: [{bearer: {value: $token}}]}}\n}' upstream.json > credential-update.json\ngateway_api PATCH \"/gateways/$IRIS_CONTEXT_GATEWAY_ID/upstreams/$UPSTREAM_ID\" \\\n  --data-binary @credential-update.json > upstream.json\nrm credential-update.json",
      "section_id": "rotate-an-upstream-credential"
    },
    {
      "id": "rotate-an-upstream-credential-ex3",
      "language": "bash",
      "code": "unset UPSTREAM_TOKEN",
      "section_id": "rotate-an-upstream-credential"
    },
    {
      "id": "delete-an-upstream-or-a-gateway-ex0",
      "language": "bash",
      "code": "iris context-gateway upstream delete support",
      "section_id": "delete-an-upstream-or-a-gateway"
    },
    {
      "id": "delete-an-upstream-or-a-gateway-ex1",
      "language": "bash",
      "code": "iris context-gateway service delete \"$IRIS_CONTEXT_GATEWAY_ID\" --dry-run",
      "section_id": "delete-an-upstream-or-a-gateway"
    },
    {
      "id": "delete-an-upstream-or-a-gateway-ex2",
      "language": "bash",
      "code": "iris context-gateway service delete \"$IRIS_CONTEXT_GATEWAY_ID\"",
      "section_id": "delete-an-upstream-or-a-gateway"
    },
    {
      "id": "delete-an-upstream-or-a-gateway-ex3",
      "language": "bash",
      "code": "gateway_api GET \"/gateways/$IRIS_CONTEXT_GATEWAY_ID/upstreams/$UPSTREAM_ID\" > upstream.json\nrevision=\"$(jq -er '.revision | @uri' upstream.json)\"\ngateway_api DELETE \"/gateways/$IRIS_CONTEXT_GATEWAY_ID/upstreams/$UPSTREAM_ID?expectedRevision=$revision\"",
      "section_id": "delete-an-upstream-or-a-gateway"
    },
    {
      "id": "delete-an-upstream-or-a-gateway-ex4",
      "language": "bash",
      "code": "gateway_api GET \"/gateways/$IRIS_CONTEXT_GATEWAY_ID\" > gateway.json\nrevision=\"$(jq -er '.revision | @uri' gateway.json)\"\ngateway_api DELETE \"/gateways/$IRIS_CONTEXT_GATEWAY_ID?expectedRevision=$revision\"",
      "section_id": "delete-an-upstream-or-a-gateway"
    }
  ]
}
