Summary
The SDK's UriTemplate silently treats an RFC 6570 prefix modifier as part of the variable name. Supplying the actual variable therefore removes its value from the expanded resource URI.
For example, resource:///{name:3} with name = "abcdef" expands to resource:///, and variableNames reports ["name:3"] rather than ["name"].
Reproduction
Environment: Windows, Node.js 24.20.0, @modelcontextprotocol/client@2.3.1.
Install in an empty directory:
npm install @modelcontextprotocol/client@2.3.1
node repro.mjs
repro.mjs:
import { UriTemplate } from '@modelcontextprotocol/client';
for (const [template, variables] of [
['{name:3}', { name: 'abcdef' }],
['resource:///{name:3}', { name: 'abcdef' }],
['{name:2}', { name: '你好世界' }],
['{name}', { name: 'abcdef' }],
]) {
const uri = new UriTemplate(template);
console.log(JSON.stringify({
template, variableNames: uri.variableNames,
actual: uri.expand(variables),
}));
}
Observed:
{"template":"{name:3}","variableNames":["name:3"],"actual":""}
{"template":"resource:///{name:3}","variableNames":["name:3"],"actual":"resource:///"}
{"template":"{name:2}","variableNames":["name:2"],"actual":""}
{"template":"{name}","variableNames":["name"],"actual":"abcdef"}
I independently ran the same cases against the unmodified packages/core-internal/src/shared/uriTemplate.ts from main b022522089a0c8b632595c6e7b536453945ed5a9 with the same results. The reproduction exercises the real implementation, requires no service credentials, and makes no network requests after installation.
Expected behavior / scope question
RFC 6570 §2.4.1 defines :N as a modifier on a variable, rather than part of its name. If this syntax is supported, the corresponding scalar expansions should be abc, resource:///abc, and %E4%BD%A0%E5%A5%BD. The ordinary {name} control already works.
If prefix modifiers are intentionally outside the SDK's supported subset, explicit validation or documented rejection would be preferable to silently producing a different URI. I would appreciate maintainer guidance on the intended support level.
Cause and proposed scope
getNames() removes * but retains :N; expansion then looks up variables["name:3"].
I'd like to implement a focused fix and submit a PR if this direction is welcome. For support, I propose parsing a scalar's name and prefix length separately, applying the prefix to Unicode characters before percent-encoding, and adding regressions in packages/core-internal/test/shared/uriTemplate.test.ts. Coverage would include ASCII, non-ASCII and supplementary characters, a prefix longer than the value, missing variables, and the existing no-modifier control. Validating malformed modifiers and defining matching behavior should be agreed before implementation: a truncated URI cannot reconstruct the original full value.
This is separate from the existing explode-modifier work (#2892), multi-variable expansion work (#2994), and percent-decoding/matching work (#2810/#1079). I checked the full open-PR title list and issue searches for prefix modifiers before drafting this report.
Could a maintainer confirm the intended scope and assign this issue to jayfeng7 if appropriate? I will follow that direction and provide focused regression evidence before submitting a PR.
Prepared with Codex assistance for analysis and reproduction. No implementation PR or full SDK test-suite result is claimed here.
Summary
The SDK's
UriTemplatesilently treats an RFC 6570 prefix modifier as part of the variable name. Supplying the actual variable therefore removes its value from the expanded resource URI.For example,
resource:///{name:3}withname = "abcdef"expands toresource:///, andvariableNamesreports["name:3"]rather than["name"].Reproduction
Environment: Windows, Node.js 24.20.0,
@modelcontextprotocol/client@2.3.1.Install in an empty directory:
repro.mjs:Observed:
{"template":"{name:3}","variableNames":["name:3"],"actual":""} {"template":"resource:///{name:3}","variableNames":["name:3"],"actual":"resource:///"} {"template":"{name:2}","variableNames":["name:2"],"actual":""} {"template":"{name}","variableNames":["name"],"actual":"abcdef"}I independently ran the same cases against the unmodified
packages/core-internal/src/shared/uriTemplate.tsfrom mainb022522089a0c8b632595c6e7b536453945ed5a9with the same results. The reproduction exercises the real implementation, requires no service credentials, and makes no network requests after installation.Expected behavior / scope question
RFC 6570 §2.4.1 defines
:Nas a modifier on a variable, rather than part of its name. If this syntax is supported, the corresponding scalar expansions should beabc,resource:///abc, and%E4%BD%A0%E5%A5%BD. The ordinary{name}control already works.If prefix modifiers are intentionally outside the SDK's supported subset, explicit validation or documented rejection would be preferable to silently producing a different URI. I would appreciate maintainer guidance on the intended support level.
Cause and proposed scope
getNames()removes*but retains:N; expansion then looks upvariables["name:3"].I'd like to implement a focused fix and submit a PR if this direction is welcome. For support, I propose parsing a scalar's name and prefix length separately, applying the prefix to Unicode characters before percent-encoding, and adding regressions in
packages/core-internal/test/shared/uriTemplate.test.ts. Coverage would include ASCII, non-ASCII and supplementary characters, a prefix longer than the value, missing variables, and the existing no-modifier control. Validating malformed modifiers and defining matching behavior should be agreed before implementation: a truncated URI cannot reconstruct the original full value.This is separate from the existing explode-modifier work (#2892), multi-variable expansion work (#2994), and percent-decoding/matching work (#2810/#1079). I checked the full open-PR title list and issue searches for prefix modifiers before drafting this report.
Could a maintainer confirm the intended scope and assign this issue to
jayfeng7if appropriate? I will follow that direction and provide focused regression evidence before submitting a PR.Prepared with Codex assistance for analysis and reproduction. No implementation PR or full SDK test-suite result is claimed here.