René's URL Explorer Experiment


Title: feat: RFC 6570 URI templates with operator-aware security by maxisbey · Pull Request #2356 · modelcontextprotocol/python-sdk · GitHub

Open Graph Title: feat: RFC 6570 URI templates with operator-aware security by maxisbey · Pull Request #2356 · modelcontextprotocol/python-sdk

X Title: feat: RFC 6570 URI templates with operator-aware security by maxisbey · Pull Request #2356 · modelcontextprotocol/python-sdk

Description: Replaces the regex-based resource template matcher with a linear-time RFC 6570 implementation, adds configurable path-safety validation, and exports a standalone UriTemplate usable from both client and low-level server. Motivation The existing matcher only supports RFC 6570 Level 1 ({var}). Users writing file://{+path} for multi-segment paths hit a confusing "mismatch" error because the regex-based extraction doesn't understand the + operator. The TypeScript, C#, and Go SDKs all support Level 3+. The matcher also doesn't escape template literals, so data://v1.0/{id} incorrectly matches data://v1X0/42. Separately, encoded ../ sequences in extracted parameters are passed to handlers unchecked. The 2026 spec adds a normative requirement that file:// resource servers sanitize paths. Closes #436, closes #220, closes #159, closes #378 Supersedes #197, #427, #1439, #2353 What's in here mcp.shared.uri_template.UriTemplate — RFC 6570 Levels 1-3 plus path-style explode ({/var*}, {.var*}, {;var*}). parse() / expand() / match(). Re-exported at the top level so clients can expand a template a server advertises. The matcher is a two-ended linear scan with no backtracking. Rather than handling ambiguous templates with scan-time special cases, the parser rejects them up front: two variables adjacent with no literal between them, more than one multi-segment variable, and more than one {?...} expression all raise InvalidUriTemplate at decoration time. Operators that emit their own delimiter ({+path}{.ext}, {+path}{/seg}, {+path}{;k}) still compose. Query expressions match leniently (order-agnostic, partial, extras ignored), and a handler parameter bound to one must declare a Python default — also checked at decoration time. mcp.shared.path_security — contains_path_traversal(), is_absolute_path(), safe_join(). The last resolves and verifies containment, catching symlink escapes. ResourceSecurity policy — wired into MCPServer(resource_security=...) and @mcp.resource(..., security=...). By default rejects .. escapes, absolute paths, and null bytes. A rejection is indistinguishable on the wire from a not-found resource (-32602) and halts template iteration. Per-parameter opt-out via exempt_params={"name"}. Tests Example-based suites for UriTemplate and path_security, e2e tests through Client for the decorator and policy, plus two seeded property tests over the full space the parser accepts: match(expand(v)) round-trips and match() never raises on any input. 100% coverage. Breaking changes See docs/migration.md for the full list. Headline items: Path-safety checks applied by default (opt out via ResourceSecurity) Template literals match exactly; {var} stops at structural delimiters and now matches an empty value Two adjacent variables, more than one multi-segment variable, more than one {?...}, and other malformed templates raise at decoration time A {?...}-bound handler parameter without a default raises at decoration time Docs Tested reference page at docs/advanced/uri-templates.md with runnable examples under docs_src/uri_templates/. AI Disclaimer

Open Graph Description: Replaces the regex-based resource template matcher with a linear-time RFC 6570 implementation, adds configurable path-safety validation, and exports a standalone UriTemplate usable from both client...

X Description: Replaces the regex-based resource template matcher with a linear-time RFC 6570 implementation, adds configurable path-safety validation, and exports a standalone UriTemplate usable from both client...

Opengraph URL: https://github.com/modelcontextprotocol/python-sdk/pull/2356

X: @github

direct link

Domain: github.com

route-pattern/:user_id/:repository/pull/:id/files(.:format)
route-controllerpull_requests
route-actionfiles
fetch-noncev2:c2f7b576-e0a7-a6d9-c854-4b685b9c808e
current-catalog-service-hashae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b
request-idBFB6:46803:A93F0C:F47470:6A58D0E1
html-safe-nonce44e69845f0e2a9131e44e27bde7a8ec053141fb26297c284bf51ab471b22cc79
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCRkI2OjQ2ODAzOkE5M0YwQzpGNDc0NzA6NkE1OEQwRTEiLCJ2aXNpdG9yX2lkIjoiNDU2NDI3MDI2NDE2MzU1MzUwNSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9
visitor-hmaccd801f61279250aba8f36303662147656c3b768f0357963bd50ce784c82a4d96
hovercard-subject-tagpull_request:3452922756
github-keyboard-shortcutsrepository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///pull_requests/show/files
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/modelcontextprotocol/python-sdk/pull/2356/files
twitter:imagehttps://avatars.githubusercontent.com/u/224885523?s=400&v=4
twitter:cardsummary_large_image
og:imagehttps://avatars.githubusercontent.com/u/224885523?s=400&v=4
og:image:altReplaces the regex-based resource template matcher with a linear-time RFC 6570 implementation, adds configurable path-safety validation, and exports a standalone UriTemplate usable from both client...
og:site_nameGitHub
og:typeobject
hostnamegithub.com
expected-hostnamegithub.com
None5f2a0c7865178af3d91dd9f13b0cdfc3c73a2529c873d2780bb4c01271a57ec6
turbo-cache-controlno-preview
diff-viewunified
go-importgithub.com/modelcontextprotocol/python-sdk git https://github.com/modelcontextprotocol/python-sdk.git
octolytics-dimension-user_id182288589
octolytics-dimension-user_loginmodelcontextprotocol
octolytics-dimension-repository_id862584018
octolytics-dimension-repository_nwomodelcontextprotocol/python-sdk
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id862584018
octolytics-dimension-repository_network_root_nwomodelcontextprotocol/python-sdk
turbo-body-classeslogged-out env-production page-responsive full-width
disable-turbotrue
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
release8aae7b8d6caacacf5c66eaeb2702d8dc88d85b4a
ui-targetfull
theme-color#1e2327
color-schemelight dark

Links:

Skip to contenthttps://github.com/modelcontextprotocol/python-sdk/pull/2356/files#start-of-content
https://github.com/
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fmodelcontextprotocol%2Fpython-sdk%2Fpull%2F2356%2Ffiles
GitHub CopilotWrite better code with AIhttps://github.com/features/copilot
GitHub Copilot appDirect agents from issue to mergehttps://github.com/features/ai/github-app
MCP RegistryNewIntegrate external toolshttps://github.com/mcp
ActionsAutomate any workflowhttps://github.com/features/actions
CodespacesInstant dev environmentshttps://github.com/features/codespaces
IssuesPlan and track workhttps://github.com/features/issues
Code ReviewManage code changeshttps://github.com/features/code-review
GitHub Advanced SecurityFind and fix vulnerabilitieshttps://github.com/security/advanced-security
Code securitySecure your code as you buildhttps://github.com/security/advanced-security/code-security
Secret protectionStop leaks before they starthttps://github.com/security/advanced-security/secret-protection
Why GitHubhttps://github.com/why-github
Documentationhttps://docs.github.com
Bloghttps://github.blog
Changeloghttps://github.blog/changelog
Marketplacehttps://github.com/marketplace
View all featureshttps://github.com/features
Enterpriseshttps://github.com/enterprise
Small and medium teamshttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
App Modernizationhttps://github.com/solutions/use-case/app-modernization
DevSecOpshttps://github.com/solutions/use-case/devsecops
DevOpshttps://github.com/solutions/use-case/devops
CI/CDhttps://github.com/solutions/use-case/ci-cd
View all use caseshttps://github.com/solutions/use-case
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
View all industrieshttps://github.com/solutions/industry
View all solutionshttps://github.com/solutions
AIhttps://github.com/resources/articles?topic=ai
Software Developmenthttps://github.com/resources/articles?topic=software-development
DevOpshttps://github.com/resources/articles?topic=devops
Securityhttps://github.com/resources/articles?topic=security
View all topicshttps://github.com/resources/articles
Customer storieshttps://github.com/customer-stories
Events & webinarshttps://github.com/resources/events
Ebooks & reportshttps://github.com/resources/whitepapers
Business insightshttps://github.com/solutions/executive-insights
GitHub Skillshttps://skills.github.com
Documentationhttps://docs.github.com
Customer supporthttps://support.github.com
Community forumhttps://github.com/orgs/community/discussions
Trust centerhttps://github.com/trust-center
Partnershttps://github.com/partners
View all resourceshttps://github.com/resources
GitHub SponsorsFund open source developershttps://github.com/open-source/sponsors
Security Labhttps://securitylab.github.com
Maintainer Communityhttps://maintainers.github.com
Acceleratorhttps://github.com/open-source/accelerator
GitHub Starshttps://stars.github.com
Archive Programhttps://archiveprogram.github.com
Topicshttps://github.com/topics
Trendinghttps://github.com/trending
Collectionshttps://github.com/collections
Enterprise platformAI-powered developer platformhttps://github.com/enterprise
GitHub Advanced SecurityEnterprise-grade security featureshttps://github.com/security/advanced-security
Copilot for BusinessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/enterprise/premium-support
Pricinghttps://github.com/pricing
Search syntax tipshttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
documentationhttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fmodelcontextprotocol%2Fpython-sdk%2Fpull%2F2356%2Ffiles
Sign up https://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fpull_requests%2Fshow%2Ffiles&source=header-repo&source_repo=modelcontextprotocol%2Fpython-sdk
Reloadhttps://github.com/modelcontextprotocol/python-sdk/pull/2356/files
Reloadhttps://github.com/modelcontextprotocol/python-sdk/pull/2356/files
Reloadhttps://github.com/modelcontextprotocol/python-sdk/pull/2356/files
Please reload this pagehttps://github.com/modelcontextprotocol/python-sdk/pull/2356/files
modelcontextprotocol https://github.com/modelcontextprotocol
python-sdkhttps://github.com/modelcontextprotocol/python-sdk
Notifications https://github.com/login?return_to=%2Fmodelcontextprotocol%2Fpython-sdk
Fork 3.7k https://github.com/login?return_to=%2Fmodelcontextprotocol%2Fpython-sdk
Star 23.6k https://github.com/login?return_to=%2Fmodelcontextprotocol%2Fpython-sdk
Code https://github.com/modelcontextprotocol/python-sdk
Issues 254 https://github.com/modelcontextprotocol/python-sdk/issues
Pull requests 290 https://github.com/modelcontextprotocol/python-sdk/pulls
Actions https://github.com/modelcontextprotocol/python-sdk/actions
Projects https://github.com/modelcontextprotocol/python-sdk/projects
Models https://github.com/modelcontextprotocol/python-sdk/models
Security and quality 6 https://github.com/modelcontextprotocol/python-sdk/security
Insights https://github.com/modelcontextprotocol/python-sdk/pulse
Code https://github.com/modelcontextprotocol/python-sdk
Issues https://github.com/modelcontextprotocol/python-sdk/issues
Pull requests https://github.com/modelcontextprotocol/python-sdk/pulls
Actions https://github.com/modelcontextprotocol/python-sdk/actions
Projects https://github.com/modelcontextprotocol/python-sdk/projects
Models https://github.com/modelcontextprotocol/python-sdk/models
Security and quality https://github.com/modelcontextprotocol/python-sdk/security
Insights https://github.com/modelcontextprotocol/python-sdk/pulse
Sign up for GitHub https://github.com/signup?return_to=%2Fmodelcontextprotocol%2Fpython-sdk%2Fissues%2Fnew%2Fchoose
terms of servicehttps://docs.github.com/terms
privacy statementhttps://docs.github.com/privacy
Sign inhttps://github.com/login?return_to=%2Fmodelcontextprotocol%2Fpython-sdk%2Fissues%2Fnew%2Fchoose
maxisbeyhttps://github.com/maxisbey
mainhttps://github.com/modelcontextprotocol/python-sdk/tree/main
feat/uri-template-rfc6570https://github.com/modelcontextprotocol/python-sdk/tree/feat/uri-template-rfc6570
Conversation 35 https://github.com/modelcontextprotocol/python-sdk/pull/2356
Commits 1 https://github.com/modelcontextprotocol/python-sdk/pull/2356/commits
Checks 34 https://github.com/modelcontextprotocol/python-sdk/pull/2356/checks
Files changed https://github.com/modelcontextprotocol/python-sdk/pull/2356/files
Please reload this pagehttps://github.com/modelcontextprotocol/python-sdk/pull/2356/files
feat: RFC 6570 URI templates with operator-aware security https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#top
Show all changes 1 commit https://github.com/modelcontextprotocol/python-sdk/pull/2356/files
c75e71c feat: RFC 6570 URI templates with operator-aware security maxisbey Jun 26, 2026 https://github.com/modelcontextprotocol/python-sdk/pull/2356/commits/c75e71c0be2da8ad09c9c72ff7ccd021a7beb662
Clear filters https://github.com/modelcontextprotocol/python-sdk/pull/2356/files
Please reload this pagehttps://github.com/modelcontextprotocol/python-sdk/pull/2356/files
Please reload this pagehttps://github.com/modelcontextprotocol/python-sdk/pull/2356/files
uri-templates.md https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-3a2a23156c9551319b12eff16b8110d85bacb10a12d3477072530a3ce7db128f
migration.md https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-758ba107a728fccfdf0d098b2c06ded59127dd53ea287d630f72fb51040bc72d
resources.md https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-3e49f975dd9f9c736e40909b219424a6bad21fb9e7bea317ec77367597538848
__init__.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-d6cdd6f74757a7c84ff21a3a399ac1fc252c0c946ccc22e0c74a7088ec26304e
tutorial001.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-37f00f7a118743d19e91e5cfd0c0c47b1f2495da2a0a84dc0aa1c35545b4b645
tutorial002.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-20c2825b217ad08a9688e871fc6bd774df4eb3cde350f483fd68aaf309e87eaf
tutorial003.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-c9241983478e1303de364082d33030326ca5bcc4a3d3ef9d40de3e7a91dc4720
tutorial004.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-739e5b2ca3b978a623a4c7f9b97c02502ef8bf547643f103b8a877395b304419
tutorial005.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-30c300156219cefad351781cdc9f2135ed017e94b931eed03f4c173cac497aeb
mkdocs.yml https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-98d0f806abc9af24e6a7c545d3d77e8f9ad57643e27211d7a7b896113e420ed2
__init__.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-208c9cff9cd42bad47f1042db6861d931673ca78db6de12bd4d8f65885f8f126
__init__.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-1212dd4293d9fb8b9118c5b2f2afed4b9d4f227de7717f269aa0d64a251ce6e0
__init__.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-ded901c4d48df2e4fbe8f25fe5c24ccb1ad2c38ac1b5fdeeffaf7c29c72db4ae
resource_manager.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-3638946fe0f98df2b1f99f9237907bc1344596ddd20cdfbb297d3ae874894cfd
templates.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-44c89eefb9a0f376f6c3004ad4a44828e0403a96114fe008c0dd7a708abde7cc
server.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-51d6996c0b80b8a5c42e7071451cb9ed3c91b398facebe99b94aad911059190e
path_security.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-33c775081029340d33d42decc5ba317446540919d1c1c1e3ce5f80e20874126a
uri_template.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-fed1ff9188bc03dbe6438f057a8a14e0836709fbe492ce2f5b1f1e07a828ca31
test_uri_templates.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-99565cbb8d2c9e64d4e019a4a18724feb70eef08c3f352fc74dffc4db75a9bfc
test_resource_template.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-1984957e9d1e3a3e525ce9a3707676cae0b81fd98ba0866abf8ce087e1c443b6
test_server.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-c191383f010475fc22bf69d35f14f16d7e45098b05a1a0f03ad66d6c151d1f34
test_path_security.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-0c2fd0c64cc28011337522c6c21ce59779a5c9d8c253b54922d6b3268cd61cb2
test_uri_template.py https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-4e3a447efa9eb14dbebca06f141da49ed4759667d30c414d01631162351412c6
docs/advanced/uri-templates.mdhttps://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-3a2a23156c9551319b12eff16b8110d85bacb10a12d3477072530a3ce7db128f
View file https://github.com/modelcontextprotocol/python-sdk/blob/c75e71c0be2da8ad09c9c72ff7ccd021a7beb662/docs/advanced/uri-templates.md
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/modelcontextprotocol/python-sdk/pull/2356/{{ revealButtonHref }}
Please reload this pagehttps://github.com/modelcontextprotocol/python-sdk/pull/2356/files
docs/migration.mdhttps://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-758ba107a728fccfdf0d098b2c06ded59127dd53ea287d630f72fb51040bc72d
View file https://github.com/modelcontextprotocol/python-sdk/blob/c75e71c0be2da8ad09c9c72ff7ccd021a7beb662/docs/migration.md
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/modelcontextprotocol/python-sdk/pull/2356/{{ revealButtonHref }}
https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-758ba107a728fccfdf0d098b2c06ded59127dd53ea287d630f72fb51040bc72d
https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-758ba107a728fccfdf0d098b2c06ded59127dd53ea287d630f72fb51040bc72d
docs/tutorial/resources.mdhttps://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-3e49f975dd9f9c736e40909b219424a6bad21fb9e7bea317ec77367597538848
View file https://github.com/modelcontextprotocol/python-sdk/blob/c75e71c0be2da8ad09c9c72ff7ccd021a7beb662/docs/tutorial/resources.md
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/modelcontextprotocol/python-sdk/pull/2356/{{ revealButtonHref }}
https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-3e49f975dd9f9c736e40909b219424a6bad21fb9e7bea317ec77367597538848
https://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-3e49f975dd9f9c736e40909b219424a6bad21fb9e7bea317ec77367597538848
docs_src/uri_templates/__init__.pyhttps://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-d6cdd6f74757a7c84ff21a3a399ac1fc252c0c946ccc22e0c74a7088ec26304e
View file https://github.com/modelcontextprotocol/python-sdk/blob/c75e71c0be2da8ad09c9c72ff7ccd021a7beb662/docs_src/uri_templates/__init__.py
Open in desktop https://desktop.github.com
docs_src/uri_templates/tutorial001.pyhttps://github.com/modelcontextprotocol/python-sdk/pull/2356/files#diff-37f00f7a118743d19e91e5cfd0c0c47b1f2495da2a0a84dc0aa1c35545b4b645
View file https://github.com/modelcontextprotocol/python-sdk/blob/c75e71c0be2da8ad09c9c72ff7ccd021a7beb662/docs_src/uri_templates/tutorial001.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/modelcontextprotocol/python-sdk/pull/2356/{{ revealButtonHref }}
Please reload this pagehttps://github.com/modelcontextprotocol/python-sdk/pull/2356/files
Please reload this pagehttps://github.com/modelcontextprotocol/python-sdk/pull/2356/files
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.