Skip to content

SEP: Namespaces using URIs #1230

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 12 commits into
base: main
Choose a base branch
from

Conversation

chughtapan
Copy link

@chughtapan chughtapan commented Aug 2, 2025

Reference implementation: for the SEP: Namespaces using URIs
Key Changes:

  1. Added uri fields to Tools and Prompts.
  2. Added capability to filter by URI prefixes for all list methods (list_resources, tools, etc.)

Motivation and Context

modelcontextprotocol/modelcontextprotocol#993 proposed namespaces as a new capability to offer hierarchical aggregation of MCP servers. However, was rejected in modelcontextprotocol/modelcontextprotocol#1061 with the motivation URIs are the preferred approach for handling hierarchies.

How Has This Been Tested?

All existing and new unit tests pass

Breaking Changes

Low-level code and SDKs might require changes, but this is non-breaking for clients & applications.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

There are several open questions:

  • What should be the reserved URI prefix for tools and prompts? I propose mcp://tools/ and mcp://prompts/ and recommend that we should reserve the entire mcp:// prefix for future.
  • What should be the semantics around filters? I'm currently using path prefix matching for now but open to other alternatives as well

Tapan Chugh and others added 10 commits July 31, 2025 17:27
Add ToolResource and PromptResource base classes that extend the Resource
base class. Tool now inherits from ToolResource and Prompt inherits from
PromptResource, establishing a proper inheritance hierarchy.

Tools and prompts automatically generate URIs with their respective schemes
(tool://name and prompt://name) when created. This allows them to be accessed
through the ResourceManager using their URIs while maintaining full backward
compatibility with existing code.

The ResourceManager's list_resources() method filters out tool and prompt
URIs by default to preserve the existing API behavior. Tools and prompts
can still be accessed directly by their URIs when needed.

Comprehensive tests verify the inheritance model works correctly and that
all existing functionality remains intact.
Apply automated formatting from ruff to ensure consistent code style
across the combined features.
- Add uri field to FastMCP Tool and Prompt classes with automatic generation
- Change ToolManager and PromptManager to use URIs as primary keys
- Implement backward compatibility with automatic name-to-URI conversion
- Update server to use stored URIs instead of generating them
- Fix tests to handle URI-based warning messages

This aligns tools and prompts with the resource storage pattern, where URIs
are the primary identifiers. Names are automatically converted to URIs
(e.g., 'my_tool' -> 'tool://my_tool') for backward compatibility.
…ions

- Rename PaginatedRequestParams to ListRequestParams and add prefix field
- Rename PaginatedRequest to ListRequest for semantic clarity
- Rename PaginatedResult to ListResult for consistency
- Remove redundant ListResourcesRequestParams and ListResourceTemplatesRequestParams
- Add prefix filtering to tools and prompts list operations
- Ensure all prefixes are treated as path prefixes ending with /
- Update lowlevel server handlers to accept full request objects
- Update FastMCP server to extract prefix from request params

This unifies the list operation API across resources, templates, tools, and
prompts. All list methods now support optional prefix filtering using URI
path prefixes (e.g., 'tool://category/' to match only tools under that path).
…storage

- Add prefix parameter to PromptManager.list_prompts() with path prefix behavior
- Add _normalize_to_uri() method to convert names to prompt:// URIs
- Update add_prompt() to use URIs as keys for consistent storage
- Update get_prompt() to accept both names and URIs
- Update FastMCP server to pass request object to lowlevel handlers
- Fix test expectation for new path prefix behavior in list_templates

This completes the implementation of consistent prefix-based filtering
across all list operations (resources, templates, tools, and prompts).
This commit fixes all test failures that occurred after implementing
consistent prefix-based filtering across tools, prompts, and resources.

Changes:
- Add required URI fields to all Tool instances in tests
- Update all list_tools handlers to accept request parameter
- Fix client session to use ListRequestParams for all list methods
- Update test handlers in streamable_http, SSE, and WS tests

The tests were failing because:
1. Tool objects now require a URI field
2. Low-level server list_tools handlers expect a request parameter
3. Client session was using old RequestParams class names

All tests now pass except for one unrelated connection error.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Add TOOL_SCHEME and PROMPT_SCHEME constants in mcp/types.py
- Create common URI utilities in uri_utils.py for normalization and prefix filtering
- Update Tool and Prompt classes to auto-generate URIs when not provided
- Replace hardcoded URI schemes throughout codebase with constants
- Fix prefix filtering to handle partial matches correctly
- Update example files to match expected function signatures
- Replace unused request parameters with _ in handler functions
- Remove explicit URI additions where auto-generation suffices
- Remove unused TOOL_SCHEME and other imports
- Keep only changes essential for prefix filtering functionality

This reduces noise in tests and examples while maintaining the core
functionality of URI-based storage and prefix filtering.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Change URI schemes from tool:// and prompt:// to mcp://tools and mcp://prompts
- Add MCP_SCHEME constant and use it for URL validation
- Add model validators to ensure URIs start with correct prefixes
- Improve filter_by_prefix to accept AnyUrl | str, removing need for str() casts
- Make Prompt description field optional (matching main branch)
- Update all tests to use scheme constants instead of hardcoded values

This provides a more standard URI format where 'mcp' is the scheme and
'tools'/'prompts' are path segments, while also simplifying the API.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
…resources

- Changed Tool and Prompt URI fields from optional to required (auto-generated)
- Updated Resource validator to block any URI using the MCP scheme (mcp://)
- Removed unnecessary None checks in URI validators since fields are now required
- Updated tests to match new error message

This provides stronger type safety and clearer API contracts while maintaining
backward compatibility through auto-generation.
@lironsher
Copy link

Can you add some examples for URIs?

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.

2 participants