Skip to content

UriTemplate.match() misparses {;var} when following literal begins with '=' #3852

Open

Description

@xgbtxy

Initial Checks

Release line

2.x (current stable)

Description

UriTemplate.match() breaks match(expand(variables)) == variables when a {;var} path-style parameter expression (ifemp = True, RFC 6570 §3.2.7) is immediately followed by a literal that begins with "=" (for example "{;a}=end{+rest}" or "/api{;mode}=fast{/id}").

In src/mcp/shared/uri_template.py (_scan_prefix), the atom.ifemp check runs:

if uri.startswith(nxt.text, pos):
    result[var.name] = ""
    continue
if pos < limit and uri[pos] == "=":
    pos += 1

Checking uri.startswith(nxt.text, pos) unconditionally before uri[pos] == "=" handles the empty-value case (a == "" -> ";a=end/x"), except when a equals the stem of nxt.text (a == "end" -> expand() emits ";a=end=end/x"). At pos right after ";a", uri[pos:] is "=end=end/x", which also starts with nxt.text ("=end"). _scan_prefix prematurely treats a as "" and leaves the second "=end" to be absorbed by a downstream greedy variable {+rest} (or fails suffix matching when no greedy variable follows).

Example Code

from mcp.shared.uri_template import UriTemplate

tpl = UriTemplate.parse("{;a}=end{+rest}")
variables = {"a": "end", "rest": "/x"}

expanded = tpl.expand(variables)
matched = tpl.match(expanded)

print("expanded:", expanded)  # ';a=end=end/x'
print("matched :", matched)   # {'a': '', 'rest': '=end/x'}  (expected {'a': 'end', 'rest': '/x'})
assert matched == variables

Python & MCP Python SDK

  • mcp: 2.3.0 (also verified on main 77001c96f9 in src/mcp/shared/uri_template.py)
  • Python: 3.12.0

Activity

  1. ZYZ666-RGB commented on Nov 13, 2026

    @ZYZ666-RGB

    I'd like to take this issue and ask to be assigned.

    UriTemplate.match() currently misparses {;var} when the following literal starts with =, because the empty-value check in _scan_prefix can treat that literal as an empty path-style value. I plan to fix that check in src/mcp/shared/uri_template.py and add tests so match(expand(variables)) == variables holds for this case (including examples like {;a}=end{+rest}).

    Please assign this issue to me. Once it is assigned, I will open a PR with Fixes #3852, as described in the contributing guide (external PRs are reviewed when assigned or labeled help wanted).

  2. added
    bugSomething isn't working
    v2Affects the v2 line (2.x on main)
    on Nov 13, 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

    bugSomething isn't workingv2Affects 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