Bug Description
ResourceTemplate.matches() in src/mcp/server/mcpserver/resources/templates.py:97 converts URI templates to regex patterns using simple string replacement, but does not escape regex-special characters in literal (non-parameter) parts of the template.
# L97
pattern = self.uri_template.replace("{", "(?P<").replace("}", ">[^/]+)")
Reproduction Cases
| Template literal char |
Regex side effect |
False match |
.well-known/{name} |
. = any char |
data://Xwell-known/hello incorrectly matches |
{id}.json |
. = any char |
data://items/123Xjson incorrectly matches |
{id}?format=json |
? = optional |
data://items/123format=json matches without ? |
{name}+suffix |
+ = one-or-more quantifier |
Semantic distortion |
{name}++suffix |
++ = possessive quantifier |
Behavior change |
Fix (proposed)
Use re.escape() on the template first, then replace escaped \{param\} with named capture groups:
import re as _re
_URI_PARAM_PATTERN = _re.compile(r"\\\{([^}]+)\\\}")
def _build_template_pattern(template: str) -> str:
escaped = _re.escape(template)
return _URI_PARAM_PATTERN.sub(lambda m: f"(?P<{m.group(1)}>[^/]+)", escaped)
AI Disclosure
Bug discovered with AI assistance (opencode).
Bug Description
ResourceTemplate.matches()insrc/mcp/server/mcpserver/resources/templates.py:97converts URI templates to regex patterns using simple string replacement, but does not escape regex-special characters in literal (non-parameter) parts of the template.Reproduction Cases
.well-known/{name}.= any chardata://Xwell-known/helloincorrectly matches{id}.json.= any chardata://items/123Xjsonincorrectly matches{id}?format=json?= optionaldata://items/123format=jsonmatches without?{name}+suffix+= one-or-more quantifier{name}++suffix++= possessive quantifierFix (proposed)
Use
re.escape()on the template first, then replace escaped\{param\}with named capture groups:AI Disclosure
Bug discovered with AI assistance (opencode).