Skip to content

[Bug]: Resource cache not invalidated when gateway deleted #1467

@gabe-l-hart

Description

@gabe-l-hart

🐞 Bug Summary

The resource_cache in main.py does not get invalidated for resources exposed by gateways when the gateway gets deleted leading to incorrect cache hits on subsequent manually-created resources with different values.


🧩 Affected Component

Select the area of the project impacted:

  • mcpgateway - API
  • mcpgateway - UI (admin panel)
  • mcpgateway.wrapper - stdio wrapper
  • Federation or Transports
  • CLI, Makefiles, or shell scripts
  • Container setup (Docker/Podman/Compose)
  • Other (explain below)

🔁 Steps to Reproduce

from mcp.server.fastmcp import FastMCP
import uvicorn
import requests
import threading
import time

mcp = FastMCP("dummy")

@mcp.resource("resource://hello")
def hello() -> str:
    return "Hi there"

# Boot the local MCP server
port = 8811
config = uvicorn.Config(mcp.sse_app(), host="localhost", port=port)
server = uvicorn.Server(config)
thread = threading.Thread(target=server.run, daemon=True)
thread.start()
time.sleep(1)

# Log into CF
print("--> LOGGING IN")
res = requests.post("http://localhost:4444/auth/login", json={"email": "admin@example.com", "password": "changeme"})
token = res.json()["access_token"]
headers = {"Authorization": f"Bearer {token}"}

# Register it with CF
print("--> REGISTERING MCP SERVER")
res = requests.post("http://localhost:4444/gateways", headers=headers, json={"name": "test-server", "url": "http://localhost:8811/sse"})
res.raise_for_status()
server_id = res.json()["id"]

# Verify the MCP-server's resource is visible
print("--> VERIFYING RESOURCES")
res = requests.get("http://localhost:4444/resources", headers=headers)
print(res.json())
resource_id = res.json()[0]["id"]

# Fetch the resource directly <-- this puts it in the cache
res = requests.get(f"http://localhost:4444/resources/{resource_id}", headers=headers)
print(res.json())

# Delete the MCP server
print("--> DELETING MCP SERVER")
res = requests.delete(f"http://localhost:4444/gateways/{server_id}", headers=headers)
time.sleep(0.5)

# Verify resource is gone
print("--> CHECKING FOR DELETED RESOURCE")
res = requests.get(f"http://localhost:4444/resources/{resource_id}", headers=headers)
print(res.text)

# Create a net-new resource
print("--> CREATING NEW RESOURCE")
res = requests.post("http://localhost:4444/resources", headers=headers, json={"resource": {"name": "test-resource", "uri": "resource://something-else", "content": "some stuff"}})
res.raise_for_status()
new_resource_id = res.json()["id"] # <-- This should conflict with the above!

# Fetch the new resource. It will have the old resource's values
print("--> FETCHING NEW RESOURCE")
res = requests.get(f"http://localhost:4444/resources/{new_resource_id}", headers=headers)
assert res.json()["uri"] == "resource://something-else" # <-- This will fail!!!!

🤔 Expected Behavior

When the gateway is deleted, the cache should be invalidated and subsequent lookups on the resource with the overlapping ID should not hit the cache.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtriageIssues / Features awaiting triage

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions