From c1c22925da095a5de9844bd636f9237e4a8646c4 Mon Sep 17 00:00:00 2001 From: Jim Clark Date: Mon, 25 Aug 2025 12:00:36 -0700 Subject: [PATCH] relax requirements on resource URIs (#365) remove checks for URI scheme; nothing in the spec requires one # Background When adding resource templates, we are currently doing checks for schemes on absolute uris. It is still common for MCP servers to use custom uris that would not pass these checks. For example, if the official GitHub MCP server were to use this sdk, it would show failures like: ``` "repo://{owner}/{repo}/contents{/path*}": parse "repo://{owner}/{repo}/contents{/path*}": invalid character "{" in host name "repo://{owner}/{repo}/refs/heads/{branch}/contents{/path*}": parse "repo://{owner}/{repo}/refs/heads/{branch}/contents{/path*}": invalid character "{" in host name "repo://{owner}/{repo}/sha/{sha}/contents{/path*}": parse "repo://{owner}/{repo}/sha/{sha}/contents{/path*}": invalid character "{" in host name invalid resource template uri "repo://{owner}/{repo}/refs/pull/{prNumber}/head/contents{/path*}": parse "repo://{owner}/{repo}/refs/pull/{prNumber}/head/contents{/path*}": invalid character "{" in host name "repo://{owner}/{repo}/refs/tags/{tag}/contents{/path*}": parse "repo://{owner}/{repo}/refs/tags/{tag}/contents{/path*}": invalid character "{" in host name ``` The wikipedia MCP would also show problems with missing schemes. ``` "/search/{query}": "/article/{title}": "/summary/{title}": "/summary/{title}/query/{query}/length/{max_length}": "/summary/{title}/section/{section_title}/length/{max_length}": "/sections/{title}": "/links/{title}": "/facts/{title}/topic/{topic_within_article}/count/{count}": "/coordinates/{title}": ``` --- mcp/server.go | 14 +------------- mcp/server_test.go | 2 -- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/mcp/server.go b/mcp/server.go index 5020823..c144033 100644 --- a/mcp/server.go +++ b/mcp/server.go @@ -345,13 +345,9 @@ func (s *Server) RemoveTools(names ...string) { func (s *Server) AddResource(r *Resource, h ResourceHandler) { s.changeAndNotify(notificationResourceListChanged, &ResourceListChangedParams{}, func() bool { - u, err := url.Parse(r.URI) - if err != nil { + if _, err := url.Parse(r.URI); err != nil { panic(err) // url.Parse includes the URI in the error } - if !u.IsAbs() { - panic(fmt.Errorf("URI %s needs a scheme", r.URI)) - } s.resources.add(&serverResource{r, h}) return true }) @@ -374,14 +370,6 @@ func (s *Server) AddResourceTemplate(t *ResourceTemplate, h ResourceHandler) { if err != nil { panic(fmt.Errorf("URI template %q is invalid: %w", t.URITemplate, err)) } - // Ensure the URI template has a valid scheme - u, err := url.Parse(t.URITemplate) - if err != nil { - panic(err) // url.Parse includes the URI in the error - } - if !u.IsAbs() { - panic(fmt.Errorf("URI template %q needs a scheme", t.URITemplate)) - } s.resourceTemplates.add(&serverResourceTemplate{t, h}) return true }) diff --git a/mcp/server_test.go b/mcp/server_test.go index cb1c05d..7db4073 100644 --- a/mcp/server_test.go +++ b/mcp/server_test.go @@ -381,8 +381,6 @@ func TestServerAddResourceTemplate(t *testing.T) { }{ {"ValidFileTemplate", "file:///{a}/{b}", false}, {"ValidCustomScheme", "myproto:///{a}", false}, - {"MissingScheme1", "://example.com/{path}", true}, - {"MissingScheme2", "/api/v1/users/{id}", true}, {"EmptyVariable", "file:///{}/{b}", true}, {"UnclosedVariable", "file:///{a", true}, }