Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions docs/community/seps/2202-non-file-uri-roots.mdx
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.

Copy link
Copy Markdown
Member

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.


## 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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.

@PederHP PederHP Feb 4, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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
2 changes: 2 additions & 0 deletions docs/community/seps/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ Specification Enhancement Proposals (SEPs) are the primary mechanism for proposi

## Summary

- **Draft**: 1
- **Final**: 24

## All SEPs

| SEP | Title | Status | Type | Created |
| ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------- | ---------------- | ---------- |
| [SEP-2202](/community/seps/2202-non-file-uri-roots) | Allow Non-File URI Schemes for Roots | <Badge color="gray" shape="pill">Draft</Badge> | Standards Track | 2025-09-29 |
| [SEP-2133](/community/seps/2133-extensions) | Extensions | <Badge color="green" shape="pill">Final</Badge> | Standards Track | 2025-01-21 |
| [SEP-2085](/community/seps/2085-governance-succession-and-amendment) | Governance Succession and Amendment Procedures | <Badge color="green" shape="pill">Final</Badge> | Process | 2025-12-05 |
| [SEP-1865](/community/seps/1865-mcp-apps-interactive-user-interfaces-for-mcp) | MCP Apps - Interactive User Interfaces for MCP | <Badge color="green" shape="pill">Final</Badge> | Extensions Track | 2025-11-21 |
Expand Down
6 changes: 6 additions & 0 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,12 @@
"community/seps/2085-governance-succession-and-amendment",
"community/seps/2133-extensions"
]
},
{
"group": "Draft",
"pages": [
"community/seps/2202-non-file-uri-roots"
]
}
]
},
Expand Down
102 changes: 102 additions & 0 deletions seps/2202-non-file-uri-roots.md
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