Bug Report
Description
When a gateway's visibility is updated via PUT /gateways/{id}, the update_gateway method calls cache.invalidate_gateways() and tool_lookup_cache.invalidate_gateway(), but does not invalidate the tools, resources, or prompts list caches. In a multi-replica deployment (multiple gunicorn workers or gateway containers behind a load balancer), the /tools, /resources, and /prompts API endpoints serve stale visibility values until their TTL expires.
Reproduction
- Deploy with multiple gateway replicas behind nginx (e.g.
docker compose up)
- Update a gateway's visibility:
PUT /gateways/{id} with {"visibility": "team"}
- Immediately query
GET /tools — tools still show old visibility
- Verify via direct DB query that the visibility IS correctly updated in the database
- Wait for cache TTL to expire (~20s for tools) — then the API reflects the correct value
Root Cause
In mcpgateway/services/gateway_service.py around line 2212-2216:
cache = _get_registry_cache()
await cache.invalidate_gateways() # Only invalidates gateway list cache
tool_lookup_cache = _get_tool_lookup_cache()
await tool_lookup_cache.invalidate_gateway(str(gateway.id)) # Only invalidates tool lookup cache
Missing calls to invalidate:
cache.invalidate_tools()
cache.invalidate_resources()
cache.invalidate_prompts()
Impact
- After a visibility change, API consumers see stale visibility for up to
tools_ttl (20s), resources_ttl (15s), or prompts_ttl (15s)
- In security-sensitive scenarios (e.g. downgrading from
public to team), tools remain visible to unauthorized callers during the cache window
Discovered During
E2E testing of PR #3476
Bug Report
Description
When a gateway's visibility is updated via
PUT /gateways/{id}, theupdate_gatewaymethod callscache.invalidate_gateways()andtool_lookup_cache.invalidate_gateway(), but does not invalidate the tools, resources, or prompts list caches. In a multi-replica deployment (multiple gunicorn workers or gateway containers behind a load balancer), the/tools,/resources, and/promptsAPI endpoints serve stale visibility values until their TTL expires.Reproduction
docker compose up)PUT /gateways/{id}with{"visibility": "team"}GET /tools— tools still show old visibilityRoot Cause
In
mcpgateway/services/gateway_service.pyaround line 2212-2216:Missing calls to invalidate:
cache.invalidate_tools()cache.invalidate_resources()cache.invalidate_prompts()Impact
tools_ttl(20s),resources_ttl(15s), orprompts_ttl(15s)publictoteam), tools remain visible to unauthorized callers during the cache windowDiscovered During
E2E testing of PR #3476