MCP Resource URI Validator

Paste an MCP resource URI or a uriTemplate, then add name=value lines to see it expanded. The expansion follows RFC 6570 and is checked against the specification's own example table, including the four rows where an empty value differs from a missing one.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Expand. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

A glob, not a template

The asterisk is a literal asterisk, so this addresses exactly one resource whose name contains one

file:///logs/*.log

Reserved expansion

{+var} deliberately does not escape slashes, which is what lets a value contribute path structure and what lets it traverse

file:///project/{+path}/{name}.log
path=logs/2026
name=app

Two slashes in a file URI

file://etc/hosts parses etc as a HOST; the empty authority in file:/// is what makes the rest a path

file://etc/hosts

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Writing a glob where a URI template belongs

    `uriTemplate` is RFC 6570, not a shell pattern. An asterisk outside an expression is a literal asterisk, so the template addresses one resource whose name contains one and matches nothing else.

    Instead:Use a named variable: `file:///logs/{name}.log`.

  2. Reaching for `{+var}` to make a path work

    Reserved expansion leaves slashes unescaped, which is the point and also the hole: a value of `../../etc/passwd` expands to exactly that, and the URI addresses something other than the template implies.

    Instead:Use plain `{var}` unless the variable genuinely needs to contribute path structure, and validate the value server-side when it does.

  3. Assuming a missing variable produces an error

    An undefined variable expands to nothing at all. `file:///{dir}/{name}` with no `dir` still produces a syntactically valid URI, pointing somewhere you did not intend.

    Instead:Supply every variable, and have the server reject a read whose URI is missing a component rather than resolving it.

RFC 6570 is not a glob, and the operator decides what gets escaped

An MCP resource template is a URI Template, a specification with four levels and eight operators. Most people use one of them. The other seven change the expansion in ways that are easy to get wrong and impossible to notice.

An asterisk is a literal asterisk

file:///logs/*.log is not a pattern. It is a template with no variables that addresses exactly one resource whose name contains an asterisk. The template language uses named expressions: file:///logs/{name}.log. This is the mistake that makes a resource template match nothing and produce no error.

{+var} does not escape slashes, and that is the point

Plain {var} percent-encodes everything outside the unreserved set, so a value containing a slash becomes %2F and stays inside one path segment. Reserved expansion with {+var} leaves the slash alone so the variable can contribute path structure. It also means a value of ../../etc/passwd expands into exactly that, so a template using + is a place to validate the value on the server rather than trusting the template to contain it.

An undefined variable expands to nothing

Not to an error, and not to an empty placeholder. It simply disappears, so file:///{dir}/{name} with no dir becomes file:///​/name, which usually still parses. That is how a template produces a perfectly valid URI addressing the wrong resource.

An empty value is not an undefined one

Under the path-parameter operator an empty value emits the bare name: {;x,empty} gives ;x=1&empty. Under the query operators it emits the name with an equals sign: {?x,empty} gives ?x=1&empty=. Implementations that treat the two the same pass most tests and fail these, which is why both forms are checked here against the specification's own example table.

file:// needs three slashes

file://etc/hosts parses etc as a host, not as a path. The empty authority in file:///etc/hosts is what makes everything after it a path. Two slashes is a URI that is valid and refers to something else entirely.

A custom scheme is allowed and often right

Resource URIs do not have to be http or file. repo://owner/name/blob, db://schema/table and note://id are all legitimate, and a scheme of your own is clearer than pretending a database row is a file. What is not allowed is no scheme: a resource URI is absolute, and there is no base to resolve a relative one against.

What this cannot see

Whether the resource exists, whether the server can read it, and whether the variable values you supply are ones the server would accept. It parses and expands the template in your browser and requests nothing. The expansion follows the specification, which is not a guarantee that a given client's expander agrees: level 4 support in particular is uneven, so a template using prefix modifiers may expand differently elsewhere.