-
Notifications
You must be signed in to change notification settings - Fork 1.6k
SEP-2202: Allow Non-File URI Schemes for Roots #2202
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| --- | ||
| title: "SEP-2202: Allow Non-File URI Schemes for Roots" | ||
| sidebarTitle: "SEP-2202: Allow Non-File URI Schemes for Roots" | ||
| description: "Allow Non-File URI Schemes for Roots" | ||
| --- | ||
|
|
||
| <div className="flex items-center gap-2 mb-4"> | ||
| <Badge color="gray" shape="pill"> | ||
| Draft | ||
| </Badge> | ||
| <Badge color="gray" shape="pill"> | ||
| Standards Track | ||
| </Badge> | ||
| </div> | ||
|
|
||
| | Field | Value | | ||
| | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | **SEP** | 2202 | | ||
| | **Title** | Allow Non-File URI Schemes for Roots | | ||
| | **Status** | Draft | | ||
| | **Type** | Standards Track | | ||
| | **Created** | 2025-09-29 | | ||
| | **Author(s)** | Tapan Chugh ([@chughtapan](https://github.com/chughtapan)), Ola ([@olaservo](https://github.com/olaservo)); original proposal by [@noctonic](https://github.com/noctonic) in #507 | | ||
| | **Sponsor** | Ola ([@olaservo](https://github.com/olaservo)) | | ||
| | **PR** | [#2202](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2202) | | ||
|
|
||
| --- | ||
|
|
||
| ## Abstract | ||
|
|
||
| This SEP proposes removing the restriction that root URIs must begin with `file://`, allowing servers to work with remote resources through any URI scheme. Reference implementations in `python-sdk`, `typescript-sdk`, client (`fast-agent`) a helper for enforcement are provided. | ||
|
|
||
| ## Motivation | ||
|
|
||
| Consider the following scenarios where scoping access to specific resources using roots is highly desirable: | ||
|
|
||
| 1. **Cloud Storage**: Restricting access to specific S3 buckets or prefixes using `s3://bucket-name/prefix/` roots allows operating only within designated storage areas while preventing access to other buckets or sensitive data paths. | ||
|
|
||
| 2. **Version Control Repository**: Limiting operations to specific repositories using `https://github.com/owner/repo/` roots limits actions within the current project context without inadvertently affecting other repositories. | ||
|
|
||
| 3. **Databases**: Restricting databases to `postgres://host/database/table/` roots enables fine-grained control over which schemas, tables, or collections a server can query or modify. No more accidentally deleting the production database. | ||
|
|
||
| ## Specification | ||
|
|
||
| This change was originally proposed in #507 but not followed through. This was due to other time commitments from the original contributor, as well as a lack of a formal SEP governance process at the time, which made it more challenging to move proposals forward. | ||
|
|
||
| ### Schema Changes | ||
|
|
||
| Update the `Root` interface in all schema versions to remove the file:// restriction: | ||
|
|
||
| ```typescript | ||
| export interface Root { | ||
| /** | ||
| * The URI identifying the root. This can be any valid URI scheme. | ||
| * Common schemes include file://, https://, github://, s3://, etc. | ||
| * Servers should document which URI schemes they support. | ||
| * | ||
| * @format uri | ||
| */ | ||
| uri: string; | ||
|
|
||
| /** | ||
| * An optional human-readable name for this root. | ||
| */ | ||
| name?: string; | ||
|
|
||
| /** | ||
| * Optional metadata for this root. | ||
| */ | ||
| _meta?: { [key: string]: unknown }; | ||
| } | ||
| ``` | ||
|
|
||
| The specification should include guidance that | ||
|
|
||
| 1. Servers must document their supported URI schemes and validate them. Clients may provide roots with any URI scheme, and servers must gracefully handle unsupported schemes by returning clear error messages rather than failing silently. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Protocol level errors? That seems harsh for this. When would this be needed and how are client supposed to handle and act on error messages? |
||
| 2. Clients SHOULD provide a way to display which Roots are active | ||
|
|
||
| ## Rationale | ||
|
|
||
| The URI field restriction in the current specification is purely a documentation constraint rather than a technical limitation. Resources in MCP already support any URI scheme, and maintaining consistency between resources and roots simplifies the mental model for developers for roots as client-specified resources which the server can access. | ||
|
|
||
| ### Alternatives Considered | ||
|
|
||
| Creating separate mechanisms for local and remote servers does not provide any clear benefits and fragments the ecosystem. The simple approach of allowing any URI maintains complete backward compatibility. Existing clients continue sending file:// roots unchanged, existing servers continue accepting them, and the ecosystem can gradually adopt support for additional schemes as needed | ||
|
|
||
| ### Future Work | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think adding scope (like read, write) to roots as future work would be incredibly useful.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💯 - will add |
||
|
|
||
| We discussed proposing programmatic discovery mechanisms for which schemes a server supports, but decided to keep this change simple by removing the file restriction. The lack of programmatic discovery follows MCP's existing patterns and shouldn't limit practical usefulness because: | ||
|
|
||
| 1. Servers will naturally document what they support, clients will implement common patterns, and the ecosystem will converge on standards, just like with resource URIs. | ||
| 2. When a client provides an unsupported root, the server returns a clear error. In this case clients can gracefully degrade or prompt users to adjust roots. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think the server should return an error. It is a reasonable pattern for the client to just broadcast roots - it is not an error to have a root that a server doesn't support, and it adds complexity if there needs to be a negotiation of back and forth to establish a set of supported roots for each server. The SEP also doesn't describe how this would happen. If roots are to be adjustable this would require further changes, I believe? (I agree that the lack of programmatic discovery is not a problem) |
||
| 3. If this becomes a pain point, a future SEP can add discovery without breaking existing implementations. | ||
|
|
||
| ## Backward Compatibility | ||
|
|
||
| This change is fully backward compatible with existing implementations. | ||
|
|
||
| ## Reference Implementation | ||
|
|
||
| **Python SDK:** https://github.com/modelcontextprotocol/python-sdk/pull/1390/files | ||
| **Typescript SDK:** https://github.com/modelcontextprotocol/typescript-sdk/pull/997/files | ||
| **Client Changes (fast-agent):** https://github.com/chughtapan/fast-agent/pull/3/files | ||
|
|
||
| Although current SDKs don't provide support for roots enforcement, an example has been implemented in [github.com/chughtapan/wags](https://github.com/chughtapan/wags/blob/main/src/wags/middleware/roots.py): a helpful decorator is provided for tools to declare which roots are required: | ||
|
|
||
| ```python | ||
| @mcp.tool | ||
| @requires_root("https://github.com/{owner}/{repo}") | ||
| async def create_issue(self, owner: str, repo: str, title: str, body: str): | ||
| # Proceed with edit operation | ||
| ``` | ||
|
|
||
| and the `call_tool` tool handlers check that provides a root which satisfies this requirement before proceeding. | ||
|
|
||
| ## Security Considerations | ||
|
|
||
| The documentation should clearly highlight that roots are not enforced at the protocol layer, but advisory for the servers. Malicious or buggy servers might violate user expectations of security. | ||
|
|
||
| Clients SHOULD provide a way to display which Roots are active | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| # SEP-2202: Allow Non-File URI Schemes for Roots | ||
|
|
||
| - **Status**: Draft | ||
| - **Type**: Standards Track | ||
| - **Created**: 2025-09-29 | ||
| - **Author(s)**: Tapan Chugh (@chughtapan), Ola (@olaservo); original proposal by @noctonic in #507 | ||
| - **Sponsor**: Ola (@olaservo) | ||
| - **PR**: #2202 | ||
| - **Original Issue**: #1573 (transferred to new PR-based SEP workflow per SEP-1850) | ||
|
|
||
| ## Abstract | ||
|
|
||
| This SEP proposes removing the restriction that root URIs must begin with `file://`, allowing servers to work with remote resources through any URI scheme. Reference implementations in `python-sdk`, `typescript-sdk`, client (`fast-agent`) a helper for enforcement are provided. | ||
|
|
||
| ## Motivation | ||
|
|
||
| Consider the following scenarios where scoping access to specific resources using roots is highly desirable: | ||
|
|
||
| 1. **Cloud Storage**: Restricting access to specific S3 buckets or prefixes using `s3://bucket-name/prefix/` roots allows operating only within designated storage areas while preventing access to other buckets or sensitive data paths. | ||
|
|
||
| 2. **Version Control Repository**: Limiting operations to specific repositories using `https://github.com/owner/repo/` roots limits actions within the current project context without inadvertently affecting other repositories. | ||
|
|
||
| 3. **Databases**: Restricting databases to `postgres://host/database/table/` roots enables fine-grained control over which schemas, tables, or collections a server can query or modify. No more accidentally deleting the production database. | ||
|
|
||
| ## Specification | ||
|
|
||
| This change was originally proposed in #507 but not followed through. This was due to other time commitments from the original contributor, as well as a lack of a formal SEP governance process at the time, which made it more challenging to move proposals forward. | ||
|
|
||
| ### Schema Changes | ||
|
|
||
| Update the `Root` interface in all schema versions to remove the file:// restriction: | ||
|
|
||
| ```typescript | ||
| export interface Root { | ||
| /** | ||
| * The URI identifying the root. This can be any valid URI scheme. | ||
| * Common schemes include file://, https://, github://, s3://, etc. | ||
| * Servers should document which URI schemes they support. | ||
| * | ||
| * @format uri | ||
| */ | ||
| uri: string; | ||
|
|
||
| /** | ||
| * An optional human-readable name for this root. | ||
| */ | ||
| name?: string; | ||
|
|
||
| /** | ||
| * Optional metadata for this root. | ||
| */ | ||
| _meta?: { [key: string]: unknown }; | ||
| } | ||
| ``` | ||
|
|
||
| The specification should include guidance that | ||
|
|
||
| 1. Servers must document their supported URI schemes and validate them. Clients may provide roots with any URI scheme, and servers must gracefully handle unsupported schemes by returning clear error messages rather than failing silently. | ||
| 2. Clients SHOULD provide a way to display which Roots are active | ||
|
|
||
| ## Rationale | ||
|
|
||
| The URI field restriction in the current specification is purely a documentation constraint rather than a technical limitation. Resources in MCP already support any URI scheme, and maintaining consistency between resources and roots simplifies the mental model for developers for roots as client-specified resources which the server can access. | ||
|
|
||
| ### Alternatives Considered | ||
|
|
||
| Creating separate mechanisms for local and remote servers does not provide any clear benefits and fragments the ecosystem. The simple approach of allowing any URI maintains complete backward compatibility. Existing clients continue sending file:// roots unchanged, existing servers continue accepting them, and the ecosystem can gradually adopt support for additional schemes as needed | ||
|
|
||
| ### Future Work | ||
|
|
||
| We discussed proposing programmatic discovery mechanisms for which schemes a server supports, but decided to keep this change simple by removing the file restriction. The lack of programmatic discovery follows MCP's existing patterns and shouldn't limit practical usefulness because: | ||
|
|
||
| 1. Servers will naturally document what they support, clients will implement common patterns, and the ecosystem will converge on standards, just like with resource URIs. | ||
| 2. When a client provides an unsupported root, the server returns a clear error. In this case clients can gracefully degrade or prompt users to adjust roots. | ||
| 3. If this becomes a pain point, a future SEP can add discovery without breaking existing implementations. | ||
|
|
||
| ## Backward Compatibility | ||
|
|
||
| This change is fully backward compatible with existing implementations. | ||
|
|
||
| ## Reference Implementation | ||
|
|
||
| **Python SDK:** https://github.com/modelcontextprotocol/python-sdk/pull/1390/files | ||
| **Typescript SDK:** https://github.com/modelcontextprotocol/typescript-sdk/pull/997/files | ||
| **Client Changes (fast-agent):** https://github.com/chughtapan/fast-agent/pull/3/files | ||
|
|
||
| Although current SDKs don't provide support for roots enforcement, an example has been implemented in [github.com/chughtapan/wags](https://github.com/chughtapan/wags/blob/main/src/wags/middleware/roots.py): a helpful decorator is provided for tools to declare which roots are required: | ||
|
|
||
| ```python | ||
| @mcp.tool | ||
| @requires_root("https://github.com/{owner}/{repo}") | ||
| async def create_issue(self, owner: str, repo: str, title: str, body: str): | ||
| # Proceed with edit operation | ||
| ``` | ||
|
|
||
| and the `call_tool` tool handlers check that provides a root which satisfies this requirement before proceeding. | ||
|
|
||
| ## Security Considerations | ||
|
|
||
| The documentation should clearly highlight that roots are not enforced at the protocol layer, but advisory for the servers. Malicious or buggy servers might violate user expectations of security. | ||
|
|
||
| Clients SHOULD provide a way to display which Roots are active |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Remote resources" could be "client and remote resources"? Using roots as a way to communicate what local resources are within limits is still a very useful (and underutilized) application of the capability.