Skip to content

[Bug] ResourceTemplate.matches() does not escape regex special chars in URI template literals #2961

Closed as duplicate

Description

@Robin1987China

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).

Activity

  1. tarunag10 commented on Jun 25, 2026

    @tarunag10

    Thanks for filing this. This appears to be covered by existing open PR #2749, which updates ResourceTemplate.matches() in the same file to escape literal template segments before converting {param} placeholders to named capture groups.

    That PR adds regression coverage for literal . and + cases, and because the implementation applies re.escape() to all non-placeholder text, it should also address examples here such as {id}?format=json and {name}++suffix being treated as regex syntax.

    Current status from the PR: CI is green and the PR is blocked on maintainer review, not on failing tests.

  2. Robin1987China commented on Jun 25, 2026

    @Robin1987China
    Author

    Closing as duplicate of #2749. Thanks @tarunag10 for pointing this out.

    If the #2749 implementation needs additional test coverage (parentheses, question marks, asterisks, full special char regression), the tests from my local implementation are available as reference.

    AI assistance disclosure: Bug discovered and fix drafted with AI assistance (opencode).

  3. added
    v2Affects the v2 line (2.x on main)
    on Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    v2Affects the v2 line (2.x on main)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions