8000 Use lowercase host in resource URI template derivation. by eiriktsarpalis · Pull Request #530 · modelcontextprotocol/csharp-sdk · GitHub
[go: up one dir, main page]

Skip to content
8000

Use lowercase host in resource URI template derivation. #530

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

eiriktsarpalis
Copy link
Contributor

Makes the following changes:

  • When deriving a resource URI template, converts the host component to lowercase.
  • Defaults the mimetype to "application/octetstream".

This should mitigate some of the issues described in #516.


/// <summary>
/// Initializes a new instance of the <see cref="McpServerPrimitiveCollection{T}"/> class.
/// </summary>
public McpServerPrimitiveCollection()
{
_primitives = typeof(T) == typeof(McpServerResource)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stephentoub I did this to address uri lookups. Let me know if this approach passes your smell test.

///
/// We do this because non-templated resources are looked up directly from the resource dictionary
/// and we need to make sure equality is implemented correctly. Templated Uris are resolved using
/// linear traversal so there's no need for equality comparison to be fully accurate.
Copy link
Contributor
@stephentoub stephentoub Jun 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not understanding how this statement relates to using this comparer with the ConcurrentDictionary in the collection, as that's not a linear search... ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It relates to this fallback, which is where any URI derived via template expansion is meant to be found:

// Fall back to an O(N) lookup, trying to match against each URI template.
// The number of templates is controlled by the server developer, and the number is expected to be
// not terribly large. If that changes, this can be tweaked to enable a more efficient lookup.
foreach (var resourceTemplate in resources)
{
if (await resourceTemplate.ReadAsync(request, cancellationToken).ConfigureAwait(false) is { } result)
{
return result;
}
}

}
else
{
return StringComparer.Ordinal.GetHashCode(uriTemplate);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this mean that two equal templates could end up with different hashcodes? I guess I'm not understanding the loose comparison rules being employed and why they're ok.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you mean uri://host/{Id} not being equal to uri://Host/{Id} it's something I've done deliberately to avoid getting lost in the weeds of defining URI template equality. I believe this is ok because

  1. Inbound resource requests ought to be non-templated URIs and should therefore always not be equal to templated keys and
  2. The downside of letting servers still declare duplicate templates up to case insensitivity is relatively minor and pre-existing.

…sure built-in resources work with the VS Code client.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MCP Resources without parameters don't work without mime-type specified
3 participants
0