You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug] ResourceManager.add_template() ignores warn_on_duplicate_resources and silently overwrites existing templates #3813
In mcp.server.mcpserver.resources.resource_manager.ResourceManager, the add_resource() method properly respects self.warn_on_duplicate_resources (configured via MCPServer(warn_on_duplicate_resources=True), which is True by default): when a duplicate URI is added, it logs a warning (Resource already exists: ...) and preserves the existing resource handler (return existing).
However, add_template() completely ignores warn_on_duplicate_resources:
It does not check self.warn_on_duplicate_resources.
It emits no log warning when an identical URI template is re-registered.
It silently overwrites the existing template in self._templates[template.uri_template] = template.
This creates divergent registration semantics between static resources and template resources registered via @server.resource(...), and leads to silent replacement of template handlers when multiple modules or extensions declare the same URI template.
Example Code
importloggingfrommcp.server.mcpserverimportMCPServerlogging.basicConfig(level=logging.WARNING)
server=MCPServer(warn_on_duplicate_resources=True)
# 1. Static resources: logs warning and preserves existing (doc1)@server.resource("file://doc")defdoc1() ->str:
return"v1"@server.resource("file://doc")defdoc2() ->str:
return"v2"# 2. Template resources: emits no warning and silently overwrites template1 with template2@server.resource("file://doc/{id}")deftemplate1(id: str) ->str:
return"template_v1"@server.resource("file://doc/{id}")deftemplate2(id: str) ->str:
return"template_v2"# Static resource warned and kept doc1:assertserver._resource_manager._resources["file://doc"].fn() =="v1"# Template resource silently overwritten without warning:assertserver._resource_manager._templates["file://doc/{id}"].name=="template2"
Expected output:
When template2 is registered for "file://doc/{id}", ResourceManager should emit: WARNING:mcp.server.mcpserver.resources.resource_manager:Template already exists: file://doc/{id}
and retain or handle the duplicate consistently with add_resource / add_tool / add_prompt.
Confirmed independently and prototyped a fix (not opening a PR — I understand unassigned-contributor PRs get auto-closed here, and this is @Tanmay9223's report to own).
Root cause (src/mcp/server/mcpserver/resources/resource_manager.py): add_template() builds the ResourceTemplate and then does self._templates[template.uri_template] = template unconditionally — there is no existing lookup at all, so warn_on_duplicate_resources is never consulted. add_resource() (same file) and add_tool()/add_prompt() (their managers) all do the lookup, warn, and return existing.
Tested branch, if useful to whoever lands this: fix/3813-duplicate-template-registration on Shanmukh-l33t/python-sdk (compare), commit 02456738 (+37/-0). Three regression tests mirroring the existing test_add_duplicate_resource / test_warn_on_duplicate_resources / test_disable_warn_on_duplicate_resources trio: duplicate registration keeps the first template (second is first), warns with the URI template when enabled, and stays silent but still non-overwriting when warn_on_duplicate_resources=False.
Evidence: the 3 new tests fail on main @ af4c6f4 (3 failed) and pass with the change (test file 14 passed); full suite 6228 passed / 8 skipped / 1 xfailed with one failure, test_file_resources.py::test_permission_error, which fails identically on pristine main in this environment (test runs as root); ruff check + ruff format --check clean; pyright clean on both touched files.
One design note: the duplicate check runs after ResourceTemplate.from_function(), so a re-registration with a malformed function still raises from from_function before the duplicate path — same failure surface as today; happy to move the lookup earlier if you'd prefer duplicates short-circuit before validation.
(AI disclosure: this analysis, patch and tests were drafted with AI assistance and reviewed by me.)
Activity
Shanmukh-l33t commentedon Nov 3, 2026
Confirmed independently and prototyped a fix (not opening a PR — I understand unassigned-contributor PRs get auto-closed here, and this is @Tanmay9223's report to own).
Root cause (
src/mcp/server/mcpserver/resources/resource_manager.py):add_template()builds theResourceTemplateand then doesself._templates[template.uri_template] = templateunconditionally — there is noexistinglookup at all, sowarn_on_duplicate_resourcesis never consulted.add_resource()(same file) andadd_tool()/add_prompt()(their managers) all do the lookup, warn, andreturn existing.Fix shape (mirror
add_resource()exactly):Tested branch, if useful to whoever lands this:
fix/3813-duplicate-template-registrationon Shanmukh-l33t/python-sdk (compare), commit02456738(+37/-0). Three regression tests mirroring the existingtest_add_duplicate_resource/test_warn_on_duplicate_resources/test_disable_warn_on_duplicate_resourcestrio: duplicate registration keeps the first template (second is first), warns with the URI template when enabled, and stays silent but still non-overwriting whenwarn_on_duplicate_resources=False.Evidence: the 3 new tests fail on
main@ af4c6f4 (3 failed) and pass with the change (test file 14 passed); full suite 6228 passed / 8 skipped / 1 xfailed with one failure,test_file_resources.py::test_permission_error, which fails identically on pristinemainin this environment (test runs as root);ruff check+ruff format --checkclean;pyrightclean on both touched files.One design note: the duplicate check runs after
ResourceTemplate.from_function(), so a re-registration with a malformed function still raises fromfrom_functionbefore the duplicate path — same failure surface as today; happy to move the lookup earlier if you'd prefer duplicates short-circuit before validation.(AI disclosure: this analysis, patch and tests were drafted with AI assistance and reviewed by me.)